summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>2011-02-01 11:19:29 -0300
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>2011-02-03 19:09:20 -0300
commit1a62d9374b228dc5bd3fb8c7da2212ceb5506430 (patch)
treec3a4047e8737a54ffdb77ae1a5fca5444634a76a
parent4a7dc8178207b00ee43f7071fa43ff1581a6199d (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.c67
-rw-r--r--gst/camerabin2/gstwrappercamerabinsrc.h3
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
165gst_wrapper_camera_bin_reset_video_src_caps (GstWrapperCameraBinSrc * self, 165gst_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
327static gboolean
328gst_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