decklinksrc: Sample the pipeline clock for the timestamps instead of coming up with...
authorSebastian Dröge <sebastian@centricular.com>
Fri, 14 Nov 2014 09:38:33 +0000 (10:38 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 28 Nov 2014 13:56:19 +0000 (14:56 +0100)
If we just count the frames and calculate timestamps from that, all frames
will arrive late in the sink as we have a live source here. Instead take
the pipeline clock at capture time as reference.

sys/decklink/capture.cpp
sys/decklink/gstdecklinksrc.cpp
sys/decklink/gstdecklinksrc.h

index e9c981b..1795af2 100644 (file)
@@ -78,6 +78,8 @@ HRESULT
     videoFrame, IDeckLinkAudioInputPacket * audioFrame)
 {
   GstDecklinkSrc *decklinksrc;
+  GstClock *clock;
+  GstClockTime base_time, clock_time, capture_time;
   const char *timecodeString = NULL;
 
   g_return_val_if_fail (priv != NULL, S_OK);
@@ -109,9 +111,32 @@ HRESULT
     }
   }
 
-  GST_DEBUG_OBJECT (decklinksrc, "Frame received [%s] - %s - Size: %li bytes",
-      timecodeString != NULL ? timecodeString : "No timecode",
-      "Valid Frame", videoFrame->GetRowBytes () * videoFrame->GetHeight ());
+  GST_OBJECT_LOCK (decklinksrc);
+  if ((clock = GST_ELEMENT_CLOCK (decklinksrc))) {
+    base_time = GST_ELEMENT (decklinksrc)->base_time;
+    gst_object_ref (clock);
+  } else {
+    base_time = GST_CLOCK_TIME_NONE;
+  }
+  GST_OBJECT_UNLOCK (decklinksrc);
+  if (clock) {
+    clock_time = gst_clock_get_time (clock);
+    gst_object_unref (clock);
+  } else {
+    clock_time = GST_CLOCK_TIME_NONE;
+  }
+
+  if (base_time != GST_CLOCK_TIME_NONE) {
+    capture_time = clock_time - base_time;
+  } else {
+    capture_time = GST_CLOCK_TIME_NONE;
+  }
+
+  GST_DEBUG_OBJECT (decklinksrc,
+      "Frame received [%s] - %s - %" GST_TIME_FORMAT "Size: %li bytes",
+      timecodeString != NULL ? timecodeString : "No timecode", "Valid Frame",
+      GST_TIME_ARGS (capture_time),
+      videoFrame->GetRowBytes () * videoFrame->GetHeight ());
 
   if (timecodeString)
     FREE_COM_STRING (timecodeString);
@@ -130,6 +155,7 @@ HRESULT
     audioFrame->AddRef ();
     decklinksrc->audio_frame = audioFrame;
   }
+  decklinksrc->capture_time = capture_time;
 
   /* increment regardless whether frame was dropped or not */
   decklinksrc->frame_num++;
index 939fb8b..f796f6c 100644 (file)
@@ -756,6 +756,7 @@ gst_decklink_src_task (void *priv)
   GstFlowReturn video_flow, audio_flow, flow;
   const GstDecklinkMode *mode;
   gboolean discont = FALSE;
+  GstClockTime capture_time;
 
   GST_DEBUG_OBJECT (decklinksrc, "task");
 
@@ -766,6 +767,7 @@ gst_decklink_src_task (void *priv)
   }
   video_frame = decklinksrc->video_frame;
   audio_frame = decklinksrc->audio_frame;
+  capture_time = decklinksrc->capture_time;
   decklinksrc->video_frame = NULL;
   decklinksrc->audio_frame = NULL;
   g_mutex_unlock (&decklinksrc->mutex);
@@ -846,12 +848,9 @@ gst_decklink_src_task (void *priv)
     vf->input->AddRef ();
   }
 
-  GST_BUFFER_TIMESTAMP (buffer) =
-      gst_util_uint64_scale_int (decklinksrc->frame_num * GST_SECOND,
+  GST_BUFFER_TIMESTAMP (buffer) = capture_time;
+  GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (GST_SECOND,
       mode->fps_d, mode->fps_n);
-  GST_BUFFER_DURATION (buffer) =
-      gst_util_uint64_scale_int ((decklinksrc->frame_num + 1) * GST_SECOND,
-      mode->fps_d, mode->fps_n) - GST_BUFFER_TIMESTAMP (buffer);
   GST_BUFFER_OFFSET (buffer) = decklinksrc->frame_num;
   GST_BUFFER_OFFSET_END (buffer) = decklinksrc->frame_num;      /* FIXME: +1? */
 
@@ -873,9 +872,7 @@ gst_decklink_src_task (void *priv)
     audio_buffer = gst_buffer_new_and_alloc (n_samples * 2 * 2);
     gst_buffer_fill (audio_buffer, 0, data, n_samples * 2 * 2);
 
-    GST_BUFFER_TIMESTAMP (audio_buffer) =
-        gst_util_uint64_scale_int (decklinksrc->num_audio_samples * GST_SECOND,
-        1, 48000);
+    GST_BUFFER_TIMESTAMP (audio_buffer) = capture_time;
     /* FIXME: should be next_timestamp - timestamp for perfect stream */
     GST_BUFFER_DURATION (audio_buffer) =
         gst_util_uint64_scale_int (n_samples * GST_SECOND, 1, 48000);
index eb7a252..5d8ae90 100644 (file)
@@ -60,6 +60,7 @@ struct _GstDecklinkSrc
   int dropped_frames;
   int dropped_frames_old;
   gboolean stop;
+  GstClockTime capture_time;
   IDeckLinkVideoInputFrame *video_frame;
   IDeckLinkAudioInputPacket * audio_frame;