opusdec: default to stereo 48000 Hz if possible when no headers seen
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Mon, 28 Nov 2011 19:47:34 +0000 (19:47 +0000)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Wed, 7 Dec 2011 13:57:38 +0000 (13:57 +0000)
https://bugzilla.gnome.org/show_bug.cgi?id=665078

ext/opus/gstopusdec.c

index 420caf1..af0f0f3 100644 (file)
@@ -213,12 +213,27 @@ gst_opus_dec_get_r128_volume (gint16 r128_gain)
   return DB_TO_LINEAR (gst_opus_dec_get_r128_gain (r128_gain));
 }
 
+static GstCaps *
+gst_opus_dec_negotiate (GstOpusDec * dec)
+{
+  GstCaps *caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dec));
+  GstStructure *s = gst_caps_get_structure (caps, 0);
+  gst_structure_fixate_field_nearest_int (s, "rate", 48000);
+  gst_structure_get_int (s, "rate", &dec->sample_rate);
+  gst_structure_fixate_field_nearest_int (s, "channels", dec->n_channels);
+  gst_structure_get_int (s, "channels", &dec->n_channels);
+
+  GST_INFO_OBJECT (dec, "Negotiated %d channels, %d Hz", dec->n_channels,
+      dec->sample_rate);
+
+  return caps;
+}
+
 static GstFlowReturn
 gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf)
 {
   const guint8 *data = GST_BUFFER_DATA (buf);
   GstCaps *caps;
-  GstStructure *s;
   const GstAudioChannelPosition *pos = NULL;
 
   g_return_val_if_fail (gst_opus_header_is_id_header (buf), GST_FLOW_ERROR);
@@ -280,16 +295,7 @@ gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf)
     }
   }
 
-  /* negotiate width with downstream */
-  caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dec));
-  s = gst_caps_get_structure (caps, 0);
-  gst_structure_fixate_field_nearest_int (s, "rate", 48000);
-  gst_structure_get_int (s, "rate", &dec->sample_rate);
-  gst_structure_fixate_field_nearest_int (s, "channels", dec->n_channels);
-  gst_structure_get_int (s, "channels", &dec->n_channels);
-
-  GST_INFO_OBJECT (dec, "Negotiated %d channels, %d Hz", dec->n_channels,
-      dec->sample_rate);
+  caps = gst_opus_dec_negotiate (dec);
 
   if (pos) {
     GST_DEBUG_OBJECT (dec, "Setting channel positions on caps");
@@ -307,7 +313,6 @@ gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf)
   return GST_FLOW_OK;
 }
 
-
 static GstFlowReturn
 gst_opus_dec_parse_comments (GstOpusDec * dec, GstBuffer * buf)
 {
@@ -328,6 +333,24 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer)
   GstBuffer *buf;
 
   if (dec->state == NULL) {
+    /* If we did not get any headers, default to 2 channels */
+    if (dec->n_channels == 0) {
+      GstCaps *caps;
+      GST_INFO_OBJECT (dec, "No header, assuming single stream");
+      dec->n_channels = 2;
+      dec->sample_rate = 48000;
+      caps = gst_opus_dec_negotiate (dec);
+      GST_INFO_OBJECT (dec, "Setting src caps to %" GST_PTR_FORMAT, caps);
+      gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), caps);
+      gst_caps_unref (caps);
+      /* default stereo mapping */
+      dec->channel_mapping_family = 0;
+      dec->channel_mapping[0] = 0;
+      dec->channel_mapping[1] = 1;
+      dec->n_streams = 1;
+      dec->n_stereo_streams = 1;
+    }
+
     GST_DEBUG_OBJECT (dec, "Creating decoder with %d channels, %d Hz",
         dec->n_channels, dec->sample_rate);
     dec->state = opus_multistream_decoder_create (dec->sample_rate,