Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux...
[deliverable/linux.git] / drivers / media / v4l2-core / videobuf2-core.c
index 66ada01c796ca934527321fe67406667c2927c9a..93b315459098932381d61d282cdb3f04194b18ae 100644 (file)
@@ -182,6 +182,7 @@ module_param(debug, int, 0644);
                                 V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
 
 static void __vb2_queue_cancel(struct vb2_queue *q);
+static void __enqueue_in_driver(struct vb2_buffer *vb);
 
 /**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
@@ -1153,8 +1154,9 @@ EXPORT_SYMBOL_GPL(vb2_plane_cookie);
 /**
  * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
  * @vb:                vb2_buffer returned from the driver
- * @state:     either VB2_BUF_STATE_DONE if the operation finished successfully
- *             or VB2_BUF_STATE_ERROR if the operation finished with an error.
+ * @state:     either VB2_BUF_STATE_DONE if the operation finished successfully,
+ *             VB2_BUF_STATE_ERROR if the operation finished with an error or
+ *             VB2_BUF_STATE_QUEUED if the driver wants to requeue buffers.
  *             If start_streaming fails then it should return buffers with state
  *             VB2_BUF_STATE_QUEUED to put them back into the queue.
  *
@@ -1205,8 +1207,11 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
        atomic_dec(&q->owned_by_drv_count);
        spin_unlock_irqrestore(&q->done_lock, flags);
 
-       if (state == VB2_BUF_STATE_QUEUED)
+       if (state == VB2_BUF_STATE_QUEUED) {
+               if (q->start_streaming_called)
+                       __enqueue_in_driver(vb);
                return;
+       }
 
        /* Inform any processes that may be waiting for buffers */
        wake_up(&q->done_wq);
@@ -1237,6 +1242,23 @@ void vb2_discard_done(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(vb2_discard_done);
 
+static void vb2_warn_zero_bytesused(struct vb2_buffer *vb)
+{
+       static bool __check_once __read_mostly;
+
+       if (__check_once)
+               return;
+
+       __check_once = true;
+       __WARN();
+
+       pr_warn_once("use of bytesused == 0 is deprecated and will be removed in the future,\n");
+       if (vb->vb2_queue->allow_zero_bytesused)
+               pr_warn_once("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n");
+       else
+               pr_warn_once("use the actual size instead.\n");
+}
+
 /**
  * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
  * v4l2_buffer by the userspace. The caller has already verified that struct
@@ -1247,16 +1269,6 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
 {
        unsigned int plane;
 
-       if (V4L2_TYPE_IS_OUTPUT(b->type)) {
-               if (WARN_ON_ONCE(b->bytesused == 0)) {
-                       pr_warn_once("use of bytesused == 0 is deprecated and will be removed in the future,\n");
-                       if (vb->vb2_queue->allow_zero_bytesused)
-                               pr_warn_once("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n");
-                       else
-                               pr_warn_once("use the actual size instead.\n");
-               }
-       }
-
        if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
                if (b->memory == V4L2_MEMORY_USERPTR) {
                        for (plane = 0; plane < vb->num_planes; ++plane) {
@@ -1297,6 +1309,9 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
                                struct v4l2_plane *pdst = &v4l2_planes[plane];
                                struct v4l2_plane *psrc = &b->m.planes[plane];
 
+                               if (psrc->bytesused == 0)
+                                       vb2_warn_zero_bytesused(vb);
+
                                if (vb->vb2_queue->allow_zero_bytesused)
                                        pdst->bytesused = psrc->bytesused;
                                else
@@ -1331,6 +1346,9 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
                }
 
                if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+                       if (b->bytesused == 0)
+                               vb2_warn_zero_bytesused(vb);
+
                        if (vb->vb2_queue->allow_zero_bytesused)
                                v4l2_planes[0].bytesused = b->bytesused;
                        else
@@ -1945,6 +1963,11 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
                        return -EIO;
                }
 
+               if (q->last_buffer_dequeued) {
+                       dprintk(3, "last buffer dequeued already, will not wait for buffers\n");
+                       return -EPIPE;
+               }
+
                if (!list_empty(&q->done_list)) {
                        /*
                         * Found a buffer that we were waiting for.
@@ -2100,6 +2123,9 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
        /* Remove from videobuf queue */
        list_del(&vb->queued_entry);
        q->queued_count--;
+       if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
+           vb->v4l2_buf.flags & V4L2_BUF_FLAG_LAST)
+               q->last_buffer_dequeued = true;
        /* go back to dequeued state */
        __vb2_dqbuf(vb);
 
@@ -2313,6 +2339,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
         */
        __vb2_queue_cancel(q);
        q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
+       q->last_buffer_dequeued = false;
 
        dprintk(3, "successful\n");
        return 0;
@@ -2655,8 +2682,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
        if (V4L2_TYPE_IS_OUTPUT(q->type) && q->queued_count < q->num_buffers)
                return res | POLLOUT | POLLWRNORM;
 
-       if (list_empty(&q->done_list))
+       if (list_empty(&q->done_list)) {
+               /*
+                * If the last buffer was dequeued from a capture queue,
+                * return immediately. DQBUF will return -EPIPE.
+                */
+               if (q->last_buffer_dequeued)
+                       return res | POLLIN | POLLRDNORM;
+
                poll_wait(file, &q->done_wq, wait);
+       }
 
        /*
         * Take first buffer available for dequeuing.
This page took 0.029187 seconds and 5 git commands to generate.