@ -102,6 +102,8 @@ typedef struct V360Context {
int in_cubemap_face_rotation [ 6 ] ;
int out_cubemap_face_rotation [ 6 ] ;
float in_pad , out_pad ;
float yaw , pitch , roll ;
int h_flip , v_flip , d_flip ;
@ -155,6 +157,8 @@ static const AVOption v360_options[] = {
{ " out_forder " , " output cubemap face order " , OFFSET ( out_forder ) , AV_OPT_TYPE_STRING , { . str = " rludfb " } , 0 , NB_DIRECTIONS - 1 , FLAGS , " out_forder " } ,
{ " in_frot " , " input cubemap face rotation " , OFFSET ( in_frot ) , AV_OPT_TYPE_STRING , { . str = " 000000 " } , 0 , NB_DIRECTIONS - 1 , FLAGS , " in_frot " } ,
{ " out_frot " , " output cubemap face rotation " , OFFSET ( out_frot ) , AV_OPT_TYPE_STRING , { . str = " 000000 " } , 0 , NB_DIRECTIONS - 1 , FLAGS , " out_frot " } ,
{ " in_pad " , " input cubemap pads " , OFFSET ( in_pad ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.f } , 0.f , 1.f , FLAGS , " in_pad " } ,
{ " out_pad " , " output cubemap pads " , OFFSET ( out_pad ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.f } , 0.f , 1.f , FLAGS , " out_pad " } ,
{ " yaw " , " yaw rotation " , OFFSET ( yaw ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.f } , - 180.f , 180.f , FLAGS , " yaw " } ,
{ " pitch " , " pitch rotation " , OFFSET ( pitch ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.f } , - 180.f , 180.f , FLAGS , " pitch " } ,
{ " roll " , " roll rotation " , OFFSET ( roll ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.f } , - 180.f , 180.f , FLAGS , " roll " } ,
@ -734,6 +738,9 @@ static void cube_to_xyz(const V360Context *s,
float norm ;
float l_x , l_y , l_z ;
uf / = ( 1.f - s - > out_pad ) ;
vf / = ( 1.f - s - > out_pad ) ;
rotate_cube_face_inverse ( & uf , & vf , s - > out_cubemap_face_rotation [ face ] ) ;
switch ( direction ) {
@ -1091,6 +1098,9 @@ static void xyz_to_cube3x2(const V360Context *s,
xyz_to_cube ( s , vec , & uf , & vf , & direction ) ;
uf * = ( 1.f - s - > in_pad ) ;
vf * = ( 1.f - s - > in_pad ) ;
face = s - > in_cubemap_face_order [ direction ] ;
u_face = face % 3 ;
v_face = face / 3 ;
@ -1108,22 +1118,44 @@ static void xyz_to_cube3x2(const V360Context *s,
for ( i = - 1 ; i < 3 ; i + + ) {
for ( j = - 1 ; j < 3 ; j + + ) {
float u , v ;
int new_ui = ui + j ;
int new_vi = vi + i ;
int u_shift , v_shift ;
int new_ewi , new_ehi ;
process_cube_coordinates ( s , 2.f * ( ui + j ) / ewi - 1.f ,
2.f * ( vi + i ) / ehi - 1.f ,
direction , & u , & v , & face ) ;
u_face = face % 3 ;
v_face = face / 3 ;
u_shift = ceilf ( ew * u_face ) ;
v_shift = ceilf ( eh * v_face ) ;
new_ewi = ceilf ( ew * ( u_face + 1 ) ) - u_shift ;
new_ehi = ceilf ( eh * ( v_face + 1 ) ) - v_shift ;
us [ i + 1 ] [ j + 1 ] = u_shift + av_clip ( roundf ( 0.5f * new_ewi * ( u + 1.f ) ) , 0 , new_ewi - 1 ) ;
vs [ i + 1 ] [ j + 1 ] = v_shift + av_clip ( roundf ( 0.5f * new_ehi * ( v + 1.f ) ) , 0 , new_ehi - 1 ) ;
if ( new_ui > = 0 & & new_ui < ewi & & new_vi > = 0 & & new_vi < ehi ) {
face = s - > in_cubemap_face_order [ direction ] ;
u_face = face % 3 ;
v_face = face / 3 ;
u_shift = ceilf ( ew * u_face ) ;
v_shift = ceilf ( eh * v_face ) ;
} else {
uf = 2.f * new_ui / ewi - 1.f ;
vf = 2.f * new_vi / ehi - 1.f ;
uf / = ( 1.f - s - > in_pad ) ;
vf / = ( 1.f - s - > in_pad ) ;
process_cube_coordinates ( s , uf , vf , direction , & uf , & vf , & face ) ;
uf * = ( 1.f - s - > in_pad ) ;
vf * = ( 1.f - s - > in_pad ) ;
u_face = face % 3 ;
v_face = face / 3 ;
u_shift = ceilf ( ew * u_face ) ;
v_shift = ceilf ( eh * v_face ) ;
new_ewi = ceilf ( ew * ( u_face + 1 ) ) - u_shift ;
new_ehi = ceilf ( eh * ( v_face + 1 ) ) - v_shift ;
new_ui = av_clip ( roundf ( 0.5f * new_ewi * ( uf + 1.f ) ) , 0 , new_ewi - 1 ) ;
new_vi = av_clip ( roundf ( 0.5f * new_ehi * ( vf + 1.f ) ) , 0 , new_ehi - 1 ) ;
}
us [ i + 1 ] [ j + 1 ] = u_shift + new_ui ;
vs [ i + 1 ] [ j + 1 ] = v_shift + new_vi ;
}
}
}
@ -1173,7 +1205,7 @@ static void xyz_to_cube6x1(const V360Context *s,
uint16_t us [ 4 ] [ 4 ] , uint16_t vs [ 4 ] [ 4 ] , float * du , float * dv )
{
const float ew = width / 6.f ;
const float eh = height ;
const int ehi = height ;
float uf , vf ;
int ui , vi ;
int ewi ;
@ -1182,11 +1214,14 @@ static void xyz_to_cube6x1(const V360Context *s,
xyz_to_cube ( s , vec , & uf , & vf , & direction ) ;
uf * = ( 1.f - s - > in_pad ) ;
vf * = ( 1.f - s - > in_pad ) ;
face = s - > in_cubemap_face_order [ direction ] ;
ewi = ceilf ( ew * ( face + 1 ) ) - ceilf ( ew * face ) ;
uf = 0.5f * ewi * ( uf + 1.f ) ;
vf = 0.5f * eh * ( vf + 1.f ) ;
vf = 0.5f * ehi * ( vf + 1.f ) ;
ui = floorf ( uf ) ;
vi = floorf ( vf ) ;
@ -1196,18 +1231,37 @@ static void xyz_to_cube6x1(const V360Context *s,
for ( i = - 1 ; i < 3 ; i + + ) {
for ( j = - 1 ; j < 3 ; j + + ) {
float u , v ;
int new_ui = ui + j ;
int new_vi = vi + i ;
int u_shift ;
int new_ewi ;
process_cube_coordinates ( s , 2.f * ( ui + j ) / ewi - 1.f ,
2.f * ( vi + i ) / eh - 1.f ,
direction , & u , & v , & face ) ;
u_shift = ceilf ( ew * face ) ;
new_ewi = ceilf ( ew * ( face + 1 ) ) - u_shift ;
if ( new_ui > = 0 & & new_ui < ewi & & new_vi > = 0 & & new_vi < ehi ) {
face = s - > in_cubemap_face_order [ direction ] ;
u_shift = ceilf ( ew * face ) ;
} else {
uf = 2.f * new_ui / ewi - 1.f ;
vf = 2.f * new_vi / ehi - 1.f ;
uf / = ( 1.f - s - > in_pad ) ;
vf / = ( 1.f - s - > in_pad ) ;
process_cube_coordinates ( s , uf , vf , direction , & uf , & vf , & face ) ;
uf * = ( 1.f - s - > in_pad ) ;
vf * = ( 1.f - s - > in_pad ) ;
u_shift = ceilf ( ew * face ) ;
new_ewi = ceilf ( ew * ( face + 1 ) ) - u_shift ;
new_ui = av_clip ( roundf ( 0.5f * new_ewi * ( uf + 1.f ) ) , 0 , new_ewi - 1 ) ;
new_vi = av_clip ( roundf ( 0.5f * ehi * ( vf + 1.f ) ) , 0 , ehi - 1 ) ;
}
us [ i + 1 ] [ j + 1 ] = u_shift + av_clip ( roundf ( 0.5f * new_ewi * ( u + 1.f ) ) , 0 , new_ewi - 1 ) ;
vs [ i + 1 ] [ j + 1 ] = av_clip ( roundf ( 0.5f * eh * ( v + 1.f ) ) , 0 , eh - 1 ) ;
us [ i + 1 ] [ j + 1 ] = u_shift + new_ui ;
vs [ i + 1 ] [ j + 1 ] = new_vi ;
}
}
}