[FFmpeg-devel] [PATCH 5/8] avformat/mux: add proper support for full N:M bitstream filtering

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Sat Mar 28 23:53:52 EET 2020


Marton Balint:
> Previously only 1:1 bitstream filters were supported, the end of the stream was
> not signalled to the bitstream filters and time base changes were ignored.
> 
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
>  libavformat/internal.h |   1 +
>  libavformat/mux.c      | 128 ++++++++++++++++++++++++++++++++++---------------
>  2 files changed, 91 insertions(+), 38 deletions(-)
> 
> diff --git a/libavformat/internal.h b/libavformat/internal.h
> index 332477a532..45aeef717a 100644
> --- a/libavformat/internal.h
> +++ b/libavformat/internal.h
> @@ -158,6 +158,7 @@ struct AVStreamInternal {
>       */
>      AVBSFContext **bsfcs;
>      int nb_bsfcs;
> +    int bsfcs_idx;
>  
>      /**
>       * Whether or not check_bitstream should still be run on each packet
> diff --git a/libavformat/mux.c b/libavformat/mux.c
> index 8c2d6a8060..3054ab8644 100644
> --- a/libavformat/mux.c
> +++ b/libavformat/mux.c
> @@ -840,14 +840,48 @@ static int prepare_input_packet(AVFormatContext *s, AVPacket *pkt)
>      return 0;
>  }
>  
> -static int do_packet_auto_bsf(AVFormatContext *s, AVPacket *pkt) {
> -    AVStream *st = s->streams[pkt->stream_index];
> -    int i, ret;
> +static int auto_bsf_receive_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
> +{
> +    AVStreamInternal *sti = st->internal;
> +    int ret = AVERROR(EAGAIN);
> +    int eof = 0;
> +
> +    while (sti->bsfcs_idx) {
> +        /* get a packet from the previous filter up the chain */
> +        ret = av_bsf_receive_packet(sti->bsfcs[sti->bsfcs_idx - 1], pkt);
> +        if (ret == AVERROR(EAGAIN)) {
> +            sti->bsfcs_idx--;
> +            continue;
> +        } else if (ret == AVERROR_EOF) {
> +            eof = 1;
> +        } else if (ret < 0)
> +            break;
> +
> +        /* send it to the next filter down the chain */
> +        if (sti->bsfcs_idx < sti->nb_bsfcs) {
> +            ret = av_bsf_send_packet(sti->bsfcs[sti->bsfcs_idx], eof ? NULL : pkt);
> +            av_assert2(ret != AVERROR(EAGAIN));
> +            if (ret < 0)
> +                break;
> +            sti->bsfcs_idx++;
> +            eof = 0;
> +        } else if (eof) {
> +            break;
> +        } else {
> +            return 0;
> +        }
> +    }

Would it actually be possible to simplify this by using the
av_bsf_list-API (right now code like this exists here and in ffmpeg.c
and probably at even more places)? The problem I see with this is that
one cannot send a packet for filtering to an unfinished bsf list whereas
the current code has this capability (although AFAIK no one uses it; if
I am not mistaken, all bsf chains that are automatically inserted
consist of exactly one bsf).

(This actually brings up a question: If check_bitstream returns that
more packets from this stream need to be checked, the current packet is
currently sent to the bsf-list as-is; it would not be sent to any bsf
that get added to the list later. Makes me wonder whether this is
actually a problem.)

- Andreas


More information about the ffmpeg-devel mailing list