]> git.sesse.net Git - vlc/blob - modules/codec/vorbis.c
* modules/codec/vorbis.c: VBR encoding is now the default + added a cbr option.
[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$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
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 #include <vlc/input.h>
30 #include <vlc/sout.h>
31
32 #include <ogg/ogg.h>
33
34 #ifdef MODULE_NAME_IS_tremor
35 #include <tremor/ivorbiscodec.h>
36
37 #else
38 #include <vorbis/codec.h>
39
40 /* vorbis header */
41 #ifdef HAVE_VORBIS_VORBISENC_H
42 #   include <vorbis/vorbisenc.h>
43 #   ifndef OV_ECTL_RATEMANAGE_AVG
44 #       define OV_ECTL_RATEMANAGE_AVG 0x0
45 #   endif
46 #endif
47
48 #endif
49
50 /*****************************************************************************
51  * decoder_sys_t : vorbis decoder descriptor
52  *****************************************************************************/
53 struct decoder_sys_t
54 {
55     /* Module mode */
56     vlc_bool_t b_packetizer;
57
58     /*
59      * Input properties
60      */
61     int i_headers;
62
63     /*
64      * Vorbis properties
65      */
66     vorbis_info      vi; /* struct that stores all the static vorbis bitstream
67                             settings */
68     vorbis_comment   vc; /* struct that stores all the bitstream user
69                           * comments */
70     vorbis_dsp_state vd; /* central working state for the packet->PCM
71                           * decoder */
72     vorbis_block     vb; /* local working space for packet->PCM decode */
73
74     /*
75      * Common properties
76      */
77     audio_date_t end_date;
78     int          i_last_block_size;
79
80 };
81
82 static int pi_channels_maps[7] =
83 {
84     0,
85     AOUT_CHAN_CENTER,
86     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
87     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
88     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
89      | AOUT_CHAN_REARRIGHT,
90     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
91      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
92     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
93      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE
94 };
95
96 /****************************************************************************
97  * Local prototypes
98  ****************************************************************************/
99 static int  OpenDecoder   ( vlc_object_t * );
100 static int  OpenPacketizer( vlc_object_t * );
101 static void CloseDecoder  ( vlc_object_t * );
102 static void *DecodeBlock  ( decoder_t *, block_t ** );
103
104 static int  ProcessHeaders( decoder_t * );
105 static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
106
107 static aout_buffer_t *DecodePacket  ( decoder_t *, ogg_packet * );
108 static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
109
110 static void ParseVorbisComments( decoder_t * );
111
112 #ifdef MODULE_NAME_IS_tremor
113 static void Interleave   ( int32_t *, const int32_t **, int, int );
114 #else
115 static void Interleave   ( float *, const float **, int, int );
116 #endif
117
118 #ifndef MODULE_NAME_IS_tremor
119 static int OpenEncoder   ( vlc_object_t * );
120 static void CloseEncoder ( vlc_object_t * );
121 static block_t *Encode   ( encoder_t *, aout_buffer_t * );
122 #endif
123
124 /*****************************************************************************
125  * Module descriptor
126  *****************************************************************************/
127 #define ENC_QUALITY_TEXT N_("Encoding quality")
128 #define ENC_QUALITY_LONGTEXT N_( \
129   "Allows you to specify a quality between 1 (low) and 10 (high), instead " \
130   "of specifying a particular bitrate. This will produce a VBR stream." )
131 #define ENC_MAXBR_TEXT N_("Maximum encoding bitrate")
132 #define ENC_MAXBR_LONGTEXT N_( \
133   "Allows you to specify a maximum bitrate in kbps. " \
134   "Useful for streaming applications." )
135 #define ENC_MINBR_TEXT N_("Minimum encoding bitrate")
136 #define ENC_MINBR_LONGTEXT N_( \
137   "Allows you to specify a minimum bitrate in kbps. " \
138   "Useful for encoding for a fixed-size channel." )
139 #define ENC_CBR_TEXT N_("CBR encoding")
140 #define ENC_CBR_LONGTEXT N_( \
141   "Allows you to force a constant bitrate encoding (CBR)." )
142
143 vlc_module_begin();
144
145     set_description( _("Vorbis audio decoder") );
146 #ifdef MODULE_NAME_IS_tremor
147     set_capability( "decoder", 90 );
148 #else
149     set_capability( "decoder", 100 );
150 #endif
151     set_callbacks( OpenDecoder, CloseDecoder );
152
153     add_submodule();
154     set_description( _("Vorbis audio packetizer") );
155     set_capability( "packetizer", 100 );
156     set_callbacks( OpenPacketizer, CloseDecoder );
157
158 #ifndef MODULE_NAME_IS_tremor
159 #   define ENC_CFG_PREFIX "sout-vorbis-"
160     add_submodule();
161     set_description( _("Vorbis audio encoder") );
162     set_capability( "encoder", 100 );
163     set_callbacks( OpenEncoder, CloseEncoder );
164
165     add_integer( ENC_CFG_PREFIX "quality", 3, NULL, ENC_QUALITY_TEXT,
166                  ENC_QUALITY_LONGTEXT, VLC_FALSE );
167     add_integer( ENC_CFG_PREFIX "max-bitrate", 0, NULL, ENC_MAXBR_TEXT,
168                  ENC_MAXBR_LONGTEXT, VLC_FALSE );
169     add_integer( ENC_CFG_PREFIX "min-bitrate", 0, NULL, ENC_MINBR_TEXT,
170                  ENC_MINBR_LONGTEXT, VLC_FALSE );
171     add_bool( ENC_CFG_PREFIX "cbr", 0, NULL, ENC_CBR_TEXT,
172                  ENC_CBR_LONGTEXT, VLC_FALSE );
173 #endif
174
175 vlc_module_end();
176
177 #ifndef MODULE_NAME_IS_tremor
178 static const char *ppsz_enc_options[] = {
179     "quality", "max-bitrate", "min-bitrate", "cbr", NULL
180 };
181 #endif
182
183 /*****************************************************************************
184  * OpenDecoder: probe the decoder and return score
185  *****************************************************************************/
186 static int OpenDecoder( vlc_object_t *p_this )
187 {
188     decoder_t *p_dec = (decoder_t*)p_this;
189     decoder_sys_t *p_sys;
190
191     if( p_dec->fmt_in.i_codec != VLC_FOURCC('v','o','r','b') )
192     {
193         return VLC_EGENERIC;
194     }
195
196     /* Allocate the memory needed to store the decoder's structure */
197     if( ( p_dec->p_sys = p_sys =
198           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
199     {
200         msg_Err( p_dec, "out of memory" );
201         return VLC_EGENERIC;
202     }
203
204     /* Misc init */
205     aout_DateSet( &p_sys->end_date, 0 );
206     p_sys->b_packetizer = VLC_FALSE;
207     p_sys->i_headers = 0;
208
209     /* Take care of vorbis init */
210     vorbis_info_init( &p_sys->vi );
211     vorbis_comment_init( &p_sys->vc );
212
213     /* Set output properties */
214     p_dec->fmt_out.i_cat = AUDIO_ES;
215 #ifdef MODULE_NAME_IS_tremor
216     p_dec->fmt_out.i_codec = VLC_FOURCC('f','i','3','2');
217 #else
218     p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
219 #endif
220
221     /* Set callbacks */
222     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
223         DecodeBlock;
224     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
225         DecodeBlock;
226
227     return VLC_SUCCESS;
228 }
229
230 static int OpenPacketizer( vlc_object_t *p_this )
231 {
232     decoder_t *p_dec = (decoder_t*)p_this;
233
234     int i_ret = OpenDecoder( p_this );
235
236     if( i_ret == VLC_SUCCESS )
237     {
238         p_dec->p_sys->b_packetizer = VLC_TRUE;
239         p_dec->fmt_out.i_codec = VLC_FOURCC('v','o','r','b');
240     }
241
242     return i_ret;
243 }
244
245 /****************************************************************************
246  * DecodeBlock: the whole thing
247  ****************************************************************************
248  * This function must be fed with ogg packets.
249  ****************************************************************************/
250 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
251 {
252     decoder_sys_t *p_sys = p_dec->p_sys;
253     ogg_packet oggpacket;
254
255     if( !pp_block ) return NULL;
256
257     if( *pp_block )
258     {
259         /* Block to Ogg packet */
260         oggpacket.packet = (*pp_block)->p_buffer;
261         oggpacket.bytes = (*pp_block)->i_buffer;
262     }
263     else
264     {
265         if( p_sys->b_packetizer ) return NULL;
266
267         /* Block to Ogg packet */
268         oggpacket.packet = NULL;
269         oggpacket.bytes = 0;
270     }
271
272     oggpacket.granulepos = -1;
273     oggpacket.b_o_s = 0;
274     oggpacket.e_o_s = 0;
275     oggpacket.packetno = 0;
276
277     /* Check for headers */
278     if( p_sys->i_headers == 0 && p_dec->fmt_in.i_extra )
279     {
280         /* Headers already available as extra data */
281         p_sys->i_headers = 3;
282     }
283     else if( oggpacket.bytes && p_sys->i_headers < 3 )
284     {
285         /* Backup headers as extra data */
286         uint8_t *p_extra;
287
288         p_dec->fmt_in.p_extra =
289             realloc( p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra +
290                      oggpacket.bytes + 2 );
291         p_extra = p_dec->fmt_in.p_extra + p_dec->fmt_in.i_extra;
292         *(p_extra++) = oggpacket.bytes >> 8;
293         *(p_extra++) = oggpacket.bytes & 0xFF;
294
295         memcpy( p_extra, oggpacket.packet, oggpacket.bytes );
296         p_dec->fmt_in.i_extra += oggpacket.bytes + 2;
297
298         block_Release( *pp_block );
299         p_sys->i_headers++;
300         return NULL;
301     }
302
303     if( p_sys->i_headers == 3 )
304     {
305         if( ProcessHeaders( p_dec ) != VLC_SUCCESS )
306         {
307             p_sys->i_headers = 0;
308             p_dec->fmt_in.i_extra = 0;
309             block_Release( *pp_block );
310             return NULL;
311         }
312         else p_sys->i_headers++;
313     }
314
315     return ProcessPacket( p_dec, &oggpacket, pp_block );
316 }
317
318 /*****************************************************************************
319  * ProcessHeaders: process Vorbis headers.
320  *****************************************************************************/
321 static int ProcessHeaders( decoder_t *p_dec )
322 {
323     decoder_sys_t *p_sys = p_dec->p_sys;
324     ogg_packet oggpacket;
325     uint8_t *p_extra;
326     int i_extra;
327
328     if( !p_dec->fmt_in.i_extra ) return VLC_EGENERIC;
329
330     oggpacket.granulepos = -1;
331     oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
332     oggpacket.e_o_s = 0;
333     oggpacket.packetno = 0;
334     p_extra = p_dec->fmt_in.p_extra;
335     i_extra = p_dec->fmt_in.i_extra;
336
337     /* Take care of the initial Vorbis header */
338     oggpacket.bytes = *(p_extra++) << 8;
339     oggpacket.bytes |= (*(p_extra++) & 0xFF);
340     oggpacket.packet = p_extra;
341     p_extra += oggpacket.bytes;
342     i_extra -= (oggpacket.bytes + 2);
343     if( i_extra < 0 )
344     {
345         msg_Err( p_dec, "header data corrupted");
346         return VLC_EGENERIC;
347     }
348
349     if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 )
350     {
351         msg_Err( p_dec, "this bitstream does not contain Vorbis audio data");
352         return VLC_EGENERIC;
353     }
354
355     /* Setup the format */
356     p_dec->fmt_out.audio.i_rate     = p_sys->vi.rate;
357     p_dec->fmt_out.audio.i_channels = p_sys->vi.channels;
358     p_dec->fmt_out.audio.i_physical_channels =
359         p_dec->fmt_out.audio.i_original_channels =
360             pi_channels_maps[p_sys->vi.channels];
361     p_dec->fmt_out.i_bitrate = p_sys->vi.bitrate_nominal;
362
363     aout_DateInit( &p_sys->end_date, p_sys->vi.rate );
364     aout_DateSet( &p_sys->end_date, 0 );
365
366     msg_Dbg( p_dec, "channels:%d samplerate:%ld bitrate:%ld",
367              p_sys->vi.channels, p_sys->vi.rate, p_sys->vi.bitrate_nominal );
368
369     /* The next packet in order is the comments header */
370     oggpacket.b_o_s = 0;
371     oggpacket.bytes = *(p_extra++) << 8;
372     oggpacket.bytes |= (*(p_extra++) & 0xFF);
373     oggpacket.packet = p_extra;
374     p_extra += oggpacket.bytes;
375     i_extra -= (oggpacket.bytes + 2);
376     if( i_extra < 0 )
377     {
378         msg_Err( p_dec, "header data corrupted");
379         return VLC_EGENERIC;
380     }
381
382     if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 )
383     {
384         msg_Err( p_dec, "2nd Vorbis header is corrupted" );
385         return VLC_EGENERIC;
386     }
387     ParseVorbisComments( p_dec );
388
389     /* The next packet in order is the codebooks header
390      * We need to watch out that this packet is not missing as a
391      * missing or corrupted header is fatal. */
392     oggpacket.bytes = *(p_extra++) << 8;
393     oggpacket.bytes |= (*(p_extra++) & 0xFF);
394     oggpacket.packet = p_extra;
395     i_extra -= (oggpacket.bytes + 2);
396     if( i_extra < 0 )
397     {
398         msg_Err( p_dec, "header data corrupted");
399         return VLC_EGENERIC;
400     }
401
402     if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 )
403     {
404         msg_Err( p_dec, "3rd Vorbis header is corrupted" );
405         return VLC_EGENERIC;
406     }
407
408     if( !p_sys->b_packetizer )
409     {
410         /* Initialize the Vorbis packet->PCM decoder */
411         vorbis_synthesis_init( &p_sys->vd, &p_sys->vi );
412         vorbis_block_init( &p_sys->vd, &p_sys->vb );
413     }
414     else
415     {
416         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
417         p_dec->fmt_out.p_extra =
418             realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
419         memcpy( p_dec->fmt_out.p_extra,
420                 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
421     }
422
423     return VLC_SUCCESS;
424 }
425
426 /*****************************************************************************
427  * ProcessPacket: processes a Vorbis packet.
428  *****************************************************************************/
429 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
430                             block_t **pp_block )
431 {
432     decoder_sys_t *p_sys = p_dec->p_sys;
433     block_t *p_block = *pp_block;
434
435     /* Date management */
436     if( p_block && p_block->i_pts > 0 &&
437         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
438     {
439         aout_DateSet( &p_sys->end_date, p_block->i_pts );
440     }
441
442     if( !aout_DateGet( &p_sys->end_date ) )
443     {
444         /* We've just started the stream, wait for the first PTS. */
445         if( p_block ) block_Release( p_block );
446         return NULL;
447     }
448
449     *pp_block = NULL; /* To avoid being fed the same packet again */
450
451     if( p_sys->b_packetizer )
452     {
453         return SendPacket( p_dec, p_oggpacket, p_block );
454     }
455     else
456     {
457         aout_buffer_t *p_aout_buffer;
458
459         if( p_sys->i_headers >= 3 )
460             p_aout_buffer = DecodePacket( p_dec, p_oggpacket );
461         else
462             p_aout_buffer = NULL;
463
464         if( p_block ) block_Release( p_block );
465         return p_aout_buffer;
466     }
467 }
468
469 /*****************************************************************************
470  * DecodePacket: decodes a Vorbis packet.
471  *****************************************************************************/
472 static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
473 {
474     decoder_sys_t *p_sys = p_dec->p_sys;
475     int           i_samples;
476
477 #ifdef MODULE_NAME_IS_tremor
478     int32_t       **pp_pcm;
479 #else
480     float         **pp_pcm;
481 #endif
482
483     if( p_oggpacket->bytes &&
484         vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
485         vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb );
486
487     /* **pp_pcm is a multichannel float vector. In stereo, for
488      * example, pp_pcm[0] is left, and pp_pcm[1] is right. i_samples is
489      * the size of each channel. Convert the float values
490      * (-1.<=range<=1.) to whatever PCM format and write it out */
491
492     if( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
493     {
494
495         aout_buffer_t *p_aout_buffer;
496
497         p_aout_buffer =
498             p_dec->pf_aout_buffer_new( p_dec, i_samples );
499
500         if( p_aout_buffer == NULL ) return NULL;
501
502         /* Interleave the samples */
503 #ifdef MODULE_NAME_IS_tremor
504         Interleave( (int32_t *)p_aout_buffer->p_buffer,
505                     (const int32_t **)pp_pcm, p_sys->vi.channels, i_samples );
506 #else
507         Interleave( (float *)p_aout_buffer->p_buffer,
508                     (const float **)pp_pcm, p_sys->vi.channels, i_samples );
509 #endif
510
511         /* Tell libvorbis how many samples we actually consumed */
512         vorbis_synthesis_read( &p_sys->vd, i_samples );
513
514         /* Date management */
515         p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
516         p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
517                                                       i_samples );
518         return p_aout_buffer;
519     }
520     else
521     {
522         return NULL;
523     }
524 }
525
526 /*****************************************************************************
527  * SendPacket: send an ogg dated packet to the stream output.
528  *****************************************************************************/
529 static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
530                             block_t *p_block )
531 {
532     decoder_sys_t *p_sys = p_dec->p_sys;
533     int i_block_size, i_samples;
534
535     i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket );
536     if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
537     i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
538     p_sys->i_last_block_size = i_block_size;
539
540     /* Date management */
541     p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
542
543     if( p_sys->i_headers >= 3 )
544         p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) -
545             p_block->i_pts;
546     else
547         p_block->i_length = 0;
548
549     return p_block;
550 }
551
552 /*****************************************************************************
553  * ParseVorbisComments: FIXME should be done in demuxer
554  *****************************************************************************/
555 static void ParseVorbisComments( decoder_t *p_dec )
556 {
557     input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
558     char *psz_name, *psz_value, *psz_comment;
559     int i = 0;
560
561     if( p_input->i_object_type != VLC_OBJECT_INPUT ) return;
562
563     while( i < p_dec->p_sys->vc.comments )
564     {
565         psz_comment = strdup( p_dec->p_sys->vc.user_comments[i] );
566         if( !psz_comment )
567         {
568             msg_Warn( p_dec, "out of memory" );
569             break;
570         }
571         psz_name = psz_comment;
572         psz_value = strchr( psz_comment, '=' );
573         if( psz_value )
574         {
575             *psz_value = '\0';
576             psz_value++;
577             input_Control( p_input, INPUT_ADD_INFO, _("Vorbis comment"),
578                            psz_name, psz_value );
579         }
580         free( psz_comment );
581         i++;
582     }
583 }
584
585 /*****************************************************************************
586  * Interleave: helper function to interleave channels
587  *****************************************************************************/
588 static void Interleave(
589 #ifdef MODULE_NAME_IS_tremor
590                         int32_t *p_out, const int32_t **pp_in,
591 #else
592                         float *p_out, const float **pp_in,
593 #endif
594                         int i_nb_channels, int i_samples )
595 {
596     int i, j;
597
598     for ( j = 0; j < i_samples; j++ )
599     {
600         for ( i = 0; i < i_nb_channels; i++ )
601         {
602             p_out[j * i_nb_channels + i] = pp_in[i][j];
603         }
604     }
605 }
606
607 /*****************************************************************************
608  * CloseDecoder: vorbis decoder destruction
609  *****************************************************************************/
610 static void CloseDecoder( vlc_object_t *p_this )
611 {
612     decoder_t *p_dec = (decoder_t *)p_this;
613     decoder_sys_t *p_sys = p_dec->p_sys;
614
615     if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
616     {
617         vorbis_block_clear( &p_sys->vb );
618         vorbis_dsp_clear( &p_sys->vd );
619     }
620
621     vorbis_comment_clear( &p_sys->vc );
622     vorbis_info_clear( &p_sys->vi );  /* must be called last */
623
624     free( p_sys );
625 }
626
627 #if defined(HAVE_VORBIS_VORBISENC_H) && !defined(MODULE_NAME_IS_tremor)
628
629 /*****************************************************************************
630  * encoder_sys_t : vorbis encoder descriptor
631  *****************************************************************************/
632 struct encoder_sys_t
633 {
634     /*
635      * Vorbis properties
636      */
637     vorbis_info      vi; /* struct that stores all the static vorbis bitstream
638                             settings */
639     vorbis_comment   vc; /* struct that stores all the bitstream user
640                           * comments */
641     vorbis_dsp_state vd; /* central working state for the packet->PCM
642                           * decoder */
643     vorbis_block     vb; /* local working space for packet->PCM decode */
644
645     int i_last_block_size;
646     int i_samples_delay;
647     int i_channels;
648
649     /*
650      * Common properties
651      */
652     mtime_t i_pts;
653 };
654
655 /*****************************************************************************
656  * OpenEncoder: probe the encoder and return score
657  *****************************************************************************/
658 static int OpenEncoder( vlc_object_t *p_this )
659 {
660     encoder_t *p_enc = (encoder_t *)p_this;
661     encoder_sys_t *p_sys;
662     int i_quality, i_min_bitrate, i_max_bitrate, i;
663     ogg_packet header[3];
664     vlc_value_t val;
665     uint8_t *p_extra;
666
667     if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') &&
668         !p_enc->b_force )
669     {
670         return VLC_EGENERIC;
671     }
672
673     /* Allocate the memory needed to store the decoder's structure */
674     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
675     {
676         msg_Err( p_enc, "out of memory" );
677         return VLC_EGENERIC;
678     }
679     p_enc->p_sys = p_sys;
680
681     p_enc->pf_encode_audio = Encode;
682     p_enc->fmt_in.i_codec = VLC_FOURCC('f','l','3','2');
683     p_enc->fmt_out.i_codec = VLC_FOURCC('v','o','r','b');
684
685     sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
686
687     var_Get( p_enc, ENC_CFG_PREFIX "quality", &val );
688     i_quality = val.i_int;
689     if( i_quality > 10 ) i_quality = 10;
690     if( i_quality < 0 ) i_quality = 0;
691     var_Get( p_enc, ENC_CFG_PREFIX "cbr", &val );
692     if( val.b_bool ) i_quality = 0;
693     var_Get( p_enc, ENC_CFG_PREFIX "max-bitrate", &val );
694     i_max_bitrate = val.i_int;
695     var_Get( p_enc, ENC_CFG_PREFIX "min-bitrate", &val );
696     i_min_bitrate = val.i_int;
697
698     /* Initialize vorbis encoder */
699     vorbis_info_init( &p_sys->vi );
700
701     if( i_quality > 0 )
702     {
703         /* VBR mode */
704         if( vorbis_encode_setup_vbr( &p_sys->vi,
705               p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate,
706               i_quality * 0.1 ) )
707         {
708             vorbis_info_clear( &p_sys->vi );
709             free( p_enc->p_sys );
710             msg_Err( p_enc, "VBR mode initialisation failed" );
711             return VLC_EGENERIC;
712         }
713
714         /* Do we have optional hard quality restrictions? */
715         if( i_max_bitrate > 0 || i_min_bitrate > 0 )
716         {
717             struct ovectl_ratemanage_arg ai;
718             vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_GET, &ai );
719
720             ai.bitrate_hard_min = i_min_bitrate;
721             ai.bitrate_hard_max = i_max_bitrate;
722             ai.management_active = 1;
723
724             vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_SET, &ai );
725
726         }
727         else
728         {
729             /* Turn off management entirely */
730             vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_SET, NULL );
731         }
732     }
733     else
734     {
735         if( vorbis_encode_setup_managed( &p_sys->vi,
736               p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate,
737               i_min_bitrate > 0 ? i_min_bitrate * 1000: -1,
738               p_enc->fmt_out.i_bitrate,
739               i_max_bitrate > 0 ? i_max_bitrate * 1000: -1 ) )
740           {
741               vorbis_info_clear( &p_sys->vi );
742               msg_Err( p_enc, "CBR mode initialisation failed" );
743               free( p_enc->p_sys );
744               return VLC_EGENERIC;
745           }
746     }
747
748     vorbis_encode_setup_init( &p_sys->vi );
749
750     /* Add a comment */
751     vorbis_comment_init( &p_sys->vc);
752     vorbis_comment_add_tag( &p_sys->vc, "ENCODER", "VLC media player");
753
754     /* Set up the analysis state and auxiliary encoding storage */
755     vorbis_analysis_init( &p_sys->vd, &p_sys->vi );
756     vorbis_block_init( &p_sys->vd, &p_sys->vb );
757
758     /* Create and store headers */
759     vorbis_analysis_headerout( &p_sys->vd, &p_sys->vc,
760                                &header[0], &header[1], &header[2]);
761     p_enc->fmt_out.i_extra = 3 * 2 + header[0].bytes +
762        header[1].bytes + header[2].bytes;
763     p_extra = p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
764     for( i = 0; i < 3; i++ )
765     {
766         *(p_extra++) = header[i].bytes >> 8;
767         *(p_extra++) = header[i].bytes & 0xFF;
768         memcpy( p_extra, header[i].packet, header[i].bytes );
769         p_extra += header[i].bytes;
770     }
771
772     p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
773     p_sys->i_last_block_size = 0;
774     p_sys->i_samples_delay = 0;
775     p_sys->i_pts = 0;
776
777     return VLC_SUCCESS;
778 }
779
780 /****************************************************************************
781  * Encode: the whole thing
782  ****************************************************************************
783  * This function spits out ogg packets.
784  ****************************************************************************/
785 static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
786 {
787     encoder_sys_t *p_sys = p_enc->p_sys;
788     ogg_packet oggpacket;
789     block_t *p_block, *p_chain = NULL;
790     float **buffer;
791     int i;
792     unsigned int j;
793
794     p_sys->i_pts = p_aout_buf->start_date -
795                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
796                 (mtime_t)p_enc->fmt_in.audio.i_rate;
797
798     p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
799
800     buffer = vorbis_analysis_buffer( &p_sys->vd, p_aout_buf->i_nb_samples );
801
802     /* convert samples to float and uninterleave */
803     for( i = 0; i < p_sys->i_channels; i++ )
804     {
805         for( j = 0 ; j < p_aout_buf->i_nb_samples ; j++ )
806         {
807             buffer[i][j]= ((float *)p_aout_buf->p_buffer)
808                                     [j * p_sys->i_channels + i ];
809         }
810     }
811
812     vorbis_analysis_wrote( &p_sys->vd, p_aout_buf->i_nb_samples );
813
814     while( vorbis_analysis_blockout( &p_sys->vd, &p_sys->vb ) == 1 )
815     {
816         int i_samples;
817
818         vorbis_analysis( &p_sys->vb, NULL );
819         vorbis_bitrate_addblock( &p_sys->vb );
820
821         while( vorbis_bitrate_flushpacket( &p_sys->vd, &oggpacket ) )
822         {
823             int i_block_size;
824             p_block = block_New( p_enc, oggpacket.bytes );
825             memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
826
827             i_block_size = vorbis_packet_blocksize( &p_sys->vi, &oggpacket );
828
829             if( i_block_size < 0 ) i_block_size = 0;
830             i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
831             p_sys->i_last_block_size = i_block_size;
832
833             p_block->i_length = (mtime_t)1000000 *
834                 (mtime_t)i_samples / (mtime_t)p_enc->fmt_in.audio.i_rate;
835
836             p_block->i_dts = p_block->i_pts = p_sys->i_pts;
837
838             p_sys->i_samples_delay -= i_samples;
839
840             /* Update pts */
841             p_sys->i_pts += p_block->i_length;
842             block_ChainAppend( &p_chain, p_block );
843         }
844     }
845
846     return p_chain;
847 }
848
849 /*****************************************************************************
850  * CloseEncoder: vorbis encoder destruction
851  *****************************************************************************/
852 static void CloseEncoder( vlc_object_t *p_this )
853 {
854     encoder_t *p_enc = (encoder_t *)p_this;
855     encoder_sys_t *p_sys = p_enc->p_sys;
856
857     vorbis_block_clear( &p_sys->vb );
858     vorbis_dsp_clear( &p_sys->vd );
859     vorbis_comment_clear( &p_sys->vc );
860     vorbis_info_clear( &p_sys->vi );  /* must be called last */
861
862     free( p_sys );
863 }
864
865 #endif /* HAVE_VORBIS_VORBISENC_H && !MODULE_NAME_IS_tremor */