Commit b28eb687 authored by Antoine Cellerier's avatar Antoine Cellerier

Port chain filter to new API. Now supports chaining of chroma conversion and...

Port chain filter to new API. Now supports chaining of chroma conversion and scaling operations. Integration of crop/padding still needs to be done. This might need to be moved in the core.
parent f4c4d8d2
......@@ -78,7 +78,3 @@ SOURCES_yuy2_i422 = \
SOURCES_yuy2_i420 = \
yuy2_i420.c \
$(NULL)
SOURCES_chroma_chain = \
chain.c \
$(NULL)
......@@ -38,4 +38,5 @@ SOURCES_grain = grain.c
SOURCES_seamcarving = seamcarving.c
SOURCES_croppadd = croppadd.c
SOURCES_blendbench = blendbench.c
SOURCES_chain = chain.c
noinst_HEADERS = filter_common.h filter_picture.h
/*****************************************************************************
* chain.c : chain multiple chroma modules as a last resort solution
* chain.c : chain multiple video filter modules as a last resort solution
*****************************************************************************
* Copyright (C) 2007-2008 the VideoLAN team
* $Id$
......@@ -37,29 +37,27 @@
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static int Activate ( vlc_object_t * );
static void Destroy ( vlc_object_t * );
static void Chain ( filter_t *, picture_t *, picture_t * );
static int Activate ( vlc_object_t * );
static void Destroy ( vlc_object_t * );
static picture_t *Chain( filter_t *, picture_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( N_("Chroma conversions using a chain of chroma conversion modules") );
set_description( N_("Video filtering using a chain of video filter modules") );
set_capability( "video filter2", 1 );
set_callbacks( Activate, Destroy );
vlc_module_end();
#define MAX_CHROMAS 2
#define MAX_FILTERS 4
struct filter_sys_t
{
vlc_fourcc_t i_chroma;
filter_t *p_chroma1;
filter_t *p_chroma2;
picture_t *p_tmp;
filter_t *p_filter1; /* conversion from fmt_in to fmr_mid */
filter_t *p_filter2; /* conversion from fmt_mid to fmt_out */
picture_t *p_tmp; /* temporary picture buffer */
video_format_t fmt_mid;
};
static const vlc_fourcc_t pi_allowed_chromas[] = {
......@@ -70,6 +68,59 @@ static const vlc_fourcc_t pi_allowed_chromas[] = {
0
};
static picture_t *get_pic( filter_t *p_filter )
{
picture_t *p_pic = (picture_t *)p_filter->p_owner;
p_filter->p_owner = NULL;
return p_pic;
}
/* FIXME: this is almost like DeleteFilter in src/misc/image.c */
static void DeleteFilter( filter_t *p_filter )
{
vlc_object_detach( p_filter );
if( p_filter->p_module ) module_Unneed( p_filter, p_filter->p_module );
vlc_object_release( p_filter );
}
/* FIXME: this is almost like CreateFilter in src/misc/image.c */
static filter_t *CreateFilter( vlc_object_t *p_this, video_format_t *fmt_in,
video_format_t *fmt_out )
{
filter_t *p_filter = vlc_object_create( p_this, VLC_OBJECT_FILTER );
vlc_object_attach( p_filter, p_this );
p_filter->pf_vout_buffer_new = get_pic;
p_filter->fmt_in = *fmt_in;
p_filter->fmt_out = *fmt_out;
p_filter->p_module = module_Need( p_filter, "video filter2", NULL, 0 );
if( !p_filter->p_module )
{
DeleteFilter( p_filter );
return NULL;
}
return p_filter;
}
static int CreateChain( vlc_object_t *p_this, filter_sys_t *p_sys )
{
p_sys->p_filter1 = CreateFilter( p_this, &p_filter->fmt_in.video,
&p_sys->fmt_mid );
if( p_sys->p_filter1 )
{
p_sys->p_filter2 = CreateFilter( p_this, &p_sys->fmt_mid,
&p_filter->fmt_out.video );
if( p_sys->p_filter2 )
return VLC_SUCCESS;
DeleteFilter( p_sys->p_filter1 );
}
return VLC_EGENERIC;
}
/*****************************************************************************
* Activate: allocate a chroma function
*****************************************************************************
......@@ -77,15 +128,16 @@ static const vlc_fourcc_t pi_allowed_chromas[] = {
*****************************************************************************/
static int Activate( vlc_object_t *p_this )
{
#if 0
static int hack = 1;
filter_t *p_filter = (filter_t *)p_this;
static int hack = 0; /* FIXME */
if( p_filter->fmt_in.video.i_chroma == p_filter->fmt_out.video.i_chroma )
return VLC_EGENERIC;
hack++;
if( hack > MAX_CHROMAS )
if( hack >= MAX_FILTERS )
{
hack--;
msg_Err( p_this, "Preventing chain chroma reccursion (already %d long)",
msg_Err( p_this, "Preventing chain filter reccursion (already %d long)",
hack );
return VLC_EGENERIC;
}
......@@ -97,105 +149,100 @@ static int Activate( vlc_object_t *p_this )
return VLC_ENOMEM;
}
memset( p_sys, 0, sizeof( filter_sys_t ) );
p_filter->p_sys = p_sys;
int i;
vlc_fourcc_t i_output_chroma = p_filter->fmt_in.video.i_chroma;
vlc_fourcc_t i_render_chroma = p_filter->fmt_out.video.i_chroma;
for( i = 0; pi_allowed_chromas[i]; i++ )
if( p_filter->fmt_in.i_width != p_filter->fmt_out.i_width ||
p_filter->fmt_in.i_height != p_filter->fmt_out.i_height ||
p_filter->fmt_in.i_visible_width != p_filter->fmt_out.i_visible_width ||
p_filter->fmt_in.i_visible_height != p_filter->fmt_out.i_visible_height )
{
msg_Warn( p_filter, "Trying %4s as a chroma chain",
(const char *)&pi_allowed_chromas[i] );
p_filter->output.i_chroma = pi_allowed_chromas[i];
p_filter->p_chroma1.p_module = module_Need( p_vout, "chroma", NULL, 0 );
p_filter->output.i_chroma = i_output_chroma;
if( !p_vout->chroma.p_module )
continue;
p_sys->chroma1 = p_vout->chroma;
memset( &p_vout->chroma, 0, sizeof( vout_chroma_t ) );
p_vout->render.i_chroma = pi_allowed_chromas[i];
p_vout->chroma.p_module = module_Need( p_vout, "chroma", NULL, 0 );
p_vout->render.i_chroma = i_render_chroma;
if( !p_vout->chroma.p_module )
/* Lets try resizing and then doing the chroma conversion */
p_sys->fmt_mid = p_filter->fmt_out.video;
p_sys->fmt_mid.i_chroma = p_filter->fmt_in.video.i_chroma;
if( CreateChain( p_this, p_sys ) == VLC_SUCCESS )
return VLC_SUCCESS;
/* Lets try it the other way arround (chroma and then resize) */
p_sys->fmt_mid = p_filter->fmt_in.video;
p_sys->fmt_mid.i_chroma = p_filter->fmt_out.video.i_chroma;
if( CreateChain( p_this, p_sys ) == VLC_SUCCESS )
return VLC_SUCCESS;
}
else
{
/* Lets try doing a chroma chain */
int i;
p_sys->fmt_mid = p_filter->fmt_in.video;
for( i = 0; pi_allowed_chomas[i]; i++ )
{
p_vout->chroma = p_sys->chroma1;
module_Unneed( p_vout, p_vout->chroma.p_module );
continue;
p_sys->fmt_mid.i_chroma = pi_allowed_chromas[i];
if( CreateChain( p_this, p_sys ) == VLC_SUCCESS )
return VLC_SUCCESS;
}
p_sys->chroma2 = p_vout->chroma;
memset( &p_vout->chroma, 0, sizeof( vout_chroma_t ) );
p_sys->i_chroma = pi_allowed_chromas[i];
p_vout->chroma.pf_convert = Chain;
p_vout->chroma.p_sys = p_sys;
hack--;
printf("Init: p_sys->p_tmp= %p\n", p_sys->p_tmp );
return VLC_SUCCESS;
}
/* Hum ... looks like this really isn't going to work. Too bad. */
free( p_sys );
hack--;
#endif
return VLC_EGENERIC;
}
static void Destroy( vlc_object_t *p_this )
{
#if 0
filter_t *p_filter = (filter_t *)p_this;
vout_chroma_t chroma = p_vout->chroma;
p_vout->chroma = chroma.p_sys->chroma1;
module_Unneed( p_vout, p_vout->chroma.p_module );
p_vout->chroma = chroma.p_sys->chroma2;
module_Unneed( p_vout, p_vout->chroma.p_module );
p_vout->chroma = chroma;
DeleteFilter( p_filter->p_sys->filter1 );
DeleteFilter( p_filter->p_sys->filter2 );
if( chroma.p_sys->p_tmp )
if( p_filter->p_sys->p_tmp )
{
free( chroma.p_sys->p_tmp->p_data_orig );
free( chroma.p_sys->p_tmp );
free( p_filter->p_sys->p_tmp->p_data_orig );
free( p_filter->p_sys->p_tmp );
}
free( chroma.p_sys );
chroma.p_sys = NULL;
#endif
free( p_filter->p_sys );
}
/*****************************************************************************
* Chain
*****************************************************************************/
static void Chain( filter_t *p_filter, picture_t *p_source,
picture_t *p_dest )
static picture_t *Chain( filter_t *p_filter, picture_t *p_pic )
{
#if 0
chroma_sys_t *p_sys = p_vout->chroma.p_sys;
picture_t *p_outpic = p_filter->pf_vout_buffer_new( p_filter );
if( !p_outpic )
{
msg_Warn( p_filter, "can't get output picture" );
if( p_pic->pf_release )
p_pic->pf_release( p_pic );
return NULL;
}
if( !p_sys->p_tmp )
{
picture_t *p_tmp = malloc( sizeof( picture_t ) );
vout_AllocatePicture( VLC_OBJECT( p_vout ), p_tmp,
p_sys->i_chroma,
p_source->p_heap->i_width,
p_source->p_heap->i_height,
p_source->p_heap->i_aspect );
p_sys->fmt_mid.i_chroma,
p_sys->fmt_mid.i_width,
p_sys->fmt_mid.i_height,
p_sys->fmt_mid.i_aspect );
if( !p_tmp )
return;
return NULL;
p_sys->p_tmp = p_tmp;
p_tmp->pf_release = NULL;
p_tmp->i_status = RESERVED_PICTURE;
p_tmp->p_sys = NULL;
}
vout_chroma_t chroma = p_vout->chroma;
p_vout->chroma = p_sys->chroma1;
p_sys->chroma1.pf_convert( p_vout, p_source, p_sys->p_tmp );
p_vout->chroma = p_sys->chroma2;
p_sys->chroma2.pf_convert( p_vout, p_sys->p_tmp, p_dest );
p_vout->chroma = chroma;
#endif
p_sys->p_filter1->p_owner = (filter_owner_sys_t*)p_sys->p_tmp;
if( !p_sys->p_filter1->pf_video_filter( p_sys->p_filter1, p_pic ) )
{
if( p_pic->pf_release )
p_pic->pf_release( p_pic );
return NULL;
}
if( p_pic->pf_release )
p_pic->pf_release( p_pic );
p_sys->p_filter2->p_owner = (filter_owner_sys_t*)p_outpic;
return p_sys->p_filter2->pf_video_filter( p_sys->p_filter2, p_sys->p_tmp );
}
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