gst_plugins_good/gst/wavenc/gstwavenc.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
--- a/gst_plugins_good/gst/wavenc/gstwavenc.c	Tue Aug 31 15:30:33 2010 +0300
+++ b/gst_plugins_good/gst/wavenc/gstwavenc.c	Wed Sep 01 12:16:41 2010 +0100
@@ -24,17 +24,24 @@
 #include "config.h"
 #endif
 
+
+
 #include <string.h>
 #include "gstwavenc.h"
-#include "riff.h"
+//#include "riff.h" rj
 
+#include "gst/riff/riff-ids.h"
+#include "gst/riff/riff-media.h"
+#include <gst/gst-i18n-plugin.h>
 
 #ifdef __SYMBIAN32__
 #include<gst/gstinfo.h>
 #endif
 
 GST_DEBUG_CATEGORY_STATIC (wavenc_debug);
-#define GST_CAT_DEFAULT wavenc_debug
+#define GST_CAT_DEFAULT (wavenc_debug) //rj
+
+#define WAVE_FORMAT_PCM 0x0001
 
 struct riff_struct
 {
@@ -81,22 +88,6 @@
     "rate = (int) [ 1, MAX ], "          \
     "channels = (int) [ 1, 2 ], "        \
     "endianness = (int) LITTLE_ENDIAN, " \
-    "width = (int) 32, "                 \
-    "depth = (int) 32, "                 \
-    "signed = (boolean) true"            \
-    "; "                                 \
-    "audio/x-raw-int, "                  \
-    "rate = (int) [ 1, MAX ], "          \
-    "channels = (int) [ 1, 2 ], "        \
-    "endianness = (int) LITTLE_ENDIAN, " \
-    "width = (int) 24, "                 \
-    "depth = (int) 24, "                 \
-    "signed = (boolean) true"            \
-    "; "                                 \
-    "audio/x-raw-int, "                  \
-    "rate = (int) [ 1, MAX ], "          \
-    "channels = (int) [ 1, 2 ], "        \
-    "endianness = (int) LITTLE_ENDIAN, " \
     "width = (int) 16, "                 \
     "depth = (int) 16, "                 \
     "signed = (boolean) true"            \
@@ -105,25 +96,6 @@
     "rate = (int) [ 1, MAX ], "          \
     "channels = (int) [ 1, 2 ], "        \
     "width = (int) 8, "                  \
-    "depth = (int) 8, "                  \
-    "signed = (boolean) false"           \
-    "; "                                 \
-    "audio/x-raw-float, "                \
-    "rate = (int) [ 1, MAX ], "          \
-    "channels = (int) [ 1, 2 ], "        \
-    "endianness = (int) LITTLE_ENDIAN, " \
-    "width = (int) { 32, 64 }; "         \
-    "audio/x-alaw, "                     \
-    "rate = (int) [ 8000, 192000 ], "    \
-    "channels = (int) [ 1, 2 ], "        \
-    "width = (int) 8, "                  \
-    "depth = (int) 8, "                  \
-    "signed = (boolean) false; "         \
-    "audio/x-mulaw, "                    \
-    "rate = (int) [ 8000, 192000 ], "    \
-    "channels = (int) [ 1, 2 ], "        \
-    "width = (int) 8, "                  \
-    "depth = (int) 8, "                  \
     "signed = (boolean) false"
 
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -138,7 +110,16 @@
     GST_STATIC_CAPS ("audio/x-wav")
     );
 
+#ifndef __SYMBIAN32__  //rj
 GST_BOILERPLATE (GstWavEnc, gst_wavenc, GstElement, GST_TYPE_ELEMENT);
+#endif
+
+//rj
+static void gst_wavenc_base_init (gpointer g_class);
+static void gst_wavenc_class_init (GstWavEncClass * klass);
+static void gst_wavenc_init (GstWavEnc * wavenc, GstWavEncClass * klass);
+static GstElementClass *parent_class = NULL;
+//rj
 
 static GstFlowReturn gst_wavenc_chain (GstPad * pad, GstBuffer * buf);
 static gboolean gst_wavenc_event (GstPad * pad, GstEvent * event);
@@ -146,6 +127,34 @@
     GstStateChange transition);
 static gboolean gst_wavenc_sink_setcaps (GstPad * pad, GstCaps * caps);
 
+
+
+
+GType gst_wavenc_get_type (void)
+{
+  static GType wavenc_type = 0;
+
+  if (!wavenc_type) {
+    static const GTypeInfo wavenc_info = {
+      sizeof (GstWavEncClass),
+      gst_wavenc_base_init,
+      NULL,
+      (GClassInitFunc) gst_wavenc_class_init,
+      NULL,
+      NULL,
+      sizeof (GstWavEnc),
+      0,
+      (GInstanceInitFunc) gst_wavenc_init,
+    };
+
+    wavenc_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstWavEnc",
+        &wavenc_info, 0);
+  }
+  return wavenc_type;
+}
+
+
 static void
 gst_wavenc_base_init (gpointer g_class)
 {
@@ -167,6 +176,8 @@
   GstElementClass *element_class;
 
   element_class = (GstElementClass *) klass;
+  
+  parent_class = g_type_class_peek_parent (klass);//rj
 
   element_class->change_state = GST_DEBUG_FUNCPTR (gst_wavenc_change_state);
 }
@@ -192,6 +203,7 @@
 
 #define WAV_HEADER_LEN 44
 
+/* FIXME: we are probably not handling depth != width correctly here */
 static GstBuffer *
 gst_wavenc_create_header_buf (GstWavEnc * wavenc, guint audio_data_size)
 {
@@ -204,23 +216,23 @@
   memset (header, 0, WAV_HEADER_LEN);
 
   wave.common.wChannels = wavenc->channels;
-  wave.common.wBitsPerSample = wavenc->width;
+  wave.common.wBitsPerSample = wavenc->depth;
   wave.common.dwSamplesPerSec = wavenc->rate;
 
   /* Fill out our wav-header with some information */
   memcpy (wave.riff.id, "RIFF", 4);
-  //g_printf("before wave.riff.len %d \n" ,wave.riff.len);
   wave.riff.len = audio_data_size + WAV_HEADER_LEN - 8;
-  //g_printf("after wave.riff.len %d \n" ,wave.riff.len);
   memcpy (wave.riff.wav_id, "WAVE", 4);
 
   memcpy (wave.format.id, "fmt ", 4);
   wave.format.len = 16;
 
-  wave.common.wFormatTag = wavenc->format;
-  wave.common.wBlockAlign = (wavenc->width / 8) * wave.common.wChannels;
+  wave.common.wFormatTag = WAVE_FORMAT_PCM;
   wave.common.dwAvgBytesPerSec =
-      wave.common.wBlockAlign * wave.common.dwSamplesPerSec;
+      wave.common.wChannels * wave.common.dwSamplesPerSec *
+      (wave.common.wBitsPerSample >> 3);
+  wave.common.wBlockAlign =
+      wave.common.wChannels * (wave.common.wBitsPerSample >> 3);
 
   memcpy (wave.data.id, "data", 4);
   wave.data.len = audio_data_size;
@@ -275,8 +287,7 @@
 {
   GstWavEnc *wavenc;
   GstStructure *structure;
-  const gchar *name;
-  gint chans, rate, width;
+  gint chans, rate, width, depth;
 
   wavenc = GST_WAVENC (gst_pad_get_parent (pad));
 
@@ -288,45 +299,21 @@
   GST_DEBUG_OBJECT (wavenc, "got caps: %" GST_PTR_FORMAT, caps);
 
   structure = gst_caps_get_structure (caps, 0);
-  name = gst_structure_get_name (structure);
-
   if (!gst_structure_get_int (structure, "channels", &chans) ||
-      !gst_structure_get_int (structure, "rate", &rate)) {
+      !gst_structure_get_int (structure, "rate", &rate) ||
+      !gst_structure_get_int (structure, "width", &width) ||
+      (width != 8 && !gst_structure_get_int (structure, "depth", &depth))) {
     GST_WARNING_OBJECT (wavenc, "caps incomplete");
     goto fail;
   }
 
-  if (strcmp (name, "audio/x-raw-int") == 0) {
-    if (!gst_structure_get_int (structure, "width", &width)) {
-      GST_WARNING_OBJECT (wavenc, "caps incomplete");
-      goto fail;
-    }
-    wavenc->format = GST_RIFF_WAVE_FORMAT_PCM;
-    wavenc->width = width;
-  } else if (strcmp (name, "audio/x-raw-float") == 0) {
-    if (!gst_structure_get_int (structure, "width", &width)) {
-      GST_WARNING_OBJECT (wavenc, "caps incomplete");
-      goto fail;
-    }
-    wavenc->format = GST_RIFF_WAVE_FORMAT_FLOAT;
-    wavenc->width = width;
-  } else if (strcmp (name, "audio/x-alaw") == 0) {
-    wavenc->format = GST_RIFF_WAVE_FORMAT_ALAW;
-    wavenc->width = 8;
-  } else if (strcmp (name, "audio/x-mulaw") == 0) {
-    wavenc->format = GST_RIFF_WAVE_FORMAT_MULAW;
-    wavenc->width = 8;
-  } else {
-    GST_WARNING_OBJECT (wavenc, "Unsupported format %s", name);
-    goto fail;
-  }
-
   wavenc->channels = chans;
+  wavenc->width = width;
+  wavenc->depth = (width == 8) ? 8 : depth;
   wavenc->rate = rate;
 
-  GST_LOG_OBJECT (wavenc,
-      "accepted caps: format=0x%04x chans=%u width=%u rate=%u",
-      wavenc->format, wavenc->channels, wavenc->width, wavenc->rate);
+  GST_LOG_OBJECT (wavenc, "accepted caps: chans=%u width=%u depth=%u rate=%u",
+      wavenc->channels, wavenc->width, wavenc->depth, wavenc->rate);
 
   gst_object_unref (wavenc);
   return TRUE;
@@ -638,9 +625,6 @@
       /* write header with correct length values */
       gst_wavenc_push_header (wavenc, wavenc->length);
 
-      /* we're done with this file */
-      wavenc->finished_properly = TRUE;
-
       /* and forward the EOS event */
       res = gst_pad_event_default (pad, event);
       break;
@@ -672,9 +656,6 @@
      * header when we get EOS and know the exact length */
     flow = gst_wavenc_push_header (wavenc, 0x7FFF0000);
 
-    /* starting a file, means we have to finish it properly */
-    wavenc->finished_properly = FALSE;
-
     if (flow != GST_FLOW_OK)
       return flow;
 
@@ -682,6 +663,8 @@
     wavenc->sent_header = TRUE;
   }
 
+  wavenc->length += GST_BUFFER_SIZE (buf);
+
   GST_LOG_OBJECT (wavenc, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT,
       GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
 
@@ -690,8 +673,6 @@
   GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->length;
   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
 
-  wavenc->length += GST_BUFFER_SIZE (buf);
-
   flow = gst_pad_push (wavenc->srcpad, buf);
 
   return flow;
@@ -705,14 +686,12 @@
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
-      wavenc->format = 0;
       wavenc->channels = 0;
       wavenc->width = 0;
+      wavenc->depth = 0;
       wavenc->rate = 0;
       wavenc->length = 0;
       wavenc->sent_header = FALSE;
-      /* its true because we haven't writen anything */
-      wavenc->finished_properly = TRUE;
       break;
     default:
       break;
@@ -722,26 +701,13 @@
   if (ret != GST_STATE_CHANGE_SUCCESS)
     return ret;
 
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      if (!wavenc->finished_properly) {
-        GST_ELEMENT_WARNING (wavenc, STREAM, MUX,
-            ("Wav stream not finished properly"),
-            ("Wav stream not finished properly, no EOS received "
-                "before shutdown"));
-      }
-      break;
-    default:
-      break;
-  }
-
   return ret;
 }
 
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
-  return gst_element_register (plugin, "wavenc", GST_RANK_PRIMARY,
+  return gst_element_register (plugin, "wavenc", GST_RANK_NONE,
       GST_TYPE_WAVENC);
 }