summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorAman Gupta <aman@tmm1.net>2018-07-18 11:52:33 -0700
committerAman Gupta <aman@tmm1.net>2018-07-19 09:15:13 -0700
commit37644f047703aab4562429d9e4441ba6b4eab8ca (patch)
tree9fafa70273d18474fd0d3b2ce13b8e563a9572b1 /libavcodec
parentb420fead53b1788dfa704a4bf4643a4a0787bb1d (diff)
downloadffmpeg-37644f047703aab4562429d9e4441ba6b4eab8ca.tar.gz
avcodec: parse options from AVCodec.bsfs
Fixes a bug that would prevent using multiple comma-separated filters, and allows options to be passed to each filter. Based on similar loop in ffmpeg_opt.c's new_output_stream(). Signed-off-by: Aman Gupta <aman@tmm1.net>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/decode.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 6a3a4df179..db364ca700 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -36,6 +36,7 @@
#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/intmath.h"
+#include "libavutil/opt.h"
#include "avcodec.h"
#include "bytestream.h"
@@ -195,27 +196,33 @@ static int bsfs_init(AVCodecContext *avctx)
while (bsfs_str && *bsfs_str) {
AVBSFContext **tmp;
const AVBitStreamFilter *filter;
- char *bsf;
+ char *bsf, *bsf_options_str, *bsf_name;
bsf = av_get_token(&bsfs_str, ",");
if (!bsf) {
ret = AVERROR(ENOMEM);
goto fail;
}
+ bsf_name = av_strtok(bsf, "=", &bsf_options_str);
+ if (!bsf_name) {
+ av_freep(&bsf);
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
- filter = av_bsf_get_by_name(bsf);
+ filter = av_bsf_get_by_name(bsf_name);
if (!filter) {
av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s "
"requested by a decoder. This is a bug, please report it.\n",
- bsf);
- ret = AVERROR_BUG;
+ bsf_name);
av_freep(&bsf);
+ ret = AVERROR_BUG;
goto fail;
}
- av_freep(&bsf);
tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs));
if (!tmp) {
+ av_freep(&bsf);
ret = AVERROR(ENOMEM);
goto fail;
}
@@ -223,8 +230,10 @@ static int bsfs_init(AVCodecContext *avctx)
s->nb_bsfs++;
ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]);
- if (ret < 0)
+ if (ret < 0) {
+ av_freep(&bsf);
goto fail;
+ }
if (s->nb_bsfs == 1) {
/* We do not currently have an API for passing the input timebase into decoders,
@@ -238,12 +247,38 @@ static int bsfs_init(AVCodecContext *avctx)
ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in,
s->bsfs[s->nb_bsfs - 2]->par_out);
}
- if (ret < 0)
+ if (ret < 0) {
+ av_freep(&bsf);
goto fail;
+ }
+
+ if (bsf_options_str && filter->priv_class) {
+ const AVOption *opt = av_opt_next(s->bsfs[s->nb_bsfs - 1]->priv_data, NULL);
+ const char * shorthand[2] = {NULL};
+
+ if (opt)
+ shorthand[0] = opt->name;
+
+ ret = av_opt_set_from_string(s->bsfs[s->nb_bsfs - 1]->priv_data, bsf_options_str, shorthand, "=", ":");
+ if (ret < 0) {
+ if (ret != AVERROR(ENOMEM)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid options for bitstream filter %s "
+ "requested by the decoder. This is a bug, please report it.\n",
+ bsf_name);
+ ret = AVERROR_BUG;
+ }
+ av_freep(&bsf);
+ goto fail;
+ }
+ }
+ av_freep(&bsf);
ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]);
if (ret < 0)
goto fail;
+
+ if (*bsfs_str)
+ bsfs_str++;
}
return 0;