/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
#include <vlc/vlc.h>
-#include <vlc/input.h>
-#include <vlc/sout.h>
-#include <vlc/vout.h>
-#include <vlc/decoder.h>
+#include <vlc_input.h>
+#include <vlc_sout.h>
+#include <vlc_aout.h>
+#include <vlc_vout.h>
+#include <vlc_codec.h>
+#include <vlc_block.h>
#include <vlc_filter.h>
#include <vlc_osd.h>
+#include <math.h>
+
#define MASTER_SYNC_MAX_DRIFT 100000
/*****************************************************************************
#define HURRYUP_LONGTEXT N_( "The transcoder will drop frames if your CPU " \
"can't keep up with the encoding rate." )
-static char *ppsz_deinterlace_type[] =
+static const char *ppsz_deinterlace_type[] =
{
"deinterlace", "ffmpeg-deinterlace"
};
AENC_LONGTEXT, VLC_FALSE );
add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
ACODEC_LONGTEXT, VLC_FALSE );
- add_integer( SOUT_CFG_PREFIX "ab", 64000, NULL, AB_TEXT,
+ add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
AB_LONGTEXT, VLC_FALSE );
add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
ACHANS_LONGTEXT, VLC_FALSE );
static const char *ppsz_sout_options[] = {
"venc", "vcodec", "vb", "croptop", "cropbottom", "cropleft", "cropright",
- "paddtop", "paddbottom", "paddleft", "paddright",
- "canvas-width", "canvas-height", "canvas-aspect",
+ "paddtop", "paddbottom", "paddleft", "paddright",
+ "canvas-width", "canvas-height", "canvas-aspect",
"scale", "fps", "width", "height", "vfilter", "deinterlace",
"deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
"afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
/* Audio */
vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
char *psz_aenc;
- sout_cfg_t *p_audio_cfg;
+ config_chain_t *p_audio_cfg;
int i_sample_rate;
int i_channels;
int i_abitrate;
char *psz_afilters[TRANSCODE_FILTERS];
- sout_cfg_t *p_afilters_cfg[TRANSCODE_FILTERS];
+ config_chain_t *p_afilters_cfg[TRANSCODE_FILTERS];
int i_afilters;
/* Video */
vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
char *psz_venc;
- sout_cfg_t *p_video_cfg;
+ config_chain_t *p_video_cfg;
int i_vbitrate;
double f_scale;
double f_fps;
unsigned int i_height, i_maxheight;
vlc_bool_t b_deinterlace;
char *psz_deinterlace;
- sout_cfg_t *p_deinterlace_cfg;
+ config_chain_t *p_deinterlace_cfg;
int i_threads;
vlc_bool_t b_high_priority;
vlc_bool_t b_hurry_up;
char *psz_vfilters[TRANSCODE_FILTERS];
- sout_cfg_t *p_vfilters_cfg[TRANSCODE_FILTERS];
+ config_chain_t *p_vfilters_cfg[TRANSCODE_FILTERS];
int i_vfilters;
int i_crop_top;
vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
char *psz_senc;
vlc_bool_t b_soverlay;
- sout_cfg_t *p_spu_cfg;
+ config_chain_t *p_spu_cfg;
spu_t *p_spu;
/* OSD Menu */
- sout_stream_id_t *id_osd; /* extension for streaming OSD menus */
vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
char *psz_osdenc;
- sout_cfg_t *p_osd_cfg;
- vlc_bool_t b_es_osd; /* VLC_TRUE when osd es is registered */
- vlc_bool_t b_sout_osd;
+ config_chain_t *p_osd_cfg;
+ vlc_bool_t b_osd; /* VLC_TRUE when osd es is registered */
/* Sync */
vlc_bool_t b_master_sync;
p_sys->i_master_drift = 0;
- sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
+ config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
p_stream->p_cfg );
/* Audio transcoding parameters */
if( val.psz_string && *val.psz_string )
{
char *psz_next;
- psz_next = sout_CfgCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
- val.psz_string );
+ psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
+ val.psz_string );
if( psz_next ) free( psz_next );
}
if( val.psz_string ) free( val.psz_string );
while( (psz_parser != NULL) && (*psz_parser != '\0')
&& (p_sys->i_afilters < TRANSCODE_FILTERS) )
{
- psz_parser = sout_CfgCreate(
+ psz_parser = config_ChainCreate(
&p_sys->psz_afilters[p_sys->i_afilters],
&p_sys->p_afilters_cfg[p_sys->i_afilters],
psz_parser );
if( val.psz_string && *val.psz_string )
{
char *psz_next;
- psz_next = sout_CfgCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
+ psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
val.psz_string );
if( psz_next ) free( psz_next );
}
while( (psz_parser != NULL) && (*psz_parser != '\0')
&& (p_sys->i_vfilters < TRANSCODE_FILTERS) )
{
- psz_parser = sout_CfgCreate(
+ psz_parser = config_ChainCreate(
&p_sys->psz_vfilters[p_sys->i_vfilters],
&p_sys->p_vfilters_cfg[p_sys->i_vfilters],
psz_parser );
if( val.psz_string && *val.psz_string )
{
char *psz_next;
- psz_next = sout_CfgCreate( &p_sys->psz_deinterlace,
+ psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
&p_sys->p_deinterlace_cfg,
val.psz_string );
if( psz_next ) free( psz_next );
if( val.psz_string && *val.psz_string )
{
char *psz_next;
- psz_next = sout_CfgCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
+ psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
val.psz_string );
if( psz_next ) free( psz_next );
}
p_sys->psz_osdenc = NULL;
p_sys->p_osd_cfg = NULL;
p_sys->i_osdcodec = 0;
- p_sys->b_es_osd = VLC_FALSE;
+ p_sys->b_osd = VLC_FALSE;
var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
- p_sys->b_sout_osd = val.b_bool;
- if( p_sys->b_sout_osd )
+ if( val.b_bool )
{
vlc_value_t osd_val;
char *psz_next;
- psz_next = sout_CfgCreate( &p_sys->psz_osdenc,
+ psz_next = config_ChainCreate( &p_sys->psz_osdenc,
&p_sys->p_osd_cfg, strdup( "dvbsub") );
if( psz_next ) free( psz_next );
sout_StreamDelete( p_sys->p_out );
+ 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] );
+ }
+
while( p_sys->p_audio_cfg != NULL )
{
- sout_cfg_t *p_next = p_sys->p_audio_cfg->p_next;
+ 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->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] );
+ }
+
while( p_sys->p_video_cfg != NULL )
{
- sout_cfg_t *p_next = p_sys->p_video_cfg->p_next;
+ 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 );
while( p_sys->p_deinterlace_cfg != NULL )
{
- sout_cfg_t *p_next = p_sys->p_deinterlace_cfg->p_next;
+ 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 );
while( p_sys->p_spu_cfg != NULL )
{
- sout_cfg_t *p_next = p_sys->p_spu_cfg->p_next;
+ 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 );
while( p_sys->p_osd_cfg != NULL )
{
- sout_cfg_t *p_next = p_sys->p_osd_cfg->p_next;
+ 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 );
sout_stream_id_t *id;
id = malloc( sizeof( sout_stream_id_t ) );
+ if( !id )
+ {
+ msg_Err( p_stream, "out of memory" );
+ goto error;
+ }
memset( id, 0, sizeof(sout_stream_id_t) );
id->id = NULL;
id->p_encoder->fmt_out.video.i_frame_rate_base = 1001;
}
}
- else if( p_fmt->i_cat == SPU_ES && (p_sys->i_scodec || p_sys->psz_senc) )
+ else if( ( p_fmt->i_cat == SPU_ES ) &&
+ ( p_sys->i_scodec || p_sys->psz_senc ) )
{
msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
"to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
goto error;
}
}
+ else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
+ {
+ msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
+ "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
+ (char*)&p_sys->i_scodec );
+
+ id->b_transcode = VLC_TRUE;
+
+ /* Create a fake OSD menu elementary stream */
+ if( transcode_osd_new( p_stream, id ) )
+ {
+ msg_Err( p_stream, "cannot create osd chain" );
+ goto error;
+ }
+ p_sys->b_osd = VLC_TRUE;
+ }
else
{
msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
if( !id->id ) goto error;
}
- if( p_sys->b_sout_osd )
- {
- /* Create a fake OSD menu elementary stream */
- if( !p_sys->b_es_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
- {
- if( transcode_osd_new( p_stream, p_sys->id_osd ) )
- {
- msg_Err( p_stream, "cannot create osd chain" );
- goto error;
- }
- p_sys->b_es_osd = VLC_TRUE;
- }
- }
return id;
error:
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
- if( p_sys->b_es_osd )
- transcode_osd_close( p_stream, p_sys->id_osd );
-
if( id->b_transcode )
{
switch( id->p_decoder->fmt_in.i_cat )
transcode_video_close( p_stream, id );
break;
case SPU_ES:
- transcode_spu_close( p_stream, id );
+ if( p_sys->b_osd )
+ transcode_osd_close( p_stream, id );
+ else
+ transcode_spu_close( p_stream, id );
break;
}
}
if( !id->b_transcode && id->id )
{
- /* Transcode OSD menu pictures. */
- if( p_sys->b_es_osd )
- {
- transcode_osd_process( p_stream, id, p_buffer, &p_out );
- }
return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
}
else if( !id->b_transcode )
break;
case SPU_ES:
- if( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
+ /* Transcode OSD menu pictures. */
+ if( p_sys->b_osd )
+ {
+ if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
+ VLC_SUCCESS )
+ {
+ return VLC_EGENERIC;
+ }
+ }
+ else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
VLC_SUCCESS )
{
return VLC_EGENERIC;
/****************************************************************************
* decoder reencoder part
****************************************************************************/
-int audio_BitsPerSample( vlc_fourcc_t i_format )
+static int audio_BitsPerSample( vlc_fourcc_t i_format )
{
switch( i_format )
{
if( psz_name )
p_filter->p_cfg = p_sys->p_afilters_cfg[id->i_ufilter];
- p_filter->p_module = module_Need( p_filter, "audio filter2", psz_name, 0 );
+ p_filter->p_module = module_Need( p_filter, "audio filter2", psz_name,
+ VLC_TRUE );
if( p_filter->p_module )
{
p_filter->fmt_out.audio.i_bitspersample =
id->p_decoder->fmt_out = id->p_decoder->fmt_in;
id->p_decoder->fmt_out.i_extra = 0;
id->p_decoder->fmt_out.p_extra = 0;
- id->p_decoder->pf_decode_audio = 0;
+ id->p_decoder->pf_decode_audio = NULL;
id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
/* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
msg_Err( p_stream, "cannot find decoder" );
return VLC_EGENERIC;
}
- id->p_decoder->fmt_out.audio.i_bitspersample =
+ id->p_decoder->fmt_out.audio.i_bitspersample =
audio_BitsPerSample( id->p_decoder->fmt_out.i_codec );
fmt_last = id->p_decoder->fmt_out;
- /* FIX decoders so we don't have to do this */
- fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
+ /* 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) )
+ fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
/*
* Open encoder
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 )
block_t *p_block, *p_audio_block;
int i;
*out = NULL;
- input_thread_t *p_input = NULL;
-
- if( p_stream->p_parent->p_parent && p_stream->p_parent->p_parent->
- i_object_type == VLC_OBJECT_INPUT )
- p_input = (input_thread_t *)p_stream->p_parent->p_parent;
while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
&in )) )
{
- if( p_input )
- stats_UpdateInteger( p_input, p_input->counters.p_decoded_audio,
- 1, NULL );
+ sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
if( p_sys->b_master_sync )
{
mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
}
p_buffer = malloc( sizeof(aout_buffer_t) );
+ if( !p_buffer ) return NULL;
+ p_buffer->b_discontinuity = VLC_FALSE;
p_buffer->pf_release = audio_release_buffer;
p_buffer->p_sys = p_block = block_New( p_dec, i_size );
id->p_decoder->fmt_out = id->p_decoder->fmt_in;
id->p_decoder->fmt_out.i_extra = 0;
id->p_decoder->fmt_out.p_extra = 0;
- id->p_decoder->pf_decode_video = 0;
+ id->p_decoder->pf_decode_video = NULL;
+ id->p_decoder->pf_get_cc = NULL;
+ id->p_decoder->pf_get_cc = 0;
id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
id->p_decoder->pf_picture_link = video_link_picture_decoder;
* We'll open it only when we have the first frame. */
module_Unneed( id->p_encoder, id->p_encoder->p_module );
if( id->p_encoder->fmt_out.p_extra )
+ {
free( id->p_encoder->fmt_out.p_extra );
+ id->p_encoder->fmt_out.p_extra = NULL;
+ id->p_encoder->fmt_out.i_extra = 0;
+ }
id->p_encoder->p_module = NULL;
if( p_sys->i_threads >= 1 )
if( p_stream->p_sys->i_threads >= 1 )
{
vlc_mutex_lock( &p_stream->p_sys->lock_out );
- p_stream->p_sys->b_die = 1;
+ vlc_object_kill( p_stream->p_sys );
vlc_cond_signal( &p_stream->p_sys->cond );
vlc_mutex_unlock( &p_stream->p_sys->lock_out );
vlc_thread_join( p_stream->p_sys );
int i_duplicate = 1, i;
picture_t *p_pic, *p_pic2 = NULL;
*out = NULL;
- input_thread_t *p_input = NULL;
-
- if( p_stream->p_parent->p_parent && p_stream->p_parent->p_parent->
- i_object_type == VLC_OBJECT_INPUT )
- p_input = (input_thread_t *)p_stream->p_parent->p_parent;
while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
{
- subpicture_t *p_subpic = 0;
- if( p_input )
- stats_UpdateInteger( p_input, p_input->counters.p_decoded_video,
- 1, NULL );
+ subpicture_t *p_subpic = NULL;
+
+ sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
{
/* Set the pts of the frame being encoded */
p_pic->date = i_pts;
- if( i_video_drift < i_master_drift - 50000 )
+ if( i_video_drift < (i_master_drift - 50000) )
{
#if 0
msg_Dbg( p_stream, "dropping frame (%i)",
p_pic->pf_release( p_pic );
continue;
}
- else if( i_video_drift > i_master_drift + 50000 )
+ else if( i_video_drift > (i_master_drift + 50000) )
{
#if 0
msg_Dbg( p_stream, "adding frame (%i)",
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, 0 );
+ "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 =
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], 0 );
+ "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 =
/* Run user specified filter chain */
for( i = 0; i < id->i_ufilter; i++ )
{
- p_pic = id->pp_ufilter[i]->pf_video_filter(id->pp_ufilter[i], p_pic);
+ p_pic = id->pp_ufilter[i]->pf_video_filter( id->pp_ufilter[i],
+ p_pic );
}
if( p_sys->i_threads == 0 )
if( p_sys->b_master_sync && i_duplicate > 1 )
{
mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
- if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
- || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
+ if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
+ || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
{
msg_Dbg( p_stream, "drift is too high, resetting master sync" );
date_Set( &id->interpolated_pts, p_pic->date );
}
p_pic = malloc( sizeof(picture_t) );
+ if( !p_pic ) return NULL;
p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
p_dec->fmt_out.video.i_chroma,
if( !p_pic->i_planes )
{
free( p_pic );
- return 0;
+ return NULL;
}
p_pic->pf_release = video_release_buffer;
p_pic->p_sys = malloc( sizeof(picture_sys_t) );
+ if( !p_pic->p_sys )
+ {
+ free( p_pic );
+ return NULL;
+ }
+
p_pic->p_sys->p_owner = p_this;
p_pic->i_status = RESERVED_PICTURE;
*/
/* Initialization of decoder structures */
+ id->p_decoder->pf_decode_sub = NULL;
id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
*out = NULL;
p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
- if( !p_subpic ) return VLC_EGENERIC;
+ if( !p_subpic )
+ return VLC_EGENERIC;
+
+ sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
if( p_sys->b_master_sync && p_sys->i_master_drift )
{
p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
spu_del_buffer( id->p_decoder, p_subpic );
-
if( p_block )
{
block_ChainAppend( out, p_block );
static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
- es_format_t fmt;
- fmt.i_cat = SPU_ES;
- fmt.i_id = 0xbd1f; /* pid ?? */
- fmt.i_group = 3; /* pmt entry ?? */
- fmt.i_codec = VLC_FOURCC( 'Y', 'U', 'V', 'A' );
- fmt.psz_language = strdup( "osd" );
-
- id = malloc( sizeof( sout_stream_id_t ) );
- memset( id, 0, sizeof(sout_stream_id_t) );
-
- id->id = NULL;
- id->p_decoder = NULL;
- id->p_encoder = NULL;
-
- /* Create encoder object */
- id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
- if( !id->p_encoder )
- {
- msg_Err( p_stream, "out of memory" );
- goto error;
- }
- vlc_object_attach( id->p_encoder, p_stream );
- id->p_encoder->p_module = NULL;
-
- /* Create fake destination format */
- es_format_Init( &id->p_encoder->fmt_out, fmt.i_cat, 0 );
- id->p_encoder->fmt_out.i_id = fmt.i_id;
- id->p_encoder->fmt_out.i_group = fmt.i_group;
- id->p_encoder->fmt_out.psz_language = strdup( fmt.psz_language );
+ id->p_decoder->fmt_in.i_cat = SPU_ES;
+ id->p_encoder->fmt_out.psz_language = strdup( "osd" );
if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
{
msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
- "to fcc=`%4.4s'", (char*)&fmt.i_codec,
+ "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
(char*)&p_sys->i_osdcodec );
/* Complete destination format */
id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
/* Open encoder */
- /* Initialization of encoder format structures */
- es_format_Init( &id->p_encoder->fmt_in, fmt.i_cat, fmt.i_codec );
- id->p_encoder->fmt_in.psz_language = strdup( fmt.psz_language );
+ es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
+ VLC_FOURCC('Y','U','V','A') );
+ id->p_encoder->fmt_in.psz_language = strdup( "osd" );
id->p_encoder->p_cfg = p_sys->p_osd_cfg;
else
{
msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
- (char*)&fmt.i_codec );
- id->id = p_sys->p_out->pf_add( p_sys->p_out, &fmt );
+ (char*)&id->p_decoder->fmt_out.i_codec );
+ id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
id->b_transcode = VLC_FALSE;
if( !id->id ) goto error;
}
- p_sys->id_osd = id;
- p_sys->b_es_osd = VLC_TRUE;
-
if( !p_sys->p_spu )
{
p_sys->p_spu = spu_Create( p_stream );
- if( spu_Init( p_sys->p_spu ) != VLC_SUCCESS )
- msg_Err( p_sys, "spu initialisation failed" );
+ spu_Init( p_sys->p_spu );
}
- if( fmt.psz_language )
- free( fmt.psz_language );
-
return VLC_SUCCESS;
error:
msg_Err( p_stream, "starting osd encoding thread failed" );
if( id->p_encoder->p_module )
module_Unneed( id->p_encoder, id->p_encoder->p_module );
- if( id->p_encoder )
- {
- vlc_object_detach( id->p_encoder );
- vlc_object_destroy( id->p_encoder );
- }
- if( fmt.psz_language ) free( fmt.psz_language );
- if( id ) free( id );
- p_sys->id_osd = NULL;
- p_sys->b_es_osd = VLC_FALSE;
+ p_sys->b_osd = VLC_FALSE;
return VLC_EGENERIC;
}
sout_stream_sys_t *p_sys = p_stream->p_sys;
/* Close encoder */
- if( p_sys->b_es_osd && id )
+ if( p_sys->b_osd && id )
{
if( id->p_encoder->p_module )
module_Unneed( id->p_encoder, id->p_encoder->p_module );
-
- if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
-
- if( id->p_encoder )
- {
- vlc_object_detach( id->p_encoder );
- vlc_object_destroy( id->p_encoder );
- }
}
- p_sys->b_es_osd = VLC_FALSE;
- if( id ) free( id );
+ p_sys->b_osd = VLC_FALSE;
}
static int transcode_osd_process( sout_stream_t *p_stream,
if( !p_sys->p_spu )
{
p_sys->p_spu = spu_Create( p_stream );
- if( spu_Init( p_sys->p_spu ) != VLC_SUCCESS )
- msg_Err( p_stream, "spu initialisation failed" );
+ spu_Init( p_sys->p_spu );
}
}
if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
}
- p_block = p_sys->id_osd->p_encoder->pf_encode_sub( p_sys->id_osd->p_encoder, p_subpic );
+ p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
+ spu_DestroySubpicture( p_sys->p_spu, p_subpic );
if( p_block )
{
p_block->i_dts = p_block->i_pts = in->i_dts;
block_ChainAppend( out, p_block );
- if( *out )
- {
- if( p_sys->p_out->pf_send( p_sys->p_out, p_sys->id_osd->id, *out ) == VLC_SUCCESS )
- spu_DestroySubpicture( p_sys->p_spu, p_subpic );
- }
return VLC_SUCCESS;
}
}