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;
407 int16_t *
u, int16_t *v, int16_t *ker)
410 const int j =
lrintf(du) + 1;
412 u[0] = rmap->
u[
i][j];
413 v[0] = rmap->
v[
i][j];
427 int16_t *
u, int16_t *v, int16_t *ker)
429 for (
int i = 0;
i < 2;
i++) {
430 for (
int j = 0; j < 2; j++) {
431 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
432 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
436 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
437 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
438 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
439 ker[3] =
lrintf( du * dv * 16385.
f);
450 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
451 coeffs[1] = -t * (t - 2.f);
452 coeffs[2] = t * (t - 1.f) * 0.5
f;
466 int16_t *
u, int16_t *v, int16_t *ker)
474 for (
int i = 0;
i < 3;
i++) {
475 for (
int j = 0; j < 3; j++) {
476 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
477 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
478 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
491 const float tt = t * t;
492 const float ttt = t * t * t;
494 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
495 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
496 coeffs[2] = t + tt / 2.f - ttt / 2.f;
497 coeffs[3] = - t / 6.f + ttt / 6.f;
511 int16_t *
u, int16_t *v, int16_t *ker)
519 for (
int i = 0;
i < 4;
i++) {
520 for (
int j = 0; j < 4; j++) {
521 u[
i * 4 + j] = rmap->
u[
i][j];
522 v[
i * 4 + j] = rmap->
v[
i][j];
523 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
538 for (
int i = 0;
i < 4;
i++) {
539 const float x =
M_PI * (t -
i + 1);
543 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
548 for (
int i = 0;
i < 4;
i++) {
564 int16_t *
u, int16_t *v, int16_t *ker)
572 for (
int i = 0;
i < 4;
i++) {
573 for (
int j = 0; j < 4; j++) {
574 u[
i * 4 + j] = rmap->
u[
i][j];
575 v[
i * 4 + j] = rmap->
v[
i][j];
576 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
589 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
590 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
591 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
592 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
606 int16_t *
u, int16_t *v, int16_t *ker)
614 for (
int i = 0;
i < 4;
i++) {
615 for (
int j = 0; j < 4; j++) {
616 u[
i * 4 + j] = rmap->
u[
i][j];
617 v[
i * 4 + j] = rmap->
v[
i][j];
618 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
633 for (
int i = 0;
i < 4;
i++) {
634 const float x = t - (
i - 1);
638 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
643 for (
int i = 0;
i < 4;
i++) {
659 int16_t *
u, int16_t *v, int16_t *ker)
667 for (
int i = 0;
i < 4;
i++) {
668 for (
int j = 0; j < 4; j++) {
669 u[
i * 4 + j] = rmap->
u[
i][j];
670 v[
i * 4 + j] = rmap->
v[
i][j];
671 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
686 float p0 = (6.f - 2.f *
b) / 6.
f,
687 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
688 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
689 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
690 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
691 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
692 q3 = (-
b - 6.f *
c) / 6.
f;
694 for (
int i = 0;
i < 4;
i++) {
695 const float x =
fabsf(t -
i + 1.
f);
697 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
698 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
699 }
else if (x < 2.
f) {
700 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
701 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
708 for (
int i = 0;
i < 4;
i++) {
724 int16_t *
u, int16_t *v, int16_t *ker)
732 for (
int i = 0;
i < 4;
i++) {
733 for (
int j = 0; j < 4; j++) {
734 u[
i * 4 + j] = rmap->
u[
i][j];
735 v[
i * 4 + j] = rmap->
v[
i][j];
736 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
751 const int res =
a %
b;
883 for (
int face = 0; face <
NB_FACES; face++) {
884 const char c =
s->in_forder[face];
889 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
894 if (direction == -1) {
896 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
900 s->in_cubemap_face_order[direction] = face;
903 for (
int face = 0; face <
NB_FACES; face++) {
904 const char c =
s->in_frot[face];
909 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
914 if (rotation == -1) {
916 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
920 s->in_cubemap_face_rotation[face] = rotation;
937 for (
int face = 0; face <
NB_FACES; face++) {
938 const char c =
s->out_forder[face];
943 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
948 if (direction == -1) {
950 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
954 s->out_cubemap_direction_order[face] = direction;
957 for (
int face = 0; face <
NB_FACES; face++) {
958 const char c =
s->out_frot[face];
963 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
968 if (rotation == -1) {
970 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
974 s->out_cubemap_face_rotation[face] = rotation;
1050 const float norm = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1070 float uf,
float vf,
int face,
1071 float *vec,
float scalew,
float scaleh)
1073 const int direction =
s->out_cubemap_direction_order[face];
1074 float l_x, l_y, l_z;
1081 switch (direction) {
1133 float *uf,
float *vf,
int *direction)
1135 const float phi =
atan2f(vec[0], vec[2]);
1136 const float theta = asinf(vec[1]);
1137 float phi_norm, theta_threshold;
1140 if (phi >= -M_PI_4 && phi < M_PI_4) {
1143 }
else if (phi >= -(
M_PI_2 + M_PI_4) && phi < -M_PI_4) {
1146 }
else if (phi >= M_PI_4 && phi <
M_PI_2 + M_PI_4) {
1151 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1154 theta_threshold =
atanf(
cosf(phi_norm));
1155 if (theta > theta_threshold) {
1157 }
else if (theta < -theta_threshold) {
1161 switch (*direction) {
1163 *uf = -vec[2] / vec[0];
1164 *vf = vec[1] / vec[0];
1167 *uf = -vec[2] / vec[0];
1168 *vf = -vec[1] / vec[0];
1171 *uf = -vec[0] / vec[1];
1172 *vf = -vec[2] / vec[1];
1175 *uf = vec[0] / vec[1];
1176 *vf = -vec[2] / vec[1];
1179 *uf = vec[0] / vec[2];
1180 *vf = vec[1] / vec[2];
1183 *uf = vec[0] / vec[2];
1184 *vf = -vec[1] / vec[2];
1190 face =
s->in_cubemap_face_order[*direction];
1207 float uf,
float vf,
int direction,
1208 float *new_uf,
float *new_vf,
int *face)
1227 *face =
s->in_cubemap_face_order[direction];
1230 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1234 }
else if (uf < -1.
f) {
1236 switch (direction) {
1270 }
else if (uf >= 1.
f) {
1272 switch (direction) {
1306 }
else if (vf < -1.
f) {
1308 switch (direction) {
1342 }
else if (vf >= 1.
f) {
1344 switch (direction) {
1384 *face =
s->in_cubemap_face_order[direction];
1390 return (0.5
f * x + 0.5
f) * (
s - 1.f);
1395 return (2.
f * x + 1.
f) /
s - 1.f;
1412 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1413 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1415 const float ew =
width / 3.f;
1416 const float eh =
height / 2.f;
1418 const int u_face =
floorf(
i / ew);
1419 const int v_face =
floorf(j / eh);
1420 const int face = u_face + 3 * v_face;
1422 const int u_shift =
ceilf(ew * u_face);
1423 const int v_shift =
ceilf(eh * v_face);
1424 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1425 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1427 const float uf =
rescale(
i - u_shift, ewi);
1428 const float vf =
rescale(j - v_shift, ehi);
1449 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1451 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1452 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1453 const float ew =
width / 3.f;
1454 const float eh =
height / 2.f;
1458 int direction, face;
1466 face =
s->in_cubemap_face_order[direction];
1469 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1470 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1472 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1473 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1481 for (
int i = 0;
i < 4;
i++) {
1482 for (
int j = 0; j < 4; j++) {
1483 int new_ui =
ui + j - 1;
1484 int new_vi = vi +
i - 1;
1485 int u_shift, v_shift;
1486 int new_ewi, new_ehi;
1488 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1489 face =
s->in_cubemap_face_order[direction];
1493 u_shift =
ceilf(ew * u_face);
1494 v_shift =
ceilf(eh * v_face);
1496 uf = 2.f * new_ui / ewi - 1.f;
1497 vf = 2.f * new_vi / ehi - 1.f;
1509 u_shift =
ceilf(ew * u_face);
1510 v_shift =
ceilf(eh * v_face);
1511 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1512 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1514 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1515 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1518 us[
i][j] = u_shift + new_ui;
1519 vs[
i][j] = v_shift + new_vi;
1540 const float scalew =
s->fout_pad > 0 ? 1.f - (float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1541 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1543 const float ew =
width;
1544 const float eh =
height / 6.f;
1546 const int face =
floorf(j / eh);
1548 const int v_shift =
ceilf(eh * face);
1549 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1552 const float vf =
rescale(j - v_shift, ehi);
1573 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1574 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1576 const float ew =
width / 6.f;
1579 const int face =
floorf(
i / ew);
1581 const int u_shift =
ceilf(ew * face);
1582 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1584 const float uf =
rescale(
i - u_shift, ewi);
1585 const float vf =
rescale(j, eh);
1606 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1608 const float scalew =
s->fin_pad > 0 ? 1.f - (float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1609 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1610 const float eh =
height / 6.f;
1611 const int ewi =
width;
1615 int direction, face;
1622 face =
s->in_cubemap_face_order[direction];
1623 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1625 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1626 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1634 for (
int i = 0;
i < 4;
i++) {
1635 for (
int j = 0; j < 4; j++) {
1636 int new_ui =
ui + j - 1;
1637 int new_vi = vi +
i - 1;
1641 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1642 face =
s->in_cubemap_face_order[direction];
1644 v_shift =
ceilf(eh * face);
1646 uf = 2.f * new_ui / ewi - 1.f;
1647 vf = 2.f * new_vi / ehi - 1.f;
1657 v_shift =
ceilf(eh * face);
1658 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1661 new_vi =
av_clip(
lrintf(0.5
f * new_ehi * (vf + 1.
f)), 0, new_ehi - 1);
1665 vs[
i][j] = v_shift + new_vi;
1686 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1688 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1689 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1690 const float ew =
width / 6.f;
1695 int direction, face;
1702 face =
s->in_cubemap_face_order[direction];
1703 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1705 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1706 vf = 0.5f * ehi * (vf + 1.f) - 0.5
f;
1714 for (
int i = 0;
i < 4;
i++) {
1715 for (
int j = 0; j < 4; j++) {
1716 int new_ui =
ui + j - 1;
1717 int new_vi = vi +
i - 1;
1721 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1722 face =
s->in_cubemap_face_order[direction];
1724 u_shift =
ceilf(ew * face);
1726 uf = 2.f * new_ui / ewi - 1.f;
1727 vf = 2.f * new_vi / ehi - 1.f;
1737 u_shift =
ceilf(ew * face);
1738 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1740 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1744 us[
i][j] = u_shift + new_ui;
1763 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
1764 s->flat_range[1] =
s->v_fov *
M_PI / 360.f;
1786 const float sin_phi =
sinf(phi);
1787 const float cos_phi =
cosf(phi);
1788 const float sin_theta =
sinf(theta);
1789 const float cos_theta =
cosf(theta);
1791 vec[0] = cos_theta * sin_phi;
1793 vec[2] = cos_theta * cos_phi;
1815 const float sin_phi =
sinf(phi);
1816 const float cos_phi =
cosf(phi);
1817 const float sin_theta =
sinf(theta);
1818 const float cos_theta =
cosf(theta);
1820 vec[0] = cos_theta * sin_phi;
1822 vec[2] = cos_theta * cos_phi;
1838 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1839 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1860 const float r = hypotf(x, y);
1861 const float theta =
atanf(
r) * 2.f;
1862 const float sin_theta =
sinf(theta);
1864 vec[0] = x /
r * sin_theta;
1865 vec[1] = y /
r * sin_theta;
1866 vec[2] =
cosf(theta);
1882 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1883 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1902 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1904 const float theta = acosf(vec[2]);
1905 const float r = tanf(theta * 0.5
f);
1906 const float c =
r / hypotf(vec[0], vec[1]);
1907 const float x = vec[0] *
c /
s->iflat_range[0];
1908 const float y = vec[1] *
c /
s->iflat_range[1];
1914 const int vi =
floorf(vf);
1918 *du = visible ? uf -
ui : 0.f;
1919 *dv = visible ? vf - vi : 0.f;
1921 for (
int i = 0;
i < 4;
i++) {
1922 for (
int j = 0; j < 4; j++) {
1942 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1943 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1964 const float r = hypotf(x, y);
1965 const float theta = asinf(
r) * 2.f;
1966 const float sin_theta =
sinf(theta);
1968 vec[0] = x /
r * sin_theta;
1969 vec[1] = y /
r * sin_theta;
1970 vec[2] =
cosf(theta);
2006 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2008 const float theta = acosf(vec[2]);
2009 const float r =
sinf(theta * 0.5
f);
2010 const float c =
r / hypotf(vec[0], vec[1]);
2011 const float x = vec[0] *
c /
s->iflat_range[0];
2012 const float y = vec[1] *
c /
s->iflat_range[1];
2018 const int vi =
floorf(vf);
2022 *du = visible ? uf -
ui : 0.f;
2023 *dv = visible ? vf - vi : 0.f;
2025 for (
int i = 0;
i < 4;
i++) {
2026 for (
int j = 0; j < 4; j++) {
2068 const float r = hypotf(x, y);
2069 const float theta = asinf(
r);
2071 vec[2] =
cosf(theta);
2117 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2119 const float theta = acosf(vec[2]);
2120 const float r =
sinf(theta);
2121 const float c =
r / hypotf(vec[0], vec[1]);
2122 const float x = vec[0] *
c /
s->iflat_range[0];
2123 const float y = vec[1] *
c /
s->iflat_range[1];
2129 const int vi =
floorf(vf);
2131 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2133 *du = visible ? uf -
ui : 0.f;
2134 *dv = visible ? vf - vi : 0.f;
2136 for (
int i = 0;
i < 4;
i++) {
2137 for (
int j = 0; j < 4; j++) {
2157 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2158 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2177 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2179 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2180 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2186 const int vi =
floorf(vf);
2192 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2194 for (
int i = 0;
i < 4;
i++) {
2195 for (
int j = 0; j < 4; j++) {
2218 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2221 const float theta = asinf(vec[1]) /
M_PI_2;
2227 const int vi =
floorf(vf);
2234 for (
int i = 0;
i < 4;
i++) {
2235 for (
int j = 0; j < 4; j++) {
2255 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2256 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2275 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2277 const float theta = acosf(vec[2]);
2278 const float r = tanf(theta);
2280 const float zf = vec[2];
2281 const float h = hypotf(vec[0], vec[1]);
2282 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2283 float uf = vec[0] *
c /
s->iflat_range[0];
2284 float vf = vec[1] *
c /
s->iflat_range[1];
2285 int visible,
ui, vi;
2293 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2298 for (
int i = 0;
i < 4;
i++) {
2299 for (
int j = 0; j < 4; j++) {
2322 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2324 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2325 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2331 const int vi =
floorf(vf);
2336 for (
int i = 0;
i < 4;
i++) {
2337 for (
int j = 0; j < 4; j++) {
2362 const float div =
expf(2.
f * y) + 1.f;
2364 const float sin_phi =
sinf(phi);
2365 const float cos_phi =
cosf(phi);
2366 const float sin_theta = 2.f *
expf(y) / div;
2367 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2369 vec[0] = -sin_theta * cos_phi;
2371 vec[2] = sin_theta * sin_phi;
2390 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2392 const float l = hypotf(vec[0], vec[1]);
2393 const float r = sqrtf(1.
f - vec[2]) /
M_SQRT2;
2394 const float d = l > 0.f ? l : 1.f;
2400 const int vi =
floorf(vf);
2405 for (
int i = 0;
i < 4;
i++) {
2406 for (
int j = 0; j < 4; j++) {
2431 const float l = hypotf(x, y);
2434 const float z = 2.f * l * sqrtf(1.
f - l * l);
2436 vec[0] = z * x / (l > 0.f ? l : 1.f);
2437 vec[1] = z * y / (l > 0.f ? l : 1.f);
2438 vec[2] = 1.f - 2.f * l * l;
2466 const float xx = x * x;
2467 const float yy = y * y;
2469 const float z = sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2472 const float b = 2.f * z * z - 1.f;
2474 const float aa =
a *
a;
2475 const float bb =
b *
b;
2477 const float w = sqrtf(1.
f - 2.
f * yy * z * z);
2479 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2481 vec[2] =
w * (bb - aa) / (aa + bb);
2500 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2502 const float theta =
atan2f(vec[0], vec[2]);
2504 const float z = sqrtf(1.
f + sqrtf(1.
f - vec[1] * vec[1]) *
cosf(theta * 0.5
f));
2505 const float x = sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2506 const float y = vec[1] / z;
2508 const float uf = (x + 1.f) *
width / 2.
f;
2509 const float vf = (y + 1.f) *
height / 2.
f;
2512 const int vi =
floorf(vf);
2517 for (
int i = 0;
i < 4;
i++) {
2518 for (
int j = 0; j < 4; j++) {
2544 const float sin_phi =
sinf(phi);
2545 const float cos_phi =
cosf(phi);
2546 const float sin_theta =
sinf(theta);
2547 const float cos_theta =
cosf(theta);
2549 vec[0] = cos_theta * sin_phi;
2551 vec[2] = cos_theta * cos_phi;
2570 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2572 const float theta = asinf(vec[1]);
2573 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2579 const int vi =
floorf(vf);
2584 for (
int i = 0;
i < 4;
i++) {
2585 for (
int j = 0; j < 4; j++) {
2664 const float pixel_pad = 2;
2665 const float u_pad = pixel_pad /
width;
2666 const float v_pad = pixel_pad /
height;
2668 int u_face, v_face, face;
2670 float l_x, l_y, l_z;
2672 float uf = (
i + 0.5f) /
width;
2673 float vf = (j + 0.5f) /
height;
2680 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2684 }
else if (uf >= 3.
f) {
2689 uf = fmodf(uf, 1.
f) - 0.5f;
2694 vf = (vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2696 if (uf >= -0.5
f && uf < 0.5
f) {
2701 if (vf >= -0.5
f && vf < 0.5
f) {
2707 face = u_face + 3 * v_face;
2765 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2767 const float pixel_pad = 2;
2768 const float u_pad = pixel_pad /
width;
2769 const float v_pad = pixel_pad /
height;
2773 int direction, face;
2778 face =
s->in_cubemap_face_order[direction];
2782 uf = M_2_PI *
atanf(uf) + 0.5f;
2783 vf = M_2_PI *
atanf(vf) + 0.5f;
2786 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2787 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2801 for (
int i = 0;
i < 4;
i++) {
2802 for (
int j = 0; j < 4; j++) {
2822 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2823 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2863 s->flat_range[0] =
s->h_fov / 180.f;
2864 s->flat_range[1] =
s->v_fov / 180.f;
2886 const float phi =
atan2f(vf, uf);
2887 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2889 const float sin_phi =
sinf(phi);
2890 const float cos_phi =
cosf(phi);
2891 const float sin_theta =
sinf(theta);
2892 const float cos_theta =
cosf(theta);
2894 vec[0] = cos_theta * cos_phi;
2895 vec[1] = cos_theta * sin_phi;
2912 s->iflat_range[0] =
s->ih_fov / 180.f;
2913 s->iflat_range[1] =
s->iv_fov / 180.f;
2932 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2934 const float h = hypotf(vec[0], vec[1]);
2935 const float lh =
h > 0.f ?
h : 1.f;
2938 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2939 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2941 const int visible = -0.5f < uf && uf < 0.5f && -0.5f < vf && vf < 0.5f;
2944 uf = (uf + 0.5f) *
width;
2945 vf = (vf + 0.5f) *
height;
2950 *du = visible ? uf -
ui : 0.f;
2951 *dv = visible ? vf - vi : 0.f;
2953 for (
int i = 0;
i < 4;
i++) {
2954 for (
int j = 0; j < 4; j++) {
2980 const float d =
s->h_fov;
2981 const float k = uf * uf / ((
d + 1.f) * (
d + 1.
f));
2982 const float dscr = k * k *
d *
d - (k + 1.f) * (k *
d *
d - 1.
f);
2983 const float clon = (-k *
d + sqrtf(dscr)) / (k + 1.
f);
2984 const float S = (
d + 1.f) / (
d + clon);
2985 const float lon =
atan2f(uf,
S * clon);
2986 const float lat =
atan2f(vf,
S);
3009 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3011 const float phi =
atan2f(vec[0], vec[2]);
3012 const float theta = asinf(vec[1]);
3014 const float d =
s->ih_fov;
3015 const float S = (
d + 1.f) / (
d +
cosf(phi));
3017 const float x =
S *
sinf(phi);
3018 const float y =
S * tanf(theta);
3024 const int vi =
floorf(vf);
3026 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3031 for (
int i = 0;
i < 4;
i++) {
3032 for (
int j = 0; j < 4; j++) {
3052 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3053 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3075 const float phi = uf;
3076 const float theta =
atanf(vf);
3078 const float sin_phi =
sinf(phi);
3079 const float cos_phi =
cosf(phi);
3080 const float sin_theta =
sinf(theta);
3081 const float cos_theta =
cosf(theta);
3083 vec[0] = cos_theta * sin_phi;
3085 vec[2] = cos_theta * cos_phi;
3101 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3102 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3121 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3123 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3124 const float theta = asinf(vec[1]);
3127 const float vf =
scale(tanf(theta) /
s->iflat_range[1],
height);
3130 const int vi =
floorf(vf);
3132 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3133 theta <=
M_PI *
s->iv_fov / 180.f &&
3134 theta >= -
M_PI *
s->iv_fov / 180.f;
3139 for (
int i = 0;
i < 4;
i++) {
3140 for (
int j = 0; j < 4; j++) {
3160 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3161 s->flat_range[1] =
s->v_fov / 180.f;
3177 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3178 s->iflat_range[1] =
s->iv_fov / 180.f;
3200 const float phi = uf;
3201 const float theta = asinf(vf);
3203 const float sin_phi =
sinf(phi);
3204 const float cos_phi =
cosf(phi);
3205 const float sin_theta =
sinf(theta);
3206 const float cos_theta =
cosf(theta);
3208 vec[0] = cos_theta * sin_phi;
3210 vec[2] = cos_theta * cos_phi;
3229 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3231 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3232 const float theta = asinf(vec[1]);
3238 const int vi =
floorf(vf);
3240 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3241 theta <=
M_PI *
s->iv_fov / 180.f &&
3242 theta >= -
M_PI *
s->iv_fov / 180.f;
3247 for (
int i = 0;
i < 4;
i++) {
3248 for (
int j = 0; j < 4; j++) {
3273 const float rh = hypotf(uf, vf);
3274 const float sinzz = 1.f - rh * rh;
3275 const float h = 1.f +
s->v_fov;
3276 const float sinz = (
h - sqrtf(sinzz)) / (
h / rh + rh /
h);
3277 const float sinz2 = sinz * sinz;
3280 const float cosz = sqrtf(1.
f - sinz2);
3282 const float theta = asinf(cosz);
3283 const float phi =
atan2f(uf, vf);
3285 const float sin_phi =
sinf(phi);
3286 const float cos_phi =
cosf(phi);
3287 const float sin_theta =
sinf(theta);
3288 const float cos_theta =
cosf(theta);
3290 vec[0] = cos_theta * sin_phi;
3291 vec[1] = cos_theta * cos_phi;
3317 const float uf = ((float)
i + 0.5
f) /
width;
3318 const float vf = ((float)j + 0.5
f) /
height;
3320 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3321 vec[1] = 1.f - vf * 2.f;
3322 vec[2] = 2.f *
fabsf(1.
f -
fabsf(1.
f - uf * 2.
f + vf)) - 1.f;
3341 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3343 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3344 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3345 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3346 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3349 float uf, vf, x, y, z;
3356 vf = 0.5f - y * 0.5f;
3358 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3359 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3360 uf = 0.25f * x + 0.25f;
3362 uf = 0.75f - 0.25f * x;
3374 for (
int i = 0;
i < 4;
i++) {
3375 for (
int j = 0; j < 4; j++) {
3395 s->iflat_range[0] =
s->ih_fov / 360.f;
3396 s->iflat_range[1] =
s->iv_fov / 360.f;
3415 const float ew =
width * 0.5f;
3418 const int ei =
i >= ew ?
i - ew :
i;
3419 const float m =
i >= ew ? 1.f : -1.f;
3421 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3422 const float vf =
s->flat_range[1] *
rescale(j, eh);
3424 const float h = hypotf(uf, vf);
3425 const float lh =
h > 0.f ?
h : 1.f;
3426 const float theta = m *
M_PI_2 * (1.f -
h);
3428 const float sin_theta =
sinf(theta);
3429 const float cos_theta =
cosf(theta);
3431 vec[0] = cos_theta * m * uf / lh;
3432 vec[1] = cos_theta * vf / lh;
3452 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3454 const float ew = (
width - 1) * 0.5
f;
3457 const float h = hypotf(vec[0], vec[1]);
3458 const float lh =
h > 0.f ?
h : 1.f;
3459 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3461 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3462 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3467 if (vec[2] >= 0.
f) {
3468 u_shift =
ceilf(ew);
3480 for (
int i = 0;
i < 4;
i++) {
3481 for (
int j = 0; j < 4; j++) {
3504 const float scale = 0.99f;
3505 float l_x, l_y, l_z;
3508 const float theta_range = M_PI_4;
3510 const int ew = 4 *
width / 5;
3514 const float theta =
rescale(j, eh) * theta_range /
scale;
3516 const float sin_phi =
sinf(phi);
3517 const float cos_phi =
cosf(phi);
3518 const float sin_theta =
sinf(theta);
3519 const float cos_theta =
cosf(theta);
3521 l_x = cos_theta * sin_phi;
3523 l_z = cos_theta * cos_phi;
3525 const int ew =
width / 5;
3526 const int eh =
height / 2;
3574 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3576 const float scale = 0.99f;
3578 const float phi =
atan2f(vec[0], vec[2]);
3579 const float theta = asinf(vec[1]);
3580 const float theta_range = M_PI_4;
3583 int u_shift, v_shift;
3587 if (theta > -theta_range && theta < theta_range) {
3595 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3603 uf = -vec[0] / vec[1];
3604 vf = -vec[2] / vec[1];
3607 uf = vec[0] / vec[1];
3608 vf = -vec[2] / vec[1];
3612 uf = 0.5f * ew * (uf *
scale + 1.f);
3613 vf = 0.5f * eh * (vf *
scale + 1.f);
3622 for (
int i = 0;
i < 4;
i++) {
3623 for (
int j = 0; j < 4; j++) {
3625 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3646 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3648 const float phi =
atan2f(vec[0], vec[2]);
3649 const float theta = asinf(vec[1]);
3651 const float theta_range = M_PI_4;
3654 int u_shift, v_shift;
3658 if (theta >= -theta_range && theta <= theta_range) {
3659 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3660 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3669 vf = theta / M_PI_4;
3672 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3674 uf = (uf * scalew + 1.f) *
width / 3.
f;
3675 vf = (vf * scaleh + 1.f) *
height / 4.
f;
3677 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3678 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3686 if (theta <= 0.f && theta >= -
M_PI_2 &&
3687 phi <= M_PI_2 && phi >= -
M_PI_2) {
3688 uf = -vec[0] / vec[1];
3689 vf = -vec[2] / vec[1];
3692 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3693 phi <= M_PI_2 && phi >= -
M_PI_2) {
3694 uf = vec[0] / vec[1];
3695 vf = -vec[2] / vec[1];
3696 v_shift =
height * 0.25f;
3697 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3698 uf = vec[0] / vec[1];
3699 vf = vec[2] / vec[1];
3703 uf = -vec[0] / vec[1];
3704 vf = vec[2] / vec[1];
3705 v_shift =
height * 0.75f;
3708 uf = 0.5f *
width / 3.f * (uf * scalew + 1.f);
3709 vf =
height * 0.25f * (vf * scaleh + 1.f) + v_offset;
3718 for (
int i = 0;
i < 4;
i++) {
3719 for (
int j = 0; j < 4; j++) {
3721 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3742 const float x = (
i + 0.5f) /
width;
3743 const float y = (j + 0.5f) /
height;
3744 float l_x, l_y, l_z;
3746 if (x < 2.
f / 3.
f) {
3747 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3748 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3750 const float back =
floorf(y * 2.
f);
3752 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3753 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3755 const float sin_phi =
sinf(phi);
3756 const float cos_phi =
cosf(phi);
3757 const float sin_theta =
sinf(theta);
3758 const float cos_theta =
cosf(theta);
3760 l_x = cos_theta * sin_phi;
3762 l_z = cos_theta * cos_phi;
3764 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3765 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3767 const int face =
floorf(y * 4.
f);
3778 l_x = (0.5f - uf) / scalew;
3780 l_z = (0.5f - vf) / scaleh;
3785 vf = 1.f - (vf - 0.5f);
3787 l_x = (0.5f - uf) / scalew;
3789 l_z = (-0.5f + vf) / scaleh;
3792 vf = y * 2.f - 0.5f;
3793 vf = 1.f - (1.f - vf);
3795 l_x = (0.5f - uf) / scalew;
3797 l_z = (0.5f - vf) / scaleh;
3800 vf = y * 2.f - 1.5f;
3802 l_x = (0.5f - uf) / scalew;
3804 l_z = (-0.5f + vf) / scaleh;
3830 const float x = (
i + 0.5f) /
width;
3831 const float y = (j + 0.5f) /
height;
3834 vec[0] = x * 4.f - 1.f;
3835 vec[1] = (y * 2.f - 1.f);
3837 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3838 y >= 0.375
f && y < 0.625
f) {
3839 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3840 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3842 }
else if (0.5
f <= x && x < 0.6875
f &&
3843 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3844 (0.375
f <= y && y < 0.625
f) ||
3845 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3847 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3848 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3849 }
else if (0.8125
f <= x && x < 1.
f &&
3850 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3851 (0.375
f <= y && y < 0.625
f) ||
3852 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3854 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3855 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3856 }
else if (0.
f <= y && y < 0.375
f &&
3857 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3858 (0.6875
f <= x && x < 0.8125
f) ||
3859 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3860 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3862 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3864 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3866 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3886 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3894 uf = (uf + 1.f) * 0.5
f;
3895 vf = (vf + 1.f) * 0.5
f;
3899 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3900 vf = 0.375f - 0.375f * vf;
3906 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3907 vf = 1.f - 0.375f * vf;
3910 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3911 uf = 0.1875f * uf + 0.8125f;
3914 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3915 uf = 0.1875f * uf + 0.5f;
3918 uf = 0.125f * uf + 0.6875f;
3919 vf = 0.25f * vf + 0.375f;
3932 for (
int i = 0;
i < 4;
i++) {
3933 for (
int j = 0; j < 4; j++) {
3958 const float ax =
fabsf(x);
3959 const float ay =
fabsf(y);
3961 vec[2] = 1.f - (ax + ay);
3962 if (ax + ay > 1.
f) {
3963 vec[0] = (1.f - ay) *
FFSIGN(x);
3964 vec[1] = (1.f - ax) *
FFSIGN(y);
3987 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4012 for (
int i = 0;
i < 4;
i++) {
4013 for (
int j = 0; j < 4; j++) {
4024 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4025 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4026 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4027 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4042 float rot_quaternion[2][4],
4043 const int rotation_order[3])
4045 const float yaw_rad = yaw *
M_PI / 180.f;
4046 const float pitch_rad = pitch *
M_PI / 180.f;
4047 const float roll_rad = roll *
M_PI / 180.f;
4049 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4050 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4051 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4052 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4053 const float sin_roll =
sinf(roll_rad * 0.5
f);
4054 const float cos_roll =
cosf(roll_rad * 0.5
f);
4059 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4060 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4061 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4076 static inline void rotate(
const float rot_quaternion[2][4],
4079 float qv[4],
temp[4], rqv[4];
4097 modifier[0] = h_flip ? -1.f : 1.f;
4098 modifier[1] = v_flip ? -1.f : 1.f;
4099 modifier[2] = d_flip ? -1.f : 1.f;
4102 static inline void mirror(
const float *modifier,
float *vec)
4104 vec[0] *= modifier[0];
4105 vec[1] *= modifier[1];
4106 vec[2] *= modifier[2];
4109 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4112 for (
int i = 0;
i < 4;
i++) {
4113 for (
int j = 0; j < 4; j++)
4114 u[
i][j] =
w - 1 -
u[
i][j];
4119 for (
int i = 0;
i < 4;
i++) {
4120 for (
int j = 0; j < 4; j++)
4121 v[
i][j] =
h - 1 - v[
i][j];
4128 const int pr_height =
s->pr_height[p];
4130 for (
int n = 0; n <
s->nb_threads; n++) {
4132 const int slice_start = (pr_height * n ) /
s->nb_threads;
4133 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4140 if (!
r->u[p] || !
r->v[p])
4149 if (sizeof_mask && !p) {
4165 *v_fov = d_fov * 0.5f;
4169 const float d = 0.5f * hypotf(
w,
h);
4170 const float l =
sinf(d_fov *
M_PI / 360.
f) /
d;
4172 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4173 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4175 if (d_fov > 180.
f) {
4176 *h_fov = 180.f - *h_fov;
4177 *v_fov = 180.f - *v_fov;
4183 const float d = 0.5f * hypotf(
w,
h);
4184 const float l =
d / (
sinf(d_fov *
M_PI / 720.
f));
4186 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4187 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4192 const float d = 0.5f * hypotf(
w,
h);
4193 const float l =
d / (tanf(d_fov *
M_PI / 720.
f));
4201 const float d = hypotf(
w * 0.5
f,
h);
4203 *h_fov = 0.5f *
w /
d * d_fov;
4204 *v_fov =
h /
d * d_fov;
4209 const float d = hypotf(
w,
h);
4211 *h_fov =
w /
d * d_fov;
4212 *v_fov =
h /
d * d_fov;
4218 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4219 const float d = hypotf(
w,
h);
4236 outw[0] = outw[3] =
w;
4238 outh[0] = outh[3] =
h;
4247 for (
int p = 0; p <
s->nb_allocated; p++) {
4248 const int max_value =
s->max_value;
4249 const int width =
s->pr_width[p];
4250 const int uv_linesize =
s->uv_linesize[p];
4251 const int height =
s->pr_height[p];
4252 const int in_width =
s->inplanewidth[p];
4253 const int in_height =
s->inplaneheight[p];
4254 const int slice_start = (
height * jobnr ) / nb_jobs;
4261 for (
int j = slice_start; j <
slice_end; j++) {
4263 int16_t *
u =
r->u[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4264 int16_t *v =
r->v[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4265 int16_t *ker =
r->ker[p] + ((j - slice_start) * uv_linesize +
i) *
elements;
4266 uint8_t *mask8 = p ?
NULL :
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4267 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4268 int in_mask, out_mask;
4270 if (
s->out_transpose)
4277 rotate(
s->rot_quaternion, vec);
4280 mirror(
s->output_mirror_modifier, vec);
4281 if (
s->in_transpose)
4282 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4284 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4285 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4287 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4289 if (!p &&
r->mask) {
4290 if (
s->mask_size == 1) {
4291 mask8[0] = 255 * (out_mask & in_mask);
4293 mask16[0] = max_value * (out_mask & in_mask);
4309 const int depth =
desc->comp[0].depth;
4310 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4311 float default_h_fov = 360.f;
4312 float default_v_fov = 180.f;
4313 float default_ih_fov = 360.f;
4314 float default_iv_fov = 180.f;
4319 int in_offset_h, in_offset_w;
4320 int out_offset_h, out_offset_w;
4325 s->max_value = (1 << depth) - 1;
4327 switch (
s->interp) {
4330 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4332 sizeof_uv =
sizeof(int16_t) *
s->elements;
4337 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4338 s->elements = 2 * 2;
4339 sizeof_uv =
sizeof(int16_t) *
s->elements;
4340 sizeof_ker =
sizeof(int16_t) *
s->elements;
4344 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4345 s->elements = 3 * 3;
4346 sizeof_uv =
sizeof(int16_t) *
s->elements;
4347 sizeof_ker =
sizeof(int16_t) *
s->elements;
4351 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4352 s->elements = 4 * 4;
4353 sizeof_uv =
sizeof(int16_t) *
s->elements;
4354 sizeof_ker =
sizeof(int16_t) *
s->elements;
4358 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4359 s->elements = 4 * 4;
4360 sizeof_uv =
sizeof(int16_t) *
s->elements;
4361 sizeof_ker =
sizeof(int16_t) *
s->elements;
4365 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4366 s->elements = 4 * 4;
4367 sizeof_uv =
sizeof(int16_t) *
s->elements;
4368 sizeof_ker =
sizeof(int16_t) *
s->elements;
4372 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4373 s->elements = 4 * 4;
4374 sizeof_uv =
sizeof(int16_t) *
s->elements;
4375 sizeof_ker =
sizeof(int16_t) *
s->elements;
4379 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4380 s->elements = 4 * 4;
4381 sizeof_uv =
sizeof(int16_t) *
s->elements;
4382 sizeof_ker =
sizeof(int16_t) *
s->elements;
4390 for (
int order = 0; order <
NB_RORDERS; order++) {
4391 const char c =
s->rorder[order];
4396 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4397 s->rotation_order[0] =
YAW;
4398 s->rotation_order[1] =
PITCH;
4399 s->rotation_order[2] =
ROLL;
4406 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4407 s->rotation_order[0] =
YAW;
4408 s->rotation_order[1] =
PITCH;
4409 s->rotation_order[2] =
ROLL;
4413 s->rotation_order[order] = rorder;
4416 switch (
s->in_stereo) {
4420 in_offset_w = in_offset_h = 0;
4441 s->in_width =
s->inplanewidth[0];
4442 s->in_height =
s->inplaneheight[0];
4447 default_ih_fov = 90.f;
4448 default_iv_fov = 45.f;
4455 default_ih_fov = 180.f;
4456 default_iv_fov = 180.f;
4461 if (
s->ih_fov == 0.f)
4462 s->ih_fov = default_ih_fov;
4464 if (
s->iv_fov == 0.f)
4465 s->iv_fov = default_iv_fov;
4467 if (
s->id_fov > 0.f)
4470 if (
s->in_transpose)
4471 FFSWAP(
int,
s->in_width,
s->in_height);
4787 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4788 s->out ==
FLAT &&
s->d_fov == 0.f) {
4790 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4791 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4792 s->out ==
FLAT &&
s->d_fov == 0.f) {
4794 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4795 }
else if (
s->width > 0 &&
s->height > 0) {
4798 }
else if (
s->width > 0 ||
s->height > 0) {
4802 if (
s->out_transpose)
4805 if (
s->in_transpose)
4815 default_h_fov = 90.f;
4816 default_v_fov = 45.f;
4823 default_h_fov = 180.f;
4824 default_v_fov = 180.f;
4830 if (
s->h_fov == 0.f)
4831 s->h_fov = default_h_fov;
4833 if (
s->v_fov == 0.f)
4834 s->v_fov = default_v_fov;
4840 err = prepare_out(
ctx);
4847 switch (
s->out_stereo) {
4849 out_offset_w = out_offset_h = 0;
4868 for (
int i = 0;
i < 4;
i++)
4878 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4879 s->nb_allocated = 1;
4880 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4882 s->nb_allocated = 2;
4883 s->map[0] =
s->map[3] = 0;
4884 s->map[1] =
s->map[2] = 1;
4887 if (!
s->slice_remap)
4888 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4889 if (!
s->slice_remap)
4892 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4893 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4899 s->rot_quaternion,
s->rotation_order);
4934 s->rot_quaternion[0][0] = 1.f;
4935 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4939 char *res,
int res_len,
int flags)
4944 if (
s->reset_rot <= 0)
4945 s->yaw =
s->pitch =
s->roll = 0.f;
4946 if (
s->reset_rot < 0)
4972 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4975 for (
int p = 0; p <
s->nb_allocated; p++) {
5012 .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 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)
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 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 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)
#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.