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
254 #define DEFINE_REMAP1_LINE(bits, div) \
255 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
256 ptrdiff_t in_linesize, \
257 const int16_t *const u, const int16_t *const v, \
258 const int16_t *const ker) \
260 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
261 uint##bits##_t *d = (uint##bits##_t *)dst; \
263 in_linesize /= div; \
265 for (int x = 0; x < width; x++) \
266 d[x] = s[v[x] * in_linesize + u[x]]; \
278 #define DEFINE_REMAP(ws, bits) \
279 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
281 ThreadData *td = arg; \
282 const V360Context *s = ctx->priv; \
283 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
284 const AVFrame *in = td->in; \
285 AVFrame *out = td->out; \
287 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
288 for (int plane = 0; plane < s->nb_planes; plane++) { \
289 const unsigned map = s->map[plane]; \
290 const int in_linesize = in->linesize[plane]; \
291 const int out_linesize = out->linesize[plane]; \
292 const int uv_linesize = s->uv_linesize[plane]; \
293 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
294 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
295 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
296 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
297 const uint8_t *const src = in->data[plane] + \
298 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
299 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
300 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
301 const int width = s->pr_width[plane]; \
302 const int height = s->pr_height[plane]; \
304 const int slice_start = (height * jobnr ) / nb_jobs; \
305 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
307 for (int y = slice_start; y < slice_end && !mask; y++) { \
308 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
309 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
310 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
312 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
315 for (int y = slice_start; y < slice_end && mask; y++) { \
316 memcpy(dst + y * out_linesize, mask + \
317 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
334 #define DEFINE_REMAP_LINE(ws, bits, div) \
335 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
336 ptrdiff_t in_linesize, \
337 const int16_t *const u, const int16_t *const v, \
338 const int16_t *const ker) \
340 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
341 uint##bits##_t *d = (uint##bits##_t *)dst; \
343 in_linesize /= div; \
345 for (int x = 0; x < width; x++) { \
346 const int16_t *const uu = u + x * ws * ws; \
347 const int16_t *const vv = v + x * ws * ws; \
348 const int16_t *const kker = ker + x * ws * ws; \
351 for (int i = 0; i < ws; i++) { \
352 const int iws = i * ws; \
353 for (int j = 0; j < ws; j++) { \
354 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
358 d[x] = av_clip_uint##bits(tmp >> 14); \
373 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
376 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
379 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
386 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
405 int16_t *
u, int16_t *v, int16_t *ker)
408 const int j =
lrintf(du) + 1;
410 u[0] = rmap->
u[
i][j];
411 v[0] = rmap->
v[
i][j];
425 int16_t *
u, int16_t *v, int16_t *ker)
427 for (
int i = 0;
i < 2;
i++) {
428 for (
int j = 0; j < 2; j++) {
429 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
430 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
434 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
435 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
436 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
437 ker[3] =
lrintf( du * dv * 16385.
f);
448 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
449 coeffs[1] = -t * (t - 2.f);
450 coeffs[2] = t * (t - 1.f) * 0.5
f;
464 int16_t *
u, int16_t *v, int16_t *ker)
472 for (
int i = 0;
i < 3;
i++) {
473 for (
int j = 0; j < 3; j++) {
474 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
475 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
476 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
489 const float tt = t * t;
490 const float ttt = t * t * t;
492 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
493 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
494 coeffs[2] = t + tt / 2.f - ttt / 2.f;
495 coeffs[3] = - t / 6.f + ttt / 6.f;
509 int16_t *
u, int16_t *v, int16_t *ker)
517 for (
int i = 0;
i < 4;
i++) {
518 for (
int j = 0; j < 4; j++) {
519 u[
i * 4 + j] = rmap->
u[
i][j];
520 v[
i * 4 + j] = rmap->
v[
i][j];
521 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
536 for (
int i = 0;
i < 4;
i++) {
537 const float x =
M_PI * (t -
i + 1);
541 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
546 for (
int i = 0;
i < 4;
i++) {
562 int16_t *
u, int16_t *v, int16_t *ker)
570 for (
int i = 0;
i < 4;
i++) {
571 for (
int j = 0; j < 4; j++) {
572 u[
i * 4 + j] = rmap->
u[
i][j];
573 v[
i * 4 + j] = rmap->
v[
i][j];
574 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
587 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
588 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
589 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
590 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
604 int16_t *
u, int16_t *v, int16_t *ker)
612 for (
int i = 0;
i < 4;
i++) {
613 for (
int j = 0; j < 4; j++) {
614 u[
i * 4 + j] = rmap->
u[
i][j];
615 v[
i * 4 + j] = rmap->
v[
i][j];
616 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
631 for (
int i = 0;
i < 4;
i++) {
632 const float x = t - (
i - 1);
636 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
641 for (
int i = 0;
i < 4;
i++) {
657 int16_t *
u, int16_t *v, int16_t *ker)
665 for (
int i = 0;
i < 4;
i++) {
666 for (
int j = 0; j < 4; j++) {
667 u[
i * 4 + j] = rmap->
u[
i][j];
668 v[
i * 4 + j] = rmap->
v[
i][j];
669 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
684 float p0 = (6.f - 2.f *
b) / 6.
f,
685 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
686 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
687 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
688 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
689 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
690 q3 = (-
b - 6.f *
c) / 6.
f;
692 for (
int i = 0;
i < 4;
i++) {
693 const float x =
fabsf(t -
i + 1.
f);
695 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
696 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
697 }
else if (x < 2.
f) {
698 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
699 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
706 for (
int i = 0;
i < 4;
i++) {
722 int16_t *
u, int16_t *v, int16_t *ker)
730 for (
int i = 0;
i < 4;
i++) {
731 for (
int j = 0; j < 4; j++) {
732 u[
i * 4 + j] = rmap->
u[
i][j];
733 v[
i * 4 + j] = rmap->
v[
i][j];
734 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
749 const int res =
a %
b;
881 for (
int face = 0; face <
NB_FACES; face++) {
882 const char c =
s->in_forder[face];
887 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
892 if (direction == -1) {
894 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
898 s->in_cubemap_face_order[direction] = face;
901 for (
int face = 0; face <
NB_FACES; face++) {
902 const char c =
s->in_frot[face];
907 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
912 if (rotation == -1) {
914 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
918 s->in_cubemap_face_rotation[face] = rotation;
935 for (
int face = 0; face <
NB_FACES; face++) {
936 const char c =
s->out_forder[face];
941 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
946 if (direction == -1) {
948 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
952 s->out_cubemap_direction_order[face] = direction;
955 for (
int face = 0; face <
NB_FACES; face++) {
956 const char c =
s->out_frot[face];
961 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
966 if (rotation == -1) {
968 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
972 s->out_cubemap_face_rotation[face] = rotation;
1037 const float norm = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1057 float uf,
float vf,
int face,
1058 float *vec,
float scalew,
float scaleh)
1060 const int direction =
s->out_cubemap_direction_order[face];
1061 float l_x, l_y, l_z;
1068 switch (direction) {
1122 float *uf,
float *vf,
int *direction)
1124 const float phi =
atan2f(vec[0], vec[2]);
1125 const float theta = asinf(vec[1]);
1126 float phi_norm, theta_threshold;
1129 if (phi >= -M_PI_4 && phi < M_PI_4) {
1132 }
else if (phi >= -(
M_PI_2 + M_PI_4) && phi < -M_PI_4) {
1135 }
else if (phi >= M_PI_4 && phi <
M_PI_2 + M_PI_4) {
1140 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1143 theta_threshold =
atanf(
cosf(phi_norm));
1144 if (theta > theta_threshold) {
1146 }
else if (theta < -theta_threshold) {
1150 switch (*direction) {
1152 *uf = -vec[2] / vec[0];
1153 *vf = vec[1] / vec[0];
1156 *uf = -vec[2] / vec[0];
1157 *vf = -vec[1] / vec[0];
1160 *uf = -vec[0] / vec[1];
1161 *vf = -vec[2] / vec[1];
1164 *uf = vec[0] / vec[1];
1165 *vf = -vec[2] / vec[1];
1168 *uf = vec[0] / vec[2];
1169 *vf = vec[1] / vec[2];
1172 *uf = vec[0] / vec[2];
1173 *vf = -vec[1] / vec[2];
1179 face =
s->in_cubemap_face_order[*direction];
1196 float uf,
float vf,
int direction,
1197 float *new_uf,
float *new_vf,
int *face)
1216 *face =
s->in_cubemap_face_order[direction];
1219 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1223 }
else if (uf < -1.
f) {
1225 switch (direction) {
1259 }
else if (uf >= 1.
f) {
1261 switch (direction) {
1295 }
else if (vf < -1.
f) {
1297 switch (direction) {
1331 }
else if (vf >= 1.
f) {
1333 switch (direction) {
1373 *face =
s->in_cubemap_face_order[direction];
1391 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1392 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1394 const float ew =
width / 3.f;
1395 const float eh =
height / 2.f;
1397 const int u_face =
floorf(
i / ew);
1398 const int v_face =
floorf(j / eh);
1399 const int face = u_face + 3 * v_face;
1401 const int u_shift =
ceilf(ew * u_face);
1402 const int v_shift =
ceilf(eh * v_face);
1403 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1404 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1406 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.
f;
1407 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.
f;
1428 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1430 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1431 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1432 const float ew =
width / 3.f;
1433 const float eh =
height / 2.f;
1437 int direction, face;
1445 face =
s->in_cubemap_face_order[direction];
1448 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1449 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1451 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1452 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1460 for (
int i = 0;
i < 4;
i++) {
1461 for (
int j = 0; j < 4; j++) {
1462 int new_ui =
ui + j - 1;
1463 int new_vi = vi +
i - 1;
1464 int u_shift, v_shift;
1465 int new_ewi, new_ehi;
1467 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1468 face =
s->in_cubemap_face_order[direction];
1472 u_shift =
ceilf(ew * u_face);
1473 v_shift =
ceilf(eh * v_face);
1475 uf = 2.f * new_ui / ewi - 1.f;
1476 vf = 2.f * new_vi / ehi - 1.f;
1488 u_shift =
ceilf(ew * u_face);
1489 v_shift =
ceilf(eh * v_face);
1490 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1491 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1493 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1494 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1497 us[
i][j] = u_shift + new_ui;
1498 vs[
i][j] = v_shift + new_vi;
1519 const float scalew =
s->fout_pad > 0 ? 1.f - (float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1520 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1522 const float ew =
width;
1523 const float eh =
height / 6.f;
1525 const int face =
floorf(j / eh);
1527 const int v_shift =
ceilf(eh * face);
1528 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1530 const float uf = 2.f * (
i + 0.5f) / ew - 1.
f;
1531 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.
f;
1552 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1553 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1555 const float ew =
width / 6.f;
1558 const int face =
floorf(
i / ew);
1560 const int u_shift =
ceilf(ew * face);
1561 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1563 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.
f;
1564 const float vf = 2.f * (j + 0.5f) / eh - 1.
f;
1585 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1587 const float scalew =
s->fin_pad > 0 ? 1.f - (float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1588 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1589 const float eh =
height / 6.f;
1590 const int ewi =
width;
1594 int direction, face;
1601 face =
s->in_cubemap_face_order[direction];
1602 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1604 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1605 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1613 for (
int i = 0;
i < 4;
i++) {
1614 for (
int j = 0; j < 4; j++) {
1615 int new_ui =
ui + j - 1;
1616 int new_vi = vi +
i - 1;
1620 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1621 face =
s->in_cubemap_face_order[direction];
1623 v_shift =
ceilf(eh * face);
1625 uf = 2.f * new_ui / ewi - 1.f;
1626 vf = 2.f * new_vi / ehi - 1.f;
1636 v_shift =
ceilf(eh * face);
1637 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1640 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1644 vs[
i][j] = v_shift + new_vi;
1665 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1667 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1668 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1669 const float ew =
width / 6.f;
1674 int direction, face;
1681 face =
s->in_cubemap_face_order[direction];
1682 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1684 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1685 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1693 for (
int i = 0;
i < 4;
i++) {
1694 for (
int j = 0; j < 4; j++) {
1695 int new_ui =
ui + j - 1;
1696 int new_vi = vi +
i - 1;
1700 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1701 face =
s->in_cubemap_face_order[direction];
1703 u_shift =
ceilf(ew * face);
1705 uf = 2.f * new_ui / ewi - 1.f;
1706 vf = 2.f * new_vi / ehi - 1.f;
1716 u_shift =
ceilf(ew * face);
1717 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1719 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1723 us[
i][j] = u_shift + new_ui;
1745 const float phi = ((2.f *
i + 0.5f) /
width - 1.
f) *
M_PI;
1746 const float theta = ((2.f * j + 0.5f) /
height - 1.
f) *
M_PI_2;
1748 const float sin_phi =
sinf(phi);
1749 const float cos_phi =
cosf(phi);
1750 const float sin_theta =
sinf(theta);
1751 const float cos_theta =
cosf(theta);
1753 vec[0] = cos_theta * sin_phi;
1755 vec[2] = cos_theta * cos_phi;
1774 const float phi = ((2.f *
i + 0.5f) /
width - 1.
f) *
M_PI_2;
1775 const float theta = ((2.f * j + 0.5f) /
height - 1.
f) *
M_PI_2;
1777 const float sin_phi =
sinf(phi);
1778 const float cos_phi =
cosf(phi);
1779 const float sin_theta =
sinf(theta);
1780 const float cos_theta =
cosf(theta);
1782 vec[0] = cos_theta * sin_phi;
1784 vec[2] = cos_theta * cos_phi;
1800 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1801 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1820 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
1821 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
1822 const float r = hypotf(x, y);
1823 const float theta =
atanf(
r) * 2.f;
1824 const float sin_theta =
sinf(theta);
1826 vec[0] = x /
r * sin_theta;
1827 vec[1] = y /
r * sin_theta;
1828 vec[2] =
cosf(theta);
1846 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1847 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1866 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1868 const float theta = acosf(vec[2]);
1869 const float r = tanf(theta * 0.5
f);
1870 const float c =
r / hypotf(vec[0], vec[1]);
1871 const float x = vec[0] *
c /
s->iflat_range[0];
1872 const float y = vec[1] *
c /
s->iflat_range[1];
1874 const float uf = (x + 1.f) *
width / 2.
f;
1875 const float vf = (y + 1.f) *
height / 2.
f;
1878 const int vi =
floorf(vf);
1882 *du = visible ? uf -
ui : 0.f;
1883 *dv = visible ? vf - vi : 0.f;
1885 for (
int i = 0;
i < 4;
i++) {
1886 for (
int j = 0; j < 4; j++) {
1906 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1907 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1926 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
1927 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
1928 const float r = hypotf(x, y);
1929 const float theta = asinf(
r) * 2.f;
1930 const float sin_theta =
sinf(theta);
1932 vec[0] = x /
r * sin_theta;
1933 vec[1] = y /
r * sin_theta;
1934 vec[2] =
cosf(theta);
1972 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1974 const float theta = acosf(vec[2]);
1975 const float r =
sinf(theta * 0.5
f);
1976 const float c =
r / hypotf(vec[0], vec[1]);
1977 const float x = vec[0] *
c /
s->iflat_range[0];
1978 const float y = vec[1] *
c /
s->iflat_range[1];
1980 const float uf = (x + 1.f) *
width / 2.
f;
1981 const float vf = (y + 1.f) *
height / 2.
f;
1984 const int vi =
floorf(vf);
1988 *du = visible ? uf -
ui : 0.f;
1989 *dv = visible ? vf - vi : 0.f;
1991 for (
int i = 0;
i < 4;
i++) {
1992 for (
int j = 0; j < 4; j++) {
2032 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
2033 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
2034 const float r = hypotf(x, y);
2035 const float theta = asinf(
r);
2039 vec[2] =
cosf(theta);
2077 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2079 const float theta = acosf(vec[2]);
2080 const float r =
sinf(theta);
2081 const float c =
r / hypotf(vec[0], vec[1]);
2082 const float x = vec[0] *
c /
s->iflat_range[0];
2083 const float y = vec[1] *
c /
s->iflat_range[1];
2085 const float uf = (x + 1.f) *
width / 2.
f;
2086 const float vf = (y + 1.f) *
height / 2.
f;
2089 const int vi =
floorf(vf);
2091 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2093 *du = visible ? uf -
ui : 0.f;
2094 *dv = visible ? vf - vi : 0.f;
2096 for (
int i = 0;
i < 4;
i++) {
2097 for (
int j = 0; j < 4; j++) {
2120 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2122 const float phi =
atan2f(vec[0], vec[2]);
2123 const float theta = asinf(vec[1]);
2125 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2129 const int vi =
floorf(vf);
2134 for (
int i = 0;
i < 4;
i++) {
2135 for (
int j = 0; j < 4; j++) {
2158 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2160 const float phi =
atan2f(vec[0], vec[2]);
2161 const float theta = asinf(vec[1]);
2167 const int vi =
floorf(vf);
2174 for (
int i = 0;
i < 4;
i++) {
2175 for (
int j = 0; j < 4; j++) {
2195 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2196 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2215 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2217 const float theta = acosf(vec[2]);
2218 const float r = tanf(theta);
2220 const float zf = vec[2];
2221 const float h = hypotf(vec[0], vec[1]);
2222 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2223 float uf = vec[0] *
c /
s->iflat_range[0];
2224 float vf = vec[1] *
c /
s->iflat_range[1];
2225 int visible,
ui, vi;
2227 uf = zf >= 0.f ? (uf + 1.f) *
width / 2.
f : 0.
f;
2228 vf = zf >= 0.f ? (vf + 1.f) *
height / 2.
f : 0.
f;
2233 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2238 for (
int i = 0;
i < 4;
i++) {
2239 for (
int j = 0; j < 4; j++) {
2262 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2264 const float phi =
atan2f(vec[0], vec[2]);
2265 const float theta = vec[1];
2267 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2271 const int vi =
floorf(vf);
2276 for (
int i = 0;
i < 4;
i++) {
2277 for (
int j = 0; j < 4; j++) {
2301 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
M_PI;
2302 const float div =
expf(2.
f * y) + 1.f;
2304 const float sin_phi =
sinf(phi);
2305 const float cos_phi =
cosf(phi);
2306 const float sin_theta = 2.f *
expf(y) / div;
2307 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2309 vec[0] = -sin_theta * cos_phi;
2311 vec[2] = sin_theta * sin_phi;
2330 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2332 const float l = hypotf(vec[0], vec[1]);
2333 const float r = sqrtf(1.
f - vec[2]) /
M_SQRT2;
2335 const float uf = (1.f +
r * vec[0] / (l > 0.f ? l : 1.f)) *
width * 0.5f;
2336 const float vf = (1.f +
r * vec[1] / (l > 0.f ? l : 1.f)) *
height * 0.5f;
2339 const int vi =
floorf(vf);
2344 for (
int i = 0;
i < 4;
i++) {
2345 for (
int j = 0; j < 4; j++) {
2368 const float x = (2.f *
i + 1.f) /
width - 1.
f;
2369 const float y = (2.f * j + 1.f) /
height - 1.
f;
2370 const float l = hypotf(x, y);
2373 const float z = 2.f * l * sqrtf(1.
f - l * l);
2375 vec[0] = z * x / (l > 0.f ? l : 1.f);
2376 vec[1] = z * y / (l > 0.f ? l : 1.f);
2377 vec[2] = 1.f - 2.f * l * l;
2402 const float x = ((2.f *
i + 1.f) /
width - 1.
f);
2403 const float y = ((2.f * j + 1.f) /
height - 1.
f);
2405 const float xx = x * x;
2406 const float yy = y * y;
2408 const float z = sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2411 const float b = 2.f * z * z - 1.f;
2413 const float aa =
a *
a;
2414 const float bb =
b *
b;
2416 const float w = sqrtf(1.
f - 2.
f * yy * z * z);
2418 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2420 vec[2] =
w * (bb - aa) / (aa + bb);
2441 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2443 const float theta =
atan2f(vec[0], vec[2]);
2445 const float z = sqrtf(1.
f + sqrtf(1.
f - vec[1] * vec[1]) *
cosf(theta * 0.5
f));
2446 const float x = sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2447 const float y = vec[1] / z;
2449 const float uf = (x + 1.f) *
width / 2.
f;
2450 const float vf = (y + 1.f) *
height / 2.
f;
2453 const int vi =
floorf(vf);
2458 for (
int i = 0;
i < 4;
i++) {
2459 for (
int j = 0; j < 4; j++) {
2482 const float theta = ((2.f * j + 1.f) /
height - 1.
f) *
M_PI_2;
2483 const float phi = ((2.f *
i + 1.f) /
width - 1.
f) *
M_PI /
cosf(theta);
2485 const float sin_phi =
sinf(phi);
2486 const float cos_phi =
cosf(phi);
2487 const float sin_theta =
sinf(theta);
2488 const float cos_theta =
cosf(theta);
2490 vec[0] = cos_theta * sin_phi;
2492 vec[2] = cos_theta * cos_phi;
2513 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2515 const float theta = asinf(vec[1]);
2516 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2518 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2522 const int vi =
floorf(vf);
2527 for (
int i = 0;
i < 4;
i++) {
2528 for (
int j = 0; j < 4; j++) {
2607 const float pixel_pad = 2;
2608 const float u_pad = pixel_pad /
width;
2609 const float v_pad = pixel_pad /
height;
2611 int u_face, v_face, face;
2613 float l_x, l_y, l_z;
2615 float uf = (
i + 0.5f) /
width;
2616 float vf = (j + 0.5f) /
height;
2623 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2627 }
else if (uf >= 3.
f) {
2632 uf = fmodf(uf, 1.
f) - 0.5f;
2637 vf = (vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2639 if (uf >= -0.5
f && uf < 0.5
f) {
2644 if (vf >= -0.5
f && vf < 0.5
f) {
2650 face = u_face + 3 * v_face;
2710 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2712 const float pixel_pad = 2;
2713 const float u_pad = pixel_pad /
width;
2714 const float v_pad = pixel_pad /
height;
2718 int direction, face;
2723 face =
s->in_cubemap_face_order[direction];
2727 uf = M_2_PI *
atanf(uf) + 0.5f;
2728 vf = M_2_PI *
atanf(vf) + 0.5f;
2731 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2732 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2746 for (
int i = 0;
i < 4;
i++) {
2747 for (
int j = 0; j < 4; j++) {
2767 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2768 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2787 const float l_x =
s->flat_range[0] * ((2.f *
i + 0.5f) /
width - 1.
f);
2788 const float l_y =
s->flat_range[1] * ((2.f * j + 0.5f) /
height - 1.
f);
2810 s->flat_range[0] =
s->h_fov / 180.f;
2811 s->flat_range[1] =
s->v_fov / 180.f;
2830 const float uf =
s->flat_range[0] * ((2.f *
i) /
width - 1.
f);
2831 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.
f);
2833 const float phi =
atan2f(vf, uf);
2834 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2836 const float sin_phi =
sinf(phi);
2837 const float cos_phi =
cosf(phi);
2838 const float sin_theta =
sinf(theta);
2839 const float cos_theta =
cosf(theta);
2841 vec[0] = cos_theta * cos_phi;
2842 vec[1] = cos_theta * sin_phi;
2861 s->iflat_range[0] =
s->ih_fov / 180.f;
2862 s->iflat_range[1] =
s->iv_fov / 180.f;
2881 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2883 const float h = hypotf(vec[0], vec[1]);
2884 const float lh =
h > 0.f ?
h : 1.f;
2887 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2888 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2890 const int visible = hypotf(uf, vf) <= 0.5f;
2893 uf = (uf + 0.5f) *
width;
2894 vf = (vf + 0.5f) *
height;
2899 *du = visible ? uf -
ui : 0.f;
2900 *dv = visible ? vf - vi : 0.f;
2902 for (
int i = 0;
i < 4;
i++) {
2903 for (
int j = 0; j < 4; j++) {
2926 const float uf = ((2.f *
i + 1.f) /
width - 1.
f);
2927 const float vf = ((2.f * j + 1.f) /
height - 1.
f);
2929 const float d =
s->h_fov;
2930 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2931 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2932 const float clon = (-k * d + sqrtf(dscr)) / (k + 1.
f);
2933 const float S = (d + 1.f) / (d + clon);
2934 const float lon =
atan2f(uf,
S * clon);
2935 const float lat =
atan2f(vf,
S);
2960 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2962 const float phi =
atan2f(vec[0], vec[2]);
2963 const float theta = asinf(vec[1]);
2965 const float d =
s->ih_fov;
2966 const float S = (d + 1.f) / (d +
cosf(phi));
2968 const float x =
S *
sinf(phi);
2969 const float y =
S * tanf(theta);
2971 const float uf = (x + 1.f) *
width / 2.
f;
2972 const float vf = (y + 1.f) *
height / 2.
f;
2975 const int vi =
floorf(vf);
2977 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
2982 for (
int i = 0;
i < 4;
i++) {
2983 for (
int j = 0; j < 4; j++) {
3003 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3004 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3023 const float uf =
s->flat_range[0] * ((2.f *
i + 1.f) /
width - 1.
f);
3024 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.
f);
3026 const float phi = uf;
3027 const float theta =
atanf(vf);
3029 const float sin_phi =
sinf(phi);
3030 const float cos_phi =
cosf(phi);
3031 const float sin_theta =
sinf(theta);
3032 const float cos_theta =
cosf(theta);
3034 vec[0] = cos_theta * sin_phi;
3036 vec[2] = cos_theta * cos_phi;
3054 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3055 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3074 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3076 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3077 const float theta = asinf(vec[1]);
3079 const float uf = (phi + 1.f) * (
width - 1) / 2.f;
3080 const float vf = (tanf(theta) /
s->iflat_range[1] + 1.f) *
height / 2.
f;
3083 const int vi =
floorf(vf);
3085 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3086 theta <=
M_PI *
s->iv_fov / 180.f &&
3087 theta >= -
M_PI *
s->iv_fov / 180.f;
3092 for (
int i = 0;
i < 4;
i++) {
3093 for (
int j = 0; j < 4; j++) {
3116 const float uf = ((2.f *
i + 1.f) /
width - 1.
f);
3117 const float vf = ((2.f * j + 1.f) /
height - 1.
f);
3118 const float rh = hypotf(uf, vf);
3119 const float sinzz = 1.f - rh * rh;
3120 const float h = 1.f +
s->v_fov;
3121 const float sinz = (
h - sqrtf(sinzz)) / (
h / rh + rh /
h);
3122 const float sinz2 = sinz * sinz;
3125 const float cosz = sqrtf(1.
f - sinz2);
3127 const float theta = asinf(cosz);
3128 const float phi =
atan2f(uf, vf);
3130 const float sin_phi =
sinf(phi);
3131 const float cos_phi =
cosf(phi);
3132 const float sin_theta =
sinf(theta);
3133 const float cos_theta =
cosf(theta);
3135 vec[0] = cos_theta * sin_phi;
3136 vec[1] = cos_theta * cos_phi;
3162 const float uf = (float)
i /
width;
3163 const float vf = (float)j /
height;
3165 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3166 vec[1] = 1.f - vf * 2.f;
3167 vec[2] = 2.f *
fabsf(1.
f -
fabsf(1.
f - uf * 2.
f + vf)) - 1.f;
3188 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3190 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3191 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3192 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3193 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3196 float uf, vf, x, y, z;
3203 vf = 0.5f - y * 0.5f;
3205 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3206 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3207 uf = 0.25f * x + 0.25f;
3209 uf = 0.75f - 0.25f * x;
3221 for (
int i = 0;
i < 4;
i++) {
3222 for (
int j = 0; j < 4; j++) {
3245 const float ew =
width / 2.f;
3248 const int ei =
i >= ew ?
i - ew :
i;
3249 const float m =
i >= ew ? 1.f : -1.f;
3251 const float uf =
s->flat_range[0] * ((2.f * ei) / ew - 1.
f);
3252 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) / eh - 1.
f);
3254 const float h = hypotf(uf, vf);
3255 const float lh =
h > 0.f ?
h : 1.f;
3256 const float theta = m *
M_PI_2 * (1.f -
h);
3258 const float sin_theta =
sinf(theta);
3259 const float cos_theta =
cosf(theta);
3261 vec[0] = cos_theta * m * uf / lh;
3262 vec[1] = cos_theta * vf / lh;
3284 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3286 const float ew =
width / 2.f;
3289 const float h = hypotf(vec[0], vec[1]);
3290 const float lh =
h > 0.f ?
h : 1.f;
3291 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3293 float uf = (theta * (vec[0] / lh) /
s->iflat_range[0] + 0.5f) * ew;
3294 float vf = (theta * (vec[1] / lh) /
s->iflat_range[1] + 0.5f) * eh;
3299 if (vec[2] >= 0.
f) {
3300 u_shift =
ceilf(ew);
3312 for (
int i = 0;
i < 4;
i++) {
3313 for (
int j = 0; j < 4; j++) {
3336 const float scale = 0.99f;
3337 float l_x, l_y, l_z;
3340 const float theta_range = M_PI_4;
3342 const int ew = 4 *
width / 5;
3345 const float phi = ((2.f *
i) / ew - 1.
f) *
M_PI / scale;
3346 const float theta = ((2.f * j) / eh - 1.
f) * theta_range / scale;
3348 const float sin_phi =
sinf(phi);
3349 const float cos_phi =
cosf(phi);
3350 const float sin_theta =
sinf(theta);
3351 const float cos_theta =
cosf(theta);
3353 l_x = cos_theta * sin_phi;
3355 l_z = cos_theta * cos_phi;
3357 const int ew =
width / 5;
3358 const int eh =
height / 2;
3363 uf = 2.f * (
i - 4 * ew) / ew - 1.
f;
3364 vf = 2.f * (j ) / eh - 1.
f;
3373 uf = 2.f * (
i - 4 * ew) / ew - 1.
f;
3374 vf = 2.f * (j - eh) / eh - 1.
f;
3408 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3410 const float scale = 0.99f;
3412 const float phi =
atan2f(vec[0], vec[2]);
3413 const float theta = asinf(vec[1]);
3414 const float theta_range = M_PI_4;
3417 int u_shift, v_shift;
3421 if (theta > -theta_range && theta < theta_range) {
3428 uf = (phi /
M_PI * scale + 1.f) * ew / 2.
f;
3429 vf = (theta / theta_range * scale + 1.f) * eh / 2.
f;
3437 uf = -vec[0] / vec[1];
3438 vf = -vec[2] / vec[1];
3441 uf = vec[0] / vec[1];
3442 vf = -vec[2] / vec[1];
3446 uf = 0.5f * ew * (uf * scale + 1.f);
3447 vf = 0.5f * eh * (vf * scale + 1.f);
3456 for (
int i = 0;
i < 4;
i++) {
3457 for (
int j = 0; j < 4; j++) {
3459 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3480 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3482 const float phi =
atan2f(vec[0], vec[2]);
3483 const float theta = asinf(vec[1]);
3485 const float theta_range = M_PI_4;
3488 int u_shift, v_shift;
3492 if (theta >= -theta_range && theta <= theta_range) {
3493 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3494 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3503 vf = theta / M_PI_4;
3506 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3508 uf = (uf * scalew + 1.f) *
width / 3.
f;
3509 vf = (vf * scaleh + 1.f) *
height / 4.
f;
3511 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3512 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3520 if (theta <= 0.f && theta >= -
M_PI_2 &&
3521 phi <= M_PI_2 && phi >= -
M_PI_2) {
3522 uf = -vec[0] / vec[1];
3523 vf = -vec[2] / vec[1];
3526 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3527 phi <= M_PI_2 && phi >= -
M_PI_2) {
3528 uf = vec[0] / vec[1];
3529 vf = -vec[2] / vec[1];
3530 v_shift =
height * 0.25f;
3531 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3532 uf = vec[0] / vec[1];
3533 vf = vec[2] / vec[1];
3537 uf = -vec[0] / vec[1];
3538 vf = vec[2] / vec[1];
3539 v_shift =
height * 0.75f;
3542 uf = 0.5f *
width / 3.f * (uf * scalew + 1.f);
3543 vf =
height * 0.25f * (vf * scaleh + 1.f) + v_offset;
3552 for (
int i = 0;
i < 4;
i++) {
3553 for (
int j = 0; j < 4; j++) {
3555 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3576 const float x = (
i + 0.5f) /
width;
3577 const float y = (j + 0.5f) /
height;
3578 float l_x, l_y, l_z;
3580 if (x < 2.
f / 3.
f) {
3581 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3582 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3584 const float back =
floorf(y * 2.
f);
3586 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3587 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3589 const float sin_phi =
sinf(phi);
3590 const float cos_phi =
cosf(phi);
3591 const float sin_theta =
sinf(theta);
3592 const float cos_theta =
cosf(theta);
3594 l_x = cos_theta * sin_phi;
3596 l_z = cos_theta * cos_phi;
3598 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3599 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3601 const int face =
floorf(y * 4.
f);
3612 l_x = (0.5f - uf) / scalew;
3614 l_z = (0.5f - vf) / scaleh;
3619 vf = 1.f - (vf - 0.5f);
3621 l_x = (0.5f - uf) / scalew;
3623 l_z = (-0.5f + vf) / scaleh;
3626 vf = y * 2.f - 0.5f;
3627 vf = 1.f - (1.f - vf);
3629 l_x = (0.5f - uf) / scalew;
3631 l_z = (0.5f - vf) / scaleh;
3634 vf = y * 2.f - 1.5f;
3636 l_x = (0.5f - uf) / scalew;
3638 l_z = (-0.5f + vf) / scaleh;
3666 const float x = (
i + 0.5f) /
width;
3667 const float y = (j + 0.5f) /
height;
3670 vec[0] = x * 4.f - 1.f;
3671 vec[1] = (y * 2.f - 1.f);
3673 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3674 y >= 0.375
f && y < 0.625
f) {
3675 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3676 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3678 }
else if (0.5
f <= x && x < 0.6875
f &&
3679 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3680 (0.375
f <= y && y < 0.625
f) ||
3681 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3683 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3684 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3685 }
else if (0.8125
f <= x && x < 1.
f &&
3686 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3687 (0.375
f <= y && y < 0.625
f) ||
3688 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3690 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3691 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3692 }
else if (0.
f <= y && y < 0.375
f &&
3693 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3694 (0.6875
f <= x && x < 0.8125
f) ||
3695 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3696 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3698 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3700 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3702 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3724 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3732 uf = (uf + 1.f) * 0.5
f;
3733 vf = (vf + 1.f) * 0.5
f;
3737 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3738 vf = 0.375f - 0.375f * vf;
3744 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3745 vf = 1.f - 0.375f * vf;
3748 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3749 uf = 0.1875f * uf + 0.8125f;
3752 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3753 uf = 0.1875f * uf + 0.5f;
3756 uf = 0.125f * uf + 0.6875f;
3757 vf = 0.25f * vf + 0.375f;
3770 for (
int i = 0;
i < 4;
i++) {
3771 for (
int j = 0; j < 4; j++) {
3794 const float x = ((
i + 0.5f) /
width) * 2.f - 1.f;
3795 const float y = ((j + 0.5f) /
height) * 2.f - 1.f;
3796 const float ax =
fabsf(x);
3797 const float ay =
fabsf(y);
3799 vec[2] = 1.f - (ax + ay);
3800 if (ax + ay > 1.
f) {
3801 vec[0] = (1.f - ay) *
FFSIGN(x);
3802 vec[1] = (1.f - ax) *
FFSIGN(y);
3827 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3843 uf = uf * 0.5f + 0.5f;
3844 vf = vf * 0.5f + 0.5f;
3855 for (
int i = 0;
i < 4;
i++) {
3856 for (
int j = 0; j < 4; j++) {
3867 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
3868 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
3869 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
3870 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
3885 float rot_quaternion[2][4],
3886 const int rotation_order[3])
3888 const float yaw_rad = yaw *
M_PI / 180.f;
3889 const float pitch_rad = pitch *
M_PI / 180.f;
3890 const float roll_rad = roll *
M_PI / 180.f;
3892 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
3893 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
3894 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
3895 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
3896 const float sin_roll =
sinf(roll_rad * 0.5
f);
3897 const float cos_roll =
cosf(roll_rad * 0.5
f);
3902 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
3903 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
3904 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
3919 static inline void rotate(
const float rot_quaternion[2][4],
3922 float qv[4],
temp[4], rqv[4];
3940 modifier[0] = h_flip ? -1.f : 1.f;
3941 modifier[1] = v_flip ? -1.f : 1.f;
3942 modifier[2] = d_flip ? -1.f : 1.f;
3945 static inline void mirror(
const float *modifier,
float *vec)
3947 vec[0] *= modifier[0];
3948 vec[1] *= modifier[1];
3949 vec[2] *= modifier[2];
3952 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
3955 for (
int i = 0;
i < 4;
i++) {
3956 for (
int j = 0; j < 4; j++)
3957 u[
i][j] =
w - 1 -
u[
i][j];
3962 for (
int i = 0;
i < 4;
i++) {
3963 for (
int j = 0; j < 4; j++)
3964 v[
i][j] =
h - 1 - v[
i][j];
3971 const int pr_height =
s->pr_height[p];
3973 for (
int n = 0; n <
s->nb_threads; n++) {
3975 const int slice_start = (pr_height * n ) /
s->nb_threads;
3976 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
3983 if (!
r->u[p] || !
r->v[p])
3992 if (sizeof_mask && !p) {
4008 const float d = 0.5f * hypotf(
w,
h);
4009 const float l =
sinf(d_fov *
M_PI / 360.
f) / d;
4011 *h_fov = asinf(
w * 0.5 * l) * 360.f /
M_PI;
4012 *v_fov = asinf(
h * 0.5 * l) * 360.f /
M_PI;
4014 if (d_fov > 180.
f) {
4015 *h_fov = 180.f - *h_fov;
4016 *v_fov = 180.f - *v_fov;
4022 const float d = 0.5f * hypotf(
w,
h);
4023 const float l = d / (
sinf(d_fov *
M_PI / 720.
f));
4025 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4026 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4031 const float d = 0.5f * hypotf(
w,
h);
4032 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
4040 const float d = 0.5f * hypotf(
w * 0.5
f,
h);
4042 *h_fov = d /
w * 2.f * d_fov;
4043 *v_fov = d /
h * d_fov;
4048 const float d = 0.5f * hypotf(
w,
h);
4050 *h_fov = d /
w * d_fov;
4051 *v_fov = d /
h * d_fov;
4057 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4058 const float d = hypotf(
w,
h);
4075 outw[0] = outw[3] =
w;
4077 outh[0] = outh[3] =
h;
4086 for (
int p = 0; p <
s->nb_allocated; p++) {
4087 const int max_value =
s->max_value;
4088 const int width =
s->pr_width[p];
4089 const int uv_linesize =
s->uv_linesize[p];
4090 const int height =
s->pr_height[p];
4091 const int in_width =
s->inplanewidth[p];
4092 const int in_height =
s->inplaneheight[p];
4093 const int slice_start = (
height * jobnr ) / nb_jobs;
4100 for (
int j = slice_start; j <
slice_end; j++) {
4102 int16_t *
u =
r->u[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4103 int16_t *v =
r->v[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4104 int16_t *ker =
r->ker[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4105 uint8_t *mask8 = p ?
NULL :
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4106 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4107 int in_mask, out_mask;
4109 if (
s->out_transpose)
4114 rotate(
s->rot_quaternion, vec);
4117 mirror(
s->output_mirror_modifier, vec);
4118 if (
s->in_transpose)
4119 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4121 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4122 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4124 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4126 if (!p &&
r->mask) {
4127 if (
s->mask_size == 1) {
4128 mask8[0] = 255 * (out_mask & in_mask);
4130 mask16[0] = max_value * (out_mask & in_mask);
4146 const int depth =
desc->comp[0].depth;
4147 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4152 int in_offset_h, in_offset_w;
4153 int out_offset_h, out_offset_w;
4158 s->max_value = (1 << depth) - 1;
4160 switch (
s->interp) {
4163 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4165 sizeof_uv =
sizeof(int16_t) *
s->elements;
4170 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4171 s->elements = 2 * 2;
4172 sizeof_uv =
sizeof(int16_t) *
s->elements;
4173 sizeof_ker =
sizeof(int16_t) *
s->elements;
4177 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4178 s->elements = 3 * 3;
4179 sizeof_uv =
sizeof(int16_t) *
s->elements;
4180 sizeof_ker =
sizeof(int16_t) *
s->elements;
4184 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4185 s->elements = 4 * 4;
4186 sizeof_uv =
sizeof(int16_t) *
s->elements;
4187 sizeof_ker =
sizeof(int16_t) *
s->elements;
4191 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4192 s->elements = 4 * 4;
4193 sizeof_uv =
sizeof(int16_t) *
s->elements;
4194 sizeof_ker =
sizeof(int16_t) *
s->elements;
4198 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4199 s->elements = 4 * 4;
4200 sizeof_uv =
sizeof(int16_t) *
s->elements;
4201 sizeof_ker =
sizeof(int16_t) *
s->elements;
4205 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4206 s->elements = 4 * 4;
4207 sizeof_uv =
sizeof(int16_t) *
s->elements;
4208 sizeof_ker =
sizeof(int16_t) *
s->elements;
4212 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4213 s->elements = 4 * 4;
4214 sizeof_uv =
sizeof(int16_t) *
s->elements;
4215 sizeof_ker =
sizeof(int16_t) *
s->elements;
4223 for (
int order = 0; order <
NB_RORDERS; order++) {
4224 const char c =
s->rorder[order];
4229 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4230 s->rotation_order[0] =
YAW;
4231 s->rotation_order[1] =
PITCH;
4232 s->rotation_order[2] =
ROLL;
4239 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4240 s->rotation_order[0] =
YAW;
4241 s->rotation_order[1] =
PITCH;
4242 s->rotation_order[2] =
ROLL;
4246 s->rotation_order[order] = rorder;
4249 switch (
s->in_stereo) {
4253 in_offset_w = in_offset_h = 0;
4274 s->in_width =
s->inplanewidth[0];
4275 s->in_height =
s->inplaneheight[0];
4277 if (
s->id_fov > 0.f)
4280 if (
s->in_transpose)
4281 FFSWAP(
int,
s->in_width,
s->in_height);
4585 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4586 s->out ==
FLAT &&
s->d_fov == 0.f) {
4588 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4589 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4590 s->out ==
FLAT &&
s->d_fov == 0.f) {
4592 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4593 }
else if (
s->width > 0 &&
s->height > 0) {
4596 }
else if (
s->width > 0 ||
s->height > 0) {
4600 if (
s->out_transpose)
4603 if (
s->in_transpose)
4614 err = prepare_out(
ctx);
4621 switch (
s->out_stereo) {
4623 out_offset_w = out_offset_h = 0;
4642 for (
int i = 0;
i < 4;
i++)
4652 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4653 s->nb_allocated = 1;
4654 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4656 s->nb_allocated = 2;
4657 s->map[0] =
s->map[3] = 0;
4658 s->map[1] =
s->map[2] = 1;
4661 if (!
s->slice_remap)
4662 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4663 if (!
s->slice_remap)
4666 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4667 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4673 s->rot_quaternion,
s->rotation_order);
4707 char *res,
int res_len,
int flags)
4712 s->yaw =
s->pitch =
s->roll = 0.f;
4725 s->rot_quaternion[0][0] = 1.f;
4726 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4735 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4738 for (
int p = 0; p <
s->nb_allocated; p++) {
4777 .priv_class = &v360_class,