decklink: Validate video input format
authorEric Knapp <emkman99@gmail.com>
Wed, 17 Aug 2022 15:42:09 +0000 (11:42 -0400)
committerEric Knapp <emkman99@gmail.com>
Wed, 17 Aug 2022 17:29:55 +0000 (13:29 -0400)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2892>

subprojects/gst-plugins-bad/sys/decklink/gstdecklink.cpp
subprojects/gst-plugins-bad/sys/decklink/gstdecklink.h
subprojects/gst-plugins-bad/sys/decklink/gstdecklinkvideosrc.cpp

index b8e89ac..9c62239 100644 (file)
@@ -1090,20 +1090,35 @@ public:
       VideoInputFormatChanged (BMDVideoInputFormatChangedEvents,
       IDeckLinkDisplayMode * mode, BMDDetectedVideoInputFormatFlags formatFlags)
   {
-    /* use the user-set format, defaulting to 8BitYUV */
-    BMDPixelFormat pixelFormat = m_input->format;
+    BMDPixelFormat pixelFormat = bmdFormatUnspecified;
 
     GST_INFO ("Video input format changed");
 
-    if (m_input->format == bmdFormat8BitYUV) {
-      /* user-set format was auto or 8BitYUV */
-      if (formatFlags & bmdDetectedVideoInputRGB444) {
+    /* Detect input format */
+    if ((formatFlags & bmdDetectedVideoInputRGB444)
+        && (formatFlags & bmdDetectedVideoInput8BitDepth)) {
+      /* Cannot detect ARGB vs BGRA, so assume ARGB unless user sets BGRA */
+      if (m_input->format == bmdFormat8BitBGRA) {
+        pixelFormat = bmdFormat8BitBGRA;
+      } else {
         pixelFormat = bmdFormat8BitARGB;
-      } else if (formatFlags & bmdDetectedVideoInputYCbCr422) {
-        if (formatFlags & bmdDetectedVideoInput10BitDepth) {
-          pixelFormat = bmdFormat10BitYUV;
-        }
       }
+    } else if (formatFlags & bmdDetectedVideoInputYCbCr422) {
+      if (formatFlags & bmdDetectedVideoInput10BitDepth) {
+        pixelFormat = bmdFormat10BitYUV;
+      } else if (formatFlags & bmdDetectedVideoInput8BitDepth) {
+        pixelFormat = bmdFormat8BitYUV;
+      }
+    }
+
+    if (pixelFormat == bmdFormatUnspecified) {
+      GST_ERROR ("Video input format is not supported");
+      return E_FAIL;
+    }
+
+    if (!m_input->auto_format && (m_input->format != pixelFormat)) {
+      GST_ERROR ("Video input format does not match the user-set format");
+      return E_FAIL;
     }
 
     g_mutex_lock (&m_input->lock);
index 5d3ca79..5b28272 100644 (file)
@@ -440,6 +440,7 @@ struct _GstDecklinkInput {
   /* Configured mode or NULL */
   const GstDecklinkMode *mode;
   BMDPixelFormat format;
+  gboolean auto_format;
 
   /* Set by the audio source */
   void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, GstClockTime hardware_time, GstClockTime hardware_duration, gboolean no_signal);
index 2385a23..1bdff4e 100644 (file)
@@ -1537,6 +1537,7 @@ gst_decklink_video_src_open (GstDecklinkVideoSrc * self)
   g_mutex_lock (&self->input->lock);
   self->input->mode = mode;
   self->input->format = self->caps_format;
+  self->input->auto_format = self->video_format == GST_DECKLINK_VIDEO_FORMAT_AUTO;
   self->input->got_video_frame = gst_decklink_video_src_got_frame;
   self->input->start_streams = gst_decklink_video_src_start_streams;
   g_mutex_unlock (&self->input->lock);