From patchwork Tue Sep 22 13:30:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Junghak Sung X-Patchwork-Id: 7238861 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4C1EE9F443 for ; Tue, 22 Sep 2015 13:31:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1FFAE20529 for ; Tue, 22 Sep 2015 13:31:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8EDF720450 for ; Tue, 22 Sep 2015 13:30:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933732AbbIVNav (ORCPT ); Tue, 22 Sep 2015 09:30:51 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:56908 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933355AbbIVNam (ORCPT ); Tue, 22 Sep 2015 09:30:42 -0400 Received: from epcpsbgr1.samsung.com (u141.gpu120.samsung.co.kr [203.254.230.141]) by mailout3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NV202QZ5YV34V30@mailout3.samsung.com> for linux-media@vger.kernel.org; Tue, 22 Sep 2015 22:30:39 +0900 (KST) Received: from epcpsbgm2new.samsung.com ( [172.20.52.112]) by epcpsbgr1.samsung.com (EPCPMTA) with SMTP id 1C.97.05274.FF751065; Tue, 22 Sep 2015 22:30:39 +0900 (KST) X-AuditID: cbfee68d-f79ae6d00000149a-58-560157ff14d3 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2new.samsung.com (EPCPMTA) with SMTP id A6.2C.18629.FF751065; Tue, 22 Sep 2015 22:30:39 +0900 (KST) Received: from localhost.localdomain ([10.252.83.96]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NV200MQ5YV32N30@mmp2.samsung.com>; Tue, 22 Sep 2015 22:30:39 +0900 (KST) From: Junghak Sung To: linux-media@vger.kernel.org, mchehab@osg.samsung.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, pawel@osciak.com Cc: inki.dae@samsung.com, sw0312.kim@samsung.com, nenggun.kim@samsung.com, sangbae90.lee@samsung.com, rany.kwon@samsung.com, Junghak Sung Subject: [RFC PATCH v5 2/8] media: videobuf2: Restructure vb2_buffer (1/3) Date: Tue, 22 Sep 2015 22:30:30 +0900 Message-id: <1442928636-3589-3-git-send-email-jh1009.sung@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1442928636-3589-1-git-send-email-jh1009.sung@samsung.com> References: <1442928636-3589-1-git-send-email-jh1009.sung@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrDLMWRmVeSWpSXmKPExsWyRsSkQPd/OGOYwfxFJhanJj9jsph0fwKL xfbjr9gtOicuYbfo2bCV1WL1swqLA327mCymvP3JbvFv2lNmizP7V7JZHP90kMVixuSXbA48 HrM7ZrJ6HP66kMXj8a+XbB5b+u+ye/RtWcXo8XmTnMepr5/ZA9ijuGxSUnMyy1KL9O0SuDJm /1/KWLD1FWNFy8RTbA2M83YxdjFycEgImEjc3JXexcgJZIpJXLi3ng3EFhJYwSjx8FANRNxE YsWyr4wQ8VmMEh3vVboYuYDs74wSd7/cYQGZwyagIzF5syFIXERgBqNE7/FVTCAOs8ByRonT r0+xgxQJC3hJzNvBBDKIRUBV4uDtR2BDeQXcJL78XMYKcY+CxJxJNiBhTgF3iWMXF0LtdZM4 fuczM8hICYFr7BKtxycxQswRkPg2+RALRK+sxKYDzBA3S0ocXHGDZQKj8AJGhlWMoqkFyQXF SelFhnrFibnFpXnpesn5uZsYgZFy+t+z3h2Mtw9YH2IU4GBU4uH16GMIE2JNLCuuzD3EaAq0 YSKzlGhyPjAe80riDY3NjCxMTUyNjcwtzZTEeRWlfgYLCaQnlqRmp6YWpBbFF5XmpBYfYmTi 4JRqYGy0/TiRVyiWd8X8WXIsonLeZu1vFQp9Ev2dHyfcF/d7aR7wYF3MOaWjjF4KyjOaRD3f xjck3DKuNzcwPeR/eIuDl2Dj/ducQaJ/8l0Oyf/Yue7k1QuXP06x3p3YdvrkrNkGa7NPZ6+W VzNlnu4ZZVX+as85k08Kq/9tUM65dK1L9ek6v3aONCWW4oxEQy3mouJEAO3I8naPAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrNIsWRmVeSWpSXmKPExsVy+t9jQd3/4YxhBucatC1OTX7GZDHp/gQW i+3HX7FbdE5cwm7Rs2Erq8XqZxUWB/p2MVlMefuT3eLftKfMFmf2r2SzOP7pIIvFjMkv2Rx4 PGZ3zGT1OPx1IYvH418v2Ty29N9l9+jbsorR4/MmOY9TXz+zB7BHNTDaZKQmpqQWKaTmJeen ZOal2yp5B8c7x5uaGRjqGlpamCsp5CXmptoqufgE6Lpl5gBdqqRQlphTChQKSCwuVtK3wzQh NMRN1wKmMULXNyQIrsfIAA0krGHMmP1/KWPB1leMFS0TT7E1MM7bxdjFyMkhIWAisWLZVyhb TOLCvfVsILaQwCxGiY73Kl2MXED2d0aJu1/usHQxcnCwCehITN5sCBIXEZjBKNF7fBUTiMMs sJxR4vTrU+wgRcICXhLzdjCBDGIRUJU4ePsR2AJeATeJLz+XsYKUSAgoSMyZZAMS5hRwlzh2 cSEjxF43ieN3PjNPYORdwMiwilEitSC5oDgpPdcoL7Vcrzgxt7g0L10vOT93EyM4Ip9J72A8 vMv9EKMAB6MSD++HboYwIdbEsuLK3EOMEhzMSiK86xQZw4R4UxIrq1KL8uOLSnNSiw8xmgLd NZFZSjQ5H5gs8kriDY1NzIwsjcwNLYyMzZXEeW8cApojkJ5YkpqdmlqQWgTTx8TBKdXAOPdv odvjpKcRF3S3rSqdeqUhr3jPB/HMbSq9vjX7jm56E8910SJDj4una3JHQUBD4vvz5vo72m7F W5tU/ddJ2PWnYrnVM+8gFW/nJK4thzbtspKc2PJuY4d8+SI7p4KkdRuFfEK5opLULP8fYms+ Xuza2PHFda3Ec+X7IYqpTLt+Zh46wbBGiaU4I9FQi7moOBEA1WEIxd4CAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Remove v4l2 stuff - v4l2_buf, v4l2_plane - from struct vb2_buffer. Add new member variables - bytesused, length, offset, userptr, fd, data_offset - to struct vb2_plane in order to cover all information of v4l2_plane. struct vb2_plane { unsigned int bytesused; unsigned int length; union { unsigned int offset; unsigned long userptr; int fd; } m; unsigned int data_offset; } Replace v4l2_buf with new member variables - index, type, memory - which are common fields for buffer management. struct vb2_buffer { unsigned int index; unsigned int type; unsigned int memory; unsigned int num_planes; struct vb2_plane planes[VIDEO_MAX_PLANES]; }; v4l2 specific fields - flags, field, timestamp, timecode, sequence - are moved to vb2_v4l2_buffer in videobuf2-v4l2.c struct vb2_v4l2_buffer { struct vb2_buffer vb2_buf; __u32 flags; __u32 field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; }; This patch includes only changes inside of the videobuf2. So, in practice, we need to fold this patch and following two patches when merging upstream, to avoid breaking git bisectability. Signed-off-by: Junghak Sung Signed-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/videobuf2-core.c | 219 ++++++++++++++++++------------ include/media/videobuf2-core.h | 66 +++++---- include/media/videobuf2-v4l2.h | 28 ++++ 3 files changed, 201 insertions(+), 112 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 9518ebd..8c456f7 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -53,7 +53,7 @@ module_param(debug, int, 0644); #define log_memop(vb, op) \ dprintk(2, "call_memop(%p, %d, %s)%s\n", \ - (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \ + (vb)->vb2_queue, (vb)->index, #op, \ (vb)->vb2_queue->mem_ops->op ? "" : " (nop)") #define call_memop(vb, op, args...) \ @@ -115,7 +115,7 @@ module_param(debug, int, 0644); #define log_vb_qop(vb, op, args...) \ dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \ - (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \ + (vb)->vb2_queue, (vb)->index, #op, \ (vb)->vb2_queue->ops->op ? "" : " (nop)") #define call_vb_qop(vb, op, args...) \ @@ -211,7 +211,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) /* Associate allocator private data with this plane */ vb->planes[plane].mem_priv = mem_priv; - vb->v4l2_planes[plane].length = q->plane_sizes[plane]; + vb->planes[plane].length = q->plane_sizes[plane]; } return 0; @@ -235,8 +235,7 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb) for (plane = 0; plane < vb->num_planes; ++plane) { call_void_memop(vb, put, vb->planes[plane].mem_priv); vb->planes[plane].mem_priv = NULL; - dprintk(3, "freed plane %d of buffer %d\n", plane, - vb->v4l2_buf.index); + dprintk(3, "freed plane %d of buffer %d\n", plane, vb->index); } } @@ -269,7 +268,9 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p) call_void_memop(vb, detach_dmabuf, p->mem_priv); dma_buf_put(p->dbuf); - memset(p, 0, sizeof(*p)); + p->mem_priv = NULL; + p->dbuf = NULL; + p->dbuf_mapped = 0; } /** @@ -299,7 +300,7 @@ static void __setup_lengths(struct vb2_queue *q, unsigned int n) continue; for (plane = 0; plane < vb->num_planes; ++plane) - vb->v4l2_planes[plane].length = q->plane_sizes[plane]; + vb->planes[plane].length = q->plane_sizes[plane]; } } @@ -314,10 +315,10 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) unsigned long off; if (q->num_buffers) { - struct v4l2_plane *p; + struct vb2_plane *p; vb = q->bufs[q->num_buffers - 1]; - p = &vb->v4l2_planes[vb->num_planes - 1]; - off = PAGE_ALIGN(p->m.mem_offset + p->length); + p = &vb->planes[vb->num_planes - 1]; + off = PAGE_ALIGN(p->m.offset + p->length); } else { off = 0; } @@ -328,12 +329,12 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) continue; for (plane = 0; plane < vb->num_planes; ++plane) { - vb->v4l2_planes[plane].m.mem_offset = off; + vb->planes[plane].m.offset = off; dprintk(3, "buffer %d, plane %d offset 0x%08lx\n", buffer, plane, off); - off += vb->v4l2_planes[plane].length; + off += vb->planes[plane].length; off = PAGE_ALIGN(off); } } @@ -361,16 +362,12 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, break; } - /* Length stores number of planes for multiplanar buffers */ - if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) - vb->v4l2_buf.length = num_planes; - vb->state = VB2_BUF_STATE_DEQUEUED; vb->vb2_queue = q; vb->num_planes = num_planes; - vb->v4l2_buf.index = q->num_buffers + buffer; - vb->v4l2_buf.type = q->type; - vb->v4l2_buf.memory = memory; + vb->index = q->num_buffers + buffer; + vb->type = q->type; + vb->memory = memory; /* Allocate video buffer memory for the MMAP type */ if (memory == V4L2_MEMORY_MMAP) { @@ -592,7 +589,7 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) length = (b->memory == V4L2_MEMORY_USERPTR || b->memory == V4L2_MEMORY_DMABUF) ? b->m.planes[plane].length - : vb->v4l2_planes[plane].length; + : vb->planes[plane].length; bytesused = b->m.planes[plane].bytesused ? b->m.planes[plane].bytesused : length; @@ -605,8 +602,7 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) } } else { length = (b->memory == V4L2_MEMORY_USERPTR) - ? b->length : vb->v4l2_planes[0].length; - bytesused = b->bytesused ? b->bytesused : length; + ? b->length : vb->planes[0].length; if (b->bytesused > length) return -EINVAL; @@ -656,12 +652,23 @@ static bool __buffers_in_use(struct vb2_queue *q) */ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) { + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_queue *q = vb->vb2_queue; + unsigned int plane; /* Copy back data such as timestamp, flags, etc. */ - memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); - b->reserved2 = vb->v4l2_buf.reserved2; - b->reserved = vb->v4l2_buf.reserved; + b->index = vb->index; + b->type = vb->type; + b->memory = vb->memory; + b->bytesused = 0; + + b->flags = vbuf->flags; + b->field = vbuf->field; + b->timestamp = vbuf->timestamp; + b->timecode = vbuf->timecode; + b->sequence = vbuf->sequence; + b->reserved2 = 0; + b->reserved = 0; if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) { /* @@ -669,21 +676,34 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) * for it. The caller has already verified memory and size. */ b->length = vb->num_planes; - memcpy(b->m.planes, vb->v4l2_planes, - b->length * sizeof(struct v4l2_plane)); + for (plane = 0; plane < vb->num_planes; ++plane) { + struct v4l2_plane *pdst = &b->m.planes[plane]; + struct vb2_plane *psrc = &vb->planes[plane]; + + pdst->bytesused = psrc->bytesused; + pdst->length = psrc->length; + if (q->memory == V4L2_MEMORY_MMAP) + pdst->m.mem_offset = psrc->m.offset; + else if (q->memory == V4L2_MEMORY_USERPTR) + pdst->m.userptr = psrc->m.userptr; + else if (q->memory == V4L2_MEMORY_DMABUF) + pdst->m.fd = psrc->m.fd; + pdst->data_offset = psrc->data_offset; + memset(pdst->reserved, 0, sizeof(pdst->reserved)); + } } else { /* * We use length and offset in v4l2_planes array even for * single-planar buffers, but userspace does not. */ - b->length = vb->v4l2_planes[0].length; - b->bytesused = vb->v4l2_planes[0].bytesused; + b->length = vb->planes[0].length; + b->bytesused = vb->planes[0].bytesused; if (q->memory == V4L2_MEMORY_MMAP) - b->m.offset = vb->v4l2_planes[0].m.mem_offset; + b->m.offset = vb->planes[0].m.offset; else if (q->memory == V4L2_MEMORY_USERPTR) - b->m.userptr = vb->v4l2_planes[0].m.userptr; + b->m.userptr = vb->planes[0].m.userptr; else if (q->memory == V4L2_MEMORY_DMABUF) - b->m.fd = vb->v4l2_planes[0].m.fd; + b->m.fd = vb->planes[0].m.fd; } /* @@ -1197,7 +1217,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) vb->cnt_buf_done++; #endif dprintk(4, "done processing on buffer %d, state: %d\n", - vb->v4l2_buf.index, state); + vb->index, state); /* sync buffers */ for (plane = 0; plane < vb->num_planes; ++plane) @@ -1278,25 +1298,26 @@ static void vb2_warn_zero_bytesused(struct vb2_buffer *vb) * v4l2_buffer by the userspace. The caller has already verified that struct * v4l2_buffer has a valid number of planes. */ -static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b, - struct v4l2_plane *v4l2_planes) +static void __fill_vb2_buffer(struct vb2_buffer *vb, + const struct v4l2_buffer *b, struct vb2_plane *planes) { + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); unsigned int plane; if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { if (b->memory == V4L2_MEMORY_USERPTR) { for (plane = 0; plane < vb->num_planes; ++plane) { - v4l2_planes[plane].m.userptr = + planes[plane].m.userptr = b->m.planes[plane].m.userptr; - v4l2_planes[plane].length = + planes[plane].length = b->m.planes[plane].length; } } if (b->memory == V4L2_MEMORY_DMABUF) { for (plane = 0; plane < vb->num_planes; ++plane) { - v4l2_planes[plane].m.fd = + planes[plane].m.fd = b->m.planes[plane].m.fd; - v4l2_planes[plane].length = + planes[plane].length = b->m.planes[plane].length; } } @@ -1320,7 +1341,7 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b * applications working. */ for (plane = 0; plane < vb->num_planes; ++plane) { - struct v4l2_plane *pdst = &v4l2_planes[plane]; + struct vb2_plane *pdst = &planes[plane]; struct v4l2_plane *psrc = &b->m.planes[plane]; if (psrc->bytesused == 0) @@ -1350,13 +1371,13 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b * old userspace applications working. */ if (b->memory == V4L2_MEMORY_USERPTR) { - v4l2_planes[0].m.userptr = b->m.userptr; - v4l2_planes[0].length = b->length; + planes[0].m.userptr = b->m.userptr; + planes[0].length = b->length; } if (b->memory == V4L2_MEMORY_DMABUF) { - v4l2_planes[0].m.fd = b->m.fd; - v4l2_planes[0].length = b->length; + planes[0].m.fd = b->m.fd; + planes[0].length = b->length; } if (V4L2_TYPE_IS_OUTPUT(b->type)) { @@ -1364,17 +1385,17 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b vb2_warn_zero_bytesused(vb); if (vb->vb2_queue->allow_zero_bytesused) - v4l2_planes[0].bytesused = b->bytesused; + planes[0].bytesused = b->bytesused; else - v4l2_planes[0].bytesused = b->bytesused ? - b->bytesused : v4l2_planes[0].length; + planes[0].bytesused = b->bytesused ? + b->bytesused : planes[0].length; } else - v4l2_planes[0].bytesused = 0; + planes[0].bytesused = 0; } /* Zero flags that the vb2 core handles */ - vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS; + vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS; if ((vb->vb2_queue->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) != V4L2_BUF_FLAG_TIMESTAMP_COPY || !V4L2_TYPE_IS_OUTPUT(b->type)) { /* @@ -1382,7 +1403,7 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b * their timestamp and timestamp source flags from the * queue. */ - vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; } if (V4L2_TYPE_IS_OUTPUT(b->type)) { @@ -1392,11 +1413,11 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b * The 'field' is valid metadata for this output buffer * and so that needs to be copied here. */ - vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE; - vb->v4l2_buf.field = b->field; + vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE; + vbuf->field = b->field; } else { /* Zero any output buffer flags as this is a capture buffer */ - vb->v4l2_buf.flags &= ~V4L2_BUFFER_OUT_FLAGS; + vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS; } } @@ -1405,7 +1426,7 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b */ static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) { - __fill_vb2_buffer(vb, b, vb->v4l2_planes); + __fill_vb2_buffer(vb, b, vb->planes); return call_vb_qop(vb, buf_prepare, vb); } @@ -1414,7 +1435,7 @@ static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) */ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) { - struct v4l2_plane planes[VIDEO_MAX_PLANES]; + struct vb2_plane planes[VIDEO_MAX_PLANES]; struct vb2_queue *q = vb->vb2_queue; void *mem_priv; unsigned int plane; @@ -1429,9 +1450,9 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) for (plane = 0; plane < vb->num_planes; ++plane) { /* Skip the plane if already verified */ - if (vb->v4l2_planes[plane].m.userptr && - vb->v4l2_planes[plane].m.userptr == planes[plane].m.userptr - && vb->v4l2_planes[plane].length == planes[plane].length) + if (vb->planes[plane].m.userptr && + vb->planes[plane].m.userptr == planes[plane].m.userptr + && vb->planes[plane].length == planes[plane].length) continue; dprintk(3, "userspace address for plane %d changed, " @@ -1457,7 +1478,10 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) } vb->planes[plane].mem_priv = NULL; - memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); + vb->planes[plane].bytesused = 0; + vb->planes[plane].length = 0; + vb->planes[plane].m.userptr = 0; + vb->planes[plane].data_offset = 0; /* Acquire each plane's memory */ mem_priv = call_ptr_memop(vb, get_userptr, q->alloc_ctx[plane], @@ -1476,8 +1500,12 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) * Now that everything is in order, copy relevant information * provided by userspace. */ - for (plane = 0; plane < vb->num_planes; ++plane) - vb->v4l2_planes[plane] = planes[plane]; + for (plane = 0; plane < vb->num_planes; ++plane) { + vb->planes[plane].bytesused = planes[plane].bytesused; + vb->planes[plane].length = planes[plane].length; + vb->planes[plane].m.userptr = planes[plane].m.userptr; + vb->planes[plane].data_offset = planes[plane].data_offset; + } if (reacquired) { /* @@ -1504,10 +1532,11 @@ err: /* In case of errors, release planes that were already acquired */ for (plane = 0; plane < vb->num_planes; ++plane) { if (vb->planes[plane].mem_priv) - call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv); + call_void_memop(vb, put_userptr, + vb->planes[plane].mem_priv); vb->planes[plane].mem_priv = NULL; - vb->v4l2_planes[plane].m.userptr = 0; - vb->v4l2_planes[plane].length = 0; + vb->planes[plane].m.userptr = 0; + vb->planes[plane].length = 0; } return ret; @@ -1518,7 +1547,7 @@ err: */ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) { - struct v4l2_plane planes[VIDEO_MAX_PLANES]; + struct vb2_plane planes[VIDEO_MAX_PLANES]; struct vb2_queue *q = vb->vb2_queue; void *mem_priv; unsigned int plane; @@ -1554,7 +1583,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) /* Skip the plane if already verified */ if (dbuf == vb->planes[plane].dbuf && - vb->v4l2_planes[plane].length == planes[plane].length) { + vb->planes[plane].length == planes[plane].length) { dma_buf_put(dbuf); continue; } @@ -1568,11 +1597,15 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) /* Release previously acquired memory if present */ __vb2_plane_dmabuf_put(vb, &vb->planes[plane]); - memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); + vb->planes[plane].bytesused = 0; + vb->planes[plane].length = 0; + vb->planes[plane].m.fd = 0; + vb->planes[plane].data_offset = 0; /* Acquire each plane's memory */ - mem_priv = call_ptr_memop(vb, attach_dmabuf, q->alloc_ctx[plane], - dbuf, planes[plane].length, dma_dir); + mem_priv = call_ptr_memop(vb, attach_dmabuf, + q->alloc_ctx[plane], dbuf, planes[plane].length, + dma_dir); if (IS_ERR(mem_priv)) { dprintk(1, "failed to attach dmabuf\n"); ret = PTR_ERR(mem_priv); @@ -1602,8 +1635,12 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) * Now that everything is in order, copy relevant information * provided by userspace. */ - for (plane = 0; plane < vb->num_planes; ++plane) - vb->v4l2_planes[plane] = planes[plane]; + for (plane = 0; plane < vb->num_planes; ++plane) { + vb->planes[plane].bytesused = planes[plane].bytesused; + vb->planes[plane].length = planes[plane].length; + vb->planes[plane].m.fd = planes[plane].m.fd; + vb->planes[plane].data_offset = planes[plane].data_offset; + } if (reacquired) { /* @@ -1654,6 +1691,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb) static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) { + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_queue *q = vb->vb2_queue; int ret; @@ -1682,9 +1720,9 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) } vb->state = VB2_BUF_STATE_PREPARING; - vb->v4l2_buf.timestamp.tv_sec = 0; - vb->v4l2_buf.timestamp.tv_usec = 0; - vb->v4l2_buf.sequence = 0; + vbuf->timestamp.tv_sec = 0; + vbuf->timestamp.tv_usec = 0; + vbuf->sequence = 0; switch (q->memory) { case V4L2_MEMORY_MMAP: @@ -1776,7 +1814,7 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) /* Fill buffer information for the userspace */ __fill_v4l2_buffer(vb, b); - dprintk(1, "prepare of buffer %d succeeded\n", vb->v4l2_buf.index); + dprintk(1, "prepare of buffer %d succeeded\n", vb->index); } return ret; } @@ -1818,7 +1856,7 @@ static int vb2_start_streaming(struct vb2_queue *q) /* * If you see this warning, then the driver isn't cleaning up properly * after a failed start_streaming(). See the start_streaming() - * documentation in videobuf2-v4l2.h for more information how buffers + * documentation in videobuf2-core.h for more information how buffers * should be returned to vb2 in start_streaming(). */ if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { @@ -1849,11 +1887,13 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) { int ret = vb2_queue_or_prepare_buf(q, b, "qbuf"); struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vbuf; if (ret) return ret; vb = q->bufs[b->index]; + vbuf = to_vb2_v4l2_buffer(vb); switch (vb->state) { case VB2_BUF_STATE_DEQUEUED: @@ -1886,10 +1926,10 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) */ if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) == V4L2_BUF_FLAG_TIMESTAMP_COPY) - vb->v4l2_buf.timestamp = b->timestamp; - vb->v4l2_buf.flags |= b->flags & V4L2_BUF_FLAG_TIMECODE; + vbuf->timestamp = b->timestamp; + vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE; if (b->flags & V4L2_BUF_FLAG_TIMECODE) - vb->v4l2_buf.timecode = b->timecode; + vbuf->timecode = b->timecode; } trace_vb2_qbuf(q, vb); @@ -1917,7 +1957,7 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) return ret; } - dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index); + dprintk(1, "qbuf of buffer %d succeeded\n", vb->index); return 0; } @@ -2107,9 +2147,11 @@ static void __vb2_dqbuf(struct vb2_buffer *vb) } } -static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) +static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, + bool nonblocking) { struct vb2_buffer *vb = NULL; + struct vb2_v4l2_buffer *vbuf = NULL; int ret; if (b->type != q->type) { @@ -2142,14 +2184,15 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n trace_vb2_dqbuf(q, vb); + vbuf = to_vb2_v4l2_buffer(vb); if (!V4L2_TYPE_IS_OUTPUT(q->type) && - vb->v4l2_buf.flags & V4L2_BUF_FLAG_LAST) + vbuf->flags & V4L2_BUF_FLAG_LAST) q->last_buffer_dequeued = true; /* go back to dequeued state */ __vb2_dqbuf(vb); dprintk(1, "dqbuf of buffer %d, with state %d\n", - vb->v4l2_buf.index, vb->state); + vb->index, vb->state); return 0; } @@ -2205,7 +2248,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) /* * If you see this warning, then the driver isn't cleaning up properly * in stop_streaming(). See the stop_streaming() documentation in - * videobuf2-v4l2.h for more information how buffers should be returned + * videobuf2-core.h for more information how buffers should be returned * to vb2 in stop_streaming(). */ if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { @@ -2407,7 +2450,7 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, vb = q->bufs[buffer]; for (plane = 0; plane < vb->num_planes; ++plane) { - if (vb->v4l2_planes[plane].m.mem_offset == off) { + if (vb->planes[plane].m.offset == off) { *_buffer = buffer; *_plane = plane; return 0; @@ -2565,7 +2608,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) * The buffer length was page_aligned at __vb2_buf_mem_alloc(), * so, we need to do the same here. */ - length = PAGE_ALIGN(vb->v4l2_planes[plane].length); + length = PAGE_ALIGN(vb->planes[plane].length); if (length < (vma->vm_end - vma->vm_start)) { dprintk(1, "MMAP invalid, as it would overflow buffer length\n"); @@ -2739,7 +2782,7 @@ EXPORT_SYMBOL_GPL(vb2_poll); * responsible of clearing it's content and setting initial values for some * required entries before calling this function. * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer - * to the struct vb2_queue description in include/media/videobuf2-v4l2.h + * to the struct vb2_queue description in include/media/videobuf2-core.h * for more information. */ int vb2_queue_init(struct vb2_queue *q) @@ -2770,7 +2813,7 @@ int vb2_queue_init(struct vb2_queue *q) init_waitqueue_head(&q->done_wq); if (q->buf_struct_size == 0) - q->buf_struct_size = sizeof(struct vb2_buffer); + q->buf_struct_size = sizeof(struct vb2_v4l2_buffer); return 0; } diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 19990d7..108fa16 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -111,10 +111,38 @@ struct vb2_mem_ops { int (*mmap)(void *buf_priv, struct vm_area_struct *vma); }; +/** + * struct vb2_plane - plane information + * @mem_priv: private data with this plane + * @dbuf: dma_buf - shared buffer object + * @dbuf_mapped: flag to show whether dbuf is mapped or not + * @bytesused: number of bytes occupied by data in the plane (payload) + * @length: size of this plane (NOT the payload) in bytes + * @mem_offset: when memory in the associated struct vb2_buffer is + * VB2_MEMORY_MMAP, equals the offset from the start of + * the device memory for this plane (or is a "cookie" that + * should be passed to mmap() called on the video node) + * @userptr: when memory is VB2_MEMORY_USERPTR, a userspace pointer + * pointing to this plane + * @fd: when memory is VB2_MEMORY_DMABUF, a userspace file + * descriptor associated with this plane + * @data_offset: offset in the plane to the start of data; usually 0, + * unless there is a header in front of the data + * Should contain enough information to be able to cover all the fields + * of struct v4l2_plane at videodev2.h + */ struct vb2_plane { void *mem_priv; struct dma_buf *dbuf; unsigned int dbuf_mapped; + unsigned int bytesused; + unsigned int length; + union { + unsigned int offset; + unsigned long userptr; + int fd; + } m; + unsigned int data_offset; }; /** @@ -163,43 +191,32 @@ struct vb2_queue; /** * struct vb2_buffer - represents a video buffer - * @v4l2_buf: struct v4l2_buffer associated with this buffer; can - * be read by the driver and relevant entries can be - * changed by the driver in case of CAPTURE types - * (such as timestamp) - * @v4l2_planes: struct v4l2_planes associated with this buffer; can - * be read by the driver and relevant entries can be - * changed by the driver in case of CAPTURE types - * (such as bytesused); NOTE that even for single-planar - * types, the v4l2_planes[0] struct should be used - * instead of v4l2_buf for filling bytesused - drivers - * should use the vb2_set_plane_payload() function for that * @vb2_queue: the queue to which this driver belongs + * @index: id number of the buffer + * @type: buffer type + * @memory: the method, in which the actual data is passed * @num_planes: number of planes in the buffer * on an internal driver queue + * @planes: private per-plane information; do not change * @state: current buffer state; do not change * @queued_entry: entry on the queued buffers list, which holds all * buffers queued from userspace * @done_entry: entry on the list that stores all buffers ready to * be dequeued to userspace - * @planes: private per-plane information; do not change */ struct vb2_buffer { - struct v4l2_buffer v4l2_buf; - struct v4l2_plane v4l2_planes[VIDEO_MAX_PLANES]; - struct vb2_queue *vb2_queue; - + unsigned int index; + unsigned int type; + unsigned int memory; unsigned int num_planes; + struct vb2_plane planes[VIDEO_MAX_PLANES]; -/* Private: internal use only */ + /* Private: internal use only */ enum vb2_buffer_state state; struct list_head queued_entry; struct list_head done_entry; - - struct vb2_plane planes[VIDEO_MAX_PLANES]; - #ifdef CONFIG_VIDEO_ADV_DEBUG /* * Counters for how often these buffer-related ops are @@ -354,7 +371,8 @@ struct v4l2_fh; * @drv_priv: driver private data * @buf_struct_size: size of the driver-specific buffer structure; * "0" indicates the driver doesn't want to use a custom buffer - * structure type, so sizeof(struct vb2_buffer) will is used + * structure type. for example, sizeof(struct vb2_v4l2_buffer) + * will be used for v4l2. * @timestamp_flags: Timestamp flags; V4L2_BUF_FLAG_TIMESTAMP_* and * V4L2_BUF_FLAG_TSTAMP_SRC_* * @gfp_flags: additional gfp flags used when allocating the buffers. @@ -573,7 +591,7 @@ static inline void vb2_set_plane_payload(struct vb2_buffer *vb, unsigned int plane_no, unsigned long size) { if (plane_no < vb->num_planes) - vb->v4l2_planes[plane_no].bytesused = size; + vb->planes[plane_no].bytesused = size; } /** @@ -585,7 +603,7 @@ static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb, unsigned int plane_no) { if (plane_no < vb->num_planes) - return vb->v4l2_planes[plane_no].bytesused; + return vb->planes[plane_no].bytesused; return 0; } @@ -598,7 +616,7 @@ static inline unsigned long vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no) { if (plane_no < vb->num_planes) - return vb->v4l2_planes[plane_no].length; + return vb->planes[plane_no].length; return 0; } diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index d4a4d9a..20d8ad2 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -12,6 +12,34 @@ #ifndef _MEDIA_VIDEOBUF2_V4L2_H #define _MEDIA_VIDEOBUF2_V4L2_H +#include #include +/** + * struct vb2_v4l2_buffer - video buffer information for v4l2 + * @vb2_buf: video buffer 2 + * @flags: buffer informational flags + * @field: enum v4l2_field; field order of the image in the buffer + * @timestamp: frame timestamp + * @timecode: frame timecode + * @sequence: sequence count of this frame + * Should contain enough information to be able to cover all the fields + * of struct v4l2_buffer at videodev2.h + */ +struct vb2_v4l2_buffer { + struct vb2_buffer vb2_buf; + + __u32 flags; + __u32 field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; +}; + +/** + * to_vb2_v4l2_buffer() - cast struct vb2_buffer * to struct vb2_v4l2_buffer * + */ +#define to_vb2_v4l2_buffer(vb) \ + (container_of(vb, struct vb2_v4l2_buffer, vb2_buf)) + #endif /* _MEDIA_VIDEOBUF2_V4L2_H */