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_adif_header.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: Change to PV template, remove default config parameter, 31 move some functionality into get_prog_config(). 32 33 Description: Update per code review 34 1) Add parameter pScratchPCE 35 2) Change way ADIF_ID is read in. 36 3) Fix comments 37 4) ADD a test for status != SUCCESS in loop. 38 39 Description: The ADIF_Header has now been delegated to the "scratch memory" 40 union. This change inside s_tDec_Int_File.h had to be reflected here also. 41 42 Description: Updated the SW template to include the full pathname to the 43 source file and a slightly modified copyright header. 44 45 Who: Date: 46 Description: 47 48 ------------------------------------------------------------------------------ 49 INPUT AND OUTPUT DEFINITIONS 50 51 Inputs: 52 pVars = pointer to the structure that contains the current state 53 of this instance of the library, of data type pointer to 54 tDec_Int_File 55 56 pScratchPCE = pointer to a ProgConfig structure used as scratch in the 57 the function get_prog_config. of data type pointer to 58 ProgConfig 59 60 Local Stores/Buffers/Pointers Needed: None 61 62 Global Stores/Buffers/Pointers Needed: None 63 64 Outputs: 65 The function returns 0 if no error occurred, non-zero otherwise. 66 67 Pointers and Buffers Modified: 68 pVars->adif_header contents are updated with the some of the ADIF header 69 contents 70 pVars->tempProgConfig contents are overwritten with last PCE found, 71 which is most likely the first one found. 72 pVars->prog_config contents are updated with the first PCE found. 73 pVars->inputStream contents are modify in such a way that the 74 stream is moved further along in the buffer. 75 pVars->SFBWidth128 contents may be updated. 76 pVars->winSeqInfo contents may be updated. 77 pScratchPCE contents may be updated. 78 79 Local Stores Modified: None 80 81 Global Stores Modified: None 82 83 ------------------------------------------------------------------------------ 84 FUNCTION DESCRIPTION 85 86 This function reads in the ADIF Header found at the front of ADIF streams. 87 If the header is not found an error is returned. An ADIF header can contain 88 from zero to sixteen program configuration elements (PCE). This function, and 89 the rest of the library, saves and uses the first PCE found. 90 ------------------------------------------------------------------------------ 91 REQUIREMENTS 92 93 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 PSEUDO-CODE 128 129 CALL getbits( 130 neededBits = 2 * LEN_BYTE, 131 pInputStream = pInputStream) 132 MODIFYING( pInputStream ) 133 RETURNING( theIDFromFile ) 134 135 CALL getbits( 136 neededBits = 2 * LEN_BYTE, 137 pInputStream = pInputStream) 138 MODIFYING( pInputStream ) 139 RETURNING( temp ) 140 141 theIDFromFile = (theIDFromFile << (2*LEN_BYTE)) | temp; 142 143 IF (theIDFromFile != ADIF_ID) 144 THEN 145 146 pInputStream->usedBits -= (4 * LEN_BYTE); 147 148 status = -1; 149 ELSE 150 CALL getbits( 151 neededBits = LEN_COPYRT_PRES, 152 pInputStream = pInputStream) 153 MODIFYING( pInputStream ) 154 RETURNING( temp ) 155 156 IF (temp != FALSE) THEN 157 FOR (i = LEN_COPYRT_ID; i > 0; i--) 158 CALL getbits( 159 neededBits = LEN_BYTE, 160 pInputStream = pInputStream) 161 MODIFYING( pInputStream ) 162 163 END FOR 164 END IF 165 166 CALL getbits( 167 neededBits = LEN_ORIG + LEN_HOME, 168 pInputStream = pInputStream) 169 MODIFYING( pInputStream ) 170 171 CALL getbits( 172 neededBits = LEN_BS_TYPE, 173 pInputStream = pInputStream) 174 MODIFYING( pInputStream ) 175 RETURNING( bitStreamType ) 176 177 CALL getbits( 178 neededBits = LEN_BIT_RATE, 179 pInputStream = pInputStream) 180 MODIFYING( pInputStream ) 181 RETURNING( pHeader->bitrate ) 182 183 CALL getbits( 184 neededBits = LEN_NUM_PCE, 185 pInputStream = pInputStream) 186 MODIFYING( pInputStream ) 187 RETURNING( numConfigElementsMinus1 ) 188 189 FOR ( i = numConfigElementsMinus1; 190 (i >= 0) && (status == SUCCESS); 191 i--) 192 193 IF (bitStreamType == CONSTANT_RATE_BITSTREAM) THEN 194 CALL getbits( 195 neededBits = LEN_ADIF_BF, 196 pInputStream = pInputStream) 197 MODIFYING( pInputStream ) 198 END IF 199 200 CALL get_prog_config( 201 pVars = pVars) 202 MODIFYING( pVars->prog_config ) 203 RETURNING( status ) 204 205 END FOR 206 END IF 207 208 RETURN (status) 209 210 ------------------------------------------------------------------------------ 211 RESOURCES USED 212 When the code is written for a specific target processor the 213 the resources used should be documented below. 214 215 STACK USAGE: [stack count for this module] + [variable to represent 216 stack usage for each subroutine called] 217 218 where: [stack usage variable] = stack usage for [subroutine 219 name] (see [filename].ext) 220 221 DATA MEMORY USED: x words 222 223 PROGRAM MEMORY USED: x words 224 225 CLOCK CYCLES: [cycle count equation for this module] + [variable 226 used to represent cycle count for each subroutine 227 called] 228 229 where: [cycle count variable] = cycle count for [subroutine 230 name] (see [filename].ext) 231 232 ------------------------------------------------------------------------------ 233 */ 234 235 /*---------------------------------------------------------------------------- 236 ; INCLUDES 237 ----------------------------------------------------------------------------*/ 238 #include "pv_audio_type_defs.h" 239 #include "e_adif_const.h" 240 241 #include "s_progconfig.h" 242 #include "s_adif_header.h" 243 #include "s_bits.h" 244 #include "s_mc_info.h" 245 #include "s_frameinfo.h" 246 #include "s_tdec_int_file.h" 247 248 #include "get_prog_config.h" 249 #include "ibstream.h" 250 251 #include "get_adif_header.h" 252 253 /*---------------------------------------------------------------------------- 254 ; MACROS 255 ; Define module specific macros here 256 ----------------------------------------------------------------------------*/ 257 258 /*---------------------------------------------------------------------------- 259 ; DEFINES 260 ; Include all pre-processor statements here. Include conditional 261 ; compile variables also. 262 ----------------------------------------------------------------------------*/ 263 264 /* 265 * This constant is simply the characters 'A' 'D' 'I' 'F' compressed into 266 * a UInt32. Any possible endian problems that exist must be solved by 267 * the function that fills the buffer and getbits(), or this constant and 268 * the rest of the bit stream will not work. 269 */ 270 #define ADIF_ID (0x41444946) 271 272 /*---------------------------------------------------------------------------- 273 ; LOCAL FUNCTION DEFINITIONS 274 ; Function Prototype declaration 275 ----------------------------------------------------------------------------*/ 276 277 /*---------------------------------------------------------------------------- 278 ; LOCAL VARIABLE DEFINITIONS 279 ; Variable declaration - defined here and used outside this module 280 ----------------------------------------------------------------------------*/ 281 282 /*---------------------------------------------------------------------------- 283 ; EXTERNAL FUNCTION REFERENCES 284 ; Declare functions defined elsewhere and referenced in this module 285 ----------------------------------------------------------------------------*/ 286 287 /*---------------------------------------------------------------------------- 288 ; EXTERNAL VARIABLES REFERENCES 289 ; Declare variables used in this module but defined elsewhere 290 ----------------------------------------------------------------------------*/ 291 292 Int get_adif_header( 293 tDec_Int_File *pVars, 294 ProgConfig *pScratchPCE) 295 { 296 Int i; 297 UInt32 temp; 298 Int numConfigElementsMinus1; 299 Int bitStreamType; 300 UInt32 theIDFromFile; 301 302 BITS *pInputStream = &pVars->inputStream; 303 ADIF_Header *pHeader = &pVars->scratch.adif_header; 304 Int status = SUCCESS; 305 306 /* 307 * The ADIF_ID field is 32 bits long, one more than what getbits() can 308 * do, so read the field in two parts. There is no point in saving the 309 * string - it either matches or it does not. If it matches, it must 310 * have been 'ADIF' 311 */ 312 313 theIDFromFile = get17_n_lessbits((2 * LEN_BYTE), pInputStream); 314 315 temp = get17_n_lessbits((2 * LEN_BYTE), pInputStream); 316 317 theIDFromFile = (theIDFromFile << (2 * LEN_BYTE)) | temp; 318 319 320 if (theIDFromFile != ADIF_ID) 321 { 322 /* 323 * Rewind the bit stream pointer so a search for ADTS header 324 * can start at the beginning. 325 */ 326 327 pInputStream->usedBits -= (4 * LEN_BYTE); 328 329 /* 330 * The constant in the next line needs to be updated when 331 * error handling method is determined. 332 */ 333 status = -1; 334 } 335 else 336 { 337 /* 338 * To save space, the unused fields are read in, but not saved. 339 */ 340 341 /* copyright string */ 342 temp = 343 get1bits(/* LEN_COPYRT_PRES,*/ 344 pInputStream); 345 346 if (temp != FALSE) 347 { 348 /* 349 * Read in and ignore the copyright string. If restoring 350 * watch out for count down loop. 351 */ 352 353 for (i = LEN_COPYRT_ID; i > 0; i--) 354 { 355 get9_n_lessbits(LEN_BYTE, 356 pInputStream); 357 } /* end for */ 358 359 /* 360 * Make sure to terminate the string with '\0' if restoring 361 * the the copyright string. 362 */ 363 364 } /* end if */ 365 366 /* Combine the original/copy and fields into one call */ 367 get9_n_lessbits( 368 LEN_ORIG + LEN_HOME, 369 pInputStream); 370 371 bitStreamType = 372 get1bits(/* LEN_BS_TYPE,*/ 373 pInputStream); 374 375 pHeader->bitrate = 376 getbits( 377 LEN_BIT_RATE, 378 pInputStream); 379 380 /* 381 * Read in all the Program Configuration Elements. 382 * For this library, only one of the up to 16 possible PCE's will be 383 * saved. Since each PCE must be read, a temporary PCE structure is 384 * used, and if that PCE is the one to use, it is copied into the 385 * single PCE. This is done inside of get_prog_config() 386 */ 387 388 numConfigElementsMinus1 = get9_n_lessbits(LEN_NUM_PCE, 389 pInputStream); 390 391 for (i = numConfigElementsMinus1; 392 (i >= 0) && (status == SUCCESS); 393 i--) 394 { 395 /* 396 * For ADIF contant bit rate streams, the _encoder_ buffer 397 * fullness is transmitted. This version of an AAC decoder has 398 * no use for this variable; yet it must be read in to move 399 * the bitstream pointers. 400 */ 401 402 if (bitStreamType == CONSTANT_RATE_BITSTREAM) 403 { 404 getbits( 405 LEN_ADIF_BF, 406 pInputStream); 407 } /* end if */ 408 409 pVars->adif_test = 1; 410 /* Get one program configuration element */ 411 status = 412 get_prog_config( 413 pVars, 414 pScratchPCE); 415 416 #ifdef AAC_PLUS 417 418 /* 419 * For implicit signalling, no hint that sbr or ps is used, so we need to 420 * check the sampling frequency of the aac content, if lesser or equal to 421 * 24 KHz, by defualt upsample, otherwise, do nothing 422 */ 423 if ((pVars->prog_config.sampling_rate_idx >= 6) && (pVars->aacPlusEnabled == true) && 424 pVars->mc_info.audioObjectType == MP4AUDIO_AAC_LC) 425 { 426 pVars->mc_info.upsamplingFactor = 2; 427 pVars->prog_config.sampling_rate_idx -= 3; 428 pVars->mc_info.sbrPresentFlag = 1; 429 pVars->sbrDecoderData.SbrChannel[0].syncState = UPSAMPLING; 430 pVars->sbrDecoderData.SbrChannel[1].syncState = UPSAMPLING; 431 } 432 #endif 433 434 435 436 } /* end for */ 437 438 439 } /* end 'else' of --> if (theIDFromFile != ADIF_ID) */ 440 441 return status; 442 443 } /* end get_adif_header */ 444