decklink: do not repeat first video format in caps template
[platform/upstream/gstreamer.git] / sys / decklink / gstdecklink.cpp
index a06b812..a5ccc22 100644 (file)
@@ -157,9 +157,9 @@ static const GstDecklinkMode modes[] = {
   {bmdModeHD1080p2997, 1920, 1080, 30000, 1001, false, HD},
   {bmdModeHD1080p30, 1920, 1080, 30, 1, false, HD},
 
-  {bmdModeHD1080i50, 1920, 1080, 50, 1, true, HD},
-  {bmdModeHD1080i5994, 1920, 1080, 60000, 1001, true, HD},
-  {bmdModeHD1080i6000, 1920, 1080, 60, 1, true, HD},
+  {bmdModeHD1080i50, 1920, 1080, 25, 1, true, HD},
+  {bmdModeHD1080i5994, 1920, 1080, 30000, 1001, true, HD},
+  {bmdModeHD1080i6000, 1920, 1080, 30, 1, true, HD},
 
   {bmdModeHD1080p50, 1920, 1080, 50, 1, false, HD},
   {bmdModeHD1080p5994, 1920, 1080, 60000, 1001, false, HD},
@@ -350,7 +350,7 @@ gst_decklink_mode_get_template_caps (void)
   GstStructure *s;
 
   caps = gst_caps_new_empty ();
-  for (i = 0; i < (int) G_N_ELEMENTS (modes); i++) {
+  for (i = 1; i < (int) G_N_ELEMENTS (modes); i++) {
     s = gst_decklink_mode_get_structure ((GstDecklinkModeEnum) i);
     gst_caps_append_structure (caps, s);
   }
@@ -474,24 +474,61 @@ public:
       VideoInputFrameArrived (IDeckLinkVideoInputFrame * video_frame,
       IDeckLinkAudioInputPacket * audio_packet)
   {
-    GstClockTime clock_time = gst_clock_get_time (m_input->clock);
+    GstElement *videosrc = NULL, *audiosrc = NULL;
+    void (*got_video_frame) (GstElement * videosrc,
+        IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode,
+        GstClockTime capture_time, GstClockTime capture_duration) = NULL;
+    void (*got_audio_packet) (GstElement * videosrc,
+        IDeckLinkAudioInputPacket * packet, GstClockTime capture_time) = NULL;
+    GstDecklinkModeEnum mode;
+    BMDTimeValue capture_time, capture_duration;
+    HRESULT res;
+
+    res =
+        video_frame->GetHardwareReferenceTimestamp (GST_SECOND, &capture_time,
+        &capture_duration);
+    if (res != S_OK) {
+      GST_ERROR ("Failed to get capture time: 0x%08x", res);
+      capture_time = GST_CLOCK_TIME_NONE;
+      capture_duration = GST_CLOCK_TIME_NONE;
+    }
 
     g_mutex_lock (&m_input->lock);
-    if (m_input->got_video_frame) {
-      GstClockTime capture_time = clock_time -
-          gst_element_get_base_time (m_input->videosrc);
-      m_input->got_video_frame (m_input->videosrc, video_frame,
-          gst_decklink_get_mode_enum_from_bmd (m_input->mode->mode),
-          capture_time);
-    }
 
-    if (m_input->got_audio_packet) {
-      GstClockTime capture_time = clock_time -
-          gst_element_get_base_time (m_input->audiosrc);
-      m_input->got_audio_packet (m_input->audiosrc, audio_packet, capture_time);
+    if (capture_time > (BMDTimeValue) m_input->clock_start_time)
+      capture_time -= m_input->clock_start_time;
+    else
+      capture_time = 0;
+
+    if (capture_time > (BMDTimeValue) m_input->clock_offset)
+      capture_time -= m_input->clock_offset;
+    else
+      capture_time = 0;
+
+    if (m_input->videosrc) {
+      videosrc = GST_ELEMENT_CAST (gst_object_ref (m_input->videosrc));
+      got_video_frame = m_input->got_video_frame;
     }
+    mode = gst_decklink_get_mode_enum_from_bmd (m_input->mode->mode);
 
+    if (m_input->audiosrc) {
+      audiosrc = GST_ELEMENT_CAST (gst_object_ref (m_input->audiosrc));
+      got_audio_packet = m_input->got_audio_packet;
+    }
     g_mutex_unlock (&m_input->lock);
+
+    if (got_video_frame && videosrc) {
+      got_video_frame (videosrc, video_frame, mode, capture_time,
+          capture_duration);
+    }
+
+    if (got_audio_packet && audiosrc) {
+      m_input->got_audio_packet (audiosrc, audio_packet, capture_time);
+    }
+
+    gst_object_replace ((GstObject **) & videosrc, NULL);
+    gst_object_replace ((GstObject **) & audiosrc, NULL);
+
     return S_OK;
   }
 };