Commit 37644f04 authored by Aman Gupta's avatar Aman Gupta

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: 's avatarAman Gupta <aman@tmm1.net>
parent b420fead
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
#include "libavutil/internal.h" #include "libavutil/internal.h"
#include "libavutil/intmath.h" #include "libavutil/intmath.h"
#include "libavutil/opt.h"
#include "avcodec.h" #include "avcodec.h"
#include "bytestream.h" #include "bytestream.h"
...@@ -195,27 +196,33 @@ static int bsfs_init(AVCodecContext *avctx) ...@@ -195,27 +196,33 @@ static int bsfs_init(AVCodecContext *avctx)
while (bsfs_str && *bsfs_str) { while (bsfs_str && *bsfs_str) {
AVBSFContext **tmp; AVBSFContext **tmp;
const AVBitStreamFilter *filter; const AVBitStreamFilter *filter;
char *bsf; char *bsf, *bsf_options_str, *bsf_name;
bsf = av_get_token(&bsfs_str, ","); bsf = av_get_token(&bsfs_str, ",");
if (!bsf) { if (!bsf) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; 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) { if (!filter) {
av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s " av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s "
"requested by a decoder. This is a bug, please report it.\n", "requested by a decoder. This is a bug, please report it.\n",
bsf); bsf_name);
ret = AVERROR_BUG;
av_freep(&bsf); av_freep(&bsf);
ret = AVERROR_BUG;
goto fail; goto fail;
} }
av_freep(&bsf);
tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs));
if (!tmp) { if (!tmp) {
av_freep(&bsf);
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
} }
...@@ -223,8 +230,10 @@ static int bsfs_init(AVCodecContext *avctx) ...@@ -223,8 +230,10 @@ static int bsfs_init(AVCodecContext *avctx)
s->nb_bsfs++; s->nb_bsfs++;
ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]); ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]);
if (ret < 0) if (ret < 0) {
av_freep(&bsf);
goto fail; goto fail;
}
if (s->nb_bsfs == 1) { if (s->nb_bsfs == 1) {
/* We do not currently have an API for passing the input timebase into decoders, /* We do not currently have an API for passing the input timebase into decoders,
...@@ -238,12 +247,38 @@ static int bsfs_init(AVCodecContext *avctx) ...@@ -238,12 +247,38 @@ static int bsfs_init(AVCodecContext *avctx)
ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in,
s->bsfs[s->nb_bsfs - 2]->par_out); s->bsfs[s->nb_bsfs - 2]->par_out);
} }
if (ret < 0) if (ret < 0) {
av_freep(&bsf);
goto fail; 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]); ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
if (*bsfs_str)
bsfs_str++;
} }
return 0; return 0;
......
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