X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fvorbisenc.c;h=4fc7b62f4c8854160b95915696ce2533ae47cd5d;hb=e74456acc879665f80d3b9092e5afb4e8335d3a1;hp=e02c758a1a7060a39261f5eb48213e5c1cc2f56b;hpb=399301e3bd2f1ae0f313c834aec21c1cd746ff96;p=platform%2Fupstream%2Flibvorbis.git diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c index e02c758..4fc7b62 100644 --- a/lib/vorbisenc.c +++ b/lib/vorbisenc.c @@ -5,13 +5,12 @@ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: simple programmatic interface for encoder mode setup - last mod: $Id$ ********************************************************************/ @@ -32,12 +31,13 @@ with > 12 partition types, or a different division of iteration, this needs to be updated. */ typedef struct { - const static_codebook *books[12][3]; + const static_codebook *books[12][4]; } static_bookblock; typedef struct { int res_type; int limit_type; /* 0 lowpass limited, 1 point stereo limited */ + int grouping; const vorbis_info_residue0 *res; const static_codebook *book_aux; const static_codebook *book_aux_managed; @@ -153,6 +153,7 @@ static const vorbis_info_mapping0 _map_nominal[2]={ #include "modes/setup_44.h" #include "modes/setup_44u.h" +#include "modes/setup_44p51.h" #include "modes/setup_32.h" #include "modes/setup_8.h" #include "modes/setup_11.h" @@ -162,6 +163,7 @@ static const vorbis_info_mapping0 _map_nominal[2]={ static const ve_setup_data_template *const setup_list[]={ &ve_setup_44_stereo, + &ve_setup_44_51, &ve_setup_44_uncoupled, &ve_setup_32_stereo, @@ -184,18 +186,6 @@ static const ve_setup_data_template *const setup_list[]={ 0 }; -static int vorbis_encode_toplevel_setup(vorbis_info *vi,int ch,long rate){ - if(vi && vi->codec_setup){ - - vi->version=0; - vi->channels=ch; - vi->rate=rate; - - return(0); - } - return(OV_EINVAL); -} - static void vorbis_encode_floor_setup(vorbis_info *vi,int s, const static_codebook *const *const *const books, const vorbis_info_floor1 *in, @@ -467,7 +457,7 @@ static void vorbis_encode_residue_setup(vorbis_info *vi, const vorbis_residue_template *res){ codec_setup_info *ci=vi->codec_setup; - int i,n; + int i; vorbis_info_residue0 *r=ci->residue_param[number]= _ogg_malloc(sizeof(*r)); @@ -475,14 +465,7 @@ static void vorbis_encode_residue_setup(vorbis_info *vi, memcpy(r,res->res,sizeof(*r)); if(ci->residues<=number)ci->residues=number+1; - switch(ci->blocksizes[block]){ - case 64:case 128:case 256: - r->grouping=16; - break; - default: - r->grouping=32; - break; - } + r->grouping=res->grouping; ci->residue_type[number]=res->res_type; /* fill in all the books */ @@ -491,7 +474,7 @@ static void vorbis_encode_residue_setup(vorbis_info *vi, if(ci->hi.managed){ for(i=0;ipartitions;i++) - for(k=0;k<3;k++) + for(k=0;k<4;k++) if(res->books_base_managed->books[i][k]) r->secondstages[i]|=(1<book_param[r->groupbook]=(static_codebook *)res->book_aux_managed; for(i=0;ipartitions;i++){ - for(k=0;k<3;k++){ + for(k=0;k<4;k++){ if(res->books_base_managed->books[i][k]){ int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]); r->booklist[booklist++]=bookid; @@ -511,7 +494,7 @@ static void vorbis_encode_residue_setup(vorbis_info *vi, }else{ for(i=0;ipartitions;i++) - for(k=0;k<3;k++) + for(k=0;k<4;k++) if(res->books_base->books[i][k]) r->secondstages[i]|=(1<book_param[r->groupbook]=(static_codebook *)res->book_aux; for(i=0;ipartitions;i++){ - for(k=0;k<3;k++){ + for(k=0;k<4;k++){ if(res->books_base->books[i][k]){ int bookid=book_dup_or_new(ci,res->books_base->books[i][k]); r->booklist[booklist++]=bookid; @@ -566,13 +549,38 @@ static void vorbis_encode_residue_setup(vorbis_info *vi, boundaries. We still lowpass 'wherever', but we have to round up here to next boundary, or the vorbis spec will round it *down* to previous boundary in encode/decode */ - if(ci->residue_type[number]==2) - r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */ + if(ci->residue_type[number]==2){ + /* residue 2 bundles together multiple channels; used by stereo + and surround. Count the channels in use */ + /* Multiple maps/submaps can point to the same residue. In the case + of residue 2, they all better have the same number of + channels/samples. */ + int j,k,ch=0; + for(i=0;imaps&&ch==0;i++){ + vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i]; + for(j=0;jsubmaps && ch==0;j++) + if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */ + for(k=0;kchannels;k++) + if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */ + ch++; + } + + r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */ r->grouping; - else + /* the blocksize and grouping may disagree at the end */ + if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping; + + }else{ + r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ r->grouping; + /* the blocksize and grouping may disagree at the end */ + if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping; + + } + if(r->end==0)r->end=r->grouping; /* LFE channel */ + } } @@ -621,12 +629,10 @@ static double setting_to_approx_bitrate(vorbis_info *vi){ return((r[is]*(1.-ds)+r[is+1]*ds)*ch); } -static void get_setup_template(vorbis_info *vi, - long ch,long srate, - double req,int q_or_bitrate){ +static const void *get_setup_template(long ch,long srate, + double req,int q_or_bitrate, + double *base_setting){ int i=0,j; - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; if(q_or_bitrate)req/=ch; while(setup_list[i]){ @@ -646,23 +652,22 @@ static void get_setup_template(vorbis_info *vi, for(j=0;j=map[j] && reqsetup=setup_list[i]; if(j==mappings) - hi->base_setting=j-.001; + *base_setting=j-.001; else{ float low=map[j]; float high=map[j+1]; float del=(req-low)/(high-low); - hi->base_setting=j+del; + *base_setting=j+del; } - return; + return(setup_list[i]); } } i++; } - hi->setup=NULL; + return NULL; } /* encoders will need to use vorbis_info_init beforehand and call @@ -852,29 +857,30 @@ int vorbis_encode_setup_init(vorbis_info *vi){ } -static int vorbis_encode_setup_setting(vorbis_info *vi, +static void vorbis_encode_setup_setting(vorbis_info *vi, long channels, long rate){ - int ret=0,i,is; + int i,is; codec_setup_info *ci=vi->codec_setup; highlevel_encode_setup *hi=&ci->hi; const ve_setup_data_template *setup=hi->setup; double ds; - ret=vorbis_encode_toplevel_setup(vi,channels,rate); - if(ret)return(ret); - - is=hi->base_setting; - ds=hi->base_setting-is; - - hi->managed=0; + vi->version=0; + vi->channels=channels; + vi->rate=rate; hi->impulse_block_p=1; hi->noise_normalize_p=1; + is=hi->base_setting; + ds=hi->base_setting-is; + hi->stereo_point_setting=hi->base_setting; - hi->lowpass_kHz= - setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds; + + if(!hi->lowpass_altered) + hi->lowpass_kHz= + setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds; hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+ setup->psy_ath_float[is+1]*ds; @@ -890,24 +896,31 @@ static int vorbis_encode_setup_setting(vorbis_info *vi, hi->block[i].noise_bias_setting=hi->base_setting; hi->block[i].noise_compand_setting=hi->base_setting; } - - return(ret); } int vorbis_encode_setup_vbr(vorbis_info *vi, long channels, long rate, float quality){ - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; + codec_setup_info *ci; + highlevel_encode_setup *hi; + if(rate<=0) return OV_EINVAL; + + ci=vi->codec_setup; + hi=&ci->hi; quality+=.0000001; if(quality>=1.)quality=.9999; - get_setup_template(vi,channels,rate,quality,0); + hi->req=quality; + hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting); if(!hi->setup)return OV_EIMPL; - return vorbis_encode_setup_setting(vi,channels,rate); + vorbis_encode_setup_setting(vi,channels,rate); + hi->managed=0; + hi->coupling_p=1; + + return 0; } int vorbis_encode_init_vbr(vorbis_info *vi, @@ -938,10 +951,14 @@ int vorbis_encode_setup_managed(vorbis_info *vi, long nominal_bitrate, long min_bitrate){ - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; - double tnominal=nominal_bitrate; - int ret=0; + codec_setup_info *ci; + highlevel_encode_setup *hi; + double tnominal; + if(rate<=0) return OV_EINVAL; + + ci=vi->codec_setup; + hi=&ci->hi; + tnominal=nominal_bitrate; if(nominal_bitrate<=0.){ if(max_bitrate>0.){ @@ -958,16 +975,14 @@ int vorbis_encode_setup_managed(vorbis_info *vi, } } - get_setup_template(vi,channels,rate,nominal_bitrate,1); + hi->req=nominal_bitrate; + hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting); if(!hi->setup)return OV_EIMPL; - ret=vorbis_encode_setup_setting(vi,channels,rate); - if(ret){ - vorbis_info_clear(vi); - return ret; - } + vorbis_encode_setup_setting(vi,channels,rate); /* initialize management with sane defaults */ + hi->coupling_p=1; hi->managed=1; hi->bitrate_min=min_bitrate; hi->bitrate_max=max_bitrate; @@ -976,7 +991,7 @@ int vorbis_encode_setup_managed(vorbis_info *vi, hi->bitrate_reservoir=nominal_bitrate*2; hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */ - return(ret); + return(0); } @@ -1153,6 +1168,7 @@ int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.; if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.; + hi->lowpass_altered=1; } return(0); case OV_ECTL_IBLOCK_GET: @@ -1170,9 +1186,37 @@ int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.; } return(0); + case OV_ECTL_COUPLING_GET: + { + int *iarg=(int *)arg; + *iarg=hi->coupling_p; + } + return(0); + case OV_ECTL_COUPLING_SET: + { + const void *new_template; + double new_base=0.; + int *iarg=(int *)arg; + hi->coupling_p=((*iarg)!=0); + + /* Fetching a new template can alter the base_setting, which + many other parameters are based on. Right now, the only + parameter drawn from the base_setting that can be altered + by an encctl is the lowpass, so that is explictly flagged + to not be overwritten when we fetch a new template and + recompute the dependant settings */ + new_template = get_setup_template(hi->coupling_p?vi->channels:-1, + vi->rate, + hi->req, + hi->managed, + &new_base); + if(!new_template)return OV_EIMPL; + hi->setup=new_template; + hi->base_setting=new_base; + vorbis_encode_setup_setting(vi,vi->channels,vi->rate); + } + return(0); } - - return(OV_EIMPL); } return(OV_EINVAL);