mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00
media: vb2: add (un)prepare_streaming queue ops
When userspace called VIDIOC_STREAMON, then you want to claim any streaming resources needed and validate the video pipeline. Waiting for start_streaming to be called is too late, since that can be postponed until the required minimum of buffers is queued. So add a prepare_streaming op (optional) that can be used for that purpose, and a matching unprepare_streaming op (optional) that can release any claimed resources. The unprepare_streaming op is called when VIDIOC_STREAMOFF is called and q->streaming is 1, or when the filehandle is closed while q->streaming is 1. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
parent
e9305a003f
commit
a10b215325
2 changed files with 35 additions and 4 deletions
|
@ -544,6 +544,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
|
||||||
*/
|
*/
|
||||||
if (q->num_buffers) {
|
if (q->num_buffers) {
|
||||||
bool unbalanced = q->cnt_start_streaming != q->cnt_stop_streaming ||
|
bool unbalanced = q->cnt_start_streaming != q->cnt_stop_streaming ||
|
||||||
|
q->cnt_prepare_streaming != q->cnt_unprepare_streaming ||
|
||||||
q->cnt_wait_prepare != q->cnt_wait_finish;
|
q->cnt_wait_prepare != q->cnt_wait_finish;
|
||||||
|
|
||||||
if (unbalanced || debug) {
|
if (unbalanced || debug) {
|
||||||
|
@ -552,14 +553,18 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
|
||||||
pr_info(" setup: %u start_streaming: %u stop_streaming: %u\n",
|
pr_info(" setup: %u start_streaming: %u stop_streaming: %u\n",
|
||||||
q->cnt_queue_setup, q->cnt_start_streaming,
|
q->cnt_queue_setup, q->cnt_start_streaming,
|
||||||
q->cnt_stop_streaming);
|
q->cnt_stop_streaming);
|
||||||
|
pr_info(" prepare_streaming: %u unprepare_streaming: %u\n",
|
||||||
|
q->cnt_prepare_streaming, q->cnt_unprepare_streaming);
|
||||||
pr_info(" wait_prepare: %u wait_finish: %u\n",
|
pr_info(" wait_prepare: %u wait_finish: %u\n",
|
||||||
q->cnt_wait_prepare, q->cnt_wait_finish);
|
q->cnt_wait_prepare, q->cnt_wait_finish);
|
||||||
}
|
}
|
||||||
q->cnt_queue_setup = 0;
|
q->cnt_queue_setup = 0;
|
||||||
q->cnt_wait_prepare = 0;
|
q->cnt_wait_prepare = 0;
|
||||||
q->cnt_wait_finish = 0;
|
q->cnt_wait_finish = 0;
|
||||||
|
q->cnt_prepare_streaming = 0;
|
||||||
q->cnt_start_streaming = 0;
|
q->cnt_start_streaming = 0;
|
||||||
q->cnt_stop_streaming = 0;
|
q->cnt_stop_streaming = 0;
|
||||||
|
q->cnt_unprepare_streaming = 0;
|
||||||
}
|
}
|
||||||
for (buffer = 0; buffer < q->num_buffers; ++buffer) {
|
for (buffer = 0; buffer < q->num_buffers; ++buffer) {
|
||||||
struct vb2_buffer *vb = q->bufs[buffer];
|
struct vb2_buffer *vb = q->bufs[buffer];
|
||||||
|
@ -1991,6 +1996,9 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
|
||||||
if (q->start_streaming_called)
|
if (q->start_streaming_called)
|
||||||
call_void_qop(q, stop_streaming, q);
|
call_void_qop(q, stop_streaming, q);
|
||||||
|
|
||||||
|
if (q->streaming)
|
||||||
|
call_void_qop(q, unprepare_streaming, q);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you see this warning, then the driver isn't cleaning up properly
|
* If you see this warning, then the driver isn't cleaning up properly
|
||||||
* in stop_streaming(). See the stop_streaming() documentation in
|
* in stop_streaming(). See the stop_streaming() documentation in
|
||||||
|
@ -2102,6 +2110,12 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = call_qop(q, prepare_streaming, q);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
q->streaming = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell driver to start streaming provided sufficient buffers
|
* Tell driver to start streaming provided sufficient buffers
|
||||||
* are available.
|
* are available.
|
||||||
|
@ -2109,16 +2123,19 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
|
||||||
if (q->queued_count >= q->min_buffers_needed) {
|
if (q->queued_count >= q->min_buffers_needed) {
|
||||||
ret = v4l_vb2q_enable_media_source(q);
|
ret = v4l_vb2q_enable_media_source(q);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto unprepare;
|
||||||
ret = vb2_start_streaming(q);
|
ret = vb2_start_streaming(q);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto unprepare;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->streaming = 1;
|
|
||||||
|
|
||||||
dprintk(q, 3, "successful\n");
|
dprintk(q, 3, "successful\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
unprepare:
|
||||||
|
call_void_qop(q, unprepare_streaming, q);
|
||||||
|
q->streaming = 0;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vb2_core_streamon);
|
EXPORT_SYMBOL_GPL(vb2_core_streamon);
|
||||||
|
|
||||||
|
|
|
@ -386,6 +386,12 @@ struct vb2_buffer {
|
||||||
* the buffer contents will be ignored anyway.
|
* the buffer contents will be ignored anyway.
|
||||||
* @buf_cleanup: called once before the buffer is freed; drivers may
|
* @buf_cleanup: called once before the buffer is freed; drivers may
|
||||||
* perform any additional cleanup; optional.
|
* perform any additional cleanup; optional.
|
||||||
|
* @prepare_streaming: called once to prepare for 'streaming' state; this is
|
||||||
|
* where validation can be done to verify everything is
|
||||||
|
* okay and streaming resources can be claimed. It is
|
||||||
|
* called when the VIDIOC_STREAMON ioctl is called. The
|
||||||
|
* actual streaming starts when @start_streaming is called.
|
||||||
|
* Optional.
|
||||||
* @start_streaming: called once to enter 'streaming' state; the driver may
|
* @start_streaming: called once to enter 'streaming' state; the driver may
|
||||||
* receive buffers with @buf_queue callback
|
* receive buffers with @buf_queue callback
|
||||||
* before @start_streaming is called; the driver gets the
|
* before @start_streaming is called; the driver gets the
|
||||||
|
@ -405,6 +411,10 @@ struct vb2_buffer {
|
||||||
* callback by calling vb2_buffer_done() with either
|
* callback by calling vb2_buffer_done() with either
|
||||||
* %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
|
* %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
|
||||||
* vb2_wait_for_all_buffers() function
|
* vb2_wait_for_all_buffers() function
|
||||||
|
* @unprepare_streaming:called as counterpart to @prepare_streaming; any claimed
|
||||||
|
* streaming resources can be released here. It is
|
||||||
|
* called when the VIDIOC_STREAMOFF ioctls is called or
|
||||||
|
* when the streaming filehandle is closed. Optional.
|
||||||
* @buf_queue: passes buffer vb to the driver; driver may start
|
* @buf_queue: passes buffer vb to the driver; driver may start
|
||||||
* hardware operation on this buffer; driver should give
|
* hardware operation on this buffer; driver should give
|
||||||
* the buffer back by calling vb2_buffer_done() function;
|
* the buffer back by calling vb2_buffer_done() function;
|
||||||
|
@ -432,8 +442,10 @@ struct vb2_ops {
|
||||||
void (*buf_finish)(struct vb2_buffer *vb);
|
void (*buf_finish)(struct vb2_buffer *vb);
|
||||||
void (*buf_cleanup)(struct vb2_buffer *vb);
|
void (*buf_cleanup)(struct vb2_buffer *vb);
|
||||||
|
|
||||||
|
int (*prepare_streaming)(struct vb2_queue *q);
|
||||||
int (*start_streaming)(struct vb2_queue *q, unsigned int count);
|
int (*start_streaming)(struct vb2_queue *q, unsigned int count);
|
||||||
void (*stop_streaming)(struct vb2_queue *q);
|
void (*stop_streaming)(struct vb2_queue *q);
|
||||||
|
void (*unprepare_streaming)(struct vb2_queue *q);
|
||||||
|
|
||||||
void (*buf_queue)(struct vb2_buffer *vb);
|
void (*buf_queue)(struct vb2_buffer *vb);
|
||||||
|
|
||||||
|
@ -641,8 +653,10 @@ struct vb2_queue {
|
||||||
u32 cnt_queue_setup;
|
u32 cnt_queue_setup;
|
||||||
u32 cnt_wait_prepare;
|
u32 cnt_wait_prepare;
|
||||||
u32 cnt_wait_finish;
|
u32 cnt_wait_finish;
|
||||||
|
u32 cnt_prepare_streaming;
|
||||||
u32 cnt_start_streaming;
|
u32 cnt_start_streaming;
|
||||||
u32 cnt_stop_streaming;
|
u32 cnt_stop_streaming;
|
||||||
|
u32 cnt_unprepare_streaming;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue