summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2013-09-26 17:53:54 +0200
committerMichael Olbrich <m.olbrich@pengutronix.de>2013-09-26 17:55:01 +0200
commitd623fea9cbb230bb13748d4830a1f3e63d55fc8a (patch)
tree562abd84c377af1f8bfbb74d66f197311f4f6c5d
parenta82c8700f09080f261ab8ee1f89c541dad84b54b (diff)
downloadgst-plugins-good-d623fea9cbb230bb13748d4830a1f3e63d55fc8a.tar.gz
gst-plugins-good-d623fea9cbb230bb13748d4830a1f3e63d55fc8a.tar.xz
v4l2: filter: rework event queue handling
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
-rw-r--r--sys/v4l2/gstv4l2filter.c92
1 files changed, 43 insertions, 49 deletions
diff --git a/sys/v4l2/gstv4l2filter.c b/sys/v4l2/gstv4l2filter.c
index d63f88297..d58883957 100644
--- a/sys/v4l2/gstv4l2filter.c
+++ b/sys/v4l2/gstv4l2filter.c
@@ -564,6 +564,12 @@ gst_v4l2filter_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
GstV4l2Filter *v4l2filter = GST_V4L2FILTER (parent);
struct v4l2_decoder_cmd dcmd;
gboolean ret = TRUE;
+ gboolean force_queue = FALSE;
+ GstClockTime position;
+
+ GST_OBJECT_LOCK (v4l2filter);
+ position = v4l2filter->segment.position;
+ GST_OBJECT_UNLOCK (v4l2filter);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
@@ -573,61 +579,49 @@ gst_v4l2filter_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
gst_event_parse_caps (event, &caps);
ret = gst_v4l2filter_sink_setcaps (pad, caps);
gst_event_unref (event);
- break;
+ return ret;
}
case GST_EVENT_EOS:
+ GST_INFO_OBJECT (v4l2filter, "got EOS event, stopping decoder");
+ /*
+ * Send V4L2_DEC_CMD_STOP decoder command on the v4l2 output side and
+ * continue to dequeue remaining buffers at the v4l2 capture side.
+ */
+ memset (&dcmd, 0, sizeof (dcmd));
+ dcmd.cmd = V4L2_DEC_CMD_STOP;
+ dcmd.flags = 0;
+ dcmd.stop.pts = 0;
+ v4l2_ioctl (v4l2filter->sink_v4l2object->video_fd,
+ VIDIOC_DECODER_CMD, &dcmd);
+ break;
case GST_EVENT_SEGMENT:
- {
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- GST_ERROR_OBJECT (v4l2filter, "got EOS event, stopping decoder");
- /*
- * Send V4L2_DEC_CMD_STOP decoder command on the v4l2 output side and
- * continue to dequeue remaining buffers at the v4l2 capture side.
- */
- memset (&dcmd, 0, sizeof (dcmd));
- dcmd.cmd = V4L2_DEC_CMD_STOP;
- dcmd.flags = 0;
- dcmd.stop.pts = 0;
- v4l2_ioctl (v4l2filter->sink_v4l2object->video_fd,
- VIDIOC_DECODER_CMD, &dcmd);
- break;
- case GST_EVENT_SEGMENT:
- GST_OBJECT_LOCK (v4l2filter);
- v4l2filter->earliest_time = GST_CLOCK_TIME_NONE;
- GST_OBJECT_UNLOCK (v4l2filter);
- gst_event_copy_segment (event, &v4l2filter->segment);
- break;
- default:
- break;
- }
- /* fallthrough */
- }
+ GST_OBJECT_LOCK (v4l2filter);
+ v4l2filter->earliest_time = GST_CLOCK_TIME_NONE;
+ GST_OBJECT_UNLOCK (v4l2filter);
+ gst_event_copy_segment (event, &v4l2filter->segment);
+ force_queue = TRUE;
+ break;
+ case GST_EVENT_STREAM_START:
+ force_queue = TRUE;
+ break;
default:
- g_mutex_lock (&v4l2filter->queue_lock);
- if (GST_EVENT_IS_SERIALIZED (event)
- && g_sequence_get_length (v4l2filter->queue) > 0) {
- GstV4l2FilterTime *time;
- GST_LOG_OBJECT (v4l2filter, "queue %" GST_PTR_FORMAT, event);
- time = g_slice_new0 (GstV4l2FilterTime);
- time->pts = GST_EVENT_TIMESTAMP (event);
- time->event = event;
- if (GST_CLOCK_TIME_IS_VALID (time->pts)) {
- time->order = time->pts;
- } else {
- GST_OBJECT_LOCK (v4l2filter);
- time->order = v4l2filter->segment.position;
- GST_OBJECT_UNLOCK (v4l2filter);
- }
- g_sequence_insert_sorted (v4l2filter->queue, time,
- v4l2filter_time_sort, 0);
- g_mutex_unlock (&v4l2filter->queue_lock);
- } else {
- g_mutex_unlock (&v4l2filter->queue_lock);
- ret = gst_pad_event_default (pad, parent, event);
- }
break;
}
+ g_mutex_lock (&v4l2filter->queue_lock);
+ if (GST_EVENT_IS_SERIALIZED (event) &&
+ ((g_sequence_get_length (v4l2filter->queue) > 0) || force_queue)) {
+ GstV4l2FilterTime *time;
+ GST_LOG_OBJECT (v4l2filter, "queue %" GST_PTR_FORMAT, event);
+ time = g_slice_new0 (GstV4l2FilterTime);
+ time->pts = GST_EVENT_TIMESTAMP (event);
+ time->event = event;
+ time->order = GST_CLOCK_TIME_IS_VALID (time->pts) ? time->pts : position;
+ g_sequence_insert_sorted (v4l2filter->queue, time, v4l2filter_time_sort, 0);
+ g_mutex_unlock (&v4l2filter->queue_lock);
+ } else {
+ g_mutex_unlock (&v4l2filter->queue_lock);
+ ret = gst_pad_event_default (pad, parent, event);
+ }
return ret;
}