diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-09-26 17:53:54 +0200 |
---|---|---|
committer | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-09-26 17:55:01 +0200 |
commit | d623fea9cbb230bb13748d4830a1f3e63d55fc8a (patch) | |
tree | 562abd84c377af1f8bfbb74d66f197311f4f6c5d | |
parent | a82c8700f09080f261ab8ee1f89c541dad84b54b (diff) | |
download | gst-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.c | 92 |
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; } |