X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fvorbis.c;h=aea8ad7ba21f9969b2c61074dc4b5e0d0312a2bd;hb=560e907c019e91025de6f6d57a52d92e83a80477;hp=24c31b2562171af558ebed9e5f3d181c085e2022;hpb=85c7ea2e8e6a0d5b3c6acebf3e7d94da695cacd3;p=vlc diff --git a/modules/codec/vorbis.c b/modules/codec/vorbis.c index 24c31b2562..aea8ad7ba2 100644 --- a/modules/codec/vorbis.c +++ b/modules/codec/vorbis.c @@ -2,9 +2,9 @@ * vorbis.c: vorbis decoder/encoder/packetizer module making use of libvorbis. ***************************************************************************** * Copyright (C) 2001-2003 VideoLAN - * $Id: vorbis.c,v 1.29 2004/01/05 13:07:02 zorglub Exp $ + * $Id$ * - * Authors: Gildas Bazin + * Authors: Gildas Bazin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +26,7 @@ *****************************************************************************/ #include #include -#include "vlc_playlist.h" +#include #include @@ -123,6 +123,19 @@ static block_t *Encode ( encoder_t *, aout_buffer_t * ); /***************************************************************************** * Module descriptor *****************************************************************************/ +#define ENC_QUALITY_TEXT N_("Encoding quality") +#define ENC_QUALITY_LONGTEXT N_( \ + "Allows you to specify a quality between 1 (low) and 10 (high), instead " \ + "of specifying a particular bitrate. This will produce a VBR stream." ) +#define ENC_MAXBR_TEXT N_("Maximum encoding bitrate") +#define ENC_MAXBR_LONGTEXT N_( \ + "Allows you to specify a maximum bitrate in kbps. " \ + "Useful for streaming applications." ) +#define ENC_MINBR_TEXT N_("Minimum encoding bitrate") +#define ENC_MINBR_LONGTEXT N_( \ + "Allows you to specify a minimum bitrate in kbps. " \ + "Useful for encoding for a fixed-size channel." ) + vlc_module_begin(); set_description( _("Vorbis audio decoder") ); @@ -139,14 +152,28 @@ vlc_module_begin(); set_callbacks( OpenPacketizer, CloseDecoder ); #ifndef MODULE_NAME_IS_tremor +# define ENC_CFG_PREFIX "sout-vorbis-" add_submodule(); set_description( _("Vorbis audio encoder") ); set_capability( "encoder", 100 ); set_callbacks( OpenEncoder, CloseEncoder ); + + add_integer( ENC_CFG_PREFIX "quality", 0, NULL, ENC_QUALITY_TEXT, + ENC_QUALITY_LONGTEXT, VLC_FALSE ); + add_integer( ENC_CFG_PREFIX "max-bitrate", 0, NULL, ENC_MAXBR_TEXT, + ENC_MAXBR_LONGTEXT, VLC_FALSE ); + add_integer( ENC_CFG_PREFIX "min-bitrate", 0, NULL, ENC_MINBR_TEXT, + ENC_MINBR_LONGTEXT, VLC_FALSE ); #endif vlc_module_end(); +#ifndef MODULE_NAME_IS_tremor +static const char *ppsz_enc_options[] = { + "quality", "max-bitrate", "min-bitrate", NULL +}; +#endif + /***************************************************************************** * OpenDecoder: probe the decoder and return score *****************************************************************************/ @@ -249,8 +276,8 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 ) { - msg_Err( p_dec, "This bitstream does not contain Vorbis " - "audio data"); + msg_Err( p_dec, "this bitstream does not contain Vorbis " + "audio data."); block_Release( *pp_block ); return NULL; } @@ -452,10 +479,6 @@ static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket, static void ParseVorbisComments( decoder_t *p_dec ) { input_thread_t *p_input = (input_thread_t *)p_dec->p_parent; - input_info_category_t *p_cat = - input_InfoCategory( p_input, _("Vorbis comment") ); - playlist_t *p_playlist = vlc_object_find( p_dec, VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); int i = 0; char *psz_name, *psz_value, *psz_comment; while ( i < p_dec->p_sys->vc.comments ) @@ -463,7 +486,7 @@ static void ParseVorbisComments( decoder_t *p_dec ) psz_comment = strdup( p_dec->p_sys->vc.user_comments[i] ); if( !psz_comment ) { - msg_Warn( p_dec, "Out of memory" ); + msg_Warn( p_dec, "out of memory" ); break; } psz_name = psz_comment; @@ -472,14 +495,12 @@ static void ParseVorbisComments( decoder_t *p_dec ) { *psz_value = '\0'; psz_value++; - input_AddInfo( p_cat, psz_name, psz_value ); - playlist_AddInfo( p_playlist, -1, _("Vorbis comment") , - psz_name, psz_value ); + input_Control( p_input, INPUT_ADD_INFO, _("Vorbis comment"), + psz_name, psz_value ); } free( psz_comment ); i++; } - if( p_playlist ) vlc_object_release( p_playlist ); } /***************************************************************************** @@ -564,8 +585,11 @@ static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; + int i_quality, i_min_bitrate, i_max_bitrate; + vlc_value_t val; - if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') ) + if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') && + !p_enc->b_force ) { return VLC_EGENERIC; } @@ -581,18 +605,70 @@ static int OpenEncoder( vlc_object_t *p_this ) p_enc->pf_header = Headers; p_enc->pf_encode_audio = Encode; p_enc->fmt_in.i_codec = VLC_FOURCC('f','l','3','2'); + p_enc->fmt_out.i_codec = VLC_FOURCC('v','o','r','b'); + + sout_ParseCfg( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg ); + + var_Get( p_enc, ENC_CFG_PREFIX "quality", &val ); + i_quality = val.i_int; + if( i_quality > 10 ) i_quality = 10; + if( i_quality < 0 ) i_quality = 0; + var_Get( p_enc, ENC_CFG_PREFIX "max-bitrate", &val ); + i_max_bitrate = val.i_int; + var_Get( p_enc, ENC_CFG_PREFIX "min-bitrate", &val ); + i_min_bitrate = val.i_int; /* Initialize vorbis encoder */ vorbis_info_init( &p_sys->vi ); - if( vorbis_encode_setup_managed( &p_sys->vi, - p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate, - -1, p_enc->fmt_out.i_bitrate, -1 ) || - vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) || - vorbis_encode_setup_init( &p_sys->vi ) ) + if( i_quality > 0 ) { - ; + /* VBR mode */ + if( vorbis_encode_setup_vbr( &p_sys->vi, + p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate, + i_quality * 0.1 ) ) + { + vorbis_info_clear( &p_sys->vi ); + free( p_enc->p_sys ); + msg_Err( p_enc, "VBR mode initialisation failed" ); + return VLC_EGENERIC; + } + + /* Do we have optional hard quality restrictions? */ + if( i_max_bitrate > 0 || i_min_bitrate > 0 ) + { + struct ovectl_ratemanage_arg ai; + vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_GET, &ai ); + + ai.bitrate_hard_min = i_min_bitrate; + ai.bitrate_hard_max = i_max_bitrate; + ai.management_active = 1; + + vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_SET, &ai ); + + } + else + { + /* Turn off management entirely */ + vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_SET, NULL ); + } } + else + { + if( vorbis_encode_setup_managed( &p_sys->vi, + p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate, + i_min_bitrate > 0 ? i_min_bitrate * 1000: -1, + p_enc->fmt_out.i_bitrate, + i_max_bitrate > 0 ? i_max_bitrate * 1000: -1 ) ) + { + vorbis_info_clear( &p_sys->vi ); + msg_Err( p_enc, "CBR mode initialisation failed" ); + free( p_enc->p_sys ); + return VLC_EGENERIC; + } + } + + vorbis_encode_setup_init( &p_sys->vi ); /* add a comment */ vorbis_comment_init( &p_sys->vc);