Commit d6e6460d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

filter_chain: introduce dedicated filter_chain_NewVideo() for video filters

Also remove the filter chain buffer functions update hack, keep constant
callbacks for video filters in the filter chain, remove now useless
parameters from filter_chain_New(), and inline
filter_chain_AppendFilterInternal().
parent 6650b321
...@@ -297,13 +297,25 @@ typedef struct filter_chain_t filter_chain_t; ...@@ -297,13 +297,25 @@ typedef struct filter_chain_t filter_chain_t;
* \param p_object pointer to a vlc object * \param p_object pointer to a vlc object
* \param psz_capability vlc capability of filters in filter chain * \param psz_capability vlc capability of filters in filter chain
* \param b_allow_format_fmt_change allow changing of fmt * \param b_allow_format_fmt_change allow changing of fmt
* \param pf_buffer_allocation_init callback function to initialize buffer allocations
* \param pf_buffer_allocation_clear callback function to clear buffer allocation initialization
* \param p_buffer_allocation_data pointer to private allocation data
* \return pointer to a filter chain * \return pointer to a filter chain
*/ */
VLC_API filter_chain_t * filter_chain_New( vlc_object_t *, const char *, bool, int (*)( filter_t *, void * ), void (*)( filter_t * ), void * ) VLC_USED; VLC_API filter_chain_t * filter_chain_New( vlc_object_t *, const char *, bool )
#define filter_chain_New( a, b, c, d, e, f ) filter_chain_New( VLC_OBJECT( a ), b, c, d, e, f ) VLC_USED;
#define filter_chain_New( a, b, c ) filter_chain_New( VLC_OBJECT( a ), b, c )
/**
* Creates a new video filter chain.
*
* \param obj pointer to parent VLC object
* \param change whether to allow changing the output format
* \param owner owner video buffer callbacks
* \return new filter chain, or NULL on error
*/
VLC_API filter_chain_t * filter_chain_NewVideo( vlc_object_t *obj, bool change,
const filter_owner_t *owner )
VLC_USED;
#define filter_chain_NewVideo( a, b, c ) \
filter_chain_NewVideo( VLC_OBJECT( a ), b, c )
/** /**
* Delete filter chain will delete all filters in the chain and free all * Delete filter chain will delete all filters in the chain and free all
......
...@@ -274,14 +274,6 @@ static void Close( vlc_object_t * p_this ) ...@@ -274,14 +274,6 @@ static void Close( vlc_object_t * p_this )
free( p_sys ); free( p_sys );
} }
static int video_filter_buffer_allocation_init( filter_t *p_filter, void *p_data )
{
p_filter->owner.sys = p_data;
p_filter->owner.video.buffer_new = video_new_buffer_filter;
p_filter->owner.video.buffer_del = video_del_buffer_filter;
return VLC_SUCCESS;
}
static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt ) static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
{ {
sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_sys_t *p_sys = p_stream->p_sys;
...@@ -400,9 +392,15 @@ static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt ) ...@@ -400,9 +392,15 @@ static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
msg_Dbg( p_stream, "psz_chain: %s", psz_chain ); msg_Dbg( p_stream, "psz_chain: %s", psz_chain );
if( psz_chain ) if( psz_chain )
{ {
p_sys->p_vf2 = filter_chain_New( p_stream, "video filter2", false, filter_owner_t owner = {
video_filter_buffer_allocation_init, .sys = p_sys->p_decoder->p_owner,
NULL, p_sys->p_decoder->p_owner ); .video = {
.buffer_new = video_new_buffer_filter,
.buffer_del = video_del_buffer_filter,
},
};
p_sys->p_vf2 = filter_chain_NewVideo( p_stream, false, &owner );
es_format_t fmt; es_format_t fmt;
es_format_Copy( &fmt, &p_sys->p_decoder->fmt_out ); es_format_Copy( &fmt, &p_sys->p_decoder->fmt_out );
if( p_sys->i_chroma ) if( p_sys->i_chroma )
......
...@@ -77,21 +77,13 @@ static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter ) ...@@ -77,21 +77,13 @@ static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter )
p_filter->fmt_out.video.i_chroma = p_filter->fmt_out.i_codec; p_filter->fmt_out.video.i_chroma = p_filter->fmt_out.i_codec;
return picture_NewFromFormat( &p_filter->fmt_out.video ); return picture_NewFromFormat( &p_filter->fmt_out.video );
} }
static void transcode_video_filter_buffer_del( filter_t *p_filter, picture_t *p_pic ) static void transcode_video_filter_buffer_del( filter_t *p_filter, picture_t *p_pic )
{ {
VLC_UNUSED(p_filter); VLC_UNUSED(p_filter);
picture_Release( p_pic ); picture_Release( p_pic );
} }
static int transcode_video_filter_allocation_init( filter_t *p_filter,
void *p_data )
{
VLC_UNUSED(p_data);
p_filter->owner.video.buffer_new = transcode_video_filter_buffer_new;
p_filter->owner.video.buffer_del = transcode_video_filter_buffer_del;
return VLC_SUCCESS;
}
static void* EncoderThread( void *obj ) static void* EncoderThread( void *obj )
{ {
sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj; sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj;
...@@ -293,13 +285,17 @@ int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id ) ...@@ -293,13 +285,17 @@ int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
static void transcode_video_filter_init( sout_stream_t *p_stream, static void transcode_video_filter_init( sout_stream_t *p_stream,
sout_stream_id_sys_t *id ) sout_stream_id_sys_t *id )
{ {
filter_owner_t owner = {
.sys = p_stream->p_sys,
.video = {
.buffer_new = transcode_video_filter_buffer_new,
.buffer_del = transcode_video_filter_buffer_del,
},
};
es_format_t *p_fmt_out = &id->p_decoder->fmt_out; es_format_t *p_fmt_out = &id->p_decoder->fmt_out;
id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
id->p_f_chain = filter_chain_New( p_stream, "video filter2", id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
false, id->p_f_chain = filter_chain_New( p_stream, false, &owner );
transcode_video_filter_allocation_init,
NULL, p_stream->p_sys );
filter_chain_Reset( id->p_f_chain, p_fmt_out, p_fmt_out ); filter_chain_Reset( id->p_f_chain, p_fmt_out, p_fmt_out );
/* Deinterlace */ /* Deinterlace */
...@@ -322,10 +318,7 @@ static void transcode_video_filter_init( sout_stream_t *p_stream, ...@@ -322,10 +318,7 @@ static void transcode_video_filter_init( sout_stream_t *p_stream,
if( p_stream->p_sys->psz_vf2 ) if( p_stream->p_sys->psz_vf2 )
{ {
id->p_uf_chain = filter_chain_New( p_stream, "video filter2", id->p_uf_chain = filter_chain_New( p_stream, true, &owner );
true,
transcode_video_filter_allocation_init,
NULL, p_stream->p_sys );
filter_chain_Reset( id->p_uf_chain, p_fmt_out, filter_chain_Reset( id->p_uf_chain, p_fmt_out,
&id->p_encoder->fmt_in ); &id->p_encoder->fmt_in );
if( p_fmt_out->video.i_chroma != id->p_encoder->fmt_in.video.i_chroma ) if( p_fmt_out->video.i_chroma != id->p_encoder->fmt_in.video.i_chroma )
......
...@@ -49,7 +49,6 @@ vlc_module_end () ...@@ -49,7 +49,6 @@ vlc_module_end ()
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
static picture_t *Chain ( filter_t *, picture_t * ); static picture_t *Chain ( filter_t *, picture_t * );
static int BufferAllocationInit ( filter_t *, void * );
static int BuildTransformChain( filter_t *p_filter ); static int BuildTransformChain( filter_t *p_filter );
static int BuildChromaResize( filter_t * ); static int BuildChromaResize( filter_t * );
...@@ -74,6 +73,23 @@ struct filter_sys_t ...@@ -74,6 +73,23 @@ struct filter_sys_t
filter_chain_t *p_chain; filter_chain_t *p_chain;
}; };
/*****************************************************************************
* Buffer management
*****************************************************************************/
static picture_t *BufferNew( filter_t *p_filter )
{
filter_t *p_parent = p_filter->owner.sys;
return filter_NewPicture( p_parent );
}
static void BufferDel( filter_t *p_filter, picture_t *p_pic )
{
filter_t *p_parent = p_filter->owner.sys;
filter_DeletePicture( p_parent, p_pic );
}
#define CHAIN_LEVEL_MAX 1 #define CHAIN_LEVEL_MAX 1
/***************************************************************************** /*****************************************************************************
...@@ -99,7 +115,15 @@ static int Activate( vlc_object_t *p_this ) ...@@ -99,7 +115,15 @@ static int Activate( vlc_object_t *p_this )
if( !p_sys ) if( !p_sys )
return VLC_ENOMEM; return VLC_ENOMEM;
p_sys->p_chain = filter_chain_New( p_filter, "video filter2", false, BufferAllocationInit, NULL, p_filter ); filter_owner_t owner = {
.sys = p_filter,
.video = {
.buffer_new = BufferNew,
.buffer_del = BufferDel,
},
};
p_sys->p_chain = filter_chain_NewVideo( p_filter, false, &owner );
if( !p_sys->p_chain ) if( !p_sys->p_chain )
{ {
free( p_sys ); free( p_sys );
...@@ -261,31 +285,6 @@ exit: ...@@ -261,31 +285,6 @@ exit:
return i_ret; return i_ret;
} }
/*****************************************************************************
* Buffer management
*****************************************************************************/
static picture_t *BufferNew( filter_t *p_filter )
{
filter_t *p_parent = p_filter->owner.sys;
return filter_NewPicture( p_parent );
}
static void BufferDel( filter_t *p_filter, picture_t *p_pic )
{
filter_t *p_parent = p_filter->owner.sys;
filter_DeletePicture( p_parent, p_pic );
}
static int BufferAllocationInit ( filter_t *p_filter, void *p_data )
{
p_filter->owner.sys = p_data;
p_filter->owner.video.buffer_new = BufferNew;
p_filter->owner.video.buffer_del = BufferDel;
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* *
*****************************************************************************/ *****************************************************************************/
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
static int Activate( vlc_object_t * ); static int Activate( vlc_object_t * );
static void Destroy( vlc_object_t * ); static void Destroy( vlc_object_t * );
static picture_t *Filter( filter_t *, picture_t * ); static picture_t *Filter( filter_t *, picture_t * );
static int alloc_init( filter_t *, void * );
/* This module effectively implements a form of picture-in-picture. /* This module effectively implements a form of picture-in-picture.
* - The outer picture is called the canvas. * - The outer picture is called the canvas.
...@@ -132,6 +131,16 @@ struct filter_sys_t ...@@ -132,6 +131,16 @@ struct filter_sys_t
filter_chain_t *p_chain; filter_chain_t *p_chain;
}; };
static picture_t *video_new( filter_t *p_filter )
{
return filter_NewPicture( p_filter->owner.sys );
}
static void video_del( filter_t *p_filter, picture_t *p_pic )
{
return filter_DeletePicture( p_filter->owner.sys, p_pic );
}
/***************************************************************************** /*****************************************************************************
* *
*****************************************************************************/ *****************************************************************************/
...@@ -226,8 +235,15 @@ static int Activate( vlc_object_t *p_this ) ...@@ -226,8 +235,15 @@ static int Activate( vlc_object_t *p_this )
return VLC_ENOMEM; return VLC_ENOMEM;
p_filter->p_sys = p_sys; p_filter->p_sys = p_sys;
p_sys->p_chain = filter_chain_New( p_filter, "video filter2", true, filter_owner_t owner = {
alloc_init, NULL, p_filter ); .sys = p_filter,
.video = {
.buffer_new = video_new,
.buffer_del = video_del,
},
};
p_sys->p_chain = filter_chain_NewVideo( p_filter, true, &owner );
if( !p_sys->p_chain ) if( !p_sys->p_chain )
{ {
msg_Err( p_filter, "Could not allocate filter chain" ); msg_Err( p_filter, "Could not allocate filter chain" );
...@@ -364,24 +380,3 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_pic ) ...@@ -364,24 +380,3 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{ {
return filter_chain_VideoFilter( p_filter->p_sys->p_chain, p_pic ); return filter_chain_VideoFilter( p_filter->p_sys->p_chain, p_pic );
} }
/*****************************************************************************
*
*****************************************************************************/
static picture_t *video_new( filter_t *p_filter )
{
return filter_NewPicture( p_filter->owner.sys );
}
static void video_del( filter_t *p_filter, picture_t *p_pic )
{
return filter_DeletePicture( p_filter->owner.sys, p_pic );
}
static int alloc_init( filter_t *p_filter, void *p_data )
{
p_filter->owner.sys = p_data;
p_filter->owner.video.buffer_new = video_new;
p_filter->owner.video.buffer_del = video_del;
return VLC_SUCCESS;
}
...@@ -127,6 +127,7 @@ filter_chain_GetLength ...@@ -127,6 +127,7 @@ filter_chain_GetLength
filter_chain_MouseFilter filter_chain_MouseFilter
filter_chain_MouseEvent filter_chain_MouseEvent
filter_chain_New filter_chain_New
filter_chain_NewVideo
filter_chain_Reset filter_chain_Reset
filter_chain_SubFilter filter_chain_SubFilter
filter_chain_VideoFilter filter_chain_VideoFilter
......
This diff is collapsed.
...@@ -65,20 +65,13 @@ static picture_t *VideoBufferNew(filter_t *filter) ...@@ -65,20 +65,13 @@ static picture_t *VideoBufferNew(filter_t *filter)
return NULL; return NULL;
return picture_pool_Get(pool); return picture_pool_Get(pool);
} }
static void VideoBufferDelete(filter_t *filter, picture_t *picture) static void VideoBufferDelete(filter_t *filter, picture_t *picture)
{ {
VLC_UNUSED(filter); VLC_UNUSED(filter);
picture_Release(picture); picture_Release(picture);
} }
static int FilterAllocationInit(filter_t *filter, void *vd)
{
filter->owner.sys = vd;
filter->owner.video.buffer_new = VideoBufferNew;
filter->owner.video.buffer_del = VideoBufferDelete;
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* *
*****************************************************************************/ *****************************************************************************/
...@@ -458,8 +451,15 @@ static void VoutDisplayCreateRender(vout_display_t *vd) ...@@ -458,8 +451,15 @@ static void VoutDisplayCreateRender(vout_display_t *vd)
msg_Dbg(vd, "A filter to adapt decoder to display is needed"); msg_Dbg(vd, "A filter to adapt decoder to display is needed");
osys->filters = filter_chain_New(vd, "video filter2", false, filter_owner_t owner = {
FilterAllocationInit, NULL, vd); .sys = vd,
.video = {
.buffer_new = VideoBufferNew,
.buffer_del = VideoBufferDelete,
},
};
osys->filters = filter_chain_NewVideo(vd, false, &owner);
assert(osys->filters); /* TODO critical */ assert(osys->filters); /* TODO critical */
/* */ /* */
......
...@@ -696,22 +696,6 @@ static void VoutVideoFilterDelPicture(filter_t *filter, picture_t *picture) ...@@ -696,22 +696,6 @@ static void VoutVideoFilterDelPicture(filter_t *filter, picture_t *picture)
picture_Release(picture); picture_Release(picture);
} }
static int VoutVideoFilterStaticAllocationSetup(filter_t *filter, void *data)
{
filter->owner.sys = data; /* vout */
filter->owner.video.buffer_new = VoutVideoFilterStaticNewPicture;
filter->owner.video.buffer_del = VoutVideoFilterDelPicture;
return VLC_SUCCESS;
}
static int VoutVideoFilterInteractiveAllocationSetup(filter_t *filter, void *data)
{
filter->owner.sys = data; /* vout */
filter->owner.video.buffer_new = VoutVideoFilterInteractiveNewPicture;
filter->owner.video.buffer_del = VoutVideoFilterDelPicture;
return VLC_SUCCESS;
}
static void ThreadFilterFlush(vout_thread_t *vout, bool is_locked) static void ThreadFilterFlush(vout_thread_t *vout, bool is_locked)
{ {
if (vout->p->displayed.current) if (vout->p->displayed.current)
...@@ -1330,12 +1314,20 @@ static int ThreadStart(vout_thread_t *vout, const vout_display_state_t *state) ...@@ -1330,12 +1314,20 @@ static int ThreadStart(vout_thread_t *vout, const vout_display_state_t *state)
vout->p->filter.configuration = NULL; vout->p->filter.configuration = NULL;
video_format_Copy(&vout->p->filter.format, &vout->p->original); video_format_Copy(&vout->p->filter.format, &vout->p->original);
filter_owner_t owner = {
.sys = vout,
.video = {
.buffer_new = VoutVideoFilterStaticNewPicture,
.buffer_del = VoutVideoFilterDelPicture,
},
};
vout->p->filter.chain_static = vout->p->filter.chain_static =
filter_chain_New( vout, "video filter2", true, filter_chain_NewVideo( vout, true, &owner );
VoutVideoFilterStaticAllocationSetup, NULL, vout);
owner.video.buffer_new = VoutVideoFilterInteractiveNewPicture;
vout->p->filter.chain_interactive = vout->p->filter.chain_interactive =
filter_chain_New( vout, "video filter2", true, filter_chain_NewVideo( vout, true, &owner );
VoutVideoFilterInteractiveAllocationSetup, NULL, vout);
vout_display_state_t state_default; vout_display_state_t state_default;
if (!state) { if (!state) {
......
...@@ -1227,10 +1227,8 @@ spu_t *spu_Create(vlc_object_t *object) ...@@ -1227,10 +1227,8 @@ spu_t *spu_Create(vlc_object_t *object)
sys->filter_chain_update = NULL; sys->filter_chain_update = NULL;
vlc_mutex_init(&sys->source_chain_lock); vlc_mutex_init(&sys->source_chain_lock);
vlc_mutex_init(&sys->filter_chain_lock); vlc_mutex_init(&sys->filter_chain_lock);
sys->source_chain = filter_chain_New(spu, "sub source", false, sys->source_chain = filter_chain_New(spu, "sub source", false);
NULL, NULL, NULL); sys->filter_chain = filter_chain_New(spu, "sub filter", false);
sys->filter_chain = filter_chain_New(spu, "sub filter", false,
NULL, NULL, NULL);
/* Load text and scale module */ /* Load text and scale module */
sys->text = SpuRenderCreateAndLoadText(spu); sys->text = SpuRenderCreateAndLoadText(spu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment