Add hack to make the flac plugin compile with both flac-1.0.2 and 1.0.3
[platform/upstream/gst-plugins-good.git] / ext / flac / gstflacdec.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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 #include <string.h>
21 #include <sys/soundcard.h>
22
23 /*#define DEBUG_ENABLED */
24 #include "gstflacdec.h"
25
26 #include "flac_compat.h"
27
28 extern GstPadTemplate *gst_flacdec_src_template, *gst_flacdec_sink_template;
29
30 /* elementfactory information */
31 GstElementDetails flacdec_details = {
32   "FLAC decoder",
33   "Codec/Audio/Decoder",
34   "LGPL",
35   "Decodes FLAC lossless audio streams",
36   VERSION,
37   "Wim Taymans <wim.taymans@chello.be>",
38   "(C) 2001",
39 };
40
41 /* FlacDec signals and args */
42 enum {
43   /* FILL ME */
44   LAST_SIGNAL
45 };
46
47 enum {
48   ARG_0,
49 };
50
51 static void             gst_flacdec_class_init          (FlacDecClass *klass);
52 static void             gst_flacdec_init                (FlacDec *flacdec);
53
54 static void             gst_flacdec_loop                (GstElement *element);
55 static GstElementStateReturn
56                         gst_flacdec_change_state        (GstElement *element);
57 static const GstFormat* gst_flacdec_get_src_formats     (GstPad *pad);
58 static gboolean         gst_flacdec_convert_src         (GstPad *pad, GstFormat src_format, gint64 src_value,
59                                                          GstFormat *dest_format, gint64 *dest_value);
60 static const GstPadQueryType* 
61                         gst_flacdec_get_src_query_types (GstPad *pad);
62 static gboolean         gst_flacdec_src_query           (GstPad *pad, GstPadQueryType type,
63                                                          GstFormat *format, gint64 *value);
64 static const GstEventMask* 
65                         gst_flacdec_get_src_event_masks (GstPad *pad);
66 static gboolean         gst_flacdec_src_event           (GstPad *pad, GstEvent *event);
67
68 static FLAC__SeekableStreamDecoderReadStatus    
69                         gst_flacdec_read                (const FLAC__SeekableStreamDecoder *decoder, 
70                                                          FLAC__byte buffer[], unsigned *bytes, 
71                                                          void *client_data);
72 static FLAC__SeekableStreamDecoderSeekStatus    
73                         gst_flacdec_seek                (const FLAC__SeekableStreamDecoder *decoder, 
74                                                          FLAC__uint64 position, void *client_data);
75 static FLAC__SeekableStreamDecoderTellStatus    
76                         gst_flacdec_tell                (const FLAC__SeekableStreamDecoder *decoder, 
77                                                          FLAC__uint64 *position, void *client_data);
78 static FLAC__SeekableStreamDecoderLengthStatus  
79                         gst_flacdec_length              (const FLAC__SeekableStreamDecoder *decoder, 
80                                                          FLAC__uint64 *length, void *client_data);
81 static FLAC__bool       gst_flacdec_eof                 (const FLAC__SeekableStreamDecoder *decoder, 
82                                                          void *client_data);
83 static FLAC__StreamDecoderWriteStatus   
84                         gst_flacdec_write               (const FLAC__SeekableStreamDecoder *decoder, 
85                                                          const FLAC__Frame *frame, 
86                                                          const FLAC__int32 * const buffer[], 
87                                                          void *client_data);
88 static void             gst_flacdec_metadata_callback   (const FLAC__SeekableStreamDecoder *decoder, 
89                                                          const FLAC__StreamMetadata *metadata, 
90                                                          void *client_data);
91 static void             gst_flacdec_error_callback      (const FLAC__SeekableStreamDecoder *decoder, 
92                                                          FLAC__StreamDecoderErrorStatus status, 
93                                                          void *client_data);
94
95 static GstElementClass *parent_class = NULL;
96 /*static guint gst_flacdec_signals[LAST_SIGNAL] = { 0 }; */
97
98 GType
99 flacdec_get_type(void) {
100   static GType flacdec_type = 0;
101
102   if (!flacdec_type) {
103     static const GTypeInfo flacdec_info = {
104       sizeof(FlacDecClass),
105       NULL,
106       NULL,
107       (GClassInitFunc)gst_flacdec_class_init,
108       NULL,
109       NULL,
110       sizeof(FlacDec),
111       0,
112       (GInstanceInitFunc)gst_flacdec_init,
113     };
114     flacdec_type = g_type_register_static (GST_TYPE_ELEMENT, "FlacDec", &flacdec_info, 0);
115   }
116   return flacdec_type;
117 }
118
119 static void
120 gst_flacdec_class_init (FlacDecClass *klass) 
121 {
122   GstElementClass *gstelement_class;
123
124   gstelement_class = (GstElementClass*)klass;
125
126   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
127
128   gstelement_class->change_state = gst_flacdec_change_state;
129 }
130
131 static void 
132 gst_flacdec_init (FlacDec *flacdec) 
133 {
134   flacdec->sinkpad = gst_pad_new_from_template (gst_flacdec_sink_template, "sink");
135   gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->sinkpad);
136   gst_pad_set_convert_function (flacdec->sinkpad, NULL);
137
138   gst_element_set_loop_function (GST_ELEMENT (flacdec), gst_flacdec_loop);
139   flacdec->srcpad = gst_pad_new_from_template (gst_flacdec_src_template, "src");
140   gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->srcpad);
141   gst_pad_set_formats_function (flacdec->srcpad, gst_flacdec_get_src_formats);
142   gst_pad_set_convert_function (flacdec->srcpad, gst_flacdec_convert_src);
143   gst_pad_set_query_type_function (flacdec->srcpad, gst_flacdec_get_src_query_types);
144   gst_pad_set_query_function (flacdec->srcpad, gst_flacdec_src_query);
145   gst_pad_set_event_mask_function (flacdec->srcpad, gst_flacdec_get_src_event_masks);
146   gst_pad_set_event_function (flacdec->srcpad, gst_flacdec_src_event);
147
148   flacdec->decoder = FLAC__seekable_stream_decoder_new ();
149   flacdec->total_samples = 0;
150   flacdec->init = TRUE;
151   flacdec->eos = FALSE;
152   flacdec->seek_pending = FALSE;
153
154   FLAC__seekable_stream_decoder_set_read_callback (flacdec->decoder, gst_flacdec_read);
155   FLAC__seekable_stream_decoder_set_seek_callback (flacdec->decoder, gst_flacdec_seek);
156   FLAC__seekable_stream_decoder_set_tell_callback (flacdec->decoder, gst_flacdec_tell);
157   FLAC__seekable_stream_decoder_set_length_callback (flacdec->decoder, gst_flacdec_length);
158   FLAC__seekable_stream_decoder_set_eof_callback (flacdec->decoder, gst_flacdec_eof);
159 #if FLAC_VERSION >= 0x010003
160   FLAC__seekable_stream_decoder_set_write_callback (flacdec->decoder, gst_flacdec_write);
161 #else
162   FLAC__seekable_stream_decoder_set_write_callback (flacdec->decoder,
163         (FLAC__StreamDecoderWriteStatus (*)
164                 (const FLAC__SeekableStreamDecoder *decoder, 
165                  const FLAC__Frame *frame,
166                  const FLAC__int32 *buffer[], 
167                  void *client_data))
168                 (gst_flacdec_write));
169 #endif
170   FLAC__seekable_stream_decoder_set_metadata_callback (flacdec->decoder, gst_flacdec_metadata_callback);
171   FLAC__seekable_stream_decoder_set_error_callback (flacdec->decoder, gst_flacdec_error_callback);
172   FLAC__seekable_stream_decoder_set_client_data (flacdec->decoder, flacdec);
173 }
174
175 static void 
176 gst_flacdec_metadata_callback (const FLAC__SeekableStreamDecoder *decoder,
177                                const FLAC__StreamMetadata *metadata, void *client_data)
178 {
179   FlacDec *flacdec;
180
181   flacdec = GST_FLACDEC (client_data);
182
183   flacdec->stream_samples = metadata->data.stream_info.total_samples;
184 }
185
186 static void 
187 gst_flacdec_error_callback (const FLAC__SeekableStreamDecoder *decoder, 
188                             FLAC__StreamDecoderErrorStatus status, void *client_data)
189 {
190   FlacDec *flacdec;
191   gchar *error;
192
193   flacdec = GST_FLACDEC (client_data);
194
195   switch (status) {
196     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
197       error = "lost sync";
198       break;
199     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
200       error = "bad header";
201       break;
202     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
203       error = "CRC mismatch";
204       break;
205     default:
206       error = "unkown error";
207       break;
208   }
209
210   GST_DEBUG (0, error);
211                                   
212   gst_element_error (GST_ELEMENT (flacdec), error);
213 }
214
215 static FLAC__SeekableStreamDecoderSeekStatus    
216 gst_flacdec_seek (const FLAC__SeekableStreamDecoder *decoder, 
217                   FLAC__uint64 position, void *client_data)
218 {
219   FlacDec *flacdec;
220
221   flacdec = GST_FLACDEC (client_data);
222
223   GST_DEBUG (0, "seek %lld\n", position);
224   if (!gst_bytestream_seek (flacdec->bs, position, GST_SEEK_METHOD_SET)) {
225     return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
226   }
227   return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
228 }
229
230 static FLAC__SeekableStreamDecoderTellStatus    
231 gst_flacdec_tell (const FLAC__SeekableStreamDecoder *decoder, 
232                   FLAC__uint64 *position, void *client_data)
233 {
234   FlacDec *flacdec;
235
236   flacdec = GST_FLACDEC (client_data);
237
238   *position = gst_bytestream_tell (flacdec->bs);
239   if (*position == -1)
240     return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
241
242   GST_DEBUG (0, "tell %lld\n", *position);
243
244   return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
245 }
246
247 static FLAC__SeekableStreamDecoderLengthStatus  
248 gst_flacdec_length (const FLAC__SeekableStreamDecoder *decoder, 
249                     FLAC__uint64 *length, void *client_data)
250 {
251   FlacDec *flacdec;
252
253   flacdec = GST_FLACDEC (client_data);
254
255   *length = gst_bytestream_length (flacdec->bs);
256   if (*length == -1)
257     return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
258
259   GST_DEBUG (0, "length %lld\n", *length);
260
261   return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
262 }
263
264 static FLAC__bool
265 gst_flacdec_eof (const FLAC__SeekableStreamDecoder *decoder, 
266                  void *client_data)
267 {
268   FlacDec *flacdec;
269
270   flacdec = GST_FLACDEC (client_data);
271   GST_DEBUG (0, "eof %d\n", flacdec->eos);
272
273   return flacdec->eos;
274 }
275
276 static FLAC__SeekableStreamDecoderReadStatus
277 gst_flacdec_read (const FLAC__SeekableStreamDecoder *decoder, 
278                   FLAC__byte buffer[], unsigned *bytes, 
279                   void *client_data)
280 {
281   FlacDec *flacdec;
282   gint insize = 0;
283   guint8 *indata;
284
285   flacdec = GST_FLACDEC (client_data);
286
287   //g_print ("read %u\n", *bytes);
288   
289   while (insize == 0) {
290     insize = gst_bytestream_peek_bytes (flacdec->bs, &indata, *bytes);
291     if (insize < *bytes) {
292       GstEvent *event;
293       guint32 avail;
294                             
295       gst_bytestream_get_status (flacdec->bs, &avail, &event);
296
297       switch (GST_EVENT_TYPE (event)) {
298         case GST_EVENT_EOS:
299           GST_DEBUG (0, "eos");
300           flacdec->eos = TRUE; 
301           gst_event_unref (event);
302           if (avail == 0) {
303             return 0;
304           }
305           break;
306         case GST_EVENT_DISCONTINUOUS:
307           GST_DEBUG (0, "discont");
308
309           /* we are not yet sending the discont, we'll do that in the next write operation */
310           flacdec->need_discont = TRUE;
311           gst_event_unref (event);
312           break;
313         default:
314           gst_pad_event_default (flacdec->sinkpad, event);
315           break;
316       }
317       if (avail > 0)
318         insize = gst_bytestream_peek_bytes (flacdec->bs, &indata, avail);
319       else
320         insize = 0;
321     }
322   }
323
324   memcpy (buffer, indata, insize);
325   *bytes = insize;
326   gst_bytestream_flush_fast (flacdec->bs, insize);
327
328   return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
329 }
330
331 static FLAC__StreamDecoderWriteStatus
332 gst_flacdec_write (const FLAC__SeekableStreamDecoder *decoder, 
333                    const FLAC__Frame *frame, 
334                    const FLAC__int32 * const buffer[], 
335                    void *client_data)
336 {
337   FlacDec *flacdec;
338   GstBuffer *outbuf;
339   guint depth = frame->header.bits_per_sample;
340   guint channels = frame->header.channels;
341   guint samples = frame->header.blocksize;
342   guint j, i;
343
344   flacdec = GST_FLACDEC (client_data);
345
346   if (flacdec->need_discont) {
347     gint64 time = 0, bytes = 0;
348     GstFormat format;
349     GstEvent *discont;
350
351     flacdec->need_discont = FALSE;
352
353     if (flacdec->seek_pending) {
354       flacdec->total_samples = flacdec->seek_value;
355     }
356
357     GST_DEBUG (0, "send discont");
358
359     format = GST_FORMAT_TIME;
360     gst_pad_convert (flacdec->srcpad, GST_FORMAT_UNITS, flacdec->total_samples,
361                   &format, &time);
362     format = GST_FORMAT_BYTES;
363     gst_pad_convert (flacdec->srcpad, GST_FORMAT_UNITS, flacdec->total_samples,
364                   &format, &bytes);
365     discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
366                                          GST_FORMAT_BYTES, bytes,
367                                          GST_FORMAT_UNITS, flacdec->total_samples, 
368                                          NULL);
369           
370     gst_pad_push (flacdec->srcpad, GST_BUFFER (discont));
371   }
372   
373   if (!GST_PAD_CAPS (flacdec->srcpad)) {
374     gst_pad_try_set_caps (flacdec->srcpad,
375                     GST_CAPS_NEW (
376                       "flac_caps",
377                       "audio/raw",
378                         "format",       GST_PROPS_STRING ("int"),
379                          "law",         GST_PROPS_INT (0),
380                          "endianness",  GST_PROPS_INT (G_BYTE_ORDER),
381                          "signed",      GST_PROPS_BOOLEAN (TRUE),
382                          "width",       GST_PROPS_INT (depth),
383                          "depth",       GST_PROPS_INT (depth),
384                          "rate",        GST_PROPS_INT (frame->header.sample_rate),
385                          "channels",    GST_PROPS_INT (channels)
386                     ));
387
388     flacdec->depth = depth;
389     flacdec->channels = channels;
390     flacdec->frequency = frame->header.sample_rate;
391   }
392
393   outbuf = gst_buffer_new ();
394   GST_BUFFER_SIZE (outbuf) = samples * channels * ((depth+7)>>3);
395   GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
396   GST_BUFFER_TIMESTAMP (outbuf) = flacdec->total_samples * GST_SECOND / frame->header.sample_rate;
397
398   if (depth == 8) {
399     guint8 *outbuffer = (guint8 *)GST_BUFFER_DATA (outbuf);
400
401     for (i=0; i<samples; i++) {
402       for (j=0; j < channels; j++) {
403         *outbuffer++ = (guint8) buffer[j][i];
404       }
405     }
406   }
407   else if (depth == 16) {
408     guint16 *outbuffer = (guint16 *)GST_BUFFER_DATA (outbuf);
409
410     for (i=0; i<samples; i++) {
411       for (j=0; j < channels; j++) {
412         *outbuffer++ = (guint16) buffer[j][i];
413       }
414     }
415   }
416   else {
417     g_warning ("flacdec: invalid depth %d found\n", depth);
418     return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
419   }
420
421   flacdec->total_samples += samples;
422
423   gst_pad_push (flacdec->srcpad, outbuf);
424
425   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
426 }
427
428 static void 
429 gst_flacdec_loop (GstElement *element) 
430 {
431   FlacDec *flacdec;
432   gboolean res;
433
434   flacdec = GST_FLACDEC (element);
435
436   if (flacdec->init) {
437     FLAC__seekable_stream_decoder_init (flacdec->decoder);
438     FLAC__seekable_stream_decoder_process_metadata (flacdec->decoder);
439     flacdec->init = FALSE;
440   }
441
442   if (flacdec->seek_pending) {
443     GST_DEBUG (GST_CAT_EVENT, "perform seek to sample %lld\n", 
444                               flacdec->seek_value);
445
446     if (FLAC__seekable_stream_decoder_seek_absolute (flacdec->decoder, 
447                                                      flacdec->seek_value)) 
448     {
449       flacdec->total_samples = flacdec->seek_value;
450       GST_DEBUG (GST_CAT_EVENT, "seek done\n");
451     }
452     else {
453       GST_DEBUG (GST_CAT_EVENT, "seek failed\n");
454     }
455     flacdec->seek_pending = FALSE;
456   }
457
458   res = FLAC__seekable_stream_decoder_process_one_frame (flacdec->decoder);
459   if (FLAC__seekable_stream_decoder_get_state (flacdec->decoder) == 
460                   FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) 
461   {
462     GstEvent *event;
463
464     FLAC__seekable_stream_decoder_finish(flacdec->decoder);
465     flacdec->init = TRUE;
466
467     event = gst_event_new(GST_EVENT_EOS);
468     gst_pad_push (flacdec->srcpad, GST_BUFFER (event));
469     gst_element_set_eos (element);
470   }
471 }
472
473 GST_FORMATS_FUNCTION (gst_flacdec_get_src_formats,
474   GST_FORMAT_UNITS,
475   GST_FORMAT_BYTES,
476   GST_FORMAT_TIME
477 )
478
479 static gboolean
480 gst_flacdec_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
481                          GstFormat *dest_format, gint64 *dest_value)
482 {
483   gboolean res = TRUE;
484   FlacDec *flacdec = GST_FLACDEC (gst_pad_get_parent (pad));
485   guint scale = 1;
486   gint bytes_per_sample;
487
488   bytes_per_sample = flacdec->channels * ((flacdec->depth+7)>>3);
489
490   switch (src_format) {
491     case GST_FORMAT_BYTES:
492       switch (*dest_format) {
493         case GST_FORMAT_UNITS:
494           if (bytes_per_sample == 0)
495             return FALSE;
496           *dest_value = src_value / bytes_per_sample;
497           break;
498         case GST_FORMAT_DEFAULT:
499           *dest_format = GST_FORMAT_TIME;
500         case GST_FORMAT_TIME:
501         {
502           gint byterate = bytes_per_sample * flacdec->frequency;
503
504           if (byterate == 0)
505             return FALSE;
506           *dest_value = src_value * GST_SECOND / byterate;
507           break;
508         }
509         default:
510           res = FALSE;
511       }
512       break;
513     case GST_FORMAT_UNITS:
514       switch (*dest_format) {
515         case GST_FORMAT_BYTES:
516           *dest_value = src_value * bytes_per_sample;
517           break;
518         case GST_FORMAT_DEFAULT:
519           *dest_format = GST_FORMAT_TIME;
520         case GST_FORMAT_TIME:
521           if (flacdec->frequency == 0)
522             return FALSE;
523           *dest_value = src_value * GST_SECOND / flacdec->frequency;
524           break;
525         default:
526           res = FALSE;
527       }
528       break;
529     case GST_FORMAT_TIME:
530       switch (*dest_format) {
531         case GST_FORMAT_DEFAULT:
532           *dest_format = GST_FORMAT_BYTES;
533         case GST_FORMAT_BYTES:
534           scale = bytes_per_sample;
535         case GST_FORMAT_UNITS:
536           *dest_value = src_value * scale * flacdec->frequency / GST_SECOND;
537           break;
538         default:
539           res = FALSE;
540       }
541       break;
542     default:
543       res = FALSE;
544   }
545   return res;
546 }
547
548 GST_PAD_QUERY_TYPE_FUNCTION (gst_flacdec_get_src_query_types,
549   GST_PAD_QUERY_TOTAL,
550   GST_PAD_QUERY_POSITION
551 )
552
553 static gboolean
554 gst_flacdec_src_query (GstPad *pad, GstPadQueryType type,
555                        GstFormat *format, gint64 *value)
556 {
557   gboolean res = TRUE;
558   FlacDec *flacdec = GST_FLACDEC (gst_pad_get_parent (pad));
559
560   switch (type) {
561     case GST_PAD_QUERY_TOTAL:
562     {
563       guint64 samples;
564
565       if (flacdec->stream_samples == 0)
566         samples = flacdec->total_samples;
567       else
568         samples = flacdec->stream_samples;
569
570       gst_pad_convert (flacdec->srcpad, 
571                        GST_FORMAT_UNITS, 
572                        samples, 
573                        format, value);
574       break;
575     }
576     case GST_PAD_QUERY_POSITION:
577       gst_pad_convert (flacdec->srcpad, 
578                        GST_FORMAT_UNITS, 
579                        flacdec->total_samples, 
580                        format, value);
581       break;
582     default:
583       res = FALSE;
584       break;
585   }
586
587   return res;
588 }
589           
590 GST_EVENT_MASK_FUNCTION (gst_flacdec_get_src_event_masks,
591     { GST_EVENT_SEEK, GST_SEEK_FLAG_ACCURATE }
592 );
593
594 static gboolean
595 gst_flacdec_src_event (GstPad *pad, GstEvent *event)
596
597   gboolean res = TRUE;
598   FlacDec *flacdec = GST_FLACDEC (gst_pad_get_parent (pad));
599   GstFormat format;
600
601   switch (GST_EVENT_TYPE (event)) {
602     case GST_EVENT_SEEK:
603       format = GST_FORMAT_UNITS;
604
605       if (gst_pad_convert (flacdec->srcpad, 
606                            GST_EVENT_SEEK_FORMAT (event), 
607                            GST_EVENT_SEEK_OFFSET (event), 
608                            &format, &flacdec->seek_value))
609         flacdec->seek_pending = TRUE;
610       else
611         res = FALSE;
612       break;
613     default:
614       res = FALSE;
615       break;
616   }
617   gst_event_unref (event);
618   return res;
619 }
620
621 static GstElementStateReturn
622 gst_flacdec_change_state (GstElement *element)
623 {
624   FlacDec *flacdec = GST_FLACDEC (element);
625
626   switch (GST_STATE_TRANSITION (element)) {
627     case GST_STATE_NULL_TO_READY:
628     case GST_STATE_READY_TO_PAUSED:
629       flacdec->bs = gst_bytestream_new (flacdec->sinkpad);
630       flacdec->seek_pending = FALSE;
631       flacdec->total_samples = 0;
632       flacdec->init = TRUE;
633       flacdec->eos = FALSE;
634       break;
635     case GST_STATE_PAUSED_TO_PLAYING:
636       flacdec->eos = FALSE;
637     case GST_STATE_PLAYING_TO_PAUSED:
638       break;
639     case GST_STATE_PAUSED_TO_READY:
640       gst_bytestream_destroy (flacdec->bs);
641       break;
642     case GST_STATE_READY_TO_NULL:
643     default:
644       break;
645   }
646
647   if (GST_ELEMENT_CLASS (parent_class)->change_state)
648     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
649
650   return GST_STATE_SUCCESS;
651 }
652