54 #define OFFSET(x) offsetof(V360Context, x)
55 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
56 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
255 #define DEFINE_REMAP1_LINE(bits, div) \
256 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
257 ptrdiff_t in_linesize, \
258 const int16_t *const u, const int16_t *const v, \
259 const int16_t *const ker) \
261 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
262 uint##bits##_t *d = (uint##bits##_t *)dst; \
264 in_linesize /= div; \
266 for (int x = 0; x < width; x++) \
267 d[x] = s[v[x] * in_linesize + u[x]]; \
279 #define DEFINE_REMAP(ws, bits) \
280 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
282 ThreadData *td = arg; \
283 const V360Context *s = ctx->priv; \
284 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
285 const AVFrame *in = td->in; \
286 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 = ff_slice_pos(height, jobnr, nb_jobs); \
307 const int slice_end = ff_slice_pos(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) * (int64_t)uv_linesize * ws * ws; \
311 const int16_t *const v = r->v[map] + (y - slice_start) * (int64_t)uv_linesize * ws * ws; \
312 const int16_t *const ker = r->ker[map] + (y - slice_start) * (int64_t)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.5f;
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.2f) * t + 1.f;
591 coeffs[2] = ((6.f / 5.f - t) * t + 0.8f) * 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;
1039 const float norm = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1059 float uf,
float vf,
int face,
1060 float *vec,
float scalew,
float scaleh)
1062 const int direction =
s->out_cubemap_direction_order[face];
1063 float l_x, l_y, l_z;
1070 switch (direction) {
1124 float *uf,
float *vf,
int *direction)
1126 const float phi =
atan2f(vec[0], vec[2]);
1127 const float theta = asinf(vec[1]);
1128 float phi_norm, theta_threshold;
1131 if (phi >= -M_PI_4 && phi < M_PI_4) {
1134 }
else if (phi >= -(
M_PI_2 + M_PI_4) && phi < -M_PI_4) {
1137 }
else if (phi >= M_PI_4 && phi <
M_PI_2 + M_PI_4) {
1142 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1145 theta_threshold =
atanf(
cosf(phi_norm));
1146 if (theta > theta_threshold) {
1148 }
else if (theta < -theta_threshold) {
1152 switch (*direction) {
1154 *uf = -vec[2] / vec[0];
1155 *vf = vec[1] / vec[0];
1158 *uf = -vec[2] / vec[0];
1159 *vf = -vec[1] / vec[0];
1162 *uf = -vec[0] / vec[1];
1163 *vf = -vec[2] / vec[1];
1166 *uf = vec[0] / vec[1];
1167 *vf = -vec[2] / vec[1];
1170 *uf = vec[0] / vec[2];
1171 *vf = vec[1] / vec[2];
1174 *uf = vec[0] / vec[2];
1175 *vf = -vec[1] / vec[2];
1181 face =
s->in_cubemap_face_order[*direction];
1198 float uf,
float vf,
int direction,
1199 float *new_uf,
float *new_vf,
int *face)
1218 *face =
s->in_cubemap_face_order[direction];
1221 if ((uf < -1.f || uf >= 1.f) && (vf < -1.f || vf >= 1.f)) {
1225 }
else if (uf < -1.f) {
1227 switch (direction) {
1261 }
else if (uf >= 1.f) {
1263 switch (direction) {
1297 }
else if (vf < -1.f) {
1299 switch (direction) {
1333 }
else if (vf >= 1.f) {
1335 switch (direction) {
1375 *face =
s->in_cubemap_face_order[direction];
1393 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.f -
s->out_pad;
1394 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1396 const float ew =
width / 3.f;
1397 const float eh =
height / 2.f;
1399 const int u_face =
floorf(
i / ew);
1400 const int v_face =
floorf(j / eh);
1401 const int face = u_face + 3 * v_face;
1403 const int u_shift =
ceilf(ew * u_face);
1404 const int v_shift =
ceilf(eh * v_face);
1405 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1406 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1408 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.f;
1409 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.f;
1430 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1432 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.f -
s->in_pad;
1433 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1434 const float ew =
width / 3.f;
1435 const float eh =
height / 2.f;
1439 int direction, face;
1447 face =
s->in_cubemap_face_order[direction];
1450 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1451 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1453 uf = 0.5f * ewi * (uf + 1.f) - 0.5f;
1454 vf = 0.5f * ehi * (vf + 1.f) - 0.5f;
1462 for (
int i = 0;
i < 4;
i++) {
1463 for (
int j = 0; j < 4; j++) {
1464 int new_ui =
ui + j - 1;
1465 int new_vi = vi +
i - 1;
1466 int u_shift, v_shift;
1467 int new_ewi, new_ehi;
1469 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1470 face =
s->in_cubemap_face_order[direction];
1474 u_shift =
ceilf(ew * u_face);
1475 v_shift =
ceilf(eh * v_face);
1477 uf = 2.f * new_ui / ewi - 1.f;
1478 vf = 2.f * new_vi / ehi - 1.f;
1490 u_shift =
ceilf(ew * u_face);
1491 v_shift =
ceilf(eh * v_face);
1492 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1493 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1495 new_ui =
av_clip(
lrintf(0.5f * new_ewi * (uf + 1.f)), 0, new_ewi - 1);
1496 new_vi =
av_clip(
lrintf(0.5f * new_ehi * (vf + 1.f)), 0, new_ehi - 1);
1499 us[
i][j] = u_shift + new_ui;
1500 vs[
i][j] = v_shift + new_vi;
1521 const float scalew =
s->fout_pad > 0 ? 1.f - (float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1522 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.f -
s->out_pad;
1524 const float ew =
width;
1525 const float eh =
height / 6.f;
1527 const int face =
floorf(j / eh);
1529 const int v_shift =
ceilf(eh * face);
1530 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1532 const float uf = 2.f * (
i + 0.5f) / ew - 1.f;
1533 const float vf = 2.f * (j - v_shift + 0.5f) / ehi - 1.f;
1554 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.f -
s->out_pad;
1555 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.f -
s->out_pad;
1557 const float ew =
width / 6.f;
1560 const int face =
floorf(
i / ew);
1562 const int u_shift =
ceilf(ew * face);
1563 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1565 const float uf = 2.f * (
i - u_shift + 0.5f) / ewi - 1.f;
1566 const float vf = 2.f * (j + 0.5f) / eh - 1.f;
1587 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1589 const float scalew =
s->fin_pad > 0 ? 1.f - (float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1590 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.f -
s->in_pad;
1591 const float eh =
height / 6.f;
1592 const int ewi =
width;
1596 int direction, face;
1603 face =
s->in_cubemap_face_order[direction];
1604 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1606 uf = 0.5f * ewi * (uf + 1.f) - 0.5f;
1607 vf = 0.5f * ehi * (vf + 1.f) - 0.5f;
1615 for (
int i = 0;
i < 4;
i++) {
1616 for (
int j = 0; j < 4; j++) {
1617 int new_ui =
ui + j - 1;
1618 int new_vi = vi +
i - 1;
1622 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1623 face =
s->in_cubemap_face_order[direction];
1625 v_shift =
ceilf(eh * face);
1627 uf = 2.f * new_ui / ewi - 1.f;
1628 vf = 2.f * new_vi / ehi - 1.f;
1638 v_shift =
ceilf(eh * face);
1639 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1641 new_ui =
av_clip(
lrintf(0.5f * ewi * (uf + 1.f)), 0, ewi - 1);
1642 new_vi =
av_clip(
lrintf(0.5f * new_ehi * (vf + 1.f)), 0, new_ehi - 1);
1646 vs[
i][j] = v_shift + new_vi;
1667 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1669 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.f -
s->in_pad;
1670 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.f -
s->in_pad;
1671 const float ew =
width / 6.f;
1676 int direction, face;
1683 face =
s->in_cubemap_face_order[direction];
1684 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1686 uf = 0.5f * ewi * (uf + 1.f) - 0.5f;
1687 vf = 0.5f * ehi * (vf + 1.f) - 0.5f;
1695 for (
int i = 0;
i < 4;
i++) {
1696 for (
int j = 0; j < 4; j++) {
1697 int new_ui =
ui + j - 1;
1698 int new_vi = vi +
i - 1;
1702 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1703 face =
s->in_cubemap_face_order[direction];
1705 u_shift =
ceilf(ew * face);
1707 uf = 2.f * new_ui / ewi - 1.f;
1708 vf = 2.f * new_vi / ehi - 1.f;
1718 u_shift =
ceilf(ew * face);
1719 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1721 new_ui =
av_clip(
lrintf(0.5f * new_ewi * (uf + 1.f)), 0, new_ewi - 1);
1722 new_vi =
av_clip(
lrintf(0.5f * ehi * (vf + 1.f)), 0, ehi - 1);
1725 us[
i][j] = u_shift + new_ui;
1747 const float phi = ((2.f *
i + 0.5f) /
width - 1.f) *
M_PI;
1748 const float theta = ((2.f * j + 0.5f) /
height - 1.f) *
M_PI_2;
1750 const float sin_phi =
sinf(phi);
1751 const float cos_phi =
cosf(phi);
1752 const float sin_theta =
sinf(theta);
1753 const float cos_theta =
cosf(theta);
1755 vec[0] = cos_theta * sin_phi;
1757 vec[2] = cos_theta * cos_phi;
1776 const float phi = ((2.f *
i + 0.5f) /
width - 1.f) *
M_PI_2;
1777 const float theta = ((2.f * j + 0.5f) /
height - 1.f) *
M_PI_2;
1779 const float sin_phi =
sinf(phi);
1780 const float cos_phi =
cosf(phi);
1781 const float sin_theta =
sinf(theta);
1782 const float cos_theta =
cosf(theta);
1784 vec[0] = cos_theta * sin_phi;
1786 vec[2] = cos_theta * cos_phi;
1802 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1803 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1822 const float x = ((2.f *
i + 1.f) /
width - 1.f) *
s->flat_range[0];
1823 const float y = ((2.f * j + 1.f) /
height - 1.f) *
s->flat_range[1];
1824 const float r = hypotf(x, y);
1825 const float theta =
atanf(
r) * 2.f;
1826 const float sin_theta =
sinf(theta);
1828 vec[0] = x /
r * sin_theta;
1829 vec[1] = y /
r * sin_theta;
1830 vec[2] =
cosf(theta);
1848 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1849 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1868 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1870 const float theta = acosf(vec[2]);
1871 const float r = tanf(theta * 0.5f);
1872 const float c =
r / hypotf(vec[0], vec[1]);
1873 const float x = vec[0] *
c /
s->iflat_range[0];
1874 const float y = vec[1] *
c /
s->iflat_range[1];
1876 const float uf = (x + 1.f) *
width / 2.f;
1877 const float vf = (y + 1.f) *
height / 2.f;
1880 const int vi =
floorf(vf);
1884 *du = visible ? uf -
ui : 0.f;
1885 *dv = visible ? vf - vi : 0.f;
1887 for (
int i = 0;
i < 4;
i++) {
1888 for (
int j = 0; j < 4; j++) {
1908 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1909 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1928 const float x = ((2.f *
i + 1.f) /
width - 1.f) *
s->flat_range[0];
1929 const float y = ((2.f * j + 1.f) /
height - 1.f) *
s->flat_range[1];
1930 const float r = hypotf(x, y);
1931 const float theta = asinf(
r) * 2.f;
1932 const float sin_theta =
sinf(theta);
1934 vec[0] = x /
r * sin_theta;
1935 vec[1] = y /
r * sin_theta;
1936 vec[2] =
cosf(theta);
1974 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1976 const float theta = acosf(vec[2]);
1977 const float r =
sinf(theta * 0.5f);
1978 const float c =
r / hypotf(vec[0], vec[1]);
1979 const float x = vec[0] *
c /
s->iflat_range[0];
1980 const float y = vec[1] *
c /
s->iflat_range[1];
1982 const float uf = (x + 1.f) *
width / 2.f;
1983 const float vf = (y + 1.f) *
height / 2.f;
1986 const int vi =
floorf(vf);
1990 *du = visible ? uf -
ui : 0.f;
1991 *dv = visible ? vf - vi : 0.f;
1993 for (
int i = 0;
i < 4;
i++) {
1994 for (
int j = 0; j < 4; j++) {
2034 const float x = ((2.f *
i + 1.f) /
width - 1.f) *
s->flat_range[0];
2035 const float y = ((2.f * j + 1.f) /
height - 1.f) *
s->flat_range[1];
2036 const float r = hypotf(x, y);
2037 const float theta = asinf(
r);
2041 vec[2] =
cosf(theta);
2079 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2081 const float theta = acosf(vec[2]);
2082 const float r =
sinf(theta);
2083 const float c =
r / hypotf(vec[0], vec[1]);
2084 const float x = vec[0] *
c /
s->iflat_range[0];
2085 const float y = vec[1] *
c /
s->iflat_range[1];
2087 const float uf = (x + 1.f) *
width / 2.f;
2088 const float vf = (y + 1.f) *
height / 2.f;
2091 const int vi =
floorf(vf);
2093 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2095 *du = visible ? uf -
ui : 0.f;
2096 *dv = visible ? vf - vi : 0.f;
2098 for (
int i = 0;
i < 4;
i++) {
2099 for (
int j = 0; j < 4; j++) {
2122 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2124 const float phi =
atan2f(vec[0], vec[2]);
2125 const float theta = asinf(vec[1]);
2127 const float uf = (phi /
M_PI + 1.f) *
width / 2.f;
2128 const float vf = (theta /
M_PI_2 + 1.f) *
height / 2.f;
2131 const int vi =
floorf(vf);
2136 for (
int i = 0;
i < 4;
i++) {
2137 for (
int j = 0; j < 4; j++) {
2160 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2162 const float phi =
atan2f(vec[0], vec[2]);
2163 const float theta = asinf(vec[1]);
2165 const float uf = (phi /
M_PI_2 + 1.f) *
width / 2.f;
2166 const float vf = (theta /
M_PI_2 + 1.f) *
height / 2.f;
2169 const int vi =
floorf(vf);
2176 for (
int i = 0;
i < 4;
i++) {
2177 for (
int j = 0; j < 4; j++) {
2197 s->iflat_range[0] = tanf(0.5f *
s->ih_fov *
M_PI / 180.f);
2198 s->iflat_range[1] = tanf(0.5f *
s->iv_fov *
M_PI / 180.f);
2217 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2219 const float theta = acosf(vec[2]);
2220 const float r = tanf(theta);
2222 const float zf = vec[2];
2223 const float h = hypotf(vec[0], vec[1]);
2224 const float c =
h <= 1e-6f ? 1.f : rr /
h;
2225 float uf = vec[0] *
c /
s->iflat_range[0];
2226 float vf = vec[1] *
c /
s->iflat_range[1];
2227 int visible,
ui, vi;
2229 uf = zf >= 0.f ? (uf + 1.f) *
width / 2.f : 0.f;
2230 vf = zf >= 0.f ? (vf + 1.f) *
height / 2.f : 0.f;
2235 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2240 for (
int i = 0;
i < 4;
i++) {
2241 for (
int j = 0; j < 4; j++) {
2264 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2266 const float phi =
atan2f(vec[0], vec[2]);
2267 const float theta = vec[1];
2269 const float uf = (phi /
M_PI + 1.f) *
width / 2.f;
2270 const float vf = (
av_clipf(logf((1.f + theta) / (1.f - theta)) / (2.f *
M_PI), -1.f, 1.f) + 1.f) *
height / 2.f;
2273 const int vi =
floorf(vf);
2278 for (
int i = 0;
i < 4;
i++) {
2279 for (
int j = 0; j < 4; j++) {
2303 const float y = ((2.f * j + 1.f) /
height - 1.f) *
M_PI;
2304 const float div =
expf(2.f * y) + 1.f;
2306 const float sin_phi =
sinf(phi);
2307 const float cos_phi =
cosf(phi);
2308 const float sin_theta = 2.f *
expf(y) / div;
2309 const float cos_theta = (
expf(2.f * y) - 1.f) / div;
2311 vec[0] = -sin_theta * cos_phi;
2313 vec[2] = sin_theta * sin_phi;
2332 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2334 const float l = hypotf(vec[0], vec[1]);
2335 const float r = sqrtf(1.f - vec[2]) /
M_SQRT2;
2337 const float uf = (1.f +
r * vec[0] / (l > 0.f ? l : 1.f)) *
width * 0.5f;
2338 const float vf = (1.f +
r * vec[1] / (l > 0.f ? l : 1.f)) *
height * 0.5f;
2341 const int vi =
floorf(vf);
2346 for (
int i = 0;
i < 4;
i++) {
2347 for (
int j = 0; j < 4; j++) {
2370 const float x = (2.f *
i + 1.f) /
width - 1.f;
2371 const float y = (2.f * j + 1.f) /
height - 1.f;
2372 const float l = hypotf(x, y);
2375 const float z = 2.f * l * sqrtf(1.f - l * l);
2377 vec[0] = z * x / (l > 0.f ? l : 1.f);
2378 vec[1] = z * y / (l > 0.f ? l : 1.f);
2379 vec[2] = 1.f - 2.f * l * l;
2404 const float x = ((2.f *
i + 1.f) /
width - 1.f);
2405 const float y = ((2.f * j + 1.f) /
height - 1.f);
2407 const float xx = x * x;
2408 const float yy = y * y;
2410 const float z = sqrtf(1.f - xx * 0.5f - yy * 0.5f);
2413 const float b = 2.f * z * z - 1.f;
2415 const float aa =
a *
a;
2416 const float bb =
b *
b;
2418 const float w = sqrtf(1.f - 2.f * yy * z * z);
2420 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2422 vec[2] =
w * (bb - aa) / (aa + bb);
2443 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2445 const float theta =
atan2f(vec[0], vec[2]);
2447 const float z = sqrtf(1.f + sqrtf(1.f - vec[1] * vec[1]) *
cosf(theta * 0.5f));
2448 const float x = sqrtf(1.f - vec[1] * vec[1]) *
sinf(theta * 0.5f) / z;
2449 const float y = vec[1] / z;
2451 const float uf = (x + 1.f) *
width / 2.f;
2452 const float vf = (y + 1.f) *
height / 2.f;
2455 const int vi =
floorf(vf);
2460 for (
int i = 0;
i < 4;
i++) {
2461 for (
int j = 0; j < 4; j++) {
2484 const float theta = ((2.f * j + 1.f) /
height - 1.f) *
M_PI_2;
2485 const float phi = ((2.f *
i + 1.f) /
width - 1.f) *
M_PI /
cosf(theta);
2487 const float sin_phi =
sinf(phi);
2488 const float cos_phi =
cosf(phi);
2489 const float sin_theta =
sinf(theta);
2490 const float cos_theta =
cosf(theta);
2492 vec[0] = cos_theta * sin_phi;
2494 vec[2] = cos_theta * cos_phi;
2515 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2517 const float theta = asinf(vec[1]);
2518 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2520 const float uf = (phi /
M_PI + 1.f) *
width / 2.f;
2521 const float vf = (theta /
M_PI_2 + 1.f) *
height / 2.f;
2524 const int vi =
floorf(vf);
2529 for (
int i = 0;
i < 4;
i++) {
2530 for (
int j = 0; j < 4; j++) {
2609 const float pixel_pad = 2;
2610 const float u_pad = pixel_pad /
width;
2611 const float v_pad = pixel_pad /
height;
2613 int u_face, v_face, face;
2615 float l_x, l_y, l_z;
2617 float uf = (
i + 0.5f) /
width;
2618 float vf = (j + 0.5f) /
height;
2625 uf = 3.f * (uf - u_pad) / (1.f - 2.f * u_pad);
2629 }
else if (uf >= 3.f) {
2634 uf = fmodf(uf, 1.f) - 0.5f;
2638 v_face =
floorf(vf * 2.f);
2639 vf = (vf - v_pad - 0.5f * v_face) / (0.5f - 2.f * v_pad) - 0.5f;
2641 if (uf >= -0.5f && uf < 0.5f) {
2646 if (vf >= -0.5f && vf < 0.5f) {
2652 face = u_face + 3 * v_face;
2712 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2714 const float pixel_pad = 2;
2715 const float u_pad = pixel_pad /
width;
2716 const float v_pad = pixel_pad /
height;
2720 int direction, face;
2725 face =
s->in_cubemap_face_order[direction];
2729 uf = M_2_PI *
atanf(uf) + 0.5f;
2730 vf = M_2_PI *
atanf(vf) + 0.5f;
2733 uf = (uf + u_face) * (1.f - 2.f * u_pad) / 3.f + u_pad;
2734 vf = vf * (0.5f - 2.f * v_pad) + v_pad + 0.5f * v_face;
2748 for (
int i = 0;
i < 4;
i++) {
2749 for (
int j = 0; j < 4; j++) {
2769 s->flat_range[0] = tanf(0.5f *
s->h_fov *
M_PI / 180.f);
2770 s->flat_range[1] = tanf(0.5f *
s->v_fov *
M_PI / 180.f);
2789 const float l_x =
s->flat_range[0] * ((2.f *
i + 0.5f) /
width - 1.f);
2790 const float l_y =
s->flat_range[1] * ((2.f * j + 0.5f) /
height - 1.f);
2812 s->flat_range[0] =
s->h_fov / 180.f;
2813 s->flat_range[1] =
s->v_fov / 180.f;
2832 const float uf =
s->flat_range[0] * ((2.f *
i) /
width - 1.f);
2833 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.f);
2835 const float phi =
atan2f(vf, uf);
2836 const float theta =
M_PI_2 * (1.f - hypotf(uf, vf));
2838 const float sin_phi =
sinf(phi);
2839 const float cos_phi =
cosf(phi);
2840 const float sin_theta =
sinf(theta);
2841 const float cos_theta =
cosf(theta);
2843 vec[0] = cos_theta * cos_phi;
2844 vec[1] = cos_theta * sin_phi;
2863 s->iflat_range[0] =
s->ih_fov / 180.f;
2864 s->iflat_range[1] =
s->iv_fov / 180.f;
2883 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2885 const float h = hypotf(vec[0], vec[1]);
2886 const float lh =
h > 0.f ?
h : 1.f;
2889 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2890 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2892 const int visible = hypotf(uf, vf) <= 0.5f;
2895 uf = (uf + 0.5f) *
width;
2896 vf = (vf + 0.5f) *
height;
2901 *du = visible ? uf -
ui : 0.f;
2902 *dv = visible ? vf - vi : 0.f;
2904 for (
int i = 0;
i < 4;
i++) {
2905 for (
int j = 0; j < 4; j++) {
2928 const float uf = ((2.f *
i + 1.f) /
width - 1.f);
2929 const float vf = ((2.f * j + 1.f) /
height - 1.f);
2931 const float d =
s->h_fov;
2932 const float k = uf * uf / ((d + 1.f) * (d + 1.f));
2933 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.f);
2934 const float clon = (-k * d + sqrtf(dscr)) / (k + 1.f);
2935 const float S = (d + 1.f) / (d + clon);
2936 const float lon =
atan2f(uf,
S * clon);
2937 const float lat =
atan2f(vf,
S);
2962 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2964 const float phi =
atan2f(vec[0], vec[2]);
2965 const float theta = asinf(vec[1]);
2967 const float d =
s->ih_fov;
2968 const float S = (d + 1.f) / (d +
cosf(phi));
2970 const float x =
S *
sinf(phi);
2971 const float y =
S * tanf(theta);
2973 const float uf = (x + 1.f) *
width / 2.f;
2974 const float vf = (y + 1.f) *
height / 2.f;
2977 const int vi =
floorf(vf);
2979 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
2984 for (
int i = 0;
i < 4;
i++) {
2985 for (
int j = 0; j < 4; j++) {
3005 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3006 s->flat_range[1] = tanf(0.5f *
s->v_fov *
M_PI / 180.f);
3025 const float uf =
s->flat_range[0] * ((2.f *
i + 1.f) /
width - 1.f);
3026 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) /
height - 1.f);
3028 const float phi = uf;
3029 const float theta =
atanf(vf);
3031 const float sin_phi =
sinf(phi);
3032 const float cos_phi =
cosf(phi);
3033 const float sin_theta =
sinf(theta);
3034 const float cos_theta =
cosf(theta);
3036 vec[0] = cos_theta * sin_phi;
3038 vec[2] = cos_theta * cos_phi;
3056 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3057 s->iflat_range[1] = tanf(0.5f *
s->iv_fov *
M_PI / 180.f);
3076 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3078 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3079 const float theta = asinf(vec[1]);
3081 const float uf = (phi + 1.f) * (
width - 1) / 2.f;
3082 const float vf = (tanf(theta) /
s->iflat_range[1] + 1.f) *
height / 2.f;
3085 const int vi =
floorf(vf);
3087 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3088 theta <=
M_PI *
s->iv_fov / 180.f &&
3089 theta >= -
M_PI *
s->iv_fov / 180.f;
3094 for (
int i = 0;
i < 4;
i++) {
3095 for (
int j = 0; j < 4; j++) {
3118 const float uf = ((2.f *
i + 1.f) /
width - 1.f);
3119 const float vf = ((2.f * j + 1.f) /
height - 1.f);
3120 const float rh = hypotf(uf, vf);
3121 const float sinzz = 1.f - rh * rh;
3122 const float h = 1.f +
s->v_fov;
3123 const float sinz = (
h - sqrtf(sinzz)) / (
h / rh + rh /
h);
3124 const float sinz2 = sinz * sinz;
3127 const float cosz = sqrtf(1.f - sinz2);
3129 const float theta = asinf(cosz);
3130 const float phi =
atan2f(uf, vf);
3132 const float sin_phi =
sinf(phi);
3133 const float cos_phi =
cosf(phi);
3134 const float sin_theta =
sinf(theta);
3135 const float cos_theta =
cosf(theta);
3137 vec[0] = cos_theta * sin_phi;
3138 vec[1] = cos_theta * cos_phi;
3164 const float uf = (float)
i /
width;
3165 const float vf = (float)j /
height;
3167 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3168 vec[1] = 1.f - vf * 2.f;
3169 vec[2] = 2.f *
fabsf(1.f -
fabsf(1.f - uf * 2.f + vf)) - 1.f;
3190 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3192 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3193 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3194 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3195 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3198 float uf, vf, x, y, z;
3205 vf = 0.5f - y * 0.5f;
3207 if ((x + y >= 0.f && y + z >= 0.f && -z - x <= 0.f) ||
3208 (x + y <= 0.f && -y + z >= 0.f && z - x >= 0.f)) {
3209 uf = 0.25f * x + 0.25f;
3211 uf = 0.75f - 0.25f * x;
3223 for (
int i = 0;
i < 4;
i++) {
3224 for (
int j = 0; j < 4; j++) {
3247 const float ew =
width / 2.f;
3250 const int ei =
i >= ew ?
i - ew :
i;
3251 const float m =
i >= ew ? 1.f : -1.f;
3253 const float uf =
s->flat_range[0] * ((2.f * ei) / ew - 1.f);
3254 const float vf =
s->flat_range[1] * ((2.f * j + 1.f) / eh - 1.f);
3256 const float h = hypotf(uf, vf);
3257 const float lh =
h > 0.f ?
h : 1.f;
3258 const float theta = m *
M_PI_2 * (1.f -
h);
3260 const float sin_theta =
sinf(theta);
3261 const float cos_theta =
cosf(theta);
3263 vec[0] = cos_theta * m * uf / lh;
3264 vec[1] = cos_theta * vf / lh;
3286 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3288 const float ew =
width / 2.f;
3291 const float h = hypotf(vec[0], vec[1]);
3292 const float lh =
h > 0.f ?
h : 1.f;
3293 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3295 float uf = (theta * (vec[0] / lh) /
s->iflat_range[0] + 0.5f) * ew;
3296 float vf = (theta * (vec[1] / lh) /
s->iflat_range[1] + 0.5f) * eh;
3301 if (vec[2] >= 0.f) {
3302 u_shift =
ceilf(ew);
3314 for (
int i = 0;
i < 4;
i++) {
3315 for (
int j = 0; j < 4; j++) {
3338 const float scale = 0.99f;
3339 float l_x, l_y, l_z;
3342 const float theta_range = M_PI_4;
3344 const int ew = 4 *
width / 5;
3347 const float phi = ((2.f *
i) / ew - 1.f) *
M_PI / scale;
3348 const float theta = ((2.f * j) / eh - 1.f) * theta_range / scale;
3350 const float sin_phi =
sinf(phi);
3351 const float cos_phi =
cosf(phi);
3352 const float sin_theta =
sinf(theta);
3353 const float cos_theta =
cosf(theta);
3355 l_x = cos_theta * sin_phi;
3357 l_z = cos_theta * cos_phi;
3359 const int ew =
width / 5;
3360 const int eh =
height / 2;
3365 uf = 2.f * (
i - 4 * ew) / ew - 1.f;
3366 vf = 2.f * (j ) / eh - 1.f;
3375 uf = 2.f * (
i - 4 * ew) / ew - 1.f;
3376 vf = 2.f * (j - eh) / eh - 1.f;
3410 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3412 const float scale = 0.99f;
3414 const float phi =
atan2f(vec[0], vec[2]);
3415 const float theta = asinf(vec[1]);
3416 const float theta_range = M_PI_4;
3419 int u_shift, v_shift;
3423 if (theta > -theta_range && theta < theta_range) {
3430 uf = (phi /
M_PI * scale + 1.f) * ew / 2.f;
3431 vf = (theta / theta_range * scale + 1.f) * eh / 2.f;
3439 uf = -vec[0] / vec[1];
3440 vf = -vec[2] / vec[1];
3443 uf = vec[0] / vec[1];
3444 vf = -vec[2] / vec[1];
3448 uf = 0.5f * ew * (uf * scale + 1.f);
3449 vf = 0.5f * eh * (vf * scale + 1.f);
3458 for (
int i = 0;
i < 4;
i++) {
3459 for (
int j = 0; j < 4; j++) {
3461 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3482 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3484 const float phi =
atan2f(vec[0], vec[2]);
3485 const float theta = asinf(vec[1]);
3487 const float theta_range = M_PI_4;
3490 int u_shift, v_shift;
3494 if (theta >= -theta_range && theta <= theta_range) {
3495 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.f -
s->in_pad;
3496 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3505 vf = theta / M_PI_4;
3508 uf = uf >= 0.f ? fmodf(uf - 1.f, 1.f) : fmodf(uf + 1.f, 1.f);
3510 uf = (uf * scalew + 1.f) *
width / 3.f;
3511 vf = (vf * scaleh + 1.f) *
height / 4.f;
3513 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.f -
s->in_pad;
3514 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3522 if (theta <= 0.f && theta >= -
M_PI_2 &&
3523 phi <= M_PI_2 && phi >= -
M_PI_2) {
3524 uf = -vec[0] / vec[1];
3525 vf = -vec[2] / vec[1];
3528 }
else if (theta >= 0.f && theta <=
M_PI_2 &&
3529 phi <= M_PI_2 && phi >= -
M_PI_2) {
3530 uf = vec[0] / vec[1];
3531 vf = -vec[2] / vec[1];
3532 v_shift =
height * 0.25f;
3533 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3534 uf = vec[0] / vec[1];
3535 vf = vec[2] / vec[1];
3539 uf = -vec[0] / vec[1];
3540 vf = vec[2] / vec[1];
3541 v_shift =
height * 0.75f;
3544 uf = 0.5f *
width / 3.f * (uf * scalew + 1.f);
3545 vf =
height * 0.25f * (vf * scaleh + 1.f) + v_offset;
3554 for (
int i = 0;
i < 4;
i++) {
3555 for (
int j = 0; j < 4; j++) {
3557 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3578 const float x = (
i + 0.5f) /
width;
3579 const float y = (j + 0.5f) /
height;
3580 float l_x, l_y, l_z;
3582 if (x < 2.f / 3.f) {
3583 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.f -
s->out_pad;
3584 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3586 const float back =
floorf(y * 2.f);
3588 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3589 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3591 const float sin_phi =
sinf(phi);
3592 const float cos_phi =
cosf(phi);
3593 const float sin_theta =
sinf(theta);
3594 const float cos_theta =
cosf(theta);
3596 l_x = cos_theta * sin_phi;
3598 l_z = cos_theta * cos_phi;
3600 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.f -
s->out_pad;
3601 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3603 const int face =
floorf(y * 4.f);
3614 l_x = (0.5f - uf) / scalew;
3616 l_z = (0.5f - vf) / scaleh;
3621 vf = 1.f - (vf - 0.5f);
3623 l_x = (0.5f - uf) / scalew;
3625 l_z = (-0.5f + vf) / scaleh;
3628 vf = y * 2.f - 0.5f;
3629 vf = 1.f - (1.f - vf);
3631 l_x = (0.5f - uf) / scalew;
3633 l_z = (0.5f - vf) / scaleh;
3636 vf = y * 2.f - 1.5f;
3638 l_x = (0.5f - uf) / scalew;
3640 l_z = (-0.5f + vf) / scaleh;
3670 const float x = (
i + 0.5f) /
width;
3671 const float y = (j + 0.5f) /
height;
3674 vec[0] = x * 4.f - 1.f;
3675 vec[1] = (y * 2.f - 1.f);
3677 }
else if (x >= 0.6875f && x < 0.8125f &&
3678 y >= 0.375f && y < 0.625f) {
3679 vec[0] = -(x - 0.6875f) * 16.f + 1.f;
3680 vec[1] = (y - 0.375f) * 8.f - 1.f;
3682 }
else if (0.5f <= x && x < 0.6875f &&
3683 ((0.f <= y && y < 0.375f && y >= 2.f * (x - 0.5f)) ||
3684 (0.375f <= y && y < 0.625f) ||
3685 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3687 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.f - 4.f * x) - 1.f;
3688 vec[2] = -2.f * (x - 0.5f) / 0.1875f + 1.f;
3689 }
else if (0.8125f <= x && x < 1.f &&
3690 ((0.f <= y && y < 0.375f && x >= (1.f - y / 2.f)) ||
3691 (0.375f <= y && y < 0.625f) ||
3692 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3694 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.f * x - 3.f) - 1.f;
3695 vec[2] = 2.f * (x - 0.8125f) / 0.1875f - 1.f;
3696 }
else if (0.f <= y && y < 0.375f &&
3697 ((0.5f <= x && x < 0.8125f && y < 2.f * (x - 0.5f)) ||
3698 (0.6875f <= x && x < 0.8125f) ||
3699 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3700 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5f - y) - 1.f;
3702 vec[2] = 2.f * (0.375f - y) / 0.375f - 1.f;
3704 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5f) - 1.f;
3706 vec[2] = -2.f * (1.f - y) / 0.375f + 1.f;
3728 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3736 uf = (uf + 1.f) * 0.5f;
3737 vf = (vf + 1.f) * 0.5f;
3741 uf = 0.1875f * vf - 0.375f * uf * vf - 0.125f * uf + 0.8125f;
3742 vf = 0.375f - 0.375f * vf;
3748 uf = 1.f - 0.1875f * vf - 0.5f * uf + 0.375f * uf * vf;
3749 vf = 1.f - 0.375f * vf;
3752 vf = 0.25f * vf + 0.75f * uf * vf - 0.375f * uf + 0.375f;
3753 uf = 0.1875f * uf + 0.8125f;
3756 vf = 0.375f * uf - 0.75f * uf * vf + vf;
3757 uf = 0.1875f * uf + 0.5f;
3760 uf = 0.125f * uf + 0.6875f;
3761 vf = 0.25f * vf + 0.375f;
3774 for (
int i = 0;
i < 4;
i++) {
3775 for (
int j = 0; j < 4; j++) {
3798 const float x = ((
i + 0.5f) /
width) * 2.f - 1.f;
3799 const float y = ((j + 0.5f) /
height) * 2.f - 1.f;
3800 const float ax =
fabsf(x);
3801 const float ay =
fabsf(y);
3803 vec[2] = 1.f - (ax + ay);
3804 if (ax + ay > 1.f) {
3805 vec[0] = (1.f - ay) *
FFSIGN(x);
3806 vec[1] = (1.f - ax) *
FFSIGN(y);
3831 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3847 uf = uf * 0.5f + 0.5f;
3848 vf = vf * 0.5f + 0.5f;
3859 for (
int i = 0;
i < 4;
i++) {
3860 for (
int j = 0; j < 4; j++) {
3871 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
3872 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
3873 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
3874 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
3889 float rot_quaternion[2][4],
3890 const int rotation_order[3])
3892 const float yaw_rad = yaw *
M_PI / 180.f;
3893 const float pitch_rad = pitch *
M_PI / 180.f;
3894 const float roll_rad = roll *
M_PI / 180.f;
3896 const float sin_yaw =
sinf(yaw_rad * 0.5f);
3897 const float cos_yaw =
cosf(yaw_rad * 0.5f);
3898 const float sin_pitch =
sinf(pitch_rad * 0.5f);
3899 const float cos_pitch =
cosf(pitch_rad * 0.5f);
3900 const float sin_roll =
sinf(roll_rad * 0.5f);
3901 const float cos_roll =
cosf(roll_rad * 0.5f);
3906 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
3907 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
3908 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
3923 static inline void rotate(
const float rot_quaternion[2][4],
3926 float qv[4],
temp[4], rqv[4];
3944 modifier[0] = h_flip ? -1.f : 1.f;
3945 modifier[1] = v_flip ? -1.f : 1.f;
3946 modifier[2] = d_flip ? -1.f : 1.f;
3949 static inline void mirror(
const float *modifier,
float *vec)
3951 vec[0] *= modifier[0];
3952 vec[1] *= modifier[1];
3953 vec[2] *= modifier[2];
3956 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
3959 for (
int i = 0;
i < 4;
i++) {
3960 for (
int j = 0; j < 4; j++)
3961 u[
i][j] =
w - 1 -
u[
i][j];
3966 for (
int i = 0;
i < 4;
i++) {
3967 for (
int j = 0; j < 4; j++)
3968 v[
i][j] =
h - 1 - v[
i][j];
3975 const int pr_height =
s->pr_height[p];
3977 for (
int n = 0; n <
s->nb_threads; n++) {
3979 const int slice_start = (pr_height * n ) /
s->nb_threads;
3980 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
3987 if (!
r->u[p] || !
r->v[p])
3996 if (sizeof_mask && !p) {
4012 const float d = 0.5f * hypotf(
w,
h);
4013 const float l =
sinf(d_fov *
M_PI / 360.f) / d;
4015 *h_fov = asinf(
w * 0.5 * l) * 360.f /
M_PI;
4016 *v_fov = asinf(
h * 0.5 * l) * 360.f /
M_PI;
4018 if (d_fov > 180.f) {
4019 *h_fov = 180.f - *h_fov;
4020 *v_fov = 180.f - *v_fov;
4026 const float d = 0.5f * hypotf(
w,
h);
4027 const float l = d / (
sinf(d_fov *
M_PI / 720.f));
4029 *h_fov = 2.f * asinf(
w * 0.5f / l) * 360.f /
M_PI;
4030 *v_fov = 2.f * asinf(
h * 0.5f / l) * 360.f /
M_PI;
4035 const float d = 0.5f * hypotf(
w,
h);
4036 const float l = d / (tanf(d_fov *
M_PI / 720.f));
4038 *h_fov = 2.f *
atan2f(
w * 0.5f, l) * 360.f /
M_PI;
4039 *v_fov = 2.f *
atan2f(
h * 0.5f, l) * 360.f /
M_PI;
4044 const float d = 0.5f * hypotf(
w * 0.5f,
h);
4046 *h_fov = d /
w * 2.f * d_fov;
4047 *v_fov = d /
h * d_fov;
4052 const float d = 0.5f * hypotf(
w,
h);
4054 *h_fov = d /
w * d_fov;
4055 *v_fov = d /
h * d_fov;
4061 const float da = tanf(0.5f *
FFMIN(d_fov, 359.f) *
M_PI / 180.f);
4062 const float d = hypotf(
w,
h);
4079 outw[0] = outw[3] =
w;
4081 outh[0] = outh[3] =
h;
4090 for (
int p = 0; p <
s->nb_allocated; p++) {
4091 const int max_value =
s->max_value;
4092 const int width =
s->pr_width[p];
4093 const int uv_linesize =
s->uv_linesize[p];
4094 const int height =
s->pr_height[p];
4095 const int in_width =
s->inplanewidth[p];
4096 const int in_height =
s->inplaneheight[p];
4104 for (
int j = slice_start; j <
slice_end; j++) {
4107 int16_t *v =
r->v[p] + ((j - slice_start) * (
int64_t)uv_linesize +
i) *
elements;
4108 int16_t *ker =
r->ker[p] + ((j - slice_start) * (
int64_t)uv_linesize +
i) *
elements;
4109 uint8_t *mask8 = (p || !
r->mask) ?
NULL :
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4110 uint16_t *mask16 = (p || !
r->mask) ?
NULL : (uint16_t *)
r->mask + ((j - slice_start) *
s->pr_width[0] +
i);
4111 int in_mask, out_mask;
4113 if (
s->out_transpose)
4118 rotate(
s->rot_quaternion, vec);
4121 mirror(
s->output_mirror_modifier, vec);
4122 if (
s->in_transpose)
4123 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4125 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4126 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4128 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4130 if (!p &&
r->mask) {
4131 if (
s->mask_size == 1) {
4132 mask8[0] = 255 * (out_mask & in_mask);
4134 mask16[0] = max_value * (out_mask & in_mask);
4147 if (!
isfinite(
val) || val < 1.f || val > INT16_MAX) {
4149 "Output %s %g is outside the allowed range [1, %d].\n",
4164 const int depth =
desc->comp[0].depth;
4165 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4170 int in_offset_h, in_offset_w;
4171 int out_offset_h, out_offset_w;
4176 s->max_value = (1 << depth) - 1;
4178 switch (
s->interp) {
4181 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4183 sizeof_uv =
sizeof(int16_t) *
s->elements;
4188 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4189 s->elements = 2 * 2;
4190 sizeof_uv =
sizeof(int16_t) *
s->elements;
4191 sizeof_ker =
sizeof(int16_t) *
s->elements;
4195 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4196 s->elements = 3 * 3;
4197 sizeof_uv =
sizeof(int16_t) *
s->elements;
4198 sizeof_ker =
sizeof(int16_t) *
s->elements;
4202 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4203 s->elements = 4 * 4;
4204 sizeof_uv =
sizeof(int16_t) *
s->elements;
4205 sizeof_ker =
sizeof(int16_t) *
s->elements;
4209 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4210 s->elements = 4 * 4;
4211 sizeof_uv =
sizeof(int16_t) *
s->elements;
4212 sizeof_ker =
sizeof(int16_t) *
s->elements;
4216 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4217 s->elements = 4 * 4;
4218 sizeof_uv =
sizeof(int16_t) *
s->elements;
4219 sizeof_ker =
sizeof(int16_t) *
s->elements;
4223 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4224 s->elements = 4 * 4;
4225 sizeof_uv =
sizeof(int16_t) *
s->elements;
4226 sizeof_ker =
sizeof(int16_t) *
s->elements;
4230 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4231 s->elements = 4 * 4;
4232 sizeof_uv =
sizeof(int16_t) *
s->elements;
4233 sizeof_ker =
sizeof(int16_t) *
s->elements;
4241 for (
int order = 0; order <
NB_RORDERS; order++) {
4242 const char c =
s->rorder[order];
4247 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4248 s->rotation_order[0] =
YAW;
4249 s->rotation_order[1] =
PITCH;
4250 s->rotation_order[2] =
ROLL;
4257 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4258 s->rotation_order[0] =
YAW;
4259 s->rotation_order[1] =
PITCH;
4260 s->rotation_order[2] =
ROLL;
4264 s->rotation_order[order] = rorder;
4267 switch (
s->in_stereo) {
4271 in_offset_w = in_offset_h = 0;
4292 s->in_width =
s->inplanewidth[0];
4293 s->in_height =
s->inplaneheight[0];
4295 if (
s->id_fov > 0.f)
4298 if (
s->in_transpose)
4299 FFSWAP(
int,
s->in_width,
s->in_height);
4302 if (
s->in_width < 1 ||
s->in_width > INT16_MAX ||
4303 s->in_height < 1 ||
s->in_height > INT16_MAX) {
4305 "Input dimensions %dx%d are outside the allowed range [1, %d].\n",
4306 s->in_width,
s->in_height, INT16_MAX);
4612 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4613 s->out ==
FLAT &&
s->d_fov == 0.f) {
4616 w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f), &
h);
4619 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4620 s->out ==
FLAT &&
s->d_fov == 0.f) {
4623 h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f), &
w);
4626 }
else if (
s->width > 0 &&
s->height > 0) {
4629 }
else if (
s->width > 0 ||
s->height > 0) {
4633 if (
s->out_transpose)
4636 if (
s->in_transpose)
4640 if (w < 1 || w > INT16_MAX || h < 1 || h > INT16_MAX) {
4642 "Output dimensions %dx%d are outside the allowed range [1, %d].\n",
4654 err = prepare_out(
ctx);
4661 switch (
s->out_stereo) {
4663 out_offset_w = out_offset_h = 0;
4682 for (
int i = 0;
i < 4;
i++)
4692 if (
desc->log2_chroma_h ==
desc->log2_chroma_w &&
desc->log2_chroma_h == 0) {
4693 s->nb_allocated = 1;
4694 s->map[0] =
s->map[1] =
s->map[2] =
s->map[3] = 0;
4696 s->nb_allocated = 2;
4697 s->map[0] =
s->map[3] = 0;
4698 s->map[1] =
s->map[2] = 1;
4701 if (!
s->slice_remap)
4702 s->slice_remap =
av_calloc(
s->nb_threads,
sizeof(*
s->slice_remap));
4703 if (!
s->slice_remap)
4706 for (
int i = 0;
i <
s->nb_allocated;
i++) {
4707 err =
allocate_plane(
s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha *
s->alpha,
i);
4713 s->rot_quaternion,
s->rotation_order);
4747 char *res,
int res_len,
int flags)
4752 s->yaw =
s->pitch =
s->roll = 0.f;
4765 s->rot_quaternion[0][0] = 1.f;
4766 s->rot_quaternion[0][1] =
s->rot_quaternion[0][2] =
s->rot_quaternion[0][3] = 0.f;
4775 for (
int n = 0; n <
s->nb_threads &&
s->slice_remap; n++) {
4778 for (
int p = 0; p <
s->nb_allocated; p++) {
4817 .priv_class = &v360_class,
static double val(void *priv, double ch)
static const char *const format[]
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next 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.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Main libavfilter public API header.
#define flags(name, subs,...)
#define u(width, name, range_min, range_max)
#define us(width, name, range_min, range_max, subs,...)
#define FFSWAP(type, a, b)
static __device__ float fabsf(float a)
static __device__ float floorf(float a)
static __device__ float ceilf(float a)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
static const int16_t alpha[]
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
#define AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUV420P14
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
#define AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P10
static const ElemCat * elements[ELEMENT_COUNT]
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
const char * name
Pad name.
const char * name
Filter name.
AVFormatInternal * internal
An opaque field for libavformat internal usage.
This structure describes decoded (raw) audio or video data.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Used for passing data between threads.
static const uint8_t q1[256]
static const uint8_t q0[256]
void ff_v360_init_x86(V360Context *s, int depth)
#define NEAREST(type, name)
static enum AVPixelFormat alpha_pix_fmts[]
static int prepare_orthographic_in(AVFilterContext *ctx)
Prepare data for processing orthographic input format.
static int prepare_cylindrical_in(AVFilterContext *ctx)
Prepare data for processing cylindrical input format.
static void set_dimensions(int *outw, int *outh, int w, int h, const AVPixFmtDescriptor *desc)
static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
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.
static int flat_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in flat format.
static void calculate_cubic_bc_coeffs(float t, float *coeffs, float b, float c)
Calculate 1-dimensional cubic_bc_spline coefficients.
static int hequirect_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in half equirectangular format.
static 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 int prepare_eac_in(AVFilterContext *ctx)
Prepare data for processing equi-angular cubemap input format.
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 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 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 void calculate_bicubic_coeffs(float t, float *coeffs)
Calculate 1-dimensional cubic coefficients.
static void rotate(const float rot_quaternion[2][4], float *vec)
Rotate vector with given rotation quaternion.
#define DEFINE_REMAP1_LINE(bits, div)
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 cube3x2_to_xyz(const V360Context *s, int i, int j, int width, int height, float *vec)
Calculate 3D coordinates on sphere for corresponding frame position in cubemap3x2 format.
static int get_output_dimension(AVFilterContext *ctx, const char *name, float val, int *dim)
static int prepare_eac_out(AVFilterContext *ctx)
Prepare data for processing equi-angular cubemap output format.
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.
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 prepare_flat_out(AVFilterContext *ctx)
Prepare data for processing flat output format.
static void input_flip(int16_t u[4][4], int16_t v[4][4], int w, int h, int hflip, int vflip)
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.
#define DEFINE_REMAP(ws, bits)
Generate remapping function with a given window size and pixel depth.
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 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.
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 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.
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 void calculate_lanczos_coeffs(float t, float *coeffs)
Calculate 1-dimensional lanczos coefficients.
static void calculate_gaussian_coeffs(float t, float *coeffs)
Calculate 1-dimensional gaussian coefficients.
static void conjugate_quaternion(float d[4], const float q[4])
static void normalize_vector(float *vec)
Normalize vector.
static int get_direction(char c)
Convert char to corresponding direction.
void ff_v360_init(V360Context *s, int depth)
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.
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 void calculate_spline16_coeffs(float t, float *coeffs)
Calculate 1-dimensional spline16 coefficients.
static int reflectx(int x, int y, int w, int h)
Reflect x operation.
static int query_formats(AVFilterContext *ctx)
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.
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 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.
static const AVFilterPad inputs[]
static int prepare_cube_in(AVFilterContext *ctx)
Prepare data for processing cubemap input format.
static int prepare_fisheye_in(AVFilterContext *ctx)
Prepare data for processing fisheye input format.
static void mirror(const float *modifier, float *vec)
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 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 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 const AVFilterPad outputs[]
static int ereflectx(int x, int y, int w, int h)
Reflect x operation for equirect.
static int prepare_equisolid_out(AVFilterContext *ctx)
Prepare data for processing equisolid output format.
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 int prepare_fisheye_out(AVFilterContext *ctx)
Prepare data for processing fisheye output format.
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.
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.
static int get_rotation(char c)
Convert char to corresponding rotation angle.
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p)
static void rotate_cube_face(float *uf, float *vf, int rotation)
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_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 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.
static int reflecty(int y, int h)
Reflect y operation.
static void bicubic_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for bicubic interpolation.
static int 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.
static void set_mirror_modifier(int h_flip, int v_flip, int d_flip, float *modifier)
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 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.
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static av_cold int init(AVFilterContext *ctx)
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.
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 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.
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.
static av_cold void uninit(AVFilterContext *ctx)
static int prepare_stereographic_out(AVFilterContext *ctx)
Prepare data for processing stereographic output format.
static void fov_from_dfov(int format, float d_fov, float w, float h, float *h_fov, float *v_fov)
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 prepare_cylindrical_out(AVFilterContext *ctx)
Prepare data for processing cylindrical output 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 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.
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 void mitchell_kernel(float du, float dv, const XYRemap *rmap, int16_t *u, int16_t *v, int16_t *ker)
Calculate kernel for mitchell interpolation.
static 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.
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 void calculate_lagrange_coeffs(float t, float *coeffs)
Calculate 1-dimensional lagrange coefficients.
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.
static int config_output(AVFilterLink *outlink)
static int prepare_flat_in(AVFilterContext *ctx)
Prepare data for processing flat input format.
static int prepare_orthographic_out(AVFilterContext *ctx)
Prepare data for processing orthographic output format.
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 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.
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_equisolid_in(AVFilterContext *ctx)
Prepare data for processing equisolid input 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.
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.
static void multiply_quaternion(float c[4], const float a[4], const float b[4])
AVFILTER_DEFINE_CLASS(v360)
#define DEFINE_REMAP_LINE(ws, bits, div)
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 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 get_rorder(char c)
Convert char to corresponding rotation order.
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.
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 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.
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 void rotate_cube_face_inverse(float *uf, float *vf, int rotation)
static int prepare_cube_out(AVFilterContext *ctx)
Prepare data for processing cubemap output format.
static const AVOption v360_options[]
static int mod(int a, int b)
Modulo operation with only positive remainders.
static int prepare_stereographic_in(AVFilterContext *ctx)
Prepare data for processing stereographic input format.
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.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.