Commit c9a57e4d authored by Rafaël Carré's avatar Rafaël Carré

avcodec: support private options

Usage:
--avcodec-options='{lowres=3,foobar=baz}'
--sout-avcodec-options='{threads=42}'

For now the decoder options are global, they apply to audio/video/subtitles decoder.
encoder options can be set in the sout chain, specific to each ES
parent 39c41fec
...@@ -144,6 +144,7 @@ vlc_module_begin () ...@@ -144,6 +144,7 @@ vlc_module_begin ()
add_obsolete_integer( "ffmpeg-threads" ) /* removed since 2.1.0 */ add_obsolete_integer( "ffmpeg-threads" ) /* removed since 2.1.0 */
add_integer( "avcodec-threads", 0, THREADS_TEXT, THREADS_LONGTEXT, true ); add_integer( "avcodec-threads", 0, THREADS_TEXT, THREADS_LONGTEXT, true );
#endif #endif
add_string( "avcodec-options", NULL, AV_OPTIONS_TEXT, AV_OPTIONS_LONGTEXT, true )
#ifdef ENABLE_SOUT #ifdef ENABLE_SOUT
...@@ -239,6 +240,8 @@ vlc_module_begin () ...@@ -239,6 +240,8 @@ vlc_module_begin ()
/* Audio AAC encoder profile */ /* Audio AAC encoder profile */
add_string( ENC_CFG_PREFIX "aac-profile", "low", add_string( ENC_CFG_PREFIX "aac-profile", "low",
ENC_PROFILE_TEXT, ENC_PROFILE_LONGTEXT, true ) ENC_PROFILE_TEXT, ENC_PROFILE_LONGTEXT, true )
add_string( ENC_CFG_PREFIX "options", NULL, AV_OPTIONS_TEXT, AV_OPTIONS_LONGTEXT, true )
#endif /* ENABLE_SOUT */ #endif /* ENABLE_SOUT */
#ifdef MERGE_FFMPEG #ifdef MERGE_FFMPEG
...@@ -416,9 +419,22 @@ int ffmpeg_OpenCodec( decoder_t *p_dec ) ...@@ -416,9 +419,22 @@ int ffmpeg_OpenCodec( decoder_t *p_dec )
p_sys->p_context->sample_rate; p_sys->p_context->sample_rate;
} }
int ret; int ret;
char *psz_opts = var_InheritString( p_dec, "avcodec-options" );
AVDictionary *options = NULL;
if (psz_opts && *psz_opts)
options = vlc_av_get_options(psz_opts);
free(psz_opts);
vlc_avcodec_lock(); vlc_avcodec_lock();
ret = avcodec_open2( p_sys->p_context, p_sys->p_codec, NULL /* options */ ); ret = avcodec_open2( p_sys->p_context, p_sys->p_codec, options ? &options : NULL );
vlc_avcodec_unlock(); vlc_avcodec_unlock();
AVDictionaryEntry *t = NULL;
while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
msg_Err( p_dec, "Unknown option \"%s\"", t->key );
}
av_dict_free(&options);
if( ret < 0 ) if( ret < 0 )
return VLC_EGENERIC; return VLC_EGENERIC;
msg_Dbg( p_dec, "avcodec codec (%s) started", p_sys->psz_namecodec ); msg_Dbg( p_dec, "avcodec codec (%s) started", p_sys->psz_namecodec );
......
...@@ -158,7 +158,7 @@ static const char *const ppsz_enc_options[] = { ...@@ -158,7 +158,7 @@ static const char *const ppsz_enc_options[] = {
#if (LIBAVCODEC_VERSION_MAJOR < 55) #if (LIBAVCODEC_VERSION_MAJOR < 55)
"luma-elim-threshold", "chroma-elim-threshold", "luma-elim-threshold", "chroma-elim-threshold",
#endif #endif
"aac-profile", "aac-profile", "options",
NULL NULL
}; };
...@@ -738,9 +738,21 @@ int OpenEncoder( vlc_object_t *p_this ) ...@@ -738,9 +738,21 @@ int OpenEncoder( vlc_object_t *p_this )
p_context->thread_count = vlc_GetCPUCount(); p_context->thread_count = vlc_GetCPUCount();
int ret; int ret;
char *psz_opts = var_InheritString(p_enc, ENC_CFG_PREFIX "options");
AVDictionary *options = NULL;
if (psz_opts && *psz_opts)
options = vlc_av_get_options(psz_opts);
free(psz_opts);
vlc_avcodec_lock(); vlc_avcodec_lock();
ret = avcodec_open2( p_context, p_codec, NULL /* options */ ); ret = avcodec_open2( p_context, p_codec, options ? &options : NULL );
vlc_avcodec_unlock(); vlc_avcodec_unlock();
AVDictionaryEntry *t = NULL;
while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
msg_Err(p_enc, "Unknown option \"%s\"", t->key);
}
if( ret ) if( ret )
{ {
if( p_enc->fmt_in.i_cat != AUDIO_ES || if( p_enc->fmt_in.i_cat != AUDIO_ES ||
...@@ -750,8 +762,8 @@ int OpenEncoder( vlc_object_t *p_this ) ...@@ -750,8 +762,8 @@ int OpenEncoder( vlc_object_t *p_this )
msg_Err( p_enc, "cannot open encoder" ); msg_Err( p_enc, "cannot open encoder" );
dialog_Fatal( p_enc, _("Streaming / Transcoding failed"), dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
"%s", _("VLC could not open the encoder.") ); "%s", _("VLC could not open the encoder.") );
free( p_sys ); av_dict_free(&options);
return VLC_EGENERIC; goto error;
} }
if( p_context->channels > 2 ) if( p_context->channels > 2 )
...@@ -774,8 +786,8 @@ int OpenEncoder( vlc_object_t *p_this ) ...@@ -774,8 +786,8 @@ int OpenEncoder( vlc_object_t *p_this )
{ {
msg_Err( p_enc, "MPEG audio doesn't support frequency=%d", msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
fmt->audio.i_rate ); fmt->audio.i_rate );
free( p_sys ); av_dict_free(&options);
return VLC_EGENERIC; goto error;
} }
for ( i = 1; i < 14; i++ ) for ( i = 1; i < 14; i++ )
...@@ -795,7 +807,7 @@ int OpenEncoder( vlc_object_t *p_this ) ...@@ -795,7 +807,7 @@ int OpenEncoder( vlc_object_t *p_this )
p_context->codec = NULL; p_context->codec = NULL;
vlc_avcodec_lock(); vlc_avcodec_lock();
ret = avcodec_open2( p_context, p_codec, NULL /* options */ ); ret = avcodec_open2( p_context, p_codec, options ? &options : NULL );
vlc_avcodec_unlock(); vlc_avcodec_unlock();
if( ret ) if( ret )
{ {
...@@ -803,11 +815,13 @@ int OpenEncoder( vlc_object_t *p_this ) ...@@ -803,11 +815,13 @@ int OpenEncoder( vlc_object_t *p_this )
dialog_Fatal( p_enc, dialog_Fatal( p_enc,
_("Streaming / Transcoding failed"), _("Streaming / Transcoding failed"),
"%s", _("VLC could not open the encoder.") ); "%s", _("VLC could not open the encoder.") );
free( p_sys ); av_dict_free(&options);
return VLC_EGENERIC; goto error;
} }
} }
av_dict_free(&options);
if( i_codec_id == AV_CODEC_ID_FLAC ) if( i_codec_id == AV_CODEC_ID_FLAC )
{ {
p_enc->fmt_out.i_extra = 4 + 1 + 3 + p_context->extradata_size; p_enc->fmt_out.i_extra = 4 + 1 + 3 + p_context->extradata_size;
......
...@@ -82,9 +82,22 @@ int InitSubtitleDec(decoder_t *dec, AVCodecContext *context, ...@@ -82,9 +82,22 @@ int InitSubtitleDec(decoder_t *dec, AVCodecContext *context,
/* */ /* */
int ret; int ret;
char *psz_opts = var_InheritString(dec, "avcodec-options");
AVDictionary *options = NULL;
if (psz_opts && *psz_opts)
options = vlc_av_get_options(psz_opts);
free(psz_opts);
vlc_avcodec_lock(); vlc_avcodec_lock();
ret = avcodec_open2(context, codec, NULL /* options */); ret = avcodec_open2(context, codec, options ? &options : NULL);
vlc_avcodec_unlock(); vlc_avcodec_unlock();
AVDictionaryEntry *t = NULL;
while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
msg_Err(dec, "Unknown option \"%s\"", t->key);
}
av_dict_free(&options);
if (ret < 0) { if (ret < 0) {
msg_Err(dec, "cannot open codec (%s)", namecodec); msg_Err(dec, "cannot open codec (%s)", namecodec);
free(context->extradata); free(context->extradata);
......
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