📄 vorbis.c
字号:
if (get_bits1(gb)) { mapping_setup->coupling_steps=get_bits(gb, 8)+1; mapping_setup->magnitude=(uint_fast8_t *)av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); mapping_setup->angle=(uint_fast8_t *)av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); for(j=0;j<mapping_setup->coupling_steps;++j) { mapping_setup->magnitude[j]=get_bits(gb, ilog(vc->audio_channels-1)); mapping_setup->angle[j]=get_bits(gb, ilog(vc->audio_channels-1)); // FIXME: sanity checks } } else { mapping_setup->coupling_steps=0; } AV_DEBUG(" %d mapping coupling steps: %d \n", i, mapping_setup->coupling_steps); if(get_bits(gb, 2)) { av_log(vc->avccontext, AV_LOG_ERROR, "%d. mapping setup data invalid. \n", i); return 1; // following spec. } if (mapping_setup->submaps>1) { mapping_setup->mux=(uint_fast8_t *)av_mallocz(vc->audio_channels * sizeof(uint_fast8_t)); for(j=0;j<vc->audio_channels;++j) { mapping_setup->mux[j]=get_bits(gb, 4); } } for(j=0;j<mapping_setup->submaps;++j) { get_bits(gb, 8); // FIXME check? mapping_setup->submap_floor[j]=get_bits(gb, 8); mapping_setup->submap_residue[j]=get_bits(gb, 8); AV_DEBUG(" %d mapping %d submap : floor %d, residue %d \n", i, j, mapping_setup->submap_floor[j], mapping_setup->submap_residue[j]); } } return 0;}// Process modes partstatic void create_map( vorbis_context * vc, uint_fast8_t floor_number ){ vorbis_floor * floors=vc->floors; vorbis_floor0 * vf; int idx; int_fast8_t blockflag; int_fast32_t * map; int_fast32_t n; //TODO: could theoretically be smaller? for (blockflag=0;blockflag<2;++blockflag) { n=(blockflag ? vc->blocksize_1 : vc->blocksize_0) / 2; floors[floor_number].data.t0.map[blockflag]= av_malloc((n+1) * sizeof(int_fast32_t)); // n+sentinel map=floors[floor_number].data.t0.map[blockflag]; vf=&floors[floor_number].data.t0; for (idx=0; idx<n;++idx) { map[idx]=floor( BARK((vf->rate*idx)/(2.0f*n)) * ((vf->bark_map_size)/ BARK(vf->rate/2.0f )) ); if (vf->bark_map_size-1 < map[idx]) { map[idx]=vf->bark_map_size-1; } } map[n]=-1; vf->map_size[blockflag]=n; }# ifdef V_DEBUG for(idx=0;idx<=n;++idx) { AV_DEBUG("floor0 map: map at pos %d is %d\n", idx, map[idx]); }# endif}static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) { GetBitContext *gb=&vc->gb; uint_fast8_t i; vc->mode_count=get_bits(gb, 6)+1; vc->modes=(vorbis_mode *)av_mallocz(vc->mode_count * sizeof(vorbis_mode)); AV_DEBUG(" There are %d modes.\n", vc->mode_count); for(i=0;i<vc->mode_count;++i) { vorbis_mode *mode_setup=&vc->modes[i]; mode_setup->blockflag=get_bits(gb, 1); mode_setup->windowtype=get_bits(gb, 16); //FIXME check mode_setup->transformtype=get_bits(gb, 16); //FIXME check mode_setup->mapping=get_bits(gb, 8); //FIXME check AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping); } return 0;}// Process the whole setup header using the functions abovestatic int vorbis_parse_setup_hdr(vorbis_context *vc) { GetBitContext *gb=&vc->gb; if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n"); return 1; } if (vorbis_parse_setup_hdr_codebooks(vc)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n"); return 2; } if (vorbis_parse_setup_hdr_tdtransforms(vc)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n"); return 3; } if (vorbis_parse_setup_hdr_floors(vc)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n"); return 4; } if (vorbis_parse_setup_hdr_residues(vc)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n"); return 5; } if (vorbis_parse_setup_hdr_mappings(vc)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n"); return 6; } if (vorbis_parse_setup_hdr_modes(vc)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n"); return 7; } if (!get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n"); return 8; // framing flag bit unset error } return 0;}// Process the identification headerstatic int vorbis_parse_id_hdr(vorbis_context *vc){ GetBitContext *gb=&vc->gb; uint_fast8_t bl0, bl1; static const float *vwin[8]={ vwin64, vwin128, vwin256, vwin512, vwin1024, vwin2048, vwin4096, vwin8192 }; if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n"); return 1; } vc->version=get_bits_long(gb, 32); //FIXME check 0 vc->audio_channels=get_bits(gb, 8); //FIXME check >0 vc->audio_samplerate=get_bits_long(gb, 32); //FIXME check >0 vc->bitrate_maximum=get_bits_long(gb, 32); vc->bitrate_nominal=get_bits_long(gb, 32); vc->bitrate_minimum=get_bits_long(gb, 32); bl0=get_bits(gb, 4); bl1=get_bits(gb, 4); vc->blocksize_0=(1<<bl0); vc->blocksize_1=(1<<bl1); if (bl0>13 || bl0<6 || bl1>13 || bl1<6) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n"); return 3; } vc->swin=vwin[bl0-6]; vc->lwin=vwin[bl1-6]; if ((get_bits1(gb)) == 0) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n"); return 2; } vc->channel_residues=(float *)av_mallocz((vc->blocksize_1/2)*vc->audio_channels * sizeof(float)); vc->channel_floors=(float *)av_mallocz((vc->blocksize_1/2)*vc->audio_channels * sizeof(float)); vc->saved=(float *)av_mallocz((vc->blocksize_1/2)*vc->audio_channels * sizeof(float)); vc->ret=(float *)av_mallocz((vc->blocksize_1/2)*vc->audio_channels * sizeof(float)); vc->buf=(float *)av_malloc(vc->blocksize_1 * sizeof(float)); vc->buf_tmp=(float *)av_malloc(vc->blocksize_1 * sizeof(float)); vc->saved_start=0; ff_mdct_init(&vc->mdct0, bl0, 1); ff_mdct_init(&vc->mdct1, bl1, 1); AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ", vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize_0, vc->blocksize_1);/* BLK=vc->blocksize_0; for(i=0;i<BLK/2;++i) { vc->swin[i]=sin(0.5*3.14159265358*(sin(((float)i+0.5)/(float)BLK*3.14159265358))*(sin(((float)i+0.5)/(float)BLK*3.14159265358))); }*/ return 0;}static void vorbis_readstring(GetBitContext *gb,char *buf,int bytes){ while (bytes--) { *buf++=get_bits(gb,8); }}static int vorbis_parse_comment_hdr(vorbis_context *vc) { GetBitContext *gb=&vc->gb; int vendorlen,i; if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis comment header packet corrupt (no vorbis signature). \n"); return 1; } vendorlen=get_bits_long(gb,32); if(vendorlen<0) return -1; vc->vendor=av_mallocz(vendorlen+1); vorbis_readstring(gb,vc->vendor,vendorlen); vc->comments=get_bits_long(gb,32); if(vc->comments<0) return -1; vc->user_comments=(char **)av_mallocz((vc->comments+1)*sizeof(*vc->user_comments)); vc->comment_lengths=(int *)av_mallocz((vc->comments+1)*sizeof(*vc->comment_lengths)); for (i=0;i<vc->comments;i++) { int len=get_bits_long(gb,32); if(len<0) return -1; vc->comment_lengths[i]=len; vc->user_comments[i]=av_mallocz(len+1); vorbis_readstring(gb,vc->user_comments[i],len); } if (!get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis comment header packet corrupt (framing flag). \n"); return -1; } return 0;}static int vorbis_comment_query_count(vorbis_context *vc, const char *tag) { int i,count=0; int taglen = strlen(tag)+1; /* +1 for the = we append */ char *fulltag = (char *)av_malloc(taglen+1); strcpy(fulltag,tag); pstrcat(fulltag, taglen+1, "="); for (i=0;i<vc->comments;i++) { if(!strnicmp(vc->user_comments[i], fulltag, taglen)) count++; } av_free(fulltag); return count;}static const char *vorbis_comment_query(vorbis_context *vc, const char *tag, int count) { long i; int found = 0; int taglen = strlen(tag)+1; /* +1 for the = we append */ char *fulltag = (char *)av_malloc(taglen+ 1); strcpy(fulltag, tag); pstrcat(fulltag, taglen+1, "="); for (i=0;i<vc->comments;i++){ if (!strnicmp(vc->user_comments[i], fulltag, taglen)) { if (count == found) {/* We return a pointer to the data, not a copy */ av_free(fulltag); return vc->user_comments[i] + taglen; } else found++; } } av_free(fulltag); return NULL; /* didn't find anything */}static int vorbis_init_id_header(AVCodecContext *avccontext,const uint8_t *headers,int header_len){ vorbis_context *vc = avccontext->priv_data ; GetBitContext *gb = &(vc->gb); int hdr_type; init_get_bits(gb, headers, header_len*8); hdr_type=get_bits(gb, 8); if (hdr_type!=1) { av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n"); return -1; } if (vorbis_parse_id_hdr(vc)) { av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n"); vorbis_free(vc); return -1; } return 0;}static int vorbis_init_setup_header(AVCodecContext *avccontext,const uint8_t *headers,int header_len){ vorbis_context *vc = avccontext->priv_data ; GetBitContext *gb = &(vc->gb); int hdr_type; init_get_bits(gb, headers, header_len*8); hdr_type=get_bits(gb, 8); if (hdr_type!=5) { av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n"); return -1; } if (vorbis_parse_setup_hdr(vc)) { av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n"); vorbis_free(vc); return -1; } return 0;}static int vorbis_init_comment_header(AVCodecContext *avccontext,const uint8_t *headers,int header_len){ vorbis_context *vc = avccontext->priv_data ; GetBitContext *gb = &(vc->gb); int hdr_type; init_get_bits(gb,headers, header_len*8); hdr_type=get_bits(gb,8); if (hdr_type!=3) { av_log(avccontext, AV_LOG_ERROR, "Second header is not the comment header.\n"); return -1; } if (vorbis_parse_comment_hdr(vc)) { av_log(avccontext, AV_LOG_ERROR, "Comment header corrupt.\n"); vorbis_free(vc); return -1; } if (vorbis_comment_query_count(vc,"LWING_GAIN")) sscanf(vorbis_comment_query(vc,"LWING_GAIN",0),"%f",&avccontext->postgain); if (vorbis_comment_query_count(vc,"POSTGAIN")) sscanf(vorbis_comment_query(vc,"POSTGAIN",0),"%f",&avccontext->postgain); if (vorbis_comment_query_count(vc,"REPLAYGAIN_TRACK_GAIN")) { if (sscanf(vorbis_comment_query(vc,"REPLAYGAIN_TRACK_GAIN",0),"%f dB",&avccontext->postgain)==1) avccontext->postgain=(float)pow(10.0,avccontext->postgain/20.0); } return 0;}// Process the extradata using the functions above (identification header, setup header)static int vorbis_decode_init(AVCodecContext *avccontext) { vorbis_context *vc = avccontext->priv_data ; const uint8_t *headers = avccontext->extradata; int headers_len=avccontext->extradata_size; int header_len[3]; int i, j; avccontext->sample_fmt=SAMPLE_FMT_FLT; vc->avccontext = avccontext; if ((!headers_len || headers[0]!=2) && avccontext->vorbis_header_size[0]==0) { av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); return 0; } if (avccontext->vorbis_header_size[0]==0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -