gstreamer: Fix libcamerasrc responding latency before setting caps
Whenever a downstream element queries latency, libcamerasrc will always reply, even though it has not yet determined the latency. However some downstream elements (e.g. glvideomixer/aggregator) will query the latency before libcamerasrc sets the caps. When these elements get the latency, they will start the caps negotiation. Since libcamerasrc has not yet determined caps, invalid negotiation is performed and workflow is disrupted. So, set latency to 'GST_CLOCK_TIME_NONE' during initialization, and reply to the query after libcamerasrc confirms the latency. At this time, libcamerasrc has also completed caps negotiation and downstream elements work fine. In addition, every time the src pad task stops, we reset the latency to GST_CLOCK_TIME_NONE to ensure that when next time task starts, the downstream elements can generate out buffers after receiving the effective latency. Signed-off-by: Hou Qi <qi.hou@nxp.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
b4c92a61bf
commit
4a277906a4
2 changed files with 8 additions and 1 deletions
|
@ -72,6 +72,10 @@ gst_libcamera_pad_query(GstPad *pad, GstObject *parent, GstQuery *query)
|
||||||
if (query->type != GST_QUERY_LATENCY)
|
if (query->type != GST_QUERY_LATENCY)
|
||||||
return gst_pad_query_default(pad, parent, query);
|
return gst_pad_query_default(pad, parent, query);
|
||||||
|
|
||||||
|
GLibLocker lock(GST_OBJECT(self));
|
||||||
|
if (self->latency == GST_CLOCK_TIME_NONE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* TRUE here means live, we assumes that max latency is the same as min
|
/* TRUE here means live, we assumes that max latency is the same as min
|
||||||
* as we have no idea that duration of frames. */
|
* as we have no idea that duration of frames. */
|
||||||
gst_query_set_latency(query, TRUE, self->latency, self->latency);
|
gst_query_set_latency(query, TRUE, self->latency, self->latency);
|
||||||
|
@ -81,6 +85,7 @@ gst_libcamera_pad_query(GstPad *pad, GstObject *parent, GstQuery *query)
|
||||||
static void
|
static void
|
||||||
gst_libcamera_pad_init(GstLibcameraPad *self)
|
gst_libcamera_pad_init(GstLibcameraPad *self)
|
||||||
{
|
{
|
||||||
|
self->latency = GST_CLOCK_TIME_NONE;
|
||||||
GST_PAD_QUERYFUNC(self) = gst_libcamera_pad_query;
|
GST_PAD_QUERYFUNC(self) = gst_libcamera_pad_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -881,8 +881,10 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task,
|
||||||
|
|
||||||
{
|
{
|
||||||
GLibRecLocker locker(&self->stream_lock);
|
GLibRecLocker locker(&self->stream_lock);
|
||||||
for (GstPad *srcpad : state->srcpads_)
|
for (GstPad *srcpad : state->srcpads_) {
|
||||||
|
gst_libcamera_pad_set_latency(srcpad, GST_CLOCK_TIME_NONE);
|
||||||
gst_libcamera_pad_set_pool(srcpad, nullptr);
|
gst_libcamera_pad_set_pool(srcpad, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_object(&self->allocator);
|
g_clear_object(&self->allocator);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue