gst_plugins_base/ext/vorbis/vorbisdec.c
branchRCL_3
changeset 30 7e817e7e631c
parent 0 0e761a78d257
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
       
     1 /* GStreamer
       
     2  * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
       
     3  *
       
     4  * This library is free software; you can redistribute it and/or
       
     5  * modify it under the terms of the GNU Library General Public
       
     6  * License as published by the Free Software Foundation; either
       
     7  * version 2 of the License, or (at your option) any later version.
       
     8  *
       
     9  * This library is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12  * Library General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU Library General Public
       
    15  * License along with this library; if not, write to the
       
    16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    17  * Boston, MA 02111-1307, USA.
       
    18  */
       
    19 
       
    20 /**
       
    21  * SECTION:element-vorbisdec
       
    22  * @short_description: a decoder that decodes Vorbis to raw audio
       
    23  * @see_also: vorbisenc, oggdemux
       
    24  *
       
    25  * <refsect2>
       
    26  * <para>
       
    27  * This element decodes a Vorbis stream to raw float audio.
       
    28  * <ulink url="http://www.vorbis.com/">Vorbis</ulink> is a royalty-free
       
    29  * audio codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
       
    30  * Foundation</ulink>.
       
    31  * </para>
       
    32  * <title>Example pipelines</title>
       
    33  * <para>
       
    34  * <programlisting>
       
    35  * gst-launch -v filesrc location=sine.ogg ! oggdemux ! vorbisdec ! audioconvert ! alsasink
       
    36  * </programlisting>
       
    37  * Decode an Ogg/Vorbis. To create an Ogg/Vorbis file refer to the documentation of vorbisenc.
       
    38  * </para>
       
    39  * </refsect2>
       
    40  *
       
    41  * Last reviewed on 2006-03-01 (0.10.4)
       
    42  */
       
    43 
       
    44 #ifdef HAVE_CONFIG_H
       
    45 #  include "config.h"
       
    46 #endif
       
    47 
       
    48 #include "vorbisdec.h"
       
    49 #include <string.h>
       
    50 #include <gst/audio/audio.h>
       
    51 #include <gst/tag/tag.h>
       
    52 #include <gst/audio/multichannel.h>
       
    53 
       
    54 GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
       
    55 #define GST_CAT_DEFAULT vorbisdec_debug
       
    56 
       
    57 static const GstElementDetails vorbis_dec_details =
       
    58 GST_ELEMENT_DETAILS ("Vorbis audio decoder",
       
    59     "Codec/Decoder/Audio",
       
    60     "decode raw vorbis streams to float audio",
       
    61     "Benjamin Otte <in7y118@public.uni-hamburg.de>");
       
    62 
       
    63 static GstStaticPadTemplate vorbis_dec_src_factory =
       
    64 GST_STATIC_PAD_TEMPLATE ("src",
       
    65     GST_PAD_SRC,
       
    66     GST_PAD_ALWAYS,
       
    67     GST_STATIC_CAPS ("audio/x-raw-float, "
       
    68         "rate = (int) [ 1, MAX ], "
       
    69         "channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, "
       
    70 /* no ifdef in macros, please
       
    71 #ifdef GST_VORBIS_DEC_SEQUENTIAL
       
    72       "layout = \"sequential\", "
       
    73 #endif
       
    74 */
       
    75         "width = (int) 32")
       
    76     );
       
    77 
       
    78 static GstStaticPadTemplate vorbis_dec_sink_factory =
       
    79 GST_STATIC_PAD_TEMPLATE ("sink",
       
    80     GST_PAD_SINK,
       
    81     GST_PAD_ALWAYS,
       
    82     GST_STATIC_CAPS ("audio/x-vorbis")
       
    83     );
       
    84 
       
    85 GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
       
    86 
       
    87 static void vorbis_dec_finalize (GObject * object);
       
    88 static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
       
    89 static GstFlowReturn vorbis_dec_chain (GstPad * pad, GstBuffer * buffer);
       
    90 static GstFlowReturn vorbis_dec_chain_forward (GstVorbisDec * vd,
       
    91     gboolean discont, GstBuffer * buffer);
       
    92 static GstStateChangeReturn vorbis_dec_change_state (GstElement * element,
       
    93     GstStateChange transition);
       
    94 
       
    95 static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event);
       
    96 static gboolean vorbis_dec_src_query (GstPad * pad, GstQuery * query);
       
    97 static gboolean vorbis_dec_convert (GstPad * pad,
       
    98     GstFormat src_format, gint64 src_value,
       
    99     GstFormat * dest_format, gint64 * dest_value);
       
   100 
       
   101 static gboolean vorbis_dec_sink_query (GstPad * pad, GstQuery * query);
       
   102 
       
   103 static void
       
   104 gst_vorbis_dec_base_init (gpointer g_class)
       
   105 {
       
   106   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
       
   107   GstPadTemplate *src_template, *sink_template;
       
   108 
       
   109   src_template = gst_static_pad_template_get (&vorbis_dec_src_factory);
       
   110   gst_element_class_add_pad_template (element_class, src_template);
       
   111 
       
   112   sink_template = gst_static_pad_template_get (&vorbis_dec_sink_factory);
       
   113   gst_element_class_add_pad_template (element_class, sink_template);
       
   114 
       
   115   gst_element_class_set_details (element_class, &vorbis_dec_details);
       
   116 }
       
   117 
       
   118 static void
       
   119 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
       
   120 {
       
   121   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
       
   122   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
       
   123 
       
   124   gobject_class->finalize = vorbis_dec_finalize;
       
   125 
       
   126   gstelement_class->change_state = GST_DEBUG_FUNCPTR (vorbis_dec_change_state);
       
   127 }
       
   128 
       
   129 static const GstQueryType *
       
   130 vorbis_get_query_types (GstPad * pad)
       
   131 {
       
   132   static const GstQueryType vorbis_dec_src_query_types[] = {
       
   133     GST_QUERY_POSITION,
       
   134     GST_QUERY_DURATION,
       
   135     GST_QUERY_CONVERT,
       
   136     0
       
   137   };
       
   138 
       
   139   return vorbis_dec_src_query_types;
       
   140 }
       
   141 
       
   142 static void
       
   143 gst_vorbis_dec_init (GstVorbisDec * dec, GstVorbisDecClass * g_class)
       
   144 {
       
   145   dec->sinkpad = gst_pad_new_from_static_template (&vorbis_dec_sink_factory,
       
   146       "sink");
       
   147 
       
   148   gst_pad_set_event_function (dec->sinkpad,
       
   149       GST_DEBUG_FUNCPTR (vorbis_dec_sink_event));
       
   150   gst_pad_set_chain_function (dec->sinkpad,
       
   151       GST_DEBUG_FUNCPTR (vorbis_dec_chain));
       
   152   gst_pad_set_query_function (dec->sinkpad,
       
   153       GST_DEBUG_FUNCPTR (vorbis_dec_sink_query));
       
   154   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
       
   155 
       
   156   dec->srcpad = gst_pad_new_from_static_template (&vorbis_dec_src_factory,
       
   157       "src");
       
   158 
       
   159   gst_pad_set_event_function (dec->srcpad,
       
   160       GST_DEBUG_FUNCPTR (vorbis_dec_src_event));
       
   161   gst_pad_set_query_type_function (dec->srcpad,
       
   162       GST_DEBUG_FUNCPTR (vorbis_get_query_types));
       
   163   gst_pad_set_query_function (dec->srcpad,
       
   164       GST_DEBUG_FUNCPTR (vorbis_dec_src_query));
       
   165   gst_pad_use_fixed_caps (dec->srcpad);
       
   166   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
       
   167 
       
   168   dec->queued = NULL;
       
   169   dec->pendingevents = NULL;
       
   170   dec->taglist = NULL;
       
   171 }
       
   172 
       
   173 static void
       
   174 vorbis_dec_finalize (GObject * object)
       
   175 {
       
   176   /* Release any possibly allocated libvorbis data.
       
   177    * _clear functions can safely be called multiple times
       
   178    */
       
   179   GstVorbisDec *vd = GST_VORBIS_DEC (object);
       
   180 
       
   181   vorbis_block_clear (&vd->vb);
       
   182   vorbis_dsp_clear (&vd->vd);
       
   183   vorbis_comment_clear (&vd->vc);
       
   184   vorbis_info_clear (&vd->vi);
       
   185 
       
   186   G_OBJECT_CLASS (parent_class)->finalize (object);
       
   187 }
       
   188 
       
   189 static void
       
   190 gst_vorbis_dec_reset (GstVorbisDec * dec)
       
   191 {
       
   192   dec->cur_timestamp = GST_CLOCK_TIME_NONE;
       
   193   dec->prev_timestamp = GST_CLOCK_TIME_NONE;
       
   194   dec->granulepos = -1;
       
   195   dec->discont = TRUE;
       
   196   gst_segment_init (&dec->segment, GST_FORMAT_TIME);
       
   197 
       
   198   g_list_foreach (dec->queued, (GFunc) gst_mini_object_unref, NULL);
       
   199   g_list_free (dec->queued);
       
   200   dec->queued = NULL;
       
   201   g_list_foreach (dec->gather, (GFunc) gst_mini_object_unref, NULL);
       
   202   g_list_free (dec->gather);
       
   203   dec->gather = NULL;
       
   204   g_list_foreach (dec->decode, (GFunc) gst_mini_object_unref, NULL);
       
   205   g_list_free (dec->decode);
       
   206   dec->decode = NULL;
       
   207   g_list_foreach (dec->pendingevents, (GFunc) gst_mini_object_unref, NULL);
       
   208   g_list_free (dec->pendingevents);
       
   209   dec->pendingevents = NULL;
       
   210 
       
   211   if (dec->taglist)
       
   212     gst_tag_list_free (dec->taglist);
       
   213   dec->taglist = NULL;
       
   214 }
       
   215 
       
   216 
       
   217 static gboolean
       
   218 vorbis_dec_convert (GstPad * pad,
       
   219     GstFormat src_format, gint64 src_value,
       
   220     GstFormat * dest_format, gint64 * dest_value)
       
   221 {
       
   222   gboolean res = TRUE;
       
   223   GstVorbisDec *dec;
       
   224   guint64 scale = 1;
       
   225 
       
   226   if (src_format == *dest_format) {
       
   227     *dest_value = src_value;
       
   228     return TRUE;
       
   229   }
       
   230 
       
   231   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
       
   232 
       
   233   if (!dec->initialized)
       
   234     goto no_header;
       
   235 
       
   236   if (dec->sinkpad == pad &&
       
   237       (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
       
   238     goto no_format;
       
   239 
       
   240   switch (src_format) {
       
   241     case GST_FORMAT_TIME:
       
   242       switch (*dest_format) {
       
   243         case GST_FORMAT_BYTES:
       
   244           scale = sizeof (float) * dec->vi.channels;
       
   245         case GST_FORMAT_DEFAULT:
       
   246           *dest_value =
       
   247               scale * gst_util_uint64_scale_int (src_value, dec->vi.rate,
       
   248               GST_SECOND);
       
   249           break;
       
   250         default:
       
   251           res = FALSE;
       
   252       }
       
   253       break;
       
   254     case GST_FORMAT_DEFAULT:
       
   255       switch (*dest_format) {
       
   256         case GST_FORMAT_BYTES:
       
   257           *dest_value = src_value * sizeof (float) * dec->vi.channels;
       
   258           break;
       
   259         case GST_FORMAT_TIME:
       
   260           *dest_value =
       
   261               gst_util_uint64_scale_int (src_value, GST_SECOND, dec->vi.rate);
       
   262           break;
       
   263         default:
       
   264           res = FALSE;
       
   265       }
       
   266       break;
       
   267     case GST_FORMAT_BYTES:
       
   268       switch (*dest_format) {
       
   269         case GST_FORMAT_DEFAULT:
       
   270           *dest_value = src_value / (sizeof (float) * dec->vi.channels);
       
   271           break;
       
   272         case GST_FORMAT_TIME:
       
   273           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
       
   274               dec->vi.rate * sizeof (float) * dec->vi.channels);
       
   275           break;
       
   276         default:
       
   277           res = FALSE;
       
   278       }
       
   279       break;
       
   280     default:
       
   281       res = FALSE;
       
   282   }
       
   283 done:
       
   284   gst_object_unref (dec);
       
   285 
       
   286   return res;
       
   287 
       
   288   /* ERRORS */
       
   289 no_header:
       
   290   {
       
   291     GST_DEBUG_OBJECT (dec, "no header packets received");
       
   292     res = FALSE;
       
   293     goto done;
       
   294   }
       
   295 no_format:
       
   296   {
       
   297     GST_DEBUG_OBJECT (dec, "formats unsupported");
       
   298     res = FALSE;
       
   299     goto done;
       
   300   }
       
   301 }
       
   302 
       
   303 static gboolean
       
   304 vorbis_dec_src_query (GstPad * pad, GstQuery * query)
       
   305 {
       
   306   GstVorbisDec *dec;
       
   307   gboolean res = FALSE;
       
   308 
       
   309   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
       
   310 
       
   311   switch (GST_QUERY_TYPE (query)) {
       
   312     case GST_QUERY_POSITION:
       
   313     {
       
   314       gint64 granulepos, value;
       
   315       GstFormat my_format, format;
       
   316       gint64 time;
       
   317 
       
   318       /* we start from the last seen granulepos */
       
   319       granulepos = dec->granulepos;
       
   320 
       
   321       gst_query_parse_position (query, &format, NULL);
       
   322 
       
   323       /* and convert to the final format in two steps with time as the
       
   324        * intermediate step */
       
   325       my_format = GST_FORMAT_TIME;
       
   326       if (!(res =
       
   327               vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos,
       
   328                   &my_format, &time)))
       
   329         goto error;
       
   330 
       
   331       /* correct for the segment values */
       
   332       time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
       
   333 
       
   334       GST_LOG_OBJECT (dec,
       
   335           "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
       
   336 
       
   337       /* and convert to the final format */
       
   338       if (!(res = vorbis_dec_convert (pad, my_format, time, &format, &value)))
       
   339         goto error;
       
   340 
       
   341       gst_query_set_position (query, format, value);
       
   342 
       
   343       GST_LOG_OBJECT (dec,
       
   344           "query %p: we return %lld (format %u)", query, value, format);
       
   345 
       
   346       break;
       
   347     }
       
   348     case GST_QUERY_DURATION:
       
   349     {
       
   350       GstPad *peer;
       
   351 
       
   352       if (!(peer = gst_pad_get_peer (dec->sinkpad))) {
       
   353         GST_WARNING_OBJECT (dec, "sink pad %" GST_PTR_FORMAT " is not linked",
       
   354             dec->sinkpad);
       
   355         goto error;
       
   356       }
       
   357 
       
   358       res = gst_pad_query (peer, query);
       
   359       gst_object_unref (peer);
       
   360       if (!res)
       
   361         goto error;
       
   362 
       
   363       break;
       
   364     }
       
   365     case GST_QUERY_CONVERT:
       
   366     {
       
   367       GstFormat src_fmt, dest_fmt;
       
   368       gint64 src_val, dest_val;
       
   369 
       
   370       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
       
   371       if (!(res =
       
   372               vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
       
   373         goto error;
       
   374       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
       
   375       break;
       
   376     }
       
   377     default:
       
   378       res = gst_pad_query_default (pad, query);
       
   379       break;
       
   380   }
       
   381 done:
       
   382   gst_object_unref (dec);
       
   383 
       
   384   return res;
       
   385 
       
   386   /* ERRORS */
       
   387 error:
       
   388   {
       
   389     GST_WARNING_OBJECT (dec, "error handling query");
       
   390     goto done;
       
   391   }
       
   392 }
       
   393 
       
   394 static gboolean
       
   395 vorbis_dec_sink_query (GstPad * pad, GstQuery * query)
       
   396 {
       
   397   GstVorbisDec *dec;
       
   398   gboolean res;
       
   399 
       
   400   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
       
   401 
       
   402   switch (GST_QUERY_TYPE (query)) {
       
   403     case GST_QUERY_CONVERT:
       
   404     {
       
   405       GstFormat src_fmt, dest_fmt;
       
   406       gint64 src_val, dest_val;
       
   407 
       
   408       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
       
   409       if (!(res =
       
   410               vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
       
   411         goto error;
       
   412       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
       
   413       break;
       
   414     }
       
   415     default:
       
   416       res = gst_pad_query_default (pad, query);
       
   417       break;
       
   418   }
       
   419 
       
   420 done:
       
   421   gst_object_unref (dec);
       
   422 
       
   423   return res;
       
   424 
       
   425   /* ERRORS */
       
   426 error:
       
   427   {
       
   428     GST_DEBUG_OBJECT (dec, "error converting value");
       
   429     goto done;
       
   430   }
       
   431 }
       
   432 
       
   433 static gboolean
       
   434 vorbis_dec_src_event (GstPad * pad, GstEvent * event)
       
   435 {
       
   436   gboolean res = TRUE;
       
   437   GstVorbisDec *dec;
       
   438 
       
   439   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
       
   440 
       
   441   switch (GST_EVENT_TYPE (event)) {
       
   442     case GST_EVENT_SEEK:
       
   443     {
       
   444       GstFormat format, tformat;
       
   445       gdouble rate;
       
   446       GstEvent *real_seek;
       
   447       GstSeekFlags flags;
       
   448       GstSeekType cur_type, stop_type;
       
   449       gint64 cur, stop;
       
   450       gint64 tcur, tstop;
       
   451 
       
   452       gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
       
   453           &stop_type, &stop);
       
   454       gst_event_unref (event);
       
   455 
       
   456       /* we have to ask our peer to seek to time here as we know
       
   457        * nothing about how to generate a granulepos from the src
       
   458        * formats or anything.
       
   459        *
       
   460        * First bring the requested format to time
       
   461        */
       
   462       tformat = GST_FORMAT_TIME;
       
   463       if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur)))
       
   464         goto convert_error;
       
   465       if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop)))
       
   466         goto convert_error;
       
   467 
       
   468       /* then seek with time on the peer */
       
   469       real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
       
   470           flags, cur_type, tcur, stop_type, tstop);
       
   471 
       
   472       res = gst_pad_push_event (dec->sinkpad, real_seek);
       
   473 
       
   474       break;
       
   475     }
       
   476     default:
       
   477       res = gst_pad_push_event (dec->sinkpad, event);
       
   478       break;
       
   479   }
       
   480 done:
       
   481   gst_object_unref (dec);
       
   482 
       
   483   return res;
       
   484 
       
   485   /* ERRORS */
       
   486 convert_error:
       
   487   {
       
   488     GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
       
   489     goto done;
       
   490   }
       
   491 }
       
   492 
       
   493 static gboolean
       
   494 vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
       
   495 {
       
   496   gboolean ret = FALSE;
       
   497   GstVorbisDec *dec;
       
   498 
       
   499   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
       
   500 
       
   501   GST_LOG_OBJECT (dec, "handling event");
       
   502   switch (GST_EVENT_TYPE (event)) {
       
   503     case GST_EVENT_EOS:
       
   504       ret = gst_pad_push_event (dec->srcpad, event);
       
   505       break;
       
   506     case GST_EVENT_FLUSH_START:
       
   507       ret = gst_pad_push_event (dec->srcpad, event);
       
   508       break;
       
   509     case GST_EVENT_FLUSH_STOP:
       
   510       /* here we must clean any state in the decoder */
       
   511 #ifdef HAVE_VORBIS_SYNTHESIS_RESTART
       
   512       vorbis_synthesis_restart (&dec->vd);
       
   513 #endif
       
   514       gst_vorbis_dec_reset (dec);
       
   515       ret = gst_pad_push_event (dec->srcpad, event);
       
   516       break;
       
   517     case GST_EVENT_NEWSEGMENT:
       
   518     {
       
   519       GstFormat format;
       
   520       gdouble rate, arate;
       
   521       gint64 start, stop, time;
       
   522       gboolean update;
       
   523 
       
   524       gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
       
   525           &start, &stop, &time);
       
   526 
       
   527       /* we need time for now */
       
   528       if (format != GST_FORMAT_TIME)
       
   529         goto newseg_wrong_format;
       
   530 
       
   531       GST_DEBUG_OBJECT (dec,
       
   532           "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
       
   533           ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
       
   534           update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
       
   535           GST_TIME_ARGS (time));
       
   536 
       
   537       /* now configure the values */
       
   538       gst_segment_set_newsegment_full (&dec->segment, update,
       
   539           rate, arate, format, start, stop, time);
       
   540 
       
   541       if (dec->initialized)
       
   542         /* and forward */
       
   543         ret = gst_pad_push_event (dec->srcpad, event);
       
   544       else {
       
   545         /* store it to send once we're initialized */
       
   546         dec->pendingevents = g_list_append (dec->pendingevents, event);
       
   547         ret = TRUE;
       
   548       }
       
   549       break;
       
   550     }
       
   551     default:
       
   552       ret = gst_pad_push_event (dec->srcpad, event);
       
   553       break;
       
   554   }
       
   555 done:
       
   556   gst_object_unref (dec);
       
   557 
       
   558   return ret;
       
   559 
       
   560   /* ERRORS */
       
   561 newseg_wrong_format:
       
   562   {
       
   563     GST_DEBUG_OBJECT (dec, "received non TIME newsegment");
       
   564     goto done;
       
   565   }
       
   566 }
       
   567 
       
   568 static GstFlowReturn
       
   569 vorbis_handle_identification_packet (GstVorbisDec * vd)
       
   570 {
       
   571   GstCaps *caps;
       
   572   const GstAudioChannelPosition *pos = NULL;
       
   573 
       
   574   switch (vd->vi.channels) {
       
   575     case 1:
       
   576     case 2:
       
   577       /* nothing */
       
   578       break;
       
   579     case 3:{
       
   580       static const GstAudioChannelPosition pos3[] = {
       
   581         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
       
   582         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
       
   583         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
       
   584       };
       
   585       pos = pos3;
       
   586       break;
       
   587     }
       
   588     case 4:{
       
   589       static const GstAudioChannelPosition pos4[] = {
       
   590         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
       
   591         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
       
   592         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
       
   593         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
       
   594       };
       
   595       pos = pos4;
       
   596       break;
       
   597     }
       
   598     case 5:{
       
   599       static const GstAudioChannelPosition pos5[] = {
       
   600         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
       
   601         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
       
   602         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
       
   603         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
       
   604         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
       
   605       };
       
   606       pos = pos5;
       
   607       break;
       
   608     }
       
   609     case 6:{
       
   610       static const GstAudioChannelPosition pos6[] = {
       
   611         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
       
   612         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
       
   613         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
       
   614         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
       
   615         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
       
   616         GST_AUDIO_CHANNEL_POSITION_LFE
       
   617       };
       
   618       pos = pos6;
       
   619       break;
       
   620     }
       
   621     default:
       
   622       goto channel_count_error;
       
   623   }
       
   624 
       
   625   caps = gst_caps_new_simple ("audio/x-raw-float",
       
   626       "rate", G_TYPE_INT, vd->vi.rate,
       
   627       "channels", G_TYPE_INT, vd->vi.channels,
       
   628       "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
       
   629 
       
   630   if (pos) {
       
   631     gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
       
   632   }
       
   633   gst_pad_set_caps (vd->srcpad, caps);
       
   634   gst_caps_unref (caps);
       
   635 
       
   636   return GST_FLOW_OK;
       
   637 
       
   638   /* ERROR */
       
   639 channel_count_error:
       
   640   {
       
   641     GST_ELEMENT_ERROR (vd, STREAM, NOT_IMPLEMENTED, (NULL),
       
   642         ("Unsupported channel count %d", vd->vi.channels));
       
   643     return GST_FLOW_ERROR;
       
   644   }
       
   645 }
       
   646 
       
   647 static GstFlowReturn
       
   648 vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
       
   649 {
       
   650   guint bitrate = 0;
       
   651   gchar *encoder = NULL;
       
   652   GstTagList *list;
       
   653   GstBuffer *buf;
       
   654 
       
   655   GST_DEBUG_OBJECT (vd, "parsing comment packet");
       
   656 
       
   657   buf = gst_buffer_new_and_alloc (packet->bytes);
       
   658   GST_BUFFER_DATA (buf) = packet->packet;
       
   659 
       
   660   list =
       
   661       gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
       
   662       &encoder);
       
   663 
       
   664   vd->taglist = gst_tag_list_merge (vd->taglist, list, GST_TAG_MERGE_REPLACE);
       
   665 
       
   666   gst_tag_list_free (list);
       
   667   gst_buffer_unref (buf);
       
   668 
       
   669   if (!vd->taglist) {
       
   670     GST_ERROR_OBJECT (vd, "couldn't decode comments");
       
   671     vd->taglist = gst_tag_list_new ();
       
   672   }
       
   673   if (encoder) {
       
   674     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
       
   675         GST_TAG_ENCODER, encoder, NULL);
       
   676     g_free (encoder);
       
   677   }
       
   678   gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
       
   679       GST_TAG_ENCODER_VERSION, vd->vi.version,
       
   680       GST_TAG_AUDIO_CODEC, "Vorbis", NULL);
       
   681   if (vd->vi.bitrate_nominal > 0) {
       
   682     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
       
   683         GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL);
       
   684     bitrate = vd->vi.bitrate_nominal;
       
   685   }
       
   686   if (vd->vi.bitrate_upper > 0) {
       
   687     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
       
   688         GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL);
       
   689     if (!bitrate)
       
   690       bitrate = vd->vi.bitrate_upper;
       
   691   }
       
   692   if (vd->vi.bitrate_lower > 0) {
       
   693     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
       
   694         GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL);
       
   695     if (!bitrate)
       
   696       bitrate = vd->vi.bitrate_lower;
       
   697   }
       
   698   if (bitrate) {
       
   699     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
       
   700         GST_TAG_BITRATE, (guint) bitrate, NULL);
       
   701   }
       
   702 
       
   703   if (vd->initialized) {
       
   704     gst_element_found_tags_for_pad (GST_ELEMENT_CAST (vd), vd->srcpad,
       
   705         vd->taglist);
       
   706     vd->taglist = NULL;
       
   707   } else {
       
   708     /* Only post them as messages for the time being. *
       
   709      * They will be pushed on the pad once the decoder is initialized */
       
   710     gst_element_post_message (GST_ELEMENT_CAST (vd),
       
   711         gst_message_new_tag (GST_OBJECT (vd), gst_tag_list_copy (vd->taglist)));
       
   712   }
       
   713 
       
   714   return GST_FLOW_OK;
       
   715 }
       
   716 
       
   717 static GstFlowReturn
       
   718 vorbis_handle_type_packet (GstVorbisDec * vd)
       
   719 {
       
   720   GList *walk;
       
   721 
       
   722   g_assert (vd->initialized == FALSE);
       
   723 
       
   724   vorbis_synthesis_init (&vd->vd, &vd->vi);
       
   725   vorbis_block_init (&vd->vd, &vd->vb);
       
   726   vd->initialized = TRUE;
       
   727 
       
   728   if (vd->pendingevents) {
       
   729     for (walk = vd->pendingevents; walk; walk = g_list_next (walk))
       
   730       gst_pad_push_event (vd->srcpad, GST_EVENT_CAST (walk->data));
       
   731     g_list_free (vd->pendingevents);
       
   732     vd->pendingevents = NULL;
       
   733   }
       
   734 
       
   735   if (vd->taglist) {
       
   736     /* The tags have already been sent on the bus as messages. */
       
   737     gst_pad_push_event (vd->srcpad, gst_event_new_tag (vd->taglist));
       
   738     vd->taglist = NULL;
       
   739   }
       
   740 
       
   741   return GST_FLOW_OK;
       
   742 }
       
   743 
       
   744 static GstFlowReturn
       
   745 vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
       
   746 {
       
   747   GstFlowReturn res;
       
   748 
       
   749   GST_DEBUG_OBJECT (vd, "parsing header packet");
       
   750 
       
   751   /* Packetno = 0 if the first byte is exactly 0x01 */
       
   752   packet->b_o_s = (packet->packet[0] == 0x1) ? 1 : 0;
       
   753 
       
   754   if (vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet))
       
   755     goto header_read_error;
       
   756 
       
   757   switch (packet->packet[0]) {
       
   758     case 0x01:
       
   759       res = vorbis_handle_identification_packet (vd);
       
   760       break;
       
   761     case 0x03:
       
   762       res = vorbis_handle_comment_packet (vd, packet);
       
   763       break;
       
   764     case 0x05:
       
   765       res = vorbis_handle_type_packet (vd);
       
   766       break;
       
   767     default:
       
   768       /* ignore */
       
   769       g_warning ("unknown vorbis header packet found");
       
   770       res = GST_FLOW_OK;
       
   771       break;
       
   772   }
       
   773   return res;
       
   774 
       
   775   /* ERRORS */
       
   776 header_read_error:
       
   777   {
       
   778     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
       
   779         (NULL), ("couldn't read header packet"));
       
   780     return GST_FLOW_ERROR;
       
   781   }
       
   782 }
       
   783 
       
   784 /* These samples can be outside of the float -1.0 -- 1.0 range, this
       
   785  * is allowed, downstream elements are supposed to clip */
       
   786 static void
       
   787 copy_samples (float *out, float **in, guint samples, gint channels)
       
   788 {
       
   789   gint i, j;
       
   790 
       
   791 #ifdef GST_VORBIS_DEC_SEQUENTIAL
       
   792   for (i = 0; i < channels; i++) {
       
   793     memcpy (out, in[i], samples * sizeof (float));
       
   794     out += samples;
       
   795   }
       
   796 #else
       
   797   for (j = 0; j < samples; j++) {
       
   798     for (i = 0; i < channels; i++) {
       
   799       *out++ = in[i][j];
       
   800     }
       
   801   }
       
   802 #endif
       
   803 }
       
   804 
       
   805 static GstFlowReturn
       
   806 vorbis_dec_push_forward (GstVorbisDec * dec, GstBuffer * buf)
       
   807 {
       
   808   GstFlowReturn result;
       
   809   gint64 outoffset, origoffset;
       
   810 
       
   811   origoffset = GST_BUFFER_OFFSET (buf);
       
   812 
       
   813 again:
       
   814   outoffset = origoffset;
       
   815 
       
   816   if (outoffset == -1) {
       
   817     dec->queued = g_list_append (dec->queued, buf);
       
   818     GST_DEBUG_OBJECT (dec, "queued buffer");
       
   819     result = GST_FLOW_OK;
       
   820   } else {
       
   821     if (G_UNLIKELY (dec->queued)) {
       
   822       guint size;
       
   823       GstClockTime ts;
       
   824       GList *walk;
       
   825 
       
   826       GST_DEBUG_OBJECT (dec, "first buffer with offset %lld", outoffset);
       
   827       ts = gst_util_uint64_scale_int (outoffset, GST_SECOND, dec->vi.rate);
       
   828 
       
   829       size = g_list_length (dec->queued);
       
   830       /* we walk the queued up list in reverse, and set the buffer fields
       
   831        * calculating backwards */
       
   832       for (walk = g_list_last (dec->queued); walk;
       
   833           walk = g_list_previous (walk)) {
       
   834         GstBuffer *buffer = GST_BUFFER (walk->data);
       
   835         guint offset;
       
   836 
       
   837         offset = GST_BUFFER_SIZE (buffer) / (sizeof (float) * dec->vi.channels);
       
   838 
       
   839         if (outoffset >= offset)
       
   840           outoffset -= offset;
       
   841         else {
       
   842           /* we can't go below 0, this means this first offset was at the eos
       
   843            * page and we need to clip to it instead */
       
   844           GST_DEBUG_OBJECT (dec, "clipping %" G_GINT64_FORMAT,
       
   845               offset - outoffset);
       
   846           origoffset += (offset - outoffset);
       
   847           goto again;
       
   848         }
       
   849 
       
   850         GST_BUFFER_OFFSET (buffer) = outoffset;
       
   851         GST_BUFFER_TIMESTAMP (buffer) =
       
   852             gst_util_uint64_scale_int (outoffset, GST_SECOND, dec->vi.rate);
       
   853         GST_BUFFER_DURATION (buffer) = GST_CLOCK_DIFF (GST_BUFFER_TIMESTAMP
       
   854             (buffer), ts);
       
   855         ts = GST_BUFFER_TIMESTAMP (buffer);
       
   856         GST_DEBUG_OBJECT (dec, "patch buffer %u, offset %" G_GUINT64_FORMAT
       
   857             ", timestamp %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
       
   858             size, outoffset,
       
   859             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
       
   860             GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
       
   861         size--;
       
   862       }
       
   863       for (walk = dec->queued; walk; walk = g_list_next (walk)) {
       
   864         GstBuffer *buffer = GST_BUFFER (walk->data);
       
   865 
       
   866         /* clips to the configured segment, or returns NULL with buffer
       
   867          * unreffed when the input buffer is completely outside the segment */
       
   868         if (!(buffer = gst_audio_buffer_clip (buffer, &dec->segment,
       
   869                     dec->vi.rate, dec->vi.channels * sizeof (float))))
       
   870           continue;
       
   871 
       
   872         if (dec->discont) {
       
   873           GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
       
   874           dec->discont = FALSE;
       
   875         }
       
   876         /* ignore the result */
       
   877         gst_pad_push (dec->srcpad, buffer);
       
   878       }
       
   879       g_list_free (dec->queued);
       
   880       dec->queued = NULL;
       
   881     }
       
   882 
       
   883     /* clip */
       
   884     if (!(buf = gst_audio_buffer_clip (buf, &dec->segment, dec->vi.rate,
       
   885                 dec->vi.channels * sizeof (float))))
       
   886       return GST_FLOW_OK;
       
   887 
       
   888     if (dec->discont) {
       
   889       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
       
   890       dec->discont = FALSE;
       
   891     }
       
   892 
       
   893     result = gst_pad_push (dec->srcpad, buf);
       
   894   }
       
   895 
       
   896   return result;
       
   897 }
       
   898 
       
   899 static GstFlowReturn
       
   900 vorbis_dec_push_reverse (GstVorbisDec * dec, GstBuffer * buf)
       
   901 {
       
   902   GstFlowReturn result = GST_FLOW_OK;
       
   903 
       
   904   dec->queued = g_list_prepend (dec->queued, buf);
       
   905 
       
   906   return result;
       
   907 }
       
   908 
       
   909 static GstFlowReturn
       
   910 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet)
       
   911 {
       
   912   float **pcm;
       
   913   guint sample_count;
       
   914   GstBuffer *out;
       
   915   GstFlowReturn result;
       
   916   GstClockTime timestamp = GST_CLOCK_TIME_NONE, nextts;
       
   917   gint size;
       
   918 
       
   919   if (!vd->initialized)
       
   920     goto not_initialized;
       
   921 
       
   922   /* FIXME, we should queue undecoded packets here until we get
       
   923    * a timestamp, then we reverse timestamp the queued packets and
       
   924    * clip them, then we decode only the ones we want and don't
       
   925    * keep decoded data in memory.
       
   926    * Ideally, of course, the demuxer gives us a valid timestamp on
       
   927    * the first packet.
       
   928    */
       
   929 
       
   930   /* normal data packet */
       
   931   /* FIXME, we can skip decoding if the packet is outside of the
       
   932    * segment, this is however not very trivial as we need a previous
       
   933    * packet to decode the current one so we must be carefull not to
       
   934    * throw away too much. For now we decode everything and clip right
       
   935    * before pushing data. */
       
   936   if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
       
   937     goto could_not_read;
       
   938 
       
   939   if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0))
       
   940     goto not_accepted;
       
   941 
       
   942   /* assume all goes well here */
       
   943   result = GST_FLOW_OK;
       
   944 
       
   945   /* count samples ready for reading */
       
   946   if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0)
       
   947     goto done;
       
   948 
       
   949   GST_LOG_OBJECT (vd, "%d samples ready for reading", sample_count);
       
   950   size = sample_count * vd->vi.channels * sizeof (float);
       
   951 
       
   952   /* alloc buffer for it */
       
   953   result =
       
   954       gst_pad_alloc_buffer_and_set_caps (vd->srcpad, GST_BUFFER_OFFSET_NONE,
       
   955       size, GST_PAD_CAPS (vd->srcpad), &out);
       
   956   if (G_UNLIKELY (result != GST_FLOW_OK))
       
   957     goto done;
       
   958 
       
   959   /* get samples ready for reading now, should be sample_count */
       
   960   if (G_UNLIKELY ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count))
       
   961     goto wrong_samples;
       
   962 
       
   963   /* copy samples in buffer */
       
   964   copy_samples ((float *) GST_BUFFER_DATA (out), pcm, sample_count,
       
   965       vd->vi.channels);
       
   966 
       
   967   GST_BUFFER_SIZE (out) = size;
       
   968 
       
   969   /* this should not overflow */
       
   970   GST_BUFFER_DURATION (out) = sample_count * GST_SECOND / vd->vi.rate;
       
   971 
       
   972   if (packet->granulepos != -1)
       
   973     vd->granulepos = packet->granulepos - sample_count;
       
   974 
       
   975   if (vd->cur_timestamp != GST_CLOCK_TIME_NONE) {
       
   976     /* we have incoming timestamps */
       
   977     timestamp = vd->cur_timestamp;
       
   978     GST_DEBUG_OBJECT (vd,
       
   979         "cur_timestamp: %" GST_TIME_FORMAT " + %" GST_TIME_FORMAT " = %"
       
   980         GST_TIME_FORMAT, GST_TIME_ARGS (vd->cur_timestamp),
       
   981         GST_TIME_ARGS (GST_BUFFER_DURATION (out)),
       
   982         GST_TIME_ARGS (vd->cur_timestamp + GST_BUFFER_DURATION (out)));
       
   983     vd->cur_timestamp += GST_BUFFER_DURATION (out);
       
   984     GST_BUFFER_OFFSET (out) = GST_CLOCK_TIME_TO_FRAMES (vd->cur_timestamp,
       
   985         vd->vi.rate);
       
   986     GST_BUFFER_OFFSET_END (out) = GST_BUFFER_OFFSET (out) + sample_count;
       
   987   } else {
       
   988     /* we have incoming granulepos */
       
   989     GST_BUFFER_OFFSET (out) = vd->granulepos;
       
   990     if (vd->granulepos != -1) {
       
   991       GST_DEBUG_OBJECT (vd, "granulepos: %" G_GINT64_FORMAT, vd->granulepos);
       
   992       GST_BUFFER_OFFSET_END (out) = vd->granulepos + sample_count;
       
   993       timestamp =
       
   994           gst_util_uint64_scale_int (vd->granulepos, GST_SECOND, vd->vi.rate);
       
   995       nextts =
       
   996           gst_util_uint64_scale_int (vd->granulepos + sample_count,
       
   997           GST_SECOND, vd->vi.rate);
       
   998       GST_DEBUG_OBJECT (vd, "corresponding timestamp %" GST_TIME_FORMAT,
       
   999           GST_TIME_ARGS (timestamp));
       
  1000       /* calculate a nano-second accurate duration */
       
  1001       GST_BUFFER_DURATION (out) = GST_CLOCK_DIFF (timestamp, nextts);
       
  1002       GST_DEBUG_OBJECT (vd, "set duration %" GST_TIME_FORMAT,
       
  1003           GST_TIME_ARGS (GST_BUFFER_DURATION (out)));
       
  1004     } else {
       
  1005       timestamp = -1;
       
  1006     }
       
  1007   }
       
  1008   GST_BUFFER_TIMESTAMP (out) = timestamp;
       
  1009 
       
  1010   if (vd->granulepos != -1)
       
  1011     vd->granulepos += sample_count;
       
  1012 
       
  1013   if (vd->segment.rate >= 0.0)
       
  1014     result = vorbis_dec_push_forward (vd, out);
       
  1015   else
       
  1016     result = vorbis_dec_push_reverse (vd, out);
       
  1017 
       
  1018 done:
       
  1019   vorbis_synthesis_read (&vd->vd, sample_count);
       
  1020 
       
  1021   GST_DEBUG_OBJECT (vd,
       
  1022       "decoded %ld bytes into %d samples, ts %" GST_TIME_FORMAT, packet->bytes,
       
  1023       sample_count, GST_TIME_ARGS (timestamp));
       
  1024 
       
  1025   /* granulepos is the last sample in the packet */
       
  1026   if (packet->granulepos != -1)
       
  1027     vd->granulepos = packet->granulepos;
       
  1028 
       
  1029   return result;
       
  1030 
       
  1031   /* ERRORS */
       
  1032 not_initialized:
       
  1033   {
       
  1034     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
       
  1035         (NULL), ("no header sent yet"));
       
  1036     return GST_FLOW_ERROR;
       
  1037   }
       
  1038 could_not_read:
       
  1039   {
       
  1040     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
       
  1041         (NULL), ("couldn't read data packet"));
       
  1042     return GST_FLOW_ERROR;
       
  1043   }
       
  1044 not_accepted:
       
  1045   {
       
  1046     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
       
  1047         (NULL), ("vorbis decoder did not accept data packet"));
       
  1048     return GST_FLOW_ERROR;
       
  1049   }
       
  1050 wrong_samples:
       
  1051   {
       
  1052     gst_buffer_unref (out);
       
  1053     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
       
  1054         (NULL), ("vorbis decoder reported wrong number of samples"));
       
  1055     return GST_FLOW_ERROR;
       
  1056   }
       
  1057 }
       
  1058 
       
  1059 static GstFlowReturn
       
  1060 vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
       
  1061 {
       
  1062   ogg_packet packet;
       
  1063   GstFlowReturn result = GST_FLOW_OK;
       
  1064   GstClockTime timestamp;
       
  1065   guint64 offset_end;
       
  1066 
       
  1067   timestamp = GST_BUFFER_TIMESTAMP (buffer);
       
  1068   offset_end = GST_BUFFER_OFFSET_END (buffer);
       
  1069 
       
  1070   /* only ogg has granulepos, demuxers of other container formats 
       
  1071    * might provide us with timestamps instead (e.g. matroskademux) */
       
  1072   if (offset_end == GST_BUFFER_OFFSET_NONE && timestamp != GST_CLOCK_TIME_NONE) {
       
  1073     /* we might get multiple consecutive buffers with the same timestamp */
       
  1074     if (timestamp != vd->prev_timestamp) {
       
  1075       vd->cur_timestamp = timestamp;
       
  1076       vd->prev_timestamp = timestamp;
       
  1077     }
       
  1078   } else {
       
  1079     vd->cur_timestamp = GST_CLOCK_TIME_NONE;
       
  1080     vd->prev_timestamp = GST_CLOCK_TIME_NONE;
       
  1081   }
       
  1082 
       
  1083   /* make ogg_packet out of the buffer */
       
  1084   packet.packet = GST_BUFFER_DATA (buffer);
       
  1085   packet.bytes = GST_BUFFER_SIZE (buffer);
       
  1086   packet.granulepos = offset_end;
       
  1087   packet.packetno = 0;          /* we don't care */
       
  1088   /*
       
  1089    * FIXME. Is there anyway to know that this is the last packet and
       
  1090    * set e_o_s??
       
  1091    * Yes there is, keep one packet at all times and only push out when
       
  1092    * you receive a new one.  Implement this.
       
  1093    */
       
  1094   packet.e_o_s = 0;
       
  1095 
       
  1096   /* error out on empty header packets, but just skip empty data packets */
       
  1097   if (G_UNLIKELY (packet.bytes == 0)) {
       
  1098     if (vd->initialized)
       
  1099       goto empty_buffer;
       
  1100     else
       
  1101       goto empty_header;
       
  1102   }
       
  1103 
       
  1104   GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GINT64_FORMAT,
       
  1105       (gint64) packet.granulepos);
       
  1106 
       
  1107   /* switch depending on packet type */
       
  1108   if (packet.packet[0] & 1) {
       
  1109     if (vd->initialized) {
       
  1110       GST_WARNING_OBJECT (vd, "Already initialized, so ignoring header packet");
       
  1111       goto done;
       
  1112     }
       
  1113     result = vorbis_handle_header_packet (vd, &packet);
       
  1114   } else {
       
  1115     result = vorbis_handle_data_packet (vd, &packet);
       
  1116   }
       
  1117 
       
  1118 done:
       
  1119   return result;
       
  1120 
       
  1121 empty_buffer:
       
  1122   {
       
  1123     /* don't error out here, just ignore the buffer, it's invalid for vorbis
       
  1124      * but not fatal. */
       
  1125     GST_WARNING_OBJECT (vd, "empty buffer received, ignoring");
       
  1126     if (packet.granulepos != -1)
       
  1127       vd->granulepos = packet.granulepos;
       
  1128     result = GST_FLOW_OK;
       
  1129     goto done;
       
  1130   }
       
  1131 
       
  1132 /* ERRORS */
       
  1133 empty_header:
       
  1134   {
       
  1135     GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty header received"));
       
  1136     result = GST_FLOW_ERROR;
       
  1137     vd->discont = TRUE;
       
  1138     goto done;
       
  1139   }
       
  1140 }
       
  1141 
       
  1142 /* 
       
  1143  * Input:
       
  1144  *  Buffer decoding order:  7  8  9  4  5  6  3  1  2  EOS
       
  1145  *  Discont flag:           D        D        D  D
       
  1146  *
       
  1147  * - Each Discont marks a discont in the decoding order.
       
  1148  *
       
  1149  * for vorbis, each buffer is a keyframe when we have the previous
       
  1150  * buffer. This means that to decode buffer 7, we need buffer 6, which
       
  1151  * arrives out of order.
       
  1152  *
       
  1153  * we first gather buffers in the gather queue until we get a DISCONT. We 
       
  1154  * prepend each incomming buffer so that they are in reversed order.
       
  1155  *   
       
  1156  *    gather queue:    9  8  7
       
  1157  *    decode queue:    
       
  1158  *    output queue:    
       
  1159  *
       
  1160  * When a DISCONT is received (buffer 4), we move the gather queue to the 
       
  1161  * decode queue. This is simply done be taking the head of the gather queue
       
  1162  * and prepending it to the decode queue. This yields:
       
  1163  * 
       
  1164  *    gather queue:    
       
  1165  *    decode queue:    7  8  9
       
  1166  *    output queue:    
       
  1167  *
       
  1168  * Then we decode each buffer in the decode queue in order and put the output
       
  1169  * buffer in the output queue. The first buffer (7) will not produce and output
       
  1170  * because it needs the previous buffer (6) which did not arrive yet. This
       
  1171  * yields:
       
  1172  *
       
  1173  *    gather queue:    
       
  1174  *    decode queue:    7  8  9
       
  1175  *    output queue:    9  8
       
  1176  *
       
  1177  * Then we remove the consumed buffers from the decode queue. Buffer 7 is not
       
  1178  * completely consumed, we need to keep it around for when we receive buffer 
       
  1179  * 6. This yields:
       
  1180  *
       
  1181  *    gather queue:    
       
  1182  *    decode queue:    7 
       
  1183  *    output queue:    9  8
       
  1184  *
       
  1185  * Then we accumulate more buffers:
       
  1186  *
       
  1187  *    gather queue:    6  5  4
       
  1188  *    decode queue:    7
       
  1189  *    output queue:    
       
  1190  *
       
  1191  * prepending to the decode queue on DISCONT yields:
       
  1192  *
       
  1193  *    gather queue:   
       
  1194  *    decode queue:    4  5  6  7
       
  1195  *    output queue:    
       
  1196  *
       
  1197  * after decoding and keeping buffer 4:
       
  1198  *
       
  1199  *    gather queue:   
       
  1200  *    decode queue:    4 
       
  1201  *    output queue:    7  6  5 
       
  1202  *
       
  1203  * Etc..
       
  1204  */
       
  1205 static GstFlowReturn
       
  1206 vorbis_dec_flush_decode (GstVorbisDec * dec)
       
  1207 {
       
  1208   GstFlowReturn res = GST_FLOW_OK;
       
  1209   GList *walk;
       
  1210 
       
  1211   walk = dec->decode;
       
  1212 
       
  1213   GST_DEBUG_OBJECT (dec, "flushing buffers to decoder");
       
  1214 
       
  1215   while (walk) {
       
  1216     GList *next;
       
  1217     GstBuffer *buf = GST_BUFFER_CAST (walk->data);
       
  1218 
       
  1219     GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
       
  1220         buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
       
  1221 
       
  1222     next = g_list_next (walk);
       
  1223 
       
  1224     /* decode buffer, prepend to output queue */
       
  1225     res = vorbis_dec_decode_buffer (dec, buf);
       
  1226 
       
  1227     /* if we generated output, we can discard the buffer, else we
       
  1228      * keep it in the queue */
       
  1229     if (dec->queued) {
       
  1230       GST_DEBUG_OBJECT (dec, "decoded buffer to %p", dec->queued->data);
       
  1231       dec->decode = g_list_delete_link (dec->decode, walk);
       
  1232       gst_buffer_unref (buf);
       
  1233     } else {
       
  1234       GST_DEBUG_OBJECT (dec, "buffer did not decode, keeping");
       
  1235     }
       
  1236     walk = next;
       
  1237   }
       
  1238   if (dec->granulepos != -1) {
       
  1239     GstClockTime endts;
       
  1240 
       
  1241     endts =
       
  1242         gst_util_uint64_scale_int (dec->granulepos, GST_SECOND, dec->vi.rate);
       
  1243 
       
  1244     GST_DEBUG_OBJECT (dec, "we have granulepos %" G_GUINT64_FORMAT ", ts %"
       
  1245         GST_TIME_FORMAT, dec->granulepos, GST_TIME_ARGS (endts));
       
  1246 
       
  1247     while (dec->queued) {
       
  1248       GstBuffer *buf;
       
  1249       guint sample_count;
       
  1250 
       
  1251       buf = GST_BUFFER_CAST (dec->queued->data);
       
  1252 
       
  1253       sample_count =
       
  1254           GST_BUFFER_SIZE (buf) / (dec->vi.channels * sizeof (float));
       
  1255 
       
  1256       GST_BUFFER_OFFSET_END (buf) = dec->granulepos;
       
  1257       endts =
       
  1258           gst_util_uint64_scale_int (dec->granulepos, GST_SECOND, dec->vi.rate);
       
  1259       dec->granulepos -= sample_count;
       
  1260       GST_BUFFER_OFFSET (buf) = dec->granulepos;
       
  1261       GST_BUFFER_TIMESTAMP (buf) =
       
  1262           gst_util_uint64_scale_int (dec->granulepos, GST_SECOND, dec->vi.rate);
       
  1263       GST_BUFFER_DURATION (buf) = endts - GST_BUFFER_TIMESTAMP (buf);
       
  1264 
       
  1265       /* clip, this will unref the buffer in case of clipping */
       
  1266       if (!(buf = gst_audio_buffer_clip (buf, &dec->segment, dec->vi.rate,
       
  1267                   dec->vi.channels * sizeof (float)))) {
       
  1268         GST_DEBUG_OBJECT (dec, "clipped buffer %p", buf);
       
  1269         goto next;
       
  1270       }
       
  1271 
       
  1272       if (dec->discont) {
       
  1273         GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
       
  1274         dec->discont = FALSE;
       
  1275       }
       
  1276       GST_DEBUG_OBJECT (dec, "pushing buffer %p, samples %u, "
       
  1277           "ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT,
       
  1278           buf, sample_count, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
       
  1279           GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
       
  1280 
       
  1281       res = gst_pad_push (dec->srcpad, buf);
       
  1282     next:
       
  1283       dec->queued = g_list_delete_link (dec->queued, dec->queued);
       
  1284     }
       
  1285   } else {
       
  1286     GST_DEBUG_OBJECT (dec, "we don't have a granulepos yet, delayed push");
       
  1287   }
       
  1288   return res;
       
  1289 }
       
  1290 
       
  1291 static GstFlowReturn
       
  1292 vorbis_dec_chain_reverse (GstVorbisDec * vd, gboolean discont, GstBuffer * buf)
       
  1293 {
       
  1294   GstFlowReturn result = GST_FLOW_OK;
       
  1295 
       
  1296   /* if we have a discont, move buffers to the decode list */
       
  1297   if (G_UNLIKELY (discont)) {
       
  1298     GST_DEBUG_OBJECT (vd, "received discont");
       
  1299     while (vd->gather) {
       
  1300       GstBuffer *gbuf;
       
  1301 
       
  1302       gbuf = GST_BUFFER_CAST (vd->gather->data);
       
  1303       /* remove from the gather list */
       
  1304       vd->gather = g_list_delete_link (vd->gather, vd->gather);
       
  1305       /* copy to decode queue */
       
  1306       vd->decode = g_list_prepend (vd->decode, gbuf);
       
  1307     }
       
  1308     /* flush and decode the decode queue */
       
  1309     result = vorbis_dec_flush_decode (vd);
       
  1310   }
       
  1311 
       
  1312   GST_DEBUG_OBJECT (vd, "gathering buffer %p, size %u", buf,
       
  1313       GST_BUFFER_SIZE (buf));
       
  1314   /* add buffer to gather queue */
       
  1315   vd->gather = g_list_prepend (vd->gather, buf);
       
  1316 
       
  1317   return result;
       
  1318 }
       
  1319 
       
  1320 static GstFlowReturn
       
  1321 vorbis_dec_chain_forward (GstVorbisDec * vd, gboolean discont,
       
  1322     GstBuffer * buffer)
       
  1323 {
       
  1324   GstFlowReturn result;
       
  1325 
       
  1326   result = vorbis_dec_decode_buffer (vd, buffer);
       
  1327 
       
  1328   gst_buffer_unref (buffer);
       
  1329 
       
  1330   return result;
       
  1331 
       
  1332 }
       
  1333 
       
  1334 static GstFlowReturn
       
  1335 vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
       
  1336 {
       
  1337   GstVorbisDec *vd;
       
  1338   GstFlowReturn result = GST_FLOW_OK;
       
  1339   gboolean discont;
       
  1340 
       
  1341   vd = GST_VORBIS_DEC (gst_pad_get_parent (pad));
       
  1342 
       
  1343   discont = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT);
       
  1344 
       
  1345   /* resync on DISCONT */
       
  1346   if (G_UNLIKELY (discont)) {
       
  1347     GST_DEBUG_OBJECT (vd, "received DISCONT buffer");
       
  1348     vd->granulepos = -1;
       
  1349     vd->cur_timestamp = GST_CLOCK_TIME_NONE;
       
  1350     vd->prev_timestamp = GST_CLOCK_TIME_NONE;
       
  1351 #ifdef HAVE_VORBIS_SYNTHESIS_RESTART
       
  1352     vorbis_synthesis_restart (&vd->vd);
       
  1353 #endif
       
  1354     vd->discont = TRUE;
       
  1355   }
       
  1356 
       
  1357   if (vd->segment.rate >= 0.0)
       
  1358     result = vorbis_dec_chain_forward (vd, discont, buffer);
       
  1359   else
       
  1360     result = vorbis_dec_chain_reverse (vd, discont, buffer);
       
  1361 
       
  1362   gst_object_unref (vd);
       
  1363 
       
  1364   return result;
       
  1365 }
       
  1366 
       
  1367 static GstStateChangeReturn
       
  1368 vorbis_dec_change_state (GstElement * element, GstStateChange transition)
       
  1369 {
       
  1370   GstVorbisDec *vd = GST_VORBIS_DEC (element);
       
  1371   GstStateChangeReturn res;
       
  1372 
       
  1373   switch (transition) {
       
  1374     case GST_STATE_CHANGE_NULL_TO_READY:
       
  1375       break;
       
  1376     case GST_STATE_CHANGE_READY_TO_PAUSED:
       
  1377       vorbis_info_init (&vd->vi);
       
  1378       vorbis_comment_init (&vd->vc);
       
  1379       vd->initialized = FALSE;
       
  1380       gst_vorbis_dec_reset (vd);
       
  1381       break;
       
  1382     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       
  1383       break;
       
  1384     default:
       
  1385       break;
       
  1386   }
       
  1387 
       
  1388   res = parent_class->change_state (element, transition);
       
  1389 
       
  1390   switch (transition) {
       
  1391     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       
  1392       break;
       
  1393     case GST_STATE_CHANGE_PAUSED_TO_READY:
       
  1394       GST_DEBUG_OBJECT (vd, "PAUSED -> READY, clearing vorbis structures");
       
  1395       vorbis_block_clear (&vd->vb);
       
  1396       vorbis_dsp_clear (&vd->vd);
       
  1397       vorbis_comment_clear (&vd->vc);
       
  1398       vorbis_info_clear (&vd->vi);
       
  1399       gst_vorbis_dec_reset (vd);
       
  1400       break;
       
  1401     case GST_STATE_CHANGE_READY_TO_NULL:
       
  1402       break;
       
  1403     default:
       
  1404       break;
       
  1405   }
       
  1406 
       
  1407   return res;
       
  1408 }