@ -149,13 +149,15 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int
return ret ;
}
void ff_null_start_frame ( AVFilterLink * link , AVFilterBufferRef * picref )
int ff_null_start_frame ( AVFilterLink * link , AVFilterBufferRef * picref )
{
AVFilterBufferRef * buf_out = avfilter_ref_buffer ( picref , ~ 0 ) ;
ff_start_frame ( link - > dst - > outputs [ 0 ] , buf_out ) ;
if ( ! buf_out )
return AVERROR ( ENOMEM ) ;
return ff_start_frame ( link - > dst - > outputs [ 0 ] , buf_out ) ;
}
static void default_start_frame ( AVFilterLink * inlink , AVFilterBufferRef * picref )
static int default_start_frame ( AVFilterLink * inlink , AVFilterBufferRef * picref )
{
AVFilterLink * outlink = NULL ;
@ -163,21 +165,37 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
outlink = inlink - > dst - > outputs [ 0 ] ;
if ( outlink ) {
AVFilterBufferRef * buf_out ;
outlink - > out_buf = ff_get_video_buffer ( outlink , AV_PERM_WRITE , outlink - > w , outlink - > h ) ;
if ( ! outlink - > out_buf )
return AVERROR ( ENOMEM ) ;
avfilter_copy_buffer_ref_props ( outlink - > out_buf , picref ) ;
outlink - > out_buf - > video - > w = outlink - > w ;
outlink - > out_buf - > video - > h = outlink - > h ;
ff_start_frame ( outlink , avfilter_ref_buffer ( outlink - > out_buf , ~ 0 ) ) ;
buf_out = avfilter_ref_buffer ( outlink - > out_buf , ~ 0 ) ;
if ( ! buf_out )
return AVERROR ( ENOMEM ) ;
return ff_start_frame ( outlink , buf_out ) ;
}
return 0 ;
}
static void clear_link ( AVFilterLink * link )
{
avfilter_unref_bufferp ( & link - > cur_buf ) ;
avfilter_unref_bufferp ( & link - > src_buf ) ;
avfilter_unref_bufferp ( & link - > out_buf ) ;
}
/* XXX: should we do the duplicating of the picture ref here, instead of
* forcing the source filter to do it ? */
void ff_start_frame ( AVFilterLink * link , AVFilterBufferRef * picref )
int ff_start_frame ( AVFilterLink * link , AVFilterBufferRef * picref )
{
void ( * start_frame ) ( AVFilterLink * , AVFilterBufferRef * ) ;
int ( * start_frame ) ( AVFilterLink * , AVFilterBufferRef * ) ;
AVFilterPad * dst = link - > dstpad ;
int perms = picref - > perms ;
int ret , perms = picref - > perms ;
AVFilterCommand * cmd = link - > dst - > command_queue ;
int64_t pts ;
@ -196,6 +214,11 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
link - > dstpad - > min_perms , link - > dstpad - > rej_perms ) ;
link - > cur_buf = ff_get_video_buffer ( link , dst - > min_perms , link - > w , link - > h ) ;
if ( ! link - > cur_buf ) {
avfilter_unref_bufferp ( & picref ) ;
return AVERROR ( ENOMEM ) ;
}
link - > src_buf = picref ;
avfilter_copy_buffer_ref_props ( link - > cur_buf , link - > src_buf ) ;
@ -215,22 +238,26 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
cmd = link - > dst - > command_queue ;
}
pts = link - > cur_buf - > pts ;
start_frame ( link , link - > cur_buf ) ;
ret = start_frame ( link , link - > cur_buf ) ;
ff_update_link_current_pts ( link , link - > cur_buf ? link - > cur_buf - > pts : pts ) ;
if ( ret < 0 )
clear_link ( link ) ;
return ret ;
}
void ff_null_start_frame_keep_ref ( AVFilterLink * inlink ,
int ff_null_start_frame_keep_ref ( AVFilterLink * inlink ,
AVFilterBufferRef * picref )
{
ff_start_frame ( inlink - > dst - > outputs [ 0 ] , avfilter_ref_buffer ( picref , ~ 0 ) ) ;
return ff_start_frame ( inlink - > dst - > outputs [ 0 ] , avfilter_ref_buffer ( picref , ~ 0 ) ) ;
}
void ff_null_end_frame ( AVFilterLink * link )
int ff_null_end_frame ( AVFilterLink * link )
{
ff_end_frame ( link - > dst - > outputs [ 0 ] ) ;
return ff_end_frame ( link - > dst - > outputs [ 0 ] ) ;
}
static void default_end_frame ( AVFilterLink * inlink )
static int default_end_frame ( AVFilterLink * inlink )
{
AVFilterLink * outlink = NULL ;
@ -238,37 +265,32 @@ static void default_end_frame(AVFilterLink *inlink)
outlink = inlink - > dst - > outputs [ 0 ] ;
if ( outlink ) {
ff_end_frame ( outlink ) ;
return ff_end_frame ( outlink ) ;
}
return 0 ;
}
void ff_end_frame ( AVFilterLink * link )
int ff_end_frame ( AVFilterLink * link )
{
void ( * end_frame ) ( AVFilterLink * ) ;
int ( * end_frame ) ( AVFilterLink * ) ;
int ret ;
if ( ! ( end_frame = link - > dstpad - > end_frame ) )
end_frame = default_end_frame ;
end_frame ( link ) ;
ret = end_frame ( link ) ;
/* unreference the source picture if we're feeding the destination filter
* a copied version dues to permission issues */
if ( link - > src_buf ) {
avfilter_unref_buffer ( link - > src_buf ) ;
link - > src_buf = NULL ;
}
if ( link - > cur_buf ! = link - > out_buf )
avfilter_unref_bufferp ( & link - > cur_buf ) ;
link - > cur_buf = NULL ;
avfilter_unref_bufferp ( & link - > out_buf ) ;
clear_link ( link ) ;
return ret ;
}
void ff_null_draw_slice ( AVFilterLink * link , int y , int h , int slice_dir )
int ff_null_draw_slice ( AVFilterLink * link , int y , int h , int slice_dir )
{
ff_draw_slice ( link - > dst - > outputs [ 0 ] , y , h , slice_dir ) ;
return ff_draw_slice ( link - > dst - > outputs [ 0 ] , y , h , slice_dir ) ;
}
static void default_draw_slice ( AVFilterLink * inlink , int y , int h , int slice_dir )
static int default_draw_slice ( AVFilterLink * inlink , int y , int h , int slice_dir )
{
AVFilterLink * outlink = NULL ;
@ -276,14 +298,15 @@ static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir
outlink = inlink - > dst - > outputs [ 0 ] ;
if ( outlink )
ff_draw_slice ( outlink , y , h , slice_dir ) ;
return ff_draw_slice ( outlink , y , h , slice_dir ) ;
return 0 ;
}
void ff_draw_slice ( AVFilterLink * link , int y , int h , int slice_dir )
int ff_draw_slice ( AVFilterLink * link , int y , int h , int slice_dir )
{
uint8_t * src [ 4 ] , * dst [ 4 ] ;
int i , j , vsub ;
void ( * draw_slice ) ( AVFilterLink * , int , int , int ) ;
int i , j , vsub , ret ;
int ( * draw_slice ) ( AVFilterLink * , int , int , int ) ;
FF_TPRINTF_START ( NULL , draw_slice ) ; ff_tlog_link ( NULL , link , 0 ) ; ff_tlog ( NULL , " y:%d h:%d dir:%d \n " , y , h , slice_dir ) ;
@ -317,11 +340,14 @@ void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if ( ! ( draw_slice = link - > dstpad - > draw_slice ) )
draw_slice = default_draw_slice ;
draw_slice ( link , y , h , slice_dir ) ;
ret = draw_slice ( link , y , h , slice_dir ) ;
if ( ret < 0 )
clear_link ( link ) ;
return ret ;
}
void avfilter_default_end_frame ( AVFilterLink * inlink )
int avfilter_default_end_frame ( AVFilterLink * inlink )
{
default_end_frame ( inlink ) ;
return default_end_frame ( inlink ) ;
}