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 = ff_slice_pos(height, jobnr, nb_jobs); \
312 const int slice_end = ff_slice_pos(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) * (int64_t)uv_linesize * ws * ws; \
316 const int16_t *const v = r->v[map] + (y - slice_start) * (int64_t)uv_linesize * ws * ws; \
317 const int16_t *const ker = r->ker[map] + (y - slice_start) * (int64_t)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;
397 #if ARCH_X86 && HAVE_X86ASM
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);
1871 vec[0] = x /
r * sin_theta;
1872 vec[1] = y /
r * sin_theta;
1873 vec[2] =
cosf(theta);
1875 vec[0] = vec[1] = 0.f;
1893 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1894 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1913 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1915 const float theta = acosf(vec[2]);
1916 const float r = tanf(theta * 0.5
f);
1917 const float c =
r / hypotf(vec[0], vec[1]);
1918 const float x = vec[0] *
c /
s->iflat_range[0];
1919 const float y = vec[1] *
c /
s->iflat_range[1];
1929 *du = visible ? uf -
ui : 0.f;
1930 *dv = visible ?
vf - vi : 0.f;
1932 for (
int i = 0;
i < 4;
i++) {
1933 for (
int j = 0; j < 4; j++) {
1953 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1954 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1975 const float r = hypotf(x, y);
1976 const float theta = asinf(
r) * 2.f;
1977 const float sin_theta =
sinf(theta);
1980 vec[0] = x /
r * sin_theta;
1981 vec[1] = y /
r * sin_theta;
1982 vec[2] =
cosf(theta);
1984 vec[0] = vec[1] = 0.f;
2022 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2024 const float theta = acosf(vec[2]);
2025 const float r =
sinf(theta * 0.5
f);
2026 const float c =
r / hypotf(vec[0], vec[1]);
2027 const float x = vec[0] *
c /
s->iflat_range[0];
2028 const float y = vec[1] *
c /
s->iflat_range[1];
2038 *du = visible ? uf -
ui : 0.f;
2039 *dv = visible ?
vf - vi : 0.f;
2041 for (
int i = 0;
i < 4;
i++) {
2042 for (
int j = 0; j < 4; j++) {
2084 const float r = hypotf(x, y);
2085 const float theta = asinf(
r);
2087 vec[2] =
cosf(theta);
2133 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2135 const float theta = acosf(vec[2]);
2136 const float r =
sinf(theta);
2137 const float c =
r / hypotf(vec[0], vec[1]);
2138 const float x = vec[0] *
c /
s->iflat_range[0];
2139 const float y = vec[1] *
c /
s->iflat_range[1];
2147 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2149 *du = visible ? uf -
ui : 0.f;
2150 *dv = visible ?
vf - vi : 0.f;
2152 for (
int i = 0;
i < 4;
i++) {
2153 for (
int j = 0; j < 4; j++) {
2173 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2174 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2193 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2195 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2196 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2208 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2210 for (
int i = 0;
i < 4;
i++) {
2211 for (
int j = 0; j < 4; j++) {
2234 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2237 const float theta = asinf(vec[1]) /
M_PI_2;
2250 for (
int i = 0;
i < 4;
i++) {
2251 for (
int j = 0; j < 4; j++) {
2271 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2272 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2291 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2293 const float theta = acosf(vec[2]);
2294 const float r = tanf(theta);
2296 const float zf = vec[2];
2297 const float h = hypotf(vec[0], vec[1]);
2298 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2299 float uf = vec[0] *
c /
s->iflat_range[0];
2300 float vf = vec[1] *
c /
s->iflat_range[1];
2301 int visible,
ui, vi;
2309 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2314 for (
int i = 0;
i < 4;
i++) {
2315 for (
int j = 0; j < 4; j++) {
2338 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2340 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2341 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2352 for (
int i = 0;
i < 4;
i++) {
2353 for (
int j = 0; j < 4; j++) {
2378 const float div =
expf(2.
f * y) + 1.f;
2380 const float sin_phi =
sinf(phi);
2381 const float cos_phi =
cosf(phi);
2382 const float sin_theta = 2.f *
expf(y) / div;
2383 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2385 vec[0] = -sin_theta * cos_phi;
2387 vec[2] = sin_theta * sin_phi;
2406 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2408 const float l = hypotf(vec[0], vec[1]);
2410 const float d = l > 0.f ? l : 1.f;
2421 for (
int i = 0;
i < 4;
i++) {
2422 for (
int j = 0; j < 4; j++) {
2447 const float l = hypotf(x, y);
2450 const float z = 2.f * l *
sqrtf(1.
f - l * l);
2452 vec[0] = z * x / (l > 0.f ? l : 1.f);
2453 vec[1] = z * y / (l > 0.f ? l : 1.f);
2454 vec[2] = 1.f - 2.f * l * l;
2482 const float xx = x * x;
2483 const float yy = y * y;
2485 const float z =
sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2488 const float b = 2.f * z * z - 1.f;
2490 const float aa =
a *
a;
2491 const float bb =
b *
b;
2493 const float w =
sqrtf(1.
f - 2.
f * yy * z * z);
2495 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2497 vec[2] =
w * (bb - aa) / (aa + bb);
2516 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2518 const float theta =
atan2f(vec[0], vec[2]);
2521 const float x =
sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2522 const float y = vec[1] / z;
2524 const float uf = (x + 1.f) *
width / 2.
f;
2525 const float vf = (y + 1.f) *
height / 2.
f;
2533 for (
int i = 0;
i < 4;
i++) {
2534 for (
int j = 0; j < 4; j++) {
2560 const float sin_phi =
sinf(phi);
2561 const float cos_phi =
cosf(phi);
2562 const float sin_theta =
sinf(theta);
2563 const float cos_theta =
cosf(theta);
2565 vec[0] = cos_theta * sin_phi;
2567 vec[2] = cos_theta * cos_phi;
2586 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2588 const float theta = asinf(vec[1]);
2589 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2600 for (
int i = 0;
i < 4;
i++) {
2601 for (
int j = 0; j < 4; j++) {
2680 const float pixel_pad = 2;
2681 const float u_pad = pixel_pad /
width;
2682 const float v_pad = pixel_pad /
height;
2684 int u_face, v_face, face;
2686 float l_x, l_y, l_z;
2688 float uf = (
i + 0.5f) /
width;
2696 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2700 }
else if (uf >= 3.
f) {
2705 uf = fmodf(uf, 1.
f) - 0.5f;
2710 vf = (
vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2712 if (uf >= -0.5
f && uf < 0.5
f) {
2717 if (
vf >= -0.5
f &&
vf < 0.5
f) {
2723 face = u_face + 3 * v_face;
2781 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2783 const float pixel_pad = 2;
2784 const float u_pad = pixel_pad /
width;
2785 const float v_pad = pixel_pad /
height;
2789 int direction, face;
2794 face =
s->in_cubemap_face_order[direction];
2802 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2803 vf =
vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2817 for (
int i = 0;
i < 4;
i++) {
2818 for (
int j = 0; j < 4; j++) {
2838 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2839 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2879 s->flat_range[0] =
s->h_fov / 180.f;
2880 s->flat_range[1] =
s->v_fov / 180.f;
2903 const float theta =
M_PI_2 * (1.f - hypotf(uf,
vf));
2905 const float sin_phi =
sinf(phi);
2906 const float cos_phi =
cosf(phi);
2907 const float sin_theta =
sinf(theta);
2908 const float cos_theta =
cosf(theta);
2910 vec[0] = cos_theta * cos_phi;
2911 vec[1] = cos_theta * sin_phi;
2928 s->iflat_range[0] =
s->ih_fov / 180.f;
2929 s->iflat_range[1] =
s->iv_fov / 180.f;
2948 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2950 const float h = hypotf(vec[0], vec[1]);
2951 const float lh =
h > 0.f ?
h : 1.f;
2954 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2955 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2957 const int visible = -0.5f < uf && uf < 0.5f && -0.5f <
vf &&
vf < 0.5f;
2966 *du = visible ? uf -
ui : 0.f;
2967 *dv = visible ?
vf - vi : 0.f;
2969 for (
int i = 0;
i < 4;
i++) {
2970 for (
int j = 0; j < 4; j++) {
2996 const float d =
s->h_fov;
2997 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2998 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2999 const float clon = (-k * d +
sqrtf(dscr)) / (k + 1.
f);
3000 const float S = (d + 1.f) / (d + clon);
3001 const float lon =
atan2f(uf,
S * clon);
3025 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3027 const float phi =
atan2f(vec[0], vec[2]);
3028 const float theta = asinf(vec[1]);
3030 const float d =
s->ih_fov;
3031 const float S = (d + 1.f) / (d +
cosf(phi));
3033 const float x =
S *
sinf(phi);
3034 const float y =
S * tanf(theta);
3042 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3047 for (
int i = 0;
i < 4;
i++) {
3048 for (
int j = 0; j < 4; j++) {
3068 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3069 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3091 const float phi = uf;
3092 const float theta =
atanf(
vf);
3094 const float sin_phi =
sinf(phi);
3095 const float cos_phi =
cosf(phi);
3096 const float sin_theta =
sinf(theta);
3097 const float cos_theta =
cosf(theta);
3099 vec[0] = cos_theta * sin_phi;
3101 vec[2] = cos_theta * cos_phi;
3117 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3118 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3137 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3139 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3140 const float theta = asinf(vec[1]);
3148 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3149 theta <=
M_PI *
s->iv_fov / 180.f &&
3150 theta >= -
M_PI *
s->iv_fov / 180.f;
3155 for (
int i = 0;
i < 4;
i++) {
3156 for (
int j = 0; j < 4; j++) {
3176 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3177 s->flat_range[1] =
s->v_fov / 180.f;
3193 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3194 s->iflat_range[1] =
s->iv_fov / 180.f;
3216 const float phi = uf;
3217 const float theta = asinf(
vf);
3219 const float sin_phi =
sinf(phi);
3220 const float cos_phi =
cosf(phi);
3221 const float sin_theta =
sinf(theta);
3222 const float cos_theta =
cosf(theta);
3224 vec[0] = cos_theta * sin_phi;
3226 vec[2] = cos_theta * cos_phi;
3245 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3247 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3248 const float theta = asinf(vec[1]);
3256 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3257 theta <=
M_PI *
s->iv_fov / 180.f &&
3258 theta >= -
M_PI *
s->iv_fov / 180.f;
3263 for (
int i = 0;
i < 4;
i++) {
3264 for (
int j = 0; j < 4; j++) {
3289 const float rh = hypotf(uf,
vf);
3290 const float sinzz = 1.f - rh * rh;
3291 const float h = 1.f +
s->v_fov;
3292 const float sinz = (
h -
sqrtf(sinzz)) / (
h / rh + rh /
h);
3293 const float sinz2 = sinz * sinz;
3296 const float cosz =
sqrtf(1.
f - sinz2);
3298 const float theta = asinf(cosz);
3301 const float sin_phi =
sinf(phi);
3302 const float cos_phi =
cosf(phi);
3303 const float sin_theta =
sinf(theta);
3304 const float cos_theta =
cosf(theta);
3306 vec[0] = cos_theta * sin_phi;
3307 vec[1] = cos_theta * cos_phi;
3336 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3337 vec[1] = 1.f -
vf * 2.f;
3357 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3359 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3360 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3361 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3362 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3365 float uf,
vf, x, y, z;
3372 vf = 0.5f - y * 0.5f;
3374 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3375 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3376 uf = 0.25f * x + 0.25f;
3378 uf = 0.75f - 0.25f * x;
3390 for (
int i = 0;
i < 4;
i++) {
3391 for (
int j = 0; j < 4; j++) {
3411 s->iflat_range[0] =
s->ih_fov / 360.f;
3412 s->iflat_range[1] =
s->iv_fov / 360.f;
3431 const float ew =
width * 0.5f;
3434 const int ei =
i >= ew ?
i - ew :
i;
3435 const float m =
i >= ew ? 1.f : -1.f;
3437 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3438 const float vf =
s->flat_range[1] *
rescale(j, eh);
3440 const float h = hypotf(uf,
vf);
3441 const float lh =
h > 0.f ?
h : 1.f;
3442 const float theta = m *
M_PI_2 * (1.f -
h);
3444 const float sin_theta =
sinf(theta);
3445 const float cos_theta =
cosf(theta);
3447 vec[0] = cos_theta * m * uf / lh;
3448 vec[1] = cos_theta *
vf / lh;
3468 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3470 const float ew =
width * 0.5f;
3473 const float h = hypotf(vec[0], vec[1]);
3474 const float lh =
h > 0.f ?
h : 1.f;
3475 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3477 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3478 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3483 if (vec[2] >= 0.
f) {
3484 u_shift =
ceilf(ew);
3496 for (
int i = 0;
i < 4;
i++) {
3497 for (
int j = 0; j < 4; j++) {
3520 const float scale = 0.99f;
3521 float l_x, l_y, l_z;
3524 const float theta_range =
M_PI_4;
3526 const int ew = 4 *
width / 5;
3530 const float theta =
rescale(j, eh) * theta_range /
scale;
3532 const float sin_phi =
sinf(phi);
3533 const float cos_phi =
cosf(phi);
3534 const float sin_theta =
sinf(theta);
3535 const float cos_theta =
cosf(theta);
3537 l_x = cos_theta * sin_phi;
3539 l_z = cos_theta * cos_phi;
3541 const int ew =
width / 5;
3542 const int eh =
height / 2;
3590 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3592 const float scale = 0.99f;
3594 const float phi =
atan2f(vec[0], vec[2]);
3595 const float theta = asinf(vec[1]);
3596 const float theta_range =
M_PI_4;
3599 int u_shift, v_shift;
3603 if (theta > -theta_range && theta < theta_range) {
3611 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3619 uf = -vec[0] / vec[1];
3620 vf = -vec[2] / vec[1];
3623 uf = vec[0] / vec[1];
3624 vf = -vec[2] / vec[1];
3628 uf = 0.5f * ew * (uf *
scale + 1.f);
3638 for (
int i = 0;
i < 4;
i++) {
3639 for (
int j = 0; j < 4; j++) {
3641 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3662 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3664 const float phi =
atan2f(vec[0], vec[2]);
3665 const float theta = asinf(vec[1]);
3667 const float theta_range =
M_PI_4;
3670 int u_shift, v_shift;
3674 if (theta >= -theta_range && theta <= theta_range) {
3675 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3676 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3688 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3690 uf = (uf * scalew + 1.f) *
width / 3.
f;
3693 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3694 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3701 uf = vec[0] / vec[1] * scalew;
3702 vf = vec[2] / vec[1] * scaleh;
3704 if (theta <= 0.f && theta >= -
M_PI_2 &&
3705 phi <= M_PI_2 && phi >= -
M_PI_2) {
3708 vf = -(
vf + 1.f) * scaleh + 1.
f;
3710 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3711 phi <= M_PI_2 && phi >= -
M_PI_2) {
3713 vf = -(
vf - 1.f) * scaleh;
3714 v_shift =
height * 0.25f;
3715 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3717 vf = (
vf - 1.f) * scaleh + 1.
f;
3722 vf = (
vf + 1.f) * scaleh;
3723 v_shift =
height * 0.75f;
3726 uf = 0.5f *
width / 3.f * (uf + 1.f);
3736 for (
int i = 0;
i < 4;
i++) {
3737 for (
int j = 0; j < 4; j++) {
3739 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3760 const float x = (
i + 0.5f) /
width;
3761 const float y = (j + 0.5f) /
height;
3762 float l_x, l_y, l_z;
3765 if (x < 2.
f / 3.
f) {
3766 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3767 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3769 const float back =
floorf(y * 2.
f);
3771 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3772 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3774 const float sin_phi =
sinf(phi);
3775 const float cos_phi =
cosf(phi);
3776 const float sin_theta =
sinf(theta);
3777 const float cos_theta =
cosf(theta);
3779 l_x = cos_theta * sin_phi;
3781 l_z = cos_theta * cos_phi;
3785 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3786 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3788 const float facef =
floorf(y * 4.
f);
3789 const int face = facef;
3790 const float dir_vert = (face == 1 || face == 3) ? 1.0
f : -1.0
f;
3799 vf = (0.5f - 2.f * y) / scaleh + facef;
3803 vf = (y * 2.f - 1.5f) / scaleh + 3.
f - facef;
3808 l_x = (0.5f - uf) / scalew;
3809 l_y = 0.5f * dir_vert;
3810 l_z = (
vf - 0.5f) * dir_vert / scaleh;
3811 ret = (l_x * l_x * scalew * scalew + l_z * l_z * scaleh * scaleh) < 0.5
f * 0.5
f;
3835 const float x = (
i + 0.5f) /
width;
3836 const float y = (j + 0.5f) /
height;
3839 vec[0] = x * 4.f - 1.f;
3840 vec[1] = (y * 2.f - 1.f);
3842 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3843 y >= 0.375
f && y < 0.625
f) {
3844 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3845 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3847 }
else if (0.5
f <= x && x < 0.6875
f &&
3848 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3849 (0.375
f <= y && y < 0.625
f) ||
3850 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3852 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3853 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3854 }
else if (0.8125
f <= x && x < 1.
f &&
3855 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3856 (0.375
f <= y && y < 0.625
f) ||
3857 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3859 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3860 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3861 }
else if (0.
f <= y && y < 0.375
f &&
3862 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3863 (0.6875
f <= x && x < 0.8125
f) ||
3864 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3865 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3867 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3869 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3871 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3891 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3899 uf = (uf + 1.f) * 0.5
f;
3900 vf = (
vf + 1.f) * 0.5
f;
3904 uf = 0.1875f *
vf - 0.375f * uf *
vf - 0.125f * uf + 0.8125f;
3905 vf = 0.375f - 0.375f *
vf;
3911 uf = 1.f - 0.1875f *
vf - 0.5f * uf + 0.375f * uf *
vf;
3912 vf = 1.f - 0.375f *
vf;
3915 vf = 0.25f *
vf + 0.75f * uf *
vf - 0.375f * uf + 0.375f;
3916 uf = 0.1875f * uf + 0.8125f;
3919 vf = 0.375f * uf - 0.75f * uf *
vf +
vf;
3920 uf = 0.1875f * uf + 0.5f;
3923 uf = 0.125f * uf + 0.6875f;
3924 vf = 0.25f *
vf + 0.375f;
3937 for (
int i = 0;
i < 4;
i++) {
3938 for (
int j = 0; j < 4; j++) {
3963 const float ax =
fabsf(x);
3964 const float ay =
fabsf(y);
3966 vec[2] = 1.f - (ax + ay);
3967 if (ax + ay > 1.
f) {
3968 vec[0] = (1.f - ay) *
FFSIGN(x);
3969 vec[1] = (1.f - ax) *
FFSIGN(y);
3992 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4017 for (
int i = 0;
i < 4;
i++) {
4018 for (
int j = 0; j < 4; j++) {
4029 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4030 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4031 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4032 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4047 float rot_quaternion[2][4],
4048 const int rotation_order[3])
4050 const float yaw_rad = yaw *
M_PI / 180.f;
4051 const float pitch_rad = pitch *
M_PI / 180.f;
4052 const float roll_rad = roll *
M_PI / 180.f;
4054 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4055 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4056 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4057 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4058 const float sin_roll =
sinf(roll_rad * 0.5
f);
4059 const float cos_roll =
cosf(roll_rad * 0.5
f);
4064 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4065 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4066 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4081 static inline void rotate(
const float rot_quaternion[2][4],
4084 float qv[4],
temp[4], rqv[4];
4102 modifier[0] = h_flip ? -1.f : 1.f;
4103 modifier[1] = v_flip ? -1.f : 1.f;
4104 modifier[2] = d_flip ? -1.f : 1.f;
4107 static inline void mirror(
const float *modifier,
float *vec)
4109 vec[0] *= modifier[0];
4110 vec[1] *= modifier[1];
4111 vec[2] *= modifier[2];
4114 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4117 for (
int i = 0;
i < 4;
i++) {
4118 for (
int j = 0; j < 4; j++)
4119 u[
i][j] =
w - 1 -
u[
i][j];
4124 for (
int i = 0;
i < 4;
i++) {
4125 for (
int j = 0; j < 4; j++)
4126 v[
i][j] =
h - 1 - v[
i][j];
4133 const int pr_height =
s->pr_height[
p];
4135 for (
int n = 0; n <
s->nb_threads; n++) {
4137 const int slice_start = (pr_height * n ) /
s->nb_threads;
4138 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4145 if (!
r->u[
p] || !
r->v[
p])
4154 if (sizeof_mask && !
p) {
4170 *v_fov = d_fov * 0.5f;
4174 const float d = 0.5f * hypotf(
w,
h);
4175 const float l =
sinf(d_fov *
M_PI / 360.
f) / d;
4177 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4178 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4180 if (d_fov > 180.
f) {
4181 *h_fov = 180.f - *h_fov;
4182 *v_fov = 180.f - *v_fov;
4188 const float d = 0.5f * hypotf(
w,
h);
4189 const float l = d / (
sinf(d_fov *
M_PI / 720.
f));
4191 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4192 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4197 const float d = 0.5f * hypotf(
w,
h);
4198 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
4206 const float d = hypotf(
w * 0.5
f,
h);
4208 *h_fov = 0.5f *
w / d * d_fov;
4209 *v_fov =
h / d * d_fov;
4214 const float d = hypotf(
w,
h);
4216 *h_fov =
w / d * d_fov;
4217 *v_fov =
h / d * d_fov;
4223 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4224 const float d = hypotf(
w,
h);
4241 outw[0] = outw[3] =
w;
4243 outh[0] = outh[3] =
h;
4252 for (
int p = 0;
p <
s->nb_allocated;
p++) {
4253 const int max_value =
s->max_value;
4254 const int width =
s->pr_width[
p];
4255 const int uv_linesize =
s->uv_linesize[
p];
4256 const int height =
s->pr_height[
p];
4257 const int in_width =
s->inplanewidth[
p];
4258 const int in_height =
s->inplaneheight[
p];
4272 uint16_t *mask16 = (
p || !
r->mask) ?
NULL : (uint16_t *)
r->mask + ((j -
slice_start) *
s->pr_width[0] +
i);
4273 int in_mask, out_mask;
4275 if (
s->out_transpose)
4280 vec[0] = vec[1] = 0.f;
4286 rotate(
s->rot_quaternion, vec);
4289 mirror(
s->output_mirror_modifier, vec);
4290 if (
s->in_transpose)
4291 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4293 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4294 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4296 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4298 if (!
p &&
r->mask) {
4299 if (
s->mask_size == 1) {
4300 mask8[0] = 255 * (out_mask & in_mask);
4302 mask16[0] = max_value * (out_mask & in_mask);
4315 if (!
isfinite(
val) || val < 1.f || val > INT16_MAX) {
4317 "Output %s %g is outside the allowed range [1, %d].\n",
4328 switch (projection) {
4333 case BARREL: *min_w = 5; *min_h = 2;
break;
4336 default: *min_w = 1; *min_h = 1;
break;
4346 const int depth =
desc->comp[0].depth;
4347 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4348 float default_h_fov = 360.f;
4349 float default_v_fov = 180.f;
4350 float default_ih_fov = 360.f;
4351 float default_iv_fov = 180.f;
4356 int in_offset_h, in_offset_w;
4357 int out_offset_h, out_offset_w;
4362 s->max_value = (1 << depth) - 1;
4364 switch (
s->interp) {
4367 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4369 sizeof_uv =
sizeof(int16_t) *
s->elements;
4374 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4375 s->elements = 2 * 2;
4376 sizeof_uv =
sizeof(int16_t) *
s->elements;
4377 sizeof_ker =
sizeof(int16_t) *
s->elements;
4381 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4382 s->elements = 3 * 3;
4383 sizeof_uv =
sizeof(int16_t) *
s->elements;
4384 sizeof_ker =
sizeof(int16_t) *
s->elements;
4388 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4389 s->elements = 4 * 4;
4390 sizeof_uv =
sizeof(int16_t) *
s->elements;
4391 sizeof_ker =
sizeof(int16_t) *
s->elements;
4395 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4396 s->elements = 4 * 4;
4397 sizeof_uv =
sizeof(int16_t) *
s->elements;
4398 sizeof_ker =
sizeof(int16_t) *
s->elements;
4402 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4403 s->elements = 4 * 4;
4404 sizeof_uv =
sizeof(int16_t) *
s->elements;
4405 sizeof_ker =
sizeof(int16_t) *
s->elements;
4409 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4410 s->elements = 4 * 4;
4411 sizeof_uv =
sizeof(int16_t) *
s->elements;
4412 sizeof_ker =
sizeof(int16_t) *
s->elements;
4416 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4417 s->elements = 4 * 4;
4418 sizeof_uv =
sizeof(int16_t) *
s->elements;
4419 sizeof_ker =
sizeof(int16_t) *
s->elements;
4427 for (
int order = 0; order <
NB_RORDERS; order++) {
4428 const char c =
s->rorder[order];
4433 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4434 s->rotation_order[0] =
YAW;
4435 s->rotation_order[1] =
PITCH;
4436 s->rotation_order[2] =
ROLL;
4443 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4444 s->rotation_order[0] =
YAW;
4445 s->rotation_order[1] =
PITCH;
4446 s->rotation_order[2] =
ROLL;
4450 s->rotation_order[order] = rorder;
4453 switch (
s->in_stereo) {
4457 in_offset_w = in_offset_h = 0;
4478 s->in_width =
s->inplanewidth[0];
4479 s->in_height =
s->inplaneheight[0];
4484 default_ih_fov = 90.f;
4485 default_iv_fov = 45.f;
4492 default_ih_fov = 180.f;
4493 default_iv_fov = 180.f;
4499 if (
s->ih_fov == 0.f)
4500 s->ih_fov = default_ih_fov;
4502 if (
s->iv_fov == 0.f)
4503 s->iv_fov = default_iv_fov;
4505 if (
s->id_fov > 0.f)
4508 if (
s->in_transpose)
4509 FFSWAP(
int,
s->in_width,
s->in_height);
4512 if (
s->in_width < 1 ||
s->in_width > INT16_MAX ||
4513 s->in_height < 1 ||
s->in_height > INT16_MAX) {
4515 "Input dimensions %dx%d are outside the allowed range [1, %d].\n",
4516 s->in_width,
s->in_height, INT16_MAX);
4528 if (pw < min_w ||
ph < min_h) {
4530 "Input %dx%d is too small for the input projection "
4531 "(requires at least %dx%d per plane).\n", pw,
ph, min_w, min_h);
4850 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4851 s->out ==
FLAT &&
s->d_fov == 0.f) {
4854 w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f), &
h);
4857 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4858 s->out ==
FLAT &&
s->d_fov == 0.f) {
4861 h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f), &
w);
4864 }
else if (
s->width > 0 &&
s->height > 0) {
4867 }
else if (
s->width > 0 ||
s->height > 0) {
4871 if (
s->out_transpose)
4874 if (
s->in_transpose)
4878 if (w < 1 || w > INT16_MAX || h < 1 || h > INT16_MAX) {
4880 "Output dimensions %dx%d are outside the allowed range [1, %d].\n",
4891 default_h_fov = 90.f;
4892 default_v_fov = 45.f;
4899 default_h_fov = 180.f;
4900 default_v_fov = 180.f;
4906 if (
s->h_fov == 0.f)
4907 s->h_fov = default_h_fov;
4909 if (
s->v_fov == 0.f)
4910 s->v_fov = default_v_fov;
4916 err = prepare_out(
ctx);
4931 if (pw < min_w ||
ph < min_h) {
4933 "Output %dx%d is too small for the output projection "
4934 "(requires at least %dx%d per plane).\n", pw,
ph, min_w, min_h);
4939 switch (
s->out_stereo) {
4941 out_offset_w = out_offset_h = 0;
4960 for (
int i = 0;
i < 4;
i++)
4970 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4971 s->nb_allocated = 1;
4972 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4974 s->nb_allocated = 2;
4975 s->map[0] =
s->map[3] = 0;
4976 s->map[1] =
s->map[2] = 1;
4979 if (!
s->slice_remap)
4980 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4981 if (!
s->slice_remap)
4984 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4985 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4991 s->rot_quaternion,
s->rotation_order);
5026 s->rot_quaternion[0][0] = 1.f;
5027 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
5031 char *res,
int res_len,
int flags)
5036 if (
s->reset_rot <= 0)
5037 s->yaw =
s->pitch =
s->roll = 0.f;
5038 if (
s->reset_rot < 0)
5064 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
5067 for (
int p = 0;
p <
s->nb_allocated;
p++) {
5098 .p.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
static int get_output_dimension(AVFilterContext *ctx, const char *name, float val, int *dim)
#define AV_LOG_WARNING
Something somehow does not look correct.
static const uint8_t q1[256]
AVPixelFormat
Pixel format.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
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]
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.
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
This structure describes decoded (raw) audio or video data.
#define AV_PIX_FMT_YUVA420P16
#define u(width, name, range_min, range_max)
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 double val(void *priv, double ch)
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
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)
#define FILTER_QUERY_FUNC2(func)
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
#define flags(name, subs,...)
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 FILTER_OUTPUTS(array)
#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)
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.
static AVFormatContext * ctx
#define AV_PIX_FMT_GRAY14
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
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.
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
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.
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
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 i(width, name, range_min, range_max)
#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
const FFFilter ff_vf_v360
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.
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 FILTER_INPUTS(array)
#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.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
@ 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...
AVFilter p
The public AVFilter.
#define us(width, name, range_min, range_max, subs,...)
@ 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 AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
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 void projection_min_size(int projection, int *min_w, int *min_h)
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.
static int prepare_orthographic_in(AVFilterContext *ctx)
Prepare data for processing orthographic input format.