[FFmpeg-devel] [PATCH v1 2/2] avcodec/v4l2_buffer: export v4l2 buffer dma-buf

Lynne dev at lynne.ee
Fri Nov 12 10:50:21 EET 2021


12 Nov 2021, 09:36 by ming.qian at nxp.com:

> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> ---
>  libavcodec/v4l2_buffers.c | 14 ++++++++++++++
>  libavcodec/v4l2_buffers.h |  1 +
>  libavcodec/v4l2_context.c |  4 ++++
>  3 files changed, 19 insertions(+)
>
> diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
> index 4b2679eb3814..efa42f4c58ea 100644
> --- a/libavcodec/v4l2_buffers.c
> +++ b/libavcodec/v4l2_buffers.c
> @@ -21,6 +21,9 @@
>  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>  */
>  
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#endif
>  #include <linux/videodev2.h>
>  #include <sys/ioctl.h>
>  #include <sys/mman.h>
> @@ -267,6 +270,8 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf)
>  if (!*buf)
>  return AVERROR(ENOMEM);
>  
> +    if (in->plane_info[plane].dmafd >= 0)
> +        av_buffer_set_dma_buf(*buf, in->plane_info[plane].dmafd);
>  ret = v4l2_buf_increase_ref(in);
>  if (ret)
>  av_buffer_unref(buf);
> @@ -494,6 +499,7 @@ int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out)
>  int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
>  {
>  V4L2Context *ctx = avbuf->context;
> +    struct v4l2_exportbuffer exp;
>  int ret, i;
>  
>  avbuf->buf.memory = V4L2_MEMORY_MMAP;
> @@ -539,6 +545,14 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
>  
>  if (avbuf->plane_info[i].mm_addr == MAP_FAILED)
>  return AVERROR(ENOMEM);
> +
> +        exp.type = ctx->type;
> +        exp.index = avbuf->buf.index;
> +        exp.plane = i;
> +        exp.fd = -1;
> +        exp.flags = O_CLOEXEC | O_RDWR;
> +        ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_EXPBUF, &exp);
> +        avbuf->plane_info[i].dmafd = exp.fd;
>  }
>  
>  avbuf->status = V4L2BUF_AVAILABLE;
> diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h
> index 3d2ff1b9a5d7..74550544e0eb 100644
> --- a/libavcodec/v4l2_buffers.h
> +++ b/libavcodec/v4l2_buffers.h
> @@ -55,6 +55,7 @@ typedef struct V4L2Buffer {
>  int bytesperline;
>  void * mm_addr;
>  size_t length;
> +        int dmafd;
>  } plane_info[VIDEO_MAX_PLANES];
>  
>  int num_planes;
> diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
> index b08f0015c2e5..f0406194293d 100644
> --- a/libavcodec/v4l2_context.c
> +++ b/libavcodec/v4l2_context.c
> @@ -453,6 +453,10 @@ static int v4l2_release_buffers(V4L2Context* ctx)
>  if (p->mm_addr && p->length)
>  if (munmap(p->mm_addr, p->length) < 0)
>  av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno)));
> +            if (p->dmafd >= 0) {
> +                close(p->dmafd);
> +                p->dmafd = -1;
> +            }
>  }
>  } 
>

We already have a standard structure for representing DRM frames,
it's AV_PIX_FMT_DRM_PRIME, which encapsulates a AVDRMFrameDescriptor,
which contains DRM fds for every plane, and layer description.

I think there may have been an old patch which did this, but I don't remember.


More information about the ffmpeg-devel mailing list