• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // -*- c++ -*-
20 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
21 
22 //                       M P 3   P A R S E R
23 
24 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
25 
26 
27 /**
28  *  @file mp3parser.h
29  *  @brief This include file contains the definitions for the actual MP3
30  *  file parser.
31  */
32 
33 #ifndef MP3PARSER_H_INCLUDED
34 #define MP3PARSER_H_INCLUDED
35 
36 
37 //----------------------------------------------------------------------
38 // Include Files
39 //----------------------------------------------------------------------
40 #ifndef OSCL_BASE_H_INCLUDED
41 #include "oscl_base.h"
42 #endif
43 #ifndef OSCL_FILE_IO_H_INCLUDED
44 #include "oscl_file_io.h"
45 #endif
46 #ifndef OSCL_MEDIA_DATA_H
47 #include "oscl_media_data.h"
48 #endif
49 #ifndef PVFILE_H_INCLUDED
50 #include "pvfile.h"
51 #endif
52 #ifndef IMP3FF_H_INCLUDED
53 #include "imp3ff.h"
54 #endif
55 #ifndef PV_GAU_H_
56 #include "pv_gau.h"
57 #endif
58 #ifndef PV_ID3_PARCOM_H_INCLUDED
59 #include "pv_id3_parcom.h"
60 #endif
61 #ifndef MP3_UTILS_H_INCLUDED
62 #include "mp3utils.h"
63 #endif
64 #ifndef __MEDIA_CLOCK_CONVERTER_H
65 #include "media_clock_converter.h"
66 #endif
67 #ifndef PVLOGGER_H_INCLUDED
68 #include "pvlogger.h"
69 #endif
70 
71 //----------------------------------------------------------------------
72 // Global Type Declarations
73 //----------------------------------------------------------------------
74 
75 //----------------------------------------------------------------------
76 // Global Constant Declarations
77 //----------------------------------------------------------------------
78 
79 
80 //----------------------------------------------------------------------
81 // Global Data Declarations
82 //----------------------------------------------------------------------
83 
84 
85 //======================================================================
86 //  CLASS DEFINITIONS and FUNCTION DECLARATIONS
87 //======================================================================
88 
89 #define MIN_RANDOM_FRAMES_TO_SCAN 4
90 #define MIN_RANDOM_LOCATION_TO_SCAN 30
91 
92 #define STR_VBRI_HEADER_IDENTIFIER "VBRI"
93 #define STR_XING_HEADER_IDENTIFIER "Xing"
94 #define STR_INFO_HEADER_IDENTIFIER "Info"
95 
96 #define VBR_HEADER_SIZE 0x04
97 #define VBRI_HEADER_OFFSET 0x0024
98 
99 #define DEFAULT_NUM_FRAMES_TO_SCAN 20
100 #define ID3_V1_TAG_SIZE 128
101 
102 #define MAX_TOC_ENTRY_COUNT 200
103 
104 typedef struct mp3Header_tag
105 {
106     int32 SamplingRate;
107     int32 BitRate;
108     int32 FrameLengthInBytes;
109     int32 FrameSizeUnComp;
110     int32 NumberOfChannels;
111 } MP3ConfigInfoType;
112 
113 typedef struct mp3HeaderInfo_tag
114 {
115     int32 frameVer;
116     int32 layerID;
117     int32 crcFollows;
118     int32 brIndex;
119     int32 srIndex;
120     int32 prvBit;
121     int32 padBit;
122     int32 chMode;
123     int32 modeExtn;
124     int32 frameSize;
125 } MP3HeaderType;
126 
127 // XING Header for VBR Support
128 // A XING Header may be present in the ancilary data field of
129 // the first frame of an mp3 bitsream
130 // The Xing header (optionally) contains:
131 //    frames   the total number of frames in the audio bitstream
132 //    bytes    total number of bytes in the bitstream
133 //    toc      table of contents
134 // TOC (Table Of Contents) gives seek points for random access
135 // the ith entry determines the seek point for i-percent duration
136 // Seek point in bytes = (toc[i]/256.0)*total_bitstream_bytes
137 // e.g. half seek point = (toc[50]/256.0)*total_bitstream_bytes
138 typedef struct xingHeader_tag
139 {
140     int32 hId;            // from MPG Header (0=Mpeg2, 1=MPEG1)
141     int32 sampRate;       // determined from header
142     int32 flags;          // from Xing Header data
143     int32 frames;         // total bitstream frames from xing header
144     int32 bytes;          // total bitstream bytes from Xing header
145     int32 vbr_scale;      // encoded VBR scale from Xing header data
146     int32 TOC[100];       // pointer to TOC[100], maybe NULL
147 } XINGHeaderType;
148 // End of XING VBR Header Support
149 
150 typedef struct vbriHeader_tag
151 {
152     int32 hId;
153     int32 vId;
154     int32 delay;
155     int32 bytes;
156     int32 frames;
157     int32 entriesTOC;
158     int32 scale;
159     int32 sTableEntry;
160     int32 fTableEntry;
161     int32 *TOC;
162     int32 sampleRate;
163 } VBRIHeaderType;
164 
165 
166 typedef enum VBRType
167 {
168     EXINGType,
169     EVBRIType,
170     ECBRType,
171     EVBRType,  // to take care of case where there is no xing or VBRI hdr present
172     EINVALIDType
173 }   MP3FileType;
174 
175 
176 /**
177  *  @brief The MP3Parser Class is the class that parses the
178  *  MP3 file.
179  */
180 
181 class MP3Parser
182 {
183 
184     public:
185         /**
186         * @brief Constructor.
187         *
188         * @param Filehandle
189         * @returns None
190         */
191         MP3Parser(PVFile* aFileHandle = NULL);
192 
193         /**
194         * @brief Destructor.
195         *
196         * @param None
197         * @returns None
198         */
199         ~MP3Parser();
200 
201         /**
202         * @brief Parses the MetaData (beginning or end) and positions
203         * the file pointer at the first audio frame.
204         *
205         * @param fpUsed Pointer to file
206         * @param enableCRC, CRC check flag
207         * @returns error type.
208         */
209         MP3ErrorType    ParseMP3File(PVFile * fpUsed, bool enableCRC);
210 
211         /**
212         * @brief Checks the file is valid mp3 clip or not
213         *
214         * @param fpUsed Pointer to file
215         * @param filename Name of file
216         * @returns error type.
217         */
218         MP3ErrorType IsMp3File(MP3_FF_FILE* aFile, uint32 aInitSearchFileSize);
219 
220         /**
221         * @brief Sets the file size to the parser
222         *
223         * @param aFileSize
224         * @returns error type.
225         */
226         MP3ErrorType SetFileSize(const uint32 aFileSize);
227 
228         /**
229         * @brief Attempts to read in the number of MP3 frames specified by n.
230         * It formats and stores the data read in the GAU structure.
231         *
232         * @param n Pointer to the number of frames to read
233         * @param pgau Pointer to data read
234         * @returns Number of bytes read
235         */
236         int32   GetNextBundledAccessUnits(uint32 *n, GAU *pgau, MP3ErrorType &err);
237 
238         /**
239         * @brief Peeks into the next MP3 frames specified by n.
240         * It formats and stores the data read in the MediaMetaInfo structure.
241         *
242         * @param n Pointer to the number of frames to check
243         * @param mInfo Pointer to info read
244         * @returns Number of bytes read
245         */
246         int32   PeekNextBundledAccessUnits(uint32 *n, MediaMetaInfo *mInfo);
247 
248         /**
249         * @brief Reads the next frame from the file
250         *
251         * @param buf Buffer to read the frame data into
252         * @param size Size of the buffer
253         * @param framesize Size of the frame data if the read is successful
254         * @param timestamp Timestamp for the frame if the read is successful
255         * @returns Result of operation: true=success; false=fail
256         */
257         MP3ErrorType  GetNextMediaSample(uint8 *buf, uint32 bufsize, uint32& framesize, uint32& timestamp);
258 
259         /**
260         * @brief Returns the timestamp of the frame
261         *
262         * @param number of the frame to retrieve the timestamp of
263         * @returns Timestamp
264         */
265         uint32  GetTimestampForSample(int32 frameNumber) const;
266         uint32  GetTimestampForCurrentSample() const;
267 
268         /**
269         * @brief Moves the file pointer to the specified timestamp
270         *
271         * @param timestamp Time to seek to
272         * @returns Timestamp seeked to
273         */
274         uint32  SeekToTimestamp(uint32 timestamp);
275 
276         /**
277         * @brief Queries the seek point timestamp corresponding to the specified timestamp
278         *
279         * @param timestamp Time to seek to
280         * @param frameNumber Number of frame associated with the seek
281         * @returns Timestamp closest to the specified timestamp. If timestamp is past end of clip, timestamp is 0.
282         */
283         uint32 SeekPointFromTimestamp(uint32 &timestamp);
284 
285         /**
286         * @brief Queries the offset corressponding to the given timestamp
287         *
288         * @param timestamp Time to seek to
289         * @param frameNumber Number of frame associated with the seek
290         * @returns offset
291         */
292         uint32 GetFileOffsetForAutoResume(uint32 &timestamp);
293 
294         /**
295         * @brief Reads the MP3 header. This contains audio settings
296         * necessary to configure the device.
297         *
298         * @param pMP3COnfig Data structure that will contain the header
299         * @returns True if successful; False otherwise
300         */
301         bool GetMP3FileHeader(MP3ConfigInfoType * pMP3COnfig);
302 
303         /**
304         * @brief Retreives and returns channel mode for the current
305         * of mp3 file
306         *
307         * @param
308         * @returns
309         */
310         uint32 GetChannelMode() const;
311 
312         /**
313         * @brief Returns the content of decoder specific info.
314         *
315         * @param None
316         * @returns Decoder specific info
317         */
318         uint8 const * GetDecoderSpecificInfoContent() const;
319 
320         /**
321         * @brief Returns the size of decoder specific info.
322         *
323         * @param None
324         * @returns Decoder specific info size
325         */
326         uint32  GetDecoderSpecificInfoSize();
327 
328         /**
329         * @brief Returns the number of frames in the clip.
330         *
331         * @param None
332         * @returns Number of frames
333         */
334         uint32  GetSampleCountInFile();
335 
336         /**
337         * @brief Returns the maximum decode buffer size used.
338         *
339         * @param None
340         * @returns Buffer size
341         */
342         uint32  GetMaximumDecodeBufferSize();
343 
344         /**
345         * @brief Returns the size of the file.
346         *
347         * @param None
348         * @returns File size
349         */
350         uint32  GetFileSize();
351 
352         /**
353         * @brief Returns the duration of the file.
354         *
355         * @param None
356         * @returns Clip duration
357         */
358         uint32  GetDuration(bool aMetadataDuration = false);
359 
360         /**
361         * @brief Returns the approximate duration of downloaded data.
362         *
363         * @param aFileSize, aNPTInMS
364         * @returns aNPTInMS
365         */
366         int32 ConvertSizeToTime(uint32 aFileSize, uint32& aNPTInMS);
367 
368         /**
369         * @brief outputs the size of id3v2 tags
370         *
371         * @param aSize, carries the tag size
372         * @returns success if meta data is parsed, failure otherwise
373         */
374         MP3ErrorType GetMetadataSize(uint32 &aSize);
375 
376         /**
377         * @brief Retrieves minimum bytes required for getting the config info
378         *
379         * @param
380         * @returns byte size of firstframe and id3 tags.
381         */
382         uint32 GetMinBytesRequired(bool aNextBytes = false);
383 
384         /**
385         * @brief Copies the metadata to the structure specified.
386         *
387         * @param None
388         * @returns Always 0.
389         */
GetMetaData(PvmiKvpSharedPtrVector & pMetaData)390         uint32  GetMetaData(PvmiKvpSharedPtrVector &pMetaData)
391         {
392             iId3TagParser.GetID3Frames(iId3Frames);
393             pMetaData = iId3Frames;
394             return 0;
395         }
GetMetaData(const OSCL_String & pFrameType,PvmiKvpSharedPtrVector & pMetaData)396         uint32 GetMetaData(const OSCL_String& pFrameType, PvmiKvpSharedPtrVector &pMetaData)
397         {
398             iId3TagParser.GetID3Frame(pFrameType, pMetaData);
399             return 0;
400         }
IsID3Frame(const OSCL_String & pFrameType)401         bool IsID3Frame(const OSCL_String& pFrameType)
402         {
403             return iId3TagParser.IsID3FrameAvailable(pFrameType);
404         }
405 
406         MP3ErrorType ScanMP3File(PVFile * fpUsed, uint32 aFramesToScan);
407     private:
408         MP3ErrorType ScanMP3File(PVFile* fpUsed);
409         MP3ErrorType GetDurationFromVBRIHeader(uint32 &aDuration);
410         MP3ErrorType GetDurationFromRandomScan(uint32 &aDuration);
411         MP3ErrorType ComputeDurationFromNRandomFrames(PVFile * fpUsed, int32 aNumFrames = MIN_RANDOM_FRAMES_TO_SCAN, int32 aNumRandomLoc = MIN_RANDOM_LOCATION_TO_SCAN);
412         void GetDurationFromCompleteScan(uint32 &aClipDuration);
413 
414         MP3ErrorType EstimateDurationFromExternalFileSize(uint32 &aClipDuration);
415 
416         uint32 GetDurationFromMetadata();
417 
418         MP3ErrorType FillTOCTable(uint32 aFilePos, uint32 aTimeStampToFrame);
419 
420         //duration related values
421         uint32 iClipDurationInMsec;
422         uint32 iClipDurationFromEstimation;
423         uint32 iClipDurationComputed;
424         uint32 iClipDurationFromVBRIHeader;
425         uint32 iClipDurationFromRandomScan;
426         uint32 iClipDurationFromMetadata;
427         bool iDurationScanComplete;
428         uint32 iTimestamp;
429         int32 iAvgBitrateInbpsFromRandomScan;
430         int32 iAvgBitrateInbps;
431         int32 iAvgBitrateInbpsFromCompleteScan;
432 
433 
434     protected:
435         uint32 iLocalFileSize;
436         uint32 iFileSizeFromExternalSource;
437         uint32 iInitSearchFileSize;
438         bool iLocalFileSizeSet;
439         PVFile * fp;
440         MediaClockConverter iClockConverter;
441         bool iFirstScan;
442         uint32 iLastScanPosition;
443         bool iScanEnable;
444 
445     private:
446         MP3ErrorType IsValidFrame(uint8 * pBuffer, uint32 offset, uint32 seekPoint, PVFile* aFile = NULL);
447         MP3ErrorType IsValidFrameHeader(uint8 * mp3FrameHeader, bool &bCRCPresent, uint32 offset, uint32 seekPoint, PVFile* aFile = NULL);
448         bool  IsValidFrameCRC(uint8 *pFrame, int32 size, uint32 crcValue);
449 
450         bool GetMP3Header(uint32 &fh, MP3HeaderType &hi);
451         bool DecodeMP3Header(MP3HeaderType &aHeaderInfoType, MP3ConfigInfoType &aConfigInfoType, bool aComputeAvgBitrate);
452         bool DecodeXINGHeader(uint8 *XingBuffer, XINGHeaderType &mp3XingHI, MP3HeaderType &hi);
453         bool DecodeVBRIHeader(uint8 * VbriBuffer, VBRIHeaderType &vbriHDI, MP3HeaderType &hi);
454         MP3ErrorType mp3FindSync(uint32 seekPoint, uint32 &syncOffset, PVFile* aFile);
455         uint16 CalcCRC16(uint8* pBuffer, uint32 dwBitSize);
456         MP3ErrorType mp3VerifyCRC(MP3HeaderType mp3HdrInfo, MP3ConfigInfoType mp3CI);
457 
458 
459         /* scan file related */
460         uint32 iScannedFrameCount;
461         /* toc related */
462         int32* iTOC;
463         uint32 iTOCFilledCount;
464         uint32 iTimestampPrev;
465         uint32 iScanTimestamp;
466         uint32 iBinWidth;
467 
468         uint32 iSamplingRate;
469         uint32 iSamplesPerFrame;
470 
471         int32 CalculateBufferSizeForHeader(uint8 *VbriHead);
472         int32 iCurrFrameNumber;
473         int32 iNumberOfFrames;
474 
475         bool bVBRFile;
476         uint8 ConfigData[4];
477         uint32 ConfigSize;
478         uint32 StartOffset;
479         uint8 * pSyncBuffer;
480         uint32 iMaxSyncBufferSize;
481 
482         MP3ConfigInfoType  iMP3ConfigInfo;
483         MP3HeaderType      iMP3HeaderInfo;
484         XINGHeaderType     iXingHeader;
485         PVID3ParCom    iId3TagParser;
486         VBRIHeaderType iVbriHeader;
487         bool iEnableCrcCalc;
488         MP3FileType mp3Type;
489         uint32 iTagSize;
490         PvmiKvpSharedPtrVector iId3Frames;
491 };
492 
493 #endif // #ifdef MP3PARSER_H_INCLUDED
494