123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- From 143033b48bc77061fd9286fb00c82160cd8b8de3 Mon Sep 17 00:00:00 2001
- From: Alexandre Janniaux <alexandre.janniaux@gmail.com>
- Date: Wed, 28 Nov 2018 18:27:16 +0100
- Subject: [PATCH 25/26] transcode: add support for mutliple venc parameters
- Add support for multiple venc parameters for transcoding. Venc
- parameters are tested in th given order and fallback if the encoder
- can't be opened.
- For example:
- --sout#transcode{\
- venc={vcodec=h264,module=avcodec{...}},\
- venc={vcodec=VP80,module=vpx{...}}}
- will first try avcodec module with h264 video format, then vpx module
- with VP8 video format.
- ---
- modules/stream_out/transcode/transcode.c | 258 ++++++++++++++++++-----
- modules/stream_out/transcode/transcode.h | 2 +
- 2 files changed, 205 insertions(+), 55 deletions(-)
- diff --git a/modules/stream_out/transcode/transcode.c b/modules/stream_out/transcode/transcode.c
- index c92dd4a974..bc9f9e694a 100644
- --- a/modules/stream_out/transcode/transcode.c
- +++ b/modules/stream_out/transcode/transcode.c
- @@ -153,6 +153,9 @@ vlc_module_begin ()
- set_section( N_("Video"), NULL )
- add_module( SOUT_CFG_PREFIX "venc", "encoder", NULL, VENC_TEXT,
- VENC_LONGTEXT, false )
- + /* XXX: VERY HACKY */
- + add_string( SOUT_CFG_PREFIX "module", NULL,
- + "define the venc module in venc{} parameters", "", true )
- add_string( SOUT_CFG_PREFIX "vcodec", NULL, VCODEC_TEXT,
- VCODEC_LONGTEXT, false )
- add_integer( SOUT_CFG_PREFIX "vb", 0, VB_TEXT,
- @@ -219,7 +222,7 @@ vlc_module_begin ()
- vlc_module_end ()
-
- static const char *const ppsz_sout_options[] = {
- - "venc", "vcodec", "vb",
- + "vcodec", "vb",
- "scale", "fps", "width", "height", "vfilter", "deinterlace",
- "deinterlace-module", "threads", "aenc", "acodec", "ab", "alang",
- "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
- @@ -227,6 +230,10 @@ static const char *const ppsz_sout_options[] = {
- NULL
- };
-
- +static const char *const ppsz_venc_options[] = {
- + "vcodec", "module", NULL
- +};
- +
- /*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
- @@ -241,6 +248,7 @@ static int Open( vlc_object_t *p_this )
- {
- sout_stream_t *p_stream = (sout_stream_t*)p_this;
- sout_stream_sys_t *p_sys;
- + config_chain_t *p_cfg;
- char *psz_string;
-
- if( !p_stream->p_next )
- @@ -251,8 +259,17 @@ static int Open( vlc_object_t *p_this )
- p_sys = calloc( 1, sizeof( *p_sys ) );
- p_sys->i_master_drift = 0;
-
- + ARRAY_INIT( p_sys->pp_vencs );
- +
- + for( p_cfg = p_stream->p_cfg; p_cfg; p_cfg = p_cfg->p_next )
- + {
- + if( !strcmp( p_cfg->psz_name, "venc" ) )
- + ARRAY_APPEND(p_sys->pp_vencs, p_cfg);
- + }
- +
- + /* Parse the other option (except venc) */
- config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
- - p_stream->p_cfg );
- + p_stream->p_cfg );
-
- /* Audio transcoding parameters */
- psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "aenc" );
- @@ -310,29 +327,6 @@ static int Open( vlc_object_t *p_this )
- free( psz_string );
-
- /* Video transcoding parameters */
- - psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "venc" );
- - p_sys->psz_venc = NULL;
- - p_sys->p_video_cfg = NULL;
- - if( psz_string && *psz_string )
- - {
- - char *psz_next;
- - psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
- - psz_string );
- - free( psz_next );
- - }
- - free( psz_string );
- -
- - psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vcodec" );
- - p_sys->i_vcodec = 0;
- - if( psz_string && *psz_string )
- - {
- - char fcc[5] = " \0";
- - memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) );
- - p_sys->i_vcodec = vlc_fourcc_GetCodecFromString( VIDEO_ES, fcc );
- - msg_Dbg( p_stream, "Checking video codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_vcodec);
- - }
- - free( psz_string );
- -
- p_sys->i_vbitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "vb" );
- if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
-
- @@ -435,6 +429,11 @@ static void Close( vlc_object_t * p_this )
- sout_stream_t *p_stream = (sout_stream_t*)p_this;
- sout_stream_sys_t *p_sys = p_stream->p_sys;
-
- + if( p_sys->p_venc_conf )
- + vlc_object_release( p_sys->p_venc_conf );
- +
- + ARRAY_RESET(p_sys->pp_vencs);
- +
- free( p_sys->psz_af );
-
- config_ChainDestroy( p_sys->p_audio_cfg );
- @@ -481,6 +480,30 @@ static void DeleteSoutStreamID( sout_stream_id_sys_t *id )
- }
- }
-
- +static encoder_t *InitEncoder( vlc_object_t *p_parent,
- + sout_stream_t *p_stream,
- + const es_format_t *p_fmt )
- +{
- + sout_stream_sys_t *p_sys = p_stream->p_sys;
- + encoder_t *p_encoder = sout_EncoderCreate( p_parent );
- + if( !p_encoder )
- + return NULL;
- + p_encoder->p_module = NULL;
- +
- + /* Create destination format */
- + es_format_Init( &p_encoder->fmt_in, p_fmt->i_cat, 0 );
- + es_format_Init( &p_encoder->fmt_out, p_fmt->i_cat, 0 );
- + p_encoder->fmt_out.i_id = p_fmt->i_id;
- + p_encoder->fmt_out.i_group = p_fmt->i_group;
- +
- + if( p_sys->psz_alang )
- + p_encoder->fmt_out.psz_language = strdup( p_sys->psz_alang );
- + else if( p_fmt->psz_language )
- + p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
- +
- + return p_encoder;
- +}
- +
- static sout_stream_id_sys_t *Add( sout_stream_t *p_stream,
- const es_format_t *p_fmt )
- {
- @@ -499,49 +522,174 @@ static sout_stream_id_sys_t *Add( sout_stream_t *p_stream,
- /* Create decoder object */
- id->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) );
- if( !id->p_decoder )
- + {
- + msg_Err( p_stream, "cannot create decoder" );
- goto error;
- + }
- id->p_decoder->p_module = NULL;
- es_format_Init( &id->p_decoder->fmt_out, p_fmt->i_cat, 0 );
- es_format_Copy( &id->p_decoder->fmt_in, p_fmt );
- id->p_decoder->b_frame_drop_allowed = false;
-
- /* Create encoder object */
- - id->p_encoder = sout_EncoderCreate( p_stream );
- - if( !id->p_encoder )
- - goto error;
- - id->p_encoder->p_module = NULL;
- -
- - /* Create destination format */
- - es_format_Init( &id->p_encoder->fmt_in, p_fmt->i_cat, 0 );
- - es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
- - id->p_encoder->fmt_out.i_id = p_fmt->i_id;
- - id->p_encoder->fmt_out.i_group = p_fmt->i_group;
- + if( p_fmt->i_cat == VIDEO_ES &&
- + ( p_sys->i_vcodec || p_sys->pp_vencs.i_size > 0 ) )
- + {
- + for( int config_idx=0;
- + config_idx<p_sys->pp_vencs.i_size;
- + config_idx++ )
- + {
- + config_chain_t *p_enc_cfg = ARRAY_VAL( p_sys->pp_vencs, config_idx );
- +
- + /* the encoder config will be hold by the encoder if it succeed */
- + p_sys->p_venc_conf =
- + vlc_object_create( p_stream, sizeof(vlc_object_t) );
- +
- + msg_Dbg( p_stream, "trying configuration venc={%s}",
- + p_enc_cfg->psz_value );
- +
- + size_t length = strlen( p_enc_cfg->psz_value );
- + size_t first_equal = strcspn( p_enc_cfg->psz_value, "=" );
- + size_t first_brace = strcspn( p_enc_cfg->psz_value, "{" );
- + size_t first_comma = strcspn( p_enc_cfg->psz_value, "," );
- +
- + config_ChainDestroy( p_sys->p_video_cfg );
- + free( p_sys->psz_venc );
- +
- + p_sys->psz_venc = NULL;
- + p_sys->p_video_cfg = NULL;
- +
- + if( first_comma == length
- + && first_equal > first_brace )
- + {
- + /* venc configuration is in the legacy form */
- + char *psz_next;
- + psz_next = config_ChainCreate( &p_sys->psz_venc,
- + &p_sys->p_video_cfg,
- + p_enc_cfg->psz_value );
- + free( psz_next );
- + }
- + else
- + {
- + /* venc configuration is in the new extended form */
- + config_chain_t *p_conf;
- + config_ChainParseOptions( &p_conf, p_enc_cfg->psz_value );
- + config_ChainParse( p_sys->p_venc_conf, SOUT_CFG_PREFIX,
- + ppsz_venc_options, p_conf );
- + config_ChainDestroy( p_conf );
- +
- + p_sys->psz_venc = NULL;
- + p_sys->p_video_cfg = NULL;
- + char *psz_string = var_GetString( p_sys->p_venc_conf,
- + SOUT_CFG_PREFIX "module" );
- +
- +
- + if( !psz_string )
- + {
- + msg_Err( p_stream,
- + "missing key \"encoder\" in extended venc option: %s",
- + p_enc_cfg->psz_value );
- + vlc_object_release( p_sys->p_venc_conf );
- + p_sys->p_venc_conf = NULL;
- + continue;
- + }
- +
- +
- + char *psz_next;
- + psz_next = config_ChainCreate( &p_sys->psz_venc,
- + &p_sys->p_video_cfg,
- + psz_string );
- + free( psz_next );
- + free( psz_string );
- + }
- +
- + char *psz_vcodec = var_GetString( p_sys->p_venc_conf,
- + SOUT_CFG_PREFIX "vcodec" );
- + if( psz_vcodec == NULL )
- + psz_vcodec = var_InheritString( p_sys->p_venc_conf,
- + SOUT_CFG_PREFIX "vcodec" );
- + p_sys->i_vcodec = 0;
- + if( psz_vcodec && *psz_vcodec )
- + {
- + char fcc[5] = " \0";
- + memcpy( fcc, psz_vcodec, __MIN( strlen( psz_vcodec ), 4 ) );
- + p_sys->i_vcodec = vlc_fourcc_GetCodecFromString( VIDEO_ES, fcc );
- + msg_Dbg( p_stream, "Checking video codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_vcodec);
- + }
- + free( psz_vcodec );
- +
- +
- + id->p_encoder = InitEncoder( p_sys->p_venc_conf, p_stream, p_fmt );
- + if( !id->p_encoder )
- + {
- + msg_Warn( p_stream, "cannot initialize encoder" );
- + vlc_object_release( p_sys->p_venc_conf );
- + p_sys->p_venc_conf = NULL;
- + continue;
- + }
- +
- + if( !p_sys->i_vcodec )
- + {
- + msg_Warn( p_stream,
- + "cannot use config venc={%s}, no vcodec defined",
- + p_enc_cfg->psz_value );
- +
- + es_format_Clean( &id->p_encoder->fmt_out );
- + vlc_object_release( p_sys->p_venc_conf );
- + p_sys->p_venc_conf = NULL;
- +
- + vlc_object_release( id->p_encoder );
- + id->p_encoder = NULL;
- + continue;
- + }
- +
- + if( !transcode_video_add( p_stream, p_fmt, id ) )
- + {
- + msg_Warn( p_stream,
- + "can't use transcode configuration with venc=%s",
- + p_enc_cfg->psz_value );
- + es_format_Clean( &id->p_encoder->fmt_out );
- +
- + vlc_object_release( p_sys->p_venc_conf );
- + p_sys->p_venc_conf = NULL;
- +
- + vlc_object_release( id->p_encoder );
- + id->p_encoder = NULL;
- + continue;
- + }
- +
- + msg_Info( p_stream, "using venc={%s} configuration for transcoding",
- + p_enc_cfg->psz_value );
- + break;
- + }
- + }
- + else
- + {
- + id->p_encoder = InitEncoder( VLC_OBJECT(p_stream), p_stream, p_fmt );
-
- - if( p_sys->psz_alang )
- - id->p_encoder->fmt_out.psz_language = strdup( p_sys->psz_alang );
- - else if( p_fmt->psz_language )
- - id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
- + bool success;
-
- - bool success;
- + if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec )
- + success = transcode_audio_add(p_stream, p_fmt, id);
- + else if( ( p_fmt->i_cat == SPU_ES ) &&
- + ( p_sys->i_scodec || p_sys->b_soverlay ) )
- + success = transcode_spu_add(p_stream, p_fmt, id);
- + else
- + {
- + msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
- + (char*)&p_fmt->i_codec );
- + id->id = sout_StreamIdAdd( p_stream->p_next, p_fmt );
- + id->b_transcode = false;
-
- - if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec )
- - success = transcode_audio_add(p_stream, p_fmt, id);
- - else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec )
- - success = transcode_video_add(p_stream, p_fmt, id);
- - else if( ( p_fmt->i_cat == SPU_ES ) &&
- - ( p_sys->i_scodec || p_sys->b_soverlay ) )
- - success = transcode_spu_add(p_stream, p_fmt, id);
- - else
- - {
- - msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
- - (char*)&p_fmt->i_codec );
- - id->id = sout_StreamIdAdd( p_stream->p_next, p_fmt );
- - id->b_transcode = false;
- + success = id->id;
- + }
-
- - success = id->id;
- + if (!success)
- + goto error;
- }
-
- - if(!success)
- +
- + if( !id->p_encoder )
- goto error;
-
- return id;
- diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
- index 1b5e886d94..e2ba426030 100644
- --- a/modules/stream_out/transcode/transcode.h
- +++ b/modules/stream_out/transcode/transcode.h
- @@ -38,6 +38,8 @@ struct sout_stream_sys_t
- char *psz_af;
-
- /* Video */
- + DECL_ARRAY(config_chain_t *) pp_vencs;
- + vlc_object_t *p_venc_conf;
- vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
- char *psz_venc;
- config_chain_t *p_video_cfg;
- --
- 2.20.1
|