[FFmpeg-devel] [PATCH] avcodec/v4l2_m2m_enc: Add option to remove ivf container

Andriy Gelman andriy.gelman at gmail.com
Sat Apr 11 18:14:53 EEST 2020


On Sat, 11. Apr 15:56, Mark Thompson wrote:
> On 04/04/2020 21:26, Andriy Gelman wrote:
> > From: Andriy Gelman <andriy.gelman at gmail.com>
> > 
> > The dequeued packets from vp8 (s5p-mfc) encoder are output in ivf format
> > which breaks the stream when the packets are muxed in avformat. This commit
> > adds an option to remove the container and thus support the encoder.
> > 
> > Signed-off-by: Andriy Gelman <andriy.gelman at gmail.com>
> > ---
> >  libavcodec/v4l2_m2m.h     |  2 ++
> >  libavcodec/v4l2_m2m_enc.c | 53 +++++++++++++++++++++++++++++++--------
> >  2 files changed, 45 insertions(+), 10 deletions(-)
> > 
> > diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
> > index 456281f48c..525f9456e9 100644
> > --- a/libavcodec/v4l2_m2m.h
> > +++ b/libavcodec/v4l2_m2m.h
> > @@ -73,6 +73,8 @@ typedef struct V4L2m2mPriv {
> >  
> >      int num_output_buffers;
> >      int num_capture_buffers;
> > +    int strip_ivf;
> > +    int ivf_detected;
> >  } V4L2m2mPriv;
> >  
> >  /**
> > diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
> > index c9f1741bfd..9c11f90567 100644
> > --- a/libavcodec/v4l2_m2m_enc.c
> > +++ b/libavcodec/v4l2_m2m_enc.c
> > @@ -25,6 +25,8 @@
> >  #include <sys/ioctl.h>
> >  #include <search.h>
> >  #include "libavcodec/avcodec.h"
> > +#include "libavcodec/internal.h"
> > +#include "libavutil/intreadwrite.h"
> >  #include "libavutil/pixdesc.h"
> >  #include "libavutil/pixfmt.h"
> >  #include "libavutil/opt.h"
> > @@ -256,6 +258,7 @@ static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame)
> >  
> >  static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
> >  {
> > +    V4L2m2mPriv *priv = avctx->priv_data;
> >      V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
> >      V4L2Context *const capture = &s->capture;
> >      V4L2Context *const output = &s->output;
> > @@ -281,7 +284,28 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
> >      }
> >  
> >  dequeue:
> > -    return ff_v4l2_context_dequeue_packet(capture, avpkt);
> > +    ret = ff_v4l2_context_dequeue_packet(capture, avpkt);
> > +    if (ret)
> > +        return ret;
> > +
> > +    if (priv->strip_ivf) {
> > +        int header_offset = 0;
> > +        if (avpkt->size >= 32 && AV_RL32(avpkt->data) == MKTAG('D','K','I','F')) {
> > +            header_offset = 32;
> > +            priv->ivf_detected = 1;
> > +        } else if (priv->ivf_detected) {
> > +            header_offset = 12;
> > +        }
> > +        header_offset = FFMIN(header_offset, avpkt->size);
> > +        avpkt->data  += header_offset;
> > +        avpkt->size  -= header_offset;
> > +
> > +        if (avpkt->size == 0) {

> 
> Does this case ever happen?  Wouldn't something have gone very wrong here to get here?

It happens on the first packet, when the dequeued packet only contains the
32byte ivf header.

Also when draining (not related to this patch), avpkt->size == 0 indicates that
all the capture buffers are flushed.

> 
> > +            av_packet_unref(avpkt);
> > +            goto dequeue;
> > +        }
> > +    }
> > +    return 0;
> >  }

> 
> Could the presence of the IVF container be autodetected?  I suspect it can, because the tag will collide with the fixed start code in the intra frame at the start of the stream.  If that were possible then it would avoid having the tricky option which users are not going to easily know about.

I think it can. Will test this approach.

> 
> Otherwise seems ok.  It's rather horrible, but it looks like the best solution to the problem.

I agree it's quite ugly. I'll look into whether auto inserted bsf can be
extended to encoders.

Thanks,
-- 
Andriy


More information about the ffmpeg-devel mailing list