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