📄 vorbis.c
字号:
if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) { av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n"); goto error; } } av_free(tmp_vlc_bits); av_free(tmp_vlc_codes); return 0;// Error:error: av_free(tmp_vlc_bits); av_free(tmp_vlc_codes); return 1;}// Process time domain transforms part (unused in Vorbis I)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; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -