decklinksrc: Set GAP flag on buffers that are captured without signal
authorSebastian Dröge <sebastian@centricular.com>
Fri, 25 Nov 2016 12:36:37 +0000 (14:36 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 28 Nov 2016 12:27:51 +0000 (14:27 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=774850

sys/decklink/gstdecklink.cpp
sys/decklink/gstdecklink.h
sys/decklink/gstdecklinkaudiosrc.cpp
sys/decklink/gstdecklinkvideosrc.cpp

index 2a79741..a744700 100644 (file)
@@ -723,13 +723,14 @@ public:
         IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode,
         GstClockTime capture_time, GstClockTime stream_time,
         GstClockTime stream_duration, guint hours, guint minutes, guint seconds,
-        guint frames, BMDTimecodeFlags bflags) = NULL;
+        guint frames, BMDTimecodeFlags bflags, gboolean no_signal) = NULL;
     void (*got_audio_packet) (GstElement * videosrc,
         IDeckLinkAudioInputPacket * packet, GstClockTime capture_time,
-        GstClockTime packet_time) = NULL;
+        GstClockTime packet_time, gboolean no_signal) = NULL;
     GstDecklinkModeEnum mode;
     GstClockTime capture_time = GST_CLOCK_TIME_NONE;
     GstClockTime base_time;
+    gboolean no_signal = FALSE;
     GstClock *clock = NULL;
     HRESULT res;
 
@@ -760,6 +761,15 @@ public:
         capture_time = 0;
     }
 
+    if (video_frame) {
+      BMDFrameFlags flags;
+
+      flags = video_frame->GetFlags ();
+      if (flags & bmdFrameHasNoInputSource) {
+        no_signal = TRUE;
+      }
+    }
+
     if (got_video_frame && videosrc && video_frame) {
       BMDTimeValue stream_time = GST_CLOCK_TIME_NONE;
       BMDTimeValue stream_duration = GST_CLOCK_TIME_NONE;
@@ -809,7 +819,7 @@ public:
 
       got_video_frame (videosrc, video_frame, mode, capture_time,
           stream_time, stream_duration, (guint8) hours, (guint8) minutes,
-          (guint8) seconds, (guint8) frames, bflags);
+          (guint8) seconds, (guint8) frames, bflags, no_signal);
     }
 
     if (got_audio_packet && audiosrc && audio_packet) {
@@ -821,7 +831,7 @@ public:
         packet_time = GST_CLOCK_TIME_NONE;
       }
       m_input->got_audio_packet (audiosrc, audio_packet, capture_time,
-          packet_time);
+          packet_time, no_signal);
     } else {
       if (!audio_packet)
         GST_DEBUG ("Received no audio packet at %" GST_TIME_FORMAT,
index 40cc917..3391650 100644 (file)
@@ -201,13 +201,13 @@ struct _GstDecklinkInput {
   GMutex lock;
 
   /* Set by the video source */
-  void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, guint hours, guint minutes, guint seconds, guint frames, BMDTimecodeFlags bflags);
+  void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, guint hours, guint minutes, guint seconds, guint frames, BMDTimecodeFlags bflags, gboolean no_signal);
   /* Configured mode or NULL */
   const GstDecklinkMode *mode;
   BMDPixelFormat format;
 
   /* Set by the audio source */
-  void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime packet_time);
+  void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime packet_time, gboolean no_signal);
 
   GstElement *audiosrc;
   gboolean audio_enabled;
index 634cead..09c2a8d 100644 (file)
@@ -57,6 +57,7 @@ typedef struct
 {
   IDeckLinkAudioInputPacket *packet;
   GstClockTime timestamp;
+  gboolean no_signal;
 } CapturePacket;
 
 static void
@@ -421,7 +422,7 @@ gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
 static void
 gst_decklink_audio_src_got_packet (GstElement * element,
     IDeckLinkAudioInputPacket * packet, GstClockTime capture_time,
-    GstClockTime packet_time)
+    GstClockTime packet_time, gboolean no_signal)
 {
   GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element);
   GstClockTime timestamp;
@@ -464,6 +465,7 @@ gst_decklink_audio_src_got_packet (GstElement * element,
     p = (CapturePacket *) g_malloc0 (sizeof (CapturePacket));
     p->packet = packet;
     p->timestamp = timestamp;
+    p->no_signal = no_signal;
     packet->AddRef ();
     g_queue_push_tail (&self->current_packets, p);
     g_cond_signal (&self->cond);
@@ -594,6 +596,8 @@ retry:
         self->info.rate) - timestamp;
   }
 
+  if (p->no_signal)
+    GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
   GST_BUFFER_TIMESTAMP (*buffer) = timestamp;
   GST_BUFFER_DURATION (*buffer) = duration;
 
index 6d8eddb..d7f131b 100644 (file)
@@ -53,6 +53,7 @@ typedef struct
   GstDecklinkModeEnum mode;
   BMDPixelFormat format;
   GstVideoTimeCode *tc;
+  gboolean no_signal;
 } CaptureFrame;
 
 static void
@@ -571,7 +572,7 @@ gst_decklink_video_src_got_frame (GstElement * element,
     IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode,
     GstClockTime capture_time, GstClockTime stream_time,
     GstClockTime stream_duration, guint hours, guint minutes, guint seconds,
-    guint frames, BMDTimecodeFlags bflags)
+    guint frames, BMDTimecodeFlags bflags, gboolean no_signal)
 {
   GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (element);
   GstClockTime timestamp, duration;
@@ -620,6 +621,7 @@ gst_decklink_video_src_got_frame (GstElement * element,
     f->duration = duration;
     f->mode = mode;
     f->format = frame->GetPixelFormat ();
+    f->no_signal = no_signal;
     bmode = gst_decklink_get_mode (mode);
     if (bmode->interlaced) {
       flags =
@@ -656,7 +658,6 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
   CaptureFrame *f;
   GstCaps *caps;
   gboolean caps_changed = FALSE;
-  BMDFrameFlags flags;
 
   g_mutex_lock (&self->lock);
   while (g_queue_is_empty (&self->current_frames) && !self->flushing) {
@@ -733,8 +734,7 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
   vf->input = self->input->input;
   vf->input->AddRef ();
 
-  flags = f->frame->GetFlags ();
-  if (flags & bmdFrameHasNoInputSource) {
+  if (f->no_signal) {
     if (!self->no_signal) {
       self->no_signal = TRUE;
       GST_ELEMENT_WARNING (GST_ELEMENT (self), RESOURCE, READ, ("No signal"),
@@ -748,6 +748,8 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
     }
   }
 
+  if (f->no_signal)
+    GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
   GST_BUFFER_TIMESTAMP (*buffer) = f->timestamp;
   GST_BUFFER_DURATION (*buffer) = f->duration;
   gst_buffer_add_video_time_code_meta (*buffer, f->tc);