LCOV - code coverage report
Current view: top level - libavcodec - v4l2_buffers.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 253 0.0 %
Date: 2018-05-20 11:54:08 Functions: 0 17 0.0 %

          Line data    Source code
       1             : /*
       2             :  * V4L2 buffer helper functions.
       3             :  *
       4             :  * Copyright (C) 2017 Alexis Ballier <aballier@gentoo.org>
       5             :  * Copyright (C) 2017 Jorge Ramirez <jorge.ramirez-ortiz@linaro.org>
       6             :  *
       7             :  * This file is part of FFmpeg.
       8             :  *
       9             :  * FFmpeg is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public
      11             :  * License as published by the Free Software Foundation; either
      12             :  * version 2.1 of the License, or (at your option) any later version.
      13             :  *
      14             :  * FFmpeg is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public
      20             :  * License along with FFmpeg; if not, write to the Free Software
      21             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      22             :  */
      23             : 
      24             : #include <linux/videodev2.h>
      25             : #include <sys/ioctl.h>
      26             : #include <sys/mman.h>
      27             : #include <unistd.h>
      28             : #include <fcntl.h>
      29             : #include <poll.h>
      30             : #include "libavcodec/avcodec.h"
      31             : #include "libavcodec/internal.h"
      32             : #include "v4l2_context.h"
      33             : #include "v4l2_buffers.h"
      34             : #include "v4l2_m2m.h"
      35             : 
      36             : #define USEC_PER_SEC 1000000
      37             : 
      38           0 : static inline V4L2m2mContext *buf_to_m2mctx(V4L2Buffer *buf)
      39             : {
      40           0 :     return V4L2_TYPE_IS_OUTPUT(buf->context->type) ?
      41           0 :         container_of(buf->context, V4L2m2mContext, output) :
      42           0 :         container_of(buf->context, V4L2m2mContext, capture);
      43             : }
      44             : 
      45           0 : static inline AVCodecContext *logger(V4L2Buffer *buf)
      46             : {
      47           0 :     return buf_to_m2mctx(buf)->avctx;
      48             : }
      49             : 
      50           0 : static inline void v4l2_set_pts(V4L2Buffer *out, int64_t pts)
      51             : {
      52           0 :     V4L2m2mContext *s = buf_to_m2mctx(out);
      53           0 :     AVRational v4l2_timebase = { 1, USEC_PER_SEC };
      54             :     int64_t v4l2_pts;
      55             : 
      56           0 :     if (pts == AV_NOPTS_VALUE)
      57           0 :         pts = 0;
      58             : 
      59             :     /* convert pts to v4l2 timebase */
      60           0 :     v4l2_pts = av_rescale_q(pts, s->avctx->time_base, v4l2_timebase);
      61           0 :     out->buf.timestamp.tv_usec = v4l2_pts % USEC_PER_SEC;
      62           0 :     out->buf.timestamp.tv_sec = v4l2_pts / USEC_PER_SEC;
      63           0 : }
      64             : 
      65           0 : static inline uint64_t v4l2_get_pts(V4L2Buffer *avbuf)
      66             : {
      67           0 :     V4L2m2mContext *s = buf_to_m2mctx(avbuf);
      68           0 :     AVRational v4l2_timebase = { 1, USEC_PER_SEC };
      69             :     int64_t v4l2_pts;
      70             : 
      71             :     /* convert pts back to encoder timebase */
      72           0 :     v4l2_pts = (int64_t)avbuf->buf.timestamp.tv_sec * USEC_PER_SEC +
      73           0 :                         avbuf->buf.timestamp.tv_usec;
      74             : 
      75           0 :     return av_rescale_q(v4l2_pts, v4l2_timebase, s->avctx->time_base);
      76             : }
      77             : 
      78           0 : static enum AVColorPrimaries v4l2_get_color_primaries(V4L2Buffer *buf)
      79             : {
      80             :     enum v4l2_ycbcr_encoding ycbcr;
      81             :     enum v4l2_colorspace cs;
      82             : 
      83           0 :     cs = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
      84           0 :         buf->context->format.fmt.pix_mp.colorspace :
      85           0 :         buf->context->format.fmt.pix.colorspace;
      86             : 
      87           0 :     ycbcr = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
      88           0 :         buf->context->format.fmt.pix_mp.ycbcr_enc:
      89           0 :         buf->context->format.fmt.pix.ycbcr_enc;
      90             : 
      91           0 :     switch(ycbcr) {
      92           0 :     case V4L2_YCBCR_ENC_XV709:
      93           0 :     case V4L2_YCBCR_ENC_709: return AVCOL_PRI_BT709;
      94           0 :     case V4L2_YCBCR_ENC_XV601:
      95           0 :     case V4L2_YCBCR_ENC_601:return AVCOL_PRI_BT470M;
      96           0 :     default:
      97           0 :         break;
      98             :     }
      99             : 
     100           0 :     switch(cs) {
     101           0 :     case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_PRI_BT470BG;
     102           0 :     case V4L2_COLORSPACE_SMPTE170M: return AVCOL_PRI_SMPTE170M;
     103           0 :     case V4L2_COLORSPACE_SMPTE240M: return AVCOL_PRI_SMPTE240M;
     104           0 :     case V4L2_COLORSPACE_BT2020: return AVCOL_PRI_BT2020;
     105           0 :     default:
     106           0 :         break;
     107             :     }
     108             : 
     109           0 :     return AVCOL_PRI_UNSPECIFIED;
     110             : }
     111             : 
     112           0 : static enum AVColorRange v4l2_get_color_range(V4L2Buffer *buf)
     113             : {
     114             :     enum v4l2_quantization qt;
     115             : 
     116           0 :     qt = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
     117           0 :         buf->context->format.fmt.pix_mp.quantization :
     118           0 :         buf->context->format.fmt.pix.quantization;
     119             : 
     120           0 :     switch (qt) {
     121           0 :     case V4L2_QUANTIZATION_LIM_RANGE: return AVCOL_RANGE_MPEG;
     122           0 :     case V4L2_QUANTIZATION_FULL_RANGE: return AVCOL_RANGE_JPEG;
     123           0 :     default:
     124           0 :         break;
     125             :     }
     126             : 
     127           0 :      return AVCOL_RANGE_UNSPECIFIED;
     128             : }
     129             : 
     130           0 : static enum AVColorSpace v4l2_get_color_space(V4L2Buffer *buf)
     131             : {
     132             :     enum v4l2_ycbcr_encoding ycbcr;
     133             :     enum v4l2_colorspace cs;
     134             : 
     135           0 :     cs = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
     136           0 :         buf->context->format.fmt.pix_mp.colorspace :
     137           0 :         buf->context->format.fmt.pix.colorspace;
     138             : 
     139           0 :     ycbcr = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
     140           0 :         buf->context->format.fmt.pix_mp.ycbcr_enc:
     141           0 :         buf->context->format.fmt.pix.ycbcr_enc;
     142             : 
     143           0 :     switch(cs) {
     144           0 :     case V4L2_COLORSPACE_SRGB: return AVCOL_SPC_RGB;
     145           0 :     case V4L2_COLORSPACE_REC709: return AVCOL_SPC_BT709;
     146           0 :     case V4L2_COLORSPACE_470_SYSTEM_M: return AVCOL_SPC_FCC;
     147           0 :     case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_SPC_BT470BG;
     148           0 :     case V4L2_COLORSPACE_SMPTE170M: return AVCOL_SPC_SMPTE170M;
     149           0 :     case V4L2_COLORSPACE_SMPTE240M: return AVCOL_SPC_SMPTE240M;
     150           0 :     case V4L2_COLORSPACE_BT2020:
     151           0 :         if (ycbcr == V4L2_YCBCR_ENC_BT2020_CONST_LUM)
     152           0 :             return AVCOL_SPC_BT2020_CL;
     153             :         else
     154           0 :              return AVCOL_SPC_BT2020_NCL;
     155           0 :     default:
     156           0 :         break;
     157             :     }
     158             : 
     159           0 :     return AVCOL_SPC_UNSPECIFIED;
     160             : }
     161             : 
     162           0 : static enum AVColorTransferCharacteristic v4l2_get_color_trc(V4L2Buffer *buf)
     163             : {
     164             :     enum v4l2_ycbcr_encoding ycbcr;
     165             :     enum v4l2_xfer_func xfer;
     166             :     enum v4l2_colorspace cs;
     167             : 
     168           0 :     cs = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
     169           0 :         buf->context->format.fmt.pix_mp.colorspace :
     170           0 :         buf->context->format.fmt.pix.colorspace;
     171             : 
     172           0 :     ycbcr = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
     173           0 :         buf->context->format.fmt.pix_mp.ycbcr_enc:
     174           0 :         buf->context->format.fmt.pix.ycbcr_enc;
     175             : 
     176           0 :     xfer = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ?
     177           0 :         buf->context->format.fmt.pix_mp.xfer_func:
     178           0 :         buf->context->format.fmt.pix.xfer_func;
     179             : 
     180           0 :     switch (xfer) {
     181           0 :     case V4L2_XFER_FUNC_709: return AVCOL_TRC_BT709;
     182           0 :     case V4L2_XFER_FUNC_SRGB: return AVCOL_TRC_IEC61966_2_1;
     183           0 :     default:
     184           0 :         break;
     185             :     }
     186             : 
     187           0 :     switch (cs) {
     188           0 :     case V4L2_COLORSPACE_470_SYSTEM_M: return AVCOL_TRC_GAMMA22;
     189           0 :     case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_TRC_GAMMA28;
     190           0 :     case V4L2_COLORSPACE_SMPTE170M: return AVCOL_TRC_SMPTE170M;
     191           0 :     case V4L2_COLORSPACE_SMPTE240M: return AVCOL_TRC_SMPTE240M;
     192           0 :     default:
     193           0 :         break;
     194             :     }
     195             : 
     196           0 :     switch (ycbcr) {
     197           0 :     case V4L2_YCBCR_ENC_XV709:
     198           0 :     case V4L2_YCBCR_ENC_XV601: return AVCOL_TRC_BT1361_ECG;
     199           0 :     default:
     200           0 :         break;
     201             :     }
     202             : 
     203           0 :     return AVCOL_TRC_UNSPECIFIED;
     204             : }
     205             : 
     206           0 : static void v4l2_free_buffer(void *opaque, uint8_t *unused)
     207             : {
     208           0 :     V4L2Buffer* avbuf = opaque;
     209           0 :     V4L2m2mContext *s = buf_to_m2mctx(avbuf);
     210             : 
     211           0 :     if (atomic_fetch_sub(&avbuf->context_refcount, 1) == 1) {
     212           0 :         atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel);
     213             : 
     214           0 :         if (s->reinit) {
     215           0 :             if (!atomic_load(&s->refcount))
     216           0 :                 sem_post(&s->refsync);
     217             :         } else {
     218           0 :             if (s->draining) {
     219             :                 /* no need to queue more buffers to the driver */
     220           0 :                 avbuf->status = V4L2BUF_AVAILABLE;
     221             :             }
     222           0 :             else if (avbuf->context->streamon)
     223           0 :                 ff_v4l2_buffer_enqueue(avbuf);
     224             :         }
     225             : 
     226           0 :         av_buffer_unref(&avbuf->context_ref);
     227             :     }
     228           0 : }
     229             : 
     230           0 : static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf)
     231             : {
     232           0 :     V4L2m2mContext *s = buf_to_m2mctx(in);
     233             : 
     234           0 :     if (plane >= in->num_planes)
     235           0 :         return AVERROR(EINVAL);
     236             : 
     237             :     /* even though most encoders return 0 in data_offset encoding vp8 does require this value */
     238           0 :     *buf = av_buffer_create((char *)in->plane_info[plane].mm_addr + in->planes[plane].data_offset,
     239           0 :                             in->plane_info[plane].length, v4l2_free_buffer, in, 0);
     240           0 :     if (!*buf)
     241           0 :         return AVERROR(ENOMEM);
     242             : 
     243           0 :     if (in->context_ref)
     244           0 :         atomic_fetch_add(&in->context_refcount, 1);
     245             :     else {
     246           0 :         in->context_ref = av_buffer_ref(s->self_ref);
     247           0 :         if (!in->context_ref) {
     248           0 :             av_buffer_unref(buf);
     249           0 :             return AVERROR(ENOMEM);
     250             :         }
     251           0 :         in->context_refcount = 1;
     252             :     }
     253             : 
     254           0 :     in->status = V4L2BUF_RET_USER;
     255           0 :     atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed);
     256             : 
     257           0 :     return 0;
     258             : }
     259             : 
     260           0 : static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, int size, AVBufferRef* bref)
     261             : {
     262             :     unsigned int bytesused, length;
     263             : 
     264           0 :     if (plane >= out->num_planes)
     265           0 :         return AVERROR(EINVAL);
     266             : 
     267           0 :     bytesused = FFMIN(size, out->plane_info[plane].length);
     268           0 :     length = out->plane_info[plane].length;
     269             : 
     270           0 :     memcpy(out->plane_info[plane].mm_addr, data, FFMIN(size, out->plane_info[plane].length));
     271             : 
     272           0 :     if (V4L2_TYPE_IS_MULTIPLANAR(out->buf.type)) {
     273           0 :         out->planes[plane].bytesused = bytesused;
     274           0 :         out->planes[plane].length = length;
     275             :     } else {
     276           0 :         out->buf.bytesused = bytesused;
     277           0 :         out->buf.length = length;
     278             :     }
     279             : 
     280           0 :     return 0;
     281             : }
     282             : 
     283             : /******************************************************************************
     284             :  *
     285             :  *              V4L2uffer interface
     286             :  *
     287             :  ******************************************************************************/
     288             : 
     289           0 : int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer* out)
     290             : {
     291             :     int i, ret;
     292             : 
     293           0 :     for(i = 0; i < out->num_planes; i++) {
     294           0 :         ret = v4l2_bufref_to_buf(out, i, frame->buf[i]->data, frame->buf[i]->size, frame->buf[i]);
     295           0 :         if (ret)
     296           0 :             return ret;
     297             :     }
     298             : 
     299           0 :     v4l2_set_pts(out, frame->pts);
     300             : 
     301           0 :     return 0;
     302             : }
     303             : 
     304           0 : int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
     305             : {
     306           0 :     V4L2m2mContext *s = buf_to_m2mctx(avbuf);
     307             :     int i, ret;
     308             : 
     309           0 :     av_frame_unref(frame);
     310             : 
     311             :     /* 1. get references to the actual data */
     312           0 :     for (i = 0; i < avbuf->num_planes; i++) {
     313           0 :         ret = v4l2_buf_to_bufref(avbuf, i, &frame->buf[i]);
     314           0 :         if (ret)
     315           0 :             return ret;
     316             : 
     317           0 :         frame->linesize[i] = avbuf->plane_info[i].bytesperline;
     318           0 :         frame->data[i] = frame->buf[i]->data;
     319             :     }
     320             : 
     321             :     /* 1.1 fixup special cases */
     322           0 :     switch (avbuf->context->av_pix_fmt) {
     323           0 :     case AV_PIX_FMT_NV12:
     324           0 :         if (avbuf->num_planes > 1)
     325           0 :             break;
     326           0 :         frame->linesize[1] = avbuf->plane_info[0].bytesperline;
     327           0 :         frame->data[1] = frame->buf[0]->data + avbuf->plane_info[0].bytesperline * avbuf->context->format.fmt.pix_mp.height;
     328           0 :         break;
     329           0 :     default:
     330           0 :         break;
     331             :     }
     332             : 
     333             :     /* 2. get frame information */
     334           0 :     frame->key_frame = !!(avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME);
     335           0 :     frame->format = avbuf->context->av_pix_fmt;
     336           0 :     frame->color_primaries = v4l2_get_color_primaries(avbuf);
     337           0 :     frame->colorspace = v4l2_get_color_space(avbuf);
     338           0 :     frame->color_range = v4l2_get_color_range(avbuf);
     339           0 :     frame->color_trc = v4l2_get_color_trc(avbuf);
     340           0 :     frame->pts = v4l2_get_pts(avbuf);
     341             : 
     342             :     /* these two values are updated also during re-init in v4l2_process_driver_event */
     343           0 :     frame->height = s->output.height;
     344           0 :     frame->width = s->output.width;
     345             : 
     346             :     /* 3. report errors upstream */
     347           0 :     if (avbuf->buf.flags & V4L2_BUF_FLAG_ERROR) {
     348           0 :         av_log(logger(avbuf), AV_LOG_ERROR, "%s: driver decode error\n", avbuf->context->name);
     349           0 :         frame->decode_error_flags |= FF_DECODE_ERROR_INVALID_BITSTREAM;
     350             :     }
     351             : 
     352           0 :     return 0;
     353             : }
     354             : 
     355           0 : int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf)
     356             : {
     357             :     int ret;
     358             : 
     359           0 :     av_packet_unref(pkt);
     360           0 :     ret = v4l2_buf_to_bufref(avbuf, 0, &pkt->buf);
     361           0 :     if (ret)
     362           0 :         return ret;
     363             : 
     364           0 :     pkt->size = V4L2_TYPE_IS_MULTIPLANAR(avbuf->buf.type) ? avbuf->buf.m.planes[0].bytesused : avbuf->buf.bytesused;
     365           0 :     pkt->data = pkt->buf->data;
     366             : 
     367           0 :     if (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME)
     368           0 :         pkt->flags |= AV_PKT_FLAG_KEY;
     369             : 
     370           0 :     if (avbuf->buf.flags & V4L2_BUF_FLAG_ERROR) {
     371           0 :         av_log(logger(avbuf), AV_LOG_ERROR, "%s driver encode error\n", avbuf->context->name);
     372           0 :         pkt->flags |= AV_PKT_FLAG_CORRUPT;
     373             :     }
     374             : 
     375           0 :     pkt->dts = pkt->pts = v4l2_get_pts(avbuf);
     376             : 
     377           0 :     return 0;
     378             : }
     379             : 
     380           0 : int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out)
     381             : {
     382             :     int ret;
     383             : 
     384           0 :     ret = v4l2_bufref_to_buf(out, 0, pkt->data, pkt->size, pkt->buf);
     385           0 :     if (ret)
     386           0 :         return ret;
     387             : 
     388           0 :     v4l2_set_pts(out, pkt->pts);
     389             : 
     390           0 :     if (pkt->flags & AV_PKT_FLAG_KEY)
     391           0 :         out->flags = V4L2_BUF_FLAG_KEYFRAME;
     392             : 
     393           0 :     return 0;
     394             : }
     395             : 
     396           0 : int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
     397             : {
     398           0 :     V4L2Context *ctx = avbuf->context;
     399             :     int ret, i;
     400             : 
     401           0 :     avbuf->buf.memory = V4L2_MEMORY_MMAP;
     402           0 :     avbuf->buf.type = ctx->type;
     403           0 :     avbuf->buf.index = index;
     404             : 
     405           0 :     if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
     406           0 :         avbuf->buf.length = VIDEO_MAX_PLANES;
     407           0 :         avbuf->buf.m.planes = avbuf->planes;
     408             :     }
     409             : 
     410           0 :     ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_QUERYBUF, &avbuf->buf);
     411           0 :     if (ret < 0)
     412           0 :         return AVERROR(errno);
     413             : 
     414           0 :     if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
     415           0 :         avbuf->num_planes = 0;
     416             :         for (;;) {
     417             :             /* in MP, the V4L2 API states that buf.length means num_planes */
     418           0 :             if (avbuf->num_planes >= avbuf->buf.length)
     419           0 :                 break;
     420           0 :             if (avbuf->buf.m.planes[avbuf->num_planes].length)
     421           0 :                 avbuf->num_planes++;
     422             :         }
     423             :     } else
     424           0 :         avbuf->num_planes = 1;
     425             : 
     426           0 :     for (i = 0; i < avbuf->num_planes; i++) {
     427             : 
     428           0 :         avbuf->plane_info[i].bytesperline = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ?
     429           0 :             ctx->format.fmt.pix_mp.plane_fmt[i].bytesperline :
     430           0 :             ctx->format.fmt.pix.bytesperline;
     431             : 
     432           0 :         if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
     433           0 :             avbuf->plane_info[i].length = avbuf->buf.m.planes[i].length;
     434           0 :             avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.m.planes[i].length,
     435             :                                            PROT_READ | PROT_WRITE, MAP_SHARED,
     436           0 :                                            buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.planes[i].m.mem_offset);
     437             :         } else {
     438           0 :             avbuf->plane_info[i].length = avbuf->buf.length;
     439           0 :             avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length,
     440             :                                           PROT_READ | PROT_WRITE, MAP_SHARED,
     441           0 :                                           buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.offset);
     442             :         }
     443             : 
     444           0 :         if (avbuf->plane_info[i].mm_addr == MAP_FAILED)
     445           0 :             return AVERROR(ENOMEM);
     446             :     }
     447             : 
     448           0 :     avbuf->status = V4L2BUF_AVAILABLE;
     449             : 
     450           0 :     if (V4L2_TYPE_IS_OUTPUT(ctx->type))
     451           0 :         return 0;
     452             : 
     453           0 :     if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
     454           0 :         avbuf->buf.m.planes = avbuf->planes;
     455           0 :         avbuf->buf.length   = avbuf->num_planes;
     456             : 
     457             :     } else {
     458           0 :         avbuf->buf.bytesused = avbuf->planes[0].bytesused;
     459           0 :         avbuf->buf.length    = avbuf->planes[0].length;
     460             :     }
     461             : 
     462           0 :     return ff_v4l2_buffer_enqueue(avbuf);
     463             : }
     464             : 
     465           0 : int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf)
     466             : {
     467             :     int ret;
     468             : 
     469           0 :     avbuf->buf.flags = avbuf->flags;
     470             : 
     471           0 :     ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_QBUF, &avbuf->buf);
     472           0 :     if (ret < 0)
     473           0 :         return AVERROR(errno);
     474             : 
     475           0 :     avbuf->status = V4L2BUF_IN_DRIVER;
     476             : 
     477           0 :     return 0;
     478             : }

Generated by: LCOV version 1.13