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
256 #define DEFINE_REMAP1_LINE(bits, div) \
257 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
258 ptrdiff_t in_linesize, \
259 const int16_t *const u, const int16_t *const v, \
260 const int16_t *const ker) \
262 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
263 uint##bits##_t *d = (uint##bits##_t *)dst; \
265 in_linesize /= div; \
267 for (int x = 0; x < width; x++) \
268 d[x] = s[v[x] * in_linesize + u[x]]; \
280 #define DEFINE_REMAP(ws, bits) \
281 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
283 ThreadData *td = arg; \
284 const V360Context *s = ctx->priv; \
285 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
286 const AVFrame *in = td->in; \
287 AVFrame *out = td->out; \
289 av_assert1(s->nb_planes <= AV_VIDEO_MAX_PLANES); \
291 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
292 for (int plane = 0; plane < s->nb_planes; plane++) { \
293 const unsigned map = s->map[plane]; \
294 const int in_linesize = in->linesize[plane]; \
295 const int out_linesize = out->linesize[plane]; \
296 const int uv_linesize = s->uv_linesize[plane]; \
297 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
298 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
299 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
300 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
301 const uint8_t *const src = in->data[plane] + \
302 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
303 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
304 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
305 const int width = s->pr_width[plane]; \
306 const int height = s->pr_height[plane]; \
308 const int slice_start = (height * jobnr ) / nb_jobs; \
309 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
311 for (int y = slice_start; y < slice_end && !mask; y++) { \
312 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
313 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
314 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
316 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
319 for (int y = slice_start; y < slice_end && mask; y++) { \
320 memcpy(dst + y * out_linesize, mask + \
321 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
338 #define DEFINE_REMAP_LINE(ws, bits, div) \
339 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
340 ptrdiff_t in_linesize, \
341 const int16_t *const u, const int16_t *const v, \
342 const int16_t *const ker) \
344 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
345 uint##bits##_t *d = (uint##bits##_t *)dst; \
347 in_linesize /= div; \
349 for (int x = 0; x < width; x++) { \
350 const int16_t *const uu = u + x * ws * ws; \
351 const int16_t *const vv = v + x * ws * ws; \
352 const int16_t *const kker = ker + x * ws * ws; \
355 for (int i = 0; i < ws; i++) { \
356 const int iws = i * ws; \
357 for (int j = 0; j < ws; j++) { \
358 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
362 d[x] = av_clip_uint##bits(tmp >> 14); \
377 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
380 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
383 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
390 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
410 int16_t *
u, int16_t *v, int16_t *ker)
413 const int j =
lrintf(du) + 1;
415 u[0] = rmap->
u[
i][j];
416 v[0] = rmap->
v[
i][j];
430 int16_t *
u, int16_t *v, int16_t *ker)
432 for (
int i = 0;
i < 2;
i++) {
433 for (
int j = 0; j < 2; j++) {
434 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
435 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
439 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
440 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
441 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
442 ker[3] =
lrintf( du * dv * 16385.
f);
453 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
454 coeffs[1] = -t * (t - 2.f);
455 coeffs[2] = t * (t - 1.f) * 0.5
f;
469 int16_t *
u, int16_t *v, int16_t *ker)
477 for (
int i = 0;
i < 3;
i++) {
478 for (
int j = 0; j < 3; j++) {
479 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
480 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
481 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
494 const float tt = t * t;
495 const float ttt = t * t * t;
497 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
498 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
499 coeffs[2] = t + tt / 2.f - ttt / 2.f;
500 coeffs[3] = - t / 6.f + ttt / 6.f;
514 int16_t *
u, int16_t *v, int16_t *ker)
522 for (
int i = 0;
i < 4;
i++) {
523 for (
int j = 0; j < 4; j++) {
524 u[
i * 4 + j] = rmap->
u[
i][j];
525 v[
i * 4 + j] = rmap->
v[
i][j];
526 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
541 for (
int i = 0;
i < 4;
i++) {
542 const float x =
M_PI * (t -
i + 1);
546 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
551 for (
int i = 0;
i < 4;
i++) {
567 int16_t *
u, int16_t *v, int16_t *ker)
575 for (
int i = 0;
i < 4;
i++) {
576 for (
int j = 0; j < 4; j++) {
577 u[
i * 4 + j] = rmap->
u[
i][j];
578 v[
i * 4 + j] = rmap->
v[
i][j];
579 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
592 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
593 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
594 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
595 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
609 int16_t *
u, int16_t *v, int16_t *ker)
617 for (
int i = 0;
i < 4;
i++) {
618 for (
int j = 0; j < 4; j++) {
619 u[
i * 4 + j] = rmap->
u[
i][j];
620 v[
i * 4 + j] = rmap->
v[
i][j];
621 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
636 for (
int i = 0;
i < 4;
i++) {
637 const float x = t - (
i - 1);
641 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
646 for (
int i = 0;
i < 4;
i++) {
662 int16_t *
u, int16_t *v, int16_t *ker)
670 for (
int i = 0;
i < 4;
i++) {
671 for (
int j = 0; j < 4; j++) {
672 u[
i * 4 + j] = rmap->
u[
i][j];
673 v[
i * 4 + j] = rmap->
v[
i][j];
674 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
689 float p0 = (6.f - 2.f *
b) / 6.
f,
690 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
691 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
692 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
693 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
694 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
695 q3 = (-
b - 6.f *
c) / 6.
f;
697 for (
int i = 0;
i < 4;
i++) {
698 const float x =
fabsf(t -
i + 1.
f);
700 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
701 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
702 }
else if (x < 2.
f) {
703 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
704 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
711 for (
int i = 0;
i < 4;
i++) {
727 int16_t *
u, int16_t *v, int16_t *ker)
735 for (
int i = 0;
i < 4;
i++) {
736 for (
int j = 0; j < 4; j++) {
737 u[
i * 4 + j] = rmap->
u[
i][j];
738 v[
i * 4 + j] = rmap->
v[
i][j];
739 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
754 const int res =
a %
b;
886 for (
int face = 0; face <
NB_FACES; face++) {
887 const char c =
s->in_forder[face];
892 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
897 if (direction == -1) {
899 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
903 s->in_cubemap_face_order[direction] = face;
906 for (
int face = 0; face <
NB_FACES; face++) {
907 const char c =
s->in_frot[face];
912 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
917 if (rotation == -1) {
919 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
923 s->in_cubemap_face_rotation[face] = rotation;
940 for (
int face = 0; face <
NB_FACES; face++) {
941 const char c =
s->out_forder[face];
946 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
951 if (direction == -1) {
953 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
957 s->out_cubemap_direction_order[face] = direction;
960 for (
int face = 0; face <
NB_FACES; face++) {
961 const char c =
s->out_frot[face];
966 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
971 if (rotation == -1) {
973 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
977 s->out_cubemap_face_rotation[face] = rotation;
1053 const float norm =
sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1073 float uf,
float vf,
int face,
1074 float *vec,
float scalew,
float scaleh)
1076 const int direction =
s->out_cubemap_direction_order[face];
1077 float l_x, l_y, l_z;
1084 switch (direction) {
1136 float *uf,
float *
vf,
int *direction)
1138 const float phi =
atan2f(vec[0], vec[2]);
1139 const float theta = asinf(vec[1]);
1140 float phi_norm, theta_threshold;
1154 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1157 theta_threshold =
atanf(
cosf(phi_norm));
1158 if (theta > theta_threshold) {
1160 }
else if (theta < -theta_threshold) {
1164 switch (*direction) {
1166 *uf = -vec[2] / vec[0];
1167 *
vf = vec[1] / vec[0];
1170 *uf = -vec[2] / vec[0];
1171 *
vf = -vec[1] / vec[0];
1174 *uf = -vec[0] / vec[1];
1175 *
vf = -vec[2] / vec[1];
1178 *uf = vec[0] / vec[1];
1179 *
vf = -vec[2] / vec[1];
1182 *uf = vec[0] / vec[2];
1183 *
vf = vec[1] / vec[2];
1186 *uf = vec[0] / vec[2];
1187 *
vf = -vec[1] / vec[2];
1193 face =
s->in_cubemap_face_order[*direction];
1210 float uf,
float vf,
int direction,
1211 float *new_uf,
float *new_vf,
int *face)
1230 *face =
s->in_cubemap_face_order[direction];
1233 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1237 }
else if (uf < -1.
f) {
1239 switch (direction) {
1273 }
else if (uf >= 1.
f) {
1275 switch (direction) {
1309 }
else if (
vf < -1.
f) {
1311 switch (direction) {
1345 }
else if (
vf >= 1.
f) {
1347 switch (direction) {
1387 *face =
s->in_cubemap_face_order[direction];
1393 return (0.5
f * x + 0.5
f) * (
s - 1.f);
1398 return (2.
f * x + 1.
f) /
s - 1.f;
1415 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1416 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1418 const float ew =
width / 3.f;
1419 const float eh =
height / 2.f;
1421 const int u_face =
floorf(
i / ew);
1422 const int v_face =
floorf(j / eh);
1423 const int face = u_face + 3 * v_face;
1425 const int u_shift =
ceilf(ew * u_face);
1426 const int v_shift =
ceilf(eh * v_face);
1427 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1428 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1430 const float uf =
rescale(
i - u_shift, ewi);
1431 const float vf =
rescale(j - v_shift, ehi);
1452 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1454 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1455 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1456 const float ew =
width / 3.f;
1457 const float eh =
height / 2.f;
1461 int direction, face;
1469 face =
s->in_cubemap_face_order[direction];
1472 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1473 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1475 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1476 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1484 for (
int i = 0;
i < 4;
i++) {
1485 for (
int j = 0; j < 4; j++) {
1486 int new_ui =
ui + j - 1;
1487 int new_vi = vi +
i - 1;
1488 int u_shift, v_shift;
1489 int new_ewi, new_ehi;
1491 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1492 face =
s->in_cubemap_face_order[direction];
1496 u_shift =
ceilf(ew * u_face);
1497 v_shift =
ceilf(eh * v_face);
1499 uf = 2.f * new_ui / ewi - 1.f;
1500 vf = 2.f * new_vi / ehi - 1.f;
1512 u_shift =
ceilf(ew * u_face);
1513 v_shift =
ceilf(eh * v_face);
1514 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1515 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1517 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1521 us[
i][j] = u_shift + new_ui;
1522 vs[
i][j] = v_shift + new_vi;
1543 const float scalew =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1544 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1546 const float ew =
width;
1547 const float eh =
height / 6.f;
1549 const int face =
floorf(j / eh);
1551 const int v_shift =
ceilf(eh * face);
1552 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1555 const float vf =
rescale(j - v_shift, ehi);
1576 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1577 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1579 const float ew =
width / 6.f;
1582 const int face =
floorf(
i / ew);
1584 const int u_shift =
ceilf(ew * face);
1585 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1587 const float uf =
rescale(
i - u_shift, ewi);
1609 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1611 const float scalew =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1612 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1613 const float eh =
height / 6.f;
1614 const int ewi =
width;
1618 int direction, face;
1625 face =
s->in_cubemap_face_order[direction];
1626 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1628 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1629 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1637 for (
int i = 0;
i < 4;
i++) {
1638 for (
int j = 0; j < 4; j++) {
1639 int new_ui =
ui + j - 1;
1640 int new_vi = vi +
i - 1;
1644 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1645 face =
s->in_cubemap_face_order[direction];
1647 v_shift =
ceilf(eh * face);
1649 uf = 2.f * new_ui / ewi - 1.f;
1650 vf = 2.f * new_vi / ehi - 1.f;
1660 v_shift =
ceilf(eh * face);
1661 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1668 vs[
i][j] = v_shift + new_vi;
1689 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1691 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1692 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1693 const float ew =
width / 6.f;
1698 int direction, face;
1705 face =
s->in_cubemap_face_order[direction];
1706 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1708 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1709 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1717 for (
int i = 0;
i < 4;
i++) {
1718 for (
int j = 0; j < 4; j++) {
1719 int new_ui =
ui + j - 1;
1720 int new_vi = vi +
i - 1;
1724 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1725 face =
s->in_cubemap_face_order[direction];
1727 u_shift =
ceilf(ew * face);
1729 uf = 2.f * new_ui / ewi - 1.f;
1730 vf = 2.f * new_vi / ehi - 1.f;
1740 u_shift =
ceilf(ew * face);
1741 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1743 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1747 us[
i][j] = u_shift + new_ui;
1766 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
1767 s->flat_range[1] =
s->v_fov *
M_PI / 360.f;
1789 const float sin_phi =
sinf(phi);
1790 const float cos_phi =
cosf(phi);
1791 const float sin_theta =
sinf(theta);
1792 const float cos_theta =
cosf(theta);
1794 vec[0] = cos_theta * sin_phi;
1796 vec[2] = cos_theta * cos_phi;
1818 const float sin_phi =
sinf(phi);
1819 const float cos_phi =
cosf(phi);
1820 const float sin_theta =
sinf(theta);
1821 const float cos_theta =
cosf(theta);
1823 vec[0] = cos_theta * sin_phi;
1825 vec[2] = cos_theta * cos_phi;
1841 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1842 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1863 const float r = hypotf(x, y);
1864 const float theta =
atanf(
r) * 2.f;
1865 const float sin_theta =
sinf(theta);
1867 vec[0] = x /
r * sin_theta;
1868 vec[1] = y /
r * sin_theta;
1869 vec[2] =
cosf(theta);
1885 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1886 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1905 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1907 const float theta = acosf(vec[2]);
1908 const float r = tanf(theta * 0.5
f);
1909 const float c =
r / hypotf(vec[0], vec[1]);
1910 const float x = vec[0] *
c /
s->iflat_range[0];
1911 const float y = vec[1] *
c /
s->iflat_range[1];
1921 *du = visible ? uf -
ui : 0.f;
1922 *dv = visible ?
vf - vi : 0.f;
1924 for (
int i = 0;
i < 4;
i++) {
1925 for (
int j = 0; j < 4; j++) {
1945 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1946 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1967 const float r = hypotf(x, y);
1968 const float theta = asinf(
r) * 2.f;
1969 const float sin_theta =
sinf(theta);
1971 vec[0] = x /
r * sin_theta;
1972 vec[1] = y /
r * sin_theta;
1973 vec[2] =
cosf(theta);
2009 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2011 const float theta = acosf(vec[2]);
2012 const float r =
sinf(theta * 0.5
f);
2013 const float c =
r / hypotf(vec[0], vec[1]);
2014 const float x = vec[0] *
c /
s->iflat_range[0];
2015 const float y = vec[1] *
c /
s->iflat_range[1];
2025 *du = visible ? uf -
ui : 0.f;
2026 *dv = visible ?
vf - vi : 0.f;
2028 for (
int i = 0;
i < 4;
i++) {
2029 for (
int j = 0; j < 4; j++) {
2071 const float r = hypotf(x, y);
2072 const float theta = asinf(
r);
2074 vec[2] =
cosf(theta);
2120 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2122 const float theta = acosf(vec[2]);
2123 const float r =
sinf(theta);
2124 const float c =
r / hypotf(vec[0], vec[1]);
2125 const float x = vec[0] *
c /
s->iflat_range[0];
2126 const float y = vec[1] *
c /
s->iflat_range[1];
2134 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2136 *du = visible ? uf -
ui : 0.f;
2137 *dv = visible ?
vf - vi : 0.f;
2139 for (
int i = 0;
i < 4;
i++) {
2140 for (
int j = 0; j < 4; j++) {
2160 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2161 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2180 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2182 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2183 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2195 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2197 for (
int i = 0;
i < 4;
i++) {
2198 for (
int j = 0; j < 4; j++) {
2221 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2224 const float theta = asinf(vec[1]) /
M_PI_2;
2237 for (
int i = 0;
i < 4;
i++) {
2238 for (
int j = 0; j < 4; j++) {
2258 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2259 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2278 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2280 const float theta = acosf(vec[2]);
2281 const float r = tanf(theta);
2283 const float zf = vec[2];
2284 const float h = hypotf(vec[0], vec[1]);
2285 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2286 float uf = vec[0] *
c /
s->iflat_range[0];
2287 float vf = vec[1] *
c /
s->iflat_range[1];
2288 int visible,
ui, vi;
2296 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2301 for (
int i = 0;
i < 4;
i++) {
2302 for (
int j = 0; j < 4; j++) {
2325 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2327 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2328 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2339 for (
int i = 0;
i < 4;
i++) {
2340 for (
int j = 0; j < 4; j++) {
2365 const float div =
expf(2.
f * y) + 1.f;
2367 const float sin_phi =
sinf(phi);
2368 const float cos_phi =
cosf(phi);
2369 const float sin_theta = 2.f *
expf(y) / div;
2370 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2372 vec[0] = -sin_theta * cos_phi;
2374 vec[2] = sin_theta * sin_phi;
2393 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2395 const float l = hypotf(vec[0], vec[1]);
2397 const float d = l > 0.f ? l : 1.f;
2408 for (
int i = 0;
i < 4;
i++) {
2409 for (
int j = 0; j < 4; j++) {
2434 const float l = hypotf(x, y);
2437 const float z = 2.f * l *
sqrtf(1.
f - l * l);
2439 vec[0] = z * x / (l > 0.f ? l : 1.f);
2440 vec[1] = z * y / (l > 0.f ? l : 1.f);
2441 vec[2] = 1.f - 2.f * l * l;
2469 const float xx = x * x;
2470 const float yy = y * y;
2472 const float z =
sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2475 const float b = 2.f * z * z - 1.f;
2477 const float aa =
a *
a;
2478 const float bb =
b *
b;
2480 const float w =
sqrtf(1.
f - 2.
f * yy * z * z);
2482 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2484 vec[2] =
w * (bb - aa) / (aa + bb);
2503 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2505 const float theta =
atan2f(vec[0], vec[2]);
2508 const float x =
sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2509 const float y = vec[1] / z;
2511 const float uf = (x + 1.f) *
width / 2.
f;
2512 const float vf = (y + 1.f) *
height / 2.
f;
2520 for (
int i = 0;
i < 4;
i++) {
2521 for (
int j = 0; j < 4; j++) {
2547 const float sin_phi =
sinf(phi);
2548 const float cos_phi =
cosf(phi);
2549 const float sin_theta =
sinf(theta);
2550 const float cos_theta =
cosf(theta);
2552 vec[0] = cos_theta * sin_phi;
2554 vec[2] = cos_theta * cos_phi;
2573 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2575 const float theta = asinf(vec[1]);
2576 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2587 for (
int i = 0;
i < 4;
i++) {
2588 for (
int j = 0; j < 4; j++) {
2667 const float pixel_pad = 2;
2668 const float u_pad = pixel_pad /
width;
2669 const float v_pad = pixel_pad /
height;
2671 int u_face, v_face, face;
2673 float l_x, l_y, l_z;
2675 float uf = (
i + 0.5f) /
width;
2683 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2687 }
else if (uf >= 3.
f) {
2692 uf = fmodf(uf, 1.
f) - 0.5f;
2697 vf = (
vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2699 if (uf >= -0.5
f && uf < 0.5
f) {
2704 if (
vf >= -0.5
f &&
vf < 0.5
f) {
2710 face = u_face + 3 * v_face;
2768 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2770 const float pixel_pad = 2;
2771 const float u_pad = pixel_pad /
width;
2772 const float v_pad = pixel_pad /
height;
2776 int direction, face;
2781 face =
s->in_cubemap_face_order[direction];
2789 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2790 vf =
vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2804 for (
int i = 0;
i < 4;
i++) {
2805 for (
int j = 0; j < 4; j++) {
2825 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2826 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2866 s->flat_range[0] =
s->h_fov / 180.f;
2867 s->flat_range[1] =
s->v_fov / 180.f;
2890 const float theta =
M_PI_2 * (1.f - hypotf(uf,
vf));
2892 const float sin_phi =
sinf(phi);
2893 const float cos_phi =
cosf(phi);
2894 const float sin_theta =
sinf(theta);
2895 const float cos_theta =
cosf(theta);
2897 vec[0] = cos_theta * cos_phi;
2898 vec[1] = cos_theta * sin_phi;
2915 s->iflat_range[0] =
s->ih_fov / 180.f;
2916 s->iflat_range[1] =
s->iv_fov / 180.f;
2935 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2937 const float h = hypotf(vec[0], vec[1]);
2938 const float lh =
h > 0.f ?
h : 1.f;
2941 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2942 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2944 const int visible = -0.5f < uf && uf < 0.5f && -0.5f <
vf &&
vf < 0.5f;
2953 *du = visible ? uf -
ui : 0.f;
2954 *dv = visible ?
vf - vi : 0.f;
2956 for (
int i = 0;
i < 4;
i++) {
2957 for (
int j = 0; j < 4; j++) {
2983 const float d =
s->h_fov;
2984 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2985 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2986 const float clon = (-k * d +
sqrtf(dscr)) / (k + 1.
f);
2987 const float S = (d + 1.f) / (d + clon);
2988 const float lon =
atan2f(uf,
S * clon);
3012 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3014 const float phi =
atan2f(vec[0], vec[2]);
3015 const float theta = asinf(vec[1]);
3017 const float d =
s->ih_fov;
3018 const float S = (d + 1.f) / (d +
cosf(phi));
3020 const float x =
S *
sinf(phi);
3021 const float y =
S * tanf(theta);
3029 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3034 for (
int i = 0;
i < 4;
i++) {
3035 for (
int j = 0; j < 4; j++) {
3055 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3056 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3078 const float phi = uf;
3079 const float theta =
atanf(
vf);
3081 const float sin_phi =
sinf(phi);
3082 const float cos_phi =
cosf(phi);
3083 const float sin_theta =
sinf(theta);
3084 const float cos_theta =
cosf(theta);
3086 vec[0] = cos_theta * sin_phi;
3088 vec[2] = cos_theta * cos_phi;
3104 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3105 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3124 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3126 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3127 const float theta = asinf(vec[1]);
3135 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3136 theta <=
M_PI *
s->iv_fov / 180.f &&
3137 theta >= -
M_PI *
s->iv_fov / 180.f;
3142 for (
int i = 0;
i < 4;
i++) {
3143 for (
int j = 0; j < 4; j++) {
3163 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3164 s->flat_range[1] =
s->v_fov / 180.f;
3180 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3181 s->iflat_range[1] =
s->iv_fov / 180.f;
3203 const float phi = uf;
3204 const float theta = asinf(
vf);
3206 const float sin_phi =
sinf(phi);
3207 const float cos_phi =
cosf(phi);
3208 const float sin_theta =
sinf(theta);
3209 const float cos_theta =
cosf(theta);
3211 vec[0] = cos_theta * sin_phi;
3213 vec[2] = cos_theta * cos_phi;
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->iflat_range[0];
3235 const float theta = asinf(vec[1]);
3243 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3244 theta <=
M_PI *
s->iv_fov / 180.f &&
3245 theta >= -
M_PI *
s->iv_fov / 180.f;
3250 for (
int i = 0;
i < 4;
i++) {
3251 for (
int j = 0; j < 4; j++) {
3276 const float rh = hypotf(uf,
vf);
3277 const float sinzz = 1.f - rh * rh;
3278 const float h = 1.f +
s->v_fov;
3279 const float sinz = (
h -
sqrtf(sinzz)) / (
h / rh + rh /
h);
3280 const float sinz2 = sinz * sinz;
3283 const float cosz =
sqrtf(1.
f - sinz2);
3285 const float theta = asinf(cosz);
3288 const float sin_phi =
sinf(phi);
3289 const float cos_phi =
cosf(phi);
3290 const float sin_theta =
sinf(theta);
3291 const float cos_theta =
cosf(theta);
3293 vec[0] = cos_theta * sin_phi;
3294 vec[1] = cos_theta * cos_phi;
3323 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3324 vec[1] = 1.f -
vf * 2.f;
3344 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3346 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3347 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3348 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3349 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3352 float uf,
vf, x, y, z;
3359 vf = 0.5f - y * 0.5f;
3361 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3362 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3363 uf = 0.25f * x + 0.25f;
3365 uf = 0.75f - 0.25f * x;
3377 for (
int i = 0;
i < 4;
i++) {
3378 for (
int j = 0; j < 4; j++) {
3398 s->iflat_range[0] =
s->ih_fov / 360.f;
3399 s->iflat_range[1] =
s->iv_fov / 360.f;
3418 const float ew =
width * 0.5f;
3421 const int ei =
i >= ew ?
i - ew :
i;
3422 const float m =
i >= ew ? 1.f : -1.f;
3424 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3425 const float vf =
s->flat_range[1] *
rescale(j, eh);
3427 const float h = hypotf(uf,
vf);
3428 const float lh =
h > 0.f ?
h : 1.f;
3429 const float theta = m *
M_PI_2 * (1.f -
h);
3431 const float sin_theta =
sinf(theta);
3432 const float cos_theta =
cosf(theta);
3434 vec[0] = cos_theta * m * uf / lh;
3435 vec[1] = cos_theta *
vf / lh;
3455 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3457 const float ew =
width * 0.5f;
3460 const float h = hypotf(vec[0], vec[1]);
3461 const float lh =
h > 0.f ?
h : 1.f;
3462 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3464 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3465 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3470 if (vec[2] >= 0.
f) {
3471 u_shift =
ceilf(ew);
3483 for (
int i = 0;
i < 4;
i++) {
3484 for (
int j = 0; j < 4; j++) {
3507 const float scale = 0.99f;
3508 float l_x, l_y, l_z;
3511 const float theta_range =
M_PI_4;
3513 const int ew = 4 *
width / 5;
3517 const float theta =
rescale(j, eh) * theta_range /
scale;
3519 const float sin_phi =
sinf(phi);
3520 const float cos_phi =
cosf(phi);
3521 const float sin_theta =
sinf(theta);
3522 const float cos_theta =
cosf(theta);
3524 l_x = cos_theta * sin_phi;
3526 l_z = cos_theta * cos_phi;
3528 const int ew =
width / 5;
3529 const int eh =
height / 2;
3577 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3579 const float scale = 0.99f;
3581 const float phi =
atan2f(vec[0], vec[2]);
3582 const float theta = asinf(vec[1]);
3583 const float theta_range =
M_PI_4;
3586 int u_shift, v_shift;
3590 if (theta > -theta_range && theta < theta_range) {
3598 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3606 uf = -vec[0] / vec[1];
3607 vf = -vec[2] / vec[1];
3610 uf = vec[0] / vec[1];
3611 vf = -vec[2] / vec[1];
3615 uf = 0.5f * ew * (uf *
scale + 1.f);
3625 for (
int i = 0;
i < 4;
i++) {
3626 for (
int j = 0; j < 4; j++) {
3628 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3649 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3651 const float phi =
atan2f(vec[0], vec[2]);
3652 const float theta = asinf(vec[1]);
3654 const float theta_range =
M_PI_4;
3657 int u_shift, v_shift;
3661 if (theta >= -theta_range && theta <= theta_range) {
3662 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3663 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3675 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3677 uf = (uf * scalew + 1.f) *
width / 3.
f;
3680 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3681 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3688 uf = vec[0] / vec[1] * scalew;
3689 vf = vec[2] / vec[1] * scaleh;
3691 if (theta <= 0.f && theta >= -
M_PI_2 &&
3692 phi <= M_PI_2 && phi >= -
M_PI_2) {
3695 vf = -(
vf + 1.f) * scaleh + 1.
f;
3697 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3698 phi <= M_PI_2 && phi >= -
M_PI_2) {
3700 vf = -(
vf - 1.f) * scaleh;
3701 v_shift =
height * 0.25f;
3702 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3704 vf = (
vf - 1.f) * scaleh + 1.
f;
3709 vf = (
vf + 1.f) * scaleh;
3710 v_shift =
height * 0.75f;
3713 uf = 0.5f *
width / 3.f * (uf + 1.f);
3723 for (
int i = 0;
i < 4;
i++) {
3724 for (
int j = 0; j < 4; j++) {
3726 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3747 const float x = (
i + 0.5f) /
width;
3748 const float y = (j + 0.5f) /
height;
3749 float l_x, l_y, l_z;
3752 if (x < 2.
f / 3.
f) {
3753 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3754 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3756 const float back =
floorf(y * 2.
f);
3758 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3759 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3761 const float sin_phi =
sinf(phi);
3762 const float cos_phi =
cosf(phi);
3763 const float sin_theta =
sinf(theta);
3764 const float cos_theta =
cosf(theta);
3766 l_x = cos_theta * sin_phi;
3768 l_z = cos_theta * cos_phi;
3772 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3773 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3775 const float facef =
floorf(y * 4.
f);
3776 const int face = facef;
3777 const float dir_vert = (face == 1 || face == 3) ? 1.0
f : -1.0
f;
3786 vf = (0.5f - 2.f * y) / scaleh + facef;
3790 vf = (y * 2.f - 1.5f) / scaleh + 3.
f - facef;
3795 l_x = (0.5f - uf) / scalew;
3796 l_y = 0.5f * dir_vert;
3797 l_z = (
vf - 0.5f) * dir_vert / scaleh;
3798 ret = (l_x * l_x * scalew * scalew + l_z * l_z * scaleh * scaleh) < 0.5
f * 0.5
f;
3822 const float x = (
i + 0.5f) /
width;
3823 const float y = (j + 0.5f) /
height;
3826 vec[0] = x * 4.f - 1.f;
3827 vec[1] = (y * 2.f - 1.f);
3829 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3830 y >= 0.375
f && y < 0.625
f) {
3831 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3832 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3834 }
else if (0.5
f <= x && x < 0.6875
f &&
3835 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3836 (0.375
f <= y && y < 0.625
f) ||
3837 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3839 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3840 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3841 }
else if (0.8125
f <= x && x < 1.
f &&
3842 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3843 (0.375
f <= y && y < 0.625
f) ||
3844 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3846 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3847 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3848 }
else if (0.
f <= y && y < 0.375
f &&
3849 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3850 (0.6875
f <= x && x < 0.8125
f) ||
3851 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3852 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3854 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3856 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3858 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3878 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3886 uf = (uf + 1.f) * 0.5
f;
3887 vf = (
vf + 1.f) * 0.5
f;
3891 uf = 0.1875f *
vf - 0.375f * uf *
vf - 0.125f * uf + 0.8125f;
3892 vf = 0.375f - 0.375f *
vf;
3898 uf = 1.f - 0.1875f *
vf - 0.5f * uf + 0.375f * uf *
vf;
3899 vf = 1.f - 0.375f *
vf;
3902 vf = 0.25f *
vf + 0.75f * uf *
vf - 0.375f * uf + 0.375f;
3903 uf = 0.1875f * uf + 0.8125f;
3906 vf = 0.375f * uf - 0.75f * uf *
vf +
vf;
3907 uf = 0.1875f * uf + 0.5f;
3910 uf = 0.125f * uf + 0.6875f;
3911 vf = 0.25f *
vf + 0.375f;
3924 for (
int i = 0;
i < 4;
i++) {
3925 for (
int j = 0; j < 4; j++) {
3950 const float ax =
fabsf(x);
3951 const float ay =
fabsf(y);
3953 vec[2] = 1.f - (ax + ay);
3954 if (ax + ay > 1.
f) {
3955 vec[0] = (1.f - ay) *
FFSIGN(x);
3956 vec[1] = (1.f - ax) *
FFSIGN(y);
3979 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4004 for (
int i = 0;
i < 4;
i++) {
4005 for (
int j = 0; j < 4; j++) {
4016 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4017 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4018 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4019 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4034 float rot_quaternion[2][4],
4035 const int rotation_order[3])
4037 const float yaw_rad = yaw *
M_PI / 180.f;
4038 const float pitch_rad = pitch *
M_PI / 180.f;
4039 const float roll_rad = roll *
M_PI / 180.f;
4041 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4042 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4043 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4044 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4045 const float sin_roll =
sinf(roll_rad * 0.5
f);
4046 const float cos_roll =
cosf(roll_rad * 0.5
f);
4051 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4052 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4053 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4068 static inline void rotate(
const float rot_quaternion[2][4],
4071 float qv[4],
temp[4], rqv[4];
4089 modifier[0] = h_flip ? -1.f : 1.f;
4090 modifier[1] = v_flip ? -1.f : 1.f;
4091 modifier[2] = d_flip ? -1.f : 1.f;
4094 static inline void mirror(
const float *modifier,
float *vec)
4096 vec[0] *= modifier[0];
4097 vec[1] *= modifier[1];
4098 vec[2] *= modifier[2];
4101 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4104 for (
int i = 0;
i < 4;
i++) {
4105 for (
int j = 0; j < 4; j++)
4106 u[
i][j] =
w - 1 -
u[
i][j];
4111 for (
int i = 0;
i < 4;
i++) {
4112 for (
int j = 0; j < 4; j++)
4113 v[
i][j] =
h - 1 - v[
i][j];
4120 const int pr_height =
s->pr_height[p];
4122 for (
int n = 0; n <
s->nb_threads; n++) {
4124 const int slice_start = (pr_height * n ) /
s->nb_threads;
4125 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4132 if (!
r->u[p] || !
r->v[p])
4141 if (sizeof_mask && !p) {
4157 *v_fov = d_fov * 0.5f;
4161 const float d = 0.5f * hypotf(
w,
h);
4162 const float l =
sinf(d_fov *
M_PI / 360.
f) / d;
4164 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4165 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4167 if (d_fov > 180.
f) {
4168 *h_fov = 180.f - *h_fov;
4169 *v_fov = 180.f - *v_fov;
4175 const float d = 0.5f * hypotf(
w,
h);
4176 const float l = d / (
sinf(d_fov *
M_PI / 720.
f));
4178 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4179 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4184 const float d = 0.5f * hypotf(
w,
h);
4185 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
4193 const float d = hypotf(
w * 0.5
f,
h);
4195 *h_fov = 0.5f *
w / d * d_fov;
4196 *v_fov =
h / d * d_fov;
4201 const float d = hypotf(
w,
h);
4203 *h_fov =
w / d * d_fov;
4204 *v_fov =
h / d * d_fov;
4210 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4211 const float d = hypotf(
w,
h);
4228 outw[0] = outw[3] =
w;
4230 outh[0] = outh[3] =
h;
4239 for (
int p = 0; p <
s->nb_allocated; p++) {
4240 const int max_value =
s->max_value;
4241 const int width =
s->pr_width[p];
4242 const int uv_linesize =
s->uv_linesize[p];
4243 const int height =
s->pr_height[p];
4244 const int in_width =
s->inplanewidth[p];
4245 const int in_height =
s->inplaneheight[p];
4258 uint8_t *mask8 = (p || !
r->mask) ?
NULL :
r->mask + ((j -
slice_start) *
s->pr_width[0] +
i);
4259 uint16_t *mask16 = (p || !
r->mask) ?
NULL : (uint16_t *)
r->mask + ((j -
slice_start) *
s->pr_width[0] +
i);
4260 int in_mask, out_mask;
4262 if (
s->out_transpose)
4269 rotate(
s->rot_quaternion, vec);
4272 mirror(
s->output_mirror_modifier, vec);
4273 if (
s->in_transpose)
4274 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4276 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4277 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4279 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4281 if (!p &&
r->mask) {
4282 if (
s->mask_size == 1) {
4283 mask8[0] = 255 * (out_mask & in_mask);
4285 mask16[0] = max_value * (out_mask & in_mask);
4301 const int depth =
desc->comp[0].depth;
4302 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4303 float default_h_fov = 360.f;
4304 float default_v_fov = 180.f;
4305 float default_ih_fov = 360.f;
4306 float default_iv_fov = 180.f;
4311 int in_offset_h, in_offset_w;
4312 int out_offset_h, out_offset_w;
4317 s->max_value = (1 << depth) - 1;
4319 switch (
s->interp) {
4322 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4324 sizeof_uv =
sizeof(int16_t) *
s->elements;
4329 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4330 s->elements = 2 * 2;
4331 sizeof_uv =
sizeof(int16_t) *
s->elements;
4332 sizeof_ker =
sizeof(int16_t) *
s->elements;
4336 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4337 s->elements = 3 * 3;
4338 sizeof_uv =
sizeof(int16_t) *
s->elements;
4339 sizeof_ker =
sizeof(int16_t) *
s->elements;
4343 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4344 s->elements = 4 * 4;
4345 sizeof_uv =
sizeof(int16_t) *
s->elements;
4346 sizeof_ker =
sizeof(int16_t) *
s->elements;
4350 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4351 s->elements = 4 * 4;
4352 sizeof_uv =
sizeof(int16_t) *
s->elements;
4353 sizeof_ker =
sizeof(int16_t) *
s->elements;
4357 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4358 s->elements = 4 * 4;
4359 sizeof_uv =
sizeof(int16_t) *
s->elements;
4360 sizeof_ker =
sizeof(int16_t) *
s->elements;
4364 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4365 s->elements = 4 * 4;
4366 sizeof_uv =
sizeof(int16_t) *
s->elements;
4367 sizeof_ker =
sizeof(int16_t) *
s->elements;
4371 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4372 s->elements = 4 * 4;
4373 sizeof_uv =
sizeof(int16_t) *
s->elements;
4374 sizeof_ker =
sizeof(int16_t) *
s->elements;
4382 for (
int order = 0; order <
NB_RORDERS; order++) {
4383 const char c =
s->rorder[order];
4388 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4389 s->rotation_order[0] =
YAW;
4390 s->rotation_order[1] =
PITCH;
4391 s->rotation_order[2] =
ROLL;
4398 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4399 s->rotation_order[0] =
YAW;
4400 s->rotation_order[1] =
PITCH;
4401 s->rotation_order[2] =
ROLL;
4405 s->rotation_order[order] = rorder;
4408 switch (
s->in_stereo) {
4412 in_offset_w = in_offset_h = 0;
4433 s->in_width =
s->inplanewidth[0];
4434 s->in_height =
s->inplaneheight[0];
4439 default_ih_fov = 90.f;
4440 default_iv_fov = 45.f;
4447 default_ih_fov = 180.f;
4448 default_iv_fov = 180.f;
4453 if (
s->ih_fov == 0.f)
4454 s->ih_fov = default_ih_fov;
4456 if (
s->iv_fov == 0.f)
4457 s->iv_fov = default_iv_fov;
4459 if (
s->id_fov > 0.f)
4462 if (
s->in_transpose)
4463 FFSWAP(
int,
s->in_width,
s->in_height);
4779 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4780 s->out ==
FLAT &&
s->d_fov == 0.f) {
4782 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4783 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4784 s->out ==
FLAT &&
s->d_fov == 0.f) {
4786 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4787 }
else if (
s->width > 0 &&
s->height > 0) {
4790 }
else if (
s->width > 0 ||
s->height > 0) {
4794 if (
s->out_transpose)
4797 if (
s->in_transpose)
4807 default_h_fov = 90.f;
4808 default_v_fov = 45.f;
4815 default_h_fov = 180.f;
4816 default_v_fov = 180.f;
4822 if (
s->h_fov == 0.f)
4823 s->h_fov = default_h_fov;
4825 if (
s->v_fov == 0.f)
4826 s->v_fov = default_v_fov;
4832 err = prepare_out(
ctx);
4839 switch (
s->out_stereo) {
4841 out_offset_w = out_offset_h = 0;
4860 for (
int i = 0;
i < 4;
i++)
4870 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4871 s->nb_allocated = 1;
4872 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4874 s->nb_allocated = 2;
4875 s->map[0] =
s->map[3] = 0;
4876 s->map[1] =
s->map[2] = 1;
4879 if (!
s->slice_remap)
4880 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4881 if (!
s->slice_remap)
4884 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4885 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4891 s->rot_quaternion,
s->rotation_order);
4926 s->rot_quaternion[0][0] = 1.f;
4927 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4931 char *res,
int res_len,
int flags)
4936 if (
s->reset_rot <= 0)
4937 s->yaw =
s->pitch =
s->roll = 0.f;
4938 if (
s->reset_rot < 0)
4964 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4967 for (
int p = 0; p <
s->nb_allocated; p++) {
5004 .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.
static const uint8_t q1[256]
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.
static const ElemCat * elements[ELEMENT_COUNT]
#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 __device__ float floorf(float a)
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
static int prepare_equirect_out(AVFilterContext *ctx)
Prepare data for processing equirectangular output format.
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
static int prepare_orthographic_out(AVFilterContext *ctx)
Prepare data for processing orthographic output format.
#define FILTER_INPUTS(array)
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.
#define NEAREST(type, name)
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)
A link between two filters.
AVFILTER_DEFINE_CLASS(v360)
#define AV_PIX_FMT_YUVA422P10
static __device__ float ceilf(float a)
static int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static av_cold int init(AVFilterContext *ctx)
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
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
@ 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
static void conjugate_quaternion(float d[4], const float q[4])
#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 prepare_equisolid_in(AVFilterContext *ctx)
Prepare data for processing equisolid input format.
static int xyz_to_orthographic(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 orthographic format for corresponding 3D coordinates on sphere.
static av_always_inline float scale(float x, float s)
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 __device__ float fabsf(float a)
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.
static void rotate(const float rot_quaternion[2][4], float *vec)
Rotate vector with given rotation quaternion.
#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 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
static int orthographic_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 orthographic format.
@ 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 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 int octahedron_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 octahedron format.
static void calculate_spline16_coeffs(float t, float *coeffs)
Calculate 1-dimensional spline16 coefficients.
static int prepare_equirect_in(AVFilterContext *ctx)
Prepare data for processing equirectangular input format.
#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
#define AV_CEIL_RSHIFT(a, b)
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 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
static int xyz_to_octahedron(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 octahedron format for corresponding 3D coordinates on sphere.
#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)
#define FILTER_OUTPUTS(array)
static void reset_rot(V360Context *s)
static void mitchell_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for mitchell interpolation.
static const uint8_t q0[256]
@ 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
static void offset_vector(float *vec, float h_offset, float v_offset)
Offset vector.
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 int prepare_cylindricalea_out(AVFilterContext *ctx)
Prepare data for processing cylindrical equal area output format.
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 __device__ float sqrtf(float a)
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 int prepare_dfisheye_in(AVFilterContext *ctx)
Prepare data for processing double fisheye input 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.
#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)
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
static int prepare_equisolid_out(AVFilterContext *ctx)
Prepare data for processing equisolid output format.
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 av_always_inline float rescale(int x, float s)
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.
static void calculate_cubic_bc_coeffs(float t, float *coeffs, float b, float c)
Calculate 1-dimensional cubic_bc_spline coefficients.
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
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t * hf
const char * name
Pad name.
static int equisolid_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 equisolid format.
void * av_calloc(size_t nmemb, size_t size)
#define AV_PIX_FMT_YUV444P9
static int mod(int a, int b)
Modulo operation with only positive remainders.
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
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.
#define FFSWAP(type, a, b)
static int xyz_to_cylindricalea(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 equal area format for corresponding 3D coordinates on sphere.
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)
static int xyz_to_equisolid(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 equisolid format for corresponding 3D coordinates on sphere.
#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.
int h
agreed upon image height
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
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.
static int cylindricalea_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 equal area format.
#define AV_PIX_FMT_YUVA422P12
@ AV_OPT_TYPE_INT
Underlying C type is int.
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 void multiply_quaternion(float c[4], const float a[4], const float b[4])
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[]
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
static void input_flip(int16_t u[4][4], int16_t v[4][4], int w, int h, int hflip, int vflip)
static void calculate_rotation(float yaw, float pitch, float roll, float rot_quaternion[2][4], const int rotation_order[3])
Calculate rotation quaternion for yaw/pitch/roll angles.
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)
static int prepare_cylindricalea_in(AVFilterContext *ctx)
Prepare data for processing cylindrical equal area input format.
#define AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV444P14
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AV_PIX_FMT_GRAY12
static enum AVPixelFormat alpha_pix_fmts[]
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t const int8_t * vf
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
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)
#define FILTER_QUERY_FUNC(func)
@ 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.
const AVFilter ff_vf_v360
static int prepare_orthographic_in(AVFilterContext *ctx)
Prepare data for processing orthographic input format.