vorbis.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:27k
源码类别:

多媒体

开发平台:

MultiPlatform

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