? ext/a52dec/libgsta52dec_la-gsta52dec.loT
Index: ext/a52dec/gsta52dec.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-ugly/ext/a52dec/gsta52dec.c,v
retrieving revision 1.65
diff -a -u -r1.65 gsta52dec.c
--- ext/a52dec/gsta52dec.c	14 Aug 2006 10:19:41 -0000	1.65
+++ ext/a52dec/gsta52dec.c	17 Aug 2006 14:30:32 -0000
@@ -58,7 +58,9 @@
 enum
 {
   ARG_0,
-  ARG_DRC
+  ARG_DRC,
+  ARG_MODE,
+  ARG_LFE,
 };
 
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -94,6 +96,30 @@
 
 static GstElementClass *parent_class = NULL;
 
+#define GST_TYPE_A52DEC_MODE (gst_a52dec_mode_get_type())
+static GType
+gst_a52dec_mode_get_type (void)
+{
+  static GType a52dec_mode_type = 0;
+  static const GEnumValue a52dec_modes[] = {
+    {A52_MONO, "Mono", "mono"},
+    {A52_STEREO, "Stereo", "stereo"},
+    {A52_3F, "3 Front", "3f"},
+    {A52_2F1R, "2 Front, 1 Rear", "2f1r"},
+    {A52_3F1R, "3 Front, 1 Rear", "3f1r"},
+    {A52_2F2R, "2 Front, 2 Rear", "2f2r"},
+    {A52_3F2R, "3 Front, 2 Rear", "3f2r"},
+    {A52_DOLBY, "Dolby", "dolby"},
+    {0, NULL, NULL},
+  };
+
+  if (!a52dec_mode_type) {
+    a52dec_mode_type = g_enum_register_static ("GstA52DecMode", a52dec_modes);
+  }
+  return a52dec_mode_type;
+}
+
+
 GType
 gst_a52dec_get_type (void)
 {
@@ -153,6 +179,11 @@
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DRC,
       g_param_spec_boolean ("drc", "Dynamic Range Compression",
           "Use Dynamic Range Compression", FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
+      g_param_spec_enum ("mode", "Decoder Mode", "Decoding Mode (default 3f2r)",
+          GST_TYPE_A52DEC_MODE, A52_3F2R, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LFE,
+      g_param_spec_boolean ("lfe", "LFE", "LFE", TRUE, G_PARAM_READWRITE));
 
   oil_init ();
 
@@ -191,6 +222,7 @@
   gst_pad_use_fixed_caps (a52dec->srcpad);
   gst_element_add_pad (GST_ELEMENT (a52dec), a52dec->srcpad);
 
+  a52dec->request_channels = A52_CHANNEL;
   a52dec->dynamic_range_compression = FALSE;
   a52dec->cache = NULL;
 }
@@ -268,6 +300,12 @@
       }
       chans += 2;
       break;
+    case A52_MONO:
+      if (pos) {
+        pos[0 + chans] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
+      }
+      chans += 1;
+      break;
     default:
       /* error, caller should post error message */
       g_free (pos);
@@ -441,6 +479,40 @@
     gst_a52dec_update_streaminfo (a52dec);
   }
 
+  /* get number of channels from source peer pad if request_channels not specified */
+  if (a52dec->request_channels == A52_CHANNEL) {
+    GstCaps *caps;
+
+    caps = gst_pad_get_allowed_caps (a52dec->srcpad);
+    if (caps && !gst_caps_is_empty (caps)
+        && !gst_caps_is_any (caps)) {
+      GstCaps *copy = gst_caps_copy_nth (caps, 0);
+      GstStructure *structure = gst_caps_get_structure (copy, 0);
+      gint channels;
+      const int a52_channels[6] = {
+        A52_MONO,
+        A52_STEREO,
+        A52_STEREO | A52_LFE,
+        A52_2F2R,
+        A52_2F2R | A52_LFE,
+        A52_3F2R | A52_LFE,
+      };
+
+      gst_structure_fixate_field_nearest_int (structure, "channels",
+          flags ? gst_a52dec_channels (flags, NULL) : 6);
+      gst_structure_get_int (structure, "channels", &channels);
+      a52dec->request_channels = a52_channels[channels - 1];
+
+      gst_caps_unref (copy);
+    } else if (flags)
+      a52dec->request_channels = a52dec->stream_channels;
+    else
+      a52dec->request_channels = A52_3F2R | A52_LFE;
+
+    if (caps)
+      gst_caps_unref (caps);
+  }
+
   /* process */
   flags = a52dec->request_channels;     /* | A52_ADJUST_LEVEL; */
   a52dec->level = 1;
@@ -681,7 +753,6 @@
       a52dec->bit_rate = -1;
       a52dec->sample_rate = -1;
       a52dec->stream_channels = A52_CHANNEL;
-      a52dec->request_channels = A52_3F2R | A52_LFE;
       a52dec->using_channels = A52_CHANNEL;
       a52dec->level = 1;
       a52dec->bias = 0;
@@ -729,6 +800,18 @@
       src->dynamic_range_compression = g_value_get_boolean (value);
       GST_OBJECT_UNLOCK (src);
       break;
+    case ARG_MODE:
+      GST_OBJECT_LOCK (src);
+      src->request_channels &= ~A52_CHANNEL_MASK;
+      src->request_channels |= g_value_get_enum (value);
+      GST_OBJECT_UNLOCK (src);
+      break;
+    case ARG_LFE:
+      GST_OBJECT_LOCK (src);
+      src->request_channels &= ~A52_LFE;
+      src->request_channels |= g_value_get_boolean (value) ? A52_LFE : 0;
+      GST_OBJECT_UNLOCK (src);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -747,6 +830,16 @@
       g_value_set_boolean (value, src->dynamic_range_compression);
       GST_OBJECT_UNLOCK (src);
       break;
+    case ARG_MODE:
+      GST_OBJECT_LOCK (src);
+      g_value_set_enum (value, src->request_channels & A52_CHANNEL_MASK);
+      GST_OBJECT_UNLOCK (src);
+      break;
+    case ARG_LFE:
+      GST_OBJECT_LOCK (src);
+      g_value_set_boolean (value, src->request_channels & A52_LFE);
+      GST_OBJECT_UNLOCK (src);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
Index: ext/a52dec/gsta52dec.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-ugly/ext/a52dec/gsta52dec.h,v
retrieving revision 1.19
diff -a -u -r1.19 gsta52dec.h
--- ext/a52dec/gsta52dec.h	1 Jun 2006 21:11:40 -0000	1.19
+++ ext/a52dec/gsta52dec.h	17 Aug 2006 14:30:32 -0000
@@ -73,6 +73,31 @@
 
 GType gst_a52dec_get_type (void);
 
+#ifndef A52_MONO
+#define A52_MONO 1
+#endif
+#ifndef A52_STEREO
+#define A52_STEREO 2
+#endif
+#ifndef A52_3F
+#define A52_3F 3
+#endif
+#ifndef A52_2F1R
+#define A52_2F1R 4
+#endif
+#ifndef A52_3F1R
+#define A52_3F1R 5
+#endif
+#ifndef A52_2F2R
+#define A52_2F2R 6
+#endif
+#ifndef A52_3F2R
+#define A52_3F2R 7
+#endif
+#ifndef A52_DOLBY
+#define A52_DOLBY 10
+#endif
+
 G_END_DECLS
 
 #endif /* __GST_A52DEC_H__ */
