| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| // -*- c++ -*- |
| // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
| |
| // A M R F I L E P A R S E R |
| |
| // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
| |
| |
| /** |
| * @file amrfileparser.h |
| * @brief This file defines the raw GSM-AMR file parser. |
| */ |
| |
| #ifndef AMRFILEPARSER_H_INCLUDED |
| #define AMRFILEPARSER_H_INCLUDED |
| |
| //---------------------------------------------------------------------------- |
| // INCLUDES |
| //---------------------------------------------------------------------------- |
| |
| #ifndef OSCL_BASE_H_INCLUDED |
| #include "oscl_base.h" |
| #endif |
| |
| #ifndef OSCL_STRING_H_INCLUDED |
| #include "oscl_string.h" |
| #endif |
| |
| #ifndef OSCL_FILE_IO_H_INCLUDED |
| #include "oscl_file_io.h" |
| #endif |
| |
| #ifndef OSCL_MEM_H_INCLUDED |
| #include "oscl_mem.h" |
| #endif |
| |
| #ifndef OSCL_VECTOR_H_INCLUDED |
| #include "oscl_vector.h" |
| #endif |
| |
| #ifndef PV_GAU_H |
| #include "pv_gau.h" |
| #endif |
| #ifndef PVFILE_H |
| #include "pvfile.h" |
| #endif |
| |
| #ifndef PVLOGGER_H_INCLUDED |
| #include "pvlogger.h" |
| #endif |
| |
| #define PVMF_AMRPARSER_LOGDIAGNOSTICS(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG,iDiagnosticLogger,PVLOGMSG_INFO,m); |
| #define PVMF_AMRPARSER_LOGERROR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m); |
| |
| #define NO_POSSIBLE_MODES 16 |
| |
| //---------------------------------------------------------------------------- |
| // CONSTANTS |
| //---------------------------------------------------------------------------- |
| |
| #define MAX_NUM_PACKED_INPUT_BYTES 61 /* Max number of packed input bytes */ |
| #define MAX_NUM_FRAMES_PER_BUFF 64 /* Max number of frames queued per call */ |
| #define NUM_BITS_PER_BYTE 8 /* There are 8 bits in a byte */ |
| #define TIME_STAMP_PER_FRAME 20 //160 /* Time stamp value per frame of AMR */ |
| |
| /* Bit format supported by the parser */ |
| enum TAMRFormat |
| { |
| EAMRIF2, // IF2 |
| EAMRETS, // ETS |
| EAMRIETF_SingleNB, // IETF storage, single channel, AMR-NB |
| EAMRIETF_MultiNB, // IETF storage, multichannel, AMR-NB |
| EAMRIETF_SingleWB, // IETF storage, single channel, AMR-WB |
| EAMRIETF_MultiWB, // IETF storage, multichannel, AMR-WB |
| EAMRWMF, // WMF format (PV's proprietary format) |
| EAMRUnrecognized // Unknown |
| }; |
| |
| /* Bit rates supported by the parser */ |
| typedef enum |
| { |
| AMRFF_AMR_475 = 0, |
| AMRFF_AMR_515, |
| AMRFF_AMR_59, |
| AMRFF_AMR_67, |
| AMRFF_AMR_74, |
| AMRFF_AMR_795, |
| AMRFF_AMR_102, |
| AMRFF_AMR_122, |
| AMRFF_AMR_SID, |
| AMRFF_GSM_EFR_SID, |
| AMRFF_TDMA_EFR_SID, |
| AMRFF_PDC_EFR_SID, |
| AMRFF_FOR_FUTURE_USE1, |
| AMRFF_FOR_FUTURE_USE2, |
| AMRFF_FOR_FUTURE_USE3, |
| AMRFF_NO_DATA |
| |
| } AMRFF_Frame_Type_3GPP; |
| |
| typedef enum |
| { |
| AMRFF_WB_660 = 0, |
| AMRFF_WB_885, |
| AMRFF_WB_1265, |
| AMRFF_WB_1425, |
| AMRFF_WB_1585, |
| AMRFF_WB_1825, |
| AMRFF_WB_1985, |
| AMRFF_WB_2305, |
| AMRFF_WB_2385, |
| AMRFF_WB_SID, |
| AMRFF_WB_FOR_FUTURE_USE1, |
| AMRFF_WB_FOR_FUTURE_USE2, |
| AMRFF_WB_FOR_FUTURE_USE3, |
| AMRFF_WB_FOR_FUTURE_USE4, |
| AMRFF_WB_SPEECH_LOST, |
| AMRFF_WB_NO_DATA |
| } AMRFF_WB_Frame_Type_3GPP; |
| |
| typedef struct |
| { |
| int32 iBitrate; |
| int32 iTimescale; |
| int32 iDuration; |
| int32 iFileSize; |
| int32 iAmrFormat; |
| } TPVAmrFileInfo; |
| |
| //---------------------------------------------------------------------------- |
| // FORWARD CLASS DECLARATIONS |
| //---------------------------------------------------------------------------- |
| |
| |
| /** |
| * @brief The bitstreamObject Class is the class used by the AMR parser to |
| * manipulate the bitstream read from the file. |
| */ |
| class bitstreamObject |
| { |
| public: |
| enum |
| { |
| MAIN_BUFF_SIZE = 8192, |
| SECOND_BUFF_SIZE = 61, |
| |
| // error types for GetNextBundledAccessUnits(), |
| // the definition is consistent with MP4_ERROR_CODE in iSucceedFail.h |
| MISC_ERROR = -2, |
| READ_ERROR = -1, |
| EVERYTHING_OK = 0, |
| END_OF_FILE = 62 |
| }; |
| |
| /** |
| * @brief Constructor |
| * |
| * @param pFile Pointer to file pointer containing bitstream |
| * @returns None |
| */ |
| bitstreamObject(PVFile* pFile = NULL) |
| { |
| oscl_memset(this, 0, sizeof(bitstreamObject)); |
| init(pFile); |
| iBuffer = OSCL_ARRAY_NEW(uint8, bitstreamObject::MAIN_BUFF_SIZE + bitstreamObject::SECOND_BUFF_SIZE); |
| if (iBuffer) |
| { |
| iStatus = true; |
| } |
| else |
| { |
| iStatus = false; |
| } |
| } |
| |
| /** |
| * @brief Destructor |
| * |
| * @param None |
| * @returns None |
| */ |
| ~bitstreamObject() |
| { |
| /*init();*/ |
| if (iBuffer) |
| { |
| OSCL_ARRAY_DELETE(iBuffer); |
| iBuffer = NULL; |
| } |
| } |
| |
| /** |
| * @brief Returns current bitstream status |
| * |
| * @param None |
| * @returns true=Bitstream instantiated; false=no bitstream |
| */ |
| inline bool get() |
| { |
| return iStatus; |
| } |
| |
| /** |
| * @brief Re-positions the file pointer. Specially used in ResetPlayback() |
| * |
| * @param filePos Position in file to move to. |
| * @returns None |
| */ |
| int32 reset(int32 filePos = 0); |
| |
| /** |
| * @brief Retrieves clip information: file size, format(WMF or IF2) and frame_type(bitrate) |
| * |
| * @param fileSize Size of file |
| * @param format AMR format |
| * @param frame_type Frame type |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| int32 getFileInfo(int32& fileSize, int32& format, int32& frame_type); |
| |
| /** |
| * @brief Retrieves one frame data plus frame type, used in getNextBundledAccessUnits(). |
| * |
| * @param frameBuffer Buffer containing frame read |
| * @param frame_type Frame type of frame |
| * @param bHeaderIncluded Indicates whether to include header or not in buffer |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| int32 getNextFrame(uint8* frameBuffer, uint8& frame_type, bool bHeaderIncluded = false); |
| |
| /** |
| * @brief Undo getNextFrame in case gau buffer overflow occurs when getting next frame |
| * |
| * @param offset Number of bytes to move back from current position in file |
| * @returns None |
| */ |
| void undoGetNextFrame(int32 offset) |
| { |
| iPos -= offset; |
| } |
| |
| /** |
| * @brief Returns the maximum buffer size of the track |
| * |
| * @param None |
| * @returns Maximum buffer size |
| */ |
| int32 getTrackMaxBufferSizeDB() |
| { |
| return iMax_size; |
| } |
| |
| private: |
| |
| /** |
| * @brief Initialization |
| * |
| * @param pFile File pointer |
| * @returns None |
| */ |
| inline void init(PVFile* pFile = NULL) |
| { |
| iFileSize = 0; |
| iBytesRead = 0; |
| iBytesProcessed = 0; |
| ipAMRFile = pFile; |
| iActual_size = iMax_size = bitstreamObject::MAIN_BUFF_SIZE; |
| iPos = bitstreamObject::MAIN_BUFF_SIZE + bitstreamObject::SECOND_BUFF_SIZE; |
| iAmrFormat = iFrame_type = 0; |
| iInitFilePos = 0; |
| |
| if (ipAMRFile) |
| { |
| ipAMRFile->Seek(0, Oscl_File::SEEKSET); |
| } |
| } |
| |
| /** |
| * @brief Reads data from bitstream, this is the only function to read data from file |
| * |
| * @param None |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| int32 refill(); |
| |
| /** |
| * @brief Parses the IETF bitstream header: "$!AMR" + 0x0a, and get format(IETF, WMF or IF2) |
| * |
| * @param None |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| int32 parseIETFHeader(); |
| |
| private: |
| int32 iPos; // pointer for iBuffer[] |
| int32 iActual_size; // number of bytes read from a file once <= max_size |
| int32 iMax_size; // max_size = bitstreamStruc::MAIN_BUFF_SIZE |
| int32 iBytesRead; // (cumulative) number of bytes read from a file so far |
| int32 iBytesProcessed; |
| int32 iFileSize; // file size of the ipAMRFile |
| int32 iAmrFormat; // 0 : WMF ; 1 : IF2 ; >=2 : IETF(AMR, AMR_WB, AMR_MC, AMR_WB_MC) |
| uint32 iInitFilePos; // For IETF bitstream, iInitFilePos = IETF header size |
| int32 iFrame_type; // frame type got from the very first frame |
| |
| uint8 *iBuffer; |
| PVFile* ipAMRFile; // bitstream file |
| bool iStatus; |
| }; |
| |
| /** |
| * @brief The CAMRFileParser Class is the class that will construct and maintain |
| * all the necessary data structures to be able to render a valid AMR file |
| * to disk. |
| * |
| * This class supports the following AMR file format specs: IF2, WMF, ETS |
| */ |
| class PVMFCPMPluginAccessInterfaceFactory; |
| class CAMRFileParser |
| { |
| public: |
| typedef OsclMemAllocator alloc_type; |
| |
| /** |
| * @brief Constructor |
| * |
| * @param None |
| * @returns None |
| */ |
| OSCL_IMPORT_REF CAMRFileParser(); |
| |
| /** |
| * @brief Destructor |
| * |
| * @param None |
| * @returns None |
| */ |
| OSCL_IMPORT_REF ~CAMRFileParser(); |
| |
| /** |
| * @brief Opens the specified clip and performs initialization of the parser |
| * |
| * @param aClip Filename to parse |
| * @param aInitParsingEnable Indicates whether to setup random positioning (true) |
| * or not (false) |
| * @param aFileSession Pointer to opened file server session. Used when opening |
| * and reading the file on certain operating systems. |
| * @returns true if the init succeeds, else false. |
| */ |
| OSCL_IMPORT_REF bool InitAMRFile(OSCL_wString& aClip, bool aInitParsingEnable = true, Oscl_FileServer* aFileSession = NULL, PVMFCPMPluginAccessInterfaceFactory*aCPM = NULL, OsclFileHandle*aHandle = NULL, uint32 countToClaculateRDATimeInterval = 1); |
| |
| /** |
| * @brief Retrieves information about the clip such as bit rate, sampling frequency, etc. |
| * |
| * @param aInfo Storage for information retrieved |
| * @returns True if successful, False otherwise. |
| */ |
| OSCL_IMPORT_REF bool RetrieveFileInfo(TPVAmrFileInfo& aInfo); |
| |
| /** |
| * @brief Resets the parser variables to allow start of playback at a new position |
| * |
| * @param aStartTime Time where to start playback from |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| OSCL_IMPORT_REF int32 ResetPlayback(int32 aStartTime = 0); |
| |
| /** |
| * @brief Returns the actual starting timestamp for a specified start time |
| * |
| * @param aStartTime Time where to start playback from |
| * @returns Timestamp corresponding to the actual start position |
| */ |
| OSCL_IMPORT_REF uint32 SeekPointFromTimestamp(uint32 aStartTime = 0); |
| |
| /** |
| * @brief Attempts to read in the number of AMR frames specified by aNumSamples. |
| * It formats the read data to WMF bit order and stores it in the GAU structure. |
| * |
| * @param aNumSamples Requested number of frames to be read from file |
| * @param aGau Frame information structure of type GAU |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| OSCL_IMPORT_REF int32 GetNextBundledAccessUnits(uint32 *aNumSamples, GAU *aGau); |
| |
| /** |
| * @brief Returns the value of the next timestamp that will be |
| * returned in a call to GetNextBundledAccessUnits. |
| * |
| * @param aTimestamp returned value of next timestamp |
| * @returns Result of operation: EVERYTHING_OK, READ_FAILED, etc. |
| */ |
| OSCL_IMPORT_REF int32 PeekNextTimestamp(uint32 *aTimestamp); |
| |
| /** |
| * @brief Returns the frame type of the current AMR frame |
| * |
| * @param aFrameIndex Index to frame |
| * @returns Frame type |
| */ |
| OSCL_IMPORT_REF uint8 GetFrameTypeInCurrentBundledAccessUnits(uint32 aFrameIndex); |
| |
| /** |
| * @brief Returns the maximum buffer size of the track |
| * |
| * @param None |
| * @returns Buffer size |
| */ |
| OSCL_IMPORT_REF int32 getTrackMaxBufferSizeDB(); |
| |
| OSCL_IMPORT_REF uint8* getCodecSpecificInfo(); |
| |
| private: |
| void SetBitRate(AMRFF_Frame_Type_3GPP aFrameType3GPP); |
| void SetBitRate(AMRFF_WB_Frame_Type_3GPP aFrameType3GPP); |
| |
| private: |
| PVFile iAMRFile; |
| int32 iAMRDuration; |
| int32 iAMRBitRate; |
| int32 iAMRFormat; |
| int32 iAMRFileSize; |
| int32 iTotalNumFramesRead; |
| bool iEndOfFileReached; |
| bitstreamObject *ipBSO; |
| Oscl_Vector<int32, alloc_type> iRPTable; // table containing sync indexes for repositioning |
| |
| /* Decoder input buffer for 1 raw encoded speech frame (IETF or IF2) */ |
| uint8 iAMRFrameBuffer[MAX_NUM_PACKED_INPUT_BYTES]; |
| uint8 iAMRFrameHeaderBuffer[MAX_NUM_FRAMES_PER_BUFF]; |
| uint32 iRandomAccessTimeInterval; |
| uint32 iCountToClaculateRDATimeInterval; |
| bool CalculateDuration(bool aInitParsingEnable, uint32 countToClaculateRDATimeInterval); |
| PVLogger* iLogger; |
| PVLogger* iDiagnosticLogger; |
| |
| }; |
| |
| #endif //AMRFILEPARSER_H_INCLUDED |
| |