]> git.sesse.net Git - vlc/blob - modules/codec/vorbis.c
* modules/codec/vorbis.c: added 5.1 channel configuration to the decoder.
[vlc] / modules / codec / vorbis.c
1 /*****************************************************************************
2  * vorbis.c: vorbis decoder/encoder/packetizer module making use of libvorbis.
3  *****************************************************************************
4  * Copyright (C) 2001-2003 VideoLAN
5  * $Id: vorbis.c,v 1.27 2003/12/15 21:54:55 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc/decoder.h>
29
30 #include <ogg/ogg.h>
31
32 #ifdef MODULE_NAME_IS_tremor
33 #include <tremor/ivorbiscodec.h>
34
35 #else
36 #include <vorbis/codec.h>
37
38 /* vorbis header */
39 #ifdef HAVE_VORBIS_VORBISENC_H
40 #   include <vorbis/vorbisenc.h>
41 #   ifndef OV_ECTL_RATEMANAGE_AVG
42 #       define OV_ECTL_RATEMANAGE_AVG 0x0
43 #   endif
44 #endif
45
46 #endif
47
48 /*****************************************************************************
49  * decoder_sys_t : vorbis decoder descriptor
50  *****************************************************************************/
51 struct decoder_sys_t
52 {
53     /* Module mode */
54     vlc_bool_t b_packetizer;
55
56     /*
57      * Input properties
58      */
59     int i_headers;
60
61     /*
62      * Vorbis properties
63      */
64     vorbis_info      vi; /* struct that stores all the static vorbis bitstream
65                             settings */
66     vorbis_comment   vc; /* struct that stores all the bitstream user
67                           * comments */
68     vorbis_dsp_state vd; /* central working state for the packet->PCM
69                           * decoder */
70     vorbis_block     vb; /* local working space for packet->PCM decode */
71
72     /*
73      * Common properties
74      */
75     audio_date_t end_date;
76     int          i_last_block_size;
77
78 };
79
80 static int pi_channels_maps[7] =
81 {
82     0,
83     AOUT_CHAN_CENTER,
84     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
85     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
86     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
87      | AOUT_CHAN_REARRIGHT,
88     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
89      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
90     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
91      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE
92 };
93
94 /****************************************************************************
95  * Local prototypes
96  ****************************************************************************/
97 static int  OpenDecoder   ( vlc_object_t * );
98 static int  OpenPacketizer( vlc_object_t * );
99 static void CloseDecoder  ( vlc_object_t * );
100 static void *DecodeBlock  ( decoder_t *, block_t ** );
101
102 static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
103
104 static aout_buffer_t *DecodePacket  ( decoder_t *, ogg_packet * );
105 static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
106
107 static void ParseVorbisComments( decoder_t * );
108
109 #ifdef MODULE_NAME_IS_tremor
110 static void Interleave   ( int32_t *, const int32_t **, int, int );
111 #else
112 static void Interleave   ( float *, const float **, int, int );
113 #endif
114
115 #ifndef MODULE_NAME_IS_tremor
116 static int OpenEncoder   ( vlc_object_t * );
117 static void CloseEncoder ( vlc_object_t * );
118 static block_t *Headers  ( encoder_t * );
119 static block_t *Encode   ( encoder_t *, aout_buffer_t * );
120 #endif
121
122 /*****************************************************************************
123  * Module descriptor
124  *****************************************************************************/
125 vlc_module_begin();
126
127     set_description( _("Vorbis audio decoder") );
128 #ifdef MODULE_NAME_IS_tremor
129     set_capability( "decoder", 90 );
130 #else
131     set_capability( "decoder", 100 );
132 #endif
133     set_callbacks( OpenDecoder, CloseDecoder );
134
135     add_submodule();
136     set_description( _("Vorbis audio packetizer") );
137     set_capability( "packetizer", 100 );
138     set_callbacks( OpenPacketizer, CloseDecoder );
139
140 #ifndef MODULE_NAME_IS_tremor
141     add_submodule();
142     set_description( _("Vorbis audio encoder") );
143     set_capability( "encoder", 100 );
144     set_callbacks( OpenEncoder, CloseEncoder );
145 #endif
146
147 vlc_module_end();
148
149 /*****************************************************************************
150  * OpenDecoder: probe the decoder and return score
151  *****************************************************************************/
152 static int OpenDecoder( vlc_object_t *p_this )
153 {
154     decoder_t *p_dec = (decoder_t*)p_this;
155     decoder_sys_t *p_sys;
156
157     if( p_dec->fmt_in.i_codec != VLC_FOURCC('v','o','r','b') )
158     {
159         return VLC_EGENERIC;
160     }
161
162     /* Allocate the memory needed to store the decoder's structure */
163     if( ( p_dec->p_sys = p_sys =
164           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
165     {
166         msg_Err( p_dec, "out of memory" );
167         return VLC_EGENERIC;
168     }
169
170     /* Misc init */
171     aout_DateSet( &p_sys->end_date, 0 );
172     p_sys->b_packetizer = VLC_FALSE;
173     p_sys->i_headers = 0;
174
175     /* Take care of vorbis init */
176     vorbis_info_init( &p_sys->vi );
177     vorbis_comment_init( &p_sys->vc );
178
179     /* Set output properties */
180     p_dec->fmt_out.i_cat = AUDIO_ES;
181 #ifdef MODULE_NAME_IS_tremor
182     p_dec->fmt_out.i_codec = VLC_FOURCC('f','i','3','2');
183 #else
184     p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
185 #endif
186
187     /* Set callbacks */
188     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
189         DecodeBlock;
190     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
191         DecodeBlock;
192
193     return VLC_SUCCESS;
194 }
195
196 static int OpenPacketizer( vlc_object_t *p_this )
197 {
198     decoder_t *p_dec = (decoder_t*)p_this;
199
200     int i_ret = OpenDecoder( p_this );
201
202     if( i_ret == VLC_SUCCESS )
203     {
204         p_dec->p_sys->b_packetizer = VLC_TRUE;
205         p_dec->fmt_out.i_codec = VLC_FOURCC('v','o','r','b');
206     }
207
208     return i_ret;
209 }
210
211 /****************************************************************************
212  * DecodeBlock: the whole thing
213  ****************************************************************************
214  * This function must be fed with ogg packets.
215  ****************************************************************************/
216 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
217 {
218     decoder_sys_t *p_sys = p_dec->p_sys;
219     ogg_packet oggpacket;
220
221     if( !pp_block ) return NULL;
222
223     if( *pp_block )
224     {
225         /* Block to Ogg packet */
226         oggpacket.packet = (*pp_block)->p_buffer;
227         oggpacket.bytes = (*pp_block)->i_buffer;
228     }
229     else
230     {
231         if( p_sys->b_packetizer ) return NULL;
232
233         /* Block to Ogg packet */
234         oggpacket.packet = NULL;
235         oggpacket.bytes = 0;
236     }
237
238     oggpacket.granulepos = -1;
239     oggpacket.b_o_s = 0;
240     oggpacket.e_o_s = 0;
241     oggpacket.packetno = 0;
242
243     if( p_sys->i_headers == 0 )
244     {
245         /* Take care of the initial Vorbis header */
246
247         oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
248         if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc,
249                                        &oggpacket ) < 0 )
250         {
251             msg_Err( p_dec, "This bitstream does not contain Vorbis "
252                      "audio data");
253             block_Release( *pp_block );
254             return NULL;
255         }
256         p_sys->i_headers++;
257
258         /* Setup the format */
259         p_dec->fmt_out.audio.i_rate     = p_sys->vi.rate;
260         p_dec->fmt_out.audio.i_channels = p_sys->vi.channels;
261         p_dec->fmt_out.audio.i_physical_channels =
262             p_dec->fmt_out.audio.i_original_channels =
263                 pi_channels_maps[p_sys->vi.channels];
264         p_dec->fmt_out.i_bitrate = p_sys->vi.bitrate_nominal;
265
266         aout_DateInit( &p_sys->end_date, p_sys->vi.rate );
267
268         msg_Dbg( p_dec, "channels:%d samplerate:%ld bitrate:%ld",
269                  p_sys->vi.channels, p_sys->vi.rate,
270                  p_sys->vi.bitrate_nominal );
271
272         return ProcessPacket( p_dec, &oggpacket, pp_block );
273     }
274
275     if( p_sys->i_headers == 1 )
276     {
277         /* The next packet in order is the comments header */
278         if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket )
279             < 0 )
280         {
281             msg_Err( p_dec, "2nd Vorbis header is corrupted" );
282             block_Release( *pp_block );
283             return NULL;
284         }
285         p_sys->i_headers++;
286     
287         ParseVorbisComments( p_dec );
288
289         return ProcessPacket( p_dec, &oggpacket, pp_block );
290     }
291
292     if( p_sys->i_headers == 2 )
293     {
294         /* The next packet in order is the codebooks header
295            We need to watch out that this packet is not missing as a
296            missing or corrupted header is fatal. */
297         if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket )
298             < 0 )
299         {
300             msg_Err( p_dec, "3rd Vorbis header is corrupted" );
301             block_Release( *pp_block );
302             return NULL;
303         }
304         p_sys->i_headers++;
305     
306         if( !p_sys->b_packetizer )
307         {
308             /* Initialize the Vorbis packet->PCM decoder */
309             vorbis_synthesis_init( &p_sys->vd, &p_sys->vi );
310             vorbis_block_init( &p_sys->vd, &p_sys->vb );
311         }
312
313         return ProcessPacket( p_dec, &oggpacket, pp_block );
314     }
315
316     return ProcessPacket( p_dec, &oggpacket, pp_block );
317 }
318
319 /*****************************************************************************
320  * ProcessPacket: processes a Vorbis packet.
321  *****************************************************************************/
322 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
323                             block_t **pp_block )
324 {
325     decoder_sys_t *p_sys = p_dec->p_sys;
326     block_t *p_block = *pp_block;
327
328     /* Date management */
329     if( p_block && p_block->i_pts > 0 &&
330         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
331     {
332         aout_DateSet( &p_sys->end_date, p_block->i_pts );
333     }
334
335     if( !aout_DateGet( &p_sys->end_date ) )
336     {
337         /* We've just started the stream, wait for the first PTS. */
338         if( p_block ) block_Release( p_block );
339         return NULL;
340     }
341
342     *pp_block = NULL; /* To avoid being fed the same packet again */
343
344     if( p_sys->b_packetizer )
345     {
346         return SendPacket( p_dec, p_oggpacket, p_block );
347     }
348     else
349     {
350         aout_buffer_t *p_aout_buffer;
351
352         if( p_sys->i_headers >= 3 )
353             p_aout_buffer = DecodePacket( p_dec, p_oggpacket );
354         else
355             p_aout_buffer = NULL;
356
357         if( p_block )
358         {
359             block_Release( p_block );
360         }
361         return p_aout_buffer;
362     }
363 }
364
365 /*****************************************************************************
366  * DecodePacket: decodes a Vorbis packet.
367  *****************************************************************************/
368 static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
369 {
370     decoder_sys_t *p_sys = p_dec->p_sys;
371     int           i_samples;
372
373 #ifdef MODULE_NAME_IS_tremor
374     int32_t       **pp_pcm;
375 #else
376     float         **pp_pcm;
377 #endif
378
379     if( p_oggpacket->bytes &&
380         vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
381         vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb );
382
383     /* **pp_pcm is a multichannel float vector. In stereo, for
384      * example, pp_pcm[0] is left, and pp_pcm[1] is right. i_samples is
385      * the size of each channel. Convert the float values
386      * (-1.<=range<=1.) to whatever PCM format and write it out */
387
388     if( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
389     {
390
391         aout_buffer_t *p_aout_buffer;
392
393         p_aout_buffer =
394             p_dec->pf_aout_buffer_new( p_dec, i_samples );
395
396         if( p_aout_buffer == NULL ) return NULL;
397
398         /* Interleave the samples */
399 #ifdef MODULE_NAME_IS_tremor
400         Interleave( (int32_t *)p_aout_buffer->p_buffer,
401                     (const int32_t **)pp_pcm, p_sys->vi.channels, i_samples );
402 #else
403         Interleave( (float *)p_aout_buffer->p_buffer,
404                     (const float **)pp_pcm, p_sys->vi.channels, i_samples );
405 #endif
406
407         /* Tell libvorbis how many samples we actually consumed */
408         vorbis_synthesis_read( &p_sys->vd, i_samples );
409
410         /* Date management */
411         p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
412         p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
413                                                       i_samples );
414         return p_aout_buffer;
415     }
416     else
417     {
418         return NULL;
419     }
420 }
421
422 /*****************************************************************************
423  * SendPacket: send an ogg dated packet to the stream output.
424  *****************************************************************************/
425 static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
426                             block_t *p_block )
427 {
428     decoder_sys_t *p_sys = p_dec->p_sys;
429     int i_block_size, i_samples;
430
431     i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket );
432     if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
433     i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
434     p_sys->i_last_block_size = i_block_size;
435
436     /* Date management */
437     p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
438
439     if( p_sys->i_headers >= 3 )
440         p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) -
441             p_block->i_pts;
442     else
443         p_block->i_length = 0;
444
445     return p_block;
446 }
447
448 /*****************************************************************************
449  * ParseVorbisComments: FIXME should be done in demuxer
450  *****************************************************************************/
451 static void ParseVorbisComments( decoder_t *p_dec )
452 {
453     input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
454     input_info_category_t *p_cat =
455         input_InfoCategory( p_input, _("Vorbis Comment") );
456     int i = 0;
457     char *psz_name, *psz_value, *psz_comment;
458     while ( i < p_dec->p_sys->vc.comments )
459     {
460         psz_comment = strdup( p_dec->p_sys->vc.user_comments[i] );
461         if( !psz_comment )
462         {
463             msg_Warn( p_dec, "Out of memory" );
464             break;
465         }
466         psz_name = psz_comment;
467         psz_value = strchr( psz_comment, '=' );
468         if( psz_value )
469         {
470             *psz_value = '\0';
471             psz_value++;
472             input_AddInfo( p_cat, psz_name, psz_value );
473         }
474         free( psz_comment );
475         i++;
476     }
477 }
478
479 /*****************************************************************************
480  * Interleave: helper function to interleave channels
481  *****************************************************************************/
482 #ifdef MODULE_NAME_IS_tremor
483 static void Interleave( int32_t *p_out, const int32_t **pp_in,
484 #else
485 static void Interleave( float *p_out, const float **pp_in,
486 #endif
487                         int i_nb_channels, int i_samples )
488 {
489     int i, j;
490
491     for ( j = 0; j < i_samples; j++ )
492     {
493         for ( i = 0; i < i_nb_channels; i++ )
494         {
495             p_out[j * i_nb_channels + i] = pp_in[i][j];
496         }
497     }
498 }
499
500 /*****************************************************************************
501  * CloseDecoder: vorbis decoder destruction
502  *****************************************************************************/
503 static void CloseDecoder( vlc_object_t *p_this )
504 {
505     decoder_t *p_dec = (decoder_t *)p_this;
506     decoder_sys_t *p_sys = p_dec->p_sys;
507
508     if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
509     {
510         vorbis_block_clear( &p_sys->vb );
511         vorbis_dsp_clear( &p_sys->vd );
512     }
513
514     vorbis_comment_clear( &p_sys->vc );
515     vorbis_info_clear( &p_sys->vi );  /* must be called last */
516
517     free( p_sys );
518 }
519
520 #if defined(HAVE_VORBIS_VORBISENC_H) && !defined(MODULE_NAME_IS_tremor)
521
522 /*****************************************************************************
523  * encoder_sys_t : theora encoder descriptor
524  *****************************************************************************/
525 struct encoder_sys_t
526 {
527     /*
528      * Input properties
529      */
530     int i_headers;
531
532     /*
533      * Vorbis properties
534      */
535     vorbis_info      vi; /* struct that stores all the static vorbis bitstream
536                             settings */
537     vorbis_comment   vc; /* struct that stores all the bitstream user
538                           * comments */
539     vorbis_dsp_state vd; /* central working state for the packet->PCM
540                           * decoder */
541     vorbis_block     vb; /* local working space for packet->PCM decode */
542
543     int i_last_block_size;
544     int i_samples_delay;
545     int i_channels;
546
547     /*
548      * Common properties
549      */
550     mtime_t i_pts;
551 };
552
553 /*****************************************************************************
554  * OpenEncoder: probe the encoder and return score
555  *****************************************************************************/
556 static int OpenEncoder( vlc_object_t *p_this )
557 {
558     encoder_t *p_enc = (encoder_t *)p_this;
559     encoder_sys_t *p_sys;
560
561     if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') )
562     {
563         return VLC_EGENERIC;
564     }
565
566     /* Allocate the memory needed to store the decoder's structure */
567     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
568     {
569         msg_Err( p_enc, "out of memory" );
570         return VLC_EGENERIC;
571     }
572     p_enc->p_sys = p_sys;
573
574     p_enc->pf_header = Headers;
575     p_enc->pf_encode_audio = Encode;
576     p_enc->fmt_in.i_codec = VLC_FOURCC('f','l','3','2');
577
578     /* Initialize vorbis encoder */
579     vorbis_info_init( &p_sys->vi );
580
581     if( vorbis_encode_setup_managed( &p_sys->vi,
582             p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate,
583             -1, p_enc->fmt_out.i_bitrate, -1 ) ||
584         vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
585         vorbis_encode_setup_init( &p_sys->vi ) ){}
586
587     /* add a comment */
588     vorbis_comment_init( &p_sys->vc);
589     vorbis_comment_add_tag( &p_sys->vc, "ENCODER", "VLC media player");
590
591     /* set up the analysis state and auxiliary encoding storage */
592     vorbis_analysis_init( &p_sys->vd, &p_sys->vi );
593     vorbis_block_init( &p_sys->vd, &p_sys->vb );
594
595     p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
596     p_sys->i_last_block_size = 0;
597     p_sys->i_samples_delay = 0;
598     p_sys->i_headers = 0;
599     p_sys->i_pts = 0;
600
601     return VLC_SUCCESS;
602 }
603
604 /****************************************************************************
605  * Encode: the whole thing
606  ****************************************************************************
607  * This function spits out ogg packets.
608  ****************************************************************************/
609 static block_t *Headers( encoder_t *p_enc )
610 {
611     encoder_sys_t *p_sys = p_enc->p_sys;
612     block_t *p_block, *p_chain = NULL;
613
614     /* Create theora headers */
615     if( !p_sys->i_headers )
616     {
617         ogg_packet header[3];
618         int i;
619
620         vorbis_analysis_headerout( &p_sys->vd, &p_sys->vc,
621                                    &header[0], &header[1], &header[2]);
622         for( i = 0; i < 3; i++ )
623         {
624             p_block = block_New( p_enc, header[i].bytes );
625             memcpy( p_block->p_buffer, header[i].packet, header[i].bytes );
626
627             p_block->i_dts = p_block->i_pts = p_block->i_length = 0;
628
629             block_ChainAppend( &p_chain, p_block );
630         }
631         p_sys->i_headers = 3;
632     }
633
634     return p_chain;
635 }
636
637 /****************************************************************************
638  * Encode: the whole thing
639  ****************************************************************************
640  * This function spits out ogg packets.
641  ****************************************************************************/
642 static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
643 {
644     encoder_sys_t *p_sys = p_enc->p_sys;
645     ogg_packet oggpacket;
646     block_t *p_block, *p_chain = NULL;
647     float **buffer;
648     int i;
649     unsigned int j;
650
651     p_sys->i_pts = p_aout_buf->start_date -
652                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
653                 (mtime_t)p_enc->fmt_in.audio.i_rate;
654
655     p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
656
657     buffer = vorbis_analysis_buffer( &p_sys->vd, p_aout_buf->i_nb_samples );
658
659     /* convert samples to float and uninterleave */
660     for( i = 0; i < p_sys->i_channels; i++ )
661     {
662         for( j = 0 ; j < p_aout_buf->i_nb_samples ; j++ )
663         {
664             buffer[i][j]= ((float)( ((int16_t *)p_aout_buf->p_buffer )
665                                     [j * p_sys->i_channels + i ] )) / 32768.f;
666         }
667     }
668
669     vorbis_analysis_wrote( &p_sys->vd, p_aout_buf->i_nb_samples );
670
671     while( vorbis_analysis_blockout( &p_sys->vd, &p_sys->vb ) == 1 )
672     {
673         int i_samples;
674
675         vorbis_analysis( &p_sys->vb, NULL );
676         vorbis_bitrate_addblock( &p_sys->vb );
677
678         while( vorbis_bitrate_flushpacket( &p_sys->vd, &oggpacket ) )
679         {
680             int i_block_size;
681             p_block = block_New( p_enc, oggpacket.bytes );
682             memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
683
684             i_block_size = vorbis_packet_blocksize( &p_sys->vi, &oggpacket );
685
686             if( i_block_size < 0 ) i_block_size = 0;
687             i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
688             p_sys->i_last_block_size = i_block_size;
689
690             p_block->i_length = (mtime_t)1000000 *
691                 (mtime_t)i_samples / (mtime_t)p_enc->fmt_in.audio.i_rate;
692
693             p_block->i_dts = p_block->i_pts = p_sys->i_pts;
694
695             p_sys->i_samples_delay -= i_samples;
696
697             /* Update pts */
698             p_sys->i_pts += p_block->i_length;
699             block_ChainAppend( &p_chain, p_block );
700         }
701     }
702
703     return p_chain;
704 }
705
706 /*****************************************************************************
707  * CloseEncoder: theora encoder destruction
708  *****************************************************************************/
709 static void CloseEncoder( vlc_object_t *p_this )
710 {
711     encoder_t *p_enc = (encoder_t *)p_this;
712     encoder_sys_t *p_sys = p_enc->p_sys;
713
714     vorbis_block_clear( &p_sys->vb );
715     vorbis_dsp_clear( &p_sys->vd );
716     vorbis_comment_clear( &p_sys->vc );
717     vorbis_info_clear( &p_sys->vi );  /* must be called last */
718
719     free( p_sys );
720 }
721
722 #endif /* HAVE_VORBIS_VORBISENC_H && !MODULE_NAME_IS_tremor */