@ -130,92 +130,127 @@ static int config_output(AVFilterLink *outlink)
return 0 ;
}
static void horizontal_frame_pack ( FramepackContext * s ,
AVFrame * ds t,
static void horizontal_frame_pack ( AVFilterLink * outlink ,
AVFrame * ou t,
int interleaved )
{
int plane , i ;
int length = dst - > width / 2 ;
int lines = dst - > height ;
for ( plane = 0 ; plane < s - > pix_desc - > nb_components ; plane + + ) {
const uint8_t * leftp = s - > input_views [ LEFT ] - > data [ plane ] ;
const uint8_t * rightp = s - > input_views [ RIGHT ] - > data [ plane ] ;
uint8_t * dstp = dst - > data [ plane ] ;
if ( plane = = 1 | | plane = = 2 ) {
length = - ( - ( dst - > width / 2 ) > > s - > pix_desc - > log2_chroma_w ) ;
lines = - ( - ( dst - > height ) > > s - > pix_desc - > log2_chroma_h ) ;
}
if ( interleaved ) {
AVFilterContext * ctx = outlink - > src ;
FramepackContext * s = ctx - > priv ;
int i , plane ;
if ( interleaved ) {
const uint8_t * leftp = s - > input_views [ LEFT ] - > data [ 0 ] ;
const uint8_t * rightp = s - > input_views [ RIGHT ] - > data [ 0 ] ;
uint8_t * dstp = out - > data [ 0 ] ;
int length = out - > width / 2 ;
int lines = out - > height ;
for ( plane = 0 ; plane < s - > pix_desc - > nb_components ; plane + + ) {
if ( plane = = 1 | | plane = = 2 ) {
length = - ( - ( out - > width / 2 ) > > s - > pix_desc - > log2_chroma_w ) ;
lines = - ( - ( out - > height ) > > s - > pix_desc - > log2_chroma_h ) ;
}
for ( i = 0 ; i < lines ; i + + ) {
int j ;
int k = 0 ;
leftp = s - > input_views [ LEFT ] - > data [ plane ] +
s - > input_views [ LEFT ] - > linesize [ plane ] * i ;
rightp = s - > input_views [ RIGHT ] - > data [ plane ] +
s - > input_views [ RIGHT ] - > linesize [ plane ] * i ;
dstp = out - > data [ plane ] + out - > linesize [ plane ] * i ;
for ( j = 0 ; j < length ; j + + ) {
dstp [ k + + ] = leftp [ j ] ;
dstp [ k + + ] = rightp [ j ] ;
// interpolate chroma as necessary
if ( ( s - > pix_desc - > log2_chroma_w | |
s - > pix_desc - > log2_chroma_h ) & &
( plane = = 1 | | plane = = 2 ) ) {
* dstp + + = ( * leftp + * rightp ) / 2 ;
* dstp + + = ( * leftp + * rightp ) / 2 ;
} else {
* dstp + + = * leftp ;
* dstp + + = * rightp ;
}
leftp + = 1 ;
rightp + = 1 ;
}
dstp + = dst - > linesize [ plane ] ;
leftp + = s - > input_views [ LEFT ] - > linesize [ plane ] ;
rightp + = s - > input_views [ RIGHT ] - > linesize [ plane ] ;
}
} else {
av_image_copy_plane ( dst - > data [ plane ] , dst - > linesize [ plane ] ,
leftp , s - > input_views [ LEFT ] - > linesize [ plane ] ,
length , lines ) ;
av_image_copy_plane ( dst - > data [ plane ] + length , dst - > linesize [ plane ] ,
rightp , s - > input_views [ RIGHT ] - > linesize [ plane ] ,
length , lines ) ;
}
} else {
for ( i = 0 ; i < 2 ; i + + ) {
const uint8_t * src [ 4 ] ;
uint8_t * dst [ 4 ] ;
int sub_w = s - > input_views [ i ] - > width > > s - > pix_desc - > log2_chroma_w ;
src [ 0 ] = s - > input_views [ i ] - > data [ 0 ] ;
src [ 1 ] = s - > input_views [ i ] - > data [ 1 ] ;
src [ 2 ] = s - > input_views [ i ] - > data [ 2 ] ;
dst [ 0 ] = out - > data [ 0 ] + i * s - > input_views [ i ] - > width ;
dst [ 1 ] = out - > data [ 1 ] + i * sub_w ;
dst [ 2 ] = out - > data [ 2 ] + i * sub_w ;
av_image_copy ( dst , out - > linesize , src , s - > input_views [ i ] - > linesize ,
s - > input_views [ i ] - > format ,
s - > input_views [ i ] - > width ,
s - > input_views [ i ] - > height ) ;
}
}
}
static void vertical_frame_pack ( FramepackContext * s ,
AVFrame * dst ,
static void vertical_frame_pack ( AVFilterLink * outlink ,
AVFrame * ou t,
int interleaved )
{
int plane , offset ;
int length = dst - > width ;
int lines = dst - > height / 2 ;
for ( plane = 0 ; plane < s - > pix_desc - > nb_components ; plane + + ) {
if ( plane = = 1 | | plane = = 2 ) {
length = - ( - ( dst - > width ) > > s - > pix_desc - > log2_chroma_w ) ;
lines = - ( - ( dst - > height / 2 ) > > s - > pix_desc - > log2_chroma_h ) ;
}
AVFilterContext * ctx = outlink - > src ;
FramepackContext * s = ctx - > priv ;
int i ;
offset = interleaved ? dst - > linesize [ plane ] : dst - > linesize [ plane ] * lines ;
av_image_copy_plane ( dst - > data [ plane ] ,
dst - > linesize [ plane ] < < interleaved ,
s - > input_views [ LEFT ] - > data [ plane ] ,
s - > input_views [ LEFT ] - > linesize [ plane ] ,
length , lines ) ;
av_image_copy_plane ( dst - > data [ plane ] + offset ,
dst - > linesize [ plane ] < < interleaved ,
s - > input_views [ RIGHT ] - > data [ plane ] ,
s - > input_views [ RIGHT ] - > linesize [ plane ] ,
length , lines ) ;
for ( i = 0 ; i < 2 ; i + + ) {
const uint8_t * src [ 4 ] ;
uint8_t * dst [ 4 ] ;
int linesizes [ 4 ] ;
int sub_h = s - > input_views [ i ] - > height > > s - > pix_desc - > log2_chroma_h ;
src [ 0 ] = s - > input_views [ i ] - > data [ 0 ] ;
src [ 1 ] = s - > input_views [ i ] - > data [ 1 ] ;
src [ 2 ] = s - > input_views [ i ] - > data [ 2 ] ;
dst [ 0 ] = out - > data [ 0 ] + i * out - > linesize [ 0 ] *
( interleaved + s - > input_views [ i ] - > height * ( 1 - interleaved ) ) ;
dst [ 1 ] = out - > data [ 1 ] + i * out - > linesize [ 1 ] *
( interleaved + sub_h * ( 1 - interleaved ) ) ;
dst [ 2 ] = out - > data [ 2 ] + i * out - > linesize [ 2 ] *
( interleaved + sub_h * ( 1 - interleaved ) ) ;
linesizes [ 0 ] = out - > linesize [ 0 ] +
interleaved * out - > linesize [ 0 ] ;
linesizes [ 1 ] = out - > linesize [ 1 ] +
interleaved * out - > linesize [ 1 ] ;
linesizes [ 2 ] = out - > linesize [ 2 ] +
interleaved * out - > linesize [ 2 ] ;
av_image_copy ( dst , linesizes , src , s - > input_views [ i ] - > linesize ,
s - > input_views [ i ] - > format ,
s - > input_views [ i ] - > width ,
s - > input_views [ i ] - > height ) ;
}
}
static av_always_inline void spatial_frame_pack ( FramepackContext * s , AVFrame * dst )
static av_always_inline void spatial_frame_pack ( AVFilterLink * outlink ,
AVFrame * dst )
{
AVFilterContext * ctx = outlink - > src ;
FramepackContext * s = ctx - > priv ;
switch ( s - > format ) {
case AV_STEREO3D_SIDEBYSIDE :
horizontal_frame_pack ( s , dst , 0 ) ;
horizontal_frame_pack ( outlink , dst , 0 ) ;
break ;
case AV_STEREO3D_COLUMNS :
horizontal_frame_pack ( s , dst , 1 ) ;
horizontal_frame_pack ( outlink , dst , 1 ) ;
break ;
case AV_STEREO3D_TOPBOTTOM :
vertical_frame_pack ( s , dst , 0 ) ;
vertical_frame_pack ( outlink , dst , 0 ) ;
break ;
case AV_STEREO3D_LINES :
vertical_frame_pack ( s , dst , 1 ) ;
vertical_frame_pack ( outlink , dst , 1 ) ;
break ;
}
}
@ -276,7 +311,7 @@ static int request_frame(AVFilterLink *outlink)
if ( ! dst )
return AVERROR ( ENOMEM ) ;
spatial_frame_pack ( s , dst ) ;
spatial_frame_pack ( outlink , dst ) ;
// get any property from the original frame
ret = av_frame_copy_props ( dst , s - > input_views [ LEFT ] ) ;