⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vorbis.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 4 页
字号:
    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->decode=vorbis_floor1_decode;            floor_setup->data.t1.partitions=get_bits(gb, 5);            AV_DEBUG(" %d.floor: %d partitions \n", i, floor_setup->data.t1.partitions);            for(j=0;j<floor_setup->data.t1.partitions;++j) {                floor_setup->data.t1.partition_class[j]=get_bits(gb, 4);                if (floor_setup->data.t1.partition_class[j]>maximum_class) maximum_class=floor_setup->data.t1.partition_class[j];                AV_DEBUG(" %d. floor %d partition class %d \n", i, j, floor_setup->data.t1.partition_class[j]);            }            AV_DEBUG(" maximum class %d \n", maximum_class);            floor_setup->data.t1.maximum_class=maximum_class;            for(j=0;j<=maximum_class;++j) {                floor_setup->data.t1.class_dimensions[j]=get_bits(gb, 3)+1;                floor_setup->data.t1.class_subclasses[j]=get_bits(gb, 2);                AV_DEBUG(" %d floor %d class dim: %d subclasses %d \n", i, j, floor_setup->data.t1.class_dimensions[j], floor_setup->data.t1.class_subclasses[j]);                if (floor_setup->data.t1.class_subclasses[j]) {                    floor_setup->data.t1.class_masterbook[j]=get_bits(gb, 8);                    AV_DEBUG("   masterbook: %d \n", floor_setup->data.t1.class_masterbook[j]);                }                for(k=0;k<(1<<floor_setup->data.t1.class_subclasses[j]);++k) {                    floor_setup->data.t1.subclass_books[j][k]=get_bits(gb, 8)-1;                    AV_DEBUG("    book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]);                }            }            floor_setup->data.t1.multiplier=get_bits(gb, 2)+1;            floor_setup->data.t1.x_list_dim=2;            for(j=0;j<floor_setup->data.t1.partitions;++j) {                floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]];            }            floor_setup->data.t1.x_list=(uint_fast16_t *)av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(uint_fast16_t));            floor_setup->data.t1.x_list_order=(uint_fast16_t *)av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(uint_fast16_t));            floor_setup->data.t1.low_neighbour=(uint_fast16_t *)av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(uint_fast16_t));            floor_setup->data.t1.high_neighbour=(uint_fast16_t *)av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(uint_fast16_t));            rangebits=get_bits(gb, 4);            floor_setup->data.t1.x_list[0] = 0;            floor_setup->data.t1.x_list[1] = (1<<rangebits);            for(j=0;j<floor_setup->data.t1.partitions;++j) {                for(k=0;k<floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]];++k,++floor1_values) {                    floor_setup->data.t1.x_list[floor1_values]=get_bits(gb, rangebits);                    AV_DEBUG(" %d. floor1 Y coord. %d \n", floor1_values, floor_setup->data.t1.x_list[floor1_values]);                }            }// Precalculate order of x coordinates - needed for decode            for(k=0;k<floor_setup->data.t1.x_list_dim;++k) {                floor_setup->data.t1.x_list_order[k]=k;            }            for(k=0;k<floor_setup->data.t1.x_list_dim-1;++k) {   // FIXME optimize sorting ?                for(j=k+1;j<floor_setup->data.t1.x_list_dim;++j) {                    if(floor_setup->data.t1.x_list[floor_setup->data.t1.x_list_order[k]]>floor_setup->data.t1.x_list[floor_setup->data.t1.x_list_order[j]]) {                        uint_fast16_t tmp=floor_setup->data.t1.x_list_order[k];                        floor_setup->data.t1.x_list_order[k]=floor_setup->data.t1.x_list_order[j];                        floor_setup->data.t1.x_list_order[j]=tmp;                    }                }            }// Precalculate low and high neighbours            for(k=2;k<floor_setup->data.t1.x_list_dim;++k) {                floor_setup->data.t1.low_neighbour[k]=0;                floor_setup->data.t1.high_neighbour[k]=1;  // correct according to SPEC requirements                for (j=0;j<k;++j) {                    if ((floor_setup->data.t1.x_list[j]<floor_setup->data.t1.x_list[k]) &&                      (floor_setup->data.t1.x_list[j]>floor_setup->data.t1.x_list[floor_setup->data.t1.low_neighbour[k]])) {                        floor_setup->data.t1.low_neighbour[k]=j;                    }                    if ((floor_setup->data.t1.x_list[j]>floor_setup->data.t1.x_list[k]) &&                      (floor_setup->data.t1.x_list[j]<floor_setup->data.t1.x_list[floor_setup->data.t1.high_neighbour[k]])) {                        floor_setup->data.t1.high_neighbour[k]=j;                    }                }            }        }        else if(floor_setup->floor_type==0) {            uint_fast8_t max_codebook_dim=0;            floor_setup->decode=vorbis_floor0_decode;            floor_setup->data.t0.order=get_bits(gb, 8);            floor_setup->data.t0.rate=get_bits(gb, 16);            floor_setup->data.t0.bark_map_size=get_bits(gb, 16);            floor_setup->data.t0.amplitude_bits=get_bits(gb, 6);            /* zero would result in a div by zero later *             * 2^0 - 1 == 0                             */            if (floor_setup->data.t0.amplitude_bits == 0) {              av_log(vc->avccontext, AV_LOG_ERROR,                     "Floor 0 amplitude bits is 0.\n");              return 1;            }            floor_setup->data.t0.amplitude_offset=get_bits(gb, 8);            floor_setup->data.t0.num_books=get_bits(gb, 4)+1;            /* allocate mem for booklist */            floor_setup->data.t0.book_list=                av_malloc(floor_setup->data.t0.num_books);            if(!floor_setup->data.t0.book_list) { return 1; }            /* read book indexes */            {                int idx;                uint_fast8_t book_idx;                for (idx=0;idx<floor_setup->data.t0.num_books;++idx) {                    book_idx=get_bits(gb, 8);                    floor_setup->data.t0.book_list[idx]=book_idx;                    if (vc->codebooks[book_idx].dimensions > max_codebook_dim)                        max_codebook_dim=vc->codebooks[book_idx].dimensions;                    if (floor_setup->data.t0.book_list[idx]>vc->codebook_count)                        return 1;                }            }            create_map( vc, i );            /* allocate mem for lsp coefficients */            {                /* codebook dim is for padding if codebook dim doesn't *                 * divide order+1 then we need to read more data       */                floor_setup->data.t0.lsp=                    av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim)                              * sizeof(float));                if(!floor_setup->data.t0.lsp) { return 1; }            }#ifdef V_DEBUG /* debug output parsed headers */            AV_DEBUG("floor0 order: %u\n", floor_setup->data.t0.order);            AV_DEBUG("floor0 rate: %u\n", floor_setup->data.t0.rate);            AV_DEBUG("floor0 bark map size: %u\n",              floor_setup->data.t0.bark_map_size);            AV_DEBUG("floor0 amplitude bits: %u\n",              floor_setup->data.t0.amplitude_bits);            AV_DEBUG("floor0 amplitude offset: %u\n",              floor_setup->data.t0.amplitude_offset);            AV_DEBUG("floor0 number of books: %u\n",              floor_setup->data.t0.num_books);            AV_DEBUG("floor0 book list pointer: %p\n",              floor_setup->data.t0.book_list);            {              int idx;              for (idx=0;idx<floor_setup->data.t0.num_books;++idx) {                AV_DEBUG( "  Book %d: %u\n",                  idx+1,                  floor_setup->data.t0.book_list[idx] );              }            }#endif        }        else {            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\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 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;    const float *vwin[8]={ vwin64, vwin128, vwin256, vwin512, vwin1024, vwin2048, vwin4096, vwin8192 };    if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -