Home | History | Annotate | Download | only in include
      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