decklinkaudiosrc: Add support for 8/16 channels via property
authorSebastian Dröge <sebastian@centricular.com>
Tue, 3 Jan 2017 15:30:07 +0000 (17:30 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 3 Jan 2017 15:30:07 +0000 (17:30 +0200)
These are unpositioned channel layouts.

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

index 1fe9005..a795567 100644 (file)
@@ -192,6 +192,26 @@ gst_decklink_audio_connection_get_type (void)
   return (GType) id;
 }
 
+GType
+gst_decklink_audio_channels_get_type (void)
+{
+  static gsize id = 0;
+  static const GEnumValue connections[] = {
+    {GST_DECKLINK_AUDIO_CHANNELS_2, "2 Channels", "2"},
+    {GST_DECKLINK_AUDIO_CHANNELS_8, "8 Channels", "8"},
+    {GST_DECKLINK_AUDIO_CHANNELS_16, "16 Channels", "16"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp =
+        g_enum_register_static ("GstDecklinkAudioChannels", connections);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
 #define NTSC 10, 11, false, "bt601"
 #define PAL 12, 11, true, "bt601"
 #define HD 1, 1, true, "bt709"
index 5ae38b2..5b94033 100644 (file)
@@ -111,6 +111,14 @@ typedef enum {
 GType gst_decklink_audio_connection_get_type (void);
 
 typedef enum {
+  GST_DECKLINK_AUDIO_CHANNELS_2 = 2,
+  GST_DECKLINK_AUDIO_CHANNELS_8 = 8,
+  GST_DECKLINK_AUDIO_CHANNELS_16 = 16
+} GstDecklinkAudioChannelsEnum;
+#define GST_TYPE_DECKLINK_AUDIO_CHANNELS (gst_decklink_audio_channels_get_type ())
+GType gst_decklink_audio_channels_get_type (void);
+
+typedef enum {
   GST_DECKLINK_VIDEO_FORMAT_AUTO,
   GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV, /* bmdFormat8BitYUV */
   GST_DECKLINK_VIDEO_FORMAT_10BIT_YUV, /* bmdFormat10BitYUV */
index 04dc2f7..4b9a353 100644 (file)
@@ -34,6 +34,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_decklink_audio_src_debug);
 
 #define DEFAULT_ALIGNMENT_THRESHOLD   (40 * GST_MSECOND)
 #define DEFAULT_DISCONT_WAIT          (1 * GST_SECOND)
+#define DEFAULT_CHANNELS              (GST_DECKLINK_AUDIO_CHANNELS_2)
 
 enum
 {
@@ -42,7 +43,8 @@ enum
   PROP_DEVICE_NUMBER,
   PROP_ALIGNMENT_THRESHOLD,
   PROP_DISCONT_WAIT,
-  PROP_BUFFER_SIZE
+  PROP_BUFFER_SIZE,
+  PROP_CHANNELS,
 };
 
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -50,6 +52,8 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS
     ("audio/x-raw, format={S16LE,S32LE}, channels=2, rate=48000, "
+        "layout=interleaved;"
+        "audio/x-raw, format={S16LE,S32LE}, channels={8,16}, channel-mask=(bitmask)0, rate=48000, "
         "layout=interleaved")
     );
 
@@ -171,6 +175,13 @@ gst_decklink_audio_src_class_init (GstDecklinkAudioSrcClass * klass)
           G_MAXINT, DEFAULT_BUFFER_SIZE,
           (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
 
+  g_object_class_install_property (gobject_class, PROP_CHANNELS,
+      g_param_spec_enum ("channels", "Channels",
+          "Audio channels",
+          GST_TYPE_DECKLINK_AUDIO_CHANNELS, DEFAULT_CHANNELS,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+              G_PARAM_CONSTRUCT)));
+
   gst_element_class_add_static_pad_template (element_class, &sink_template);
 
   gst_element_class_set_static_metadata (element_class, "Decklink Audio Source",
@@ -188,6 +199,7 @@ gst_decklink_audio_src_init (GstDecklinkAudioSrc * self)
   self->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
   self->discont_wait = DEFAULT_DISCONT_WAIT;
   self->buffer_size = DEFAULT_BUFFER_SIZE;
+  self->channels = DEFAULT_CHANNELS;
 
   gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
   gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
@@ -221,6 +233,9 @@ gst_decklink_audio_src_set_property (GObject * object, guint property_id,
     case PROP_BUFFER_SIZE:
       self->buffer_size = g_value_get_uint (value);
       break;
+    case PROP_CHANNELS:
+      self->channels = (GstDecklinkAudioChannelsEnum) g_value_get_enum (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -249,6 +264,9 @@ gst_decklink_audio_src_get_property (GObject * object, guint property_id,
     case PROP_BUFFER_SIZE:
       g_value_set_uint (value, self->buffer_size);
       break;
+    case PROP_CHANNELS:
+      g_value_set_enum (value, self->channels);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -383,7 +401,7 @@ gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
   }
 
   ret = self->input->input->EnableAudioInput (bmdAudioSampleRate48kHz,
-      sample_depth, 2);
+      sample_depth, self->info.channels);
   if (ret != S_OK) {
     GST_WARNING_OBJECT (self, "Failed to enable audio input: 0x%08x", ret);
     return FALSE;
@@ -401,13 +419,22 @@ gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
 static GstCaps *
 gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
 {
+  GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
   GstCaps *caps;
 
   // We don't support renegotiation
   caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (bsrc));
 
-  if (!caps)
-    caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc));
+  if (!caps) {
+    GstCaps *channel_filter, *templ;
+    templ = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc));
+    channel_filter =
+        gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT,
+        self->channels, NULL);
+    caps = gst_caps_intersect (channel_filter, templ);
+    gst_caps_unref (channel_filter);
+    gst_caps_unref (templ);
+  }
 
   if (filter) {
     GstCaps *tmp =
index 9d0af77..d6e2e07 100644 (file)
@@ -52,6 +52,7 @@ struct _GstDecklinkAudioSrc
   GstDecklinkModeEnum mode;
   GstDecklinkAudioConnectionEnum connection;
   gint device_number;
+  GstDecklinkAudioChannelsEnum channels;
 
   GstAudioInfo info;