More fixes to vorbisdec
authorWim Taymans <wim.taymans@gmail.com>
Fri, 21 Dec 2001 01:14:21 +0000 (01:14 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Fri, 21 Dec 2001 01:14:21 +0000 (01:14 +0000)
Original commit message from CVS:
More fixes to vorbisdec
Fixed the encoder

ext/vorbis/Makefile.am
ext/vorbis/vorbisdec.c
ext/vorbis/vorbisenc.c
ext/vorbis/vorbisenc.h

index 5a87e9e..5bc7197 100644 (file)
@@ -3,7 +3,7 @@ plugindir = $(libdir)/gst
 plugin_LTLIBRARIES = libgstvorbis.la
 
 libgstvorbis_la_SOURCES = vorbis.c vorbisenc.c vorbisdec.c
-libgstvorbis_la_LIBADD = $(VORBIS_LIBS)
+libgstvorbis_la_LIBADD = $(VORBIS_LIBS) -lvorbisenc
 libgstvorbis_la_CFLAGS = $(VORBIS_CFLAGS) $(GST_CFLAGS)
 
 noinst_HEADERS = vorbisenc.h vorbisdec.h
index 5c690af..cd8c9f5 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <vorbisdec.h>
 
-static void gst_vorbisdec_loop (GstElement * element);
 
 extern GstPadTemplate *dec_src_template, *dec_sink_template;
 
@@ -50,12 +49,12 @@ enum
   ARG_0,
 };
 
-static void gst_vorbisdec_class_init (VorbisDecClass * klass);
-static void gst_vorbisdec_init (VorbisDec * vorbisdec);
+static void    gst_vorbisdec_class_init        (VorbisDecClass *klass);
+static void    gst_vorbisdec_init              (VorbisDec *vorbisdec);
 
+static void    gst_vorbisdec_loop              (GstElement *element);
 
 static GstElementClass *parent_class = NULL;
-
 /*static guint gst_vorbisdec_signals[LAST_SIGNAL] = { 0 }; */
 
 GType
index 30dbd94..0210741 100644 (file)
@@ -35,30 +35,34 @@ GstElementDetails vorbisenc_details = {
   "Filter/Audio/Encoder",
   "Encodes audio in OGG Vorbis format",
   VERSION,
-  "Monty <monty@xiph.org>, "\
+  "Monty <monty@xiph.org>, " 
   "Wim Taymans <wim.taymans@chello.be>",
   "(C) 2000",
 };
 
 /* VorbisEnc signals and args */
-enum {
+enum
+{
   /* FILL ME */
   LAST_SIGNAL
 };
 
-enum {
+enum
+{
   ARG_0,
   ARG_BITRATE,
 };
 
-static void    gst_vorbisenc_class_init        (VorbisEncClass *klass);
-static void    gst_vorbisenc_init              (VorbisEnc *vorbisenc);
+static void    gst_vorbisenc_class_init        (VorbisEncClass * klass);
+static void    gst_vorbisenc_init              (VorbisEnc * vorbisenc);
 
-static void    gst_vorbisenc_chain             (GstPad *pad, GstBuffer *buf);
-static void    gst_vorbisenc_setup             (VorbisEnc *vorbisenc);
+static void    gst_vorbisenc_chain             (GstPad * pad, GstBuffer * buf);
+static void    gst_vorbisenc_setup             (VorbisEnc * vorbisenc);
 
-static void     gst_vorbisenc_get_property           (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-static void     gst_vorbisenc_set_property           (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void    gst_vorbisenc_get_property      (GObject * object, guint prop_id, GValue * value,
+                                                GParamSpec * pspec);
+static void    gst_vorbisenc_set_property      (GObject * object, guint prop_id, const GValue * value,
+                                                GParamSpec * pspec);
 
 static GstElementClass *parent_class = NULL;
 /*static guint gst_vorbisenc_signals[LAST_SIGNAL] = { 0 }; */
@@ -70,41 +74,42 @@ vorbisenc_get_type (void)
 
   if (!vorbisenc_type) {
     static const GTypeInfo vorbisenc_info = {
-      sizeof(VorbisEncClass),      NULL,
+      sizeof (VorbisEncClass), NULL,
       NULL,
-      (GClassInitFunc)gst_vorbisenc_class_init,
+      (GClassInitFunc) gst_vorbisenc_class_init,
       NULL,
       NULL,
-      sizeof(VorbisEnc),
+      sizeof (VorbisEnc),
       0,
-      (GInstanceInitFunc)gst_vorbisenc_init,
+      (GInstanceInitFunc) gst_vorbisenc_init,
     };
-    vorbisenc_type = g_type_register_static(GST_TYPE_ELEMENT, "VorbisEnc", &vorbisenc_info, 0);
+
+    vorbisenc_type = g_type_register_static (GST_TYPE_ELEMENT, "VorbisEnc", &vorbisenc_info, 0);
   }
   return vorbisenc_type;
 }
 
 static void
-gst_vorbisenc_class_init (VorbisEncClass *klass)
+gst_vorbisenc_class_init (VorbisEncClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
 
-  gobject_class = (GObjectClass*)klass;
-  gstelement_class = (GstElementClass*)klass;
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
 
-  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BITRATE,
-    g_param_spec_int("bitrate","bitrate","bitrate",
-                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, 
+    g_param_spec_int ("bitrate", "bitrate", "bitrate", 
+           G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
 
-  parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
 
   gobject_class->set_property = gst_vorbisenc_set_property;
   gobject_class->get_property = gst_vorbisenc_get_property;
 }
 
 static void
-gst_vorbisenc_newcaps (GstPad *pad, GstCaps *caps)
+gst_vorbisenc_newcaps (GstPad * pad, GstCaps * caps)
 {
   VorbisEnc *vorbisenc;
 
@@ -117,46 +122,50 @@ gst_vorbisenc_newcaps (GstPad *pad, GstCaps *caps)
 }
 
 static void
-gst_vorbisenc_init (VorbisEnc *vorbisenc)
+gst_vorbisenc_init (VorbisEnc * vorbisenc)
 {
   vorbisenc->sinkpad = gst_pad_new_from_template (enc_sink_template, "sink");
-  gst_element_add_pad(GST_ELEMENT(vorbisenc),vorbisenc->sinkpad);
-  gst_pad_set_chain_function(vorbisenc->sinkpad,gst_vorbisenc_chain);
+  gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
+  gst_pad_set_chain_function (vorbisenc->sinkpad, gst_vorbisenc_chain);
   gst_pad_set_newcaps_function (vorbisenc->sinkpad, gst_vorbisenc_newcaps);
 
   vorbisenc->srcpad = gst_pad_new_from_template (enc_src_template, "src");
   gst_pad_set_caps (vorbisenc->srcpad, gst_pad_get_padtemplate_caps (vorbisenc->srcpad));
-  gst_element_add_pad(GST_ELEMENT(vorbisenc),vorbisenc->srcpad);
+  gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
 
   vorbisenc->channels = 2;
   vorbisenc->frequency = 44100;
   vorbisenc->bitrate = 128000;
+  vorbisenc->setup = FALSE;
+
+  /* we're chained and we can deal with events */
+  GST_FLAG_SET (vorbisenc, GST_ELEMENT_EVENT_AWARE);
 }
 
 static void
-gst_vorbisenc_setup (VorbisEnc *vorbisenc)
+gst_vorbisenc_setup (VorbisEnc * vorbisenc)
 {
   /********** Encode setup ************/
 
   /* choose an encoding mode */
   /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
-  vorbis_info_init(&vorbisenc->vi);
-  vorbis_encode_init(&vorbisenc->vi, vorbisenc->channels, vorbisenc->frequency, 
-                 -1, vorbisenc->bitrate, -1);
+  vorbis_info_init (&vorbisenc->vi);
+  vorbis_encode_init (&vorbisenc->vi, vorbisenc->channels, vorbisenc->frequency,
+                     -1, vorbisenc->bitrate, -1);
 
   /* add a comment */
-  vorbis_comment_init(&vorbisenc->vc);
-  vorbis_comment_add(&vorbisenc->vc,"Track encoded by GStreamer:vorbisenc");
+  vorbis_comment_init (&vorbisenc->vc);
+  vorbis_comment_add (&vorbisenc->vc, "Track encoded with GStreamer");
 
   /* set up the analysis state and auxiliary encoding storage */
-  vorbis_analysis_init(&vorbisenc->vd,&vorbisenc->vi);
-  vorbis_block_init(&vorbisenc->vd,&vorbisenc->vb);
+  vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
+  vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
 
   /* set up our packet->stream encoder */
   /* pick a random serial number; that way we can more likely build
      chained streams just by concatenation */
-  srand(time(NULL));
-  ogg_stream_init(&vorbisenc->os,rand());
+  srand (time (NULL));
+  ogg_stream_init (&vorbisenc->os, rand ());
 
   /* Vorbis streams begin with three headers; the initial header (with
      most of the codec setup parameters) which is mandated by the Ogg
@@ -170,89 +179,111 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
     ogg_packet header_comm;
     ogg_packet header_code;
 
-    vorbis_analysis_headerout(&vorbisenc->vd,&vorbisenc->vc,&header,&header_comm,&header_code);
-    ogg_stream_packetin(&vorbisenc->os,&header); /* automatically placed in its own
-                                        page */
-    ogg_stream_packetin(&vorbisenc->os,&header_comm);
-    ogg_stream_packetin(&vorbisenc->os,&header_code);
+    vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header, &header_comm, &header_code);
+    ogg_stream_packetin (&vorbisenc->os, &header);     /* automatically placed in its own
+                                                          page */
+    ogg_stream_packetin (&vorbisenc->os, &header_comm);
+    ogg_stream_packetin (&vorbisenc->os, &header_code);
 
     /* no need to write out here.  We'll get to that in the main loop */
   }
+
+  vorbisenc->setup = TRUE;
 }
 
 static void
-gst_vorbisenc_chain (GstPad *pad,GstBuffer *buf)
+gst_vorbisenc_chain (GstPad * pad, GstBuffer * buf)
 {
   VorbisEnc *vorbisenc;
-  gint16 *data;
-  gulong size;
-  gulong i, j;
-  GstBuffer *outbuf;
 
-  g_return_if_fail(pad != NULL);
-  g_return_if_fail(GST_IS_PAD(pad));
-  g_return_if_fail(buf != NULL);
+  g_return_if_fail (pad != NULL);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (buf != NULL);
 
   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
-  data = (gint16 *)GST_BUFFER_DATA(buf);
-  size = GST_BUFFER_SIZE(buf)/2;
 
-  if(size==0){
-    /* end of file.  this can be done implicitly in the mainline,
-       but it's easier to see here in non-clever fashion.
-       Tell the library we're at end of stream so that it can handle
-       the last frame and mark end of stream in the output properly */
-    vorbis_analysis_wrote(&vorbisenc->vd,0);
+  if (!vorbisenc->setup) {
+    gst_element_error (GST_ELEMENT (vorbisenc), "encoder not initialized");
+    if (GST_IS_BUFFER (buf))
+      gst_buffer_unref (buf);
+    else
+      gst_pad_event_default (pad, GST_EVENT (buf));
+    return;
+  }
 
-  }else{
+  if (GST_IS_EVENT (buf)) {
+    switch (GST_EVENT_TYPE (buf)) {
+      case GST_EVENT_EOS:
+        /* end of file.  this can be done implicitly in the mainline,
+           but it's easier to see here in non-clever fashion.
+           Tell the library we're at end of stream so that it can handle
+           the last frame and mark end of stream in the output properly */
+        vorbis_analysis_wrote (&vorbisenc->vd, 0);
+      default:
+       gst_pad_event_default (pad, GST_EVENT (buf));
+       break;
+    }
+  }
+  else {
+    gint16 *data;
+    gulong size;
+    gulong i, j;
+    float **buffer;
+  
     /* data to encode */
+    data = (gint16 *) GST_BUFFER_DATA (buf);
+    size = GST_BUFFER_SIZE (buf) / 2;
 
     /* expose the buffer to submit data */
-    float **buffer=vorbis_analysis_buffer(&vorbisenc->vd,size/vorbisenc->channels);
+    buffer = vorbis_analysis_buffer (&vorbisenc->vd, size / vorbisenc->channels);
 
     /* uninterleave samples */
-    for(i=0;i<size/vorbisenc->channels;i++)
-    {
-      for(j=0;j<vorbisenc->channels;j++)
-        buffer[j][i] = data[i*vorbisenc->channels+j]/32768.f;
+    for (i = 0; i < size / vorbisenc->channels; i++) {
+      for (j = 0; j < vorbisenc->channels; j++)
+       buffer[j][i] = data[i * vorbisenc->channels + j] / 32768.f;
     }
 
     /* tell the library how much we actually submitted */
-    vorbis_analysis_wrote(&vorbisenc->vd, size/vorbisenc->channels);
+    vorbis_analysis_wrote (&vorbisenc->vd, size / vorbisenc->channels);
+
+    gst_buffer_unref (buf);
   }
 
   /* vorbis does some data preanalysis, then divvies up blocks for
      more involved (potentially parallel) processing.  Get a single
      block for encoding now */
-  while(vorbis_analysis_blockout(&vorbisenc->vd,&vorbisenc->vb)==1){
+  while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
 
     /* analysis */
-    vorbis_analysis(&vorbisenc->vb,&vorbisenc->op);
+    vorbis_analysis (&vorbisenc->vb, &vorbisenc->op);
 
     /* weld the packet into the bitstream */
-    ogg_stream_packetin(&vorbisenc->os,&vorbisenc->op);
+    ogg_stream_packetin (&vorbisenc->os, &vorbisenc->op);
 
     /* write out pages (if any) */
-    while(!vorbisenc->eos){
-      int result=ogg_stream_pageout(&vorbisenc->os,&vorbisenc->og);
-      if(result==0)break;
+    while (!vorbisenc->eos) {
+      int result = ogg_stream_pageout (&vorbisenc->os, &vorbisenc->og);
+      GstBuffer *outbuf;
 
-      outbuf = gst_buffer_new();
-      GST_BUFFER_DATA(outbuf) = g_malloc(vorbisenc->og.header_len+vorbisenc->og.body_len);
-      GST_BUFFER_SIZE(outbuf) = vorbisenc->og.header_len+vorbisenc->og.body_len;
+      if (result == 0)
+       break;
 
-      memcpy(GST_BUFFER_DATA(outbuf), vorbisenc->og.header, vorbisenc->og.header_len);
-      memcpy(GST_BUFFER_DATA(outbuf)+vorbisenc->og.header_len, vorbisenc->og.body, vorbisenc->og.body_len);
+      outbuf = gst_buffer_new ();
+      GST_BUFFER_DATA (outbuf) = g_malloc (vorbisenc->og.header_len + vorbisenc->og.body_len);
+      GST_BUFFER_SIZE (outbuf) = vorbisenc->og.header_len + vorbisenc->og.body_len;
 
-      GST_DEBUG (0, "vorbisenc: encoded buffer of %d bytes\n", GST_BUFFER_SIZE(outbuf));
+      memcpy (GST_BUFFER_DATA (outbuf), vorbisenc->og.header, vorbisenc->og.header_len);
+      memcpy (GST_BUFFER_DATA (outbuf) + vorbisenc->og.header_len, vorbisenc->og.body,
+             vorbisenc->og.body_len);
 
-      gst_pad_push(vorbisenc->srcpad, outbuf);
+      GST_DEBUG (0, "vorbisenc: encoded buffer of %d bytes\n", GST_BUFFER_SIZE (outbuf));
+
+      gst_pad_push (vorbisenc->srcpad, outbuf);
 
       /* this could be set above, but for illustrative purposes, I do
          it here (to show that vorbis does know where the stream ends) */
-
-      if(ogg_page_eos(&vorbisenc->og)) {
-        vorbisenc->eos=1;
+      if (ogg_page_eos (&vorbisenc->og)) {
+       vorbisenc->eos = 1;
       }
     }
   }
@@ -260,17 +291,16 @@ gst_vorbisenc_chain (GstPad *pad,GstBuffer *buf)
   if (vorbisenc->eos) {
     /* clean up and exit.  vorbis_info_clear() must be called last */
 
-    ogg_stream_clear(&vorbisenc->os);
-    vorbis_block_clear(&vorbisenc->vb);
-    vorbis_dsp_clear(&vorbisenc->vd);
-    vorbis_info_clear(&vorbisenc->vi);
+    ogg_stream_clear (&vorbisenc->os);
+    vorbis_block_clear (&vorbisenc->vb);
+    vorbis_dsp_clear (&vorbisenc->vd);
+    vorbis_info_clear (&vorbisenc->vi);
   }
 
-  gst_buffer_unref(buf);
 }
 
 static void
-gst_vorbisenc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
 {
   VorbisEnc *vorbisenc;
 
@@ -289,7 +319,8 @@ gst_vorbisenc_get_property (GObject *object, guint prop_id, GValue *value, GPara
 }
 
 static void
-gst_vorbisenc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * value,
+                           GParamSpec * pspec)
 {
   VorbisEnc *vorbisenc;
 
@@ -306,4 +337,3 @@ gst_vorbisenc_set_property (GObject *object, guint prop_id, const GValue *value,
       break;
   }
 }
-
index dd647f4..dffac76 100644 (file)
@@ -67,6 +67,8 @@ struct _VorbisEnc {
   gint bitrate;
   gint channels;
   gint frequency;
+
+  gboolean setup;
 };
 
 struct _VorbisEncClass {