[FFmpeg-devel] [PATCH] avformat/utils: use the existing packet reference when parsing complete frames

wm4 nfxjfg at googlemail.com
Fri Apr 13 00:52:22 EEST 2018


On Thu, 12 Apr 2018 16:22:01 -0300
James Almer <jamrial at gmail.com> wrote:

> On 4/12/2018 3:59 PM, wm4 wrote:
> > On Thu, 12 Apr 2018 15:34:29 -0300
> > James Almer <jamrial at gmail.com> wrote:
> >   
> >> If the parser returns full frames, then the output pointer retured by
> >> av_parser_parse2() is guaranteed to point to data contained in the
> >> input packet's buffer.
> >>
> >> Create a new reference to said buffer in that case, to avoid
> >> unnecessary data copy when queueing the packet later in the function.
> >>
> >> Signed-off-by: James Almer <jamrial at gmail.com>
> >> ---
> >>  libavformat/utils.c | 23 ++++++++++++++++++++---
> >>  1 file changed, 20 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/libavformat/utils.c b/libavformat/utils.c
> >> index 3e482a3bbc..8ad2ef4d70 100644
> >> --- a/libavformat/utils.c
> >> +++ b/libavformat/utils.c
> >> @@ -1471,6 +1471,22 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
> >>          if (!out_pkt.size)
> >>              continue;
> >>  
> >> +        if (pkt->buf && out_pkt.data == pkt->data) {
> >> +            /* reference pkt->buf only when out_pkt.data is guaranteed to point
> >> +             * to data in it and not in the parser's internal buffer. */
> >> +            /* XXX: Ensure this is the case with all parsers when the muxer sets
> >> +             * PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */
> >> +            out_pkt.buf = av_buffer_ref(pkt->buf);
> >> +            if (!out_pkt.buf) {
> >> +                ret = AVERROR(ENOMEM);
> >> +                goto fail;
> >> +            }
> >> +        } else {
> >> +            ret = av_packet_make_refcounted(&out_pkt);
> >> +            if (ret < 0)
> >> +                goto fail;
> >> +        }
> >> +
> >>          if (pkt->side_data) {
> >>              out_pkt.side_data       = pkt->side_data;
> >>              out_pkt.side_data_elems = pkt->side_data_elems;
> >> @@ -1511,10 +1527,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
> >>  
> >>          ret = ff_packet_list_put(&s->internal->parse_queue,
> >>                                   &s->internal->parse_queue_end,
> >> -                                 &out_pkt, FF_PACKETLIST_FLAG_REF_PACKET);
> >> -        av_packet_unref(&out_pkt);
> >> -        if (ret < 0)
> >> +                                 &out_pkt, 0);
> >> +        if (ret < 0) {
> >> +            av_packet_unref(&out_pkt);
> >>              goto fail;
> >> +        }
> >>      }
> >>  
> >>      /* end of the stream => close and free the parser */  
> > 
> > For which cases is this?  
> 
> Pretty much every single packet from a demuxer that sets
> AVSTREAM_PARSE_HEADERS, meaning every non-raw demuxer with a couple
> exceptions.
> 
> > Maybe we should just make a new parser API (or
> > reuse the BSF one), and make it cover the cases we care about.  
> 
> I remember a new parser API that works on packets rather than raw data,
> much like the new bsf API, was the plan at some point.
> There's no lack of ideas in any case, just manpower in general.

To be honest I wish we just did away with this probing stuff and
restrict libavformat to actually demuxing stuff.

Could we use that PARSE_HEADERS probably never changes packet contents?


More information about the ffmpeg-devel mailing list