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;
}
Esempio n. 2
0
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);
}