Svace issue fix
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_format_mp3.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <string.h>     /*memcmp*/
23
24 #include <sys/types.h>
25 #include <sys/stat.h>   /*stat*/
26 #include <unistd.h>
27
28 #include <stdlib.h>     /*malloc*/
29
30 #include "mm_file_debug.h"
31 #include "mm_file_utils.h"
32 #include "mm_file_format_private.h"
33 #include "mm_file_format_audio.h"
34 #include "mm_file_format_mp3.h"
35
36
37 #define __MMFILE_NEW_FRAME_FUNC
38
39 #ifdef __MMFILE_NEW_TAGLIBS__
40 #include "mm_file_format_tags.h"
41 #endif
42
43
44 #define AV_MP3_FIND_SYNC_LEN            1024*30
45 #undef MIN
46 #define MIN(a, b) ((a) < (b) ? (a) : (b))
47
48
49 static const unsigned char mp3FrameMasking[4] = {0xFF, 0xFE, 0x0C, 0x00};
50 static unsigned char mp3FrameDataValid[4];
51
52 static const int mp3BitRateTable[2][3][16] = {
53         {       {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
54                 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
55                 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
56         },
57
58         {       {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
59                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
60                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
61         }
62 };
63
64 static const int mp3SamRateTable[3][3] = {
65         {44100, 48000, 32000},
66         {22050, 24000, 16000},
67         {11025, 12000, 8000}
68 };
69
70 #define IS_VALID_FRAME_MP3(x) \
71         ((((x)[0] & mp3FrameMasking[0]) == mp3FrameDataValid[0]) && \
72          (((x)[1] & mp3FrameMasking[1]) == mp3FrameDataValid[1]) && \
73          (((x)[2] & mp3FrameMasking[2]) == mp3FrameDataValid[2]) && \
74          (((x)[3] & mp3FrameMasking[3]) == mp3FrameDataValid[3]))
75
76
77
78 /* interface functions */
79 int mmfile_format_read_stream_mp3(MMFileFormatContext *formatContext);
80 int mmfile_format_read_frame_mp3(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
81 int mmfile_format_read_tag_mp3(MMFileFormatContext *formatContext);
82 int mmfile_format_close_mp3(MMFileFormatContext *formatContext);
83
84 /* internal */
85 static int mmf_file_mp3_get_infomation(char *src, AvFileContentInfo *pInfo);
86
87 EXPORT_API
88 int mmfile_format_open_mp3(MMFileFormatContext *formatContext)
89 {
90         AvFileContentInfo *privateData = NULL;;
91         int ret = 0;
92
93 #ifdef __MMFILE_TEST_MODE__
94         debug_fenter();
95 #endif
96
97         if (NULL == formatContext) {
98                 debug_error("formatContext is NULL\n");
99                 return MMFILE_FORMAT_FAIL;
100         }
101
102         if (formatContext->pre_checked == 0) {
103                 ret = MMFileFormatIsValidMP3(NULL, formatContext->uriFileName, 5);
104                 if (ret == 0) {
105                         debug_error("It is not mp3 file\n");
106                         return MMFILE_FORMAT_FAIL;
107                 }
108         }
109
110
111         formatContext->ReadStream   = mmfile_format_read_stream_mp3;
112         formatContext->ReadFrame    = mmfile_format_read_frame_mp3;
113         formatContext->ReadTag      = mmfile_format_read_tag_mp3;
114         formatContext->Close        = mmfile_format_close_mp3;
115
116         formatContext->videoTotalTrackNum = 0;
117         formatContext->audioTotalTrackNum = 1;
118
119         privateData = mmfile_malloc(sizeof(AvFileContentInfo));
120         if (!privateData) {
121                 debug_error("error: mmfile_malloc MP3 privateData\n");
122                 return MMFILE_FORMAT_FAIL;
123         }
124
125         formatContext->privateFormatData = privateData;
126
127         ret = mmf_file_mp3_get_infomation(formatContext->uriFileName, privateData);
128         if (ret == -1) {
129                 debug_error("error: mmfile_format_read_stream_mp3\n");
130                 goto exception;
131         }
132
133         return MMFILE_FORMAT_SUCCESS;
134
135 exception:
136         mmfile_format_close_mp3(formatContext);
137         return MMFILE_FORMAT_FAIL;
138 }
139
140
141 EXPORT_API
142 int mmfile_format_read_stream_mp3(MMFileFormatContext *formatContext)
143 {
144         AvFileContentInfo *privateData = NULL;
145
146 #ifdef __MMFILE_TEST_MODE__
147         debug_fenter();
148 #endif
149
150         if (!formatContext || !formatContext->privateFormatData) {
151                 debug_error("formatContext is NULL\n");
152                 return MMFILE_FORMAT_FAIL;
153         }
154
155         privateData = formatContext->privateFormatData;
156
157         formatContext->duration = privateData->duration;
158         formatContext->videoTotalTrackNum = 0;
159         formatContext->audioTotalTrackNum = 1;
160         formatContext->nbStreams = 1;
161         formatContext->streams[MMFILE_AUDIO_STREAM] = mmfile_malloc(sizeof(MMFileFormatStream));
162         if (NULL == formatContext->streams[MMFILE_AUDIO_STREAM]) {
163                 debug_error("formatContext->streams[MMFILE_AUDIO_STREAM] is NULL\n");
164                 return MMFILE_FORMAT_FAIL;
165         }
166
167         formatContext->streams[MMFILE_AUDIO_STREAM]->streamType = MMFILE_AUDIO_STREAM;
168         formatContext->streams[MMFILE_AUDIO_STREAM]->codecId = MM_AUDIO_CODEC_MP3;
169         formatContext->streams[MMFILE_AUDIO_STREAM]->bitRate = (privateData->bitRate * 1000);
170         formatContext->streams[MMFILE_AUDIO_STREAM]->framePerSec = (privateData->duration == 0 ? 0 : privateData->frameNum / privateData->duration);
171         formatContext->streams[MMFILE_AUDIO_STREAM]->width = 0;
172         formatContext->streams[MMFILE_AUDIO_STREAM]->height = 0;
173         formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = privateData->channels;
174         formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = privateData->sampleRate;
175
176         return MMFILE_FORMAT_SUCCESS;
177 }
178
179
180 EXPORT_API
181 int mmfile_format_read_frame_mp3(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
182 {
183         return MMFILE_FORMAT_SUCCESS;
184 }
185
186 EXPORT_API
187 int mmfile_format_read_tag_mp3(MMFileFormatContext *formatContext)
188 {
189         AvFileContentInfo *privateData = NULL;
190
191 #ifdef __MMFILE_TEST_MODE__
192         debug_fenter();
193 #endif
194
195         if (!formatContext || !formatContext->privateFormatData) {
196                 debug_error("formatContext is NULL\n");
197                 return MMFILE_FORMAT_FAIL;
198         }
199
200         privateData = formatContext->privateFormatData;
201
202         if (privateData->pTitle)                                formatContext->title = mmfile_strdup(privateData->pTitle);
203         if (privateData->pArtist)                       formatContext->artist = mmfile_strdup(privateData->pArtist);
204         if (privateData->pAuthor)                       formatContext->author = mmfile_strdup(privateData->pAuthor);
205         if (privateData->pCopyright)            formatContext->copyright = mmfile_strdup(privateData->pCopyright);
206         if (privateData->pComment)              formatContext->comment = mmfile_strdup(privateData->pComment);
207         if (privateData->pAlbum)                        formatContext->album = mmfile_strdup(privateData->pAlbum);
208         if (privateData->pAlbum_Artist)                 formatContext->album_artist = mmfile_strdup(privateData->pAlbum_Artist);
209         if (privateData->pYear)                         formatContext->year = mmfile_strdup(privateData->pYear);
210         if (privateData->pGenre)                        formatContext->genre = mmfile_strdup(privateData->pGenre);
211         if (privateData->pTrackNum)             formatContext->tagTrackNum = mmfile_strdup(privateData->pTrackNum);
212         if (privateData->pComposer)             formatContext->composer = mmfile_strdup(privateData->pComposer);
213         if (privateData->pContentGroup) formatContext->classification = mmfile_strdup(privateData->pContentGroup);
214         if (privateData->pConductor)            formatContext->conductor = mmfile_strdup(privateData->pConductor);
215         if (privateData->pUnsyncLyrics)         formatContext->unsyncLyrics = mmfile_strdup(privateData->pUnsyncLyrics);
216         if (privateData->pSyncLyrics)           formatContext->syncLyrics = privateData->pSyncLyrics;
217         if (privateData->syncLyricsNum)         formatContext->syncLyricsNum = privateData->syncLyricsNum;
218         if (privateData->pRecDate)                      formatContext->recDate = mmfile_strdup(privateData->pRecDate);
219
220         if (privateData->imageInfo.imageLen > 0) {
221                 formatContext->artwork = mmfile_malloc(privateData->imageInfo.imageLen);
222                 if (formatContext->artwork) {
223                         formatContext->artworkSize = privateData->imageInfo.imageLen;
224                         memcpy(formatContext->artwork, privateData->imageInfo.pImageBuf, privateData->imageInfo.imageLen);
225                         if (strlen(privateData->imageInfo.imageMIMEType) > 0)
226                                 formatContext->artworkMime = mmfile_strdup(privateData->imageInfo.imageMIMEType);
227                         else if (strlen(privateData->imageInfo.imageExt) > 0) {
228 #ifdef __MMFILE_TEST_MODE__
229                                 debug_msg("ID3 tag V2 File");
230 #endif
231                                 formatContext->artworkMime = mmfile_strdup(privateData->imageInfo.imageExt);
232                         } else {
233                                 debug_error("Album art image exist but there is no type information of album art\n");
234                         }
235                 }
236         }
237
238         return MMFILE_FORMAT_SUCCESS;
239 }
240
241 EXPORT_API
242 int mmfile_format_close_mp3(MMFileFormatContext *formatContext)
243 {
244         AvFileContentInfo *privateData = NULL;
245
246         if (formatContext) {
247                 privateData = formatContext->privateFormatData;
248                 if (privateData) {
249                         mm_file_free_AvFileContentInfo(privateData);
250                         mmfile_free(privateData);
251                         formatContext->privateFormatData = NULL;
252                 }
253         }
254
255         return MMFILE_FORMAT_SUCCESS;
256 }
257
258 static int
259 __AvExtractI4(unsigned char *buf)
260 {
261         int I4;
262
263         I4 = buf[0];
264         I4 <<= 8;
265         I4 |= buf[1];
266         I4 <<= 8;
267         I4 |= buf[2];
268         I4 <<= 8;
269         I4 |= buf[3];
270
271         return I4;
272 }
273
274 static int
275 __AvExtractI2(unsigned char *buf)
276 {
277         int I2;
278
279         I2 = buf[0];
280         I2 <<= 8;
281         I2 |= buf[1];
282         I2 <<= 8;
283
284         return I2;
285 }
286
287 static int
288 __AvGetXingHeader(AvXHeadData *headData,  unsigned char *buf)
289 {
290         int                     index, headFlags;
291         int                     hId, hMode, hSrIndex;
292         int     mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
293
294         /* get Xing header data */
295         headData->flags = 0;
296
297         /* get selected MP3 header data */
298         hId                     = (buf[1] >> 3) & 1;
299         hSrIndex        = (buf[2] >> 2) & 3;
300         hMode           = (buf[3] >> 6) & 3;
301
302
303         /* determine offset of header */
304         if (hId) {      /* mpeg1 */
305                 if (hMode != 3)
306                         buf += (32 + 4);
307                 else
308                         buf += (17 + 4);
309         } else {        /* mpeg2 */
310                 if (hMode != 3)
311                         buf += (17 + 4);
312                 else
313                         buf += (9 + 4);
314         }
315
316         /* There could be 2 attrs in this header : Xing or Info */
317         if (buf[0] == 'X') {
318                 if (buf[1] != 'i') return 0;
319                 if (buf[2] != 'n') return 0;
320                 if (buf[3] != 'g') return 0;
321         } else if (buf[0] == 'I') {
322                 if (buf[1] != 'n') return 0;
323                 if (buf[2] != 'f') return 0;
324                 if (buf[3] != 'o') return 0;
325         } else {
326                 return 0;
327         }
328
329         buf += 4;
330
331         headData->hId = hId;
332         headData->sampRate = mp3SampleRateTable[hSrIndex];
333         if (hId == 0)
334                 headData->sampRate >>= 1;
335
336         headFlags = headData->flags = __AvExtractI4(buf);               /* get flags */
337         buf += 4;
338
339         if (headFlags & FRAMES_FLAG) {
340                 headData->frames   = __AvExtractI4(buf);
341                 buf += 4;
342         }
343         if (headFlags & BYTES_FLAG) {
344                 headData->bytes = __AvExtractI4(buf);
345                 buf += 4;
346         }
347
348         if (headFlags & TOC_FLAG) {
349                 if (headData->toc != NULL) {
350                         for (index = 0; index < 100; index++)
351                                 headData->toc[index] = buf[index];
352                 }
353                 buf += 100;
354         }
355
356         headData->vbrScale = -1;
357         if (headFlags & VBR_SCALE_FLAG) {
358                 headData->vbrScale = __AvExtractI4(buf);
359         }
360
361 #ifdef __MMFILE_TEST_MODE__
362         debug_msg("Xing header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
363                   headData->sampRate, headData->bytes, headData->frames);
364 #endif
365
366         return 1;       /* success */
367 }
368
369 static int
370 __AvGetVBRIHeader(AvVBRIHeadData *headData,  unsigned char *buf)
371 {
372         int                     hId, hSrIndex;
373         int     mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
374
375
376         /* get selected MP3 header data */
377         hId                     = (buf[1] >> 3) & 1;
378         hSrIndex        = (buf[2] >> 2) & 3;
379
380         buf += (32 + 4);
381
382         if (buf[0] != 'V') return 0;     /* fail */
383         if (buf[1] != 'B') return 0;     /* header not found */
384         if (buf[2] != 'R') return 0;
385         if (buf[3] != 'I') return 0;
386         buf += 4;
387
388         headData->hId = hId;
389         headData->sampRate = mp3SampleRateTable[hSrIndex];
390         if (hId == 0)
391                 headData->sampRate >>= 1;
392
393         headData->vID = __AvExtractI2(buf);             /* get ver ID */
394         buf += 2;
395         headData->delay = __AvExtractI2(buf);
396         buf += 2;
397         headData->qualityIndicator = buf[0];
398         buf += 2;
399         headData->bytes = __AvExtractI4(buf);
400         buf += 4;
401         headData->frames = __AvExtractI4(buf);
402         buf += 4;
403         headData->numOfTOC = __AvExtractI2(buf);
404         buf += 2;
405         headData->vbriScale = __AvExtractI2(buf);
406         buf += 2;
407         headData->sizePerTable = __AvExtractI2(buf);
408         buf += 2;
409         headData->framesPerTable = __AvExtractI2(buf);
410
411 #ifdef __MMFILE_TEST_MODE__
412         debug_msg("Vbri header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
413                   headData->sampRate, headData->bytes, headData->frames);
414 #endif
415
416         return true;       /* success */
417 }
418 static bool
419 __AvIsValidHeader(AvFileContentInfo *pInfo, unsigned char *buf)
420 {
421         bool    bSync = false;
422
423         if (VALID_SYNC(buf)) {
424                 mp3FrameDataValid[0] = (0xFF) & (mp3FrameMasking[0]);
425                 mp3FrameDataValid[1] = (0xE0 | (buf[AV_MP3HDR_VERSION_OFS] & AV_MP3HDR_VERSION_M)
426                                         | (buf[AV_MP3HDR_LAYER_OFS] & AV_MP3HDR_LAYER_M)) & (mp3FrameMasking[1]);
427                 mp3FrameDataValid[2] = (buf[AV_MP3HDR_SAMPLERATE_OFS] & AV_MP3HDR_SAMPLERATE_M) &
428                                        (mp3FrameMasking[2]);
429                 mp3FrameDataValid[3] = (buf[AV_MP3HDR_CHANNEL_OFS] & AV_MP3HDR_CHANNEL_M) &
430                                        (mp3FrameMasking[3]);
431
432 #ifdef __MMFILE_TEST_MODE__
433                 debug_msg("*** [%02x][%02x][%02x][%02x] : [%02x][%02x][%02x][%02x]",
434                           buf[0], buf[1], buf[2], buf[3],
435                           mp3FrameDataValid[0], mp3FrameDataValid[1], mp3FrameDataValid[2], mp3FrameDataValid[3]);
436 #endif
437
438                 /*
439                  * MPEG Audio Layer I/II/III frame header
440                  * from : http://www.mp3-tech.org/programmer/frame_header.html           *
441                  *
442                  * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
443                  *
444                  * A    11      (31-21)         Frame sync (all bits must be set)
445                  * B    2       (20,19)         MPEG Audio version ID
446                  * C    2       (18,17)         Layer description
447                  * D    1       (16)    Protection bit
448                  * E    4       (15,12)         Bitrate index
449                  * F    2       (11,10)         Sampling rate frequency index
450                  * G    1       (9)     Padding bit
451                  * H    1       (8)     Private bit. This one is only informative.
452                  * I    2       (7,6)   Channel Mode
453                  * J    2       (5,4)   Mode extension (Only used in Joint stereo)
454                  * K    1       (3)     Copyright
455                  * L    1       (2)     Original
456                  * M    2       (1,0)   Emphasis
457                  *
458                  */
459
460                 /* Simple check for version, layer, bitrate, samplerate */
461                 if ((buf[1] & 0x18) != 0x08 &&  /* 000XX000 : MPEG Audio version ID, XX=01 - reserved => 00001000(0x08) */
462                     (buf[1] & 0x06) != 0x00 && /* 00000XX0 : Layer description, XX=00 - reserved => 00000000(0x00) */
463                     (buf[2] & 0xF0) != 0xF0 && /* XXXX0000 : Bitrate index, XX=1111 - bad => 11110000(0xF0) */
464                     (buf[2] & 0x0C) != 0x0C) { /* 0000XX00 : Sampling rate frequency index, XX=11 -reserved => 00001100(0x0C) */
465                         bSync = true;
466                 }
467 #ifdef __MMFILE_TEST_MODE__
468                 debug_msg("=> %s\n", bSync ? "Good!" : "Bad...");
469 #endif
470         }
471
472         if (bSync == true)
473                 return true;
474         else
475                 return false;
476 }
477
478 static bool
479 __AvParseMp3Header(AvFileContentInfo *pInfo,  unsigned char *header)
480 {
481         unsigned char   result;
482
483 #ifdef __MMFILE_TEST_MODE__
484         debug_msg("### [%02x][%02x][%02x][%02x] ###\n", header[0], header[1], header[2], header[3]);
485 #endif
486
487         /* 1. Check the version of mp3 */
488         result = header[1] & MASK_MPEG;
489         switch (result) {
490                 case MASK_MPEG_1:
491                         pInfo->mpegVersion = AV_MPEG_VER_1;
492                         break;
493                 case MASK_MPEG_2:
494                         pInfo->mpegVersion = AV_MPEG_VER_2;
495                         break;
496                 case MASK_MPEG_25:
497                         pInfo->mpegVersion = AV_MPEG_VER_25;
498                         break;
499                 default:
500                         return false;
501         }
502
503         /* 2. Get a layer */
504         result = header[1] & MASK_LAYER;
505         switch (result) {
506                 case MASK_LAYER_1:
507                         pInfo->layer = AV_MP3_LAYER_1;
508                         break;
509                 case MASK_LAYER_2:
510                         pInfo->layer = AV_MP3_LAYER_2;
511                         break;
512                 case MASK_LAYER_3:
513                         pInfo->layer = AV_MP3_LAYER_3;
514                         break;
515                 default:
516                         return false;
517         }
518
519         /* 3. bitrate */
520         result = header[2] >> 4;
521         if (pInfo->mpegVersion == AV_MPEG_VER_1)
522                 pInfo->bitRate = mp3BitRateTable[0][pInfo->layer - 1][(int)result] ;
523         else
524                 pInfo->bitRate = mp3BitRateTable[1][pInfo->layer - 1][(int)result] ;
525
526         /* 4. samplerate */
527         result = (header[2] & MASK_SAMPLERATE) >> 2;
528         if (result == 0x03)
529                 return false;
530         else
531                 pInfo->sampleRate = mp3SamRateTable[pInfo->mpegVersion - 1][(int)result];
532
533         /* 5. channel */
534         result = header[3] & MASK_CHANNEL;
535         switch (result) {
536                 case MASK_CHANNEL_ST:
537                         pInfo->channelIndex = 0;
538                         pInfo->channels = 2;
539                         break;
540                 case MASK_CHANNEL_JS:
541                         pInfo->channelIndex = 1;
542                         pInfo->channels = 2;
543                         break;
544                 case MASK_CHANNEL_DC:
545                         pInfo->channelIndex = 2;
546                         pInfo->channels = 2;
547                         break;
548                 case MASK_CHANNEL_MN:
549                         pInfo->channelIndex = 3;;
550                         pInfo->channels = 1;
551                         break;
552                 default:
553                         return false;
554         }
555
556         /*      6. padding */
557         result = header[2] & MASK_PADDING;
558         if (result == MASK_PADDING)
559                 pInfo->bPadding = true;
560         else
561                 pInfo->bPadding = false;
562
563 #ifdef __MMFILE_TEST_MODE__
564         debug_msg("=> samplerate=%d, bitrate=%d, layer=%d, version=%d, channel=%d, padding=%d",
565                   pInfo->sampleRate, pInfo->bitRate, pInfo->layer, pInfo->mpegVersion, pInfo->channels, pInfo->bPadding);
566 #endif
567
568         return true;
569 }
570
571 static bool
572 __AvParseXingHeader(AvFileContentInfo *pInfo, unsigned char *buf)
573 {
574         AvXHeadData data;
575         memset(&data, 0x00, sizeof(AvXHeadData));
576
577         /*      1. Xing Header */
578         /* There could be 2 attrs in this header : Xing or Info */
579         if ((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2)) {
580                 if (buf[36] == 'X') {
581                         if (buf[37] != 'i') return false;
582                         if (buf[38] != 'n') return false;
583                         if (buf[39] != 'g') return false;
584                 } else if (buf[36] == 'I') {
585                         if (buf[37] != 'n') return false;
586                         if (buf[38] != 'f') return false;
587                         if (buf[39] != 'o') return false;
588                 } else {
589                         return false;
590                 }
591         } else if ((pInfo->mpegVersion == AV_MPEG_VER_2 || pInfo->mpegVersion == AV_MPEG_VER_25) && (pInfo->channels == 1)) {
592                 if (buf[13] == 'X') {
593                         if (buf[14] != 'i') return false;
594                         if (buf[15] != 'n') return false;
595                         if (buf[16] != 'g') return false;
596                 } else if (buf[13] == 'I') {
597                         if (buf[14] != 'n') return false;
598                         if (buf[15] != 'f') return false;
599                         if (buf[16] != 'o') return false;
600                 } else {
601                         return false;
602                 }
603         } else {
604                 if (buf[21] == 'X') {
605                         if (buf[22] != 'i') return false;
606                         if (buf[23] != 'n') return false;
607                         if (buf[24] != 'g') return false;
608                 } else if (buf[21] == 'I') {
609                         if (buf[22] != 'n') return false;
610                         if (buf[23] != 'f') return false;
611                         if (buf[24] != 'o') return false;
612                 } else {
613                         return false;
614                 }
615         }
616
617         /*      2. TOC */
618         if (pInfo->pToc)
619                 data.toc = (unsigned char *)(pInfo->pToc);
620
621         if (__AvGetXingHeader(&data, (unsigned char *)buf) == 1) {   /* VBR. */
622                 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
623                         debug_error("invalid Xing header\n");
624                         return false;
625                 }
626
627                 pInfo->datafileLen = data.bytes;
628                 pInfo->frameNum = data.frames;
629                 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames)  ;
630                 pInfo->bVbr = true;
631                 return true;
632         } else
633                 return false;
634 }
635
636 static bool
637 __AvParseVBRIHeader(AvFileContentInfo *pInfo, unsigned char *buf)
638 {
639         AvVBRIHeadData data;
640         memset(&data, 0x00, sizeof(AvVBRIHeadData));
641
642         /*      1. Xing Header */
643         if ((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2)) {
644                 if (buf[36] != 'V') return false;
645                 if (buf[37] != 'B') return false;
646                 if (buf[38] != 'R') return false;
647                 if (buf[39] != 'I') return false;
648         } else if ((pInfo->mpegVersion == AV_MPEG_VER_2) && (pInfo->channels == 1)) {
649                 if (buf[36] != 'V') return false;
650                 if (buf[37] != 'B') return false;
651                 if (buf[38] != 'R') return false;
652                 if (buf[39] != 'I') return false;
653         } else {
654                 if (buf[36] != 'V') return false;
655                 if (buf[37] != 'B') return false;
656                 if (buf[38] != 'R') return false;
657                 if (buf[39] != 'I') return false;
658         }
659
660         /*      2. TOC */
661         if (pInfo->pToc)
662                 data.toc = (unsigned char *)(pInfo->pToc);
663
664         if (__AvGetVBRIHeader(&data, (unsigned char *)buf) == 1) {  /* VBR. */
665                 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
666                         debug_error("invalid Vbri header\n");
667                         return false;
668                 }
669
670                 pInfo->sampleRate = data.sampRate;
671                 pInfo->datafileLen = data.bytes;
672                 pInfo->frameNum = data.frames;
673                 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames)  ;
674                 pInfo->bVbr = true;
675                 return true;
676         } else
677                 return false;
678 }
679
680 #ifdef __MMFILE_NEW_FRAME_FUNC /* from gst */
681 static bool
682 __AvGetMp3FrameSize(AvFileContentInfo *pInfo)
683 {
684         unsigned int frameSize = 0;
685         if (pInfo == NULL)
686                 return false;
687
688         frameSize =  pInfo->bPadding;
689         if (pInfo->bitRate == 0) {
690                 if (pInfo->layer == 1) {
691                         frameSize *= 4;
692                         frameSize += 0/* FIXME: possible_free_framelen*/;
693                         pInfo->bitRate = frameSize * pInfo->sampleRate / 48000;
694                 } else {
695                         frameSize += 0/* FIXME: possible_free_framelen*/;
696                         pInfo->bitRate = frameSize * pInfo->sampleRate /
697                                          ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000);
698                 }
699         } else {
700                 /* calculating */
701                 if (pInfo->layer == 1) {
702                         frameSize = ((12000 * pInfo->bitRate / pInfo->sampleRate) + frameSize) * 4;
703                 } else {
704                         frameSize += ((pInfo->layer == AV_MP3_LAYER_3
705                                        && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000) * pInfo->bitRate / pInfo->sampleRate;
706                 }
707         }
708
709         pInfo->frameSize = (int)frameSize;
710
711         return true;
712 }
713 #endif
714
715
716 static bool
717 __AvGetXingBitrate(AvFileContentInfo *pInfo)
718 {
719         float   br, factor;
720         int             padding;
721
722         if (pInfo == NULL || pInfo->bVbr == false)
723                 return false;
724
725         if (pInfo->bPadding)
726                 padding = 1;
727         else
728                 padding = 0;
729
730         if (pInfo->mpegVersion == AV_MPEG_VER_1) {      /* MPEG version 1 */
731                 if (pInfo->layer == AV_MP3_LAYER_1)     /* Layer 1 */
732                         factor = 48000.0;
733                 else                                            /* Layer 2, 3 */
734                         factor = 144000.0;
735         } else {                                                /* MPEG version 2 */
736                 if (pInfo->layer == AV_MP3_LAYER_1)     /*      Layer 1 */
737                         factor = 24000.0;
738                 else                                            /*      Layer 2, 3 */
739                         factor = 72000.0;
740         }
741
742         br = (pInfo->frameSize - padding) * pInfo->sampleRate / factor;
743
744         pInfo->bitRate = (int) br;
745
746         return true;
747 }
748
749 static bool
750 __AvGetVBRIBitrate(AvFileContentInfo *pInfo)
751 {
752         float   br, factor;
753         int             padding;
754
755         if (pInfo == NULL || pInfo->bVbr == false)
756                 return false;
757
758         if (pInfo->bPadding)
759                 padding = 1;
760         else
761                 padding = 0;
762
763         if (pInfo->mpegVersion == AV_MPEG_VER_1) {      /* MPEG version 1 */
764                 if (pInfo->layer == AV_MP3_LAYER_1)     /* Layer 1 */
765                         factor = 48000.0;
766                 else                                            /* Layer 2, 3 */
767                         factor = 144000.0;
768         } else {                                                /* MPEG version 2 */
769                 if (pInfo->layer == AV_MP3_LAYER_1)     /*      Layer 1 */
770                         factor = 24000.0;
771                 else                                            /*      Layer 2, 3 */
772                         factor = 72000.0;
773         }
774
775         br = (pInfo->frameSize - padding) * pInfo->sampleRate / factor;
776
777         pInfo->bitRate = (int) br;
778
779         return true;
780 }
781
782 static int __AvGetLastID3offset(MMFileIOHandle *fp, unsigned int *offset)
783 {
784 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
785 #define _MMFILE_GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
786
787         unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0, };
788         unsigned int tagInfoSize = 0;
789         unsigned int acc_tagsize = 0;
790         int tagVersion = 0;
791         int encSize = 0;
792         int readed = 0;
793
794         /*init offset*/
795         *offset = 0;
796
797         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
798
799 _START_TAG_SEARCH:
800
801         readed = mmfile_read(fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
802         if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
803                 debug_error("read error occured.\n");
804                 return 0;
805         }
806
807         if (memcmp(tagHeader, "ID3", 3) == 0) {
808 #ifdef __MMFILE_TEST_MODE__
809                 debug_msg("'ID3' found.\n");
810 #endif
811         } else {
812 #ifdef __MMFILE_TEST_MODE__
813                 debug_msg("'ID3' not found.\n");
814 #endif
815                 goto search_end;
816         }
817
818         /**@note weak id3v2 tag checking*/
819         if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
820             (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
821             (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
822 #ifdef __MMFILE_TEST_MODE__
823                 debug_msg("good ID3V2 tag.\n");
824 #endif
825         } else {
826                 debug_warning("It's bad ID3V2 tag.\n");
827                 goto search_end;
828         }
829
830         tagVersion = tagHeader[3];
831
832         if (tagVersion > 4) {
833 #ifdef __MMFILE_TEST_MODE__
834                 debug_msg("Tag version not supported\n");
835 #endif
836                 goto search_end;
837         }
838
839         encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
840         tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
841         tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
842
843         /**@note unfortunately, some contents has many id3 tag.*/
844         acc_tagsize += tagInfoSize;
845 #ifdef __MMFILE_TEST_MODE__
846         debug_msg("tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
847 #endif
848
849         mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
850         *offset = acc_tagsize;
851         goto _START_TAG_SEARCH;
852
853 search_end:
854         return 1;
855 }
856
857
858
859 /*
860  *      This fuction retrieves the start position of header.
861  *      Param   _pFile [in]     Specifies the file pointer of mp3 file.
862  *      This function returns the start position of header.
863  */
864 static int
865 __AvFindStartOfMp3Header(MMFileIOHandle *hFile,  unsigned char *buf, AvFileContentInfo *pInfo)
866 {
867         unsigned int            index = 0;
868         long    readLen;
869         unsigned long   id3v2TagLen = 0;
870         unsigned char   *pHeader = NULL;
871         unsigned long  preHeaderGap = 0;
872         unsigned long  frameLen = 0;
873         unsigned long  nextFrameOff = 0;     /* Offset to the start of the next frame */
874         unsigned long  nextFrameOffEnd = 0;
875         unsigned long  bufLen = 0;
876         bool bFoundSync = false;
877         unsigned long  minLen;
878
879         if (pInfo->fileLen > ((long long)_AV_MP3_HEADER_POSITION_MAX + (long long)pInfo->tagV2Info.tagLen))
880                 bufLen = _AV_MP3_HEADER_POSITION_MAX;
881         else
882                 bufLen = pInfo->fileLen - pInfo->tagV2Info.tagLen;
883
884         if (IS_ID3V2_TAG(buf)) {
885
886
887                 if (pInfo->tagV2Info.tagVersion == 0x02) {
888
889                         if (!mm_file_id3tag_parse_v222(pInfo, buf))
890                                 pInfo->tagV2Info.tagLen = 0;
891                 } else if (pInfo->tagV2Info.tagVersion == 0x03) {
892
893                         if (!mm_file_id3tag_parse_v223(pInfo, buf))
894                                 pInfo->tagV2Info.tagLen = 0;
895                 } else if (pInfo->tagV2Info.tagVersion == 0x04) {
896
897                         if (!mm_file_id3tag_parse_v224(pInfo, buf)) /* currently 2.4 ver pased by 2.3 routine */
898                                 pInfo->tagV2Info.tagLen = 0;
899                 } else {
900 #ifdef __MMFILE_TEST_MODE__
901                         debug_msg("pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagVersion);
902 #endif
903                 }
904
905                 id3v2TagLen = pInfo->tagV2Info.tagLen;
906
907 #ifdef __MMFILE_TEST_MODE__
908                 debug_msg("id3v2TagLen(%d)\n", id3v2TagLen);
909 #endif
910
911                 if (id3v2TagLen) {
912                         if (mmfile_seek(hFile, id3v2TagLen, SEEK_SET) < 0) {
913                                 debug_error("seek failed.\n");
914                                 return -1;
915                         }
916                         if ((readLen = mmfile_read(hFile, buf, bufLen)) <= 0) {
917                                 debug_error("seek failed.\n");
918                                 return -1;
919                         }
920                 }
921                 while (1) {
922                         if (preHeaderGap == bufLen - 2)
923                                 break;
924                         if (__AvIsValidHeader(pInfo, buf + preHeaderGap))
925                                 break;
926                         preHeaderGap++;
927                 }
928
929         } else {
930                 while (1) {
931                         if (preHeaderGap == bufLen - 2)
932                                 break;
933                         if (__AvIsValidHeader(pInfo, buf + preHeaderGap))
934                                 break;
935                         preHeaderGap++;
936                 }
937
938         }
939         minLen = 4;
940
941         buf += preHeaderGap;
942         index += preHeaderGap;
943         while (index <= (bufLen - minLen)) {
944                 if (buf[0] == 0xff) {
945                         if (VALID_SYNC(buf)) {
946                                 if (bufLen - index > 256) {
947                                         pHeader = mmfile_malloc(256);
948                                         if (pHeader == NULL) {
949                                                 debug_error("malloc failed.\n");
950                                                 return -1;
951                                         }
952                                         strncpy((char *)pHeader, (char *)buf, 256);
953                                 } else {
954                                         debug_error("Header field is not exist\n");
955                                         return -1;
956                                 }
957                                 if (__AvParseMp3Header(pInfo, pHeader) == false) {
958                                         /*return -1; */
959                                         if (pHeader)
960                                                 _FREE_EX(pHeader);
961                                         debug_warning("Mp3 parse header failed & index(%d)\n", index);
962                                         buf++;
963                                         index++;
964                                         continue;
965                                 } else {
966 #ifdef __MMFILE_TEST_MODE__
967                                         debug_msg("This header is valid. index(%d)\n", index);
968 #endif
969                                 }
970
971                                 if (__AvParseXingHeader(pInfo, pHeader)) {
972                                         __AvGetXingBitrate(pInfo);
973                                 } else if (__AvParseVBRIHeader(pInfo, pHeader)) {
974                                         __AvGetVBRIBitrate(pInfo);
975                                 }
976
977                                 if (pInfo->bVbr) {
978                                         if (pHeader)
979                                                 _FREE_EX(pHeader);
980                                         bFoundSync = true;
981                                         break;
982                                 } else {
983                                         if (__AvIsValidHeader(pInfo, pHeader)) {
984                                                 if (pHeader)
985                                                         _FREE_EX(pHeader);
986
987                                                 __AvGetMp3FrameSize(pInfo);
988                                                 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
989                                                 frameLen = pInfo->frameSize;
990                                                 if (frameLen) {
991 #ifdef __MMFILE_TEST_MODE__
992                                                         debug_msg("<<< frameLen=[%d] >>> \n", frameLen);
993 #endif
994
995 #ifndef __MMFILE_NEW_FRAME_FUNC /* FIXME : what purpose to do this? */
996                                                         /* Account for loss of precision in the frame length calculation*/
997                                                         frameLen--;
998 #endif
999
1000                                                         /* Check if the remaining buffer size is large enough to
1001                                                         * look for another sync */
1002                                                         if ((index + frameLen) < (bufLen - (minLen - 1))) {
1003                                                                 nextFrameOff = frameLen;
1004                                                                 nextFrameOffEnd = nextFrameOff + MIN(6, bufLen - (index + frameLen) - (minLen - 1));
1005
1006                                                                 /* Search the next few bytes for the next sync */
1007                                                                 while (nextFrameOff < nextFrameOffEnd) {
1008                                                                         if (VALID_SYNC(buf + nextFrameOff)) {
1009                                                                                 if (IS_VALID_FRAME_MP3(buf + nextFrameOff)) {
1010                                                                                         bFoundSync = true;
1011                                                                                         break;
1012                                                                                 }
1013                                                                         }
1014                                                                         nextFrameOff++;
1015                                                                 }
1016                                                                 if (bFoundSync == true)
1017                                                                         break;
1018                                                         } else {
1019                                                                 /* Assume that the first sync is valid, since there is not
1020                                                                 * enough data in the buffer to look for the next sync */
1021                                                                 bFoundSync = true;
1022                                                                 break;
1023                                                         }
1024                                                 }
1025
1026                                         } else {
1027                                                 debug_warning("Is not vaild header pHeader\n");
1028                                         }
1029                                 }
1030                                 if (pHeader)
1031                                         _FREE_EX(pHeader);
1032                         } else {
1033                                 debug_warning("Mp3 file frist byte is 0xff, but not header sync\n");
1034                         }
1035                 }
1036                 buf++;
1037                 index++;
1038         }
1039
1040         _FREE_EX(pHeader);
1041
1042         if (mmfile_seek(hFile, 0, SEEK_SET) < 0) {
1043                 debug_error("seek error!\n");
1044                 return -1;
1045         }
1046         if (index > (bufLen - minLen)) {
1047                 debug_warning("Mp3 file sync is not found : index(%d) bufLen(%d), minLen(%d)\n", index, bufLen, minLen);
1048                 return -1;
1049         }
1050
1051         if (bFoundSync == true) {
1052 #ifdef __MMFILE_TEST_MODE__
1053                 debug_msg("Mp3 file found a sync Success!\n");
1054 #endif
1055         } else {
1056 #ifdef __MMFILE_TEST_MODE__
1057                 debug_msg("Mp3 file found a sync Failed!\n");
1058 #endif
1059                 return -1;
1060         }
1061
1062         return index + id3v2TagLen;
1063 }
1064
1065 /*
1066  *      This function retrieves the mp3 information.
1067  *      Param   szFileName [in] Specifies a mp3 file path.
1068  *      Param   _frame [out]    Specifies a struct pointer for mp3 information.
1069  *      This function returns true on success, or false on failure.
1070  */
1071 static int mmf_file_mp3_get_infomation(char *filename, AvFileContentInfo *pInfo)
1072 {
1073         MMFileIOHandle  *hFile;
1074         unsigned char   header[256];
1075         unsigned long   frameSamples = 0;
1076         unsigned char   *buf = NULL;
1077         unsigned char   *v2TagExistCheck = NULL;
1078         int     readAmount = 0, readedDataLen = 0;
1079         unsigned char   TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
1080         unsigned char           TagV1ID[4] = { 0x54, 0x41, 0x47}; /*TAG */
1081         int             tagHeaderPos = 0;
1082         int ret = 0;
1083         unsigned int head_offset = 0;
1084
1085 #ifdef __MMFILE_TEST_MODE__
1086         debug_fenter();
1087 #endif
1088
1089         if (pInfo == NULL || filename == NULL)
1090                 return -1;
1091
1092         memset(pInfo, 0x00, sizeof(AvFileContentInfo));
1093
1094         pInfo->tagV2Info.tagLen = 0;
1095         pInfo->headerPos = 0;
1096         pInfo->genre = 148;
1097
1098         /*open*/
1099         ret = mmfile_open(&hFile, filename, MMFILE_RDONLY);
1100         if (ret == MMFILE_UTIL_FAIL) {
1101                 debug_error("open failed.\n");
1102                 return -1;
1103         }
1104
1105         mmfile_seek(hFile, 0L, SEEK_END);
1106         pInfo->fileLen = mmfile_tell(hFile);
1107         if (pInfo->fileLen <= 0) {
1108                 debug_error("file is too small.\n");
1109                 goto EXCEPTION;
1110         }
1111         mmfile_seek(hFile, 0L, SEEK_SET);
1112
1113         v2TagExistCheck = mmfile_malloc(MP3_TAGv2_HEADER_LEN);
1114         if (v2TagExistCheck == NULL) {
1115                 debug_error("malloc failed.\n");
1116                 goto EXCEPTION;
1117         }
1118
1119         if (mmfile_read(hFile, v2TagExistCheck, MP3_TAGv2_HEADER_LEN) > 0) {
1120                 if (IS_ID3V2_TAG(v2TagExistCheck)) {
1121                         if (!(v2TagExistCheck[3] == 0xFF || v2TagExistCheck[4] == 0xFF || v2TagExistCheck[6] >= 0x80 || v2TagExistCheck[7] >= 0x80 || v2TagExistCheck[8] >= 0x80 || v2TagExistCheck[9] >= 0x80)) {
1122                                 if (!(v2TagExistCheck[3] > 0x04)) {
1123                                         pInfo->tagV2Info.tagVersion = v2TagExistCheck[3];
1124                                         pInfo->tagV2Info.tagLen = MP3_TAGv2_HEADER_LEN;
1125                                         pInfo->tagV2Info.tagLen += (unsigned long)v2TagExistCheck[6] << 21 | (unsigned long)v2TagExistCheck[7] << 14 | (unsigned long)v2TagExistCheck[8] << 7  | (unsigned long)v2TagExistCheck[9];
1126 #ifdef __MMFILE_TEST_MODE__
1127                                         debug_msg("pInfo->tagV2Info.tagLen(%d), pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagLen, pInfo->tagV2Info.tagVersion);
1128 #endif
1129                                 } else {
1130 #ifdef __MMFILE_TEST_MODE__
1131                                         debug_msg("tag is a not supported version(%d)\n", v2TagExistCheck[3]);
1132 #endif
1133                                 }
1134                         } else {
1135 #ifdef __MMFILE_TEST_MODE__
1136                                 debug_msg("tag is a tag data is valid.\n");
1137 #endif
1138                         }
1139                 } else {
1140 #ifdef __MMFILE_TEST_MODE__
1141                         debug_msg("this mp3 file is not included ID3v2 tag info!\n");
1142 #endif
1143                 }
1144         } else {
1145                 debug_error("v2TagExistCheck value read fail!\n");
1146                 if (v2TagExistCheck)
1147                         _FREE_EX(v2TagExistCheck);
1148                 goto EXCEPTION;
1149         }
1150
1151         if (v2TagExistCheck)
1152                 _FREE_EX(v2TagExistCheck);
1153
1154         if (!(pInfo->fileLen > pInfo->tagV2Info.tagLen))
1155                 pInfo->tagV2Info.tagLen = 0;
1156
1157         if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
1158                 goto EXCEPTION;
1159
1160 #ifdef __MMFILE_TEST_MODE__
1161         debug_msg("pInfo->fileLen(%lld)\n", pInfo->fileLen);
1162 #endif
1163
1164         if (pInfo->fileLen > ((long long)_AV_MP3_HEADER_POSITION_MAX + (long long)pInfo->tagV2Info.tagLen)) {
1165                 readAmount = _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen;
1166                 buf = mmfile_malloc(readAmount);
1167                 if (buf == NULL) {
1168                         debug_error("malloc failed.\n");
1169                         goto EXCEPTION;
1170                 }
1171
1172                 while (readAmount > 0) {
1173                         if (readAmount >= AV_MP3_HEADER_READ_MAX) {
1174                                 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1175                                     && (mmfile_read(hFile, buf + readedDataLen, AV_MP3_HEADER_READ_MAX) <= 0)) {
1176                                         if (buf)
1177                                                 _FREE_EX(buf);
1178
1179                                         goto EXCEPTION;
1180                                 } else {
1181 #ifdef __MMFILE_TEST_MODE__
1182                                         debug_msg("Reading buf readedDataLen(%d) readAmount (%d)\n", readedDataLen, readAmount);
1183 #endif
1184                                 }
1185                         } else {
1186                                 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1187                                     && (mmfile_read(hFile, buf + readedDataLen, readAmount) <= 0)) {
1188                                         if (buf)
1189                                                 _FREE_EX(buf);
1190
1191                                         goto EXCEPTION;
1192                                 } else {
1193 #ifdef __MMFILE_TEST_MODE__
1194                                         debug_msg("The remained buf readed! readedDataLen(%d) readAmount (%d)\n", readedDataLen, readAmount);
1195 #endif
1196                                 }
1197                         }
1198
1199                         readAmount -= AV_MP3_HEADER_READ_MAX;
1200                         readedDataLen += AV_MP3_HEADER_READ_MAX;
1201
1202                         if (readAmount <= 0)
1203                                 break;
1204                 }
1205         } else {
1206                 buf = mmfile_malloc(pInfo->fileLen);
1207                 if (buf == NULL) {
1208                         goto EXCEPTION;
1209                 }
1210
1211                 if (mmfile_read(hFile, buf, pInfo->fileLen) <= 0) {
1212                         if (buf)
1213                                 _FREE_EX(buf);
1214                         goto EXCEPTION;
1215                 }
1216         }
1217
1218
1219         if (__AvGetLastID3offset(hFile, &head_offset)) {
1220 #ifdef __MMFILE_TEST_MODE__
1221                 debug_msg("search start offset: %u\n", head_offset);
1222 #endif
1223                 pInfo->tagV2Info.tagLen = head_offset;
1224         }
1225
1226         pInfo->headerPos = (long) __AvFindStartOfMp3Header(hFile, buf, pInfo);
1227
1228 #ifdef __MMFILE_TEST_MODE__
1229         debug_msg("Header Pos: %ld\n", pInfo->headerPos);
1230 #endif
1231
1232         if (buf)
1233                 _FREE_EX(buf);
1234
1235         if (pInfo->headerPos == -1)
1236                 goto EXCEPTION;
1237
1238         if (mmfile_seek(hFile, pInfo->headerPos, SEEK_SET) < 0)
1239                 goto EXCEPTION;
1240
1241         if (mmfile_read(hFile, header, 256) <= 0)
1242                 goto EXCEPTION;
1243
1244         if (__AvParseMp3Header(pInfo, header) == false)
1245                 goto EXCEPTION;
1246
1247         if (__AvParseXingHeader(pInfo, header)) {
1248                 __AvGetXingBitrate(pInfo);
1249         } else if (__AvParseVBRIHeader(pInfo, header)) {
1250                 __AvGetVBRIBitrate(pInfo);
1251         } else {
1252                 __AvGetMp3FrameSize(pInfo);
1253                 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1254 #ifdef __MMFILE_TEST_MODE__
1255                 debug_msg("Mp3 File FrameSize (%d) pInfo->headerPos(%d)\n", pInfo->frameSize, pInfo->headerPos);
1256 #endif
1257         }
1258
1259         if (mmfile_seek(hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
1260                 goto EXCEPTION;
1261
1262
1263         pInfo->bV1tagFound = false;
1264
1265         if (mmfile_read(hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) <= 0)
1266                 goto EXCEPTION;
1267
1268         if ((tagHeaderPos = __AvMemstr(TagBuff, TagV1ID, 3, TAGV1_SEEK_GAP + 5)) >= 0) {
1269 #ifdef __MMFILE_TEST_MODE__
1270                 debug_msg("Mp3 File Tag is existing\n");
1271 #endif
1272
1273                 pInfo->bV1tagFound = true;
1274                 /* In this case, V2 Tag alreay exist So, ignore V1 tag  */
1275                 if (pInfo->tagV2Info.tagLen == 0) {
1276                         memcpy(TagBuff, (TagBuff + tagHeaderPos), MP3TAGINFO_SIZE);
1277                         if (!mm_file_id3tag_parse_v110(pInfo, TagBuff))
1278                                 goto EXCEPTION;
1279                 }
1280         }
1281
1282         mm_file_id3tag_restore_content_info(pInfo);
1283
1284         if (pInfo->mpegVersion == 1) {
1285                 if (pInfo->layer == 1)
1286                         frameSamples = MPEG_1_SIZE_LAYER_1;
1287                 else
1288                         frameSamples = MPEG_1_SIZE_LAYER_2_3;
1289         } else {
1290                 if (pInfo->layer == 1)
1291                         frameSamples = MPEG_2_SIZE_LAYER_1;
1292                 else
1293                         frameSamples = MPEG_2_SIZE_LAYER_2_3;
1294         }
1295
1296 #if 0
1297         unsigned long   numOfFrames = 0;
1298         unsigned long long      tempduration = 0;
1299         unsigned int            tempNumFrames = 0;
1300
1301         if (pInfo->bVbr)
1302                 numOfFrames = pInfo->frameNum * 10;
1303         else {
1304                 numOfFrames = ((pInfo->fileLen
1305                                 - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0))) * 10) / pInfo->frameSize;
1306         }
1307         tempNumFrames = (unsigned int)(numOfFrames / 10);
1308
1309         if ((numOfFrames - tempNumFrames * 10) > 5)
1310                 numOfFrames = (numOfFrames / 10) + 1;
1311         else
1312                 numOfFrames = numOfFrames / 10;
1313
1314
1315
1316         tempduration = (unsigned long long)(numOfFrames * 1000);
1317
1318         if (pInfo->mpegVersion == 1) {
1319                 if (pInfo->layer == 1)
1320                         frameSamples = MPEG_1_SIZE_LAYER_1;
1321                 else
1322                         frameSamples = MPEG_1_SIZE_LAYER_2_3;
1323         } else {
1324                 if (pInfo->layer == 1)
1325                         frameSamples = MPEG_2_SIZE_LAYER_1;
1326                 else
1327                         frameSamples = MPEG_2_SIZE_LAYER_2_3;
1328         }
1329
1330 #ifdef __MMFILE_TEST_MODE__
1331         debug_msg("frameSamples : %d, tempduration : %ld", frameSamples, tempduration);
1332 #endif
1333
1334         if (tempduration < (unsigned long long)pInfo->sampleRate) {
1335                 tempduration = (tempduration * frameSamples * 10) / pInfo->sampleRate;
1336                 tempduration = (tempduration / 10);
1337         } else
1338                 tempduration = (tempduration * frameSamples) / pInfo->sampleRate;
1339
1340         pInfo->duration = tempduration;
1341 #else
1342         if (pInfo->bVbr) {
1343                 pInfo->duration = ((double)(frameSamples * 1000) / pInfo->sampleRate) * pInfo->frameNum;
1344                 debug_msg("duration for VBR : %lld", pInfo->duration);
1345         } else {
1346                 unsigned long long frame_duration = (((unsigned long long)frameSamples * 1000000000) / pInfo->sampleRate / 1000);
1347                 int file_size_except_header = pInfo->fileLen - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0));
1348                 pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * frame_duration / 1000;
1349                 /*pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * (frameSamples * 1000 / pInfo->sampleRate); */
1350                 debug_msg("duration from new algorithm : %lld", pInfo->duration);
1351         }
1352 #endif
1353
1354         mmfile_close(hFile);
1355
1356         /*debug print*/
1357 #ifdef __MMFILE_TEST_MODE__
1358         debug_msg("Mp3 File pInfo->duration (%lld) \n", pInfo->duration);
1359         debug_msg("** MP3 **\n");
1360         debug_msg("Version    : %u\n", pInfo->mpegVersion);
1361         debug_msg("Layer      : %u\n", pInfo->layer);
1362         debug_msg("Channel idx: %u\n", pInfo->channelIndex);
1363         debug_msg("Is VBR     : %d\n", (pInfo->bVbr == true ? 1 : 0));
1364         debug_msg("Bitrate    : %u\n", pInfo->bitRate);
1365         debug_msg("SampleRate : %u\n", pInfo->sampleRate);
1366         debug_msg("Channels   : %u\n", pInfo->channels);
1367         debug_msg("**** Info #1 ****\n");
1368         debug_msg("Title       : %s\n", pInfo->pTitle);
1369         debug_msg("Artist      : %s\n", pInfo->pArtist);
1370         debug_msg("Album       : %s\n", pInfo->pAlbum);
1371         debug_msg("Album_Artist: %s\n", pInfo->pAlbum_Artist);
1372         debug_msg("Year        : %s\n", pInfo->pYear);
1373         debug_msg("Comment     : %s\n", pInfo->pComment);
1374         debug_msg("TrackNum    : %s\n", pInfo->pTrackNum);
1375         debug_msg("Genre       : %s\n", pInfo->pGenre);
1376         debug_msg("**** Info #2 ****\n");
1377         debug_msg("Author      : %s\n", pInfo->pAuthor);
1378         debug_msg("Copyright   : %s\n", pInfo->pCopyright);
1379         debug_msg("Comment : %s\n", pInfo->pComment);
1380         debug_msg("Rating      : %s\n", pInfo->pRating);
1381         debug_msg("RecDate     : %s\n", pInfo->pRecDate);
1382         debug_msg("Encoded by  : %s\n", pInfo->pEncBy);
1383         debug_msg("URL         : %s\n", pInfo->pURL);
1384         debug_msg("Ori. Artist : %s\n", pInfo->pOriginArtist);
1385         debug_msg("Composer    : %s\n", pInfo->pComposer);
1386         debug_msg("Conductor   : %s\n", pInfo->pConductor);
1387         debug_msg("Artwork     : mime(%s) addr(%p) size(%d)\n", pInfo->imageInfo.imageMIMEType, pInfo->imageInfo.pImageBuf, pInfo->imageInfo.imageLen);
1388         debug_msg("UnsyncLyrics   : %s\n", pInfo->pUnsyncLyrics);
1389         debug_msg("SyncLyrics size  : %d\n", pInfo->syncLyricsNum);
1390
1391 #endif
1392
1393         return 0;
1394
1395 EXCEPTION:
1396         debug_error("Error occured!\n");
1397         mmfile_close(hFile);
1398         return -1;
1399 }