📄 vorbis.c
字号:
static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) { GetBitContext *gb=&vc->gb; uint_fast8_t i; uint_fast8_t vorbis_time_count=get_bits(gb, 6)+1; for(i=0;i<vorbis_time_count;++i) { uint_fast16_t vorbis_tdtransform=get_bits(gb, 16); AV_DEBUG(" Vorbis time domain transform %d: %d \n", vorbis_time_count, vorbis_tdtransform); if (vorbis_tdtransform) { av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n"); return 1; } } return 0;}// Process floors part - only floor type 1 is supportedstatic int vorbis_parse_setup_hdr_floors(vorbis_context *vc) { GetBitContext *gb=&vc->gb; uint_fast16_t i,j,k; vc->floor_count=get_bits(gb, 6)+1; vc->floors=(vorbis_floor *)av_mallocz(vc->floor_count * sizeof(vorbis_floor)); for (i=0;i<vc->floor_count;++i) { vorbis_floor *floor_setup=&vc->floors[i]; floor_setup->floor_type=get_bits(gb, 16); AV_DEBUG(" %d. floor type %d \n", i, floor_setup->floor_type); if (floor_setup->floor_type==1) { uint_fast8_t maximum_class=0; uint_fast8_t rangebits; uint_fast16_t floor1_values=2; floor_setup->partitions=get_bits(gb, 5); AV_DEBUG(" %d.floor: %d partitions \n", i, floor_setup->partitions); for(j=0;j<floor_setup->partitions;++j) { floor_setup->partition_class[j]=get_bits(gb, 4); if (floor_setup->partition_class[j]>maximum_class) maximum_class=floor_setup->partition_class[j]; AV_DEBUG(" %d. floor %d partition class %d \n", i, j, floor_setup->partition_class[j]); } AV_DEBUG(" maximum class %d \n", maximum_class); floor_setup->maximum_class=maximum_class; for(j=0;j<=maximum_class;++j) { floor_setup->class_dimensions[j]=get_bits(gb, 3)+1; floor_setup->class_subclasses[j]=get_bits(gb, 2); AV_DEBUG(" %d floor %d class dim: %d subclasses %d \n", i, j, floor_setup->class_dimensions[j], floor_setup->class_subclasses[j]); if (floor_setup->class_subclasses[j]) { floor_setup->class_masterbook[j]=get_bits(gb, 8); AV_DEBUG(" masterbook: %d \n", floor_setup->class_masterbook[j]); } for(k=0;k<(1<<floor_setup->class_subclasses[j]);++k) { floor_setup->subclass_books[j][k]=get_bits(gb, 8)-1; AV_DEBUG(" book %d. : %d \n", k, floor_setup->subclass_books[j][k]); } } floor_setup->multiplier=get_bits(gb, 2)+1; floor_setup->x_list_dim=2; for(j=0;j<floor_setup->partitions;++j) { floor_setup->x_list_dim+=floor_setup->class_dimensions[floor_setup->partition_class[j]]; } floor_setup->x_list=(uint_fast16_t *)av_mallocz(floor_setup->x_list_dim * sizeof(uint_fast16_t)); floor_setup->x_list_order=(uint_fast16_t *)av_mallocz(floor_setup->x_list_dim * sizeof(uint_fast16_t)); floor_setup->low_neighbour=(uint_fast16_t *)av_mallocz(floor_setup->x_list_dim * sizeof(uint_fast16_t)); floor_setup->high_neighbour=(uint_fast16_t *)av_mallocz(floor_setup->x_list_dim * sizeof(uint_fast16_t)); rangebits=get_bits(gb, 4); floor_setup->x_list[0] = 0; floor_setup->x_list[1] = (1<<rangebits); for(j=0;j<floor_setup->partitions;++j) { for(k=0;k<floor_setup->class_dimensions[floor_setup->partition_class[j]];++k,++floor1_values) { floor_setup->x_list[floor1_values]=get_bits(gb, rangebits); AV_DEBUG(" %d. floor1 Y coord. %d \n", floor1_values, floor_setup->x_list[floor1_values]); } }// Precalculate order of x coordinates - needed for decode for(k=0;k<floor_setup->x_list_dim;++k) { floor_setup->x_list_order[k]=k; } for(k=0;k<floor_setup->x_list_dim-1;++k) { // FIXME optimize sorting ? for(j=k+1;j<floor_setup->x_list_dim;++j) { if(floor_setup->x_list[floor_setup->x_list_order[k]]>floor_setup->x_list[floor_setup->x_list_order[j]]) { uint_fast16_t tmp=floor_setup->x_list_order[k]; floor_setup->x_list_order[k]=floor_setup->x_list_order[j]; floor_setup->x_list_order[j]=tmp; } } }// Precalculate low and high neighbours for(k=2;k<floor_setup->x_list_dim;++k) { floor_setup->low_neighbour[k]=0; floor_setup->high_neighbour[k]=1; // correct according to SPEC requirements for (j=0;j<k;++j) { if ((floor_setup->x_list[j]<floor_setup->x_list[k]) && (floor_setup->x_list[j]>floor_setup->x_list[floor_setup->low_neighbour[k]])) { floor_setup->low_neighbour[k]=j; } if ((floor_setup->x_list[j]>floor_setup->x_list[k]) && (floor_setup->x_list[j]<floor_setup->x_list[floor_setup->high_neighbour[k]])) { floor_setup->high_neighbour[k]=j; } } } } else { av_log(vc->avccontext, AV_LOG_ERROR, "Only floor type 1 supported. \n"); return 1; } } return 0;}// Process residues partstatic int vorbis_parse_setup_hdr_residues(vorbis_context *vc){ GetBitContext *gb=&vc->gb; uint_fast8_t i, j, k; vc->residue_count=get_bits(gb, 6)+1; vc->residues=(vorbis_residue *)av_mallocz(vc->residue_count * sizeof(vorbis_residue)); AV_DEBUG(" There are %d residues. \n", vc->residue_count); for(i=0;i<vc->residue_count;++i) { vorbis_residue *res_setup=&vc->residues[i]; uint_fast8_t cascade[64]; uint_fast8_t high_bits; uint_fast8_t low_bits; res_setup->type=get_bits(gb, 16); AV_DEBUG(" %d. residue type %d \n", i, res_setup->type); res_setup->begin=get_bits(gb, 24); res_setup->end=get_bits(gb, 24); res_setup->partition_size=get_bits(gb, 24)+1; res_setup->classifications=get_bits(gb, 6)+1; res_setup->classbook=get_bits(gb, 8); AV_DEBUG(" begin %d end %d part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size, res_setup->classifications, res_setup->classbook); for(j=0;j<res_setup->classifications;++j) { high_bits=0; low_bits=get_bits(gb, 3); if (get_bits1(gb)) { high_bits=get_bits(gb, 5); } cascade[j]=(high_bits<<3)+low_bits; AV_DEBUG(" %d class casscade depth: %d \n", j, ilog(cascade[j])); } res_setup->maxpass=0; for(j=0;j<res_setup->classifications;++j) { for(k=0;k<8;++k) { if (cascade[j]&(1<<k)) { res_setup->books[j][k]=get_bits(gb, 8); AV_DEBUG(" %d class casscade depth %d book: %d \n", j, k, res_setup->books[j][k]); if (k>res_setup->maxpass) { res_setup->maxpass=k; } } else { res_setup->books[j][k]=-1; } } } } return 0;}// Process mappings partstatic int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) { GetBitContext *gb=&vc->gb; uint_fast8_t i, j; vc->mapping_count=get_bits(gb, 6)+1; vc->mappings=(vorbis_mapping *)av_mallocz(vc->mapping_count * sizeof(vorbis_mapping)); AV_DEBUG(" There are %d mappings. \n", vc->mapping_count); for(i=0;i<vc->mapping_count;++i) { vorbis_mapping *mapping_setup=&vc->mappings[i]; if (get_bits(gb, 16)) { av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n"); return 1; } if (get_bits1(gb)) { mapping_setup->submaps=get_bits(gb, 4)+1; } else { mapping_setup->submaps=1; } 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 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_le(gb, 32); //FIXME check 0 vc->audio_channels=get_bits(gb, 8); //FIXME check >0 vc->audio_samplerate=get_bits_long_le(gb, 32); //FIXME check >0 vc->bitrate_maximum=get_bits_long_le(gb, 32); vc->bitrate_nominal=get_bits_long_le(gb, 32); vc->bitrate_minimum=get_bits_long_le(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->avccontext,&vc->mdct0, bl0, 1); ff_mdct_init(vc->avccontext,&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_le(gb,32); if(vendorlen<0) return -1; vc->vendor=av_mallocz(vendorlen+1); vorbis_readstring(gb,vc->vendor,vendorlen); vc->comments=get_bits_long_le(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_le(gb,32); if(len<0) return -1; vc->comment_lengths[i]=len; vc->user_comments[i]=av_mallocz(len+1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -