+ return 0;
+}
+
+static int v4l2_buffer_swframe_to_buf(const AVFrame *frame, V4L2Buffer *out)
+{
+ int i, ret;
+ struct v4l2_format fmt = out->context->format;
+ int pixel_format = V4L2_TYPE_IS_MULTIPLANAR(fmt.type) ?
+ fmt.fmt.pix_mp.pixelformat : fmt.fmt.pix.pixelformat;
+ int height = V4L2_TYPE_IS_MULTIPLANAR(fmt.type) ?
+ fmt.fmt.pix_mp.height : fmt.fmt.pix.height;
+ int is_planar_format = 0;
+
+ switch (pixel_format) {
+ case V4L2_PIX_FMT_YUV420M:
+ case V4L2_PIX_FMT_YVU420M:
+#ifdef V4L2_PIX_FMT_YUV422M
+ case V4L2_PIX_FMT_YUV422M:
+#endif
+#ifdef V4L2_PIX_FMT_YVU422M
+ case V4L2_PIX_FMT_YVU422M:
+#endif
+#ifdef V4L2_PIX_FMT_YUV444M
+ case V4L2_PIX_FMT_YUV444M:
+#endif
+#ifdef V4L2_PIX_FMT_YVU444M
+ case V4L2_PIX_FMT_YVU444M:
+#endif
+ case V4L2_PIX_FMT_NV12M:
+ case V4L2_PIX_FMT_NV21M:
+ case V4L2_PIX_FMT_NV12MT_16X16:
+ case V4L2_PIX_FMT_NV12MT:
+ case V4L2_PIX_FMT_NV16M:
+ case V4L2_PIX_FMT_NV61M:
+ is_planar_format = 1;
+ }
+
+ if (!is_planar_format) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ int planes_nb = 0;
+ int offset = 0;
+
+ for (i = 0; i < desc->nb_components; i++)
+ planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
+
+ for (i = 0; i < planes_nb; i++) {
+ int size, h = height;
+ if (i == 1 || i == 2) {
+ h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
+ }
+ size = frame->linesize[i] * h;
+ ret = v4l2_bufref_to_buf(out, 0, frame->data[i], size, offset);
+ if (ret)
+ return ret;
+ offset += size;
+ }
+ return 0;
+ }
+
+ for (i = 0; i < out->num_planes; i++) {
+ ret = v4l2_bufref_to_buf(out, i, frame->buf[i]->data, frame->buf[i]->size, 0);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/******************************************************************************
+ *
+ * V4L2Buffer interface
+ *
+ ******************************************************************************/
+
+int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out)
+{
+ v4l2_set_pts(out, frame->pts);
+
+ return v4l2_buffer_swframe_to_buf(frame, out);
+}
+
+int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
+{
+ int ret;
+
+ av_frame_unref(frame);
+
+ /* 1. get references to the actual data */
+ ret = v4l2_buffer_buf_to_swframe(frame, avbuf);
+ if (ret)
+ return ret;
+