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
254 #define DEFINE_REMAP1_LINE(bits, div) \
255 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
256 ptrdiff_t in_linesize, \
257 const int16_t *const u, const int16_t *const v, \
258 const int16_t *const ker) \
260 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
261 uint##bits##_t *d = (uint##bits##_t *)dst; \
263 in_linesize /= div; \
265 for (int x = 0; x < width; x++) \
266 d[x] = s[v[x] * in_linesize + u[x]]; \
278 #define DEFINE_REMAP(ws, bits) \
279 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
281 ThreadData *td = arg; \
282 const V360Context *s = ctx->priv; \
283 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
284 const AVFrame *in = td->in; \
285 AVFrame *out = td->out; \
287 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
288 for (int plane = 0; plane < s->nb_planes; plane++) { \
289 const unsigned map = s->map[plane]; \
290 const int in_linesize = in->linesize[plane]; \
291 const int out_linesize = out->linesize[plane]; \
292 const int uv_linesize = s->uv_linesize[plane]; \
293 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
294 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
295 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
296 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
297 const uint8_t *const src = in->data[plane] + \
298 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
299 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
300 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
301 const int width = s->pr_width[plane]; \
302 const int height = s->pr_height[plane]; \
304 const int slice_start = (height * jobnr ) / nb_jobs; \
305 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
307 for (int y = slice_start; y < slice_end && !mask; y++) { \
308 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
309 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
310 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
312 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
315 for (int y = slice_start; y < slice_end && mask; y++) { \
316 memcpy(dst + y * out_linesize, mask + \
317 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
334 #define DEFINE_REMAP_LINE(ws, bits, div) \
335 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
336 ptrdiff_t in_linesize, \
337 const int16_t *const u, const int16_t *const v, \
338 const int16_t *const ker) \
340 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
341 uint##bits##_t *d = (uint##bits##_t *)dst; \
343 in_linesize /= div; \
345 for (int x = 0; x < width; x++) { \
346 const int16_t *const uu = u + x * ws * ws; \
347 const int16_t *const vv = v + x * ws * ws; \
348 const int16_t *const kker = ker + x * ws * ws; \
351 for (int i = 0; i < ws; i++) { \
352 const int iws = i * ws; \
353 for (int j = 0; j < ws; j++) { \
354 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
358 d[x] = av_clip_uint##bits(tmp >> 14); \
373 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
376 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
379 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
386 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
405 int16_t *
u, int16_t *v, int16_t *ker)
408 const int j =
lrintf(du) + 1;
410 u[0] = rmap->
u[
i][j];
411 v[0] = rmap->
v[
i][j];
425 int16_t *
u, int16_t *v, int16_t *ker)
427 for (
int i = 0;
i < 2;
i++) {
428 for (
int j = 0; j < 2; j++) {
429 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
430 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
434 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
435 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
436 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
437 ker[3] =
lrintf( du * dv * 16385.
f);
448 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
449 coeffs[1] = -t * (t - 2.f);
450 coeffs[2] = t * (t - 1.f) * 0.5
f;
464 int16_t *
u, int16_t *v, int16_t *ker)
472 for (
int i = 0;
i < 3;
i++) {
473 for (
int j = 0; j < 3; j++) {
474 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
475 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
476 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
489 const float tt = t * t;
490 const float ttt = t * t * t;
492 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
493 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
494 coeffs[2] = t + tt / 2.f - ttt / 2.f;
495 coeffs[3] = - t / 6.f + ttt / 6.f;
509 int16_t *
u, int16_t *v, int16_t *ker)
517 for (
int i = 0;
i < 4;
i++) {
518 for (
int j = 0; j < 4; j++) {
519 u[
i * 4 + j] = rmap->
u[
i][j];
520 v[
i * 4 + j] = rmap->
v[
i][j];
521 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
536 for (
int i = 0;
i < 4;
i++) {
537 const float x =
M_PI * (t -
i + 1);
541 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
546 for (
int i = 0;
i < 4;
i++) {
562 int16_t *
u, int16_t *v, int16_t *ker)
570 for (
int i = 0;
i < 4;
i++) {
571 for (
int j = 0; j < 4; j++) {
572 u[
i * 4 + j] = rmap->
u[
i][j];
573 v[
i * 4 + j] = rmap->
v[
i][j];
574 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
587 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
588 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
589 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
590 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
604 int16_t *
u, int16_t *v, int16_t *ker)
612 for (
int i = 0;
i < 4;
i++) {
613 for (
int j = 0; j < 4; j++) {
614 u[
i * 4 + j] = rmap->
u[
i][j];
615 v[
i * 4 + j] = rmap->
v[
i][j];
616 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
631 for (
int i = 0;
i < 4;
i++) {
632 const float x = t - (
i - 1);
636 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
641 for (
int i = 0;
i < 4;
i++) {
657 int16_t *
u, int16_t *v, int16_t *ker)
665 for (
int i = 0;
i < 4;
i++) {
666 for (
int j = 0; j < 4; j++) {
667 u[
i * 4 + j] = rmap->
u[
i][j];
668 v[
i * 4 + j] = rmap->
v[
i][j];
669 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
684 float p0 = (6.f - 2.f *
b) / 6.
f,
685 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
686 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
687 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
688 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
689 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
690 q3 = (-
b - 6.f *
c) / 6.
f;
692 for (
int i = 0;
i < 4;
i++) {
693 const float x =
fabsf(t -
i + 1.
f);
695 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
696 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
697 }
else if (x < 2.
f) {
698 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
699 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
706 for (
int i = 0;
i < 4;
i++) {
722 int16_t *
u, int16_t *v, int16_t *ker)
730 for (
int i = 0;
i < 4;
i++) {
731 for (
int j = 0; j < 4; j++) {
732 u[
i * 4 + j] = rmap->
u[
i][j];
733 v[
i * 4 + j] = rmap->
v[
i][j];
734 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
749 const int res =
a %
b;
881 for (
int face = 0; face <
NB_FACES; face++) {
882 const char c =
s->in_forder[face];
887 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
892 if (direction == -1) {
894 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
898 s->in_cubemap_face_order[direction] = face;
901 for (
int face = 0; face <
NB_FACES; face++) {
902 const char c =
s->in_frot[face];
907 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
912 if (rotation == -1) {
914 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
918 s->in_cubemap_face_rotation[face] = rotation;
935 for (
int face = 0; face <
NB_FACES; face++) {
936 const char c =
s->out_forder[face];
941 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
946 if (direction == -1) {
948 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
952 s->out_cubemap_direction_order[face] = direction;
955 for (
int face = 0; face <
NB_FACES; face++) {
956 const char c =
s->out_frot[face];
961 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
966 if (rotation == -1) {
968 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
972 s->out_cubemap_face_rotation[face] = rotation;
1037 const float norm = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1057 float uf,
float vf,
int face,
1058 float *vec,
float scalew,
float scaleh)
1060 const int direction =
s->out_cubemap_direction_order[face];
1061 float l_x, l_y, l_z;
1068 switch (direction) {
1122 float *uf,
float *vf,
int *direction)
1124 const float phi =
atan2f(vec[0], vec[2]);
1125 const float theta = asinf(vec[1]);
1126 float phi_norm, theta_threshold;
1129 if (phi >= -M_PI_4 && phi < M_PI_4) {
1132 }
else if (phi >= -(
M_PI_2 + M_PI_4) && phi < -M_PI_4) {
1135 }
else if (phi >= M_PI_4 && phi <
M_PI_2 + M_PI_4) {
1140 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1143 theta_threshold =
atanf(
cosf(phi_norm));
1144 if (theta > theta_threshold) {
1146 }
else if (theta < -theta_threshold) {
1150 switch (*direction) {
1152 *uf = -vec[2] / vec[0];
1153 *vf = vec[1] / vec[0];
1156 *uf = -vec[2] / vec[0];
1157 *vf = -vec[1] / vec[0];
1160 *uf = -vec[0] / vec[1];
1161 *vf = -vec[2] / vec[1];
1164 *uf = vec[0] / vec[1];
1165 *vf = -vec[2] / vec[1];
1168 *uf = vec[0] / vec[2];
1169 *vf = vec[1] / vec[2];
1172 *uf = vec[0] / vec[2];
1173 *vf = -vec[1] / vec[2];
1179 face =
s->in_cubemap_face_order[*direction];
1196 float uf,
float vf,
int direction,
1197 float *new_uf,
float *new_vf,
int *face)
1216 *face =
s->in_cubemap_face_order[direction];
1219 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1223 }
else if (uf < -1.
f) {
1225 switch (direction) {
1259 }
else if (uf >= 1.
f) {
1261 switch (direction) {
1295 }
else if (vf < -1.
f) {
1297 switch (direction) {
1331 }
else if (vf >= 1.
f) {
1333 switch (direction) {
1373 *face =
s->in_cubemap_face_order[direction];
1391 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1392 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1394 const float ew =
width / 3.f;
1395 const float eh =
height / 2.f;
1397 const int u_face =
floorf(
i / ew);
1398 const int v_face =
floorf(j / eh);
1399 const int face = u_face + 3 * v_face;
1401 const int u_shift =
ceilf(ew * u_face);
1402 const int v_shift =
ceilf(eh * v_face);
1403 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1404 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1406 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.
f;
1407 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.
f;
1428 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1430 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1431 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1432 const float ew =
width / 3.f;
1433 const float eh =
height / 2.f;
1437 int direction, face;
1445 face =
s->in_cubemap_face_order[direction];
1448 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1449 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1451 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1452 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1460 for (
int i = 0;
i < 4;
i++) {
1461 for (
int j = 0; j < 4; j++) {
1462 int new_ui =
ui + j - 1;
1463 int new_vi = vi +
i - 1;
1464 int u_shift, v_shift;
1465 int new_ewi, new_ehi;
1467 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1468 face =
s->in_cubemap_face_order[direction];
1472 u_shift =
ceilf(ew * u_face);
1473 v_shift =
ceilf(eh * v_face);
1475 uf = 2.f * new_ui / ewi - 1.f;
1476 vf = 2.f * new_vi / ehi - 1.f;
1488 u_shift =
ceilf(ew * u_face);
1489 v_shift =
ceilf(eh * v_face);
1490 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1491 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1493 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1494 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1497 us[
i][j] = u_shift + new_ui;
1498 vs[
i][j] = v_shift + new_vi;
1519 const float scalew =
s->fout_pad > 0 ? 1.f - (float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1520 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1522 const float ew =
width;
1523 const float eh =
height / 6.f;
1525 const int face =
floorf(j / eh);
1527 const int v_shift =
ceilf(eh * face);
1528 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1530 const float uf = 2.f * (
i + 0.5f) / ew - 1.
f;
1531 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.
f;
1552 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1553 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1555 const float ew =
width / 6.f;
1558 const int face =
floorf(
i / ew);
1560 const int u_shift =
ceilf(ew * face);
1561 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1563 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.
f;
1564 const float vf = 2.f * (j + 0.5f) / eh - 1.
f;
1585 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1587 const float scalew =
s->fin_pad > 0 ? 1.f - (float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1588 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1589 const float eh =
height / 6.f;
1590 const int ewi =
width;
1594 int direction, face;
1601 face =
s->in_cubemap_face_order[direction];
1602 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1604 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1605 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1613 for (
int i = 0;
i < 4;
i++) {
1614 for (
int j = 0; j < 4; j++) {
1615 int new_ui =
ui + j - 1;
1616 int new_vi = vi +
i - 1;
1620 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1621 face =
s->in_cubemap_face_order[direction];
1623 v_shift =
ceilf(eh * face);
1625 uf = 2.f * new_ui / ewi - 1.f;
1626 vf = 2.f * new_vi / ehi - 1.f;
1636 v_shift =
ceilf(eh * face);
1637 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1640 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1644 vs[
i][j] = v_shift + new_vi;
1665 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1667 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1668 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1669 const float ew =
width / 6.f;
1674 int direction, face;
1681 face =
s->in_cubemap_face_order[direction];
1682 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1684 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1685 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1693 for (
int i = 0;
i < 4;
i++) {
1694 for (
int j = 0; j < 4; j++) {
1695 int new_ui =
ui + j - 1;
1696 int new_vi = vi +
i - 1;
1700 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1701 face =
s->in_cubemap_face_order[direction];
1703 u_shift =
ceilf(ew * face);
1705 uf = 2.f * new_ui / ewi - 1.f;
1706 vf = 2.f * new_vi / ehi - 1.f;
1716 u_shift =
ceilf(ew * face);
1717 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1719 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1723 us[
i][j] = u_shift + new_ui;
1745 const float phi = ((2.f *
i + 0.5f) /
width - 1.
f) *
M_PI;
1746 const float theta = ((2.f * j + 0.5f) /
height - 1.
f) *
M_PI_2;
1748 const float sin_phi =
sinf(phi);
1749 const float cos_phi =
cosf(phi);
1750 const float sin_theta =
sinf(theta);
1751 const float cos_theta =
cosf(theta);
1753 vec[0] = cos_theta * sin_phi;
1755 vec[2] = cos_theta * cos_phi;
1774 const float phi = ((2.f *
i + 0.5f) /
width - 1.
f) *
M_PI_2;
1775 const float theta = ((2.f * j + 0.5f) /
height - 1.
f) *
M_PI_2;
1777 const float sin_phi =
sinf(phi);
1778 const float cos_phi =
cosf(phi);
1779 const float sin_theta =
sinf(theta);
1780 const float cos_theta =
cosf(theta);
1782 vec[0] = cos_theta * sin_phi;
1784 vec[2] = cos_theta * cos_phi;
1800 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1801 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1820 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
1821 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
1822 const float r = hypotf(x, y);
1823 const float theta =
atanf(
r) * 2.f;
1824 const float sin_theta =
sinf(theta);
1826 vec[0] = x /
r * sin_theta;
1827 vec[1] = y /
r * sin_theta;
1828 vec[2] =
cosf(theta);
1846 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1847 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1866 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1868 const float theta = acosf(vec[2]);
1869 const float r = tanf(theta * 0.5
f);
1870 const float c =
r / hypotf(vec[0], vec[1]);
1871 const float x = vec[0] *
c /
s->iflat_range[0];
1872 const float y = vec[1] *
c /
s->iflat_range[1];
1874 const float uf = (x + 1.f) *
width / 2.
f;
1875 const float vf = (y + 1.f) *
height / 2.
f;
1878 const int vi =
floorf(vf);
1882 *du = visible ? uf -
ui : 0.f;
1883 *dv = visible ? vf - vi : 0.f;
1885 for (
int i = 0;
i < 4;
i++) {
1886 for (
int j = 0; j < 4; j++) {
1906 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1907 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1926 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
1927 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
1928 const float r = hypotf(x, y);
1929 const float theta = asinf(
r) * 2.f;
1930 const float sin_theta =
sinf(theta);
1932 vec[0] = x /
r * sin_theta;
1933 vec[1] = y /
r * sin_theta;
1934 vec[2] =
cosf(theta);
1972 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1974 const float theta = acosf(vec[2]);
1975 const float r =
sinf(theta * 0.5
f);
1976 const float c =
r / hypotf(vec[0], vec[1]);
1977 const float x = vec[0] *
c /
s->iflat_range[0];
1978 const float y = vec[1] *
c /
s->iflat_range[1];
1980 const float uf = (x + 1.f) *
width / 2.
f;
1981 const float vf = (y + 1.f) *
height / 2.
f;
1984 const int vi =
floorf(vf);
1988 *du = visible ? uf -
ui : 0.f;
1989 *dv = visible ? vf - vi : 0.f;
1991 for (
int i = 0;
i < 4;
i++) {
1992 for (
int j = 0; j < 4; j++) {
2032 const float x = ((2.f *
i + 1.f) /
width - 1.
f) *
s->flat_range[0];
2033 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
s->flat_range[1];
2034 const float r = hypotf(x, y);
2035 const float theta = asinf(
r);
2039 vec[2] =
cosf(theta);
2077 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2079 const float theta = acosf(vec[2]);
2080 const float r =
sinf(theta);
2081 const float c =
r / hypotf(vec[0], vec[1]);
2082 const float x = vec[0] *
c /
s->iflat_range[0];
2083 const float y = vec[1] *
c /
s->iflat_range[1];
2085 const float uf = (x + 1.f) *
width / 2.
f;
2086 const float vf = (y + 1.f) *
height / 2.
f;
2089 const int vi =
floorf(vf);
2091 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2093 *du = visible ? uf -
ui : 0.f;
2094 *dv = visible ? vf - vi : 0.f;
2096 for (
int i = 0;
i < 4;
i++) {
2097 for (
int j = 0; j < 4; j++) {
2120 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2122 const float phi =
atan2f(vec[0], vec[2]);
2123 const float theta = asinf(vec[1]);
2125 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2129 const int vi =
floorf(vf);
2134 for (
int i = 0;
i < 4;
i++) {
2135 for (
int j = 0; j < 4; j++) {
2158 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2160 const float phi =
atan2f(vec[0], vec[2]);
2161 const float theta = asinf(vec[1]);
2167 const int vi =
floorf(vf);
2174 for (
int i = 0;
i < 4;
i++) {
2175 for (
int j = 0; j < 4; j++) {
2195 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2196 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2215 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2217 const float theta = acosf(vec[2]);
2218 const float r = tanf(theta);
2220 const float zf = vec[2];
2221 const float h = hypotf(vec[0], vec[1]);
2222 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2223 float uf = vec[0] *
c /
s->iflat_range[0];
2224 float vf = vec[1] *
c /
s->iflat_range[1];
2225 int visible,
ui, vi;
2227 uf = zf >= 0.f ? (uf + 1.f) *
width / 2.
f : 0.
f;
2228 vf = zf >= 0.f ? (vf + 1.f) *
height / 2.
f : 0.
f;
2233 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2238 for (
int i = 0;
i < 4;
i++) {
2239 for (
int j = 0; j < 4; j++) {
2262 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2264 const float phi =
atan2f(vec[0], vec[2]);
2265 const float theta = vec[1];
2267 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2271 const int vi =
floorf(vf);
2276 for (
int i = 0;
i < 4;
i++) {
2277 for (
int j = 0; j < 4; j++) {
2301 const float y = ((2.f * j + 1.f) /
height - 1.
f) *
M_PI;
2302 const float div =
expf(2.
f * y) + 1.f;
2304 const float sin_phi =
sinf(phi);
2305 const float cos_phi =
cosf(phi);
2306 const float sin_theta = 2.f *
expf(y) / div;
2307 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2309 vec[0] = -sin_theta * cos_phi;
2311 vec[2] = sin_theta * sin_phi;
2330 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2332 const float l = hypotf(vec[0], vec[1]);
2333 const float r = sqrtf(1.
f - vec[2]) /
M_SQRT2;
2335 const float uf = (1.f +
r * vec[0] / (l > 0.f ? l : 1.f)) *
width * 0.5f;
2336 const float vf = (1.f +
r * vec[1] / (l > 0.f ? l : 1.f)) *
height * 0.5f;
2339 const int vi =
floorf(vf);
2344 for (
int i = 0;
i < 4;
i++) {
2345 for (
int j = 0; j < 4; j++) {
2368 const float x = (2.f *
i + 1.f) /
width - 1.
f;
2369 const float y = (2.f * j + 1.f) /
height - 1.
f;
2370 const float l = hypotf(x, y);
2373 const float z = 2.f * l * sqrtf(1.
f - l * l);
2375 vec[0] = z * x / (l > 0.f ? l : 1.f);
2376 vec[1] = z * y / (l > 0.f ? l : 1.f);
2377 vec[2] = 1.f - 2.f * l * l;
2402 const float x = ((2.f *
i + 1.f) /
width - 1.
f);
2403 const float y = ((2.f * j + 1.f) /
height - 1.
f);
2405 const float xx = x * x;
2406 const float yy = y * y;
2408 const float z = sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2411 const float b = 2.f * z * z - 1.f;
2413 const float aa =
a *
a;
2414 const float bb =
b *
b;
2416 const float w = sqrtf(1.
f - 2.
f * yy * z * z);
2418 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2420 vec[2] =
w * (bb - aa) / (aa + bb);
2441 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2443 const float theta =
atan2f(vec[0], vec[2]);
2445 const float z = sqrtf(1.
f + sqrtf(1.
f - vec[1] * vec[1]) *
cosf(theta * 0.5
f));
2446 const float x = sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2447 const float y = vec[1] / z;
2449 const float uf = (x + 1.f) *
width / 2.
f;
2450 const float vf = (y + 1.f) *
height / 2.
f;
2453 const int vi =
floorf(vf);
2458 for (
int i = 0;
i < 4;
i++) {
2459 for (
int j = 0; j < 4; j++) {
2482 const float theta = ((2.f * j + 1.f) /
height - 1.
f) *
M_PI_2;
2483 const float phi = ((2.f *
i + 1.f) /
width - 1.
f) *
M_PI /
cosf(theta);
2485 const float sin_phi =
sinf(phi);
2486 const float cos_phi =
cosf(phi);
2487 const float sin_theta =
sinf(theta);
2488 const float cos_theta =
cosf(theta);
2490 vec[0] = cos_theta * sin_phi;
2492 vec[2] = cos_theta * cos_phi;
2513 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2515 const float theta = asinf(vec[1]);
2516 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2518 const float uf = (phi /
M_PI + 1.f) *
width / 2.
f;
2522 const int vi =
floorf(vf);
2527 for (
int i = 0;
i < 4;
i++) {
2528 for (
int j = 0; j < 4; j++) {
2607 const float pixel_pad = 2;
2608 const float u_pad = pixel_pad /
width;
2609 const float v_pad = pixel_pad /
height;
2611 int u_face, v_face, face;
2613 float l_x, l_y, l_z;
2615 float uf = (
i + 0.5f) /
width;
2616 float vf = (j + 0.5f) /
height;
2623 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2627 }
else if (uf >= 3.
f) {
2632 uf = fmodf(uf, 1.
f) - 0.5f;
2637 vf = (vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2639 if (uf >= -0.5
f && uf < 0.5
f) {
2644 if (vf >= -0.5
f && vf < 0.5
f) {
2650 face = u_face + 3 * v_face;
2710 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2712 const float pixel_pad = 2;
2713 const float u_pad = pixel_pad /
width;
2714 const float v_pad = pixel_pad /
height;
2718 int direction, face;
2723 face =
s->in_cubemap_face_order[direction];
2727 uf = M_2_PI *
atanf(uf) + 0.5f;
2728 vf = M_2_PI *
atanf(vf) + 0.5f;
2731 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2732 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2746 for (
int i = 0;
i < 4;
i++) {
2747 for (
int j = 0; j < 4; j++) {
2767 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2768 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2787 const float l_x =
s->flat_range[0] * ((2.f *
i + 0.5f) /
width - 1.
f);
2788 const float l_y =
s->flat_range[1] * ((2.f * j + 0.5f) /
height - 1.
f);
2810 s->flat_range[0] =
s->h_fov / 180.f;
2811 s->flat_range[1] =
s->v_fov / 180.f;
2830 const float uf =
s->flat_range[0] * ((2.f *
i) /
width - 1.
f);
2831 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.
f);
2833 const float phi =
atan2f(vf, uf);
2834 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2836 const float sin_phi =
sinf(phi);
2837 const float cos_phi =
cosf(phi);
2838 const float sin_theta =
sinf(theta);
2839 const float cos_theta =
cosf(theta);
2841 vec[0] = cos_theta * cos_phi;
2842 vec[1] = cos_theta * sin_phi;
2861 s->iflat_range[0] =
s->ih_fov / 180.f;
2862 s->iflat_range[1] =
s->iv_fov / 180.f;
2881 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2883 const float h = hypotf(vec[0], vec[1]);
2884 const float lh =
h > 0.f ?
h : 1.f;
2887 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2888 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2890 const int visible = hypotf(uf, vf) <= 0.5f;
2893 uf = (uf + 0.5f) *
width;
2894 vf = (vf + 0.5f) *
height;
2899 *du = visible ? uf -
ui : 0.f;
2900 *dv = visible ? vf - vi : 0.f;
2902 for (
int i = 0;
i < 4;
i++) {
2903 for (
int j = 0; j < 4; j++) {
2926 const float uf = ((2.f *
i + 1.f) /
width - 1.
f);
2927 const float vf = ((2.f * j + 1.f) /
height - 1.
f);
2929 const float d =
s->h_fov;
2930 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2931 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2932 const float clon = (-k * d + sqrtf(dscr)) / (k + 1.
f);
2933 const float S = (d + 1.f) / (d + clon);
2934 const float lon =
atan2f(uf,
S * clon);
2935 const float lat =
atan2f(vf,
S);
2960 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2962 const float phi =
atan2f(vec[0], vec[2]);
2963 const float theta = asinf(vec[1]);
2965 const float d =
s->ih_fov;
2966 const float S = (d + 1.f) / (d +
cosf(phi));
2968 const float x =
S *
sinf(phi);
2969 const float y =
S * tanf(theta);
2971 const float uf = (x + 1.f) *
width / 2.
f;
2972 const float vf = (y + 1.f) *
height / 2.
f;
2975 const int vi =
floorf(vf);
2977 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
2982 for (
int i = 0;
i < 4;
i++) {
2983 for (
int j = 0; j < 4; j++) {
3003 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3004 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3023 const float uf =
s->flat_range[0] * ((2.f *
i + 1.f) /
width - 1.
f);
3024 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.
f);
3026 const float phi = uf;
3027 const float theta =
atanf(vf);
3029 const float sin_phi =
sinf(phi);
3030 const float cos_phi =
cosf(phi);
3031 const float sin_theta =
sinf(theta);
3032 const float cos_theta =
cosf(theta);
3034 vec[0] = cos_theta * sin_phi;
3036 vec[2] = cos_theta * cos_phi;
3054 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3055 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3074 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3076 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3077 const float theta = asinf(vec[1]);
3079 const float uf = (phi + 1.f) * (
width - 1) / 2.f;
3080 const float vf = (tanf(theta) /
s->iflat_range[1] + 1.f) *
height / 2.
f;
3083 const int vi =
floorf(vf);
3085 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3086 theta <=
M_PI *
s->iv_fov / 180.f &&
3087 theta >= -
M_PI *
s->iv_fov / 180.f;
3092 for (
int i = 0;
i < 4;
i++) {
3093 for (
int j = 0; j < 4; j++) {
3116 const float uf = ((2.f *
i + 1.f) /
width - 1.
f);
3117 const float vf = ((2.f * j + 1.f) /
height - 1.
f);
3118 const float rh = hypotf(uf, vf);
3119 const float sinzz = 1.f - rh * rh;
3120 const float h = 1.f +
s->v_fov;
3121 const float sinz = (
h - sqrtf(sinzz)) / (
h / rh + rh /
h);
3122 const float sinz2 = sinz * sinz;
3125 const float cosz = sqrtf(1.
f - sinz2);
3127 const float theta = asinf(cosz);
3128 const float phi =
atan2f(uf, vf);
3130 const float sin_phi =
sinf(phi);
3131 const float cos_phi =
cosf(phi);
3132 const float sin_theta =
sinf(theta);
3133 const float cos_theta =
cosf(theta);
3135 vec[0] = cos_theta * sin_phi;
3136 vec[1] = cos_theta * cos_phi;
3162 const float uf = (float)
i /
width;
3163 const float vf = (float)j /
height;
3165 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3166 vec[1] = 1.f - vf * 2.f;
3167 vec[2] = 2.f *
fabsf(1.
f -
fabsf(1.
f - uf * 2.
f + vf)) - 1.f;
3188 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3190 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3191 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3192 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3193 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3196 float uf, vf, x, y, z;
3203 vf = 0.5f - y * 0.5f;
3205 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3206 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3207 uf = 0.25f * x + 0.25f;
3209 uf = 0.75f - 0.25f * x;
3221 for (
int i = 0;
i < 4;
i++) {
3222 for (
int j = 0; j < 4; j++) {
3245 const float ew =
width / 2.f;
3248 const int ei =
i >= ew ?
i - ew :
i;
3249 const float m =
i >= ew ? 1.f : -1.f;
3251 const float uf =
s->flat_range[0] * ((2.f * ei) / ew - 1.
f);
3252 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) / eh - 1.
f);
3254 const float h = hypotf(uf, vf);
3255 const float lh =
h > 0.f ?
h : 1.f;
3256 const float theta = m *
M_PI_2 * (1.f -
h);
3258 const float sin_theta =
sinf(theta);
3259 const float cos_theta =
cosf(theta);
3261 vec[0] = cos_theta * m * uf / lh;
3262 vec[1] = cos_theta * vf / lh;
3284 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3286 const float ew =
width / 2.f;
3289 const float h = hypotf(vec[0], vec[1]);
3290 const float lh =
h > 0.f ?
h : 1.f;
3291 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3293 float uf = (theta * (vec[0] / lh) /
s->iflat_range[0] + 0.5f) * ew;
3294 float vf = (theta * (vec[1] / lh) /
s->iflat_range[1] + 0.5f) * eh;
3299 if (vec[2] >= 0.
f) {
3300 u_shift =
ceilf(ew);
3312 for (
int i = 0;
i < 4;
i++) {
3313 for (
int j = 0; j < 4; j++) {
3336 const float scale = 0.99f;
3337 float l_x, l_y, l_z;
3340 const float theta_range = M_PI_4;
3342 const int ew = 4 *
width / 5;
3345 const float phi = ((2.f *
i) / ew - 1.
f) *
M_PI / scale;
3346 const float theta = ((2.f * j) / eh - 1.
f) * theta_range / scale;
3348 const float sin_phi =
sinf(phi);
3349 const float cos_phi =
cosf(phi);
3350 const float sin_theta =
sinf(theta);
3351 const float cos_theta =
cosf(theta);
3353 l_x = cos_theta * sin_phi;
3355 l_z = cos_theta * cos_phi;
3357 const int ew =
width / 5;
3358 const int eh =
height / 2;
3363 uf = 2.f * (
i - 4 * ew) / ew - 1.
f;
3364 vf = 2.f * (j ) / eh - 1.
f;
3373 uf = 2.f * (
i - 4 * ew) / ew - 1.
f;
3374 vf = 2.f * (j - eh) / eh - 1.
f;
3408 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3410 const float scale = 0.99f;
3412 const float phi =
atan2f(vec[0], vec[2]);
3413 const float theta = asinf(vec[1]);
3414 const float theta_range = M_PI_4;
3417 int u_shift, v_shift;
3421 if (theta > -theta_range && theta < theta_range) {
3428 uf = (phi /
M_PI * scale + 1.f) * ew / 2.
f;
3429 vf = (theta / theta_range * scale + 1.f) * eh / 2.
f;
3437 uf = -vec[0] / vec[1];
3438 vf = -vec[2] / vec[1];
3441 uf = vec[0] / vec[1];
3442 vf = -vec[2] / vec[1];
3446 uf = 0.5f * ew * (uf * scale + 1.f);
3447 vf = 0.5f * eh * (vf * scale + 1.f);
3456 for (
int i = 0;
i < 4;
i++) {
3457 for (
int j = 0; j < 4; j++) {
3459 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3480 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3482 const float phi =
atan2f(vec[0], vec[2]);
3483 const float theta = asinf(vec[1]);
3485 const float theta_range = M_PI_4;
3488 int u_shift, v_shift;
3492 if (theta >= -theta_range && theta <= theta_range) {
3493 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3494 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3503 vf = theta / M_PI_4;
3506 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3508 uf = (uf * scalew + 1.f) *
width / 3.
f;
3509 vf = (vf * scaleh + 1.f) *
height / 4.
f;
3511 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3512 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3520 if (theta <= 0.f && theta >= -
M_PI_2 &&
3521 phi <= M_PI_2 && phi >= -
M_PI_2) {
3522 uf = -vec[0] / vec[1];
3523 vf = -vec[2] / vec[1];
3526 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3527 phi <= M_PI_2 && phi >= -
M_PI_2) {
3528 uf = vec[0] / vec[1];
3529 vf = -vec[2] / vec[1];
3530 v_shift =
height * 0.25f;
3531 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3532 uf = vec[0] / vec[1];
3533 vf = vec[2] / vec[1];
3537 uf = -vec[0] / vec[1];
3538 vf = vec[2] / vec[1];
3539 v_shift =
height * 0.75f;
3542 uf = 0.5f *
width / 3.f * (uf * scalew + 1.f);
3543 vf =
height * 0.25f * (vf * scaleh + 1.f) + v_offset;
3552 for (
int i = 0;
i < 4;
i++) {
3553 for (
int j = 0; j < 4; j++) {
3555 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3576 const float x = (
i + 0.5f) /
width;
3577 const float y = (j + 0.5f) /
height;
3578 float l_x, l_y, l_z;
3580 if (x < 2.
f / 3.
f) {
3581 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3582 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3584 const float back =
floorf(y * 2.
f);
3586 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3587 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3589 const float sin_phi =
sinf(phi);
3590 const float cos_phi =
cosf(phi);
3591 const float sin_theta =
sinf(theta);
3592 const float cos_theta =
cosf(theta);
3594 l_x = cos_theta * sin_phi;
3596 l_z = cos_theta * cos_phi;
3598 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3599 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3601 const int face =
floorf(y * 4.
f);
3612 l_x = (0.5f - uf) / scalew;
3614 l_z = (0.5f - vf) / scaleh;
3619 vf = 1.f - (vf - 0.5f);
3621 l_x = (0.5f - uf) / scalew;
3623 l_z = (-0.5f + vf) / scaleh;
3626 vf = y * 2.f - 0.5f;
3627 vf = 1.f - (1.f - vf);
3629 l_x = (0.5f - uf) / scalew;
3631 l_z = (0.5f - vf) / scaleh;
3634 vf = y * 2.f - 1.5f;
3636 l_x = (0.5f - uf) / scalew;
3638 l_z = (-0.5f + vf) / scaleh;
3666 const float x = (
i + 0.5f) /
width;
3667 const float y = (j + 0.5f) /
height;
3670 vec[0] = x * 4.f - 1.f;
3671 vec[1] = (y * 2.f - 1.f);
3673 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3674 y >= 0.375
f && y < 0.625
f) {
3675 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3676 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3678 }
else if (0.5
f <= x && x < 0.6875
f &&
3679 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3680 (0.375
f <= y && y < 0.625
f) ||
3681 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3683 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3684 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3685 }
else if (0.8125
f <= x && x < 1.
f &&
3686 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3687 (0.375
f <= y && y < 0.625
f) ||
3688 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3690 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3691 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3692 }
else if (0.
f <= y && y < 0.375
f &&
3693 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3694 (0.6875
f <= x && x < 0.8125
f) ||
3695 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3696 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3698 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3700 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3702 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3724 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3732 uf = (uf + 1.f) * 0.5
f;
3733 vf = (vf + 1.f) * 0.5
f;
3737 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3738 vf = 0.375f - 0.375f * vf;
3744 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3745 vf = 1.f - 0.375f * vf;
3748 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3749 uf = 0.1875f * uf + 0.8125f;
3752 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3753 uf = 0.1875f * uf + 0.5f;
3756 uf = 0.125f * uf + 0.6875f;
3757 vf = 0.25f * vf + 0.375f;
3770 for (
int i = 0;
i < 4;
i++) {
3771 for (
int j = 0; j < 4; j++) {
3794 const float x = ((
i + 0.5f) /
width) * 2.f - 1.f;
3795 const float y = ((j + 0.5f) /
height) * 2.f - 1.f;
3796 const float ax =
fabsf(x);
3797 const float ay =
fabsf(y);
3799 vec[2] = 1.f - (ax + ay);
3800 if (ax + ay > 1.
f) {
3801 vec[0] = (1.f - ay) *
FFSIGN(x);
3802 vec[1] = (1.f - ax) *
FFSIGN(y);
3827 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3843 uf = uf * 0.5f + 0.5f;
3844 vf = vf * 0.5f + 0.5f;
3855 for (
int i = 0;
i < 4;
i++) {
3856 for (
int j = 0; j < 4; j++) {
3867 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
3868 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
3869 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
3870 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
3885 float rot_quaternion[2][4],
3886 const int rotation_order[3])
3888 const float yaw_rad = yaw *
M_PI / 180.f;
3889 const float pitch_rad = pitch *
M_PI / 180.f;
3890 const float roll_rad = roll *
M_PI / 180.f;
3892 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
3893 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
3894 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
3895 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
3896 const float sin_roll =
sinf(roll_rad * 0.5
f);
3897 const float cos_roll =
cosf(roll_rad * 0.5
f);
3902 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
3903 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
3904 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
3919 static inline void rotate(
const float rot_quaternion[2][4],
3922 float qv[4],
temp[4], rqv[4];
3940 modifier[0] = h_flip ? -1.f : 1.f;
3941 modifier[1] = v_flip ? -1.f : 1.f;
3942 modifier[2] = d_flip ? -1.f : 1.f;
3945 static inline void mirror(
const float *modifier,
float *vec)
3947 vec[0] *= modifier[0];
3948 vec[1] *= modifier[1];
3949 vec[2] *= modifier[2];
3952 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
3955 for (
int i = 0;
i < 4;
i++) {
3956 for (
int j = 0; j < 4; j++)
3957 u[
i][j] =
w - 1 -
u[
i][j];
3962 for (
int i = 0;
i < 4;
i++) {
3963 for (
int j = 0; j < 4; j++)
3964 v[
i][j] =
h - 1 - v[
i][j];
3971 const int pr_height =
s->pr_height[p];
3973 for (
int n = 0; n <
s->nb_threads; n++) {
3975 const int slice_start = (pr_height * n ) /
s->nb_threads;
3976 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
3983 if (!
r->u[p] || !
r->v[p])
3992 if (sizeof_mask && !p) {
4008 const float d = 0.5f * hypotf(
w,
h);
4009 const float l =
sinf(d_fov *
M_PI / 360.
f) / d;
4011 *h_fov = asinf(
w * 0.5 * l) * 360.f /
M_PI;
4012 *v_fov = asinf(
h * 0.5 * l) * 360.f /
M_PI;
4014 if (d_fov > 180.
f) {
4015 *h_fov = 180.f - *h_fov;
4016 *v_fov = 180.f - *v_fov;
4022 const float d = 0.5f * hypotf(
w,
h);
4023 const float l = d / (
sinf(d_fov *
M_PI / 720.
f));
4025 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4026 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4031 const float d = 0.5f * hypotf(
w,
h);
4032 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
4040 const float d = 0.5f * hypotf(
w * 0.5
f,
h);
4042 *h_fov = d /
w * 2.f * d_fov;
4043 *v_fov = d /
h * d_fov;
4048 const float d = 0.5f * hypotf(
w,
h);
4050 *h_fov = d /
w * d_fov;
4051 *v_fov = d /
h * d_fov;
4057 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4058 const float d = hypotf(
w,
h);
4075 outw[0] = outw[3] =
w;
4077 outh[0] = outh[3] =
h;
4086 for (
int p = 0; p <
s->nb_allocated; p++) {
4087 const int max_value =
s->max_value;
4088 const int width =
s->pr_width[p];
4089 const int uv_linesize =
s->uv_linesize[p];
4090 const int height =
s->pr_height[p];
4091 const int in_width =
s->inplanewidth[p];
4092 const int in_height =
s->inplaneheight[p];
4093 const int slice_start = (
height * jobnr ) / nb_jobs;
4100 for (
int j = slice_start; j <
slice_end; j++) {
4102 int16_t *
u =
r->u[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4103 int16_t *v =
r->v[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4104 int16_t *ker =
r->ker[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4105 uint8_t *mask8 = p ?
NULL :
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4106 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4107 int in_mask, out_mask;
4109 if (
s->out_transpose)
4114 rotate(
s->rot_quaternion, vec);
4117 mirror(
s->output_mirror_modifier, vec);
4118 if (
s->in_transpose)
4119 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4121 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4122 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4124 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4126 if (!p &&
r->mask) {
4127 if (
s->mask_size == 1) {
4128 mask8[0] = 255 * (out_mask & in_mask);
4130 mask16[0] = max_value * (out_mask & in_mask);
4146 const int depth =
desc->comp[0].depth;
4147 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4152 int in_offset_h, in_offset_w;
4153 int out_offset_h, out_offset_w;
4158 s->max_value = (1 << depth) - 1;
4160 switch (
s->interp) {
4163 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4165 sizeof_uv =
sizeof(int16_t) *
s->elements;
4170 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4171 s->elements = 2 * 2;
4172 sizeof_uv =
sizeof(int16_t) *
s->elements;
4173 sizeof_ker =
sizeof(int16_t) *
s->elements;
4177 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4178 s->elements = 3 * 3;
4179 sizeof_uv =
sizeof(int16_t) *
s->elements;
4180 sizeof_ker =
sizeof(int16_t) *
s->elements;
4184 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4185 s->elements = 4 * 4;
4186 sizeof_uv =
sizeof(int16_t) *
s->elements;
4187 sizeof_ker =
sizeof(int16_t) *
s->elements;
4191 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4192 s->elements = 4 * 4;
4193 sizeof_uv =
sizeof(int16_t) *
s->elements;
4194 sizeof_ker =
sizeof(int16_t) *
s->elements;
4198 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4199 s->elements = 4 * 4;
4200 sizeof_uv =
sizeof(int16_t) *
s->elements;
4201 sizeof_ker =
sizeof(int16_t) *
s->elements;
4205 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4206 s->elements = 4 * 4;
4207 sizeof_uv =
sizeof(int16_t) *
s->elements;
4208 sizeof_ker =
sizeof(int16_t) *
s->elements;
4212 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4213 s->elements = 4 * 4;
4214 sizeof_uv =
sizeof(int16_t) *
s->elements;
4215 sizeof_ker =
sizeof(int16_t) *
s->elements;
4223 for (
int order = 0; order <
NB_RORDERS; order++) {
4224 const char c =
s->rorder[order];
4229 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4230 s->rotation_order[0] =
YAW;
4231 s->rotation_order[1] =
PITCH;
4232 s->rotation_order[2] =
ROLL;
4239 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4240 s->rotation_order[0] =
YAW;
4241 s->rotation_order[1] =
PITCH;
4242 s->rotation_order[2] =
ROLL;
4246 s->rotation_order[order] = rorder;
4249 switch (
s->in_stereo) {
4253 in_offset_w = in_offset_h = 0;
4274 s->in_width =
s->inplanewidth[0];
4275 s->in_height =
s->inplaneheight[0];
4277 if (
s->id_fov > 0.f)
4280 if (
s->in_transpose)
4281 FFSWAP(
int,
s->in_width,
s->in_height);
4585 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4586 s->out ==
FLAT &&
s->d_fov == 0.f) {
4588 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4589 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4590 s->out ==
FLAT &&
s->d_fov == 0.f) {
4592 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4593 }
else if (
s->width > 0 &&
s->height > 0) {
4596 }
else if (
s->width > 0 ||
s->height > 0) {
4600 if (
s->out_transpose)
4603 if (
s->in_transpose)
4614 err = prepare_out(
ctx);
4621 switch (
s->out_stereo) {
4623 out_offset_w = out_offset_h = 0;
4642 for (
int i = 0;
i < 4;
i++)
4652 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4653 s->nb_allocated = 1;
4654 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4656 s->nb_allocated = 2;
4657 s->map[0] =
s->map[3] = 0;
4658 s->map[1] =
s->map[2] = 1;
4661 if (!
s->slice_remap)
4662 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4663 if (!
s->slice_remap)
4666 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4667 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4673 s->rot_quaternion,
s->rotation_order);
4707 char *res,
int res_len,
int flags)
4712 s->yaw =
s->pitch =
s->roll = 0.f;
4725 s->rot_quaternion[0][0] = 1.f;
4726 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4735 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4738 for (
int p = 0; p <
s->nb_allocated; p++) {
4777 .priv_class = &v360_class,
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 FFSWAP(type, a, b)
#define u(width, name, range_min, range_max)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
static void gaussian_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for gaussian interpolation.
static __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
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.
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)
AVFormatInternal * internal
An opaque field for libavformat internal usage.
A link between two filters.
AVFILTER_DEFINE_CLASS(v360)
#define AV_PIX_FMT_YUVA422P10
static __device__ float ceilf(float a)
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
@ 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 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.
#define DEFINE_REMAP(ws, bits)
Generate remapping function with a given window size and pixel depth.
#define AV_PIX_FMT_GBRAP12
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
#define AV_PIX_FMT_YUV444P16
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
static int fisheye_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in fisheye format.
static int reflecty(int y, int h)
Reflect y operation.
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
static void bilinear_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for bilinear interpolation.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static enum AVPixelFormat pix_fmts[]
#define AV_PIX_FMT_YUVA444P12
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)
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
void ff_v360_init(V360Context *s, int depth)
#define AV_PIX_FMT_GBRP16
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
static int xyz_to_cube1x6(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cubemap1x6 format for corresponding 3D coordinates on sphere.
static void calculate_gaussian_coeffs(float t, float *coeffs)
Calculate 1-dimensional gaussian coefficients.
static int ereflectx(int x, int y, int w, int h)
Reflect x operation for equirect.
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
static int mercator_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in mercator format.
static int prepare_fisheye_out(AVFilterContext *ctx)
Prepare data for processing fisheye output format.
#define AV_PIX_FMT_YUV440P10
static void rotate_cube_face(float *uf, float *vf, int rotation)
static void calculate_lagrange_coeffs(float t, float *coeffs)
Calculate 1-dimensional lagrange coefficients.
static int cube1x6_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap1x6 format.
static int barrel_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in barrel facebook's format.
#define AV_PIX_FMT_YUV422P10
static int prepare_cylindrical_out(AVFilterContext *ctx)
Prepare data for processing cylindrical output format.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
static int prepare_cylindrical_in(AVFilterContext *ctx)
Prepare data for processing cylindrical input format.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static int pannini_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in pannini format.
static int xyz_to_ball(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in ball format for corresponding 3D coordinates on sphere.
static int hammer_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in hammer format.
static void mirror(const float *modifier, float *vec)
static int cylindrical_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cylindrical format.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void nearest_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Save nearest pixel coordinates for remapping.
#define AV_PIX_FMT_YUV422P12
static void spline16_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for spline16 interpolation.
static av_cold void uninit(AVFilterContext *ctx)
#define AV_PIX_FMT_YUV444P12
AVFilterContext * src
source filter
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
static int eac_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in equi-angular cubemap format.
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
#define AV_PIX_FMT_YUVA444P10
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int prepare_fisheye_in(AVFilterContext *ctx)
Prepare data for processing fisheye input format.
static int query_formats(AVFilterContext *ctx)
static int prepare_equisolid_out(AVFilterContext *ctx)
Prepare data for processing equisolid output format.
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static void bicubic_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for bicubic interpolation.
static int xyz_to_equirect(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in equirectangular format for corresponding 3D coordinates on sphere.
static int cube3x2_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap3x2 format.
static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p)
int w
agreed upon image width
#define DEFINE_REMAP_LINE(ws, bits, div)
static int prepare_stereographic_out(AVFilterContext *ctx)
Prepare data for processing stereographic output format.
static int config_output(AVFilterLink *outlink)
#define AV_PIX_FMT_GBRP12
static int cube6x1_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap6x1 format.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
static void xyz_to_cube(const V360Context *s, const float *vec, float *uf, float *vf, int *direction)
Calculate cubemap position for corresponding 3D coordinates on sphere.
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static int xyz_to_fisheye(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in fisheye format for corresponding 3D coordinates on sphere.
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
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.
#define AV_PIX_FMT_YUV444P9
static int mod(int a, int b)
Modulo operation with only positive remainders.
static int prepare_flat_out(AVFilterContext *ctx)
Prepare data for processing flat output format.
static int hequirect_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in half equirectangular format.
static int xyz_to_tetrahedron(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in tetrahedron format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA444P9
#define DEFINE_REMAP1_LINE(bits, div)
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.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
int h
agreed upon image height
static int xyz_to_pannini(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in pannini format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA422P12
static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static void calculate_bicubic_coeffs(float t, float *coeffs)
Calculate 1-dimensional cubic coefficients.
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
static int prepare_flat_in(AVFilterContext *ctx)
Prepare data for processing flat input format.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
static 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[]
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)
#define AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_GRAY12
static enum AVPixelFormat alpha_pix_fmts[]
static int get_direction(char c)
Convert char to corresponding direction.
static int prepare_eac_in(AVFilterContext *ctx)
Prepare data for processing equi-angular cubemap input format.
static void set_dimensions(int *outw, int *outh, int w, int h, const AVPixFmtDescriptor *desc)
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
#define AV_PIX_FMT_YUV420P14
static int flat_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in flat format.
static int prepare_orthographic_in(AVFilterContext *ctx)
Prepare data for processing orthographic input format.