diff options
author | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2011-02-01 11:19:29 -0300 |
---|---|---|
committer | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2011-02-03 19:09:20 -0300 |
commit | 1a62d9374b228dc5bd3fb8c7da2212ceb5506430 (patch) | |
tree | c3a4047e8737a54ffdb77ae1a5fca5444634a76a | |
parent | 4a7dc8178207b00ee43f7071fa43ff1581a6199d (diff) |
wrappercamerabinsrc: Handle src state change to avoid losing timestamps
Camerabin2 uses state changes to force the source to renegotiate its
caps to the capture formats. The state changes makes the source lose
its clock and base_time, causing it to stop timestamping the buffers.
We still need a proper way to make sources renegotiate its caps, so this
patch is a hack to make the source continue timestamping buffers even
after changing state. The patch works by getting the clock and base
time before doing the state change to NULL and setting them back
after putting it to PLAYING again. It also cares to drop the first
new segment after this state change.
-rw-r--r-- | gst/camerabin2/gstwrappercamerabinsrc.c | 67 | ||||
-rw-r--r-- | gst/camerabin2/gstwrappercamerabinsrc.h | 3 |
2 files changed, 69 insertions, 1 deletions
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c index c35fe8d77..0f2e6090a 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.c +++ b/gst/camerabin2/gstwrappercamerabinsrc.c | |||
@@ -165,12 +165,50 @@ static void | |||
165 | gst_wrapper_camera_bin_reset_video_src_caps (GstWrapperCameraBinSrc * self, | 165 | gst_wrapper_camera_bin_reset_video_src_caps (GstWrapperCameraBinSrc * self, |
166 | GstCaps * caps) | 166 | GstCaps * caps) |
167 | { | 167 | { |
168 | GstClock *clock; | ||
169 | gint64 base_time; | ||
170 | |||
168 | GST_DEBUG_OBJECT (self, "Resetting src caps to %" GST_PTR_FORMAT, caps); | 171 | GST_DEBUG_OBJECT (self, "Resetting src caps to %" GST_PTR_FORMAT, caps); |
169 | if (self->src_vid_src) { | 172 | if (self->src_vid_src) { |
173 | clock = gst_element_get_clock (self->src_vid_src); | ||
174 | base_time = gst_element_get_base_time (self->src_vid_src); | ||
175 | |||
170 | gst_element_set_state (self->src_vid_src, GST_STATE_NULL); | 176 | gst_element_set_state (self->src_vid_src, GST_STATE_NULL); |
171 | set_capsfilter_caps (self, caps); | 177 | set_capsfilter_caps (self, caps); |
178 | |||
179 | self->drop_newseg = TRUE; | ||
180 | |||
172 | GST_DEBUG_OBJECT (self, "Bringing source up"); | 181 | GST_DEBUG_OBJECT (self, "Bringing source up"); |
173 | gst_element_sync_state_with_parent (self->src_vid_src); | 182 | gst_element_sync_state_with_parent (self->src_vid_src); |
183 | |||
184 | gst_element_set_clock (self->src_vid_src, clock); | ||
185 | gst_element_set_base_time (self->src_vid_src, base_time); | ||
186 | |||
187 | if (GST_IS_BIN (self->src_vid_src)) { | ||
188 | GstIterator *it = gst_bin_iterate_elements (GST_BIN (self->src_vid_src)); | ||
189 | gpointer item = NULL; | ||
190 | gboolean done = FALSE; | ||
191 | while (!done) { | ||
192 | switch (gst_iterator_next (it, &item)) { | ||
193 | case GST_ITERATOR_OK: | ||
194 | gst_element_set_base_time (GST_ELEMENT (item), base_time); | ||
195 | gst_object_unref (item); | ||
196 | break; | ||
197 | case GST_ITERATOR_RESYNC: | ||
198 | gst_iterator_resync (it); | ||
199 | break; | ||
200 | case GST_ITERATOR_ERROR: | ||
201 | done = TRUE; | ||
202 | break; | ||
203 | case GST_ITERATOR_DONE: | ||
204 | done = TRUE; | ||
205 | break; | ||
206 | } | ||
207 | } | ||
208 | gst_iterator_free (it); | ||
209 | } | ||
210 | |||
211 | gst_object_unref (clock); | ||
174 | } | 212 | } |
175 | } | 213 | } |
176 | 214 | ||
@@ -286,6 +324,30 @@ gst_wrapper_camera_bin_src_event (GstPad * pad, GstEvent * event) | |||
286 | return src->srcpad_event_func (pad, event); | 324 | return src->srcpad_event_func (pad, event); |
287 | } | 325 | } |
288 | 326 | ||
327 | static gboolean | ||
328 | gst_wrapper_camera_src_src_event_probe (GstPad * pad, GstEvent * evt, | ||
329 | gpointer udata) | ||
330 | { | ||
331 | gboolean ret = TRUE; | ||
332 | GstWrapperCameraBinSrc *self = udata; | ||
333 | |||
334 | switch (GST_EVENT_TYPE (evt)) { | ||
335 | case GST_EVENT_EOS: | ||
336 | /* drop */ | ||
337 | ret = FALSE; | ||
338 | break; | ||
339 | case GST_EVENT_NEWSEGMENT: | ||
340 | if (self->drop_newseg) { | ||
341 | ret = FALSE; | ||
342 | self->drop_newseg = FALSE; | ||
343 | } | ||
344 | break; | ||
345 | default: | ||
346 | break; | ||
347 | } | ||
348 | return ret; | ||
349 | } | ||
350 | |||
289 | /** | 351 | /** |
290 | * gst_wrapper_camera_bin_src_construct_pipeline: | 352 | * gst_wrapper_camera_bin_src_construct_pipeline: |
291 | * @bcamsrc: camerasrc object | 353 | * @bcamsrc: camerasrc object |
@@ -334,7 +396,7 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc) | |||
334 | pad = gst_element_get_static_pad (self->src_vid_src, "src"); | 396 | pad = gst_element_get_static_pad (self->src_vid_src, "src"); |
335 | 397 | ||
336 | self->src_event_probe_id = gst_pad_add_event_probe (pad, | 398 | self->src_event_probe_id = gst_pad_add_event_probe (pad, |
337 | (GCallback) gst_camerabin_drop_eos_probe, NULL); | 399 | (GCallback) gst_wrapper_camera_src_src_event_probe, self); |
338 | gst_object_unref (pad); | 400 | gst_object_unref (pad); |
339 | } | 401 | } |
340 | 402 | ||
@@ -991,6 +1053,9 @@ gst_wrapper_camera_bin_src_change_state (GstElement * element, | |||
991 | goto end; | 1053 | goto end; |
992 | 1054 | ||
993 | switch (trans) { | 1055 | switch (trans) { |
1056 | case GST_STATE_CHANGE_PAUSED_TO_READY: | ||
1057 | self->drop_newseg = FALSE; | ||
1058 | break; | ||
994 | case GST_STATE_CHANGE_READY_TO_NULL: | 1059 | case GST_STATE_CHANGE_READY_TO_NULL: |
995 | gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL); | 1060 | gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL); |
996 | break; | 1061 | break; |
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.h b/gst/camerabin2/gstwrappercamerabinsrc.h index b2f4c7ae6..d937321a8 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.h +++ b/gst/camerabin2/gstwrappercamerabinsrc.h | |||
@@ -88,6 +88,9 @@ struct _GstWrapperCameraBinSrc | |||
88 | 88 | ||
89 | GstPadEventFunction srcpad_event_func; | 89 | GstPadEventFunction srcpad_event_func; |
90 | 90 | ||
91 | /* For changing caps without losing timestamps */ | ||
92 | gboolean drop_newseg; | ||
93 | |||
91 | /* Application configurable elements */ | 94 | /* Application configurable elements */ |
92 | GstElement *app_vid_src; | 95 | GstElement *app_vid_src; |
93 | 96 | ||