1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20 Pathname: get_prog_config.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Description:  Modified from original shareware code
26
27 Description:  Modified to pass variables by reference to eliminate use
28               of global variables.
29
30 Description:  Move functionality from get_adif_header for when to change
31               the current program configuration, add a temporary config
32               to read into, clean up code, change function prototype.
33
34 Description:  Clean up
35
36 Description:  Update per review comments
37
38 Description:  Fix double 'could'
39
40 Description:  change enter_mc_info to set_mc_info
41
42 Description:  update comments
43
44 Description: Replace some instances of getbits to get9_n_lessbits
45              when the number of bits read is 9 or less and get1bits
46              when only 1 bit is read.
47
48 Who:                                   Date:
49 Description:
50
51------------------------------------------------------------------------------
52 INPUT AND OUTPUT DEFINITIONS
53
54 Inputs:
55    pVars      = pointer to the structure that holds all information for
56                 this instance of the library. pVars->prog_config is directly
57                 used, and pVars->mc_info, pVars->prog_config, pVars->winmap,
58                 pVars->SFBWidth128 are needed indirectly for calling
59                 set_mc_info. Data type  pointer to tDec_Int_File structure.
60
61    pScratchPCE = pointer to a temporary ProgConfig structure to be used
62                  to read in the program configuration element.
63
64 Local Stores/Buffers/Pointers Needed: None
65
66 Global Stores/Buffers/Pointers Needed: None
67
68 Outputs:
69    status     = zero if no error was found, non-zero otherwise.
70
71 Pointers and Buffers Modified:
72    pVars->prog_config contents are updated with the PCE read in.
73    pVars->mc_info contents are updated with channel information.
74    pVars->winmap contents are updated with window information.
75    pVars->SFBWidth128 contents are updated with scale factor band width data.
76
77 Local Stores Modified: None
78
79 Global Stores Modified: None
80
81------------------------------------------------------------------------------
82 FUNCTION DESCRIPTION
83
84 This function reads from the input stream to memory for a temporary
85 program configuration element (PCE). If the PCE read is the first
86 encountered it is saved. Or, if the tag of the PCE read matches the tag of
87 the first PCE encounted, it is saved as well. This is a mechanism for
88 changing the sampling rate.
89
90------------------------------------------------------------------------------
91 REQUIREMENTS
92
93 This function shall not use static or global variables.
94
95------------------------------------------------------------------------------
96 REFERENCES
97
98 (1) ISO/IEC 13818-7:1997 Titled "Information technology - Generic coding
99   of moving pictures and associated audio information - Part 7: Advanced
100   Audio Coding (AAC)", Table 6.21 - Syntax of program_config_element(),
101   page 16, and section 8.5 "Program Config Element (PCE)", page 30.
102
103 (2) MPEG-2 NBC Audio Decoder
104   "This software module was originally developed by AT&T, Dolby
105   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
106   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
107   3. This software module is an implementation of a part of one or more
108   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
109   Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
110   standards free license to this software module or modifications thereof
111   for use in hardware or software products claiming conformance to the
112   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
113   module in hardware or software products are advised that this use may
114   infringe existing patents. The original developer of this software
115   module and his/her company, the subsequent editors and their companies,
116   and ISO/IEC have no liability for use of this software module or
117   modifications thereof in an implementation. Copyright is not released
118   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
119   developer retains full right to use the code for his/her own purpose,
120   assign or donate the code to a third party and to inhibit third party
121   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
122   This copyright notice must be included in all copies or derivative
123   works."
124   Copyright(c)1996.
125
126
127------------------------------------------------------------------------------
128 PSEUDO-CODE
129
130    status          = SUCCESS;
131    pInputStream   = &(pVars->inputStream);
132
133
134    CALL getbits(
135        neededBits = LEN_TAG,
136        pInputStream = pInputStream )
137    MODIFYING( pInputStream )
138    RETURNING( tag = returnValue )
139
140    CALL getbits(
141        neededBits = LEN_PROFILE,
142        pInputStream = pInputStream )
143    MODIFYING( pInputStream )
144    RETURNING( pScratchPCE->profile = returnValue )
145
146    CALL getbits(
147        neededBits = LEN_PROFILE,
148        pInputStream = pInputStream )
149    MODIFYING( pInputStream )
150    RETURNING( pScratchPCE->sampling_rate_idx = returnValue )
151
152    CALL getbits(
153        neededBits = LEN_NUM_ELE,
154        pInputStream = pInputStream )
155    MODIFYING( pInputStream )
156    RETURNING( temp = returnValue )
157
158    pScratchPCE->front.num_ele = temp;
159
160    CALL getbits(
161        neededBits = LEN_NUM_ELE,
162        pInputStream = pInputStream )
163    MODIFYING( pInputStream )
164    RETURNING( temp = returnValue )
165
166    pScratchPCE->side.num_ele = temp;
167
168    CALL getbits(
169        neededBits = LEN_NUM_ELE,
170        pInputStream = pInputStream )
171    MODIFYING( pInputStream )
172    RETURNING( temp = returnValue )
173
174    pScratchPCE->back.num_ele = temp;
175
176    CALL getbits(
177        neededBits = LEN_NUM_LFE,
178        pInputStream = pInputStream )
179    MODIFYING( pInputStream )
180    RETURNING( temp = returnValue )
181
182    pScratchPCE->lfe.num_ele = temp;
183
184    CALL getbits(
185        neededBits = LEN_NUM_DAT,
186        pInputStream = pInputStream )
187    MODIFYING( pInputStream )
188    RETURNING( temp = returnValue )
189
190    pScratchPCE->data.num_ele = temp;
191
192    CALL getbits(
193        neededBits = LEN_NUM_CCE,
194        pInputStream = pInputStream )
195    MODIFYING( pInputStream )
196    RETURNING( temp = returnValue )
197
198    pScratchPCE->coupling.num_ele = temp;
199
200    CALL getbits(
201        neededBits = LEN_MIX_PRES,
202        pInputStream = pInputStream )
203    MODIFYING( pInputStream )
204    RETURNING( flag = returnValue )
205
206    pScratchPCE->mono_mix.present = flag;
207
208    IF (flag != FALSE)
209    THEN
210        CALL getbits(
211            neededBits = LEN_TAG,
212            pInputStream = pInputStream )
213        MODIFYING( pInputStream )
214        RETURNING( temp = returnValue )
215
216        pScratchPCE->mono_mix.ele_tag = temp;
217
218    ENDIF
219
220    CALL getbits(
221        neededBits = LEN_MIX_PRES,
222        pInputStream = pInputStream )
223    MODIFYING( pInputStream )
224    RETURNING( flag = returnValue )
225
226    pScratchPCE->stereo_mix.present = flag;
227
228    IF (flag != FALSE)
229    THEN
230
231        CALL getbits(
232            neededBits = LEN_TAG,
233            pInputStream = pInputStream )
234        MODIFYING( pInputStream )
235        RETURNING( temp = returnValue )
236
237        pScratchPCE->stereo_mix.ele_tag = temp;
238
239    ENDIF
240
241    CALL getbits(
242        neededBits = LEN_MIX_PRES,
243        pInputStream = pInputStream )
244    MODIFYING( pInputStream )
245    RETURNING( flag = returnValue )
246
247    flag =
248        getbits(
249            LEN_MIX_PRES,
250            pInputStream);
251
252    pScratchPCE->matrix_mix.present = flag;
253
254    IF (flag != FALSE)
255    THEN
256        CALL getbits(
257            neededBits = LEN_MMIX_IDX,
258            pInputStream = pInputStream )
259        MODIFYING( pInputStream )
260        RETURNING( temp = returnValue )
261
262        pScratchPCE->matrix_mix.ele_tag = temp;
263
264        CALL getbits(
265            neededBits = LEN_PSUR_ENAB,
266            pInputStream = pInputStream )
267        MODIFYING( pInputStream )
268        RETURNING( temp = returnValue )
269
270        pScratchPCE->matrix_mix.pseudo_enab = temp;
271
272    ENDIF
273
274
275    CALL get_ele_list(
276        pElementList = &pScratchPCE->front,
277        pInputStream = pInputStream,
278        enableCPE    = TRUE )
279    MODIFYING( pInputStream )
280    MODIFYING( pScratchPCE->front )
281    RETURNING( nothing )
282
283    CALL get_ele_list(
284        pElementList = &pScratchPCE->side,
285        pInputStream = pInputStream,
286        enableCPE    = TRUE )
287    MODIFYING( pInputStream )
288    MODIFYING( pScratchPCE->side )
289    RETURNING( nothing )
290
291    CALL get_ele_list(
292        pElementList = &pScratchPCE->back,
293        pInputStream = pInputStream,
294        enableCPE    = TRUE )
295    MODIFYING( pInputStream )
296    MODIFYING( pScratchPCE->back )
297    RETURNING( nothing )
298
299    CALL get_ele_list(
300        pElementList = &pScratchPCE->lfe,
301        pInputStream = pInputStream,
302        enableCPE    = FALSE )
303    MODIFYING( pInputStream )
304    MODIFYING( pScratchPCE->lfe )
305    RETURNING( nothing )
306
307    CALL get_ele_list(
308        pElementList = &pScratchPCE->data,
309        pInputStream = pInputStream,
310        enableCPE    = FALSE )
311    MODIFYING( pInputStream )
312    MODIFYING( pScratchPCE->data )
313    RETURNING( nothing )
314
315    CALL get_ele_list(
316        pElementList = &pScratchPCE->coupling,
317        pInputStream = pInputStream,
318        enableCPE    = TRUE )
319    MODIFYING( pInputStream )
320    MODIFYING( pScratchPCE->coupling )
321    RETURNING( nothing )
322
323
324    CALL byte_align(
325        pInputStream = pInputStream )
326    MODIFYING( pInputStream )
327    RETURNING( nothing )
328
329    CALL getbits(
330        neededBits = LEN_COMMENT_BYTES,
331        pInputStream = pInputStream )
332    MODIFYING( pInputStream )
333    RETURNING( numChars = returnValue )
334
335    FOR (i = numChars; i > 0; i--)
336
337        CALL getbits(
338            neededBits = LEN_COMMENT_BYTES,
339            pInputStream = pInputStream )
340        MODIFYING( pInputStream )
341        RETURNING( nothing )
342
343    ENDFOR
344
345    IF (pVars->current_program < 0)
346    THEN
347        pVars->current_program = tag;
348    ENDIF
349
350
351    IF (tag == pVars->current_program)
352    THEN
353
354        CALL pv_memcpy(
355            to = &pVars->prog_config,
356            from = pScratchPCE,
357            n = sizeof(ProgConfig))
358        MODIFYING( pVars->prog_config )
359        RETURNING( nothing )
360
361        CALL set_mc_info(
362            pMC_Info = &pVars->mc_info,
363            objectType = pVars->prog_config.profile + 1,
364            samplin_rate_idx = pVars->prog_config.sampling_rate_idx,
365            tag = pVars->prog_config.front.ele_tag[0],
366            is_cpe = pVars->prog_config.front.ele_is_cpe[0],
367            pWinSeqInfo = pVars->winmap,
368            pSfbwidth128 = pVars->SFBWidth128)
369        MODIFYING( pVars->mc_info )
370        MODIFYING( pVars->winmap )
371        MODIFYING( pVars->SFBWidth128 )
372        RETURN( status = return_value )
373
374    ENDIF
375
376    MODIFY( pVars->mc_info )
377    MODIFY( pVars->winmap )
378    MODIFY( pVars->SFBWidth128 )
379    RETURN (status)
380
381------------------------------------------------------------------------------
382 RESOURCES USED
383   When the code is written for a specific target processor the
384     the resources used should be documented below.
385
386 STACK USAGE: [stack count for this module] + [variable to represent
387          stack usage for each subroutine called]
388
389     where: [stack usage variable] = stack usage for [subroutine
390         name] (see [filename].ext)
391
392 DATA MEMORY USED: x words
393
394 PROGRAM MEMORY USED: x words
395
396 CLOCK CYCLES: [cycle count equation for this module] + [variable
397           used to represent cycle count for each subroutine
398           called]
399
400     where: [cycle count variable] = cycle count for [subroutine
401        name] (see [filename].ext)
402
403------------------------------------------------------------------------------
404*/
405
406
407/*----------------------------------------------------------------------------
408; INCLUDES
409----------------------------------------------------------------------------*/
410#include "pv_audio_type_defs.h"
411#include "s_bits.h"
412#include "s_elelist.h"
413#include "s_tdec_int_file.h"
414#include "s_tdec_int_chan.h"
415#include "e_progconfigconst.h"
416#include "ibstream.h"
417#include "get_ele_list.h"
418#include "aac_mem_funcs.h"
419#include "set_mc_info.h"
420#include "get_prog_config.h"
421
422/*----------------------------------------------------------------------------
423; MACROS
424; Define module specific macros here
425----------------------------------------------------------------------------*/
426
427/*----------------------------------------------------------------------------
428; DEFINES
429; Include all pre-processor statements here. Include conditional
430; compile variables also.
431----------------------------------------------------------------------------*/
432
433/*----------------------------------------------------------------------------
434; LOCAL FUNCTION DEFINITIONS
435; Function Prototype declaration
436----------------------------------------------------------------------------*/
437
438/*----------------------------------------------------------------------------
439; LOCAL VARIABLE DEFINITIONS
440; Variable declaration - defined here and used outside this module
441----------------------------------------------------------------------------*/
442
443/*----------------------------------------------------------------------------
444; EXTERNAL FUNCTION REFERENCES
445; Declare functions defined elsewhere and referenced in this module
446----------------------------------------------------------------------------*/
447
448/*----------------------------------------------------------------------------
449; EXTERNAL VARIABLES REFERENCES
450; Declare variables used in this module but defined elsewhere
451----------------------------------------------------------------------------*/
452
453Int get_prog_config(
454    tDec_Int_File *pVars,
455    ProgConfig    *pScratchPCE)
456{
457    Int    i;
458    UInt    tag;
459    Int    numChars;
460    UInt    temp;
461    Bool   flag;
462    Int    status          = SUCCESS;
463    BITS  *pInputStream   = &(pVars->inputStream);
464
465
466    /*
467     * The tag is used at the very end to see if this PCE is
468     * the one to be used. Otherwise it does not need to be saved for the
469     * the simple configurations to be used in this version of an AAC
470     * decoder.
471     *
472     * All of the bits of this PCE must be read even if this PCE will not
473     * be used. They are read into a temporary PCE, then later it is decided
474     * whether to keep this PCE.
475     *
476     * To allow quick removal of the fields from the ProgConfig structure
477     * that will probably not be used at a later date,
478     * while still advancing the bitstream pointer,the return value of
479     * getbits is saved into a temporary variable, then transfered to
480     * the structure item.
481     */
482    tag =
483        get9_n_lessbits(
484            LEN_TAG,
485            pInputStream);
486
487    pScratchPCE->profile =
488        get9_n_lessbits(
489            LEN_PROFILE,
490            pInputStream);
491
492    pScratchPCE->sampling_rate_idx =
493        get9_n_lessbits(
494            LEN_SAMP_IDX,
495            pInputStream);
496
497    if (!pVars->adif_test && pScratchPCE->sampling_rate_idx != pVars->prog_config.sampling_rate_idx)
498    {
499        /* rewind the pointer as implicit channel configuration maybe the case */
500        pInputStream->usedBits -= (LEN_TAG + LEN_PROFILE + LEN_SAMP_IDX);
501
502        return (1); /*  mismatch cannot happen */
503    }
504
505
506    /*
507     * Retrieve the number of element lists for each of
508     * front, side, back, lfe, data, and coupling.
509     *
510     * For two-channel stereo or mono, only the data in the front needs
511     * to be saved. However, ALL fields need to be skipped over in some
512     * fashion. Also, the number of elements needs to be temporarily saved
513     * to call get_ele_list(). If that function was changed to pass in
514     * the number of points to be read, the memory set aside inside the
515     * ProgConfig structure could be removed.
516     */
517
518    /*
519     * The next six function calls could be combined into one, then use
520     * shifts and masks to retrieve the individual fields.
521     */
522    temp =
523        get9_n_lessbits(
524            LEN_NUM_ELE,
525            pInputStream);
526
527    pScratchPCE->front.num_ele = temp;
528
529    /* Needed only to read in the element list. */
530    temp =
531        get9_n_lessbits(
532            LEN_NUM_ELE,
533            pInputStream);
534
535    pScratchPCE->side.num_ele = temp;
536
537    /* Needed only to read in the element list. */
538    temp =
539        get9_n_lessbits(
540            LEN_NUM_ELE,
541            pInputStream);
542
543    pScratchPCE->back.num_ele = temp;
544
545    /* Needed only to read in the element list. */
546    temp =
547        get9_n_lessbits(
548            LEN_NUM_LFE,
549            pInputStream);
550
551    pScratchPCE->lfe.num_ele = temp;
552
553    /* Needed only to read in the element list. */
554    temp =
555        get9_n_lessbits(
556            LEN_NUM_DAT,
557            pInputStream);
558    pScratchPCE->data.num_ele = temp;
559
560    /* Needed only to read in the element list. */
561    temp =
562        get9_n_lessbits(
563            LEN_NUM_CCE,
564            pInputStream);
565
566    pScratchPCE->coupling.num_ele = temp;
567
568    /*
569     * Read in mix down data.
570     *
571     * Whether these fields can be removed and have proper operation
572     * will be determined at a later date.
573     */
574
575    /* Read presence of mono_mix */
576    flag =
577        get1bits(/*            LEN_MIX_PRES,*/
578            pInputStream);
579
580    pScratchPCE->mono_mix.present = flag;
581
582    if (flag != FALSE)
583    {
584        temp =
585            get9_n_lessbits(
586                LEN_TAG,
587                pInputStream);
588
589        pScratchPCE->mono_mix.ele_tag = temp;
590
591    } /* end if (flag != FALSE) */
592
593    /* Read presence of stereo mix */
594    flag =
595        get1bits(/*            LEN_MIX_PRES,*/
596            pInputStream);
597
598    pScratchPCE->stereo_mix.present = flag;
599
600    if (flag != FALSE)
601    {
602        temp =
603            get9_n_lessbits(
604                LEN_TAG,
605                pInputStream);
606
607        pScratchPCE->stereo_mix.ele_tag = temp;
608
609    } /* end if (flag != FALSE) */
610
611    /* Read presence of matrix mix */
612    flag =
613        get1bits(/*            LEN_MIX_PRES,*/
614            pInputStream);
615
616    pScratchPCE->matrix_mix.present = flag;
617
618    if (flag != FALSE)
619    {
620        temp =
621            get9_n_lessbits(
622                LEN_MMIX_IDX,
623                pInputStream);
624
625        pScratchPCE->matrix_mix.ele_tag = temp;
626
627        temp =
628            get1bits(/*                LEN_PSUR_ENAB,*/
629                pInputStream);
630
631        pScratchPCE->matrix_mix.pseudo_enab = temp;
632
633    } /* end if (flag != FALSE) */
634
635    /*
636     * Get each of the element lists. Only the front information will be
637     * used for the PV decoder, but the usedBits field of pInputStream must
638     * be advanced appropriately.
639     *
640     * This could be optimized by advancing the bit stream for the
641     * elements that do not need to be read.
642     */
643    get_ele_list(
644        &pScratchPCE->front,
645        pInputStream,
646        TRUE);
647
648    get_ele_list(
649        &pScratchPCE->side,
650        pInputStream,
651        TRUE);
652
653    get_ele_list(
654        &pScratchPCE->back,
655        pInputStream,
656        TRUE);
657
658    get_ele_list(
659        &pScratchPCE->lfe,
660        pInputStream,
661        FALSE);
662
663    get_ele_list(
664        &pScratchPCE->data,
665        pInputStream,
666        FALSE);
667
668    get_ele_list(
669        &pScratchPCE->coupling,
670        pInputStream,
671        TRUE);
672
673    /*
674     * The standard requests a byte alignment before reading in the
675     * comment. This can be done because LEN_COMMENT_BYTES == 8.
676     */
677    byte_align(pInputStream);
678
679    numChars =
680        get9_n_lessbits(
681            LEN_COMMENT_BYTES, pInputStream);
682
683    /*
684     * Ignore the comment - it requires 65 bytes to store (or worse on DSP).
685     * If this field is restored, make sure to append a trailing '\0'
686     */
687    for (i = numChars; i > 0; i--)
688    {
689        pScratchPCE->comments[i] = (Char) get9_n_lessbits(LEN_BYTE,
690                                   pInputStream);
691
692    } /* end for */
693
694    if (pVars->current_program < 0)
695    {
696        /*
697         * If this is the first PCE, it becomes the current, regardless of
698         * its tag number.
699         */
700        pVars->current_program = tag;
701
702    } /* end if (pVars->current_program < 0) */
703
704
705    if (tag == (UInt)pVars->current_program)
706    {
707        /*
708         * This branch is reached under two conditions:
709         * 1) This is the first PCE found, it was selected in the above if
710         *    block. In all encoders found thus far, the tag value has been
711         *    zero.
712         * 2) A PCE has been sent by the encoder with a tag that matches the
713         *    the first one sent. It will then be re-read. No encoder found
714         *    thus far re-sends a PCE, when looking at ADIF files.
715         *
716         * Regardless, the temporary PCE will now be copied into the
717         * the one official program configuration.
718         */
719        pv_memcpy(
720            &pVars->prog_config,
721            pScratchPCE,
722            sizeof(ProgConfig));
723
724        /* enter configuration into MC_Info structure */
725        status =
726            set_mc_info(
727                &pVars->mc_info,
728                (tMP4AudioObjectType)(pVars->prog_config.profile + 1),
729                pVars->prog_config.sampling_rate_idx,
730                pVars->prog_config.front.ele_tag[0],
731                pVars->prog_config.front.ele_is_cpe[0],
732                pVars->winmap,
733                pVars->SFBWidth128);
734
735    } /* end if (tag == pVars->current_program) */
736
737    return (status);
738}
739
740