static int get_prog_config(BitData *bf, ProgConfig *p) { int tag; p->nChannels = 0; tag = GetBits(bf, 4); p->profile = GetBits(bf, 2); p->sampling_rate_idx = GetBits(bf, 4); p->front.num_ele = GetBits(bf, 4); p->side.num_ele = GetBits(bf, 4); p->back.num_ele = GetBits(bf, 4); p->lfe.num_ele = GetBits(bf, 2); p->data.num_ele = GetBits(bf, 3); p->coupling.num_ele = GetBits(bf, 4); if ( ( p->mono_mix.present = GetBits(bf, 1) ) == 1 ) p->mono_mix.ele_tag = GetBits(bf, 4); if ( ( p->stereo_mix.present = GetBits(bf, 1) ) == 1 ) p->stereo_mix.ele_tag = GetBits(bf, 4); if ( ( p->matrix_mix.present = GetBits(bf, 1) ) == 1 ) { p->matrix_mix.ele_tag = GetBits(bf, 2); p->matrix_mix.pseudo_enab = GetBits(bf, 1); } p->nChannels += get_ele_list(bf, &p->front, 1); p->nChannels += get_ele_list(bf, &p->side, 1); p->nChannels += get_ele_list(bf, &p->back, 1); p->nChannels += get_ele_list(bf, &p->lfe, 0); return 1; }
int get_prog_config(faacDecHandle hDecoder, ProgConfig *p) { int i, j, tag; tag = faad_getbits(&hDecoder->ld, LEN_TAG); p->object_type = faad_getbits(&hDecoder->ld, LEN_OBJECTTYPE); p->sampling_rate_idx = faad_getbits(&hDecoder->ld, LEN_SAMP_IDX); p->front.num_ele = faad_getbits(&hDecoder->ld, LEN_NUM_ELE); p->side.num_ele = faad_getbits(&hDecoder->ld, LEN_NUM_ELE); p->back.num_ele = faad_getbits(&hDecoder->ld, LEN_NUM_ELE); p->lfe.num_ele = faad_getbits(&hDecoder->ld, LEN_NUM_LFE); p->data.num_ele = faad_getbits(&hDecoder->ld, LEN_NUM_DAT); p->coupling.num_ele = faad_getbits(&hDecoder->ld, LEN_NUM_CCE); if ((p->mono_mix.present = faad_getbits(&hDecoder->ld, LEN_MIX_PRES)) == 1) p->mono_mix.ele_tag = faad_getbits(&hDecoder->ld, LEN_TAG); if ((p->stereo_mix.present = faad_getbits(&hDecoder->ld, LEN_MIX_PRES)) == 1) p->stereo_mix.ele_tag = faad_getbits(&hDecoder->ld, LEN_TAG); if ((p->matrix_mix.present = faad_getbits(&hDecoder->ld, LEN_MIX_PRES)) == 1) { p->matrix_mix.ele_tag = faad_getbits(&hDecoder->ld, LEN_MMIX_IDX); p->matrix_mix.pseudo_enab = faad_getbits(&hDecoder->ld, LEN_PSUR_ENAB); } get_ele_list(hDecoder, &p->front, 1); get_ele_list(hDecoder, &p->side, 1); get_ele_list(hDecoder, &p->back, 1); get_ele_list(hDecoder, &p->lfe, 0); get_ele_list(hDecoder, &p->data, 0); get_ele_list(hDecoder, &p->coupling, 1); /* * if this is a MPEG4 file and the PCE is inside a raw_data_block() * this should be aligned to beginning of raw_data_block() boundary, * not byte boundary (FIXME!!!) */ faad_byte_align(&hDecoder->ld); j = faad_getbits(&hDecoder->ld, LEN_COMMENT_BYTES); for (i=0; i<j; i++) p->comments[i] = (char)faad_getbits(&hDecoder->ld, LEN_BYTE); p->comments[i] = 0; /* null terminator for string */ /* activate new program configuration if appropriate */ if (hDecoder->current_program < 0) hDecoder->current_program = tag; /* always select new program */ if (tag == hDecoder->current_program) { /* enter configuration into MC_Info structure */ if ((hDecoder->pceChannels = enter_mc_info(hDecoder, &hDecoder->mc_info, p)) < 0) return -1; /* inhibit default configuration */ hDecoder->default_config = 0; } return tag; }
Int get_prog_config( tDec_Int_File *pVars, ProgConfig *pScratchPCE) { Int i; UInt tag; Int numChars; UInt temp; Bool flag; Int status = SUCCESS; BITS *pInputStream = &(pVars->inputStream); /* * The tag is used at the very end to see if this PCE is * the one to be used. Otherwise it does not need to be saved for the * the simple configurations to be used in this version of an AAC * decoder. * * All of the bits of this PCE must be read even if this PCE will not * be used. They are read into a temporary PCE, then later it is decided * whether to keep this PCE. * * To allow quick removal of the fields from the ProgConfig structure * that will probably not be used at a later date, * while still advancing the bitstream pointer,the return value of * getbits is saved into a temporary variable, then transfered to * the structure item. */ tag = get9_n_lessbits(LEN_TAG, pInputStream); pScratchPCE->profile = get9_n_lessbits(LEN_PROFILE, pInputStream); pScratchPCE->sampling_rate_idx = get9_n_lessbits(LEN_SAMP_IDX, pInputStream); if (!pVars->adif_test && (pScratchPCE->sampling_rate_idx != pVars->prog_config.sampling_rate_idx)) { #ifdef AAC_PLUS /* * PCE carries the baseline frequency, if SBR or PS are used, the frequencies will not match * so check for this unique case, and let decoding continue if this is a redundant PCE */ if ((pScratchPCE->sampling_rate_idx != (pVars->prog_config.sampling_rate_idx + 3)) || (pVars->mc_info.upsamplingFactor != 2)) #endif { /* rewind the pointer as implicit channel configuration maybe the case */ pInputStream->usedBits -= (LEN_TAG + LEN_PROFILE + LEN_SAMP_IDX); return (1); /* mismatch cannot happen */ } } /* * Retrieve the number of element lists for each of * front, side, back, lfe, data, and coupling. * * For two-channel stereo or mono, only the data in the front needs * to be saved. However, ALL fields need to be skipped over in some * fashion. Also, the number of elements needs to be temporarily saved * to call get_ele_list(). If that function was changed to pass in * the number of points to be read, the memory set aside inside the * ProgConfig structure could be removed. */ /* * The next six function calls could be combined into one, then use * shifts and masks to retrieve the individual fields. */ temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream); pScratchPCE->front.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream); pScratchPCE->side.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream); pScratchPCE->back.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_LFE, pInputStream); pScratchPCE->lfe.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_DAT, pInputStream); pScratchPCE->data.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_CCE, pInputStream); pScratchPCE->coupling.num_ele = temp; /* * Read in mix down data. * * Whether these fields can be removed and have proper operation * will be determined at a later date. */ /* Read presence of mono_mix */ flag = get1bits(pInputStream);/* LEN_MIX_PRES,*/ pScratchPCE->mono_mix.present = flag; if (flag != FALSE) { temp = get9_n_lessbits(LEN_TAG, pInputStream); pScratchPCE->mono_mix.ele_tag = temp; } /* end if (flag != FALSE) */ /* Read presence of stereo mix */ flag = get1bits(pInputStream); /* LEN_MIX_PRES,*/ pScratchPCE->stereo_mix.present = flag; if (flag != FALSE) { temp = get9_n_lessbits(LEN_TAG, pInputStream); pScratchPCE->stereo_mix.ele_tag = temp; } /* end if (flag != FALSE) */ /* Read presence of matrix mix */ flag = get1bits(pInputStream); /* LEN_MIX_PRES,*/ pScratchPCE->matrix_mix.present = flag; if (flag != FALSE) { temp = get9_n_lessbits(LEN_MMIX_IDX, pInputStream); pScratchPCE->matrix_mix.ele_tag = temp; temp = get1bits(pInputStream); /* LEN_PSUR_ENAB,*/ pScratchPCE->matrix_mix.pseudo_enab = temp; } /* end if (flag != FALSE) */ /* * Get each of the element lists. Only the front information will be * used for the PV decoder, but the usedBits field of pInputStream must * be advanced appropriately. * * This could be optimized by advancing the bit stream for the * elements that do not need to be read. */ get_ele_list(&pScratchPCE->front, pInputStream, TRUE); get_ele_list(&pScratchPCE->side, pInputStream, TRUE); get_ele_list(&pScratchPCE->back, pInputStream, TRUE); get_ele_list(&pScratchPCE->lfe, pInputStream, FALSE); get_ele_list(&pScratchPCE->data, pInputStream, FALSE); get_ele_list(&pScratchPCE->coupling, pInputStream, TRUE); /* * The standard requests a byte alignment before reading in the * comment. This can be done because LEN_COMMENT_BYTES == 8. */ byte_align(pInputStream); numChars = get9_n_lessbits(LEN_COMMENT_BYTES, pInputStream); /* * Ignore the comment - it requires 65 bytes to store (or worse on DSP). * If this field is restored, make sure to append a trailing '\0' */ for (i = numChars; i > 0; i--) { pScratchPCE->comments[i] = (Char) get9_n_lessbits(LEN_BYTE, pInputStream); } /* end for */ if (pVars->current_program < 0) { /* * If this is the first PCE, it becomes the current, regardless of * its tag number. */ pVars->current_program = tag; pVars->mc_info.ch_info[0].tag = 0; } /* end if (pVars->current_program < 0) */ if (tag == (UInt)pVars->current_program) { /* * This branch is reached under two conditions: * 1) This is the first PCE found, it was selected in the above if * block. In all encoders found thus far, the tag value has been * zero. * 2) A PCE has been sent by the encoder with a tag that matches the * the first one sent. It will then be re-read. No encoder found * * Regardless, the temporary PCE will now be copied into the * the one official program configuration. */ /* * Keep adts setting in case of a redundant PCE (only applicable when * using aac-lib own adts parser) */ pScratchPCE->file_is_adts = pVars->prog_config.file_is_adts; pScratchPCE->headerless_frames = pVars->prog_config.headerless_frames; pv_memcpy(&pVars->prog_config, pScratchPCE, sizeof(ProgConfig)); tag = 0; /* * Check that dual-mono does not carry more than 2 tracks, otherwise flag an non-supported error */ if ((pVars->prog_config.front.num_ele > 2) && !(pVars->prog_config.front.ele_is_cpe[tag])) { status = 1; } /* * Check that stereo does not carry more than 1 track, otherwise flag an non-supported error */ if ((pVars->prog_config.front.num_ele > 1) && (pVars->prog_config.front.ele_is_cpe[tag])) { status = 1; } if (!status) { /* enter configuration into MC_Info structure */ status = set_mc_info(&pVars->mc_info, (tMP4AudioObjectType)(pVars->prog_config.profile + 1), pVars->prog_config.sampling_rate_idx, pVars->prog_config.front.ele_tag[tag], pVars->prog_config.front.ele_is_cpe[tag], pVars->winmap, pVars->SFBWidth128); if (pVars->mc_info.upsamplingFactor == 2) { /* * prog_config.sampling_rate_idx corresponds to the aac base layer, * if the upsampling factor is active, then the output frequency needs * to be adjusted accordingly */ pVars->prog_config.sampling_rate_idx -= 3; } } } /* end if (tag == pVars->current_program) */ return (status); }