53 #define OFFSET(x) offsetof(V360Context, x)
54 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
55 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
256 #define DEFINE_REMAP1_LINE(bits, div) \
257 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
258 ptrdiff_t in_linesize, \
259 const int16_t *const u, const int16_t *const v, \
260 const int16_t *const ker) \
262 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
263 uint##bits##_t *d = (uint##bits##_t *)dst; \
265 in_linesize /= div; \
267 for (int x = 0; x < width; x++) \
268 d[x] = s[v[x] * in_linesize + u[x]]; \
280 #define DEFINE_REMAP(ws, bits) \
281 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
283 ThreadData *td = arg; \
284 const V360Context *s = ctx->priv; \
285 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
286 const AVFrame *in = td->in; \
287 AVFrame *out = td->out; \
289 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
290 for (int plane = 0; plane < s->nb_planes; plane++) { \
291 const unsigned map = s->map[plane]; \
292 const int in_linesize = in->linesize[plane]; \
293 const int out_linesize = out->linesize[plane]; \
294 const int uv_linesize = s->uv_linesize[plane]; \
295 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
296 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
297 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
298 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
299 const uint8_t *const src = in->data[plane] + \
300 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
301 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
302 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
303 const int width = s->pr_width[plane]; \
304 const int height = s->pr_height[plane]; \
306 const int slice_start = (height * jobnr ) / nb_jobs; \
307 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
309 for (int y = slice_start; y < slice_end && !mask; y++) { \
310 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
311 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
312 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
314 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
317 for (int y = slice_start; y < slice_end && mask; y++) { \
318 memcpy(dst + y * out_linesize, mask + \
319 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
336 #define DEFINE_REMAP_LINE(ws, bits, div) \
337 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
338 ptrdiff_t in_linesize, \
339 const int16_t *const u, const int16_t *const v, \
340 const int16_t *const ker) \
342 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
343 uint##bits##_t *d = (uint##bits##_t *)dst; \
345 in_linesize /= div; \
347 for (int x = 0; x < width; x++) { \
348 const int16_t *const uu = u + x * ws * ws; \
349 const int16_t *const vv = v + x * ws * ws; \
350 const int16_t *const kker = ker + x * ws * ws; \
353 for (int i = 0; i < ws; i++) { \
354 const int iws = i * ws; \
355 for (int j = 0; j < ws; j++) { \
356 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
360 d[x] = av_clip_uint##bits(tmp >> 14); \
375 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
378 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
381 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
388 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
407 int16_t *
u, int16_t *v, int16_t *ker)
410 const int j =
lrintf(du) + 1;
412 u[0] = rmap->
u[
i][j];
413 v[0] = rmap->
v[
i][j];
427 int16_t *
u, int16_t *v, int16_t *ker)
429 for (
int i = 0;
i < 2;
i++) {
430 for (
int j = 0; j < 2; j++) {
431 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
432 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
436 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
437 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
438 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
439 ker[3] =
lrintf( du * dv * 16385.
f);
450 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
451 coeffs[1] = -t * (t - 2.f);
452 coeffs[2] = t * (t - 1.f) * 0.5
f;
466 int16_t *
u, int16_t *v, int16_t *ker)
474 for (
int i = 0;
i < 3;
i++) {
475 for (
int j = 0; j < 3; j++) {
476 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
477 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
478 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
491 const float tt = t * t;
492 const float ttt = t * t * t;
494 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
495 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
496 coeffs[2] = t + tt / 2.f - ttt / 2.f;
497 coeffs[3] = - t / 6.f + ttt / 6.f;
511 int16_t *
u, int16_t *v, int16_t *ker)
519 for (
int i = 0;
i < 4;
i++) {
520 for (
int j = 0; j < 4; j++) {
521 u[
i * 4 + j] = rmap->
u[
i][j];
522 v[
i * 4 + j] = rmap->
v[
i][j];
523 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
538 for (
int i = 0;
i < 4;
i++) {
539 const float x =
M_PI * (t -
i + 1);
543 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
548 for (
int i = 0;
i < 4;
i++) {
564 int16_t *
u, int16_t *v, int16_t *ker)
572 for (
int i = 0;
i < 4;
i++) {
573 for (
int j = 0; j < 4; j++) {
574 u[
i * 4 + j] = rmap->
u[
i][j];
575 v[
i * 4 + j] = rmap->
v[
i][j];
576 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
589 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
590 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
591 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
592 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
606 int16_t *
u, int16_t *v, int16_t *ker)
614 for (
int i = 0;
i < 4;
i++) {
615 for (
int j = 0; j < 4; j++) {
616 u[
i * 4 + j] = rmap->
u[
i][j];
617 v[
i * 4 + j] = rmap->
v[
i][j];
618 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
633 for (
int i = 0;
i < 4;
i++) {
634 const float x = t - (
i - 1);
638 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
643 for (
int i = 0;
i < 4;
i++) {
659 int16_t *
u, int16_t *v, int16_t *ker)
667 for (
int i = 0;
i < 4;
i++) {
668 for (
int j = 0; j < 4; j++) {
669 u[
i * 4 + j] = rmap->
u[
i][j];
670 v[
i * 4 + j] = rmap->
v[
i][j];
671 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
686 float p0 = (6.f - 2.f *
b) / 6.
f,
687 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
688 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
689 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
690 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
691 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
692 q3 = (-
b - 6.f *
c) / 6.
f;
694 for (
int i = 0;
i < 4;
i++) {
695 const float x =
fabsf(t -
i + 1.
f);
697 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
698 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
699 }
else if (x < 2.
f) {
700 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
701 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
708 for (
int i = 0;
i < 4;
i++) {
724 int16_t *
u, int16_t *v, int16_t *ker)
732 for (
int i = 0;
i < 4;
i++) {
733 for (
int j = 0; j < 4; j++) {
734 u[
i * 4 + j] = rmap->
u[
i][j];
735 v[
i * 4 + j] = rmap->
v[
i][j];
736 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
751 const int res =
a %
b;
883 for (
int face = 0; face <
NB_FACES; face++) {
884 const char c =
s->in_forder[face];
889 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
894 if (direction == -1) {
896 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
900 s->in_cubemap_face_order[direction] = face;
903 for (
int face = 0; face <
NB_FACES; face++) {
904 const char c =
s->in_frot[face];
909 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
914 if (rotation == -1) {
916 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
920 s->in_cubemap_face_rotation[face] = rotation;
937 for (
int face = 0; face <
NB_FACES; face++) {
938 const char c =
s->out_forder[face];
943 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
948 if (direction == -1) {
950 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
954 s->out_cubemap_direction_order[face] = direction;
957 for (
int face = 0; face <
NB_FACES; face++) {
958 const char c =
s->out_frot[face];
963 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
968 if (rotation == -1) {
970 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
974 s->out_cubemap_face_rotation[face] = rotation;
1050 const float norm = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1070 float uf,
float vf,
int face,
1071 float *vec,
float scalew,
float scaleh)
1073 const int direction =
s->out_cubemap_direction_order[face];
1074 float l_x, l_y, l_z;
1081 switch (direction) {
1133 float *uf,
float *vf,
int *direction)
1135 const float phi =
atan2f(vec[0], vec[2]);
1136 const float theta = asinf(vec[1]);
1137 float phi_norm, theta_threshold;
1140 if (phi >= -M_PI_4 && phi < M_PI_4) {
1143 }
else if (phi >= -(
M_PI_2 + M_PI_4) && phi < -M_PI_4) {
1146 }
else if (phi >= M_PI_4 && phi <
M_PI_2 + M_PI_4) {
1151 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1154 theta_threshold =
atanf(
cosf(phi_norm));
1155 if (theta > theta_threshold) {
1157 }
else if (theta < -theta_threshold) {
1161 switch (*direction) {
1163 *uf = -vec[2] / vec[0];
1164 *vf = vec[1] / vec[0];
1167 *uf = -vec[2] / vec[0];
1168 *vf = -vec[1] / vec[0];
1171 *uf = -vec[0] / vec[1];
1172 *vf = -vec[2] / vec[1];
1175 *uf = vec[0] / vec[1];
1176 *vf = -vec[2] / vec[1];
1179 *uf = vec[0] / vec[2];
1180 *vf = vec[1] / vec[2];
1183 *uf = vec[0] / vec[2];
1184 *vf = -vec[1] / vec[2];
1190 face =
s->in_cubemap_face_order[*direction];
1207 float uf,
float vf,
int direction,
1208 float *new_uf,
float *new_vf,
int *face)
1227 *face =
s->in_cubemap_face_order[direction];
1230 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1234 }
else if (uf < -1.
f) {
1236 switch (direction) {
1270 }
else if (uf >= 1.
f) {
1272 switch (direction) {
1306 }
else if (vf < -1.
f) {
1308 switch (direction) {
1342 }
else if (vf >= 1.
f) {
1344 switch (direction) {
1384 *face =
s->in_cubemap_face_order[direction];
1390 return (0.5
f * x + 0.5
f) * (
s - 1.f);
1395 return (2.
f * x + 1.
f) /
s - 1.f;
1412 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1413 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1415 const float ew =
width / 3.f;
1416 const float eh =
height / 2.f;
1418 const int u_face =
floorf(
i / ew);
1419 const int v_face =
floorf(j / eh);
1420 const int face = u_face + 3 * v_face;
1422 const int u_shift =
ceilf(ew * u_face);
1423 const int v_shift =
ceilf(eh * v_face);
1424 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1425 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1427 const float uf =
rescale(
i - u_shift, ewi);
1428 const float vf =
rescale(j - v_shift, ehi);
1449 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1451 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1452 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1453 const float ew =
width / 3.f;
1454 const float eh =
height / 2.f;
1458 int direction, face;
1466 face =
s->in_cubemap_face_order[direction];
1469 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1470 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1472 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1473 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1481 for (
int i = 0;
i < 4;
i++) {
1482 for (
int j = 0; j < 4; j++) {
1483 int new_ui =
ui + j - 1;
1484 int new_vi = vi +
i - 1;
1485 int u_shift, v_shift;
1486 int new_ewi, new_ehi;
1488 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1489 face =
s->in_cubemap_face_order[direction];
1493 u_shift =
ceilf(ew * u_face);
1494 v_shift =
ceilf(eh * v_face);
1496 uf = 2.f * new_ui / ewi - 1.f;
1497 vf = 2.f * new_vi / ehi - 1.f;
1509 u_shift =
ceilf(ew * u_face);
1510 v_shift =
ceilf(eh * v_face);
1511 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1512 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1514 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1515 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1518 us[
i][j] = u_shift + new_ui;
1519 vs[
i][j] = v_shift + new_vi;
1540 const float scalew =
s->fout_pad > 0 ? 1.f - (float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1541 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1543 const float ew =
width;
1544 const float eh =
height / 6.f;
1546 const int face =
floorf(j / eh);
1548 const int v_shift =
ceilf(eh * face);
1549 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1552 const float vf =
rescale(j - v_shift, ehi);
1573 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1574 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1576 const float ew =
width / 6.f;
1579 const int face =
floorf(
i / ew);
1581 const int u_shift =
ceilf(ew * face);
1582 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1584 const float uf =
rescale(
i - u_shift, ewi);
1585 const float vf =
rescale(j, eh);
1606 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1608 const float scalew =
s->fin_pad > 0 ? 1.f - (float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1609 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1610 const float eh =
height / 6.f;
1611 const int ewi =
width;
1615 int direction, face;
1622 face =
s->in_cubemap_face_order[direction];
1623 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1625 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1626 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1634 for (
int i = 0;
i < 4;
i++) {
1635 for (
int j = 0; j < 4; j++) {
1636 int new_ui =
ui + j - 1;
1637 int new_vi = vi +
i - 1;
1641 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1642 face =
s->in_cubemap_face_order[direction];
1644 v_shift =
ceilf(eh * face);
1646 uf = 2.f * new_ui / ewi - 1.f;
1647 vf = 2.f * new_vi / ehi - 1.f;
1657 v_shift =
ceilf(eh * face);
1658 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1661 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1665 vs[
i][j] = v_shift + new_vi;
1686 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1688 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1689 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1690 const float ew =
width / 6.f;
1695 int direction, face;
1702 face =
s->in_cubemap_face_order[direction];
1703 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1705 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1706 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1714 for (
int i = 0;
i < 4;
i++) {
1715 for (
int j = 0; j < 4; j++) {
1716 int new_ui =
ui + j - 1;
1717 int new_vi = vi +
i - 1;
1721 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1722 face =
s->in_cubemap_face_order[direction];
1724 u_shift =
ceilf(ew * face);
1726 uf = 2.f * new_ui / ewi - 1.f;
1727 vf = 2.f * new_vi / ehi - 1.f;
1737 u_shift =
ceilf(ew * face);
1738 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1740 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1744 us[
i][j] = u_shift + new_ui;
1763 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
1764 s->flat_range[1] =
s->v_fov *
M_PI / 360.f;
1786 const float sin_phi =
sinf(phi);
1787 const float cos_phi =
cosf(phi);
1788 const float sin_theta =
sinf(theta);
1789 const float cos_theta =
cosf(theta);
1791 vec[0] = cos_theta * sin_phi;
1793 vec[2] = cos_theta * cos_phi;
1815 const float sin_phi =
sinf(phi);
1816 const float cos_phi =
cosf(phi);
1817 const float sin_theta =
sinf(theta);
1818 const float cos_theta =
cosf(theta);
1820 vec[0] = cos_theta * sin_phi;
1822 vec[2] = cos_theta * cos_phi;
1838 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1839 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1860 const float r = hypotf(x, y);
1861 const float theta =
atanf(
r) * 2.f;
1862 const float sin_theta =
sinf(theta);
1864 vec[0] = x /
r * sin_theta;
1865 vec[1] = y /
r * sin_theta;
1866 vec[2] =
cosf(theta);
1882 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1883 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1902 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1904 const float theta = acosf(vec[2]);
1905 const float r = tanf(theta * 0.5
f);
1906 const float c =
r / hypotf(vec[0], vec[1]);
1907 const float x = vec[0] *
c /
s->iflat_range[0];
1908 const float y = vec[1] *
c /
s->iflat_range[1];
1914 const int vi =
floorf(vf);
1918 *du = visible ? uf -
ui : 0.f;
1919 *dv = visible ? vf - vi : 0.f;
1921 for (
int i = 0;
i < 4;
i++) {
1922 for (
int j = 0; j < 4; j++) {
1942 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1943 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1964 const float r = hypotf(x, y);
1965 const float theta = asinf(
r) * 2.f;
1966 const float sin_theta =
sinf(theta);
1968 vec[0] = x /
r * sin_theta;
1969 vec[1] = y /
r * sin_theta;
1970 vec[2] =
cosf(theta);
2006 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2008 const float theta = acosf(vec[2]);
2009 const float r =
sinf(theta * 0.5
f);
2010 const float c =
r / hypotf(vec[0], vec[1]);
2011 const float x = vec[0] *
c /
s->iflat_range[0];
2012 const float y = vec[1] *
c /
s->iflat_range[1];
2018 const int vi =
floorf(vf);
2022 *du = visible ? uf -
ui : 0.f;
2023 *dv = visible ? vf - vi : 0.f;
2025 for (
int i = 0;
i < 4;
i++) {
2026 for (
int j = 0; j < 4; j++) {
2068 const float r = hypotf(x, y);
2069 const float theta = asinf(
r);
2071 vec[2] =
cosf(theta);
2117 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2119 const float theta = acosf(vec[2]);
2120 const float r =
sinf(theta);
2121 const float c =
r / hypotf(vec[0], vec[1]);
2122 const float x = vec[0] *
c /
s->iflat_range[0];
2123 const float y = vec[1] *
c /
s->iflat_range[1];
2129 const int vi =
floorf(vf);
2131 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2133 *du = visible ? uf -
ui : 0.f;
2134 *dv = visible ? vf - vi : 0.f;
2136 for (
int i = 0;
i < 4;
i++) {
2137 for (
int j = 0; j < 4; j++) {
2157 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2158 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2177 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2179 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2180 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2186 const int vi =
floorf(vf);
2192 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2194 for (
int i = 0;
i < 4;
i++) {
2195 for (
int j = 0; j < 4; j++) {
2218 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2221 const float theta = asinf(vec[1]) /
M_PI_2;
2227 const int vi =
floorf(vf);
2234 for (
int i = 0;
i < 4;
i++) {
2235 for (
int j = 0; j < 4; j++) {
2255 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2256 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2275 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2277 const float theta = acosf(vec[2]);
2278 const float r = tanf(theta);
2280 const float zf = vec[2];
2281 const float h = hypotf(vec[0], vec[1]);
2282 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2283 float uf = vec[0] *
c /
s->iflat_range[0];
2284 float vf = vec[1] *
c /
s->iflat_range[1];
2285 int visible,
ui, vi;
2293 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2298 for (
int i = 0;
i < 4;
i++) {
2299 for (
int j = 0; j < 4; j++) {
2322 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2324 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2325 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2331 const int vi =
floorf(vf);
2336 for (
int i = 0;
i < 4;
i++) {
2337 for (
int j = 0; j < 4; j++) {
2362 const float div =
expf(2.
f * y) + 1.f;
2364 const float sin_phi =
sinf(phi);
2365 const float cos_phi =
cosf(phi);
2366 const float sin_theta = 2.f *
expf(y) / div;
2367 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2369 vec[0] = -sin_theta * cos_phi;
2371 vec[2] = sin_theta * sin_phi;
2390 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2392 const float l = hypotf(vec[0], vec[1]);
2393 const float r = sqrtf(1.
f - vec[2]) /
M_SQRT2;
2394 const float d = l > 0.f ? l : 1.f;
2400 const int vi =
floorf(vf);
2405 for (
int i = 0;
i < 4;
i++) {
2406 for (
int j = 0; j < 4; j++) {
2431 const float l = hypotf(x, y);
2434 const float z = 2.f * l * sqrtf(1.
f - l * l);
2436 vec[0] = z * x / (l > 0.f ? l : 1.f);
2437 vec[1] = z * y / (l > 0.f ? l : 1.f);
2438 vec[2] = 1.f - 2.f * l * l;
2466 const float xx = x * x;
2467 const float yy = y * y;
2469 const float z = sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2472 const float b = 2.f * z * z - 1.f;
2474 const float aa =
a *
a;
2475 const float bb =
b *
b;
2477 const float w = sqrtf(1.
f - 2.
f * yy * z * z);
2479 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2481 vec[2] =
w * (bb - aa) / (aa + bb);
2500 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2502 const float theta =
atan2f(vec[0], vec[2]);
2504 const float z = sqrtf(1.
f + sqrtf(1.
f - vec[1] * vec[1]) *
cosf(theta * 0.5
f));
2505 const float x = sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2506 const float y = vec[1] / z;
2508 const float uf = (x + 1.f) *
width / 2.
f;
2509 const float vf = (y + 1.f) *
height / 2.
f;
2512 const int vi =
floorf(vf);
2517 for (
int i = 0;
i < 4;
i++) {
2518 for (
int j = 0; j < 4; j++) {
2544 const float sin_phi =
sinf(phi);
2545 const float cos_phi =
cosf(phi);
2546 const float sin_theta =
sinf(theta);
2547 const float cos_theta =
cosf(theta);
2549 vec[0] = cos_theta * sin_phi;
2551 vec[2] = cos_theta * cos_phi;
2570 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2572 const float theta = asinf(vec[1]);
2573 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2579 const int vi =
floorf(vf);
2584 for (
int i = 0;
i < 4;
i++) {
2585 for (
int j = 0; j < 4; j++) {
2664 const float pixel_pad = 2;
2665 const float u_pad = pixel_pad /
width;
2666 const float v_pad = pixel_pad /
height;
2668 int u_face, v_face, face;
2670 float l_x, l_y, l_z;
2672 float uf = (
i + 0.5f) /
width;
2673 float vf = (j + 0.5f) /
height;
2680 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2684 }
else if (uf >= 3.
f) {
2689 uf = fmodf(uf, 1.
f) - 0.5f;
2694 vf = (vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2696 if (uf >= -0.5
f && uf < 0.5
f) {
2701 if (vf >= -0.5
f && vf < 0.5
f) {
2707 face = u_face + 3 * v_face;
2765 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2767 const float pixel_pad = 2;
2768 const float u_pad = pixel_pad /
width;
2769 const float v_pad = pixel_pad /
height;
2773 int direction, face;
2778 face =
s->in_cubemap_face_order[direction];
2782 uf = M_2_PI *
atanf(uf) + 0.5f;
2783 vf = M_2_PI *
atanf(vf) + 0.5f;
2786 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2787 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2801 for (
int i = 0;
i < 4;
i++) {
2802 for (
int j = 0; j < 4; j++) {
2822 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2823 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2863 s->flat_range[0] =
s->h_fov / 180.f;
2864 s->flat_range[1] =
s->v_fov / 180.f;
2886 const float phi =
atan2f(vf, uf);
2887 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2889 const float sin_phi =
sinf(phi);
2890 const float cos_phi =
cosf(phi);
2891 const float sin_theta =
sinf(theta);
2892 const float cos_theta =
cosf(theta);
2894 vec[0] = cos_theta * cos_phi;
2895 vec[1] = cos_theta * sin_phi;
2912 s->iflat_range[0] =
s->ih_fov / 180.f;
2913 s->iflat_range[1] =
s->iv_fov / 180.f;
2932 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2934 const float h = hypotf(vec[0], vec[1]);
2935 const float lh =
h > 0.f ?
h : 1.f;
2938 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2939 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2941 const int visible = -0.5f < uf && uf < 0.5f && -0.5f < vf && vf < 0.5f;
2944 uf = (uf + 0.5f) *
width;
2945 vf = (vf + 0.5f) *
height;
2950 *du = visible ? uf -
ui : 0.f;
2951 *dv = visible ? vf - vi : 0.f;
2953 for (
int i = 0;
i < 4;
i++) {
2954 for (
int j = 0; j < 4; j++) {
2980 const float d =
s->h_fov;
2981 const float k = uf * uf / ((
d + 1.f) * (
d + 1.
f));
2982 const float dscr = k * k *
d *
d - (k + 1.f) * (k *
d *
d - 1.
f);
2983 const float clon = (-k *
d + sqrtf(dscr)) / (k + 1.
f);
2984 const float S = (
d + 1.f) / (
d + clon);
2985 const float lon =
atan2f(uf,
S * clon);
2986 const float lat =
atan2f(vf,
S);
3009 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3011 const float phi =
atan2f(vec[0], vec[2]);
3012 const float theta = asinf(vec[1]);
3014 const float d =
s->ih_fov;
3015 const float S = (
d + 1.f) / (
d +
cosf(phi));
3017 const float x =
S *
sinf(phi);
3018 const float y =
S * tanf(theta);
3024 const int vi =
floorf(vf);
3026 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3031 for (
int i = 0;
i < 4;
i++) {
3032 for (
int j = 0; j < 4; j++) {
3052 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3053 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3075 const float phi = uf;
3076 const float theta =
atanf(vf);
3078 const float sin_phi =
sinf(phi);
3079 const float cos_phi =
cosf(phi);
3080 const float sin_theta =
sinf(theta);
3081 const float cos_theta =
cosf(theta);
3083 vec[0] = cos_theta * sin_phi;
3085 vec[2] = cos_theta * cos_phi;
3101 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3102 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3121 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3123 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3124 const float theta = asinf(vec[1]);
3127 const float vf =
scale(tanf(theta) /
s->iflat_range[1],
height);
3130 const int vi =
floorf(vf);
3132 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3133 theta <=
M_PI *
s->iv_fov / 180.f &&
3134 theta >= -
M_PI *
s->iv_fov / 180.f;
3139 for (
int i = 0;
i < 4;
i++) {
3140 for (
int j = 0; j < 4; j++) {
3160 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3161 s->flat_range[1] =
s->v_fov / 180.f;
3177 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3178 s->iflat_range[1] =
s->iv_fov / 180.f;
3200 const float phi = uf;
3201 const float theta = asinf(vf);
3203 const float sin_phi =
sinf(phi);
3204 const float cos_phi =
cosf(phi);
3205 const float sin_theta =
sinf(theta);
3206 const float cos_theta =
cosf(theta);
3208 vec[0] = cos_theta * sin_phi;
3210 vec[2] = cos_theta * cos_phi;
3229 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3231 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3232 const float theta = asinf(vec[1]);
3238 const int vi =
floorf(vf);
3240 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3241 theta <=
M_PI *
s->iv_fov / 180.f &&
3242 theta >= -
M_PI *
s->iv_fov / 180.f;
3247 for (
int i = 0;
i < 4;
i++) {
3248 for (
int j = 0; j < 4; j++) {
3273 const float rh = hypotf(uf, vf);
3274 const float sinzz = 1.f - rh * rh;
3275 const float h = 1.f +
s->v_fov;
3276 const float sinz = (
h - sqrtf(sinzz)) / (
h / rh + rh /
h);
3277 const float sinz2 = sinz * sinz;
3280 const float cosz = sqrtf(1.
f - sinz2);
3282 const float theta = asinf(cosz);
3283 const float phi =
atan2f(uf, vf);
3285 const float sin_phi =
sinf(phi);
3286 const float cos_phi =
cosf(phi);
3287 const float sin_theta =
sinf(theta);
3288 const float cos_theta =
cosf(theta);
3290 vec[0] = cos_theta * sin_phi;
3291 vec[1] = cos_theta * cos_phi;
3317 const float uf = ((float)
i + 0.5
f) /
width;
3318 const float vf = ((float)j + 0.5
f) /
height;
3320 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3321 vec[1] = 1.f - vf * 2.f;
3322 vec[2] = 2.f *
fabsf(1.
f -
fabsf(1.
f - uf * 2.
f + vf)) - 1.f;
3341 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3343 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3344 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3345 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3346 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3349 float uf, vf, x, y, z;
3356 vf = 0.5f - y * 0.5f;
3358 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3359 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3360 uf = 0.25f * x + 0.25f;
3362 uf = 0.75f - 0.25f * x;
3374 for (
int i = 0;
i < 4;
i++) {
3375 for (
int j = 0; j < 4; j++) {
3395 s->iflat_range[0] =
s->ih_fov / 360.f;
3396 s->iflat_range[1] =
s->iv_fov / 360.f;
3415 const float ew =
width * 0.5f;
3418 const int ei =
i >= ew ?
i - ew :
i;
3419 const float m =
i >= ew ? 1.f : -1.f;
3421 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3422 const float vf =
s->flat_range[1] *
rescale(j, eh);
3424 const float h = hypotf(uf, vf);
3425 const float lh =
h > 0.f ?
h : 1.f;
3426 const float theta = m *
M_PI_2 * (1.f -
h);
3428 const float sin_theta =
sinf(theta);
3429 const float cos_theta =
cosf(theta);
3431 vec[0] = cos_theta * m * uf / lh;
3432 vec[1] = cos_theta * vf / lh;
3452 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3454 const float ew = (
width - 1) * 0.5
f;
3457 const float h = hypotf(vec[0], vec[1]);
3458 const float lh =
h > 0.f ?
h : 1.f;
3459 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3461 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3462 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3467 if (vec[2] >= 0.
f) {
3468 u_shift =
ceilf(ew);
3480 for (
int i = 0;
i < 4;
i++) {
3481 for (
int j = 0; j < 4; j++) {
3504 const float scale = 0.99f;
3505 float l_x, l_y, l_z;
3508 const float theta_range = M_PI_4;
3510 const int ew = 4 *
width / 5;
3514 const float theta =
rescale(j, eh) * theta_range /
scale;
3516 const float sin_phi =
sinf(phi);
3517 const float cos_phi =
cosf(phi);
3518 const float sin_theta =
sinf(theta);
3519 const float cos_theta =
cosf(theta);
3521 l_x = cos_theta * sin_phi;
3523 l_z = cos_theta * cos_phi;
3525 const int ew =
width / 5;
3526 const int eh =
height / 2;
3574 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3576 const float scale = 0.99f;
3578 const float phi =
atan2f(vec[0], vec[2]);
3579 const float theta = asinf(vec[1]);
3580 const float theta_range = M_PI_4;
3583 int u_shift, v_shift;
3587 if (theta > -theta_range && theta < theta_range) {
3595 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3603 uf = -vec[0] / vec[1];
3604 vf = -vec[2] / vec[1];
3607 uf = vec[0] / vec[1];
3608 vf = -vec[2] / vec[1];
3612 uf = 0.5f * ew * (uf *
scale + 1.f);
3613 vf = 0.5f * eh * (vf *
scale + 1.f);
3622 for (
int i = 0;
i < 4;
i++) {
3623 for (
int j = 0; j < 4; j++) {
3625 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3646 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3648 const float phi =
atan2f(vec[0], vec[2]);
3649 const float theta = asinf(vec[1]);
3651 const float theta_range = M_PI_4;
3654 int u_shift, v_shift;
3658 if (theta >= -theta_range && theta <= theta_range) {
3659 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3660 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3669 vf = theta / M_PI_4;
3672 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3674 uf = (uf * scalew + 1.f) *
width / 3.
f;
3675 vf = (vf * scaleh + 1.f) *
height / 4.
f;
3677 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3678 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3686 if (theta <= 0.f && theta >= -
M_PI_2 &&
3687 phi <= M_PI_2 && phi >= -
M_PI_2) {
3688 uf = -vec[0] / vec[1];
3689 vf = -vec[2] / vec[1];
3692 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3693 phi <= M_PI_2 && phi >= -
M_PI_2) {
3694 uf = vec[0] / vec[1];
3695 vf = -vec[2] / vec[1];
3696 v_shift =
height * 0.25f;
3697 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3698 uf = vec[0] / vec[1];
3699 vf = vec[2] / vec[1];
3703 uf = -vec[0] / vec[1];
3704 vf = vec[2] / vec[1];
3705 v_shift =
height * 0.75f;
3708 uf = 0.5f *
width / 3.f * (uf * scalew + 1.f);
3709 vf =
height * 0.25f * (vf * scaleh + 1.f) + v_offset;
3718 for (
int i = 0;
i < 4;
i++) {
3719 for (
int j = 0; j < 4; j++) {
3721 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3742 const float x = (
i + 0.5f) /
width;
3743 const float y = (j + 0.5f) /
height;
3744 float l_x, l_y, l_z;
3746 if (x < 2.
f / 3.
f) {
3747 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3748 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3750 const float back =
floorf(y * 2.
f);
3752 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3753 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3755 const float sin_phi =
sinf(phi);
3756 const float cos_phi =
cosf(phi);
3757 const float sin_theta =
sinf(theta);
3758 const float cos_theta =
cosf(theta);
3760 l_x = cos_theta * sin_phi;
3762 l_z = cos_theta * cos_phi;
3764 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3765 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3767 const int face =
floorf(y * 4.
f);
3778 l_x = (0.5f - uf) / scalew;
3780 l_z = (0.5f - vf) / scaleh;
3785 vf = 1.f - (vf - 0.5f);
3787 l_x = (0.5f - uf) / scalew;
3789 l_z = (-0.5f + vf) / scaleh;
3792 vf = y * 2.f - 0.5f;
3793 vf = 1.f - (1.f - vf);
3795 l_x = (0.5f - uf) / scalew;
3797 l_z = (0.5f - vf) / scaleh;
3800 vf = y * 2.f - 1.5f;
3802 l_x = (0.5f - uf) / scalew;
3804 l_z = (-0.5f + vf) / scaleh;
3830 const float x = (
i + 0.5f) /
width;
3831 const float y = (j + 0.5f) /
height;
3834 vec[0] = x * 4.f - 1.f;
3835 vec[1] = (y * 2.f - 1.f);
3837 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3838 y >= 0.375
f && y < 0.625
f) {
3839 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3840 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3842 }
else if (0.5
f <= x && x < 0.6875
f &&
3843 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3844 (0.375
f <= y && y < 0.625
f) ||
3845 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3847 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3848 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3849 }
else if (0.8125
f <= x && x < 1.
f &&
3850 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3851 (0.375
f <= y && y < 0.625
f) ||
3852 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3854 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3855 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3856 }
else if (0.
f <= y && y < 0.375
f &&
3857 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3858 (0.6875
f <= x && x < 0.8125
f) ||
3859 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3860 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3862 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3864 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3866 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3886 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3894 uf = (uf + 1.f) * 0.5
f;
3895 vf = (vf + 1.f) * 0.5
f;
3899 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3900 vf = 0.375f - 0.375f * vf;
3906 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3907 vf = 1.f - 0.375f * vf;
3910 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3911 uf = 0.1875f * uf + 0.8125f;
3914 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3915 uf = 0.1875f * uf + 0.5f;
3918 uf = 0.125f * uf + 0.6875f;
3919 vf = 0.25f * vf + 0.375f;
3932 for (
int i = 0;
i < 4;
i++) {
3933 for (
int j = 0; j < 4; j++) {
3958 const float ax =
fabsf(x);
3959 const float ay =
fabsf(y);
3961 vec[2] = 1.f - (ax + ay);
3962 if (ax + ay > 1.
f) {
3963 vec[0] = (1.f - ay) *
FFSIGN(x);
3964 vec[1] = (1.f - ax) *
FFSIGN(y);
3987 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4012 for (
int i = 0;
i < 4;
i++) {
4013 for (
int j = 0; j < 4; j++) {
4024 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4025 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4026 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4027 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4042 float rot_quaternion[2][4],
4043 const int rotation_order[3])
4045 const float yaw_rad = yaw *
M_PI / 180.f;
4046 const float pitch_rad = pitch *
M_PI / 180.f;
4047 const float roll_rad = roll *
M_PI / 180.f;
4049 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4050 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4051 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4052 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4053 const float sin_roll =
sinf(roll_rad * 0.5
f);
4054 const float cos_roll =
cosf(roll_rad * 0.5
f);
4059 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4060 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4061 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4076 static inline void rotate(
const float rot_quaternion[2][4],
4079 float qv[4],
temp[4], rqv[4];
4097 modifier[0] = h_flip ? -1.f : 1.f;
4098 modifier[1] = v_flip ? -1.f : 1.f;
4099 modifier[2] = d_flip ? -1.f : 1.f;
4102 static inline void mirror(
const float *modifier,
float *vec)
4104 vec[0] *= modifier[0];
4105 vec[1] *= modifier[1];
4106 vec[2] *= modifier[2];
4109 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4112 for (
int i = 0;
i < 4;
i++) {
4113 for (
int j = 0; j < 4; j++)
4114 u[
i][j] =
w - 1 -
u[
i][j];
4119 for (
int i = 0;
i < 4;
i++) {
4120 for (
int j = 0; j < 4; j++)
4121 v[
i][j] =
h - 1 - v[
i][j];
4128 const int pr_height =
s->pr_height[p];
4130 for (
int n = 0; n <
s->nb_threads; n++) {
4132 const int slice_start = (pr_height * n ) /
s->nb_threads;
4133 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4140 if (!
r->u[p] || !
r->v[p])
4149 if (sizeof_mask && !p) {
4165 *v_fov = d_fov * 0.5f;
4169 const float d = 0.5f * hypotf(
w,
h);
4170 const float l =
sinf(d_fov *
M_PI / 360.
f) /
d;
4172 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4173 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4175 if (d_fov > 180.
f) {
4176 *h_fov = 180.f - *h_fov;
4177 *v_fov = 180.f - *v_fov;
4183 const float d = 0.5f * hypotf(
w,
h);
4184 const float l =
d / (
sinf(d_fov *
M_PI / 720.
f));
4186 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4187 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4192 const float d = 0.5f * hypotf(
w,
h);
4193 const float l =
d / (tanf(d_fov *
M_PI / 720.
f));
4201 const float d = hypotf(
w * 0.5
f,
h);
4203 *h_fov = 0.5f *
w /
d * d_fov;
4204 *v_fov =
h /
d * d_fov;
4209 const float d = hypotf(
w,
h);
4211 *h_fov =
w /
d * d_fov;
4212 *v_fov =
h /
d * d_fov;
4218 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4219 const float d = hypotf(
w,
h);
4236 outw[0] = outw[3] =
w;
4238 outh[0] = outh[3] =
h;
4247 for (
int p = 0; p <
s->nb_allocated; p++) {
4248 const int max_value =
s->max_value;
4249 const int width =
s->pr_width[p];
4250 const int uv_linesize =
s->uv_linesize[p];
4251 const int height =
s->pr_height[p];
4252 const int in_width =
s->inplanewidth[p];
4253 const int in_height =
s->inplaneheight[p];
4254 const int slice_start = (
height * jobnr ) / nb_jobs;
4261 for (
int j = slice_start; j <
slice_end; j++) {
4263 int16_t *
u =
r->u[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4264 int16_t *v =
r->v[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4265 int16_t *ker =
r->ker[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4266 uint8_t *mask8 = p ?
NULL :
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4267 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4268 int in_mask, out_mask;
4270 if (
s->out_transpose)
4277 rotate(
s->rot_quaternion, vec);
4280 mirror(
s->output_mirror_modifier, vec);
4281 if (
s->in_transpose)
4282 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4284 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4285 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4287 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4289 if (!p &&
r->mask) {
4290 if (
s->mask_size == 1) {
4291 mask8[0] = 255 * (out_mask & in_mask);
4293 mask16[0] = max_value * (out_mask & in_mask);
4309 const int depth =
desc->comp[0].depth;
4310 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4311 float default_h_fov = 360.f;
4312 float default_v_fov = 180.f;
4313 float default_ih_fov = 360.f;
4314 float default_iv_fov = 180.f;
4319 int in_offset_h, in_offset_w;
4320 int out_offset_h, out_offset_w;
4325 s->max_value = (1 << depth) - 1;
4327 switch (
s->interp) {
4330 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4332 sizeof_uv =
sizeof(int16_t) *
s->elements;
4337 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4338 s->elements = 2 * 2;
4339 sizeof_uv =
sizeof(int16_t) *
s->elements;
4340 sizeof_ker =
sizeof(int16_t) *
s->elements;
4344 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4345 s->elements = 3 * 3;
4346 sizeof_uv =
sizeof(int16_t) *
s->elements;
4347 sizeof_ker =
sizeof(int16_t) *
s->elements;
4351 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4352 s->elements = 4 * 4;
4353 sizeof_uv =
sizeof(int16_t) *
s->elements;
4354 sizeof_ker =
sizeof(int16_t) *
s->elements;
4358 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4359 s->elements = 4 * 4;
4360 sizeof_uv =
sizeof(int16_t) *
s->elements;
4361 sizeof_ker =
sizeof(int16_t) *
s->elements;
4365 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4366 s->elements = 4 * 4;
4367 sizeof_uv =
sizeof(int16_t) *
s->elements;
4368 sizeof_ker =
sizeof(int16_t) *
s->elements;
4372 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4373 s->elements = 4 * 4;
4374 sizeof_uv =
sizeof(int16_t) *
s->elements;
4375 sizeof_ker =
sizeof(int16_t) *
s->elements;
4379 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4380 s->elements = 4 * 4;
4381 sizeof_uv =
sizeof(int16_t) *
s->elements;
4382 sizeof_ker =
sizeof(int16_t) *
s->elements;
4390 for (
int order = 0; order <
NB_RORDERS; order++) {
4391 const char c =
s->rorder[order];
4396 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4397 s->rotation_order[0] =
YAW;
4398 s->rotation_order[1] =
PITCH;
4399 s->rotation_order[2] =
ROLL;
4406 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4407 s->rotation_order[0] =
YAW;
4408 s->rotation_order[1] =
PITCH;
4409 s->rotation_order[2] =
ROLL;
4413 s->rotation_order[order] = rorder;
4416 switch (
s->in_stereo) {
4420 in_offset_w = in_offset_h = 0;
4441 s->in_width =
s->inplanewidth[0];
4442 s->in_height =
s->inplaneheight[0];
4447 default_ih_fov = 90.f;
4448 default_iv_fov = 45.f;
4455 default_ih_fov = 180.f;
4456 default_iv_fov = 180.f;
4461 if (
s->ih_fov == 0.f)
4462 s->ih_fov = default_ih_fov;
4464 if (
s->iv_fov == 0.f)
4465 s->iv_fov = default_iv_fov;
4467 if (
s->id_fov > 0.f)
4470 if (
s->in_transpose)
4471 FFSWAP(
int,
s->in_width,
s->in_height);
4787 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4788 s->out ==
FLAT &&
s->d_fov == 0.f) {
4790 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4791 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4792 s->out ==
FLAT &&
s->d_fov == 0.f) {
4794 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4795 }
else if (
s->width > 0 &&
s->height > 0) {
4798 }
else if (
s->width > 0 ||
s->height > 0) {
4802 if (
s->out_transpose)
4805 if (
s->in_transpose)
4815 default_h_fov = 90.f;
4816 default_v_fov = 45.f;
4823 default_h_fov = 180.f;
4824 default_v_fov = 180.f;
4830 if (
s->h_fov == 0.f)
4831 s->h_fov = default_h_fov;
4833 if (
s->v_fov == 0.f)
4834 s->v_fov = default_v_fov;
4840 err = prepare_out(
ctx);
4847 switch (
s->out_stereo) {
4849 out_offset_w = out_offset_h = 0;
4868 for (
int i = 0;
i < 4;
i++)
4878 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4879 s->nb_allocated = 1;
4880 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4882 s->nb_allocated = 2;
4883 s->map[0] =
s->map[3] = 0;
4884 s->map[1] =
s->map[2] = 1;
4887 if (!
s->slice_remap)
4888 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4889 if (!
s->slice_remap)
4892 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4893 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4899 s->rot_quaternion,
s->rotation_order);
4934 s->rot_quaternion[0][0] = 1.f;
4935 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4939 char *res,
int res_len,
int flags)
4944 if (
s->reset_rot <= 0)
4945 s->yaw =
s->pitch =
s->roll = 0.f;
4946 if (
s->reset_rot < 0)