Go to the documentation of this file.
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
247 #define DEFINE_REMAP1_LINE(bits, div) \
248 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
249 ptrdiff_t in_linesize, \
250 const int16_t *const u, const int16_t *const v, \
251 const int16_t *const ker) \
253 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
254 uint##bits##_t *d = (uint##bits##_t *)dst; \
256 in_linesize /= div; \
258 for (int x = 0; x < width; x++) \
259 d[x] = s[v[x] * in_linesize + u[x]]; \
271 #define DEFINE_REMAP(ws, bits) \
272 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
274 ThreadData *td = arg; \
275 const V360Context *s = ctx->priv; \
276 const AVFrame *in = td->in; \
277 AVFrame *out = td->out; \
279 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
280 for (int plane = 0; plane < s->nb_planes; plane++) { \
281 const unsigned map = s->map[plane]; \
282 const int in_linesize = in->linesize[plane]; \
283 const int out_linesize = out->linesize[plane]; \
284 const int uv_linesize = s->uv_linesize[plane]; \
285 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
286 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
287 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
288 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
289 const uint8_t *const src = in->data[plane] + \
290 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
291 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
292 const uint8_t *mask = plane == 3 ? s->mask : NULL; \
293 const int width = s->pr_width[plane]; \
294 const int height = s->pr_height[plane]; \
296 const int slice_start = (height * jobnr ) / nb_jobs; \
297 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
299 for (int y = slice_start; y < slice_end && !mask; y++) { \
300 const int16_t *const u = s->u[map] + y * uv_linesize * ws * ws; \
301 const int16_t *const v = s->v[map] + y * uv_linesize * ws * ws; \
302 const int16_t *const ker = s->ker[map] + y * uv_linesize * ws * ws; \
304 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
307 for (int y = slice_start; y < slice_end && mask; y++) { \
308 memcpy(dst + y * out_linesize, mask + y * width * (bits >> 3), width * (bits >> 3)); \
325 #define DEFINE_REMAP_LINE(ws, bits, div) \
326 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
327 ptrdiff_t in_linesize, \
328 const int16_t *const u, const int16_t *const v, \
329 const int16_t *const ker) \
331 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
332 uint##bits##_t *d = (uint##bits##_t *)dst; \
334 in_linesize /= div; \
336 for (int x = 0; x < width; x++) { \
337 const int16_t *const uu = u + x * ws * ws; \
338 const int16_t *const vv = v + x * ws * ws; \
339 const int16_t *const kker = ker + x * ws * ws; \
342 for (int i = 0; i < ws; i++) { \
343 for (int j = 0; j < ws; j++) { \
344 tmp += kker[i * ws + j] * s[vv[i * ws + j] * in_linesize + uu[i * ws + j]]; \
348 d[x] = av_clip_uint##bits(tmp >> 14); \
363 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
366 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
369 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
375 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
394 int16_t *
u, int16_t *v, int16_t *ker)
397 const int j =
lrintf(du) + 1;
399 u[0] = rmap->
u[
i][j];
400 v[0] = rmap->
v[
i][j];
414 int16_t *
u, int16_t *v, int16_t *ker)
416 for (
int i = 0;
i < 2;
i++) {
417 for (
int j = 0; j < 2; j++) {
418 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
419 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
423 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
424 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
425 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
426 ker[3] =
lrintf( du * dv * 16385.
f);
437 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
438 coeffs[1] = -t * (t - 2.f);
439 coeffs[2] = t * (t - 1.f) * 0.5
f;
453 int16_t *
u, int16_t *v, int16_t *ker)
461 for (
int i = 0;
i < 3;
i++) {
462 for (
int j = 0; j < 3; j++) {
463 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
464 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
465 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
478 const float tt = t * t;
479 const float ttt = t * t * t;
481 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
482 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
483 coeffs[2] = t + tt / 2.f - ttt / 2.f;
484 coeffs[3] = - t / 6.f + ttt / 6.f;
498 int16_t *
u, int16_t *v, int16_t *ker)
506 for (
int i = 0;
i < 4;
i++) {
507 for (
int j = 0; j < 4; j++) {
508 u[
i * 4 + j] = rmap->
u[
i][j];
509 v[
i * 4 + j] = rmap->
v[
i][j];
510 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
525 for (
int i = 0;
i < 4;
i++) {
526 const float x =
M_PI * (t -
i + 1);
530 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
535 for (
int i = 0;
i < 4;
i++) {
551 int16_t *
u, int16_t *v, int16_t *ker)
559 for (
int i = 0;
i < 4;
i++) {
560 for (
int j = 0; j < 4; j++) {
561 u[
i * 4 + j] = rmap->
u[
i][j];
562 v[
i * 4 + j] = rmap->
v[
i][j];
563 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
576 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
577 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
578 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
579 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
593 int16_t *
u, int16_t *v, int16_t *ker)
601 for (
int i = 0;
i < 4;
i++) {
602 for (
int j = 0; j < 4; j++) {
603 u[
i * 4 + j] = rmap->
u[
i][j];
604 v[
i * 4 + j] = rmap->
v[
i][j];
605 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
620 for (
int i = 0;
i < 4;
i++) {
621 const float x = t - (
i - 1);
625 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
630 for (
int i = 0;
i < 4;
i++) {
646 int16_t *
u, int16_t *v, int16_t *ker)
654 for (
int i = 0;
i < 4;
i++) {
655 for (
int j = 0; j < 4; j++) {
656 u[
i * 4 + j] = rmap->
u[
i][j];
657 v[
i * 4 + j] = rmap->
v[
i][j];
658 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
673 const int res =
a %
b;
692 return 2 *
h - 1 - y;
805 for (
int face = 0; face <
NB_FACES; face++) {
806 const char c =
s->in_forder[face];
811 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
816 if (direction == -1) {
818 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
822 s->in_cubemap_face_order[direction] = face;
825 for (
int face = 0; face <
NB_FACES; face++) {
826 const char c =
s->in_frot[face];
831 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
836 if (rotation == -1) {
838 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
842 s->in_cubemap_face_rotation[face] = rotation;
859 for (
int face = 0; face <
NB_FACES; face++) {
860 const char c =
s->out_forder[face];
865 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
870 if (direction == -1) {
872 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
876 s->out_cubemap_direction_order[face] = direction;
879 for (
int face = 0; face <
NB_FACES; face++) {
880 const char c =
s->out_frot[face];
885 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
890 if (rotation == -1) {
892 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
896 s->out_cubemap_face_rotation[face] = rotation;
961 const float norm = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
981 float uf,
float vf,
int face,
982 float *vec,
float scalew,
float scaleh)
984 const int direction =
s->out_cubemap_direction_order[face];
1046 float *uf,
float *vf,
int *direction)
1048 const float phi =
atan2f(vec[0], vec[2]);
1049 const float theta = asinf(vec[1]);
1050 float phi_norm, theta_threshold;
1053 if (phi >= -M_PI_4 && phi < M_PI_4) {
1056 }
else if (phi >= -(
M_PI_2 + M_PI_4) && phi < -M_PI_4) {
1059 }
else if (phi >= M_PI_4 && phi <
M_PI_2 + M_PI_4) {
1064 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1067 theta_threshold =
atanf(
cosf(phi_norm));
1068 if (theta > theta_threshold) {
1070 }
else if (theta < -theta_threshold) {
1074 switch (*direction) {
1076 *uf = -vec[2] / vec[0];
1077 *vf = vec[1] / vec[0];
1080 *uf = -vec[2] / vec[0];
1081 *vf = -vec[1] / vec[0];
1084 *uf = -vec[0] / vec[1];
1085 *vf = -vec[2] / vec[1];
1088 *uf = vec[0] / vec[1];
1089 *vf = -vec[2] / vec[1];
1092 *uf = vec[0] / vec[2];
1093 *vf = vec[1] / vec[2];
1096 *uf = vec[0] / vec[2];
1097 *vf = -vec[1] / vec[2];
1103 face =
s->in_cubemap_face_order[*direction];
1106 (*uf) *=
s->input_mirror_modifier[0];
1107 (*vf) *=
s->input_mirror_modifier[1];
1123 float uf,
float vf,
int direction,
1124 float *new_uf,
float *new_vf,
int *face)
1143 *face =
s->in_cubemap_face_order[direction];
1146 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1150 }
else if (uf < -1.
f) {
1152 switch (direction) {
1186 }
else if (uf >= 1.
f) {
1188 switch (direction) {
1222 }
else if (vf < -1.
f) {
1224 switch (direction) {
1258 }
else if (vf >= 1.
f) {
1260 switch (direction) {
1300 *face =
s->in_cubemap_face_order[direction];
1318 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1319 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1321 const float ew =
width / 3.f;
1322 const float eh =
height / 2.f;
1324 const int u_face = floorf(
i / ew);
1325 const int v_face = floorf(j / eh);
1326 const int face = u_face + 3 * v_face;
1328 const int u_shift = ceilf(ew * u_face);
1329 const int v_shift = ceilf(eh * v_face);
1330 const int ewi = ceilf(ew * (u_face + 1)) - u_shift;
1331 const int ehi = ceilf(eh * (v_face + 1)) - v_shift;
1333 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.
f;
1334 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.
f;
1355 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1357 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1358 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1359 const float ew =
width / 3.f;
1360 const float eh =
height / 2.f;
1364 int direction, face;
1372 face =
s->in_cubemap_face_order[direction];
1375 ewi = ceilf(ew * (u_face + 1)) - ceilf(ew * u_face);
1376 ehi = ceilf(eh * (v_face + 1)) - ceilf(eh * v_face);
1378 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1379 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1387 for (
int i = 0;
i < 4;
i++) {
1388 for (
int j = 0; j < 4; j++) {
1389 int new_ui =
ui + j - 1;
1390 int new_vi = vi +
i - 1;
1391 int u_shift, v_shift;
1392 int new_ewi, new_ehi;
1394 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1395 face =
s->in_cubemap_face_order[direction];
1399 u_shift = ceilf(ew * u_face);
1400 v_shift = ceilf(eh * v_face);
1402 uf = 2.f * new_ui / ewi - 1.f;
1403 vf = 2.f * new_vi / ehi - 1.f;
1415 u_shift = ceilf(ew * u_face);
1416 v_shift = ceilf(eh * v_face);
1417 new_ewi = ceilf(ew * (u_face + 1)) - u_shift;
1418 new_ehi = ceilf(eh * (v_face + 1)) - v_shift;
1420 new_ui = av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1421 new_vi = av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1424 us[
i][j] = u_shift + new_ui;
1425 vs[
i][j] = v_shift + new_vi;
1446 const float scalew =
s->fout_pad > 0 ? 1.f - (float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1447 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1449 const float ew =
width;
1450 const float eh =
height / 6.f;
1452 const int face = floorf(j / eh);
1454 const int v_shift = ceilf(eh * face);
1455 const int ehi = ceilf(eh * (face + 1)) - v_shift;
1457 const float uf = 2.f * (
i + 0.5f) / ew - 1.
f;
1458 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.
f;
1479 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1480 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1482 const float ew =
width / 6.f;
1485 const int face = floorf(
i / ew);
1487 const int u_shift = ceilf(ew * face);
1488 const int ewi = ceilf(ew * (face + 1)) - u_shift;
1490 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.
f;
1491 const float vf = 2.f * (j + 0.5f) / eh - 1.
f;
1512 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1514 const float scalew =
s->fin_pad > 0 ? 1.f - (float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1515 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1516 const float eh =
height / 6.f;
1517 const int ewi =
width;
1521 int direction, face;
1528 face =
s->in_cubemap_face_order[direction];
1529 ehi = ceilf(eh * (face + 1)) - ceilf(eh * face);
1531 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1532 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1540 for (
int i = 0;
i < 4;
i++) {
1541 for (
int j = 0; j < 4; j++) {
1542 int new_ui =
ui + j - 1;
1543 int new_vi = vi +
i - 1;
1547 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1548 face =
s->in_cubemap_face_order[direction];
1550 v_shift = ceilf(eh * face);
1552 uf = 2.f * new_ui / ewi - 1.f;
1553 vf = 2.f * new_vi / ehi - 1.f;
1563 v_shift = ceilf(eh * face);
1564 new_ehi = ceilf(eh * (face + 1)) - v_shift;
1566 new_ui = av_clip(
lrintf(0.5
f * ewi * (uf + 1.
f)), 0, ewi - 1);
1567 new_vi = av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1571 vs[
i][j] = v_shift + new_vi;
1592 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1594 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1595 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1596 const float ew =
width / 6.f;
1601 int direction, face;
1608 face =
s->in_cubemap_face_order[direction];
1609 ewi = ceilf(ew * (face + 1)) - ceilf(ew * face);
1611 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1612 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1620 for (
int i = 0;
i < 4;
i++) {
1621 for (
int j = 0; j < 4; j++) {
1622 int new_ui =
ui + j - 1;
1623 int new_vi = vi +
i - 1;
1627 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1628 face =
s->in_cubemap_face_order[direction];
1630 u_shift = ceilf(ew * face);
1632 uf = 2.f * new_ui / ewi - 1.f;
1633 vf = 2.f * new_vi / ehi - 1.f;
1643 u_shift = ceilf(ew * face);
1644 new_ewi = ceilf(ew * (face + 1)) - u_shift;
1646 new_ui = av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1647 new_vi = av_clip(
lrintf(0.5
f * ehi * (vf + 1.
f)), 0, ehi - 1);
1650 us[
i][j] = u_shift + new_ui;
1672 const float phi = ((2.f *
i + 0.5f) /
width - 1.
f) *
M_PI;
1673 const float theta = ((2.f * j + 0.5f) /
height - 1.
f) *
M_PI_2;
1675 const float sin_phi =
sinf(phi);
1676 const float cos_phi =
cosf(phi);
1677 const float sin_theta =
sinf(theta);
1678 const float cos_theta =
cosf(theta);
1680 vec[0] = cos_theta * sin_phi;
1682 vec[2] = cos_theta * cos_phi;
1701 const float phi = ((2.f *
i + 0.5f) /
width - 1.
f) *
M_PI_2;
1702 const float theta = ((2.f * j + 0.5f) /
height - 1.
f) *
M_PI_2;
1704 const float sin_phi =
sinf(phi);
1705 const float cos_phi =
cosf(phi);
1706 const float sin_theta =
sinf(theta);
1707 const float cos_theta =
cosf(theta);
1709 vec[0] = cos_theta * sin_phi;
1711 vec[2] = cos_theta * cos_phi;
1727 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1728 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1747 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
1748 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
1749 const float r = hypotf(x, y);
1750 const float theta =
atanf(
r) * 2.f;
1751 const float sin_theta =
sinf(theta);
1753 vec[0] = x /
r * sin_theta;
1754 vec[1] = y /
r * sin_theta;
1755 vec[2] =
cosf(theta);
1773 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1774 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1793 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1795 const float theta = acosf(vec[2]);
1796 const float r = tanf(theta * 0.5
f);
1797 const float c =
r / hypotf(vec[0], vec[1]);
1798 const float x = vec[0] *
c /
s->iflat_range[0] *
s->input_mirror_modifier[0];
1799 const float y = vec[1] *
c /
s->iflat_range[1] *
s->input_mirror_modifier[1];
1801 const float uf = (x + 1.f) *
width / 2.
f;
1802 const float vf = (y + 1.f) *
height / 2.
f;
1804 const int ui = floorf(uf);
1805 const int vi = floorf(vf);
1809 *du = visible ? uf -
ui : 0.f;
1810 *dv = visible ? vf - vi : 0.f;
1812 for (
int i = 0;
i < 4;
i++) {
1813 for (
int j = 0; j < 4; j++) {
1814 us[
i][j] = visible ? av_clip(
ui + j - 1, 0,
width - 1) : 0;
1815 vs[
i][j] = visible ? av_clip(vi +
i - 1, 0,
height - 1) : 0;
1836 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1838 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
1839 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
1841 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
1844 const int ui = floorf(uf);
1845 const int vi = floorf(vf);
1850 for (
int i = 0;
i < 4;
i++) {
1851 for (
int j = 0; j < 4; j++) {
1874 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1876 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
1877 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
1882 const int ui = floorf(uf);
1883 const int vi = floorf(vf);
1890 for (
int i = 0;
i < 4;
i++) {
1891 for (
int j = 0; j < 4; j++) {
1892 us[
i][j] = av_clip(
ui + j - 1, 0,
width - 1);
1893 vs[
i][j] = av_clip(vi +
i - 1, 0,
height - 1);
1911 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
1912 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
1931 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1933 const float theta = acosf(vec[2]);
1934 const float r = tanf(theta);
1936 const float zf = vec[2];
1937 const float h = hypotf(vec[0], vec[1]);
1938 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
1939 float uf = vec[0] *
c /
s->iflat_range[0] *
s->input_mirror_modifier[0];
1940 float vf = vec[1] *
c /
s->iflat_range[1] *
s->input_mirror_modifier[1];
1941 int visible,
ui, vi;
1943 uf = zf >= 0.f ? (uf + 1.f) *
width / 2.
f : 0.
f;
1944 vf = zf >= 0.f ? (vf + 1.f) *
height / 2.
f : 0.
f;
1949 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
1954 for (
int i = 0;
i < 4;
i++) {
1955 for (
int j = 0; j < 4; j++) {
1956 us[
i][j] = visible ? av_clip(
ui + j - 1, 0,
width - 1) : 0;
1957 vs[
i][j] = visible ? av_clip(vi +
i - 1, 0,
height - 1) : 0;
1978 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1980 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
1981 const float theta = vec[1] *
s->input_mirror_modifier[1];
1983 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
1984 const float vf = (av_clipf(logf((1.
f + theta) / (1.
f - theta)) / (2.
f *
M_PI), -1.
f, 1.
f) + 1.f) *
height / 2.
f;
1986 const int ui = floorf(uf);
1987 const int vi = floorf(vf);
1992 for (
int i = 0;
i < 4;
i++) {
1993 for (
int j = 0; j < 4; j++) {
1994 us[
i][j] = av_clip(
ui + j - 1, 0,
width - 1);
1995 vs[
i][j] = av_clip(vi +
i - 1, 0,
height - 1);
2017 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
M_PI;
2018 const float div =
expf(2.
f * y) + 1.f;
2020 const float sin_phi =
sinf(phi);
2021 const float cos_phi =
cosf(phi);
2022 const float sin_theta = 2.f *
expf(y) / div;
2023 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2025 vec[0] = -sin_theta * cos_phi;
2027 vec[2] = sin_theta * sin_phi;
2046 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2048 const float l = hypotf(vec[0], vec[1]);
2049 const float r = sqrtf(1.
f - vec[2]) /
M_SQRT2;
2051 const float uf = (1.f +
r * vec[0] *
s->input_mirror_modifier[0] / (l > 0.f ? l : 1.f)) *
width * 0.5f;
2052 const float vf = (1.f +
r * vec[1] *
s->input_mirror_modifier[1] / (l > 0.f ? l : 1.f)) *
height * 0.5f;
2054 const int ui = floorf(uf);
2055 const int vi = floorf(vf);
2060 for (
int i = 0;
i < 4;
i++) {
2061 for (
int j = 0; j < 4; j++) {
2062 us[
i][j] = av_clip(
ui + j - 1, 0,
width - 1);
2063 vs[
i][j] = av_clip(vi +
i - 1, 0,
height - 1);
2084 const float x = (2.f *
i + 1.f) /
width - 1.
f;
2085 const float y = (2.f * j + 1.f) /
height - 1.
f;
2086 const float l = hypotf(x, y);
2089 const float z = 2.f * l * sqrtf(1.
f - l * l);
2091 vec[0] = z * x / (l > 0.f ? l : 1.f);
2092 vec[1] = z * y / (l > 0.f ? l : 1.f);
2093 vec[2] = 1.f - 2.f * l * l;
2118 const float x = ((2.f *
i + 1.f) /
width - 1.
f);
2119 const float y = ((2.f * j + 1.f) /
height - 1.
f);
2121 const float xx = x * x;
2122 const float yy = y * y;
2124 const float z = sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2127 const float b = 2.f * z * z - 1.f;
2129 const float aa =
a *
a;
2130 const float bb =
b *
b;
2132 const float w = sqrtf(1.
f - 2.
f * yy * z * z);
2134 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2136 vec[2] =
w * (bb - aa) / (aa + bb);
2157 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2159 const float theta =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
2161 const float z = sqrtf(1.
f + sqrtf(1.
f - vec[1] * vec[1]) *
cosf(theta * 0.5
f));
2162 const float x = sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2163 const float y = vec[1] / z *
s->input_mirror_modifier[1];
2165 const float uf = (x + 1.f) *
width / 2.
f;
2166 const float vf = (y + 1.f) *
height / 2.
f;
2168 const int ui = floorf(uf);
2169 const int vi = floorf(vf);
2174 for (
int i = 0;
i < 4;
i++) {
2175 for (
int j = 0; j < 4; j++) {
2176 us[
i][j] = av_clip(
ui + j - 1, 0,
width - 1);
2177 vs[
i][j] = av_clip(vi +
i - 1, 0,
height - 1);
2198 const float theta = ((2.f * j + 1.f) /
height - 1.
f) *
M_PI_2;
2199 const float phi = ((2.f *
i + 1.f) /
width - 1.
f) *
M_PI /
cosf(theta);
2201 const float sin_phi =
sinf(phi);
2202 const float cos_phi =
cosf(phi);
2203 const float sin_theta =
sinf(theta);
2204 const float cos_theta =
cosf(theta);
2206 vec[0] = cos_theta * sin_phi;
2208 vec[2] = cos_theta * cos_phi;
2229 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2231 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
2232 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0] *
cosf(theta);
2234 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2237 const int ui = floorf(uf);
2238 const int vi = floorf(vf);
2243 for (
int i = 0;
i < 4;
i++) {
2244 for (
int j = 0; j < 4; j++) {
2245 us[
i][j] = av_clip(
ui + j - 1, 0,
width - 1);
2246 vs[
i][j] = av_clip(vi +
i - 1, 0,
height - 1);
2264 if (
s->ih_flip &&
s->iv_flip) {
2271 }
else if (
s->ih_flip) {
2278 }
else if (
s->iv_flip) {
2355 const float pixel_pad = 2;
2356 const float u_pad = pixel_pad /
width;
2357 const float v_pad = pixel_pad /
height;
2359 int u_face, v_face, face;
2361 float l_x, l_y, l_z;
2363 float uf = (
i + 0.5f) /
width;
2364 float vf = (j + 0.5f) /
height;
2371 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2375 }
else if (uf >= 3.
f) {
2379 u_face = floorf(uf);
2380 uf = fmodf(uf, 1.
f) - 0.5f;
2384 v_face = floorf(vf * 2.
f);
2385 vf = (vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2387 if (uf >= -0.5
f && uf < 0.5
f) {
2392 if (vf >= -0.5
f && vf < 0.5
f) {
2398 face = u_face + 3 * v_face;
2458 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2460 const float pixel_pad = 2;
2461 const float u_pad = pixel_pad /
width;
2462 const float v_pad = pixel_pad /
height;
2466 int direction, face;
2471 face =
s->in_cubemap_face_order[direction];
2475 uf = M_2_PI *
atanf(uf) + 0.5f;
2476 vf = M_2_PI *
atanf(vf) + 0.5f;
2479 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2480 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2494 for (
int i = 0;
i < 4;
i++) {
2495 for (
int j = 0; j < 4; j++) {
2496 us[
i][j] = av_clip(
ui + j - 1, 0,
width - 1);
2497 vs[
i][j] = av_clip(vi +
i - 1, 0,
height - 1);
2515 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2516 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2535 const float l_x =
s->flat_range[0] * ((2.f *
i + 0.5f) /
width - 1.
f);
2536 const float l_y =
s->flat_range[1] * ((2.f * j + 0.5f) /
height - 1.
f);
2558 s->flat_range[0] =
s->h_fov / 180.f;
2559 s->flat_range[1] =
s->v_fov / 180.f;
2578 const float uf =
s->flat_range[0] * ((2.f *
i) /
width - 1.
f);
2579 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.
f);
2581 const float phi =
atan2f(vf, uf);
2582 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2584 const float sin_phi =
sinf(phi);
2585 const float cos_phi =
cosf(phi);
2586 const float sin_theta =
sinf(theta);
2587 const float cos_theta =
cosf(theta);
2589 vec[0] = cos_theta * cos_phi;
2590 vec[1] = cos_theta * sin_phi;
2609 s->iflat_range[0] =
s->ih_fov / 180.f;
2610 s->iflat_range[1] =
s->iv_fov / 180.f;
2629 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2631 const float h = hypotf(vec[0], vec[1]);
2632 const float lh =
h > 0.f ?
h : 1.f;
2635 float uf = vec[0] / lh * phi *
s->input_mirror_modifier[0] /
s->iflat_range[0];
2636 float vf = vec[1] / lh * phi *
s->input_mirror_modifier[1] /
s->iflat_range[1];
2638 const int visible = hypotf(uf, vf) <= 0.5f;
2641 uf = (uf + 0.5f) *
width;
2642 vf = (vf + 0.5f) *
height;
2647 *du = visible ? uf -
ui : 0.f;
2648 *dv = visible ? vf - vi : 0.f;
2650 for (
int i = 0;
i < 4;
i++) {
2651 for (
int j = 0; j < 4; j++) {
2652 us[
i][j] = visible ? av_clip(
ui + j - 1, 0,
width - 1) : 0;
2653 vs[
i][j] = visible ? av_clip(vi +
i - 1, 0,
height - 1) : 0;
2674 const float uf = ((2.f *
i + 1.f) /
width - 1.
f);
2675 const float vf = ((2.f * j + 1.f) /
height - 1.
f);
2677 const float d =
s->h_fov;
2678 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2679 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2680 const float clon = (-k * d + sqrtf(dscr)) / (k + 1.
f);
2681 const float S = (d + 1.f) / (d + clon);
2682 const float lon =
atan2f(uf,
S * clon);
2683 const float lat =
atan2f(vf,
S);
2708 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2710 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
2711 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
2713 const float d =
s->ih_fov;
2714 const float S = (d + 1.f) / (d +
cosf(phi));
2716 const float x =
S *
sinf(phi);
2717 const float y =
S * tanf(theta);
2719 const float uf = (x + 1.f) *
width / 2.
f;
2720 const float vf = (y + 1.f) *
height / 2.
f;
2722 const int ui = floorf(uf);
2723 const int vi = floorf(vf);
2725 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
2730 for (
int i = 0;
i < 4;
i++) {
2731 for (
int j = 0; j < 4; j++) {
2732 us[
i][j] = visible ? av_clip(
ui + j - 1, 0,
width - 1) : 0;
2733 vs[
i][j] = visible ? av_clip(vi +
i - 1, 0,
height - 1) : 0;
2751 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
2752 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2771 const float uf =
s->flat_range[0] * ((2.f *
i + 1.f) /
width - 1.
f);
2772 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.
f);
2774 const float phi = uf;
2775 const float theta =
atanf(vf);
2777 const float sin_phi =
sinf(phi);
2778 const float cos_phi =
cosf(phi);
2779 const float sin_theta =
sinf(theta);
2780 const float cos_theta =
cosf(theta);
2782 vec[0] = cos_theta * sin_phi;
2784 vec[2] = cos_theta * cos_phi;
2802 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
2803 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2822 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2824 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0] /
s->iflat_range[0];
2825 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
2827 const float uf = (phi + 1.f) * (
width - 1) / 2.f;
2828 const float vf = (tanf(theta) /
s->iflat_range[1] + 1.f) *
height / 2.
f;
2830 const int ui = floorf(uf);
2831 const int vi = floorf(vf);
2833 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
2834 theta <=
M_PI *
s->iv_fov / 180.f &&
2835 theta >= -
M_PI *
s->iv_fov / 180.f;
2840 for (
int i = 0;
i < 4;
i++) {
2841 for (
int j = 0; j < 4; j++) {
2842 us[
i][j] = visible ? av_clip(
ui + j - 1, 0,
width - 1) : 0;
2843 vs[
i][j] = visible ? av_clip(vi +
i - 1, 0,
height - 1) : 0;
2864 const float uf = ((2.f *
i + 1.f) /
width - 1.
f);
2865 const float vf = ((2.f * j + 1.f) /
height - 1.
f);
2866 const float rh = hypotf(uf, vf);
2867 const float sinzz = 1.f - rh * rh;
2868 const float h = 1.f +
s->v_fov;
2869 const float sinz = (
h - sqrtf(sinzz)) / (
h / rh + rh /
h);
2870 const float sinz2 = sinz * sinz;
2873 const float cosz = sqrtf(1.
f - sinz2);
2875 const float theta = asinf(cosz);
2876 const float phi =
atan2f(uf, vf);
2878 const float sin_phi =
sinf(phi);
2879 const float cos_phi =
cosf(phi);
2880 const float sin_theta =
sinf(theta);
2881 const float cos_theta =
cosf(theta);
2883 vec[0] = cos_theta * sin_phi;
2885 vec[2] = cos_theta * cos_phi;
2911 const float uf = (float)
i /
width;
2912 const float vf = (float)j /
height;
2914 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
2915 vec[1] = 1.f - vf * 2.f;
2916 vec[2] = 2.f * fabsf(1.
f - fabsf(1.
f - uf * 2.
f + vf)) - 1.f;
2937 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2939 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
2940 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
2941 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
2942 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
2945 float uf, vf, x, y, z;
2952 vf = 0.5f - y * 0.5f *
s->input_mirror_modifier[1];
2954 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
2955 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
2956 uf = 0.25f * x *
s->input_mirror_modifier[0] + 0.25f;
2958 uf = 0.75f - 0.25f * x *
s->input_mirror_modifier[0];
2970 for (
int i = 0;
i < 4;
i++) {
2971 for (
int j = 0; j < 4; j++) {
2994 const float ew =
width / 2.f;
2997 const int ei =
i >= ew ?
i - ew :
i;
2998 const float m =
i >= ew ? 1.f : -1.f;
3000 const float uf =
s->flat_range[0] * ((2.f * ei) / ew - 1.
f);
3001 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) / eh - 1.
f);
3003 const float h = hypotf(uf, vf);
3004 const float lh =
h > 0.f ?
h : 1.f;
3005 const float theta = m *
M_PI_2 * (1.f -
h);
3007 const float sin_theta =
sinf(theta);
3008 const float cos_theta =
cosf(theta);
3010 vec[0] = cos_theta * m * uf / lh;
3011 vec[1] = cos_theta * vf / lh;
3033 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3035 const float ew =
width / 2.f;
3038 const float h = hypotf(vec[0], vec[1]);
3039 const float lh =
h > 0.f ?
h : 1.f;
3040 const float theta = acosf(fabsf(vec[2])) /
M_PI;
3042 float uf = (theta * (vec[0] / lh) *
s->input_mirror_modifier[0] /
s->iflat_range[0] + 0.5f) * ew;
3043 float vf = (theta * (vec[1] / lh) *
s->input_mirror_modifier[1] /
s->iflat_range[1] + 0.5f) * eh;
3048 if (vec[2] >= 0.
f) {
3049 u_shift = ceilf(ew);
3061 for (
int i = 0;
i < 4;
i++) {
3062 for (
int j = 0; j < 4; j++) {
3063 us[
i][j] = av_clip(u_shift +
ui + j - 1, 0,
width - 1);
3064 vs[
i][j] = av_clip( vi +
i - 1, 0,
height - 1);
3085 const float scale = 0.99f;
3086 float l_x, l_y, l_z;
3089 const float theta_range = M_PI_4;
3091 const int ew = 4 *
width / 5;
3094 const float phi = ((2.f *
i) / ew - 1.
f) *
M_PI / scale;
3095 const float theta = ((2.f * j) / eh - 1.
f) * theta_range / scale;
3097 const float sin_phi =
sinf(phi);
3098 const float cos_phi =
cosf(phi);
3099 const float sin_theta =
sinf(theta);
3100 const float cos_theta =
cosf(theta);
3102 l_x = cos_theta * sin_phi;
3104 l_z = cos_theta * cos_phi;
3106 const int ew =
width / 5;
3107 const int eh =
height / 2;
3112 uf = 2.f * (
i - 4 * ew) / ew - 1.
f;
3113 vf = 2.f * (j ) / eh - 1.
f;
3122 uf = 2.f * (
i - 4 * ew) / ew - 1.
f;
3123 vf = 2.f * (j - eh) / eh - 1.
f;
3157 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3159 const float scale = 0.99f;
3161 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
3162 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
3163 const float theta_range = M_PI_4;
3166 int u_shift, v_shift;
3170 if (theta > -theta_range && theta < theta_range) {
3174 u_shift =
s->ih_flip ?
width / 5 : 0;
3177 uf = (phi /
M_PI * scale + 1.f) * ew / 2.
f;
3178 vf = (theta / theta_range * scale + 1.f) * eh / 2.
f;
3183 u_shift =
s->ih_flip ? 0 : 4 * ew;
3186 uf = -vec[0] / vec[1];
3187 vf = -vec[2] / vec[1];
3190 uf = vec[0] / vec[1];
3191 vf = -vec[2] / vec[1];
3195 uf *=
s->input_mirror_modifier[0] *
s->input_mirror_modifier[1];
3196 vf *=
s->input_mirror_modifier[1];
3198 uf = 0.5f * ew * (uf * scale + 1.f);
3199 vf = 0.5f * eh * (vf * scale + 1.f);
3208 for (
int i = 0;
i < 4;
i++) {
3209 for (
int j = 0; j < 4; j++) {
3210 us[
i][j] = u_shift + av_clip(
ui + j - 1, 0, ew - 1);
3211 vs[
i][j] = v_shift + av_clip(vi +
i - 1, 0, eh - 1);
3232 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3234 const float phi =
atan2f(vec[0], vec[2]) *
s->input_mirror_modifier[0];
3235 const float theta = asinf(vec[1]) *
s->input_mirror_modifier[1];
3237 const float theta_range = M_PI_4;
3240 int u_shift, v_shift;
3244 if (theta >= -theta_range && theta <= theta_range) {
3245 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3246 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3251 u_shift =
s->ih_flip ?
width / 3 : 0;
3255 vf = theta / M_PI_4;
3258 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3260 uf = (uf * scalew + 1.f) *
width / 3.
f;
3261 vf = (vf * scaleh + 1.f) *
height / 4.
f;
3263 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3264 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3270 u_shift =
s->ih_flip ? 0 : 2 * ew;
3272 if (theta <= 0.f && theta >= -
M_PI_2 &&
3273 phi <= M_PI_2 && phi >= -
M_PI_2) {
3274 uf = -vec[0] / vec[1];
3275 vf = -vec[2] / vec[1];
3278 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3279 phi <= M_PI_2 && phi >= -
M_PI_2) {
3280 uf = vec[0] / vec[1];
3281 vf = -vec[2] / vec[1];
3282 v_shift =
height * 0.25f;
3283 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3284 uf = vec[0] / vec[1];
3285 vf = vec[2] / vec[1];
3289 uf = -vec[0] / vec[1];
3290 vf = vec[2] / vec[1];
3291 v_shift =
height * 0.75f;
3294 uf *=
s->input_mirror_modifier[0] *
s->input_mirror_modifier[1];
3295 vf *=
s->input_mirror_modifier[1];
3297 uf = 0.5f *
width / 3.f * (uf * scalew + 1.f);
3298 vf =
height * 0.25f * (vf * scaleh + 1.f) + v_offset;
3307 for (
int i = 0;
i < 4;
i++) {
3308 for (
int j = 0; j < 4; j++) {
3309 us[
i][j] = u_shift + av_clip(
ui + j - 1, 0, ew - 1);
3310 vs[
i][j] = v_shift + av_clip(vi +
i - 1, 0, eh - 1);
3331 const float x = (
i + 0.5f) /
width;
3332 const float y = (j + 0.5f) /
height;
3333 float l_x, l_y, l_z;
3335 if (x < 2.
f / 3.
f) {
3336 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3337 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3339 const float back = floorf(y * 2.
f);
3341 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3342 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3344 const float sin_phi =
sinf(phi);
3345 const float cos_phi =
cosf(phi);
3346 const float sin_theta =
sinf(theta);
3347 const float cos_theta =
cosf(theta);
3349 l_x = cos_theta * sin_phi;
3351 l_z = cos_theta * cos_phi;
3353 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3354 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3356 const int face = floorf(y * 4.
f);
3367 l_x = (0.5f - uf) / scalew;
3369 l_z = (0.5f - vf) / scaleh;
3374 vf = 1.f - (vf - 0.5f);
3376 l_x = (0.5f - uf) / scalew;
3378 l_z = (-0.5f + vf) / scaleh;
3381 vf = y * 2.f - 0.5f;
3382 vf = 1.f - (1.f - vf);
3384 l_x = (0.5f - uf) / scalew;
3386 l_z = (0.5f - vf) / scaleh;
3389 vf = y * 2.f - 1.5f;
3391 l_x = (0.5f - uf) / scalew;
3393 l_z = (-0.5f + vf) / scaleh;
3421 const float x = (
i + 0.5f) /
width;
3422 const float y = (j + 0.5f) /
height;
3425 vec[0] = x * 4.f - 1.f;
3426 vec[1] = (y * 2.f - 1.f);
3428 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3429 y >= 0.375
f && y < 0.625
f) {
3430 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3431 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3433 }
else if (0.5
f <= x && x < 0.6875
f &&
3434 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3435 (0.375
f <= y && y < 0.625
f) ||
3436 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3438 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3439 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3440 }
else if (0.8125
f <= x && x < 1.
f &&
3441 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3442 (0.375
f <= y && y < 0.625
f) ||
3443 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3445 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3446 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3447 }
else if (0.
f <= y && y < 0.375
f &&
3448 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3449 (0.6875
f <= x && x < 0.8125
f) ||
3450 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3451 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3453 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3455 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3457 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3479 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3487 uf = (uf + 1.f) * 0.5
f;
3488 vf = (vf + 1.f) * 0.5
f;
3492 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3493 vf = 0.375f - 0.375f * vf;
3499 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3500 vf = 1.f - 0.375f * vf;
3503 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3504 uf = 0.1875f * uf + 0.8125f;
3507 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3508 uf = 0.1875f * uf + 0.5f;
3511 uf = 0.125f * uf + 0.6875f;
3512 vf = 0.25f * vf + 0.375f;
3525 for (
int i = 0;
i < 4;
i++) {
3526 for (
int j = 0; j < 4; j++) {
3537 for (
int i = 0;
i < 3;
i++) {
3538 for (
int j = 0; j < 3; j++) {
3541 for (
int k = 0; k < 3; k++)
3542 sum +=
a[
i][k] *
b[k][j];
3553 float rot_mat[3][3],
3554 const int rotation_order[3])
3556 const float yaw_rad = yaw *
M_PI / 180.f;
3557 const float pitch_rad = pitch *
M_PI / 180.f;
3558 const float roll_rad = roll *
M_PI / 180.f;
3560 const float sin_yaw =
sinf(yaw_rad);
3561 const float cos_yaw =
cosf(yaw_rad);
3562 const float sin_pitch =
sinf(pitch_rad);
3563 const float cos_pitch =
cosf(pitch_rad);
3564 const float sin_roll =
sinf(roll_rad);
3565 const float cos_roll =
cosf(roll_rad);
3570 m[0][0][0] = cos_yaw; m[0][0][1] = 0; m[0][0][2] = sin_yaw;
3571 m[0][1][0] = 0; m[0][1][1] = 1; m[0][1][2] = 0;
3572 m[0][2][0] = -sin_yaw; m[0][2][1] = 0; m[0][2][2] = cos_yaw;
3574 m[1][0][0] = 1; m[1][0][1] = 0; m[1][0][2] = 0;
3575 m[1][1][0] = 0; m[1][1][1] = cos_pitch; m[1][1][2] = -sin_pitch;
3576 m[1][2][0] = 0; m[1][2][1] = sin_pitch; m[1][2][2] = cos_pitch;
3578 m[2][0][0] = cos_roll; m[2][0][1] = -sin_roll; m[2][0][2] = 0;
3579 m[2][1][0] = sin_roll; m[2][1][1] = cos_roll; m[2][1][2] = 0;
3580 m[2][2][0] = 0; m[2][2][1] = 0; m[2][2][2] = 1;
3592 static inline void rotate(
const float rot_mat[3][3],
3595 const float x_tmp = vec[0] * rot_mat[0][0] + vec[1] * rot_mat[0][1] + vec[2] * rot_mat[0][2];
3596 const float y_tmp = vec[0] * rot_mat[1][0] + vec[1] * rot_mat[1][1] + vec[2] * rot_mat[1][2];
3597 const float z_tmp = vec[0] * rot_mat[2][0] + vec[1] * rot_mat[2][1] + vec[2] * rot_mat[2][2];
3607 modifier[0] = h_flip ? -1.f : 1.f;
3608 modifier[1] = v_flip ? -1.f : 1.f;
3609 modifier[2] = d_flip ? -1.f : 1.f;
3612 static inline void mirror(
const float *modifier,
float *vec)
3614 vec[0] *= modifier[0];
3615 vec[1] *= modifier[1];
3616 vec[2] *= modifier[2];
3622 s->u[p] =
av_calloc(
s->uv_linesize[p] *
s->pr_height[p], sizeof_uv);
3624 s->v[p] =
av_calloc(
s->uv_linesize[p] *
s->pr_height[p], sizeof_uv);
3625 if (!
s->u[p] || !
s->v[p])
3629 s->ker[p] =
av_calloc(
s->uv_linesize[p] *
s->pr_height[p], sizeof_ker);
3634 if (sizeof_mask && !p) {
3636 s->mask =
av_calloc(
s->pr_width[p] *
s->pr_height[p], sizeof_mask);
3649 const float d = 0.5f * hypotf(
w,
h);
3650 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
3658 const float d = 0.5f * hypotf(
w * 0.5
f,
h);
3660 *h_fov = d /
w * 2.f * d_fov;
3661 *v_fov = d /
h * d_fov;
3666 const float d = 0.5f * hypotf(
w,
h);
3668 *h_fov = d /
w * d_fov;
3669 *v_fov = d /
h * d_fov;
3675 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
3676 const float d = hypotf(
w,
h);
3693 outw[0] = outw[3] =
w;
3695 outh[0] = outh[3] =
h;
3703 for (
int p = 0; p <
s->nb_allocated; p++) {
3704 const int max_value =
s->max_value;
3705 const int width =
s->pr_width[p];
3706 const int uv_linesize =
s->uv_linesize[p];
3707 const int height =
s->pr_height[p];
3708 const int in_width =
s->inplanewidth[p];
3709 const int in_height =
s->inplaneheight[p];
3710 const int slice_start = (
height * jobnr ) / nb_jobs;
3716 for (
int j = slice_start; j <
slice_end; j++) {
3718 int16_t *
u =
s->u[p] + (j * uv_linesize +
i) *
s->elements;
3719 int16_t *v =
s->v[p] + (j * uv_linesize +
i) *
s->elements;
3720 int16_t *ker =
s->ker[p] + (j * uv_linesize +
i) *
s->elements;
3722 uint16_t *mask16 = p ?
NULL : (uint16_t *)
s->mask + (j *
s->pr_width[0] +
i);
3723 int in_mask, out_mask;
3725 if (
s->out_transpose)
3733 mirror(
s->output_mirror_modifier, vec);
3734 if (
s->in_transpose)
3735 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
3737 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
3739 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
3741 if (!p &&
s->mask) {
3742 if (
s->mask_size == 1) {
3743 mask8[0] = 255 * (out_mask & in_mask);
3745 mask16[0] = max_value * (out_mask & in_mask);
3761 const int depth =
desc->comp[0].depth;
3762 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
3767 int in_offset_h, in_offset_w;
3768 int out_offset_h, out_offset_w;
3773 s->max_value = (1 << depth) - 1;
3774 s->input_mirror_modifier[0] =
s->ih_flip ? -1.f : 1.f;
3775 s->input_mirror_modifier[1] =
s->iv_flip ? -1.f : 1.f;
3777 switch (
s->interp) {
3780 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
3782 sizeof_uv =
sizeof(int16_t) *
s->elements;
3787 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
3788 s->elements = 2 * 2;
3789 sizeof_uv =
sizeof(int16_t) *
s->elements;
3790 sizeof_ker =
sizeof(int16_t) *
s->elements;
3794 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
3795 s->elements = 3 * 3;
3796 sizeof_uv =
sizeof(int16_t) *
s->elements;
3797 sizeof_ker =
sizeof(int16_t) *
s->elements;
3801 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
3802 s->elements = 4 * 4;
3803 sizeof_uv =
sizeof(int16_t) *
s->elements;
3804 sizeof_ker =
sizeof(int16_t) *
s->elements;
3808 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
3809 s->elements = 4 * 4;
3810 sizeof_uv =
sizeof(int16_t) *
s->elements;
3811 sizeof_ker =
sizeof(int16_t) *
s->elements;
3815 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
3816 s->elements = 4 * 4;
3817 sizeof_uv =
sizeof(int16_t) *
s->elements;
3818 sizeof_ker =
sizeof(int16_t) *
s->elements;
3822 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
3823 s->elements = 4 * 4;
3824 sizeof_uv =
sizeof(int16_t) *
s->elements;
3825 sizeof_ker =
sizeof(int16_t) *
s->elements;
3833 for (
int order = 0; order <
NB_RORDERS; order++) {
3834 const char c =
s->rorder[order];
3839 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
3840 s->rotation_order[0] =
YAW;
3841 s->rotation_order[1] =
PITCH;
3842 s->rotation_order[2] =
ROLL;
3849 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
3850 s->rotation_order[0] =
YAW;
3851 s->rotation_order[1] =
PITCH;
3852 s->rotation_order[2] =
ROLL;
3856 s->rotation_order[order] = rorder;
3859 switch (
s->in_stereo) {
3863 in_offset_w = in_offset_h = 0;
3884 s->in_width =
s->inplanewidth[0];
3885 s->in_height =
s->inplaneheight[0];
3887 if (
s->id_fov > 0.f)
3890 if (
s->in_transpose)
3891 FFSWAP(
int,
s->in_width,
s->in_height);
4159 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4160 s->out ==
FLAT &&
s->d_fov == 0.f) {
4162 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4163 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4164 s->out ==
FLAT &&
s->d_fov == 0.f) {
4166 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4167 }
else if (
s->width > 0 &&
s->height > 0) {
4170 }
else if (
s->width > 0 ||
s->height > 0) {
4174 if (
s->out_transpose)
4177 if (
s->in_transpose)
4188 err = prepare_out(
ctx);
4195 switch (
s->out_stereo) {
4197 out_offset_w = out_offset_h = 0;
4216 for (
int i = 0;
i < 4;
i++)
4225 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4226 s->nb_allocated = 1;
4227 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4229 s->nb_allocated = 2;
4230 s->map[0] =
s->map[3] = 0;
4231 s->map[1] =
s->map[2] = 1;
4234 for (
int i = 0;
i <
s->nb_allocated;
i++)
4235 allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4270 char *res,
int res_len,
int flags)
4285 for (
int p = 0; p <
s->nb_allocated; p++) {
4319 .priv_class = &v360_class,
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
#define AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_GBRAP16
#define AV_LOG_WARNING
Something somehow does not look correct.
AVPixelFormat
Pixel format.
static void process_cube_coordinates(const V360Context *s, float uf, float vf, int direction, float *new_uf, float *new_vf, int *face)
Find position on another cube face in case of overflow/underflow.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static int xyz_to_mercator(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in mercator format for corresponding 3D coordinates on sphere.
static int prepare_stereographic_in(AVFilterContext *ctx)
Prepare data for processing stereographic input format.
static int xyz_to_eac(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in equi-angular cubemap format for corresponding 3D coordinates on sphere.
#define FFSWAP(type, a, b)
#define u(width, name, range_min, range_max)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
static void gaussian_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for gaussian interpolation.
static const AVFilterPad outputs[]
void ff_v360_init_x86(V360Context *s, int depth)
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static int xyz_to_stereographic(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in stereographic format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA422P9
This structure describes decoded (raw) audio or video data.
#define AV_PIX_FMT_YUVA420P16
static int prepare_cube_out(AVFilterContext *ctx)
Prepare data for processing cubemap output format.
static int xyz_to_cylindrical(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cylindrical format for corresponding 3D coordinates on sphere.
static int barrelsplit_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in barrel split facebook's format...
static int stereographic_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in stereographic format.
#define AV_PIX_FMT_YUVA420P10
static int prepare_cube_in(AVFilterContext *ctx)
Prepare data for processing cubemap input format.
static int get_rotation(char c)
Convert char to corresponding rotation angle.
#define AV_PIX_FMT_YUV420P10
static int xyz_to_barrel(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in barrel facebook's format for corresponding 3D coordinates on sphere.
static int perspective_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in perspective format.
static int xyz_to_cube3x2(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cubemap3x2 format for corresponding 3D coordinates on sphere.
static const AVOption v360_options[]
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int xyz_to_tspyramid(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in tspyramid format for corresponding 3D coordinates on sphere.
const char * name
Filter name.
static void rotate_cube_face_inverse(float *uf, float *vf, int rotation)
AVFormatInternal * internal
An opaque field for libavformat internal usage.
A link between two filters.
AVFILTER_DEFINE_CLASS(v360)
#define AV_PIX_FMT_YUVA422P10
static int xyz_to_sinusoidal(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in sinusoidal format for corresponding 3D coordinates on sphere.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_YUVA420P9
static int prepare_eac_out(AVFilterContext *ctx)
Prepare data for processing equi-angular cubemap output format.
#define AV_PIX_FMT_GBRP14
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
#define AV_PIX_FMT_GBRP10
static void calculate_lanczos_coeffs(float t, float *coeffs)
Calculate 1-dimensional lanczos coefficients.
#define AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUV422P9
static void lanczos_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for lanczos interpolation.
static const AVFilterPad inputs[]
static int equirect_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in equirectangular format.
#define AV_PIX_FMT_GRAY16
#define us(width, name, range_min, range_max, subs,...)
static int xyz_to_cube6x1(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cubemap6x1 format for corresponding 3D coordinates on sphere.
static int ball_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in ball format.
static int xyz_to_hammer(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in hammer format for corresponding 3D coordinates on sphere.
A filter pad used for either input or output.
#define AV_PIX_FMT_YUV444P10
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
static int reflectx(int x, int y, int w, int h)
Reflect x operation.
static void multiply_matrix(float c[3][3], const float a[3][3], const float b[3][3])
static void lagrange_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for lagrange interpolation.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define AV_PIX_FMT_YUV422P16
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
#define AV_PIX_FMT_GBRAP10
static void rotate(const float rot_mat[3][3], float *vec)
Rotate vector with given rotation matrix.
static int tetrahedron_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in tetrahedron format.
static void calculate_spline16_coeffs(float t, float *coeffs)
Calculate 1-dimensional spline16 coefficients.
#define DEFINE_REMAP(ws, bits)
Generate remapping function with a given window size and pixel depth.
#define AV_PIX_FMT_GBRAP12
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
#define AV_PIX_FMT_YUV444P16
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
static int fisheye_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in fisheye format.
static int reflecty(int y, int h)
Reflect y operation.
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
static void bilinear_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for bilinear interpolation.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static enum AVPixelFormat pix_fmts[]
#define AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
#define AV_PIX_FMT_GRAY14
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
#define AV_PIX_FMT_GRAY10
void ff_v360_init(V360Context *s, int depth)
#define AV_PIX_FMT_GBRP16
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
static int xyz_to_cube1x6(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cubemap1x6 format for corresponding 3D coordinates on sphere.
static void calculate_gaussian_coeffs(float t, float *coeffs)
Calculate 1-dimensional gaussian coefficients.
static int ereflectx(int x, int y, int w, int h)
Reflect x operation for equirect.
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
static int mercator_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in mercator format.
static int prepare_fisheye_out(AVFilterContext *ctx)
Prepare data for processing fisheye output format.
#define AV_PIX_FMT_YUV440P10
static void rotate_cube_face(float *uf, float *vf, int rotation)
static void calculate_lagrange_coeffs(float t, float *coeffs)
Calculate 1-dimensional lagrange coefficients.
static int cube1x6_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap1x6 format.
static int barrel_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in barrel facebook's format.
#define AV_PIX_FMT_YUV422P10
static int prepare_cylindrical_out(AVFilterContext *ctx)
Prepare data for processing cylindrical output format.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
static int prepare_cylindrical_in(AVFilterContext *ctx)
Prepare data for processing cylindrical input format.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static int pannini_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in pannini format.
static int xyz_to_ball(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in ball format for corresponding 3D coordinates on sphere.
static int hammer_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in hammer format.
static void mirror(const float *modifier, float *vec)
static int cylindrical_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cylindrical format.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void nearest_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Save nearest pixel coordinates for remapping.
static void calculate_rotation_matrix(float yaw, float pitch, float roll, float rot_mat[3][3], const int rotation_order[3])
Calculate rotation matrix for yaw/pitch/roll angles.
#define AV_PIX_FMT_YUV422P12
static void spline16_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for spline16 interpolation.
static av_cold void uninit(AVFilterContext *ctx)
#define AV_PIX_FMT_YUV444P12
AVFilterContext * src
source filter
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
static int eac_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in equi-angular cubemap format.
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
#define AV_PIX_FMT_YUVA444P10
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int prepare_fisheye_in(AVFilterContext *ctx)
Prepare data for processing fisheye input format.
static int query_formats(AVFilterContext *ctx)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static void bicubic_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for bicubic interpolation.
#define i(width, name, range_min, range_max)
static int xyz_to_equirect(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in equirectangular format for corresponding 3D coordinates on sphere.
static int cube3x2_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap3x2 format.
static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p)
int w
agreed upon image width
#define DEFINE_REMAP_LINE(ws, bits, div)
static int prepare_stereographic_out(AVFilterContext *ctx)
Prepare data for processing stereographic output format.
static int config_output(AVFilterLink *outlink)
#define AV_PIX_FMT_GBRP12
static int cube6x1_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap6x1 format.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
static void xyz_to_cube(const V360Context *s, const float *vec, float *uf, float *vf, int *direction)
Calculate cubemap position for corresponding 3D coordinates on sphere.
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static int xyz_to_fisheye(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in fisheye format for corresponding 3D coordinates on sphere.
Used for passing data between threads.
static int xyz_to_flat(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in flat format for corresponding 3D coordinates on sphere.
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
const char * name
Pad name.
#define AV_PIX_FMT_YUV444P9
static int mod(int a, int b)
Modulo operation with only positive remainders.
static int prepare_flat_out(AVFilterContext *ctx)
Prepare data for processing flat output format.
static int hequirect_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in half equirectangular format.
static int xyz_to_tetrahedron(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in tetrahedron format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA444P9
#define DEFINE_REMAP1_LINE(bits, div)
#define AV_PIX_FMT_YUV420P12
static int sinusoidal_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in sinusoidal format.
static void normalize_vector(float *vec)
Normalize vector.
#define AV_PIX_FMT_YUV422P14
static int get_rorder(char c)
Convert char to corresponding rotation order.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
int h
agreed upon image height
static int xyz_to_pannini(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in pannini format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA422P12
static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static void calculate_bicubic_coeffs(float t, float *coeffs)
Calculate 1-dimensional cubic coefficients.
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
static int prepare_flat_in(AVFilterContext *ctx)
Prepare data for processing flat input format.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
static int dfisheye_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in dual fisheye format.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
static int xyz_to_barrelsplit(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in barrel split facebook's format for corresponding 3D coordinates on sphere...
static int xyz_to_hequirect(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in half equirectangular format for corresponding 3D coordinates on sphere.
static const int16_t alpha[]
static int xyz_to_dfisheye(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in dual fisheye format for corresponding 3D coordinates on sphere.
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
static void cube_to_xyz(const V360Context *s, float uf, float vf, int face, float *vec, float scalew, float scaleh)
Calculate 3D coordinates on sphere for corresponding cubemap position.
static int tspyramid_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in tspyramid format.
#define flags(name, subs,...)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
static void fov_from_dfov(int format, float d_fov, float w, float h, float *h_fov, float *v_fov)
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
static void set_mirror_modifier(int h_flip, int v_flip, int d_flip, float *modifier)
#define AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_GRAY12
static enum AVPixelFormat alpha_pix_fmts[]
static int get_direction(char c)
Convert char to corresponding direction.
static int prepare_eac_in(AVFilterContext *ctx)
Prepare data for processing equi-angular cubemap input format.
static void set_dimensions(int *outw, int *outh, int w, int h, const AVPixFmtDescriptor *desc)
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
#define AV_PIX_FMT_YUV420P14
static int flat_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in flat format.