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
259 #define DEFINE_REMAP1_LINE(bits, div) \
260 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
261 ptrdiff_t in_linesize, \
262 const int16_t *const u, const int16_t *const v, \
263 const int16_t *const ker) \
265 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
266 uint##bits##_t *d = (uint##bits##_t *)dst; \
268 in_linesize /= div; \
270 for (int x = 0; x < width; x++) \
271 d[x] = s[v[x] * in_linesize + u[x]]; \
283 #define DEFINE_REMAP(ws, bits) \
284 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
286 ThreadData *td = arg; \
287 const V360Context *s = ctx->priv; \
288 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
289 const AVFrame *in = td->in; \
290 AVFrame *out = td->out; \
292 av_assert1(s->nb_planes <= AV_VIDEO_MAX_PLANES); \
294 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
295 for (int plane = 0; plane < s->nb_planes; plane++) { \
296 const unsigned map = s->map[plane]; \
297 const int in_linesize = in->linesize[plane]; \
298 const int out_linesize = out->linesize[plane]; \
299 const int uv_linesize = s->uv_linesize[plane]; \
300 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
301 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
302 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
303 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
304 const uint8_t *const src = in->data[plane] + \
305 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
306 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
307 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
308 const int width = s->pr_width[plane]; \
309 const int height = s->pr_height[plane]; \
311 const int slice_start = (height * jobnr ) / nb_jobs; \
312 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
314 for (int y = slice_start; y < slice_end && !mask; y++) { \
315 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
316 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
317 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
319 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
322 for (int y = slice_start; y < slice_end && mask; y++) { \
323 memcpy(dst + y * out_linesize, mask + \
324 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
341 #define DEFINE_REMAP_LINE(ws, bits, div) \
342 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
343 ptrdiff_t in_linesize, \
344 const int16_t *const u, const int16_t *const v, \
345 const int16_t *const ker) \
347 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
348 uint##bits##_t *d = (uint##bits##_t *)dst; \
350 in_linesize /= div; \
352 for (int x = 0; x < width; x++) { \
353 const int16_t *const uu = u + x * ws * ws; \
354 const int16_t *const vv = v + x * ws * ws; \
355 const int16_t *const kker = ker + x * ws * ws; \
358 for (int i = 0; i < ws; i++) { \
359 const int iws = i * ws; \
360 for (int j = 0; j < ws; j++) { \
361 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
365 d[x] = av_clip_uint##bits(tmp >> 14); \
380 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
383 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
386 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
393 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
413 int16_t *
u, int16_t *v, int16_t *ker)
416 const int j =
lrintf(du) + 1;
418 u[0] = rmap->
u[
i][j];
419 v[0] = rmap->
v[
i][j];
433 int16_t *
u, int16_t *v, int16_t *ker)
435 for (
int i = 0;
i < 2;
i++) {
436 for (
int j = 0; j < 2; j++) {
437 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
438 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
442 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
443 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
444 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
445 ker[3] =
lrintf( du * dv * 16385.
f);
456 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
457 coeffs[1] = -t * (t - 2.f);
458 coeffs[2] = t * (t - 1.f) * 0.5
f;
472 int16_t *
u, int16_t *v, int16_t *ker)
480 for (
int i = 0;
i < 3;
i++) {
481 for (
int j = 0; j < 3; j++) {
482 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
483 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
484 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
497 const float tt = t * t;
498 const float ttt = t * t * t;
500 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
501 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
502 coeffs[2] = t + tt / 2.f - ttt / 2.f;
503 coeffs[3] = - t / 6.f + ttt / 6.f;
517 int16_t *
u, int16_t *v, int16_t *ker)
525 for (
int i = 0;
i < 4;
i++) {
526 for (
int j = 0; j < 4; j++) {
527 u[
i * 4 + j] = rmap->
u[
i][j];
528 v[
i * 4 + j] = rmap->
v[
i][j];
529 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
544 for (
int i = 0;
i < 4;
i++) {
545 const float x =
M_PI * (t -
i + 1);
549 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
554 for (
int i = 0;
i < 4;
i++) {
570 int16_t *
u, int16_t *v, int16_t *ker)
578 for (
int i = 0;
i < 4;
i++) {
579 for (
int j = 0; j < 4; j++) {
580 u[
i * 4 + j] = rmap->
u[
i][j];
581 v[
i * 4 + j] = rmap->
v[
i][j];
582 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
595 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
596 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
597 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
598 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
612 int16_t *
u, int16_t *v, int16_t *ker)
620 for (
int i = 0;
i < 4;
i++) {
621 for (
int j = 0; j < 4; j++) {
622 u[
i * 4 + j] = rmap->
u[
i][j];
623 v[
i * 4 + j] = rmap->
v[
i][j];
624 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
639 for (
int i = 0;
i < 4;
i++) {
640 const float x = t - (
i - 1);
644 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
649 for (
int i = 0;
i < 4;
i++) {
665 int16_t *
u, int16_t *v, int16_t *ker)
673 for (
int i = 0;
i < 4;
i++) {
674 for (
int j = 0; j < 4; j++) {
675 u[
i * 4 + j] = rmap->
u[
i][j];
676 v[
i * 4 + j] = rmap->
v[
i][j];
677 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
692 float p0 = (6.f - 2.f *
b) / 6.
f,
693 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
694 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
695 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
696 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
697 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
698 q3 = (-
b - 6.f *
c) / 6.
f;
700 for (
int i = 0;
i < 4;
i++) {
701 const float x =
fabsf(t -
i + 1.
f);
703 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
704 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
705 }
else if (x < 2.
f) {
706 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
707 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
714 for (
int i = 0;
i < 4;
i++) {
730 int16_t *
u, int16_t *v, int16_t *ker)
738 for (
int i = 0;
i < 4;
i++) {
739 for (
int j = 0; j < 4; j++) {
740 u[
i * 4 + j] = rmap->
u[
i][j];
741 v[
i * 4 + j] = rmap->
v[
i][j];
742 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
757 const int res =
a %
b;
889 for (
int face = 0; face <
NB_FACES; face++) {
890 const char c =
s->in_forder[face];
895 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
900 if (direction == -1) {
902 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
906 s->in_cubemap_face_order[direction] = face;
909 for (
int face = 0; face <
NB_FACES; face++) {
910 const char c =
s->in_frot[face];
915 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
920 if (rotation == -1) {
922 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
926 s->in_cubemap_face_rotation[face] = rotation;
943 for (
int face = 0; face <
NB_FACES; face++) {
944 const char c =
s->out_forder[face];
949 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
954 if (direction == -1) {
956 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
960 s->out_cubemap_direction_order[face] = direction;
963 for (
int face = 0; face <
NB_FACES; face++) {
964 const char c =
s->out_frot[face];
969 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
974 if (rotation == -1) {
976 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
980 s->out_cubemap_face_rotation[face] = rotation;
1056 const float norm =
sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1076 float uf,
float vf,
int face,
1077 float *vec,
float scalew,
float scaleh)
1079 const int direction =
s->out_cubemap_direction_order[face];
1080 float l_x, l_y, l_z;
1087 switch (direction) {
1139 float *uf,
float *
vf,
int *direction)
1141 const float phi =
atan2f(vec[0], vec[2]);
1142 const float theta = asinf(vec[1]);
1143 float phi_norm, theta_threshold;
1157 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1160 theta_threshold =
atanf(
cosf(phi_norm));
1161 if (theta > theta_threshold) {
1163 }
else if (theta < -theta_threshold) {
1167 switch (*direction) {
1169 *uf = -vec[2] / vec[0];
1170 *
vf = vec[1] / vec[0];
1173 *uf = -vec[2] / vec[0];
1174 *
vf = -vec[1] / vec[0];
1177 *uf = -vec[0] / vec[1];
1178 *
vf = -vec[2] / vec[1];
1181 *uf = vec[0] / vec[1];
1182 *
vf = -vec[2] / vec[1];
1185 *uf = vec[0] / vec[2];
1186 *
vf = vec[1] / vec[2];
1189 *uf = vec[0] / vec[2];
1190 *
vf = -vec[1] / vec[2];
1196 face =
s->in_cubemap_face_order[*direction];
1213 float uf,
float vf,
int direction,
1214 float *new_uf,
float *new_vf,
int *face)
1233 *face =
s->in_cubemap_face_order[direction];
1236 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1240 }
else if (uf < -1.
f) {
1242 switch (direction) {
1276 }
else if (uf >= 1.
f) {
1278 switch (direction) {
1312 }
else if (
vf < -1.
f) {
1314 switch (direction) {
1348 }
else if (
vf >= 1.
f) {
1350 switch (direction) {
1390 *face =
s->in_cubemap_face_order[direction];
1396 return (0.5
f * x + 0.5
f) * (
s - 1.f);
1401 return (2.
f * x + 1.
f) /
s - 1.f;
1418 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1419 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1421 const float ew =
width / 3.f;
1422 const float eh =
height / 2.f;
1424 const int u_face =
floorf(
i / ew);
1425 const int v_face =
floorf(j / eh);
1426 const int face = u_face + 3 * v_face;
1428 const int u_shift =
ceilf(ew * u_face);
1429 const int v_shift =
ceilf(eh * v_face);
1430 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1431 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1433 const float uf =
rescale(
i - u_shift, ewi);
1434 const float vf =
rescale(j - v_shift, ehi);
1455 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1457 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1458 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1459 const float ew =
width / 3.f;
1460 const float eh =
height / 2.f;
1464 int direction, face;
1472 face =
s->in_cubemap_face_order[direction];
1475 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1476 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1478 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1479 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1487 for (
int i = 0;
i < 4;
i++) {
1488 for (
int j = 0; j < 4; j++) {
1489 int new_ui =
ui + j - 1;
1490 int new_vi = vi +
i - 1;
1491 int u_shift, v_shift;
1492 int new_ewi, new_ehi;
1494 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1495 face =
s->in_cubemap_face_order[direction];
1499 u_shift =
ceilf(ew * u_face);
1500 v_shift =
ceilf(eh * v_face);
1502 uf = 2.f * new_ui / ewi - 1.f;
1503 vf = 2.f * new_vi / ehi - 1.f;
1515 u_shift =
ceilf(ew * u_face);
1516 v_shift =
ceilf(eh * v_face);
1517 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1518 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1520 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1524 us[
i][j] = u_shift + new_ui;
1525 vs[
i][j] = v_shift + new_vi;
1546 const float scalew =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1547 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1549 const float ew =
width;
1550 const float eh =
height / 6.f;
1552 const int face =
floorf(j / eh);
1554 const int v_shift =
ceilf(eh * face);
1555 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1558 const float vf =
rescale(j - v_shift, ehi);
1579 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1580 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1582 const float ew =
width / 6.f;
1585 const int face =
floorf(
i / ew);
1587 const int u_shift =
ceilf(ew * face);
1588 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1590 const float uf =
rescale(
i - u_shift, ewi);
1612 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1614 const float scalew =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1615 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1616 const float eh =
height / 6.f;
1617 const int ewi =
width;
1621 int direction, face;
1628 face =
s->in_cubemap_face_order[direction];
1629 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1631 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1632 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1640 for (
int i = 0;
i < 4;
i++) {
1641 for (
int j = 0; j < 4; j++) {
1642 int new_ui =
ui + j - 1;
1643 int new_vi = vi +
i - 1;
1647 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1648 face =
s->in_cubemap_face_order[direction];
1650 v_shift =
ceilf(eh * face);
1652 uf = 2.f * new_ui / ewi - 1.f;
1653 vf = 2.f * new_vi / ehi - 1.f;
1663 v_shift =
ceilf(eh * face);
1664 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1671 vs[
i][j] = v_shift + new_vi;
1692 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1694 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1695 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1696 const float ew =
width / 6.f;
1701 int direction, face;
1708 face =
s->in_cubemap_face_order[direction];
1709 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1711 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1712 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1720 for (
int i = 0;
i < 4;
i++) {
1721 for (
int j = 0; j < 4; j++) {
1722 int new_ui =
ui + j - 1;
1723 int new_vi = vi +
i - 1;
1727 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1728 face =
s->in_cubemap_face_order[direction];
1730 u_shift =
ceilf(ew * face);
1732 uf = 2.f * new_ui / ewi - 1.f;
1733 vf = 2.f * new_vi / ehi - 1.f;
1743 u_shift =
ceilf(ew * face);
1744 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1746 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1750 us[
i][j] = u_shift + new_ui;
1769 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
1770 s->flat_range[1] =
s->v_fov *
M_PI / 360.f;
1792 const float sin_phi =
sinf(phi);
1793 const float cos_phi =
cosf(phi);
1794 const float sin_theta =
sinf(theta);
1795 const float cos_theta =
cosf(theta);
1797 vec[0] = cos_theta * sin_phi;
1799 vec[2] = cos_theta * cos_phi;
1821 const float sin_phi =
sinf(phi);
1822 const float cos_phi =
cosf(phi);
1823 const float sin_theta =
sinf(theta);
1824 const float cos_theta =
cosf(theta);
1826 vec[0] = cos_theta * sin_phi;
1828 vec[2] = cos_theta * cos_phi;
1844 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1845 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1866 const float r = hypotf(x, y);
1867 const float theta =
atanf(
r) * 2.f;
1868 const float sin_theta =
sinf(theta);
1870 vec[0] = x /
r * sin_theta;
1871 vec[1] = y /
r * sin_theta;
1872 vec[2] =
cosf(theta);
1888 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1889 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1908 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1910 const float theta = acosf(vec[2]);
1911 const float r = tanf(theta * 0.5
f);
1912 const float c =
r / hypotf(vec[0], vec[1]);
1913 const float x = vec[0] *
c /
s->iflat_range[0];
1914 const float y = vec[1] *
c /
s->iflat_range[1];
1924 *du = visible ? uf -
ui : 0.f;
1925 *dv = visible ?
vf - vi : 0.f;
1927 for (
int i = 0;
i < 4;
i++) {
1928 for (
int j = 0; j < 4; j++) {
1948 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1949 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1970 const float r = hypotf(x, y);
1971 const float theta = asinf(
r) * 2.f;
1972 const float sin_theta =
sinf(theta);
1974 vec[0] = x /
r * sin_theta;
1975 vec[1] = y /
r * sin_theta;
1976 vec[2] =
cosf(theta);
2012 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2014 const float theta = acosf(vec[2]);
2015 const float r =
sinf(theta * 0.5
f);
2016 const float c =
r / hypotf(vec[0], vec[1]);
2017 const float x = vec[0] *
c /
s->iflat_range[0];
2018 const float y = vec[1] *
c /
s->iflat_range[1];
2028 *du = visible ? uf -
ui : 0.f;
2029 *dv = visible ?
vf - vi : 0.f;
2031 for (
int i = 0;
i < 4;
i++) {
2032 for (
int j = 0; j < 4; j++) {
2074 const float r = hypotf(x, y);
2075 const float theta = asinf(
r);
2077 vec[2] =
cosf(theta);
2123 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2125 const float theta = acosf(vec[2]);
2126 const float r =
sinf(theta);
2127 const float c =
r / hypotf(vec[0], vec[1]);
2128 const float x = vec[0] *
c /
s->iflat_range[0];
2129 const float y = vec[1] *
c /
s->iflat_range[1];
2137 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2139 *du = visible ? uf -
ui : 0.f;
2140 *dv = visible ?
vf - vi : 0.f;
2142 for (
int i = 0;
i < 4;
i++) {
2143 for (
int j = 0; j < 4; j++) {
2163 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2164 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2183 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2185 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2186 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2198 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2200 for (
int i = 0;
i < 4;
i++) {
2201 for (
int j = 0; j < 4; j++) {
2224 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2227 const float theta = asinf(vec[1]) /
M_PI_2;
2240 for (
int i = 0;
i < 4;
i++) {
2241 for (
int j = 0; j < 4; j++) {
2261 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2262 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2281 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2283 const float theta = acosf(vec[2]);
2284 const float r = tanf(theta);
2286 const float zf = vec[2];
2287 const float h = hypotf(vec[0], vec[1]);
2288 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2289 float uf = vec[0] *
c /
s->iflat_range[0];
2290 float vf = vec[1] *
c /
s->iflat_range[1];
2291 int visible,
ui, vi;
2299 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2304 for (
int i = 0;
i < 4;
i++) {
2305 for (
int j = 0; j < 4; j++) {
2328 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2330 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2331 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2342 for (
int i = 0;
i < 4;
i++) {
2343 for (
int j = 0; j < 4; j++) {
2368 const float div =
expf(2.
f * y) + 1.f;
2370 const float sin_phi =
sinf(phi);
2371 const float cos_phi =
cosf(phi);
2372 const float sin_theta = 2.f *
expf(y) / div;
2373 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2375 vec[0] = -sin_theta * cos_phi;
2377 vec[2] = sin_theta * sin_phi;
2396 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2398 const float l = hypotf(vec[0], vec[1]);
2400 const float d = l > 0.f ? l : 1.f;
2411 for (
int i = 0;
i < 4;
i++) {
2412 for (
int j = 0; j < 4; j++) {
2437 const float l = hypotf(x, y);
2440 const float z = 2.f * l *
sqrtf(1.
f - l * l);
2442 vec[0] = z * x / (l > 0.f ? l : 1.f);
2443 vec[1] = z * y / (l > 0.f ? l : 1.f);
2444 vec[2] = 1.f - 2.f * l * l;
2472 const float xx = x * x;
2473 const float yy = y * y;
2475 const float z =
sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2478 const float b = 2.f * z * z - 1.f;
2480 const float aa =
a *
a;
2481 const float bb =
b *
b;
2483 const float w =
sqrtf(1.
f - 2.
f * yy * z * z);
2485 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2487 vec[2] =
w * (bb - aa) / (aa + bb);
2506 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2508 const float theta =
atan2f(vec[0], vec[2]);
2511 const float x =
sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2512 const float y = vec[1] / z;
2514 const float uf = (x + 1.f) *
width / 2.
f;
2515 const float vf = (y + 1.f) *
height / 2.
f;
2523 for (
int i = 0;
i < 4;
i++) {
2524 for (
int j = 0; j < 4; j++) {
2550 const float sin_phi =
sinf(phi);
2551 const float cos_phi =
cosf(phi);
2552 const float sin_theta =
sinf(theta);
2553 const float cos_theta =
cosf(theta);
2555 vec[0] = cos_theta * sin_phi;
2557 vec[2] = cos_theta * cos_phi;
2576 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2578 const float theta = asinf(vec[1]);
2579 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2590 for (
int i = 0;
i < 4;
i++) {
2591 for (
int j = 0; j < 4; j++) {
2670 const float pixel_pad = 2;
2671 const float u_pad = pixel_pad /
width;
2672 const float v_pad = pixel_pad /
height;
2674 int u_face, v_face, face;
2676 float l_x, l_y, l_z;
2678 float uf = (
i + 0.5f) /
width;
2686 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2690 }
else if (uf >= 3.
f) {
2695 uf = fmodf(uf, 1.
f) - 0.5f;
2700 vf = (
vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2702 if (uf >= -0.5
f && uf < 0.5
f) {
2707 if (
vf >= -0.5
f &&
vf < 0.5
f) {
2713 face = u_face + 3 * v_face;
2771 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2773 const float pixel_pad = 2;
2774 const float u_pad = pixel_pad /
width;
2775 const float v_pad = pixel_pad /
height;
2779 int direction, face;
2784 face =
s->in_cubemap_face_order[direction];
2792 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2793 vf =
vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2807 for (
int i = 0;
i < 4;
i++) {
2808 for (
int j = 0; j < 4; j++) {
2828 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2829 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2869 s->flat_range[0] =
s->h_fov / 180.f;
2870 s->flat_range[1] =
s->v_fov / 180.f;
2893 const float theta =
M_PI_2 * (1.f - hypotf(uf,
vf));
2895 const float sin_phi =
sinf(phi);
2896 const float cos_phi =
cosf(phi);
2897 const float sin_theta =
sinf(theta);
2898 const float cos_theta =
cosf(theta);
2900 vec[0] = cos_theta * cos_phi;
2901 vec[1] = cos_theta * sin_phi;
2918 s->iflat_range[0] =
s->ih_fov / 180.f;
2919 s->iflat_range[1] =
s->iv_fov / 180.f;
2938 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2940 const float h = hypotf(vec[0], vec[1]);
2941 const float lh =
h > 0.f ?
h : 1.f;
2944 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2945 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2947 const int visible = -0.5f < uf && uf < 0.5f && -0.5f <
vf &&
vf < 0.5f;
2956 *du = visible ? uf -
ui : 0.f;
2957 *dv = visible ?
vf - vi : 0.f;
2959 for (
int i = 0;
i < 4;
i++) {
2960 for (
int j = 0; j < 4; j++) {
2986 const float d =
s->h_fov;
2987 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2988 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2989 const float clon = (-k * d +
sqrtf(dscr)) / (k + 1.
f);
2990 const float S = (d + 1.f) / (d + clon);
2991 const float lon =
atan2f(uf,
S * clon);
3015 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3017 const float phi =
atan2f(vec[0], vec[2]);
3018 const float theta = asinf(vec[1]);
3020 const float d =
s->ih_fov;
3021 const float S = (d + 1.f) / (d +
cosf(phi));
3023 const float x =
S *
sinf(phi);
3024 const float y =
S * tanf(theta);
3032 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3037 for (
int i = 0;
i < 4;
i++) {
3038 for (
int j = 0; j < 4; j++) {
3058 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3059 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3081 const float phi = uf;
3082 const float theta =
atanf(
vf);
3084 const float sin_phi =
sinf(phi);
3085 const float cos_phi =
cosf(phi);
3086 const float sin_theta =
sinf(theta);
3087 const float cos_theta =
cosf(theta);
3089 vec[0] = cos_theta * sin_phi;
3091 vec[2] = cos_theta * cos_phi;
3107 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3108 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3127 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3129 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3130 const float theta = asinf(vec[1]);
3138 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3139 theta <=
M_PI *
s->iv_fov / 180.f &&
3140 theta >= -
M_PI *
s->iv_fov / 180.f;
3145 for (
int i = 0;
i < 4;
i++) {
3146 for (
int j = 0; j < 4; j++) {
3166 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3167 s->flat_range[1] =
s->v_fov / 180.f;
3183 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3184 s->iflat_range[1] =
s->iv_fov / 180.f;
3206 const float phi = uf;
3207 const float theta = asinf(
vf);
3209 const float sin_phi =
sinf(phi);
3210 const float cos_phi =
cosf(phi);
3211 const float sin_theta =
sinf(theta);
3212 const float cos_theta =
cosf(theta);
3214 vec[0] = cos_theta * sin_phi;
3216 vec[2] = cos_theta * cos_phi;
3235 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3237 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3238 const float theta = asinf(vec[1]);
3246 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3247 theta <=
M_PI *
s->iv_fov / 180.f &&
3248 theta >= -
M_PI *
s->iv_fov / 180.f;
3253 for (
int i = 0;
i < 4;
i++) {
3254 for (
int j = 0; j < 4; j++) {
3279 const float rh = hypotf(uf,
vf);
3280 const float sinzz = 1.f - rh * rh;
3281 const float h = 1.f +
s->v_fov;
3282 const float sinz = (
h -
sqrtf(sinzz)) / (
h / rh + rh /
h);
3283 const float sinz2 = sinz * sinz;
3286 const float cosz =
sqrtf(1.
f - sinz2);
3288 const float theta = asinf(cosz);
3291 const float sin_phi =
sinf(phi);
3292 const float cos_phi =
cosf(phi);
3293 const float sin_theta =
sinf(theta);
3294 const float cos_theta =
cosf(theta);
3296 vec[0] = cos_theta * sin_phi;
3297 vec[1] = cos_theta * cos_phi;
3326 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3327 vec[1] = 1.f -
vf * 2.f;
3347 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3349 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3350 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3351 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3352 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3355 float uf,
vf, x, y, z;
3362 vf = 0.5f - y * 0.5f;
3364 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3365 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3366 uf = 0.25f * x + 0.25f;
3368 uf = 0.75f - 0.25f * x;
3380 for (
int i = 0;
i < 4;
i++) {
3381 for (
int j = 0; j < 4; j++) {
3401 s->iflat_range[0] =
s->ih_fov / 360.f;
3402 s->iflat_range[1] =
s->iv_fov / 360.f;
3421 const float ew =
width * 0.5f;
3424 const int ei =
i >= ew ?
i - ew :
i;
3425 const float m =
i >= ew ? 1.f : -1.f;
3427 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3428 const float vf =
s->flat_range[1] *
rescale(j, eh);
3430 const float h = hypotf(uf,
vf);
3431 const float lh =
h > 0.f ?
h : 1.f;
3432 const float theta = m *
M_PI_2 * (1.f -
h);
3434 const float sin_theta =
sinf(theta);
3435 const float cos_theta =
cosf(theta);
3437 vec[0] = cos_theta * m * uf / lh;
3438 vec[1] = cos_theta *
vf / lh;
3458 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3460 const float ew =
width * 0.5f;
3463 const float h = hypotf(vec[0], vec[1]);
3464 const float lh =
h > 0.f ?
h : 1.f;
3465 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3467 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3468 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3473 if (vec[2] >= 0.
f) {
3474 u_shift =
ceilf(ew);
3486 for (
int i = 0;
i < 4;
i++) {
3487 for (
int j = 0; j < 4; j++) {
3510 const float scale = 0.99f;
3511 float l_x, l_y, l_z;
3514 const float theta_range =
M_PI_4;
3516 const int ew = 4 *
width / 5;
3520 const float theta =
rescale(j, eh) * theta_range /
scale;
3522 const float sin_phi =
sinf(phi);
3523 const float cos_phi =
cosf(phi);
3524 const float sin_theta =
sinf(theta);
3525 const float cos_theta =
cosf(theta);
3527 l_x = cos_theta * sin_phi;
3529 l_z = cos_theta * cos_phi;
3531 const int ew =
width / 5;
3532 const int eh =
height / 2;
3580 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3582 const float scale = 0.99f;
3584 const float phi =
atan2f(vec[0], vec[2]);
3585 const float theta = asinf(vec[1]);
3586 const float theta_range =
M_PI_4;
3589 int u_shift, v_shift;
3593 if (theta > -theta_range && theta < theta_range) {
3601 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3609 uf = -vec[0] / vec[1];
3610 vf = -vec[2] / vec[1];
3613 uf = vec[0] / vec[1];
3614 vf = -vec[2] / vec[1];
3618 uf = 0.5f * ew * (uf *
scale + 1.f);
3628 for (
int i = 0;
i < 4;
i++) {
3629 for (
int j = 0; j < 4; j++) {
3631 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3652 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3654 const float phi =
atan2f(vec[0], vec[2]);
3655 const float theta = asinf(vec[1]);
3657 const float theta_range =
M_PI_4;
3660 int u_shift, v_shift;
3664 if (theta >= -theta_range && theta <= theta_range) {
3665 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3666 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3678 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3680 uf = (uf * scalew + 1.f) *
width / 3.
f;
3683 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3684 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3691 uf = vec[0] / vec[1] * scalew;
3692 vf = vec[2] / vec[1] * scaleh;
3694 if (theta <= 0.f && theta >= -
M_PI_2 &&
3695 phi <= M_PI_2 && phi >= -
M_PI_2) {
3698 vf = -(
vf + 1.f) * scaleh + 1.
f;
3700 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3701 phi <= M_PI_2 && phi >= -
M_PI_2) {
3703 vf = -(
vf - 1.f) * scaleh;
3704 v_shift =
height * 0.25f;
3705 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3707 vf = (
vf - 1.f) * scaleh + 1.
f;
3712 vf = (
vf + 1.f) * scaleh;
3713 v_shift =
height * 0.75f;
3716 uf = 0.5f *
width / 3.f * (uf + 1.f);
3726 for (
int i = 0;
i < 4;
i++) {
3727 for (
int j = 0; j < 4; j++) {
3729 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3750 const float x = (
i + 0.5f) /
width;
3751 const float y = (j + 0.5f) /
height;
3752 float l_x, l_y, l_z;
3755 if (x < 2.
f / 3.
f) {
3756 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3757 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3759 const float back =
floorf(y * 2.
f);
3761 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3762 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3764 const float sin_phi =
sinf(phi);
3765 const float cos_phi =
cosf(phi);
3766 const float sin_theta =
sinf(theta);
3767 const float cos_theta =
cosf(theta);
3769 l_x = cos_theta * sin_phi;
3771 l_z = cos_theta * cos_phi;
3775 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3776 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3778 const float facef =
floorf(y * 4.
f);
3779 const int face = facef;
3780 const float dir_vert = (face == 1 || face == 3) ? 1.0
f : -1.0
f;
3789 vf = (0.5f - 2.f * y) / scaleh + facef;
3793 vf = (y * 2.f - 1.5f) / scaleh + 3.
f - facef;
3798 l_x = (0.5f - uf) / scalew;
3799 l_y = 0.5f * dir_vert;
3800 l_z = (
vf - 0.5f) * dir_vert / scaleh;
3801 ret = (l_x * l_x * scalew * scalew + l_z * l_z * scaleh * scaleh) < 0.5
f * 0.5
f;
3825 const float x = (
i + 0.5f) /
width;
3826 const float y = (j + 0.5f) /
height;
3829 vec[0] = x * 4.f - 1.f;
3830 vec[1] = (y * 2.f - 1.f);
3832 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3833 y >= 0.375
f && y < 0.625
f) {
3834 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3835 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3837 }
else if (0.5
f <= x && x < 0.6875
f &&
3838 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3839 (0.375
f <= y && y < 0.625
f) ||
3840 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3842 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3843 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3844 }
else if (0.8125
f <= x && x < 1.
f &&
3845 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3846 (0.375
f <= y && y < 0.625
f) ||
3847 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3849 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3850 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3851 }
else if (0.
f <= y && y < 0.375
f &&
3852 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3853 (0.6875
f <= x && x < 0.8125
f) ||
3854 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3855 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3857 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3859 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3861 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3881 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3889 uf = (uf + 1.f) * 0.5
f;
3890 vf = (
vf + 1.f) * 0.5
f;
3894 uf = 0.1875f *
vf - 0.375f * uf *
vf - 0.125f * uf + 0.8125f;
3895 vf = 0.375f - 0.375f *
vf;
3901 uf = 1.f - 0.1875f *
vf - 0.5f * uf + 0.375f * uf *
vf;
3902 vf = 1.f - 0.375f *
vf;
3905 vf = 0.25f *
vf + 0.75f * uf *
vf - 0.375f * uf + 0.375f;
3906 uf = 0.1875f * uf + 0.8125f;
3909 vf = 0.375f * uf - 0.75f * uf *
vf +
vf;
3910 uf = 0.1875f * uf + 0.5f;
3913 uf = 0.125f * uf + 0.6875f;
3914 vf = 0.25f *
vf + 0.375f;
3927 for (
int i = 0;
i < 4;
i++) {
3928 for (
int j = 0; j < 4; j++) {
3953 const float ax =
fabsf(x);
3954 const float ay =
fabsf(y);
3956 vec[2] = 1.f - (ax + ay);
3957 if (ax + ay > 1.
f) {
3958 vec[0] = (1.f - ay) *
FFSIGN(x);
3959 vec[1] = (1.f - ax) *
FFSIGN(y);
3982 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4007 for (
int i = 0;
i < 4;
i++) {
4008 for (
int j = 0; j < 4; j++) {
4019 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4020 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4021 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4022 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4037 float rot_quaternion[2][4],
4038 const int rotation_order[3])
4040 const float yaw_rad = yaw *
M_PI / 180.f;
4041 const float pitch_rad = pitch *
M_PI / 180.f;
4042 const float roll_rad = roll *
M_PI / 180.f;
4044 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4045 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4046 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4047 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4048 const float sin_roll =
sinf(roll_rad * 0.5
f);
4049 const float cos_roll =
cosf(roll_rad * 0.5
f);
4054 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4055 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4056 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4071 static inline void rotate(
const float rot_quaternion[2][4],
4074 float qv[4],
temp[4], rqv[4];
4092 modifier[0] = h_flip ? -1.f : 1.f;
4093 modifier[1] = v_flip ? -1.f : 1.f;
4094 modifier[2] = d_flip ? -1.f : 1.f;
4097 static inline void mirror(
const float *modifier,
float *vec)
4099 vec[0] *= modifier[0];
4100 vec[1] *= modifier[1];
4101 vec[2] *= modifier[2];
4104 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4107 for (
int i = 0;
i < 4;
i++) {
4108 for (
int j = 0; j < 4; j++)
4109 u[
i][j] =
w - 1 -
u[
i][j];
4114 for (
int i = 0;
i < 4;
i++) {
4115 for (
int j = 0; j < 4; j++)
4116 v[
i][j] =
h - 1 - v[
i][j];
4123 const int pr_height =
s->pr_height[p];
4125 for (
int n = 0; n <
s->nb_threads; n++) {
4127 const int slice_start = (pr_height * n ) /
s->nb_threads;
4128 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4135 if (!
r->u[p] || !
r->v[p])
4144 if (sizeof_mask && !p) {
4160 *v_fov = d_fov * 0.5f;
4164 const float d = 0.5f * hypotf(
w,
h);
4165 const float l =
sinf(d_fov *
M_PI / 360.
f) / d;
4167 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4168 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4170 if (d_fov > 180.
f) {
4171 *h_fov = 180.f - *h_fov;
4172 *v_fov = 180.f - *v_fov;
4178 const float d = 0.5f * hypotf(
w,
h);
4179 const float l = d / (
sinf(d_fov *
M_PI / 720.
f));
4181 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4182 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4187 const float d = 0.5f * hypotf(
w,
h);
4188 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
4196 const float d = hypotf(
w * 0.5
f,
h);
4198 *h_fov = 0.5f *
w / d * d_fov;
4199 *v_fov =
h / d * d_fov;
4204 const float d = hypotf(
w,
h);
4206 *h_fov =
w / d * d_fov;
4207 *v_fov =
h / d * d_fov;
4213 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4214 const float d = hypotf(
w,
h);
4231 outw[0] = outw[3] =
w;
4233 outh[0] = outh[3] =
h;
4242 for (
int p = 0; p <
s->nb_allocated; p++) {
4243 const int max_value =
s->max_value;
4244 const int width =
s->pr_width[p];
4245 const int uv_linesize =
s->uv_linesize[p];
4246 const int height =
s->pr_height[p];
4247 const int in_width =
s->inplanewidth[p];
4248 const int in_height =
s->inplaneheight[p];
4262 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j -
slice_start) *
s->pr_width[0] +
i);
4263 int in_mask, out_mask;
4265 if (
s->out_transpose)
4272 rotate(
s->rot_quaternion, vec);
4275 mirror(
s->output_mirror_modifier, vec);
4276 if (
s->in_transpose)
4277 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4279 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4280 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4282 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4284 if (!p &&
r->mask) {
4285 if (
s->mask_size == 1) {
4286 mask8[0] = 255 * (out_mask & in_mask);
4288 mask16[0] = max_value * (out_mask & in_mask);
4304 const int depth =
desc->comp[0].depth;
4305 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4306 float default_h_fov = 360.f;
4307 float default_v_fov = 180.f;
4308 float default_ih_fov = 360.f;
4309 float default_iv_fov = 180.f;
4314 int in_offset_h, in_offset_w;
4315 int out_offset_h, out_offset_w;
4320 s->max_value = (1 << depth) - 1;
4322 switch (
s->interp) {
4325 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4327 sizeof_uv =
sizeof(int16_t) *
s->elements;
4332 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4333 s->elements = 2 * 2;
4334 sizeof_uv =
sizeof(int16_t) *
s->elements;
4335 sizeof_ker =
sizeof(int16_t) *
s->elements;
4339 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4340 s->elements = 3 * 3;
4341 sizeof_uv =
sizeof(int16_t) *
s->elements;
4342 sizeof_ker =
sizeof(int16_t) *
s->elements;
4346 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4347 s->elements = 4 * 4;
4348 sizeof_uv =
sizeof(int16_t) *
s->elements;
4349 sizeof_ker =
sizeof(int16_t) *
s->elements;
4353 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4354 s->elements = 4 * 4;
4355 sizeof_uv =
sizeof(int16_t) *
s->elements;
4356 sizeof_ker =
sizeof(int16_t) *
s->elements;
4360 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4361 s->elements = 4 * 4;
4362 sizeof_uv =
sizeof(int16_t) *
s->elements;
4363 sizeof_ker =
sizeof(int16_t) *
s->elements;
4367 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4368 s->elements = 4 * 4;
4369 sizeof_uv =
sizeof(int16_t) *
s->elements;
4370 sizeof_ker =
sizeof(int16_t) *
s->elements;
4374 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4375 s->elements = 4 * 4;
4376 sizeof_uv =
sizeof(int16_t) *
s->elements;
4377 sizeof_ker =
sizeof(int16_t) *
s->elements;
4385 for (
int order = 0; order <
NB_RORDERS; order++) {
4386 const char c =
s->rorder[order];
4391 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4392 s->rotation_order[0] =
YAW;
4393 s->rotation_order[1] =
PITCH;
4394 s->rotation_order[2] =
ROLL;
4401 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4402 s->rotation_order[0] =
YAW;
4403 s->rotation_order[1] =
PITCH;
4404 s->rotation_order[2] =
ROLL;
4408 s->rotation_order[order] = rorder;
4411 switch (
s->in_stereo) {
4415 in_offset_w = in_offset_h = 0;
4436 s->in_width =
s->inplanewidth[0];
4437 s->in_height =
s->inplaneheight[0];
4442 default_ih_fov = 90.f;
4443 default_iv_fov = 45.f;
4450 default_ih_fov = 180.f;
4451 default_iv_fov = 180.f;
4456 if (
s->ih_fov == 0.f)
4457 s->ih_fov = default_ih_fov;
4459 if (
s->iv_fov == 0.f)
4460 s->iv_fov = default_iv_fov;
4462 if (
s->id_fov > 0.f)
4465 if (
s->in_transpose)
4466 FFSWAP(
int,
s->in_width,
s->in_height);
4782 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4783 s->out ==
FLAT &&
s->d_fov == 0.f) {
4785 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4786 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4787 s->out ==
FLAT &&
s->d_fov == 0.f) {
4789 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4790 }
else if (
s->width > 0 &&
s->height > 0) {
4793 }
else if (
s->width > 0 ||
s->height > 0) {
4797 if (
s->out_transpose)
4800 if (
s->in_transpose)
4810 default_h_fov = 90.f;
4811 default_v_fov = 45.f;
4818 default_h_fov = 180.f;
4819 default_v_fov = 180.f;
4825 if (
s->h_fov == 0.f)
4826 s->h_fov = default_h_fov;
4828 if (
s->v_fov == 0.f)
4829 s->v_fov = default_v_fov;
4835 err = prepare_out(
ctx);
4842 switch (
s->out_stereo) {
4844 out_offset_w = out_offset_h = 0;
4863 for (
int i = 0;
i < 4;
i++)
4873 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4874 s->nb_allocated = 1;
4875 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4877 s->nb_allocated = 2;
4878 s->map[0] =
s->map[3] = 0;
4879 s->map[1] =
s->map[2] = 1;
4882 if (!
s->slice_remap)
4883 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4884 if (!
s->slice_remap)
4887 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4888 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4894 s->rot_quaternion,
s->rotation_order);
4929 s->rot_quaternion[0][0] = 1.f;
4930 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4934 char *res,
int res_len,
int flags)
4939 if (
s->reset_rot <= 0)
4940 s->yaw =
s->pitch =
s->roll = 0.f;
4941 if (
s->reset_rot < 0)
4967 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4970 for (
int p = 0; p <
s->nb_allocated; p++) {
5007 .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[]
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
#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.
@ 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.
#define FILTER_QUERY_FUNC2(func)
@ 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)
@ 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.