decklinkvideo/audiosrc: Add GstReferenceTimestampMeta with the stream time to each...
authorSebastian Dröge <sebastian@centricular.com>
Sat, 25 Feb 2017 10:37:46 +0000 (12:37 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 19 Apr 2017 18:06:37 +0000 (19:06 +0100)
This is basically a frame counter provided by the driver and it's
advancing at the speed of the HDMI/SDI input. Having this available on
each buffer allows to know what constant-framerate-based timestamp each
frame is corresponding to and can be used e.g. to write out files
accordingly without having the local pipeline clock timestamps used.

https://bugzilla.gnome.org/show_bug.cgi?id=779213

sys/decklink/gstdecklinkaudiosrc.cpp
sys/decklink/gstdecklinkvideosrc.cpp

index 43c2d42..f1dc2d6 100644 (file)
@@ -61,6 +61,7 @@ typedef struct
 {
   IDeckLinkAudioInputPacket *packet;
   GstClockTime timestamp;
+  GstClockTime stream_timestamp;
   gboolean no_signal;
 } CapturePacket;
 
@@ -531,6 +532,7 @@ gst_decklink_audio_src_got_packet (GstElement * element,
     memset (&p, 0, sizeof (p));
     p.packet = packet;
     p.timestamp = timestamp;
+    p.stream_timestamp = packet_time;
     p.no_signal = no_signal;
     packet->AddRef ();
     gst_queue_array_push_tail_struct (self->current_packets, &p);
@@ -553,6 +555,8 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
   GstClockTime start_time, end_time;
   guint64 start_offset, end_offset;
   gboolean discont = FALSE;
+  static GstStaticCaps stream_reference =
+      GST_STATIC_CAPS ("timestamp/x-stream");
 
 retry:
   g_mutex_lock (&self->lock);
@@ -667,6 +671,10 @@ retry:
   GST_BUFFER_TIMESTAMP (*buffer) = timestamp;
   GST_BUFFER_DURATION (*buffer) = duration;
 
+  gst_buffer_add_reference_timestamp_meta (*buffer,
+      gst_static_caps_get (&stream_reference), p->stream_timestamp,
+      end_time - start_time);
+
   GST_DEBUG_OBJECT (self,
       "Outputting buffer %p with timestamp %" GST_TIME_FORMAT " and duration %"
       GST_TIME_FORMAT, *buffer, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*buffer)),
index 5f3ff75..34c716f 100644 (file)
@@ -55,6 +55,8 @@ typedef struct
 {
   IDeckLinkVideoInputFrame *frame;
   GstClockTime timestamp, duration;
+  GstClockTime stream_timestamp;
+  GstClockTime stream_duration;
   GstDecklinkModeEnum mode;
   BMDPixelFormat format;
   GstVideoTimeCode *tc;
@@ -684,6 +686,8 @@ gst_decklink_video_src_got_frame (GstElement * element,
     f.frame = frame;
     f.timestamp = timestamp;
     f.duration = duration;
+    f.stream_timestamp = stream_time;
+    f.stream_duration = stream_duration;
     f.mode = mode;
     f.format = frame->GetPixelFormat ();
     f.no_signal = no_signal;
@@ -743,6 +747,8 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
   GstCaps *caps;
   gboolean caps_changed = FALSE;
   const GstDecklinkMode *mode;
+  static GstStaticCaps stream_reference =
+      GST_STATIC_CAPS ("timestamp/x-stream");
 
   g_mutex_lock (&self->lock);
   while (gst_queue_array_is_empty (self->current_frames) && !self->flushing) {
@@ -840,6 +846,9 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
   GST_BUFFER_DURATION (*buffer) = f.duration;
   if (f.tc != NULL)
     gst_buffer_add_video_time_code_meta (*buffer, f.tc);
+  gst_buffer_add_reference_timestamp_meta (*buffer,
+      gst_static_caps_get (&stream_reference), f.stream_timestamp,
+      f.stream_duration);
 
   mode = gst_decklink_get_mode (self->mode);
   if (mode->interlaced && mode->tff)