summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJan Schmidt <jan@centricular.com>2017-05-18 15:57:22 +0200
committerJan Schmidt <jan@centricular.com>2017-05-18 17:49:46 +0200
commit47abc9a09c15f38cff9112f1952b5146631f792e (patch)
treebee748369e2270296f3a1298fd819710ca9705fd /sys
parent67980f27ced7e3260ee5ace81b2c6e13bcb8b4e5 (diff)
uvch264src: Apply timestamps to outgoing aux buffers
When extracting an aux buffer from an MJPG carrier, at *least* put the original timestamp on it, even if we fail to apply any other timestamp (which we always do at the moment, because the timestamp calculating code was never finished). Apply a DTS using the camera supplied delay value as well, assuming that there's no re-ordering going on (there isn't in the C920, which is really the only extant camera doing this stuff) and a warning if that turns out not to be true.
Diffstat (limited to 'sys')
-rw-r--r--sys/uvch264/gstuvch264_mjpgdemux.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/sys/uvch264/gstuvch264_mjpgdemux.c b/sys/uvch264/gstuvch264_mjpgdemux.c
index e90ac6fbe..0f8369889 100644
--- a/sys/uvch264/gstuvch264_mjpgdemux.c
+++ b/sys/uvch264/gstuvch264_mjpgdemux.c
@@ -148,6 +148,8 @@ struct _GstUvcH264MjpgDemuxPrivate
/* input segment */
GstSegment segment;
+ GstClockTime last_pts;
+ gboolean pts_reordered_warning;
};
typedef struct
@@ -231,6 +233,8 @@ gst_uvc_h264_mjpg_demux_init (GstUvcH264MjpgDemux * self)
GstUvcH264MjpgDemuxPrivate);
+ self->priv->last_pts = GST_CLOCK_TIME_NONE;
+ self->priv->pts_reordered_warning = FALSE;
self->priv->device_fd = -1;
/* create the sink and src pads */
@@ -369,6 +373,7 @@ gst_uvc_h264_mjpg_demux_sink_event (GstPad * pad, GstObject * parent,
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
gst_event_copy_segment (event, &self->priv->segment);
+ self->priv->last_pts = GST_CLOCK_TIME_NONE;
res = gst_pad_push_event (self->priv->jpeg_pad, event);
break;
case GST_EVENT_CAPS:
@@ -654,6 +659,32 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad,
/* Push completed aux data */
if (aux_size == 0) {
+ /* Last attempt to apply timestamp. FIXME: This
+ * is broken for H.264 with B-frames */
+ if (GST_BUFFER_PTS (aux_buf) == GST_CLOCK_TIME_NONE) {
+ if (!self->priv->pts_reordered_warning &&
+ self->priv->last_pts != GST_CLOCK_TIME_NONE &&
+ self->priv->last_pts > GST_BUFFER_PTS (buf)) {
+ GST_WARNING_OBJECT (self, "PTS went backward, timestamping "
+ "might be broken");
+ self->priv->pts_reordered_warning = TRUE;
+ }
+ self->priv->last_pts = GST_BUFFER_PTS (buf);
+
+ GST_BUFFER_PTS (aux_buf) = GST_BUFFER_PTS (buf);
+ }
+ if (GST_BUFFER_DTS (aux_buf) == GST_CLOCK_TIME_NONE) {
+ GstClockTime dts = GST_BUFFER_PTS (aux_buf);
+ GstClockTime delay = aux_header.delay * GST_MSECOND;
+ if (dts > delay)
+ dts -= delay;
+ else
+ dts = 0;
+ GST_BUFFER_DTS (aux_buf) = dts;
+ GST_LOG_OBJECT (self, "Applied DTS %" GST_TIME_FORMAT
+ " to aux_buf", GST_TIME_ARGS (dts));
+ }
+
GST_DEBUG_OBJECT (self, "Pushing %" GST_FOURCC_FORMAT
" auxiliary buffer %" GST_PTR_FORMAT,
GST_FOURCC_ARGS (aux_header.type), *aux_caps);