diff options
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 68 | ||||
-rw-r--r-- | include/media/videobuf2-core.h | 15 |
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 | } |
1379 | EXPORT_SYMBOL_GPL(vb2_prepare_buf); | 1379 | EXPORT_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 | */ | ||
1390 | static 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 | |||
1381 | static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | 1414 | static 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 | } |
1581 | EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers); | 1621 | EXPORT_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 | */ |
328 | struct vb2_queue { | 334 | struct 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 | }; |