Commit 1064ec21 authored by Jean-Paul Saman's avatar Jean-Paul Saman Committed by Jean-Paul Saman

Backport of trunk additions for audio filters.

parent 9236c65c
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
#include <vlc/sout.h> #include <vlc/sout.h>
#include <vlc/vout.h> #include <vlc/vout.h>
#include <vlc/decoder.h> #include <vlc/decoder.h>
#include "vlc_filter.h" #include <vlc_filter.h>
#include "vlc_osd.h" #include <vlc_osd.h>
#define MASTER_SYNC_MAX_DRIFT 100000 #define MASTER_SYNC_MAX_DRIFT 100000
...@@ -136,6 +136,10 @@ ...@@ -136,6 +136,10 @@
#define ACHANS_TEXT N_("Audio channels") #define ACHANS_TEXT N_("Audio channels")
#define ACHANS_LONGTEXT N_( \ #define ACHANS_LONGTEXT N_( \
"Number of audio channels in the transcoded streams." ) "Number of audio channels in the transcoded streams." )
#define AFILTER_TEXT N_("Audio filter")
#define AFILTER_LONGTEXT N_( \
"Audio filters will be applied to the audio streams (after conversion " \
"filters are applied). You must enter a comma-separated list of filters." )
#define SENC_TEXT N_("Subtitles encoder") #define SENC_TEXT N_("Subtitles encoder")
#define SENC_LONGTEXT N_( \ #define SENC_LONGTEXT N_( \
...@@ -260,6 +264,9 @@ vlc_module_begin(); ...@@ -260,6 +264,9 @@ vlc_module_begin();
ARATE_LONGTEXT, VLC_TRUE ); ARATE_LONGTEXT, VLC_TRUE );
add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT, add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
ASYNC_LONGTEXT, VLC_FALSE ); ASYNC_LONGTEXT, VLC_FALSE );
add_module_list_cat( SOUT_CFG_PREFIX "afilter", SUBCAT_AUDIO_MISC,
NULL, NULL,
AFILTER_TEXT, AFILTER_LONGTEXT, VLC_FALSE );
set_section( N_("Overlays/Subtitles"), NULL ); set_section( N_("Overlays/Subtitles"), NULL );
add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT, add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
...@@ -290,7 +297,7 @@ static const char *ppsz_sout_options[] = { ...@@ -290,7 +297,7 @@ static const char *ppsz_sout_options[] = {
"canvas-width", "canvas-height", "canvas-aspect", "canvas-width", "canvas-height", "canvas-aspect",
"scale", "fps", "width", "height", "vfilter", "deinterlace", "scale", "fps", "width", "height", "vfilter", "deinterlace",
"deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab", "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
"samplerate", "channels", "senc", "scodec", "soverlay", "sfilter", "afilter", "samplerate", "channels", "senc", "scodec", "soverlay", "sfilter",
"osd", "audio-sync", "high-priority", "maxwidth", "maxheight", NULL "osd", "audio-sync", "high-priority", "maxwidth", "maxheight", NULL
}; };
...@@ -348,6 +355,7 @@ static int pi_channels_maps[6] = ...@@ -348,6 +355,7 @@ static int pi_channels_maps[6] =
#define PICTURE_RING_SIZE 64 #define PICTURE_RING_SIZE 64
#define SUBPICTURE_RING_SIZE 20 #define SUBPICTURE_RING_SIZE 20
#define TRANSCODE_FILTERS 10
struct sout_stream_sys_t struct sout_stream_sys_t
{ {
...@@ -366,8 +374,11 @@ struct sout_stream_sys_t ...@@ -366,8 +374,11 @@ struct sout_stream_sys_t
char *psz_aenc; char *psz_aenc;
sout_cfg_t *p_audio_cfg; sout_cfg_t *p_audio_cfg;
int i_sample_rate; int i_sample_rate;
int i_channels; unsigned int i_channels;
int i_abitrate; int i_abitrate;
char *psz_afilters[TRANSCODE_FILTERS];
sout_cfg_t *p_afilters_cfg[TRANSCODE_FILTERS];
int i_afilters;
/* Video */ /* Video */
vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */ vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
...@@ -384,8 +395,8 @@ struct sout_stream_sys_t ...@@ -384,8 +395,8 @@ struct sout_stream_sys_t
int i_threads; int i_threads;
vlc_bool_t b_high_priority; vlc_bool_t b_high_priority;
vlc_bool_t b_hurry_up; vlc_bool_t b_hurry_up;
char *psz_vfilters[10]; char *psz_vfilters[TRANSCODE_FILTERS];
sout_cfg_t *p_vfilters_cfg[10]; sout_cfg_t *p_vfilters_cfg[TRANSCODE_FILTERS];
int i_vfilters; int i_vfilters;
int i_crop_top; int i_crop_top;
...@@ -502,8 +513,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -502,8 +513,8 @@ static int Open( vlc_object_t *p_this )
if( p_sys->i_acodec ) if( p_sys->i_acodec )
{ {
if( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) && if( ( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) ) &&
p_sys->i_channels > 2 ) ( p_sys->i_channels > 2 ) )
{ {
msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2", msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
p_sys->i_channels ); p_sys->i_channels );
...@@ -514,6 +525,31 @@ static int Open( vlc_object_t *p_this ) ...@@ -514,6 +525,31 @@ static int Open( vlc_object_t *p_this )
p_sys->i_channels, p_sys->i_abitrate / 1000 ); p_sys->i_channels, p_sys->i_abitrate / 1000 );
} }
var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
p_sys->i_afilters = 0;
if( val.psz_string && *val.psz_string )
{
char *psz_parser = val.psz_string;
while( (psz_parser != NULL) && (*psz_parser != '\0')
&& (p_sys->i_afilters < TRANSCODE_FILTERS) )
{
psz_parser = sout_CfgCreate(
&p_sys->psz_afilters[p_sys->i_afilters],
&p_sys->p_afilters_cfg[p_sys->i_afilters],
psz_parser );
p_sys->i_afilters++;
if( (psz_parser != NULL) && (*psz_parser != '\0') ) psz_parser++;
}
}
if( val.psz_string ) free( val.psz_string );
if( p_sys->i_afilters < TRANSCODE_FILTERS-1 )
{
p_sys->psz_afilters[p_sys->i_afilters] = NULL;
p_sys->p_afilters_cfg[p_sys->i_afilters] = NULL;
}
/* Video transcoding parameters */ /* Video transcoding parameters */
var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val ); var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
p_sys->psz_venc = NULL; p_sys->psz_venc = NULL;
...@@ -568,7 +604,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -568,7 +604,8 @@ static int Open( vlc_object_t *p_this )
{ {
char *psz_parser = val.psz_string; char *psz_parser = val.psz_string;
while( psz_parser != NULL && *psz_parser != '\0' ) while( psz_parser != NULL && *psz_parser != '\0'
&& (p_sys->i_vfilters < TRANSCODE_FILTERS) )
{ {
psz_parser = sout_CfgCreate( psz_parser = sout_CfgCreate(
&p_sys->psz_vfilters[p_sys->i_vfilters], &p_sys->psz_vfilters[p_sys->i_vfilters],
...@@ -579,8 +616,12 @@ static int Open( vlc_object_t *p_this ) ...@@ -579,8 +616,12 @@ static int Open( vlc_object_t *p_this )
} }
} }
if( val.psz_string ) free( val.psz_string ); if( val.psz_string ) free( val.psz_string );
p_sys->psz_vfilters[p_sys->i_vfilters] = NULL;
p_sys->p_vfilters_cfg[p_sys->i_vfilters] = NULL; if( p_sys->i_vfilters < TRANSCODE_FILTERS-1 )
{
p_sys->psz_vfilters[p_sys->i_vfilters] = NULL;
p_sys->p_vfilters_cfg[p_sys->i_vfilters] = NULL;
}
var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val ); var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
p_sys->b_deinterlace = val.b_bool; p_sys->b_deinterlace = val.b_bool;
...@@ -633,7 +674,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -633,7 +674,6 @@ static int Open( vlc_object_t *p_this )
VOUT_ASPECT_FACTOR / atoi( psz_parser ); VOUT_ASPECT_FACTOR / atoi( psz_parser );
} }
else msg_Warn( p_stream, "bad aspect ratio %s", val.psz_string ); else msg_Warn( p_stream, "bad aspect ratio %s", val.psz_string );
} }
if( val.psz_string ) free( val.psz_string ); if( val.psz_string ) free( val.psz_string );
...@@ -838,9 +878,9 @@ struct sout_stream_id_t ...@@ -838,9 +878,9 @@ struct sout_stream_id_t
decoder_t *p_decoder; decoder_t *p_decoder;
/* Filters */ /* Filters */
filter_t *pp_filter[10]; filter_t *pp_filter[TRANSCODE_FILTERS];
int i_filter; int i_filter;
filter_t *pp_vfilter[10]; filter_t *pp_vfilter[TRANSCODE_FILTERS];
int i_vfilter; int i_vfilter;
/* Encoder */ /* Encoder */
...@@ -904,12 +944,12 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ) ...@@ -904,12 +944,12 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
/* Complete destination format */ /* Complete destination format */
id->p_encoder->fmt_out.i_codec = p_sys->i_acodec; id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ? id->p_encoder->fmt_out.audio.i_rate = ( p_sys->i_sample_rate > 0 ) ?
p_sys->i_sample_rate : (int)p_fmt->audio.i_rate; p_sys->i_sample_rate : (int)p_fmt->audio.i_rate;
id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate; id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
id->p_encoder->fmt_out.audio.i_bitspersample = id->p_encoder->fmt_out.audio.i_bitspersample =
p_fmt->audio.i_bitspersample; p_fmt->audio.i_bitspersample;
id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ? id->p_encoder->fmt_out.audio.i_channels = ( p_sys->i_channels > 0 ) ?
p_sys->i_channels : p_fmt->audio.i_channels; p_sys->i_channels : p_fmt->audio.i_channels;
/* Sanity check for audio channels */ /* Sanity check for audio channels */
id->p_encoder->fmt_out.audio.i_channels = id->p_encoder->fmt_out.audio.i_channels =
...@@ -1210,8 +1250,10 @@ static int audio_BitsPerSample( vlc_fourcc_t i_format ) ...@@ -1210,8 +1250,10 @@ static int audio_BitsPerSample( vlc_fourcc_t i_format )
static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream, static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
sout_stream_id_t *id, sout_stream_id_t *id,
es_format_t *p_fmt_in, es_format_t *p_fmt_in,
es_format_t *p_fmt_out ) es_format_t *p_fmt_out,
const char *psz_name )
{ {
sout_stream_sys_t *p_sys = p_stream->p_sys;
filter_t *p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER ); filter_t *p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER );
vlc_object_attach( p_filter, p_stream ); vlc_object_attach( p_filter, p_stream );
...@@ -1220,7 +1262,10 @@ static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream, ...@@ -1220,7 +1262,10 @@ static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
p_filter->fmt_in = *p_fmt_in; p_filter->fmt_in = *p_fmt_in;
p_filter->fmt_out = *p_fmt_out; p_filter->fmt_out = *p_fmt_out;
p_filter->p_module = module_Need( p_filter, "audio filter2", 0, 0 ); if( psz_name )
p_filter->p_cfg = p_sys->p_afilters_cfg[id->i_filter];
p_filter->p_module = module_Need( p_filter, "audio filter2", psz_name, 0 );
if( p_filter->p_module ) if( p_filter->p_module )
{ {
p_filter->fmt_out.audio.i_bitspersample = p_filter->fmt_out.audio.i_bitspersample =
...@@ -1243,6 +1288,7 @@ static int transcode_audio_new( sout_stream_t *p_stream, ...@@ -1243,6 +1288,7 @@ static int transcode_audio_new( sout_stream_t *p_stream,
sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_sys_t *p_sys = p_stream->p_sys;
es_format_t fmt_last; es_format_t fmt_last;
int i_pass = 6; int i_pass = 6;
int i;
/* /*
* Open decoder * Open decoder
...@@ -1317,24 +1363,26 @@ static int transcode_audio_new( sout_stream_t *p_stream, ...@@ -1317,24 +1363,26 @@ static int transcode_audio_new( sout_stream_t *p_stream,
fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2'); fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
id->pp_filter[id->i_filter] = id->pp_filter[id->i_filter] =
transcode_audio_filter_new( p_stream, id, &fmt_last, &fmt_out ); transcode_audio_filter_new( p_stream, id, &fmt_last, &fmt_out, NULL );
if( id->pp_filter[id->i_filter] ) id->i_filter++; if( id->pp_filter[id->i_filter] ) id->i_filter++;
} }
while( i_pass-- ) while( i_pass-- )
{ {
if( fmt_last.audio.i_channels != if( ( fmt_last.audio.i_channels !=
id->p_encoder->fmt_in.audio.i_channels || id->p_encoder->fmt_in.audio.i_channels ) ||
fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate || ( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate ) ||
fmt_last.i_codec != id->p_encoder->fmt_in.i_codec ) ( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec ) )
{ {
id->pp_filter[id->i_filter] = id->pp_filter[id->i_filter] =
transcode_audio_filter_new( p_stream, id, &fmt_last, transcode_audio_filter_new( p_stream, id, &fmt_last,
&id->p_encoder->fmt_in ); &id->p_encoder->fmt_in, NULL );
if( id->pp_filter[id->i_filter] ) id->i_filter++; if( id->pp_filter[id->i_filter] )
else break; id->i_filter++;
else
break;
} }
} }
...@@ -1348,6 +1396,21 @@ static int transcode_audio_new( sout_stream_t *p_stream, ...@@ -1348,6 +1396,21 @@ static int transcode_audio_new( sout_stream_t *p_stream,
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Load user specified audio filters now */
for( i = 0; (i < p_sys->i_afilters) &&
(id->i_filter < TRANSCODE_FILTERS); i++ )
{
id->pp_filter[id->i_filter] =
transcode_audio_filter_new( p_stream, id, &fmt_last,
&id->p_encoder->fmt_in,
p_sys->psz_afilters[i] );
if( id->pp_filter[id->i_filter] )
id->i_filter++;
else
break;
}
if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ) if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
{ {
#if 1 #if 1
...@@ -1437,6 +1500,7 @@ static void transcode_audio_close( sout_stream_t *p_stream, ...@@ -1437,6 +1500,7 @@ static void transcode_audio_close( sout_stream_t *p_stream,
if( id->pp_filter[i]->p_module ) if( id->pp_filter[i]->p_module )
module_Unneed( id->pp_filter[i], 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_destroy( id->pp_filter[i] );
id->pp_filter[i] = NULL;
} }
} }
...@@ -1620,7 +1684,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) ...@@ -1620,7 +1684,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{ {
msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_venc ); msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_venc );
module_Unneed( id->p_decoder, 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;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -1648,7 +1712,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) ...@@ -1648,7 +1712,7 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{ {
msg_Err( p_stream, "cannot spawn encoder thread" ); msg_Err( p_stream, "cannot spawn encoder thread" );
module_Unneed( id->p_decoder, 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;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
...@@ -2006,6 +2070,7 @@ static void transcode_video_close( sout_stream_t *p_stream, ...@@ -2006,6 +2070,7 @@ static void transcode_video_close( sout_stream_t *p_stream,
free( id->pp_filter[i]->p_owner ); free( id->pp_filter[i]->p_owner );
vlc_object_destroy( id->pp_filter[i] ); vlc_object_destroy( id->pp_filter[i] );
id->pp_filter[i] = NULL;
} }
for( i = 0; i < id->i_vfilter; i++ ) for( i = 0; i < id->i_vfilter; i++ )
{ {
......
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