aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-12-13 11:13:42 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 04:12:43 -0500
commit02f142ecd24aaf891324ffba8527284c1731b561 (patch)
tree1ac39716460e3abac1fd96f8bd0621af83efff76
parentb2f2f04719638322b9d792ecd25f70a55acf8270 (diff)
[media] vb2: retry start_streaming in case of insufficient buffers
If start_streaming returns -ENOBUFS, then it will be retried the next time a buffer is queued. This means applications no longer need to know how many buffers need to be queued before STREAMON can be called. This is particularly useful for output stream I/O. If a DMA engine needs at least X buffers before it can start streaming, then for applications to get a buffer out as soon as possible they need to know the minimum number of buffers to queue before STREAMON can be called. You can't just try STREAMON after every buffer since on failure STREAMON will dequeue all your buffers. (Is that a bug or a feature? Frankly, I'm not sure). This patch simplifies applications substantially: they can just call STREAMON at the beginning and then start queuing buffers and the DMA engine will kick in automagically once enough buffers are available. This also fixes using write() to stream video: the fileio implementation calls streamon without having any queued buffers, which will fail today for any driver that requires a minimum number of buffers. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c68
-rw-r--r--include/media/videobuf2-core.h15
2 files changed, 66 insertions, 17 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 14a360490be9..0d5b84f3b570 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1378,6 +1378,39 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
1378} 1378}
1379EXPORT_SYMBOL_GPL(vb2_prepare_buf); 1379EXPORT_SYMBOL_GPL(vb2_prepare_buf);
1380 1380
1381/**
1382 * vb2_start_streaming() - Attempt to start streaming.
1383 * @q: videobuf2 queue
1384 *
1385 * If there are not enough buffers, then retry_start_streaming is set to
1386 * 1 and 0 is returned. The next time a buffer is queued and
1387 * retry_start_streaming is 1, this function will be called again to
1388 * retry starting the DMA engine.
1389 */
1390static int vb2_start_streaming(struct vb2_queue *q)
1391{
1392 int ret;
1393
1394 /* Tell the driver to start streaming */
1395 ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
1396
1397 /*
1398 * If there are not enough buffers queued to start streaming, then
1399 * the start_streaming operation will return -ENOBUFS and you have to
1400 * retry when the next buffer is queued.
1401 */
1402 if (ret == -ENOBUFS) {
1403 dprintk(1, "qbuf: not enough buffers, retry when more buffers are queued.\n");
1404 q->retry_start_streaming = 1;
1405 return 0;
1406 }
1407 if (ret)
1408 dprintk(1, "qbuf: driver refused to start streaming\n");
1409 else
1410 q->retry_start_streaming = 0;
1411 return ret;
1412}
1413
1381static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) 1414static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
1382{ 1415{
1383 int ret = vb2_queue_or_prepare_buf(q, b, "qbuf"); 1416 int ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
@@ -1426,6 +1459,12 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
1426 /* Fill buffer information for the userspace */ 1459 /* Fill buffer information for the userspace */
1427 __fill_v4l2_buffer(vb, b); 1460 __fill_v4l2_buffer(vb, b);
1428 1461
1462 if (q->retry_start_streaming) {
1463 ret = vb2_start_streaming(q);
1464 if (ret)
1465 return ret;
1466 }
1467
1429 dprintk(1, "%s() of buffer %d succeeded\n", __func__, vb->v4l2_buf.index); 1468 dprintk(1, "%s() of buffer %d succeeded\n", __func__, vb->v4l2_buf.index);
1430 return 0; 1469 return 0;
1431} 1470}
@@ -1575,7 +1614,8 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q)
1575 return -EINVAL; 1614 return -EINVAL;
1576 } 1615 }
1577 1616
1578 wait_event(q->done_wq, !atomic_read(&q->queued_count)); 1617 if (!q->retry_start_streaming)
1618 wait_event(q->done_wq, !atomic_read(&q->queued_count));
1579 return 0; 1619 return 0;
1580} 1620}
1581EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers); 1621EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
@@ -1689,6 +1729,11 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
1689{ 1729{
1690 unsigned int i; 1730 unsigned int i;
1691 1731
1732 if (q->retry_start_streaming) {
1733 q->retry_start_streaming = 0;
1734 q->streaming = 0;
1735 }
1736
1692 /* 1737 /*
1693 * Tell driver to stop all transactions and release all queued 1738 * Tell driver to stop all transactions and release all queued
1694 * buffers. 1739 * buffers.
@@ -1738,12 +1783,9 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1738 list_for_each_entry(vb, &q->queued_list, queued_entry) 1783 list_for_each_entry(vb, &q->queued_list, queued_entry)
1739 __enqueue_in_driver(vb); 1784 __enqueue_in_driver(vb);
1740 1785
1741 /* 1786 /* Tell driver to start streaming. */
1742 * Let driver notice that streaming state has been enabled. 1787 ret = vb2_start_streaming(q);
1743 */
1744 ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
1745 if (ret) { 1788 if (ret) {
1746 dprintk(1, "streamon: driver refused to start streaming\n");
1747 __vb2_queue_cancel(q); 1789 __vb2_queue_cancel(q);
1748 return ret; 1790 return ret;
1749 } 1791 }
@@ -2313,15 +2355,15 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
2313 goto err_reqbufs; 2355 goto err_reqbufs;
2314 fileio->bufs[i].queued = 1; 2356 fileio->bufs[i].queued = 1;
2315 } 2357 }
2316
2317 /*
2318 * Start streaming.
2319 */
2320 ret = vb2_streamon(q, q->type);
2321 if (ret)
2322 goto err_reqbufs;
2323 } 2358 }
2324 2359
2360 /*
2361 * Start streaming.
2362 */
2363 ret = vb2_streamon(q, q->type);
2364 if (ret)
2365 goto err_reqbufs;
2366
2325 q->fileio = fileio; 2367 q->fileio = fileio;
2326 2368
2327 return ret; 2369 return ret;
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index ea766525a268..bef53ce555d2 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -252,10 +252,13 @@ struct vb2_buffer {
252 * receive buffers with @buf_queue callback before 252 * receive buffers with @buf_queue callback before
253 * @start_streaming is called; the driver gets the number 253 * @start_streaming is called; the driver gets the number
254 * of already queued buffers in count parameter; driver 254 * of already queued buffers in count parameter; driver
255 * can return an error if hardware fails or not enough 255 * can return an error if hardware fails, in that case all
256 * buffers has been queued, in such case all buffers that 256 * buffers that have been already given by the @buf_queue
257 * have been already given by the @buf_queue callback are 257 * callback are invalidated.
258 * invalidated. 258 * If there were not enough queued buffers to start
259 * streaming, then this callback returns -ENOBUFS, and the
260 * vb2 core will retry calling @start_streaming when a new
261 * buffer is queued.
259 * @stop_streaming: called when 'streaming' state must be disabled; driver 262 * @stop_streaming: called when 'streaming' state must be disabled; driver
260 * should stop any DMA transactions or wait until they 263 * should stop any DMA transactions or wait until they
261 * finish and give back all buffers it got from buf_queue() 264 * finish and give back all buffers it got from buf_queue()
@@ -323,6 +326,9 @@ struct v4l2_fh;
323 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued 326 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
324 * @alloc_ctx: memory type/allocator-specific contexts for each plane 327 * @alloc_ctx: memory type/allocator-specific contexts for each plane
325 * @streaming: current streaming state 328 * @streaming: current streaming state
329 * @retry_start_streaming: start_streaming() was called, but there were not enough
330 * buffers queued. If set, then retry calling start_streaming when
331 * queuing a new buffer.
326 * @fileio: file io emulator internal data, used only if emulator is active 332 * @fileio: file io emulator internal data, used only if emulator is active
327 */ 333 */
328struct vb2_queue { 334struct vb2_queue {
@@ -355,6 +361,7 @@ struct vb2_queue {
355 unsigned int plane_sizes[VIDEO_MAX_PLANES]; 361 unsigned int plane_sizes[VIDEO_MAX_PLANES];
356 362
357 unsigned int streaming:1; 363 unsigned int streaming:1;
364 unsigned int retry_start_streaming:1;
358 365
359 struct vb2_fileio_data *fileio; 366 struct vb2_fileio_data *fileio;
360}; 367};