Re: [FFmpeg-devel] [PATCH] avcodec/decode: use a single list bsf for codec decode bsfs
On Sat, 25 Apr 2020, James Almer wrote: On 4/25/2020 7:11 PM, Marton Balint wrote: Signed-off-by: Marton Balint --- libavcodec/cuviddec.c | 2 +- libavcodec/decode.c | 162 +++--- libavcodec/internal.h | 3 +- 3 files changed, 22 insertions(+), 145 deletions(-) diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index 50dc8956c3..13a7db10cd 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -946,7 +946,7 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) } if (avctx->codec->bsfs) { -const AVCodecParameters *par = avctx->internal->filter.bsfs[avctx->internal->filter.nb_bsfs - 1]->par_out; +const AVCodecParameters *par = avctx->internal->filter.bsf->par_out; ctx->cuparse_ext.format.seqhdr_data_length = par->extradata_size; memcpy(ctx->cuparse_ext.raw_seqhdr_data, par->extradata, diff --git a/libavcodec/decode.c b/libavcodec/decode.c index d4bdb9b1c0..167eaa6bb6 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -205,100 +205,28 @@ int ff_decode_bsfs_init(AVCodecContext *avctx) { AVCodecInternal *avci = avctx->internal; DecodeFilterContext *s = &avci->filter; -const char *bsfs_str; int ret; -if (s->nb_bsfs) +if (s->bsf) return 0; -bsfs_str = avctx->codec->bsfs ? avctx->codec->bsfs : "null"; If i'm reading this right, if the string passed to av_bsf_list_parse_str() results in no bsf being inserted to the list, ff_list_bsf acts the same as if it was the null bsf, right? Yes. -while (bsfs_str && *bsfs_str) { -AVBSFContext **tmp; -const AVBitStreamFilter *filter; -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_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_name); -av_freep(&bsf); -ret = AVERROR_BUG; -goto fail; -} - -tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); -if (!tmp) { -av_freep(&bsf); -ret = AVERROR(ENOMEM); -goto fail; -} -s->bsfs = tmp; - -ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs]); -if (ret < 0) { -av_freep(&bsf); -goto fail; -} -s->nb_bsfs++; - -if (s->nb_bsfs == 1) { -/* We do not currently have an API for passing the input timebase into decoders, - * but no filters used here should actually need it. - * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ -s->bsfs[s->nb_bsfs - 1]->time_base_in = (AVRational){ 1, 9 }; -ret = avcodec_parameters_from_context(s->bsfs[s->nb_bsfs - 1]->par_in, - avctx); -} else { -s->bsfs[s->nb_bsfs - 1]->time_base_in = s->bsfs[s->nb_bsfs - 2]->time_base_out; -ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, - s->bsfs[s->nb_bsfs - 2]->par_out); -} -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_list_parse_str(avctx->codec->bsfs, &s->bsf); +if (ret < 0) { +av_log(avctx, AV_LOG_ERROR, "Error parsing decoder bitstream filters '%s': %s\n", avctx->codec->bsfs, av_err2str(ret)); +goto fail; You should keep the AVERROR_BUG code from above. Decoders insert bsfs with hardcoded arguments and they absolutely must be valid. Otherwise it's a bug in our code. Return ENOMEM if that w
Re: [FFmpeg-devel] [PATCH] avcodec/decode: use a single list bsf for codec decode bsfs
On 4/25/2020 7:11 PM, Marton Balint wrote: > Signed-off-by: Marton Balint > --- > libavcodec/cuviddec.c | 2 +- > libavcodec/decode.c | 162 > +++--- > libavcodec/internal.h | 3 +- > 3 files changed, 22 insertions(+), 145 deletions(-) > > diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c > index 50dc8956c3..13a7db10cd 100644 > --- a/libavcodec/cuviddec.c > +++ b/libavcodec/cuviddec.c > @@ -946,7 +946,7 @@ static av_cold int cuvid_decode_init(AVCodecContext > *avctx) > } > > if (avctx->codec->bsfs) { > -const AVCodecParameters *par = > avctx->internal->filter.bsfs[avctx->internal->filter.nb_bsfs - 1]->par_out; > +const AVCodecParameters *par = avctx->internal->filter.bsf->par_out; > ctx->cuparse_ext.format.seqhdr_data_length = par->extradata_size; > memcpy(ctx->cuparse_ext.raw_seqhdr_data, > par->extradata, > diff --git a/libavcodec/decode.c b/libavcodec/decode.c > index d4bdb9b1c0..167eaa6bb6 100644 > --- a/libavcodec/decode.c > +++ b/libavcodec/decode.c > @@ -205,100 +205,28 @@ int ff_decode_bsfs_init(AVCodecContext *avctx) > { > AVCodecInternal *avci = avctx->internal; > DecodeFilterContext *s = &avci->filter; > -const char *bsfs_str; > int ret; > > -if (s->nb_bsfs) > +if (s->bsf) > return 0; > > -bsfs_str = avctx->codec->bsfs ? avctx->codec->bsfs : "null"; If i'm reading this right, if the string passed to av_bsf_list_parse_str() results in no bsf being inserted to the list, ff_list_bsf acts the same as if it was the null bsf, right? > -while (bsfs_str && *bsfs_str) { > -AVBSFContext **tmp; > -const AVBitStreamFilter *filter; > -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_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_name); > -av_freep(&bsf); > -ret = AVERROR_BUG; > -goto fail; > -} > - > -tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); > -if (!tmp) { > -av_freep(&bsf); > -ret = AVERROR(ENOMEM); > -goto fail; > -} > -s->bsfs = tmp; > - > -ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs]); > -if (ret < 0) { > -av_freep(&bsf); > -goto fail; > -} > -s->nb_bsfs++; > - > -if (s->nb_bsfs == 1) { > -/* We do not currently have an API for passing the input > timebase into decoders, > - * but no filters used here should actually need it. > - * So we make up some plausible-looking number (the MPEG 90kHz > timebase) */ > -s->bsfs[s->nb_bsfs - 1]->time_base_in = (AVRational){ 1, 9 }; > -ret = avcodec_parameters_from_context(s->bsfs[s->nb_bsfs - > 1]->par_in, > - avctx); > -} else { > -s->bsfs[s->nb_bsfs - 1]->time_base_in = s->bsfs[s->nb_bsfs - > 2]->time_base_out; > -ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, > - s->bsfs[s->nb_bsfs - 2]->par_out); > -} > -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_list_parse_str(avctx->codec->bsfs, &s->bsf); > +if (ret < 0) { > +av_log(avctx, AV_LOG_ERROR, "Error parsing decoder bitstream filters > '%s': %s\n", avctx->codec->bsfs, av_err2str(ret));