/*****************************************************************************
* transcode.c: transcoding stream output module
*****************************************************************************
- * Copyright (C) 2003-2004 the VideoLAN team
+ * Copyright (C) 2003-2008 the VideoLAN team
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
/*****************************************************************************
* Preamble
*****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <vlc/vlc.h>
#include <vlc_input.h>
#include <vlc_sout.h>
static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );
static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
-static void transcode_audio_close ( sout_stream_t *, sout_stream_id_t * );
+static void transcode_audio_close ( sout_stream_id_t * );
static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
block_t *, block_t ** );
static void video_del_buffer_filter( filter_t *, picture_t * );
static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
-static void transcode_spu_close ( sout_stream_t *, sout_stream_id_t * );
+static void transcode_spu_close ( sout_stream_id_t * );
static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
block_t *, block_t ** );
if( !p_sys->p_out )
{
msg_Err( p_stream, "cannot create chain" );
- vlc_object_destroy( p_sys );
+ vlc_object_release( p_sys );
return VLC_EGENERIC;
}
char *psz_next;
psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
val.psz_string );
- if( psz_next ) free( psz_next );
+ free( psz_next );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
p_sys->i_acodec = 0;
memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
p_sys->i_abitrate = val.i_int;
if( (psz_parser != NULL) && (*psz_parser != '\0') ) psz_parser++;
}
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
if( p_sys->i_afilters < TRANSCODE_FILTERS-1 )
{
p_sys->psz_afilters[p_sys->i_afilters] = NULL;
char *psz_next;
psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
val.psz_string );
- if( psz_next ) free( psz_next );
+ free( psz_next );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
p_sys->i_vcodec = 0;
memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
p_sys->i_vbitrate = val.i_int;
if( psz_parser != NULL && *psz_parser != '\0' ) psz_parser++;
}
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
if( p_sys->i_vfilters < TRANSCODE_FILTERS-1 )
{
p_sys->psz_vfilters[p_sys->i_vfilters] = NULL;
psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
&p_sys->p_deinterlace_cfg,
val.psz_string );
- if( psz_next ) free( psz_next );
+ free( psz_next );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "croptop", &val );
p_sys->i_crop_top = val.i_int;
else msg_Warn( p_stream, "bad aspect ratio %s", val.psz_string );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
p_sys->i_threads = val.i_int;
char *psz_next;
psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
val.psz_string );
- if( psz_next ) free( psz_next );
+ free( psz_next );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
if( val.psz_string && *val.psz_string )
memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
if( p_sys->i_scodec )
{
var_Set( p_sys->p_spu, "sub-filter", val );
spu_Init( p_sys->p_spu );
}
- if( val.psz_string ) free( val.psz_string );
+ free( val.psz_string );
/* OSD menu transcoding parameters */
p_sys->psz_osdenc = NULL;
psz_next = config_ChainCreate( &p_sys->psz_osdenc,
&p_sys->p_osd_cfg, strdup( "dvbsub") );
- if( psz_next ) free( psz_next );
+ free( psz_next );
p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );
var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
var_Set( p_sys->p_spu, "sub-filter", osd_val );
spu_Init( p_sys->p_spu );
- if( osd_val.psz_string ) free( osd_val.psz_string );
+ free( osd_val.psz_string );
}
else
{
osd_val.psz_string = strdup("osdmenu");
var_Set( p_sys->p_spu, "sub-filter", osd_val );
- if( osd_val.psz_string ) free( osd_val.psz_string );
+ free( osd_val.psz_string );
}
}
while( p_sys->i_afilters )
{
p_sys->i_afilters--;
- if( p_sys->psz_afilters[p_sys->i_afilters] )
- free( p_sys->psz_afilters[p_sys->i_afilters] );
- if( p_sys->p_afilters_cfg[p_sys->i_afilters] )
- free( p_sys->p_afilters_cfg[p_sys->i_afilters] );
+ free( p_sys->psz_afilters[p_sys->i_afilters] );
+ free( p_sys->p_afilters_cfg[p_sys->i_afilters] );
}
while( p_sys->p_audio_cfg != NULL )
{
config_chain_t *p_next = p_sys->p_audio_cfg->p_next;
- if( p_sys->p_audio_cfg->psz_name )
- free( p_sys->p_audio_cfg->psz_name );
- if( p_sys->p_audio_cfg->psz_value )
- free( p_sys->p_audio_cfg->psz_value );
+ free( p_sys->p_audio_cfg->psz_name );
+ free( p_sys->p_audio_cfg->psz_value );
free( p_sys->p_audio_cfg );
p_sys->p_audio_cfg = p_next;
}
- if( p_sys->psz_aenc ) free( p_sys->psz_aenc );
+ free( p_sys->psz_aenc );
while( p_sys->i_vfilters )
{
p_sys->i_vfilters--;
- if( p_sys->psz_vfilters[p_sys->i_vfilters] )
- free( p_sys->psz_vfilters[p_sys->i_vfilters] );
- if( p_sys->p_vfilters_cfg[p_sys->i_vfilters] )
- free( p_sys->p_vfilters_cfg[p_sys->i_vfilters] );
+ free( p_sys->psz_vfilters[p_sys->i_vfilters] );
+ free( p_sys->p_vfilters_cfg[p_sys->i_vfilters] );
}
while( p_sys->p_video_cfg != NULL )
{
config_chain_t *p_next = p_sys->p_video_cfg->p_next;
- if( p_sys->p_video_cfg->psz_name )
- free( p_sys->p_video_cfg->psz_name );
- if( p_sys->p_video_cfg->psz_value )
- free( p_sys->p_video_cfg->psz_value );
+ free( p_sys->p_video_cfg->psz_name );
+ free( p_sys->p_video_cfg->psz_value );
free( p_sys->p_video_cfg );
p_sys->p_video_cfg = p_next;
}
- if( p_sys->psz_venc ) free( p_sys->psz_venc );
+ free( p_sys->psz_venc );
while( p_sys->p_deinterlace_cfg != NULL )
{
config_chain_t *p_next = p_sys->p_deinterlace_cfg->p_next;
- if( p_sys->p_deinterlace_cfg->psz_name )
- free( p_sys->p_deinterlace_cfg->psz_name );
- if( p_sys->p_deinterlace_cfg->psz_value )
- free( p_sys->p_deinterlace_cfg->psz_value );
+ free( p_sys->p_deinterlace_cfg->psz_name );
+ free( p_sys->p_deinterlace_cfg->psz_value );
free( p_sys->p_deinterlace_cfg );
p_sys->p_deinterlace_cfg = p_next;
}
- if( p_sys->psz_deinterlace ) free( p_sys->psz_deinterlace );
+ free( p_sys->psz_deinterlace );
while( p_sys->p_spu_cfg != NULL )
{
config_chain_t *p_next = p_sys->p_spu_cfg->p_next;
- if( p_sys->p_spu_cfg->psz_name )
- free( p_sys->p_spu_cfg->psz_name );
- if( p_sys->p_spu_cfg->psz_value )
- free( p_sys->p_spu_cfg->psz_value );
+ free( p_sys->p_spu_cfg->psz_name );
+ free( p_sys->p_spu_cfg->psz_value );
free( p_sys->p_spu_cfg );
p_sys->p_spu_cfg = p_next;
}
- if( p_sys->psz_senc ) free( p_sys->psz_senc );
+ free( p_sys->psz_senc );
if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
{
config_chain_t *p_next = p_sys->p_osd_cfg->p_next;
- if( p_sys->p_osd_cfg->psz_name )
- free( p_sys->p_osd_cfg->psz_name );
- if( p_sys->p_osd_cfg->psz_value )
- free( p_sys->p_osd_cfg->psz_value );
+ free( p_sys->p_osd_cfg->psz_name );
+ free( p_sys->p_osd_cfg->psz_value );
free( p_sys->p_osd_cfg );
p_sys->p_osd_cfg = p_next;
}
- if( p_sys->psz_osdenc ) free( p_sys->psz_osdenc );
+ free( p_sys->psz_osdenc );
- vlc_object_destroy( p_sys );
+ vlc_object_release( p_sys );
}
struct sout_stream_id_t
if( !id->id )
{
- transcode_audio_close( p_stream, id );
+ transcode_audio_close( id );
goto error;
}
if( !id->id )
{
- transcode_spu_close( p_stream, id );
+ transcode_spu_close( id );
goto error;
}
}
if( id->p_decoder )
{
vlc_object_detach( id->p_decoder );
- vlc_object_destroy( id->p_decoder );
+ vlc_object_release( id->p_decoder );
id->p_decoder = NULL;
}
{
vlc_object_detach( id->p_encoder );
es_format_Clean( &id->p_encoder->fmt_out );
- vlc_object_destroy( id->p_encoder );
+ vlc_object_release( id->p_encoder );
id->p_encoder = NULL;
}
switch( id->p_decoder->fmt_in.i_cat )
{
case AUDIO_ES:
- transcode_audio_close( p_stream, id );
+ transcode_audio_close( id );
break;
case VIDEO_ES:
transcode_video_close( p_stream, id );
if( p_sys->b_osd )
transcode_osd_close( p_stream, id );
else
- transcode_spu_close( p_stream, id );
+ transcode_spu_close( id );
break;
}
}
if( id->p_decoder )
{
vlc_object_detach( id->p_decoder );
- vlc_object_destroy( id->p_decoder );
+ vlc_object_release( id->p_decoder );
id->p_decoder = NULL;
}
{
vlc_object_detach( id->p_encoder );
es_format_Clean( &id->p_encoder->fmt_out );
- vlc_object_destroy( id->p_encoder );
+ vlc_object_release( id->p_encoder );
id->p_encoder = NULL;
}
free( id );
else
{
vlc_object_detach( p_filter );
- vlc_object_destroy( p_filter );
+ vlc_object_release( p_filter );
p_filter = 0;
}
id->p_encoder->fmt_in.audio.i_bitspersample =
audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
- /* Fix AAC SBR changing number of channels and sampling rate */
- if( id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
- fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
- fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
- {
- id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
- id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
- }
-
/* Load conversion filters */
if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
(char *)&fmt_last.i_codec,
(char *)&id->p_encoder->fmt_in.i_codec );
- transcode_audio_close( p_stream, id );
+ transcode_audio_close( id );
return VLC_EGENERIC;
}
if( !id->p_encoder->p_module )
{
msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
- transcode_audio_close( p_stream, id );
+ transcode_audio_close( id );
return VLC_EGENERIC;
}
id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
" %i to %i channels", fmt_last.audio.i_channels,
id->p_encoder->fmt_in.audio.i_channels );
- transcode_audio_close( p_stream, id );
+ transcode_audio_close( id );
return VLC_EGENERIC;
#endif
}
id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
#else
- transcode_audio_close( p_stream, id );
+ transcode_audio_close( id );
return VLC_EGENERIC;
#endif
}
return VLC_SUCCESS;
}
-static void transcode_audio_close( sout_stream_t *p_stream,
- sout_stream_id_t *id )
+static void transcode_audio_close( sout_stream_id_t *id )
{
int i;
vlc_object_detach( id->pp_filter[i] );
if( id->pp_filter[i]->p_module )
module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
- vlc_object_destroy( id->pp_filter[i] );
+ vlc_object_release( id->pp_filter[i] );
}
for( i = 0; i < id->i_ufilter; i++ )
{
vlc_object_detach( id->pp_ufilter[i] );
if( id->pp_ufilter[i]->p_module )
module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module );
- vlc_object_destroy( id->pp_ufilter[i] );
+ vlc_object_release( id->pp_ufilter[i] );
}
}
static void audio_release_buffer( aout_buffer_t *p_buffer )
{
if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
- if( p_buffer ) free( p_buffer );
+ free( p_buffer );
}
static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
{
+ VLC_UNUSED(p_dec);
if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
- if( p_buffer ) free( p_buffer );
+ free( p_buffer );
}
/*
* video
*/
+
+static filter_t *transcode_video_filter_new( sout_stream_t *p_stream,
+ es_format_t *p_fmt_in,
+ es_format_t *p_fmt_out,
+ config_chain_t *p_cfg,
+ const char *psz_name )
+{
+ sout_stream_sys_t *p_sys = p_stream->p_sys;
+ filter_t *p_filter;
+ int i;
+
+ if( !p_stream || !p_fmt_in || !p_fmt_out ) return NULL;
+
+ p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER );
+ vlc_object_attach( p_filter, p_stream );
+
+ p_filter->pf_vout_buffer_new = video_new_buffer_filter;
+ p_filter->pf_vout_buffer_del = video_del_buffer_filter;
+
+ es_format_Copy( &p_filter->fmt_in, p_fmt_in );
+ es_format_Copy( &p_filter->fmt_out, p_fmt_out );
+ p_filter->p_cfg = p_cfg;
+
+ p_filter->p_module = module_Need( p_filter, "video filter2",
+ psz_name, VLC_TRUE );
+ if( !p_filter->p_module )
+ {
+ msg_Dbg( p_stream, "no video filter found" );
+ vlc_object_detach( p_filter );
+ vlc_object_release( p_filter );
+ return NULL;
+ }
+
+ p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
+ if( !p_filter->p_owner )
+ {
+ module_Unneed( p_filter,p_filter->p_module );
+ vlc_object_detach( p_filter );
+ vlc_object_release( p_filter );
+ return NULL;
+ }
+
+ for( i = 0; i < PICTURE_RING_SIZE; i++ )
+ p_filter->p_owner->pp_pics[i] = 0;
+ p_filter->p_owner->p_sys = p_sys;
+
+ return p_filter;
+}
+
+static void transcode_video_filter_close( sout_stream_t *p_stream,
+ filter_t *p_filter )
+{
+ int j;
+
+ if( !p_stream || !p_filter ) return;
+
+ vlc_object_detach( p_filter );
+ if( p_filter->p_module )
+ module_Unneed( p_filter, p_filter->p_module );
+
+ /* Clean-up pictures ring buffer */
+ for( j = 0; j < PICTURE_RING_SIZE; j++ )
+ {
+ if( p_filter->p_owner->pp_pics[j] )
+ video_del_buffer( VLC_OBJECT(p_filter),
+ p_filter->p_owner->pp_pics[j] );
+ }
+ free( p_filter->p_owner );
+ vlc_object_release( p_filter );
+ p_filter = NULL;
+}
+
static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
static void transcode_video_close( sout_stream_t *p_stream,
sout_stream_id_t *id )
{
- int i, j;
+ int i;
if( p_stream->p_sys->i_threads >= 1 )
{
/* Close filters */
for( i = 0; i < id->i_filter; i++ )
{
- vlc_object_detach( id->pp_filter[i] );
- if( id->pp_filter[i]->p_module )
- module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
-
- /* Clean-up pictures ring buffer */
- for( j = 0; j < PICTURE_RING_SIZE; j++ )
- {
- if( id->pp_filter[i]->p_owner->pp_pics[j] )
- video_del_buffer( VLC_OBJECT(id->pp_filter[i]),
- id->pp_filter[i]->p_owner->pp_pics[j] );
- }
- free( id->pp_filter[i]->p_owner );
- vlc_object_destroy( id->pp_filter[i] );
+ transcode_video_filter_close( p_stream, id->pp_filter[i] );
id->pp_filter[i] = NULL;
}
+ id->i_filter = 0;
for( i = 0; i < id->i_ufilter; i++ )
{
- vlc_object_detach( id->pp_ufilter[i] );
- if( id->pp_ufilter[i]->p_module )
- module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module );
-
- /* Clean-up pictures ring buffer */
- for( j = 0; j < PICTURE_RING_SIZE; j++ )
- {
- if( id->pp_ufilter[i]->p_owner->pp_pics[j] )
- video_del_buffer( VLC_OBJECT(id->pp_ufilter[i]),
- id->pp_ufilter[i]->p_owner->pp_pics[j] );
- }
- free( id->pp_ufilter[i]->p_owner );
- vlc_object_destroy( id->pp_ufilter[i] );
+ transcode_video_filter_close( p_stream, id->pp_ufilter[i] );
id->pp_ufilter[i] = NULL;
}
+ id->i_ufilter = 0;
}
static int transcode_video_process( sout_stream_t *p_stream,
if( p_stream->p_sys->b_deinterlace )
{
id->pp_filter[id->i_filter] =
- vlc_object_create( p_stream, VLC_OBJECT_FILTER );
- vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
-
- id->pp_filter[id->i_filter]->pf_vout_buffer_new =
- video_new_buffer_filter;
- id->pp_filter[id->i_filter]->pf_vout_buffer_del =
- video_del_buffer_filter;
-
- id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
- id->pp_filter[id->i_filter]->fmt_out = id->p_decoder->fmt_out;
- id->pp_filter[id->i_filter]->p_cfg = p_sys->p_deinterlace_cfg;
- id->pp_filter[id->i_filter]->p_module =
- module_Need( id->pp_filter[id->i_filter],
- "video filter2", p_sys->psz_deinterlace,
- VLC_TRUE );
- if( id->pp_filter[id->i_filter]->p_module )
- {
- id->pp_filter[id->i_filter]->p_owner =
- malloc( sizeof(filter_owner_sys_t) );
- for( i = 0; i < PICTURE_RING_SIZE; i++ )
- id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
- id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;
+ transcode_video_filter_new( p_stream,
+ &id->p_decoder->fmt_out, &id->p_decoder->fmt_out,
+ p_sys->p_deinterlace_cfg,
+ p_sys->psz_deinterlace );
+ if( id->pp_filter[id->i_filter] )
id->i_filter++;
- }
- else
+ }
+
+#if (defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)) || defined(HAVE_LIBSWSCALE_SWSCALE_H)
+ if( ( id->p_decoder->fmt_out.video.i_chroma !=
+ id->p_encoder->fmt_in.video.i_chroma ) ||
+ ( id->p_decoder->fmt_out.video.i_width !=
+ id->p_encoder->fmt_out.video.i_width ) ||
+ ( id->p_decoder->fmt_out.video.i_height !=
+ id->p_encoder->fmt_out.video.i_height ) )
+ {
+ id->pp_filter[id->i_filter] =
+ transcode_video_filter_new( p_stream,
+ &id->p_decoder->fmt_out, &id->p_encoder->fmt_in,
+ NULL, "scale" );
+ if( !id->pp_filter[id->i_filter] )
{
- msg_Dbg( p_stream, "no video filter found" );
- vlc_object_detach( id->pp_filter[id->i_filter] );
- vlc_object_destroy( id->pp_filter[id->i_filter] );
+ p_pic->pf_release( p_pic );
+ transcode_video_close( p_stream, id );
+ id->b_transcode = VLC_FALSE;
+ return VLC_EGENERIC;
}
+ id->i_filter++;
}
+#if 0 /* FIXME: */
+ /* we don't do chroma conversion or scaling in croppad */
+// es_format_t fmt_in, fmt_out;
+// es_format_Copy( &fmt_out, &id->p_encoder->fmt_in );
+// es_format_Copy( &fmt_in, &id->p_encoder->fmt_in );
+
+ if( ( id->p_decoder->fmt_out.video.i_chroma ==
+ id->p_encoder->fmt_in.video.i_chroma ) &&
+
+ ( ( (int)id->p_decoder->fmt_out.video.i_width !=
+ p_sys->i_crop_width ) ||
+ ( p_sys->i_crop_width != p_sys->i_nopadd_width ) ||
+ ( p_sys->i_nopadd_width !=
+ (int)id->p_encoder->fmt_out.video.i_width ) ||
+
+ ( (int)id->p_decoder->fmt_out.video.i_height !=
+ p_sys->i_crop_height ) ||
+ ( p_sys->i_crop_height != p_sys->i_nopadd_height ) ||
+ ( p_sys->i_nopadd_height !=
+ (int)id->p_encoder->fmt_out.video.i_height ) ) )
+ {
+ id->pp_filter[id->i_filter] =
+ transcode_video_filter_new( p_stream,
+ &id->p_decoder->fmt_out, &id->p_encoder->fmt_in,
+ NULL, "croppadd" );
+ if( id->pp_filter[id->i_filter] )
+ {
+ /* Set crop and padding information */
+ id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset;
+ id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset;
+ id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width;
+ id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height;
+
+ id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset;
+ id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset;
+ id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width;
+ id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height;
+ id->i_filter++;
+ }
+ }
+#endif
+#else
/* Check if we need a filter for chroma conversion or resizing */
if( id->p_decoder->fmt_out.video.i_chroma !=
id->p_encoder->fmt_in.video.i_chroma ||
p_sys->i_nopadd_height != (int)id->p_encoder->fmt_out.video.i_height)
{
id->pp_filter[id->i_filter] =
- vlc_object_create( p_stream, VLC_OBJECT_FILTER );
- vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
-
- id->pp_filter[id->i_filter]->pf_vout_buffer_new =
- video_new_buffer_filter;
- id->pp_filter[id->i_filter]->pf_vout_buffer_del =
- video_del_buffer_filter;
-
- id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
- id->pp_filter[id->i_filter]->fmt_out = id->p_encoder->fmt_in;
- id->pp_filter[id->i_filter]->p_cfg = NULL;
+ transcode_video_filter_new( p_stream,
+ &id->p_decoder->fmt_out, &id->p_encoder->fmt_in,
+ NULL, "crop padd" );
+ if( !id->pp_filter[id->i_filter] )
+ {
+ p_pic->pf_release( p_pic );
+ transcode_video_close( p_stream, id );
+ id->b_transcode = VLC_FALSE;
+ return VLC_EGENERIC;
+ }
+ /* Set crop and padding information */
id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset;
id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset;
id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width;
id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width;
id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height;
- id->pp_filter[id->i_filter]->p_module =
- module_Need( id->pp_filter[id->i_filter],
- "crop padd", 0, 0 );
- if( id->pp_filter[id->i_filter]->p_module )
- {
- id->pp_filter[id->i_filter]->p_owner =
- malloc( sizeof(filter_owner_sys_t) );
- for( i = 0; i < PICTURE_RING_SIZE; i++ )
- id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
- id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;
-
- id->i_filter++;
- }
- else
- {
- msg_Dbg( p_stream, "no video filter found" );
- vlc_object_detach( id->pp_filter[id->i_filter] );
- vlc_object_destroy( id->pp_filter[id->i_filter] );
-
- p_pic->pf_release( p_pic );
- transcode_video_close( p_stream, id );
- id->b_transcode = VLC_FALSE;
- return VLC_EGENERIC;
- }
+ id->i_filter++;
}
-
+#endif
for( i = 0; (i < p_sys->i_vfilters) && (id->i_ufilter < TRANSCODE_FILTERS); i++ )
{
id->pp_ufilter[id->i_ufilter] =
- vlc_object_create( p_stream, VLC_OBJECT_FILTER );
- vlc_object_attach( id->pp_ufilter[id->i_ufilter], p_stream );
-
- id->pp_ufilter[id->i_ufilter]->pf_vout_buffer_new =
- video_new_buffer_filter;
- id->pp_ufilter[id->i_ufilter]->pf_vout_buffer_del =
- video_del_buffer_filter;
-
- id->pp_ufilter[id->i_ufilter]->fmt_in = id->p_encoder->fmt_in;
- id->pp_ufilter[id->i_ufilter]->fmt_out = id->p_encoder->fmt_in;
- id->pp_ufilter[id->i_ufilter]->p_cfg = p_sys->p_vfilters_cfg[i];
- id->pp_ufilter[id->i_ufilter]->p_module =
- module_Need( id->pp_ufilter[id->i_ufilter],
- "video filter2", p_sys->psz_vfilters[i], VLC_TRUE );
- if( id->pp_ufilter[id->i_ufilter]->p_module )
- {
- id->pp_ufilter[id->i_ufilter]->p_owner =
- malloc( sizeof(filter_owner_sys_t) );
- for( i = 0; i < PICTURE_RING_SIZE; i++ )
- id->pp_ufilter[id->i_ufilter]->p_owner->pp_pics[i] = 0;
- id->pp_ufilter[id->i_ufilter]->p_owner->p_sys = p_sys;
+ transcode_video_filter_new( p_stream,
+ &id->p_decoder->fmt_out, &id->p_encoder->fmt_in,
+ p_sys->p_vfilters_cfg[i], p_sys->psz_vfilters[i] );
+ if( id->pp_ufilter[id->i_filter] )
id->i_ufilter++;
- }
else
- {
- msg_Dbg( p_stream, "no video filter found" );
- vlc_object_detach( id->pp_ufilter[id->i_ufilter] );
- vlc_object_destroy( id->pp_ufilter[id->i_ufilter] );
id->pp_ufilter[id->i_ufilter] = NULL;
- }
}
}
static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
{
- if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
- if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
- if( p_pic ) free( p_pic );
+ VLC_UNUSED(p_this);
+ if( p_pic )
+ {
+ free( p_pic->p_data_orig );
+ free( p_pic->p_sys );
+ free( p_pic );
+ }
}
static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
{
+ VLC_UNUSED(p_decoder);
p_pic->i_refcount = 0;
p_pic->i_status = DESTROYED_PICTURE;
}
static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
{
+ VLC_UNUSED(p_filter);
p_pic->i_refcount = 0;
p_pic->i_status = DESTROYED_PICTURE;
}
static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
{
+ VLC_UNUSED(p_dec);
p_pic->i_refcount++;
}
static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
{
+ VLC_UNUSED(p_dec);
video_release_buffer( p_pic );
}
return VLC_SUCCESS;
}
-static void transcode_spu_close( sout_stream_t *p_stream, sout_stream_id_t *id)
+static void transcode_spu_close( sout_stream_id_t *id)
{
/* Close decoder */
if( id->p_decoder->p_module )