#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>
#define MASTER_SYNC_MAX_DRIFT 100000
+/* FIXME Ugly */
+#include "../../src/input/input_internal.h"
+
/*****************************************************************************
* Module descriptor
*****************************************************************************/
"associated options)." )
#define SCODEC_TEXT N_("Destination subtitles codec")
#define SCODEC_LONGTEXT N_( \
- "This is the subtitles coded that will be used." )
+ "This is the subtitles codec that will be used." )
#define SFILTER_TEXT N_("Overlays")
#define SFILTER_LONGTEXT N_( \
MAXWIDTH_LONGTEXT, VLC_TRUE );
add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
MAXHEIGHT_LONGTEXT, VLC_TRUE );
- add_module_list_cat( SOUT_CFG_PREFIX "vfilter", SUBCAT_VIDEO_VFILTER2,
+ add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
NULL, NULL,
VFILTER_TEXT, VFILTER_LONGTEXT, VLC_FALSE );
/* 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;
+ config_chain_t *p_osd_cfg;
vlc_bool_t b_es_osd; /* VLC_TRUE when osd es is registered */
vlc_bool_t b_sout_osd;
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 );
}
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 );
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 );
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 );
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
{
msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
module_Unneed( id->p_decoder, id->p_decoder->p_module );
- id->p_decoder->p_module = 0;
+ id->p_decoder->p_module = NULL;
return VLC_EGENERIC;
}
id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
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 )
if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
{
- msg_Err( p_stream, "no audio filter found for mixing from"
- " %i to %i channels", fmt_last.audio.i_channels,
- id->p_encoder->fmt_in.audio.i_channels );
-#if 0
- /* FIXME : this might work, but only if the encoder is restarted */
+#if 1
+ module_Unneed( id->p_encoder, id->p_encoder->p_module );
+ id->p_encoder->p_module = NULL;
+
+ /* This might work, but only if the encoder is restarted */
id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
id->p_encoder->fmt_out.audio.i_physical_channels =
id->p_encoder->fmt_out.audio.i_original_channels =
fmt_last.audio.i_physical_channels;
+
+ msg_Dbg( p_stream, "number of audio channels for mixing changed, "
+ "trying to reopen the encoder for mixing %i to %i channels",
+ fmt_last.audio.i_channels,
+ id->p_encoder->fmt_in.audio.i_channels );
+
+ /* reload encoder */
+ id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
+ id->p_encoder->p_module =
+ module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, VLC_TRUE );
+ if( !id->p_encoder->p_module )
+ {
+ msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
+ transcode_audio_close( p_stream, id );
+ return VLC_EGENERIC;
+ }
+ id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
+ id->p_encoder->fmt_in.audio.i_bitspersample =
+ audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
#else
+ msg_Err( p_stream, "no audio filter found for mixing from"
+ " %i to %i channels", fmt_last.audio.i_channels,
+ id->p_encoder->fmt_in.audio.i_channels );
+
transcode_audio_close( p_stream, id );
return VLC_EGENERIC;
#endif
/* Close decoder */
if( id->p_decoder->p_module )
module_Unneed( id->p_decoder, id->p_decoder->p_module );
- id->p_decoder->p_module = 0;
+ id->p_decoder->p_module = NULL;
/* Close encoder */
if( id->p_encoder->p_module )
module_Unneed( id->p_encoder, id->p_encoder->p_module );
- id->p_encoder->p_module = 0;
+ id->p_encoder->p_module = NULL;
/* Close filters */
for( i = 0; i < id->i_filter; i++ )
&in )) )
{
if( p_input )
- stats_UpdateInteger( p_input, p_input->counters.p_decoded_audio,
+ stats_UpdateInteger( p_input, p_input->p->counters.p_decoded_audio,
1, NULL );
if( p_sys->b_master_sync )
{
* 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 )
{
subpicture_t *p_subpic = 0;
if( p_input )
- stats_UpdateInteger( p_input, p_input->counters.p_decoded_video,
+ stats_UpdateInteger( p_input, p_input->p->counters.p_decoded_video,
1, NULL );
if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
/* Check if we have a subpicture to overlay */
if( p_sys->p_spu )
{
- p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date );
+ p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
+ VLC_FALSE /* Fixme: check if stream is paused */ );
/* TODO: get another pic */
}
/* Check if we have a subpicture to send */
if( p_sys->p_spu && in->i_dts > 0)
{
- p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts );
+ p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, VLC_FALSE );
}
else
{