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