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 // -*- c++ -*- 19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 20 21 // A M R F I L E P A R S E R 22 23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 24 25 26 /** 27 * @file amrfileparser.h 28 * @brief This file defines the raw GSM-AMR file parser. 29 */ 30 31 #ifndef AMRFILEPARSER_H_INCLUDED 32 #define AMRFILEPARSER_H_INCLUDED 33 34 //---------------------------------------------------------------------------- 35 // INCLUDES 36 //---------------------------------------------------------------------------- 37 38 #ifndef OSCL_BASE_H_INCLUDED 39 #include "oscl_base.h" 40 #endif 41 42 #ifndef OSCL_STRING_H_INCLUDED 43 #include "oscl_string.h" 44 #endif 45 46 #ifndef OSCL_FILE_IO_H_INCLUDED 47 #include "oscl_file_io.h" 48 #endif 49 50 #ifndef OSCL_MEM_H_INCLUDED 51 #include "oscl_mem.h" 52 #endif 53 54 #ifndef OSCL_VECTOR_H_INCLUDED 55 #include "oscl_vector.h" 56 #endif 57 58 #ifndef PV_GAU_H 59 #include "pv_gau.h" 60 #endif 61 #ifndef PVFILE_H 62 #include "pvfile.h" 63 #endif 64 65 #ifndef PVLOGGER_H_INCLUDED 66 #include "pvlogger.h" 67 #endif 68 69 #define PVMF_AMRPARSER_LOGDIAGNOSTICS(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG,iDiagnosticLogger,PVLOGMSG_INFO,m); 70 #define PVMF_AMRPARSER_LOGERROR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m); 71 #define PVMF_AMRPARSER_LOGDEBUG(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_DEBUG,m); 72 73 #define NO_POSSIBLE_MODES 16 74 75 //---------------------------------------------------------------------------- 76 // CONSTANTS 77 //---------------------------------------------------------------------------- 78 79 #define MAX_NUM_PACKED_INPUT_BYTES 61 /* Max number of packed input bytes */ 80 #define MAX_NUM_FRAMES_PER_BUFF 64 /* Max number of frames queued per call */ 81 #define NUM_BITS_PER_BYTE 8 /* There are 8 bits in a byte */ 82 #define TIME_STAMP_PER_FRAME 20 //160 /* Time stamp value per frame of AMR */ 83 84 /* Bit format supported by the parser */ 85 enum TAMRFormat 86 { 87 EAMRIF2, // IF2 88 EAMRETS, // ETS 89 EAMRIETF_SingleNB, // IETF storage, single channel, AMR-NB 90 EAMRIETF_MultiNB, // IETF storage, multichannel, AMR-NB 91 EAMRIETF_SingleWB, // IETF storage, single channel, AMR-WB 92 EAMRIETF_MultiWB, // IETF storage, multichannel, AMR-WB 93 EAMRWMF, // WMF format (PV's proprietary format) 94 EAMRUnrecognized // Unknown 95 }; 96 97 /* Bit rates supported by the parser */ 98 typedef enum 99 { 100 AMRFF_AMR_475 = 0, 101 AMRFF_AMR_515, 102 AMRFF_AMR_59, 103 AMRFF_AMR_67, 104 AMRFF_AMR_74, 105 AMRFF_AMR_795, 106 AMRFF_AMR_102, 107 AMRFF_AMR_122, 108 AMRFF_AMR_SID, 109 AMRFF_GSM_EFR_SID, 110 AMRFF_TDMA_EFR_SID, 111 AMRFF_PDC_EFR_SID, 112 AMRFF_FOR_FUTURE_USE1, 113 AMRFF_FOR_FUTURE_USE2, 114 AMRFF_FOR_FUTURE_USE3, 115 AMRFF_NO_DATA 116 117 } AMRFF_Frame_Type_3GPP; 118 119 typedef enum 120 { 121 AMRFF_WB_660 = 0, 122 AMRFF_WB_885, 123 AMRFF_WB_1265, 124 AMRFF_WB_1425, 125 AMRFF_WB_1585, 126 AMRFF_WB_1825, 127 AMRFF_WB_1985, 128 AMRFF_WB_2305, 129 AMRFF_WB_2385, 130 AMRFF_WB_SID, 131 AMRFF_WB_FOR_FUTURE_USE1, 132 AMRFF_WB_FOR_FUTURE_USE2, 133 AMRFF_WB_FOR_FUTURE_USE3, 134 AMRFF_WB_FOR_FUTURE_USE4, 135 AMRFF_WB_SPEECH_LOST, 136 AMRFF_WB_NO_DATA 137 } AMRFF_WB_Frame_Type_3GPP; 138 139 typedef struct 140 { 141 int32 iBitrate; 142 int32 iTimescale; 143 int32 iDuration; 144 int32 iFileSize; 145 int32 iAmrFormat; 146 } TPVAmrFileInfo; 147 148 //---------------------------------------------------------------------------- 149 // FORWARD CLASS DECLARATIONS 150 //---------------------------------------------------------------------------- 151 152 153 /** 154 * @brief The bitstreamObject Class is the class used by the AMR parser to 155 * manipulate the bitstream read from the file. 156 */ 157 class bitstreamObject 158 { 159 public: 160 enum 161 { 162 MAIN_BUFF_SIZE = 8192, 163 SECOND_BUFF_SIZE = 61, 164 165 // error types for GetNextBundledAccessUnits(), 166 // the definition is consistent with MP4_ERROR_CODE in iSucceedFail.h 167 MISC_ERROR = -2, 168 READ_ERROR = -1, 169 EVERYTHING_OK = 0, 170 END_OF_FILE = 62, 171 DATA_INSUFFICIENT = 141 172 }; 173 174 /** 175 * @brief Constructor 176 * 177 * @param pFile Pointer to file pointer containing bitstream 178 * @returns None 179 */ 180 bitstreamObject(PVLogger *aLogger, PVFile* pFile = NULL) 181 { 182 oscl_memset(this, 0, sizeof(bitstreamObject)); 183 iLogger = aLogger; 184 init(pFile); 185 iBuffer = OSCL_ARRAY_NEW(uint8, bitstreamObject::MAIN_BUFF_SIZE + bitstreamObject::SECOND_BUFF_SIZE); 186 if (iBuffer) 187 { 188 iStatus = true; 189 } 190 else 191 { 192 iStatus = false; 193 } 194 } 195 196 /** 197 * @brief Destructor 198 * 199 * @param None 200 * @returns None 201 */ 202 ~bitstreamObject() 203 { 204 /*init();*/ 205 if (iBuffer) 206 { 207 OSCL_ARRAY_DELETE(iBuffer); 208 iBuffer = NULL; 209 } 210 } 211 212 /** 213 * @brief Returns current bitstream status 214 * 215 * @param None 216 * @returns true=Bitstream instantiated; false=no bitstream 217 */ 218 inline bool get() 219 { 220 return iStatus; 221 } 222 223 /** 224 * @brief Re-positions the file pointer. Specially used in ResetPlayback() 225 * 226 * @param filePos Position in file to move to. 227 * @returns None 228 */ 229 int32 reset(int32 filePos = 0); 230 231 /** 232 * @brief Retrieves clip information: file size, format(WMF or IF2) and frame_type(bitrate) 233 * 234 * @param fileSize Size of file 235 * @param format AMR format 236 * @param frame_type Frame type 237 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 238 */ 239 int32 getFileInfo(int32& fileSize, int32& format, int32& frame_type); 240 241 /** 242 * @brief Retrieves one frame data plus frame type, used in getNextBundledAccessUnits(). 243 * 244 * @param frameBuffer Buffer containing frame read 245 * @param frame_type Frame type of frame 246 * @param bHeaderIncluded Indicates whether to include header or not in buffer 247 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 248 */ 249 int32 getNextFrame(uint8* frameBuffer, uint8& frame_type, bool bHeaderIncluded = false); 250 251 /** 252 * @brief Undo getNextFrame in case gau buffer overflow occurs when getting next frame 253 * 254 * @param offset Number of bytes to move back from current position in file 255 * @returns None 256 */ 257 void undoGetNextFrame(int32 offset) 258 { 259 iPos -= offset; 260 } 261 262 /** 263 * @brief Returns the maximum buffer size of the track 264 * 265 * @param None 266 * @returns Maximum buffer size 267 */ 268 int32 getTrackMaxBufferSizeDB() 269 { 270 return iMax_size; 271 } 272 273 private: 274 275 /** 276 * @brief Initialization 277 * 278 * @param pFile File pointer 279 * @returns None 280 */ 281 inline void init(PVFile* pFile = NULL) 282 { 283 iFileSize = 0; 284 iBytesRead = 0; 285 iBytesProcessed = 0; 286 ipAMRFile = pFile; 287 iActual_size = iMax_size = bitstreamObject::MAIN_BUFF_SIZE; 288 iPos = bitstreamObject::MAIN_BUFF_SIZE + bitstreamObject::SECOND_BUFF_SIZE; 289 iAmrFormat = iFrame_type = 0; 290 iInitFilePos = 0; 291 292 if (ipAMRFile) 293 { 294 ipAMRFile->Seek(0, Oscl_File::SEEKSET); 295 } 296 } 297 298 /** 299 * @brief Reads data from bitstream, this is the only function to read data from file 300 * 301 * @param None 302 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 303 */ 304 int32 refill(); 305 306 /** 307 * @brief Parses the IETF bitstream header: "$!AMR" + 0x0a, and get format(IETF, WMF or IF2) 308 * 309 * @param None 310 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 311 */ 312 int32 parseIETFHeader(); 313 314 /** 315 * @brief Gets the updated file size 316 * 317 * @param None 318 * @returns Result of operation: true/false. 319 */ 320 bool UpdateFileSize(); 321 322 323 private: 324 int32 iPos; // pointer for iBuffer[] 325 int32 iActual_size; // number of bytes read from a file once <= max_size 326 int32 iMax_size; // max_size = bitstreamStruc::MAIN_BUFF_SIZE 327 int32 iBytesRead; // (cumulative) number of bytes read from a file so far 328 int32 iBytesProcessed; 329 int32 iFileSize; // file size of the ipAMRFile 330 int32 iAmrFormat; // 0 : WMF ; 1 : IF2 ; >=2 : IETF(AMR, AMR_WB, AMR_MC, AMR_WB_MC) 331 uint32 iInitFilePos; // For IETF bitstream, iInitFilePos = IETF header size 332 int32 iFrame_type; // frame type got from the very first frame 333 334 uint8 *iBuffer; 335 PVFile* ipAMRFile; // bitstream file 336 bool iStatus; 337 PVLogger *iLogger; 338 }; 339 340 /** 341 * @brief The CAMRFileParser Class is the class that will construct and maintain 342 * all the necessary data structures to be able to render a valid AMR file 343 * to disk. 344 * 345 * This class supports the following AMR file format specs: IF2, WMF, ETS 346 */ 347 class PVMFCPMPluginAccessInterfaceFactory; 348 class CAMRFileParser 349 { 350 public: 351 typedef OsclMemAllocator alloc_type; 352 353 /** 354 * @brief Constructor 355 * 356 * @param None 357 * @returns None 358 */ 359 OSCL_IMPORT_REF CAMRFileParser(); 360 361 /** 362 * @brief Destructor 363 * 364 * @param None 365 * @returns None 366 */ 367 OSCL_IMPORT_REF ~CAMRFileParser(); 368 369 /** 370 * @brief Opens the specified clip and performs initialization of the parser 371 * 372 * @param aClip Filename to parse 373 * @param aInitParsingEnable Indicates whether to setup random positioning (true) 374 * or not (false) 375 * @param aFileSession Pointer to opened file server session. Used when opening 376 * and reading the file on certain operating systems. 377 * @returns true if the init succeeds, else false. 378 */ 379 OSCL_IMPORT_REF bool InitAMRFile(OSCL_wString& aClip, bool aInitParsingEnable = true, Oscl_FileServer* aFileSession = NULL, PVMFCPMPluginAccessInterfaceFactory*aCPM = NULL, OsclFileHandle*aHandle = NULL, uint32 countToClaculateRDATimeInterval = 1); 380 381 /** 382 * @brief Retrieves information about the clip such as bit rate, sampling frequency, etc. 383 * 384 * @param aInfo Storage for information retrieved 385 * @returns True if successful, False otherwise. 386 */ 387 OSCL_IMPORT_REF bool RetrieveFileInfo(TPVAmrFileInfo& aInfo); 388 389 /** 390 * @brief Resets the parser variables to allow start of playback at a new position 391 * 392 * @param aStartTime Time where to start playback from 393 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 394 */ 395 OSCL_IMPORT_REF int32 ResetPlayback(int32 aStartTime = 0); 396 397 /** 398 * @brief Returns the actual starting timestamp for a specified start time 399 * 400 * @param aStartTime Time where to start playback from 401 * @returns Timestamp corresponding to the actual start position 402 */ 403 OSCL_IMPORT_REF uint32 SeekPointFromTimestamp(uint32 aStartTime = 0); 404 405 /** 406 * @brief Attempts to read in the number of AMR frames specified by aNumSamples. 407 * It formats the read data to WMF bit order and stores it in the GAU structure. 408 * 409 * @param aNumSamples Requested number of frames to be read from file 410 * @param aGau Frame information structure of type GAU 411 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 412 */ 413 OSCL_IMPORT_REF int32 GetNextBundledAccessUnits(uint32 *aNumSamples, GAU *aGau); 414 415 /** 416 * @brief Returns the value of the next timestamp that will be 417 * returned in a call to GetNextBundledAccessUnits. 418 * 419 * @param aTimestamp returned value of next timestamp 420 * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. 421 */ 422 OSCL_IMPORT_REF int32 PeekNextTimestamp(uint32 *aTimestamp); 423 424 /** 425 * @brief Returns the frame type of the current AMR frame 426 * 427 * @param aFrameIndex Index to frame 428 * @returns Frame type 429 */ 430 OSCL_IMPORT_REF uint8 GetFrameTypeInCurrentBundledAccessUnits(uint32 aFrameIndex); 431 432 /** 433 * @brief Returns the maximum buffer size of the track 434 * 435 * @param None 436 * @returns Buffer size 437 */ 438 OSCL_IMPORT_REF int32 getTrackMaxBufferSizeDB(); 439 440 OSCL_IMPORT_REF uint8* getCodecSpecificInfo(); 441 442 private: 443 void SetBitRate(AMRFF_Frame_Type_3GPP aFrameType3GPP); 444 void SetBitRate(AMRFF_WB_Frame_Type_3GPP aFrameType3GPP); 445 446 private: 447 PVFile iAMRFile; 448 int32 iAMRDuration; 449 int32 iAMRBitRate; 450 int32 iAMRFormat; 451 int32 iAMRFileSize; 452 int32 iTotalNumFramesRead; 453 bool iEndOfFileReached; 454 bitstreamObject *ipBSO; 455 Oscl_Vector<int32, alloc_type> iRPTable; // table containing sync indexes for repositioning 456 457 /* Decoder input buffer for 1 raw encoded speech frame (IETF or IF2) */ 458 uint8 iAMRFrameBuffer[MAX_NUM_PACKED_INPUT_BYTES]; 459 uint8 iAMRFrameHeaderBuffer[MAX_NUM_FRAMES_PER_BUFF]; 460 uint32 iRandomAccessTimeInterval; 461 uint32 iCountToClaculateRDATimeInterval; 462 bool CalculateDuration(bool aInitParsingEnable, uint32 countToClaculateRDATimeInterval); 463 PVLogger* iLogger; 464 PVLogger* iDiagnosticLogger; 465 466 }; 467 468 #endif //AMRFILEPARSER_H_INCLUDED 469 470