Go to the documentation of this file.
53 #define OFFSET(x) offsetof(V360Context, x)
54 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
55 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
256 #define DEFINE_REMAP1_LINE(bits, div) \
257 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
258 ptrdiff_t in_linesize, \
259 const int16_t *const u, const int16_t *const v, \
260 const int16_t *const ker) \
262 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
263 uint##bits##_t *d = (uint##bits##_t *)dst; \
265 in_linesize /= div; \
267 for (int x = 0; x < width; x++) \
268 d[x] = s[v[x] * in_linesize + u[x]]; \
280 #define DEFINE_REMAP(ws, bits) \
281 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
283 ThreadData *td = arg; \
284 const V360Context *s = ctx->priv; \
285 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
286 const AVFrame *in = td->in; \
287 AVFrame *out = td->out; \
289 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
290 for (int plane = 0; plane < s->nb_planes; plane++) { \
291 const unsigned map = s->map[plane]; \
292 const int in_linesize = in->linesize[plane]; \
293 const int out_linesize = out->linesize[plane]; \
294 const int uv_linesize = s->uv_linesize[plane]; \
295 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
296 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
297 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
298 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
299 const uint8_t *const src = in->data[plane] + \
300 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
301 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
302 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
303 const int width = s->pr_width[plane]; \
304 const int height = s->pr_height[plane]; \
306 const int slice_start = (height * jobnr ) / nb_jobs; \
307 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
309 for (int y = slice_start; y < slice_end && !mask; y++) { \
310 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
311 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
312 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
314 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
317 for (int y = slice_start; y < slice_end && mask; y++) { \
318 memcpy(dst + y * out_linesize, mask + \
319 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
336 #define DEFINE_REMAP_LINE(ws, bits, div) \
337 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
338 ptrdiff_t in_linesize, \
339 const int16_t *const u, const int16_t *const v, \
340 const int16_t *const ker) \
342 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
343 uint##bits##_t *d = (uint##bits##_t *)dst; \
345 in_linesize /= div; \
347 for (int x = 0; x < width; x++) { \
348 const int16_t *const uu = u + x * ws * ws; \
349 const int16_t *const vv = v + x * ws * ws; \
350 const int16_t *const kker = ker + x * ws * ws; \
353 for (int i = 0; i < ws; i++) { \
354 const int iws = i * ws; \
355 for (int j = 0; j < ws; j++) { \
356 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
360 d[x] = av_clip_uint##bits(tmp >> 14); \
375 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
378 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
381 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
388 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
408 int16_t *
u, int16_t *v, int16_t *ker)
411 const int j =
lrintf(du) + 1;
413 u[0] = rmap->
u[
i][j];
414 v[0] = rmap->
v[
i][j];
428 int16_t *
u, int16_t *v, int16_t *ker)
430 for (
int i = 0;
i < 2;
i++) {
431 for (
int j = 0; j < 2; j++) {
432 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
433 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
437 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
438 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
439 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
440 ker[3] =
lrintf( du * dv * 16385.
f);
451 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
452 coeffs[1] = -t * (t - 2.f);
453 coeffs[2] = t * (t - 1.f) * 0.5
f;
467 int16_t *
u, int16_t *v, int16_t *ker)
475 for (
int i = 0;
i < 3;
i++) {
476 for (
int j = 0; j < 3; j++) {
477 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
478 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
479 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
492 const float tt = t * t;
493 const float ttt = t * t * t;
495 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
496 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
497 coeffs[2] = t + tt / 2.f - ttt / 2.f;
498 coeffs[3] = - t / 6.f + ttt / 6.f;
512 int16_t *
u, int16_t *v, int16_t *ker)
520 for (
int i = 0;
i < 4;
i++) {
521 for (
int j = 0; j < 4; j++) {
522 u[
i * 4 + j] = rmap->
u[
i][j];
523 v[
i * 4 + j] = rmap->
v[
i][j];
524 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
539 for (
int i = 0;
i < 4;
i++) {
540 const float x =
M_PI * (t -
i + 1);
544 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
549 for (
int i = 0;
i < 4;
i++) {
565 int16_t *
u, int16_t *v, int16_t *ker)
573 for (
int i = 0;
i < 4;
i++) {
574 for (
int j = 0; j < 4; j++) {
575 u[
i * 4 + j] = rmap->
u[
i][j];
576 v[
i * 4 + j] = rmap->
v[
i][j];
577 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
590 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
591 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
592 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
593 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
607 int16_t *
u, int16_t *v, int16_t *ker)
615 for (
int i = 0;
i < 4;
i++) {
616 for (
int j = 0; j < 4; j++) {
617 u[
i * 4 + j] = rmap->
u[
i][j];
618 v[
i * 4 + j] = rmap->
v[
i][j];
619 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
634 for (
int i = 0;
i < 4;
i++) {
635 const float x = t - (
i - 1);
639 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
644 for (
int i = 0;
i < 4;
i++) {
660 int16_t *
u, int16_t *v, int16_t *ker)
668 for (
int i = 0;
i < 4;
i++) {
669 for (
int j = 0; j < 4; j++) {
670 u[
i * 4 + j] = rmap->
u[
i][j];
671 v[
i * 4 + j] = rmap->
v[
i][j];
672 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
687 float p0 = (6.f - 2.f *
b) / 6.
f,
688 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
689 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
690 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
691 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
692 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
693 q3 = (-
b - 6.f *
c) / 6.
f;
695 for (
int i = 0;
i < 4;
i++) {
696 const float x =
fabsf(t -
i + 1.
f);
698 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
699 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
700 }
else if (x < 2.
f) {
701 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
702 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
709 for (
int i = 0;
i < 4;
i++) {
725 int16_t *
u, int16_t *v, int16_t *ker)
733 for (
int i = 0;
i < 4;
i++) {
734 for (
int j = 0; j < 4; j++) {
735 u[
i * 4 + j] = rmap->
u[
i][j];
736 v[
i * 4 + j] = rmap->
v[
i][j];
737 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
752 const int res =
a %
b;
884 for (
int face = 0; face <
NB_FACES; face++) {
885 const char c =
s->in_forder[face];
890 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
895 if (direction == -1) {
897 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
901 s->in_cubemap_face_order[direction] = face;
904 for (
int face = 0; face <
NB_FACES; face++) {
905 const char c =
s->in_frot[face];
910 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
915 if (rotation == -1) {
917 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
921 s->in_cubemap_face_rotation[face] = rotation;
938 for (
int face = 0; face <
NB_FACES; face++) {
939 const char c =
s->out_forder[face];
944 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
949 if (direction == -1) {
951 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
955 s->out_cubemap_direction_order[face] = direction;
958 for (
int face = 0; face <
NB_FACES; face++) {
959 const char c =
s->out_frot[face];
964 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
969 if (rotation == -1) {
971 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
975 s->out_cubemap_face_rotation[face] = rotation;
1051 const float norm =
sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1071 float uf,
float vf,
int face,
1072 float *vec,
float scalew,
float scaleh)
1074 const int direction =
s->out_cubemap_direction_order[face];
1075 float l_x, l_y, l_z;
1082 switch (direction) {
1134 float *uf,
float *vf,
int *direction)
1136 const float phi =
atan2f(vec[0], vec[2]);
1137 const float theta = asinf(vec[1]);
1138 float phi_norm, theta_threshold;
1152 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1155 theta_threshold =
atanf(
cosf(phi_norm));
1156 if (theta > theta_threshold) {
1158 }
else if (theta < -theta_threshold) {
1162 switch (*direction) {
1164 *uf = -vec[2] / vec[0];
1165 *vf = vec[1] / vec[0];
1168 *uf = -vec[2] / vec[0];
1169 *vf = -vec[1] / vec[0];
1172 *uf = -vec[0] / vec[1];
1173 *vf = -vec[2] / vec[1];
1176 *uf = vec[0] / vec[1];
1177 *vf = -vec[2] / vec[1];
1180 *uf = vec[0] / vec[2];
1181 *vf = vec[1] / vec[2];
1184 *uf = vec[0] / vec[2];
1185 *vf = -vec[1] / vec[2];
1191 face =
s->in_cubemap_face_order[*direction];
1208 float uf,
float vf,
int direction,
1209 float *new_uf,
float *new_vf,
int *face)
1228 *face =
s->in_cubemap_face_order[direction];
1231 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1235 }
else if (uf < -1.
f) {
1237 switch (direction) {
1271 }
else if (uf >= 1.
f) {
1273 switch (direction) {
1307 }
else if (vf < -1.
f) {
1309 switch (direction) {
1343 }
else if (vf >= 1.
f) {
1345 switch (direction) {
1385 *face =
s->in_cubemap_face_order[direction];
1391 return (0.5
f * x + 0.5
f) * (
s - 1.f);
1396 return (2.
f * x + 1.
f) /
s - 1.f;
1413 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1414 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1416 const float ew =
width / 3.f;
1417 const float eh =
height / 2.f;
1419 const int u_face =
floorf(
i / ew);
1420 const int v_face =
floorf(j / eh);
1421 const int face = u_face + 3 * v_face;
1423 const int u_shift =
ceilf(ew * u_face);
1424 const int v_shift =
ceilf(eh * v_face);
1425 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1426 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1428 const float uf =
rescale(
i - u_shift, ewi);
1429 const float vf =
rescale(j - v_shift, ehi);
1450 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1452 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1453 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1454 const float ew =
width / 3.f;
1455 const float eh =
height / 2.f;
1459 int direction, face;
1467 face =
s->in_cubemap_face_order[direction];
1470 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1471 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1473 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1474 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1482 for (
int i = 0;
i < 4;
i++) {
1483 for (
int j = 0; j < 4; j++) {
1484 int new_ui =
ui + j - 1;
1485 int new_vi = vi +
i - 1;
1486 int u_shift, v_shift;
1487 int new_ewi, new_ehi;
1489 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1490 face =
s->in_cubemap_face_order[direction];
1494 u_shift =
ceilf(ew * u_face);
1495 v_shift =
ceilf(eh * v_face);
1497 uf = 2.f * new_ui / ewi - 1.f;
1498 vf = 2.f * new_vi / ehi - 1.f;
1510 u_shift =
ceilf(ew * u_face);
1511 v_shift =
ceilf(eh * v_face);
1512 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1513 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1515 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1516 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1519 us[
i][j] = u_shift + new_ui;
1520 vs[
i][j] = v_shift + new_vi;
1541 const float scalew =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1542 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1544 const float ew =
width;
1545 const float eh =
height / 6.f;
1547 const int face =
floorf(j / eh);
1549 const int v_shift =
ceilf(eh * face);
1550 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1553 const float vf =
rescale(j - v_shift, ehi);
1574 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1575 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1577 const float ew =
width / 6.f;
1580 const int face =
floorf(
i / ew);
1582 const int u_shift =
ceilf(ew * face);
1583 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1585 const float uf =
rescale(
i - u_shift, ewi);
1586 const float vf =
rescale(j, eh);
1607 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1609 const float scalew =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1610 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1611 const float eh =
height / 6.f;
1612 const int ewi =
width;
1616 int direction, face;
1623 face =
s->in_cubemap_face_order[direction];
1624 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1626 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1627 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1635 for (
int i = 0;
i < 4;
i++) {
1636 for (
int j = 0; j < 4; j++) {
1637 int new_ui =
ui + j - 1;
1638 int new_vi = vi +
i - 1;
1642 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1643 face =
s->in_cubemap_face_order[direction];
1645 v_shift =
ceilf(eh * face);
1647 uf = 2.f * new_ui / ewi - 1.f;
1648 vf = 2.f * new_vi / ehi - 1.f;
1658 v_shift =
ceilf(eh * face);
1659 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1662 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1666 vs[
i][j] = v_shift + new_vi;
1687 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1689 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1690 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1691 const float ew =
width / 6.f;
1696 int direction, face;
1703 face =
s->in_cubemap_face_order[direction];
1704 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1706 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1707 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1715 for (
int i = 0;
i < 4;
i++) {
1716 for (
int j = 0; j < 4; j++) {
1717 int new_ui =
ui + j - 1;
1718 int new_vi = vi +
i - 1;
1722 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1723 face =
s->in_cubemap_face_order[direction];
1725 u_shift =
ceilf(ew * face);
1727 uf = 2.f * new_ui / ewi - 1.f;
1728 vf = 2.f * new_vi / ehi - 1.f;
1738 u_shift =
ceilf(ew * face);
1739 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1741 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1745 us[
i][j] = u_shift + new_ui;
1764 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
1765 s->flat_range[1] =
s->v_fov *
M_PI / 360.f;
1787 const float sin_phi =
sinf(phi);
1788 const float cos_phi =
cosf(phi);
1789 const float sin_theta =
sinf(theta);
1790 const float cos_theta =
cosf(theta);
1792 vec[0] = cos_theta * sin_phi;
1794 vec[2] = cos_theta * cos_phi;
1816 const float sin_phi =
sinf(phi);
1817 const float cos_phi =
cosf(phi);
1818 const float sin_theta =
sinf(theta);
1819 const float cos_theta =
cosf(theta);
1821 vec[0] = cos_theta * sin_phi;
1823 vec[2] = cos_theta * cos_phi;
1839 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1840 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1861 const float r = hypotf(x, y);
1862 const float theta =
atanf(
r) * 2.f;
1863 const float sin_theta =
sinf(theta);
1865 vec[0] = x /
r * sin_theta;
1866 vec[1] = y /
r * sin_theta;
1867 vec[2] =
cosf(theta);
1883 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1884 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1903 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1905 const float theta = acosf(vec[2]);
1906 const float r = tanf(theta * 0.5
f);
1907 const float c =
r / hypotf(vec[0], vec[1]);
1908 const float x = vec[0] *
c /
s->iflat_range[0];
1909 const float y = vec[1] *
c /
s->iflat_range[1];
1915 const int vi =
floorf(vf);
1919 *du = visible ? uf -
ui : 0.f;
1920 *dv = visible ? vf - vi : 0.f;
1922 for (
int i = 0;
i < 4;
i++) {
1923 for (
int j = 0; j < 4; j++) {
1943 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1944 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1965 const float r = hypotf(x, y);
1966 const float theta = asinf(
r) * 2.f;
1967 const float sin_theta =
sinf(theta);
1969 vec[0] = x /
r * sin_theta;
1970 vec[1] = y /
r * sin_theta;
1971 vec[2] =
cosf(theta);
2007 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2009 const float theta = acosf(vec[2]);
2010 const float r =
sinf(theta * 0.5
f);
2011 const float c =
r / hypotf(vec[0], vec[1]);
2012 const float x = vec[0] *
c /
s->iflat_range[0];
2013 const float y = vec[1] *
c /
s->iflat_range[1];
2019 const int vi =
floorf(vf);
2023 *du = visible ? uf -
ui : 0.f;
2024 *dv = visible ? vf - vi : 0.f;
2026 for (
int i = 0;
i < 4;
i++) {
2027 for (
int j = 0; j < 4; j++) {
2069 const float r = hypotf(x, y);
2070 const float theta = asinf(
r);
2072 vec[2] =
cosf(theta);
2118 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2120 const float theta = acosf(vec[2]);
2121 const float r =
sinf(theta);
2122 const float c =
r / hypotf(vec[0], vec[1]);
2123 const float x = vec[0] *
c /
s->iflat_range[0];
2124 const float y = vec[1] *
c /
s->iflat_range[1];
2130 const int vi =
floorf(vf);
2132 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2134 *du = visible ? uf -
ui : 0.f;
2135 *dv = visible ? vf - vi : 0.f;
2137 for (
int i = 0;
i < 4;
i++) {
2138 for (
int j = 0; j < 4; j++) {
2158 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2159 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2178 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2180 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2181 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2187 const int vi =
floorf(vf);
2193 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2195 for (
int i = 0;
i < 4;
i++) {
2196 for (
int j = 0; j < 4; j++) {
2219 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2222 const float theta = asinf(vec[1]) /
M_PI_2;
2228 const int vi =
floorf(vf);
2235 for (
int i = 0;
i < 4;
i++) {
2236 for (
int j = 0; j < 4; j++) {
2256 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2257 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2276 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2278 const float theta = acosf(vec[2]);
2279 const float r = tanf(theta);
2281 const float zf = vec[2];
2282 const float h = hypotf(vec[0], vec[1]);
2283 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2284 float uf = vec[0] *
c /
s->iflat_range[0];
2285 float vf = vec[1] *
c /
s->iflat_range[1];
2286 int visible,
ui, vi;
2294 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2299 for (
int i = 0;
i < 4;
i++) {
2300 for (
int j = 0; j < 4; j++) {
2323 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2325 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2326 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2332 const int vi =
floorf(vf);
2337 for (
int i = 0;
i < 4;
i++) {
2338 for (
int j = 0; j < 4; j++) {
2363 const float div =
expf(2.
f * y) + 1.f;
2365 const float sin_phi =
sinf(phi);
2366 const float cos_phi =
cosf(phi);
2367 const float sin_theta = 2.f *
expf(y) / div;
2368 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2370 vec[0] = -sin_theta * cos_phi;
2372 vec[2] = sin_theta * sin_phi;
2391 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2393 const float l = hypotf(vec[0], vec[1]);
2395 const float d = l > 0.f ? l : 1.f;
2401 const int vi =
floorf(vf);
2406 for (
int i = 0;
i < 4;
i++) {
2407 for (
int j = 0; j < 4; j++) {
2432 const float l = hypotf(x, y);
2435 const float z = 2.f * l *
sqrtf(1.
f - l * l);
2437 vec[0] = z * x / (l > 0.f ? l : 1.f);
2438 vec[1] = z * y / (l > 0.f ? l : 1.f);
2439 vec[2] = 1.f - 2.f * l * l;
2467 const float xx = x * x;
2468 const float yy = y * y;
2470 const float z =
sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2473 const float b = 2.f * z * z - 1.f;
2475 const float aa =
a *
a;
2476 const float bb =
b *
b;
2478 const float w =
sqrtf(1.
f - 2.
f * yy * z * z);
2480 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2482 vec[2] =
w * (bb - aa) / (aa + bb);
2501 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2503 const float theta =
atan2f(vec[0], vec[2]);
2506 const float x =
sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2507 const float y = vec[1] / z;
2509 const float uf = (x + 1.f) *
width / 2.
f;
2510 const float vf = (y + 1.f) *
height / 2.
f;
2513 const int vi =
floorf(vf);
2518 for (
int i = 0;
i < 4;
i++) {
2519 for (
int j = 0; j < 4; j++) {
2545 const float sin_phi =
sinf(phi);
2546 const float cos_phi =
cosf(phi);
2547 const float sin_theta =
sinf(theta);
2548 const float cos_theta =
cosf(theta);
2550 vec[0] = cos_theta * sin_phi;
2552 vec[2] = cos_theta * cos_phi;
2571 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2573 const float theta = asinf(vec[1]);
2574 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2580 const int vi =
floorf(vf);
2585 for (
int i = 0;
i < 4;
i++) {
2586 for (
int j = 0; j < 4; j++) {
2665 const float pixel_pad = 2;
2666 const float u_pad = pixel_pad /
width;
2667 const float v_pad = pixel_pad /
height;
2669 int u_face, v_face, face;
2671 float l_x, l_y, l_z;
2673 float uf = (
i + 0.5f) /
width;
2674 float vf = (j + 0.5f) /
height;
2681 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2685 }
else if (uf >= 3.
f) {
2690 uf = fmodf(uf, 1.
f) - 0.5f;
2695 vf = (vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2697 if (uf >= -0.5
f && uf < 0.5
f) {
2702 if (vf >= -0.5
f && vf < 0.5
f) {
2708 face = u_face + 3 * v_face;
2766 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2768 const float pixel_pad = 2;
2769 const float u_pad = pixel_pad /
width;
2770 const float v_pad = pixel_pad /
height;
2774 int direction, face;
2779 face =
s->in_cubemap_face_order[direction];
2787 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2788 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2802 for (
int i = 0;
i < 4;
i++) {
2803 for (
int j = 0; j < 4; j++) {
2823 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2824 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2864 s->flat_range[0] =
s->h_fov / 180.f;
2865 s->flat_range[1] =
s->v_fov / 180.f;
2887 const float phi =
atan2f(vf, uf);
2888 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2890 const float sin_phi =
sinf(phi);
2891 const float cos_phi =
cosf(phi);
2892 const float sin_theta =
sinf(theta);
2893 const float cos_theta =
cosf(theta);
2895 vec[0] = cos_theta * cos_phi;
2896 vec[1] = cos_theta * sin_phi;
2913 s->iflat_range[0] =
s->ih_fov / 180.f;
2914 s->iflat_range[1] =
s->iv_fov / 180.f;
2933 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2935 const float h = hypotf(vec[0], vec[1]);
2936 const float lh =
h > 0.f ?
h : 1.f;
2939 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2940 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2942 const int visible = -0.5f < uf && uf < 0.5f && -0.5f < vf && vf < 0.5f;
2951 *du = visible ? uf -
ui : 0.f;
2952 *dv = visible ? vf - vi : 0.f;
2954 for (
int i = 0;
i < 4;
i++) {
2955 for (
int j = 0; j < 4; j++) {
2981 const float d =
s->h_fov;
2982 const float k = uf * uf / ((
d + 1.f) * (
d + 1.
f));
2983 const float dscr = k * k *
d *
d - (k + 1.f) * (k *
d *
d - 1.
f);
2984 const float clon = (-k *
d +
sqrtf(dscr)) / (k + 1.
f);
2985 const float S = (
d + 1.f) / (
d + clon);
2986 const float lon =
atan2f(uf,
S * clon);
2987 const float lat =
atan2f(vf,
S);
3010 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3012 const float phi =
atan2f(vec[0], vec[2]);
3013 const float theta = asinf(vec[1]);
3015 const float d =
s->ih_fov;
3016 const float S = (
d + 1.f) / (
d +
cosf(phi));
3018 const float x =
S *
sinf(phi);
3019 const float y =
S * tanf(theta);
3025 const int vi =
floorf(vf);
3027 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3032 for (
int i = 0;
i < 4;
i++) {
3033 for (
int j = 0; j < 4; j++) {
3053 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3054 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3076 const float phi = uf;
3077 const float theta =
atanf(vf);
3079 const float sin_phi =
sinf(phi);
3080 const float cos_phi =
cosf(phi);
3081 const float sin_theta =
sinf(theta);
3082 const float cos_theta =
cosf(theta);
3084 vec[0] = cos_theta * sin_phi;
3086 vec[2] = cos_theta * cos_phi;
3102 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3103 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3122 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3124 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3125 const float theta = asinf(vec[1]);
3128 const float vf =
scale(tanf(theta) /
s->iflat_range[1],
height);
3131 const int vi =
floorf(vf);
3133 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3134 theta <=
M_PI *
s->iv_fov / 180.f &&
3135 theta >= -
M_PI *
s->iv_fov / 180.f;
3140 for (
int i = 0;
i < 4;
i++) {
3141 for (
int j = 0; j < 4; j++) {
3161 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3162 s->flat_range[1] =
s->v_fov / 180.f;
3178 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3179 s->iflat_range[1] =
s->iv_fov / 180.f;
3201 const float phi = uf;
3202 const float theta = asinf(vf);
3204 const float sin_phi =
sinf(phi);
3205 const float cos_phi =
cosf(phi);
3206 const float sin_theta =
sinf(theta);
3207 const float cos_theta =
cosf(theta);
3209 vec[0] = cos_theta * sin_phi;
3211 vec[2] = cos_theta * cos_phi;
3230 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3232 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3233 const float theta = asinf(vec[1]);
3239 const int vi =
floorf(vf);
3241 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3242 theta <=
M_PI *
s->iv_fov / 180.f &&
3243 theta >= -
M_PI *
s->iv_fov / 180.f;
3248 for (
int i = 0;
i < 4;
i++) {
3249 for (
int j = 0; j < 4; j++) {
3274 const float rh = hypotf(uf, vf);
3275 const float sinzz = 1.f - rh * rh;
3276 const float h = 1.f +
s->v_fov;
3277 const float sinz = (
h -
sqrtf(sinzz)) / (
h / rh + rh /
h);
3278 const float sinz2 = sinz * sinz;
3281 const float cosz =
sqrtf(1.
f - sinz2);
3283 const float theta = asinf(cosz);
3284 const float phi =
atan2f(uf, vf);
3286 const float sin_phi =
sinf(phi);
3287 const float cos_phi =
cosf(phi);
3288 const float sin_theta =
sinf(theta);
3289 const float cos_theta =
cosf(theta);
3291 vec[0] = cos_theta * sin_phi;
3292 vec[1] = cos_theta * cos_phi;
3321 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3322 vec[1] = 1.f - vf * 2.f;
3323 vec[2] = 2.f *
fabsf(1.
f -
fabsf(1.
f - uf * 2.
f + vf)) - 1.f;
3342 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3344 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3345 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3346 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3347 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3350 float uf, vf, x, y, z;
3357 vf = 0.5f - y * 0.5f;
3359 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3360 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3361 uf = 0.25f * x + 0.25f;
3363 uf = 0.75f - 0.25f * x;
3375 for (
int i = 0;
i < 4;
i++) {
3376 for (
int j = 0; j < 4; j++) {
3396 s->iflat_range[0] =
s->ih_fov / 360.f;
3397 s->iflat_range[1] =
s->iv_fov / 360.f;
3416 const float ew =
width * 0.5f;
3419 const int ei =
i >= ew ?
i - ew :
i;
3420 const float m =
i >= ew ? 1.f : -1.f;
3422 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3423 const float vf =
s->flat_range[1] *
rescale(j, eh);
3425 const float h = hypotf(uf, vf);
3426 const float lh =
h > 0.f ?
h : 1.f;
3427 const float theta = m *
M_PI_2 * (1.f -
h);
3429 const float sin_theta =
sinf(theta);
3430 const float cos_theta =
cosf(theta);
3432 vec[0] = cos_theta * m * uf / lh;
3433 vec[1] = cos_theta * vf / lh;
3453 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3455 const float ew =
width * 0.5f;
3458 const float h = hypotf(vec[0], vec[1]);
3459 const float lh =
h > 0.f ?
h : 1.f;
3460 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3462 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3463 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3468 if (vec[2] >= 0.
f) {
3469 u_shift =
ceilf(ew);
3481 for (
int i = 0;
i < 4;
i++) {
3482 for (
int j = 0; j < 4; j++) {
3505 const float scale = 0.99f;
3506 float l_x, l_y, l_z;
3509 const float theta_range =
M_PI_4;
3511 const int ew = 4 *
width / 5;
3515 const float theta =
rescale(j, eh) * theta_range /
scale;
3517 const float sin_phi =
sinf(phi);
3518 const float cos_phi =
cosf(phi);
3519 const float sin_theta =
sinf(theta);
3520 const float cos_theta =
cosf(theta);
3522 l_x = cos_theta * sin_phi;
3524 l_z = cos_theta * cos_phi;
3526 const int ew =
width / 5;
3527 const int eh =
height / 2;
3575 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3577 const float scale = 0.99f;
3579 const float phi =
atan2f(vec[0], vec[2]);
3580 const float theta = asinf(vec[1]);
3581 const float theta_range =
M_PI_4;
3584 int u_shift, v_shift;
3588 if (theta > -theta_range && theta < theta_range) {
3596 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3604 uf = -vec[0] / vec[1];
3605 vf = -vec[2] / vec[1];
3608 uf = vec[0] / vec[1];
3609 vf = -vec[2] / vec[1];
3613 uf = 0.5f * ew * (uf *
scale + 1.f);
3614 vf = 0.5f * eh * (vf *
scale + 1.f);
3623 for (
int i = 0;
i < 4;
i++) {
3624 for (
int j = 0; j < 4; j++) {
3626 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3647 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3649 const float phi =
atan2f(vec[0], vec[2]);
3650 const float theta = asinf(vec[1]);
3652 const float theta_range =
M_PI_4;
3655 int u_shift, v_shift;
3659 if (theta >= -theta_range && theta <= theta_range) {
3660 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3661 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3673 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3675 uf = (uf * scalew + 1.f) *
width / 3.
f;
3676 vf = (vf * scaleh + 1.f) *
height / 4.
f;
3678 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3679 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3686 uf = vec[0] / vec[1] * scalew;
3687 vf = vec[2] / vec[1] * scaleh;
3689 if (theta <= 0.f && theta >= -
M_PI_2 &&
3690 phi <= M_PI_2 && phi >= -
M_PI_2) {
3693 vf = -(vf + 1.f) * scaleh + 1.
f;
3695 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3696 phi <= M_PI_2 && phi >= -
M_PI_2) {
3698 vf = -(vf - 1.f) * scaleh;
3699 v_shift =
height * 0.25f;
3700 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3702 vf = (vf - 1.f) * scaleh + 1.
f;
3707 vf = (vf + 1.f) * scaleh;
3708 v_shift =
height * 0.75f;
3711 uf = 0.5f *
width / 3.f * (uf + 1.f);
3721 for (
int i = 0;
i < 4;
i++) {
3722 for (
int j = 0; j < 4; j++) {
3724 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3745 const float x = (
i + 0.5f) /
width;
3746 const float y = (j + 0.5f) /
height;
3747 float l_x, l_y, l_z;
3750 if (x < 2.
f / 3.
f) {
3751 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3752 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3754 const float back =
floorf(y * 2.
f);
3756 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3757 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3759 const float sin_phi =
sinf(phi);
3760 const float cos_phi =
cosf(phi);
3761 const float sin_theta =
sinf(theta);
3762 const float cos_theta =
cosf(theta);
3764 l_x = cos_theta * sin_phi;
3766 l_z = cos_theta * cos_phi;
3770 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3771 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3773 const float facef =
floorf(y * 4.
f);
3774 const int face = facef;
3775 const float dir_vert = (face == 1 || face == 3) ? 1.0
f : -1.0
f;
3784 vf = (0.5f - 2.f * y) / scaleh + facef;
3788 vf = (y * 2.f - 1.5f) / scaleh + 3.
f - facef;
3791 l_x = (0.5f - uf) / scalew;
3792 l_y = 0.5f * dir_vert;
3793 l_z = (vf - 0.5f) * dir_vert / scaleh;
3794 ret = (l_x * l_x * scalew * scalew + l_z * l_z * scaleh * scaleh) < 0.5
f * 0.5
f;
3818 const float x = (
i + 0.5f) /
width;
3819 const float y = (j + 0.5f) /
height;
3822 vec[0] = x * 4.f - 1.f;
3823 vec[1] = (y * 2.f - 1.f);
3825 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3826 y >= 0.375
f && y < 0.625
f) {
3827 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3828 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3830 }
else if (0.5
f <= x && x < 0.6875
f &&
3831 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3832 (0.375
f <= y && y < 0.625
f) ||
3833 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3835 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3836 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3837 }
else if (0.8125
f <= x && x < 1.
f &&
3838 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3839 (0.375
f <= y && y < 0.625
f) ||
3840 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3842 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3843 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3844 }
else if (0.
f <= y && y < 0.375
f &&
3845 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3846 (0.6875
f <= x && x < 0.8125
f) ||
3847 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3848 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3850 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3852 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3854 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3874 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3882 uf = (uf + 1.f) * 0.5
f;
3883 vf = (vf + 1.f) * 0.5
f;
3887 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3888 vf = 0.375f - 0.375f * vf;
3894 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3895 vf = 1.f - 0.375f * vf;
3898 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3899 uf = 0.1875f * uf + 0.8125f;
3902 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3903 uf = 0.1875f * uf + 0.5f;
3906 uf = 0.125f * uf + 0.6875f;
3907 vf = 0.25f * vf + 0.375f;
3920 for (
int i = 0;
i < 4;
i++) {
3921 for (
int j = 0; j < 4; j++) {
3946 const float ax =
fabsf(x);
3947 const float ay =
fabsf(y);
3949 vec[2] = 1.f - (ax + ay);
3950 if (ax + ay > 1.
f) {
3951 vec[0] = (1.f - ay) *
FFSIGN(x);
3952 vec[1] = (1.f - ax) *
FFSIGN(y);
3975 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4000 for (
int i = 0;
i < 4;
i++) {
4001 for (
int j = 0; j < 4; j++) {
4012 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4013 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4014 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4015 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4030 float rot_quaternion[2][4],
4031 const int rotation_order[3])
4033 const float yaw_rad = yaw *
M_PI / 180.f;
4034 const float pitch_rad = pitch *
M_PI / 180.f;
4035 const float roll_rad = roll *
M_PI / 180.f;
4037 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4038 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4039 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4040 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4041 const float sin_roll =
sinf(roll_rad * 0.5
f);
4042 const float cos_roll =
cosf(roll_rad * 0.5
f);
4047 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4048 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4049 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4064 static inline void rotate(
const float rot_quaternion[2][4],
4067 float qv[4],
temp[4], rqv[4];
4085 modifier[0] = h_flip ? -1.f : 1.f;
4086 modifier[1] = v_flip ? -1.f : 1.f;
4087 modifier[2] = d_flip ? -1.f : 1.f;
4090 static inline void mirror(
const float *modifier,
float *vec)
4092 vec[0] *= modifier[0];
4093 vec[1] *= modifier[1];
4094 vec[2] *= modifier[2];
4097 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4100 for (
int i = 0;
i < 4;
i++) {
4101 for (
int j = 0; j < 4; j++)
4102 u[
i][j] =
w - 1 -
u[
i][j];
4107 for (
int i = 0;
i < 4;
i++) {
4108 for (
int j = 0; j < 4; j++)
4109 v[
i][j] =
h - 1 - v[
i][j];
4116 const int pr_height =
s->pr_height[p];
4118 for (
int n = 0; n <
s->nb_threads; n++) {
4120 const int slice_start = (pr_height * n ) /
s->nb_threads;
4121 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4128 if (!
r->u[p] || !
r->v[p])
4137 if (sizeof_mask && !p) {
4153 *v_fov = d_fov * 0.5f;
4157 const float d = 0.5f * hypotf(
w,
h);
4158 const float l =
sinf(d_fov *
M_PI / 360.
f) /
d;
4160 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4161 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4163 if (d_fov > 180.
f) {
4164 *h_fov = 180.f - *h_fov;
4165 *v_fov = 180.f - *v_fov;
4171 const float d = 0.5f * hypotf(
w,
h);
4172 const float l =
d / (
sinf(d_fov *
M_PI / 720.
f));
4174 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4175 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4180 const float d = 0.5f * hypotf(
w,
h);
4181 const float l =
d / (tanf(d_fov *
M_PI / 720.
f));
4189 const float d = hypotf(
w * 0.5
f,
h);
4191 *h_fov = 0.5f *
w /
d * d_fov;
4192 *v_fov =
h /
d * d_fov;
4197 const float d = hypotf(
w,
h);
4199 *h_fov =
w /
d * d_fov;
4200 *v_fov =
h /
d * d_fov;
4206 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4207 const float d = hypotf(
w,
h);
4224 outw[0] = outw[3] =
w;
4226 outh[0] = outh[3] =
h;
4235 for (
int p = 0; p <
s->nb_allocated; p++) {
4236 const int max_value =
s->max_value;
4237 const int width =
s->pr_width[p];
4238 const int uv_linesize =
s->uv_linesize[p];
4239 const int height =
s->pr_height[p];
4240 const int in_width =
s->inplanewidth[p];
4241 const int in_height =
s->inplaneheight[p];
4242 const int slice_start = (
height * jobnr ) / nb_jobs;
4249 for (
int j = slice_start; j <
slice_end; j++) {
4251 int16_t *
u =
r->u[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4252 int16_t *v =
r->v[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4253 int16_t *ker =
r->ker[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4254 uint8_t *mask8 = p ?
NULL :
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4255 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4256 int in_mask, out_mask;
4258 if (
s->out_transpose)
4265 rotate(
s->rot_quaternion, vec);
4268 mirror(
s->output_mirror_modifier, vec);
4269 if (
s->in_transpose)
4270 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4272 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4273 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4275 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4277 if (!p &&
r->mask) {
4278 if (
s->mask_size == 1) {
4279 mask8[0] = 255 * (out_mask & in_mask);
4281 mask16[0] = max_value * (out_mask & in_mask);
4297 const int depth =
desc->comp[0].depth;
4298 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4299 float default_h_fov = 360.f;
4300 float default_v_fov = 180.f;
4301 float default_ih_fov = 360.f;
4302 float default_iv_fov = 180.f;
4307 int in_offset_h, in_offset_w;
4308 int out_offset_h, out_offset_w;
4313 s->max_value = (1 << depth) - 1;
4315 switch (
s->interp) {
4318 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4320 sizeof_uv =
sizeof(int16_t) *
s->elements;
4325 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4326 s->elements = 2 * 2;
4327 sizeof_uv =
sizeof(int16_t) *
s->elements;
4328 sizeof_ker =
sizeof(int16_t) *
s->elements;
4332 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4333 s->elements = 3 * 3;
4334 sizeof_uv =
sizeof(int16_t) *
s->elements;
4335 sizeof_ker =
sizeof(int16_t) *
s->elements;
4339 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4340 s->elements = 4 * 4;
4341 sizeof_uv =
sizeof(int16_t) *
s->elements;
4342 sizeof_ker =
sizeof(int16_t) *
s->elements;
4346 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4347 s->elements = 4 * 4;
4348 sizeof_uv =
sizeof(int16_t) *
s->elements;
4349 sizeof_ker =
sizeof(int16_t) *
s->elements;
4353 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4354 s->elements = 4 * 4;
4355 sizeof_uv =
sizeof(int16_t) *
s->elements;
4356 sizeof_ker =
sizeof(int16_t) *
s->elements;
4360 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4361 s->elements = 4 * 4;
4362 sizeof_uv =
sizeof(int16_t) *
s->elements;
4363 sizeof_ker =
sizeof(int16_t) *
s->elements;
4367 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4368 s->elements = 4 * 4;
4369 sizeof_uv =
sizeof(int16_t) *
s->elements;
4370 sizeof_ker =
sizeof(int16_t) *
s->elements;
4378 for (
int order = 0; order <
NB_RORDERS; order++) {
4379 const char c =
s->rorder[order];
4384 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4385 s->rotation_order[0] =
YAW;
4386 s->rotation_order[1] =
PITCH;
4387 s->rotation_order[2] =
ROLL;
4394 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4395 s->rotation_order[0] =
YAW;
4396 s->rotation_order[1] =
PITCH;
4397 s->rotation_order[2] =
ROLL;
4401 s->rotation_order[order] = rorder;
4404 switch (
s->in_stereo) {
4408 in_offset_w = in_offset_h = 0;
4429 s->in_width =
s->inplanewidth[0];
4430 s->in_height =
s->inplaneheight[0];
4435 default_ih_fov = 90.f;
4436 default_iv_fov = 45.f;
4443 default_ih_fov = 180.f;
4444 default_iv_fov = 180.f;
4449 if (
s->ih_fov == 0.f)
4450 s->ih_fov = default_ih_fov;
4452 if (
s->iv_fov == 0.f)
4453 s->iv_fov = default_iv_fov;
4455 if (
s->id_fov > 0.f)
4458 if (
s->in_transpose)
4459 FFSWAP(
int,
s->in_width,
s->in_height);
4775 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4776 s->out ==
FLAT &&
s->d_fov == 0.f) {
4778 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4779 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4780 s->out ==
FLAT &&
s->d_fov == 0.f) {
4782 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4783 }
else if (
s->width > 0 &&
s->height > 0) {
4786 }
else if (
s->width > 0 ||
s->height > 0) {
4790 if (
s->out_transpose)
4793 if (
s->in_transpose)
4803 default_h_fov = 90.f;
4804 default_v_fov = 45.f;
4811 default_h_fov = 180.f;
4812 default_v_fov = 180.f;
4818 if (
s->h_fov == 0.f)
4819 s->h_fov = default_h_fov;
4821 if (
s->v_fov == 0.f)
4822 s->v_fov = default_v_fov;
4828 err = prepare_out(
ctx);
4835 switch (
s->out_stereo) {
4837 out_offset_w = out_offset_h = 0;
4856 for (
int i = 0;
i < 4;
i++)
4866 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4867 s->nb_allocated = 1;
4868 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4870 s->nb_allocated = 2;
4871 s->map[0] =
s->map[3] = 0;
4872 s->map[1] =
s->map[2] = 1;
4875 if (!
s->slice_remap)
4876 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4877 if (!
s->slice_remap)
4880 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4881 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4887 s->rot_quaternion,
s->rotation_order);
4922 s->rot_quaternion[0][0] = 1.f;
4923 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4927 char *res,
int res_len,
int flags)
4932 if (
s->reset_rot <= 0)
4933 s->yaw =
s->pitch =
s->roll = 0.f;
4934 if (
s->reset_rot < 0)
4960 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4963 for (
int p = 0; p <
s->nb_allocated; p++) {
5000 .priv_class = &v360_class,
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
#define AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_GBRAP16
#define AV_LOG_WARNING
Something somehow does not look correct.
static const uint8_t q1[256]
AVPixelFormat
Pixel format.
static void process_cube_coordinates(const V360Context *s, float uf, float vf, int direction, float *new_uf, float *new_vf, int *face)
Find position on another cube face in case of overflow/underflow.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static int xyz_to_mercator(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in mercator format for corresponding 3D coordinates on sphere.
static int prepare_stereographic_in(AVFilterContext *ctx)
Prepare data for processing stereographic input format.
static int xyz_to_eac(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in equi-angular cubemap format for corresponding 3D coordinates on sphere.
static const ElemCat * elements[ELEMENT_COUNT]
#define u(width, name, range_min, range_max)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
static void gaussian_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for gaussian interpolation.
static __device__ float floorf(float a)
static const AVFilterPad outputs[]
void ff_v360_init_x86(V360Context *s, int depth)
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
static int prepare_equirect_out(AVFilterContext *ctx)
Prepare data for processing equirectangular output format.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static int xyz_to_stereographic(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in stereographic format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA422P9
static int prepare_orthographic_out(AVFilterContext *ctx)
Prepare data for processing orthographic output format.
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 FILTER_QUERY_FUNC(func)
#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
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
#define AV_PIX_FMT_GBRP10
static void calculate_lanczos_coeffs(float t, float *coeffs)
Calculate 1-dimensional lanczos coefficients.
#define AV_PIX_FMT_YUVA444P16
static void conjugate_quaternion(float d[4], const float q[4])
#define AV_PIX_FMT_YUV422P9
static void lanczos_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for lanczos interpolation.
static const AVFilterPad inputs[]
static int prepare_equisolid_in(AVFilterContext *ctx)
Prepare data for processing equisolid input format.
static int xyz_to_orthographic(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in orthographic format for corresponding 3D coordinates on sphere.
static av_always_inline float scale(float x, float s)
static int equirect_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in equirectangular format.
#define AV_PIX_FMT_GRAY16
#define us(width, name, range_min, range_max, subs,...)
static int xyz_to_cube6x1(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cubemap6x1 format for corresponding 3D coordinates on sphere.
static __device__ float fabsf(float a)
static int ball_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in ball format.
static int xyz_to_hammer(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in hammer format for corresponding 3D coordinates on sphere.
A filter pad used for either input or output.
static void rotate(const float rot_quaternion[2][4], float *vec)
Rotate vector with given rotation quaternion.
#define AV_PIX_FMT_YUV444P10
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
static int reflectx(int x, int y, int w, int h)
Reflect x operation.
static void lagrange_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for lagrange interpolation.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define AV_PIX_FMT_YUV422P16
static int orthographic_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in orthographic format.
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
#define AV_PIX_FMT_GBRAP10
static int tetrahedron_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in tetrahedron format.
static int octahedron_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in octahedron format.
static void calculate_spline16_coeffs(float t, float *coeffs)
Calculate 1-dimensional spline16 coefficients.
static int prepare_equirect_in(AVFilterContext *ctx)
Prepare data for processing equirectangular input format.
#define DEFINE_REMAP(ws, bits)
Generate remapping function with a given window size and pixel depth.
#define AV_PIX_FMT_GBRAP12
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
#define AV_PIX_FMT_YUV444P16
#define AV_CEIL_RSHIFT(a, b)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
static int fisheye_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in fisheye format.
static int reflecty(int y, int h)
Reflect y operation.
static 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 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.
#define FILTER_INPUTS(array)
static const uint8_t q0[256]
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
#define AV_PIX_FMT_GRAY10
static void offset_vector(float *vec, float h_offset, float v_offset)
Offset vector.
void ff_v360_init(V360Context *s, int depth)
#define AV_PIX_FMT_GBRP16
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
static int xyz_to_cube1x6(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cubemap1x6 format for corresponding 3D coordinates on sphere.
static void calculate_gaussian_coeffs(float t, float *coeffs)
Calculate 1-dimensional gaussian coefficients.
static int ereflectx(int x, int y, int w, int h)
Reflect x operation for equirect.
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
static int mercator_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in mercator format.
static int prepare_fisheye_out(AVFilterContext *ctx)
Prepare data for processing fisheye output format.
#define AV_PIX_FMT_YUV440P10
static int prepare_cylindricalea_out(AVFilterContext *ctx)
Prepare data for processing cylindrical equal area output format.
static void rotate_cube_face(float *uf, float *vf, int rotation)
static void calculate_lagrange_coeffs(float t, float *coeffs)
Calculate 1-dimensional lagrange coefficients.
static int cube1x6_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap1x6 format.
static __device__ float sqrtf(float a)
static int barrel_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in barrel facebook's format.
#define AV_PIX_FMT_YUV422P10
static int prepare_cylindrical_out(AVFilterContext *ctx)
Prepare data for processing cylindrical output format.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
static int prepare_cylindrical_in(AVFilterContext *ctx)
Prepare data for processing cylindrical input format.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static int pannini_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in pannini format.
static int xyz_to_ball(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in ball format for corresponding 3D coordinates on sphere.
static int hammer_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in hammer format.
static int prepare_dfisheye_in(AVFilterContext *ctx)
Prepare data for processing double fisheye input format.
static void mirror(const float *modifier, float *vec)
static int cylindrical_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cylindrical format.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void nearest_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Save nearest pixel coordinates for remapping.
#define AV_PIX_FMT_YUV422P12
static void spline16_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for spline16 interpolation.
static av_cold void uninit(AVFilterContext *ctx)
#define AV_PIX_FMT_YUV444P12
AVFilterContext * src
source filter
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
static int eac_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in equi-angular cubemap format.
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
#define AV_PIX_FMT_YUVA444P10
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int prepare_fisheye_in(AVFilterContext *ctx)
Prepare data for processing fisheye input format.
static int query_formats(AVFilterContext *ctx)
static int prepare_equisolid_out(AVFilterContext *ctx)
Prepare data for processing equisolid output format.
static void bicubic_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for bicubic interpolation.
#define i(width, name, range_min, range_max)
static int xyz_to_equirect(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in equirectangular format for corresponding 3D coordinates on sphere.
static int cube3x2_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap3x2 format.
static av_always_inline float rescale(int x, float s)
static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p)
int w
agreed upon image width
#define DEFINE_REMAP_LINE(ws, bits, div)
static int prepare_stereographic_out(AVFilterContext *ctx)
Prepare data for processing stereographic output format.
static int config_output(AVFilterLink *outlink)
#define AV_PIX_FMT_GBRP12
static int cube6x1_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap6x1 format.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
static void xyz_to_cube(const V360Context *s, const float *vec, float *uf, float *vf, int *direction)
Calculate cubemap position for corresponding 3D coordinates on sphere.
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static int xyz_to_fisheye(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in fisheye format for corresponding 3D coordinates on sphere.
static void calculate_cubic_bc_coeffs(float t, float *coeffs, float b, float c)
Calculate 1-dimensional cubic_bc_spline coefficients.
Used for passing data between threads.
static int xyz_to_flat(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in flat format for corresponding 3D coordinates on sphere.
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
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 prepare_flat_out(AVFilterContext *ctx)
Prepare data for processing flat output format.
static int hequirect_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in half equirectangular format.
#define FFSWAP(type, a, b)
static int xyz_to_cylindricalea(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in cylindrical equal area format for corresponding 3D coordinates on sphere.
static int xyz_to_tetrahedron(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in tetrahedron format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUVA444P9
#define DEFINE_REMAP1_LINE(bits, div)
static int xyz_to_equisolid(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in equisolid format for corresponding 3D coordinates on sphere.
#define AV_PIX_FMT_YUV420P12
static int sinusoidal_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in sinusoidal format.
static void normalize_vector(float *vec)
Normalize vector.
#define AV_PIX_FMT_YUV422P14
static int get_rorder(char c)
Convert char to corresponding rotation order.
int h
agreed upon image height
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
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)
#define FILTER_OUTPUTS(array)
static void calculate_rotation(float yaw, float pitch, float roll, float rot_quaternion[2][4], const int rotation_order[3])
Calculate rotation quaternion for yaw/pitch/roll angles.
static int xyz_to_dfisheye(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv)
Calculate frame position in dual fisheye format for corresponding 3D coordinates on sphere.
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
static void cube_to_xyz(const V360Context *s, float uf, float vf, int face, float *vec, float scalew, float scaleh)
Calculate 3D coordinates on sphere for corresponding cubemap position.
static int tspyramid_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in tspyramid format.
#define flags(name, subs,...)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
static void fov_from_dfov(int format, float d_fov, float w, float h, float *h_fov, float *v_fov)
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
static void set_mirror_modifier(int h_flip, int v_flip, int d_flip, float *modifier)
static int prepare_cylindricalea_in(AVFilterContext *ctx)
Prepare data for processing cylindrical equal area input format.
#define AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_GRAY12
static enum AVPixelFormat alpha_pix_fmts[]
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
static int get_direction(char c)
Convert char to corresponding direction.
static int prepare_eac_in(AVFilterContext *ctx)
Prepare data for processing equi-angular cubemap input format.
static void set_dimensions(int *outw, int *outh, int w, int h, const AVPixFmtDescriptor *desc)
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
#define AV_PIX_FMT_YUV420P14
static int flat_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in flat format.
const AVFilter ff_vf_v360
static int prepare_orthographic_in(AVFilterContext *ctx)
Prepare data for processing orthographic input format.