Support m360 tag in mp4
[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 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include "mm_file_debug.h"
27 #include "mm_file_utils.h"
28 #include "mm_file_format_private.h"
29 #include "mm_file_format_audio.h"
30 #include "mm_file_format_mp3.h"
31
32 static const int mp3BitRateTable[2][3][16] = {
33         {       {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
34                 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
35                 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
36         },
37
38         {       {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
39                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
40                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
41         }
42 };
43
44 static const int mp3SamRateTable[3][3] = {
45         {44100, 48000, 32000},
46         {22050, 24000, 16000},
47         {11025, 12000, 8000}
48 };
49
50 /* interface functions */
51 int mmfile_format_read_stream_mp3(MMFileFormatContext *formatContext);
52 int mmfile_format_read_frame_mp3(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
53 int mmfile_format_read_tag_mp3(MMFileFormatContext *formatContext);
54 int mmfile_format_close_mp3(MMFileFormatContext *formatContext);
55
56 /* internal */
57 static bool __get_tag_info(char *src, AvFileContentInfo *pInfo, bool extract_artwork);
58 static bool __get_stream_info(char *src, AvFileContentInfo *pInfo);
59
60
61 int mmfile_format_open_mp3(MMFileFormatContext *formatContext)
62 {
63         AvFileContentInfo *privateData = NULL;;
64         debug_fenter(RELEASE);
65
66         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
67         mm_file_retvm_if_fails(DEBUG, MMFileFormatIsValidMP3(NULL, formatContext->uriFileName, 5), MMFILE_FORMAT_FAIL);
68
69         formatContext->ReadStream   = mmfile_format_read_stream_mp3;
70         formatContext->ReadFrame    = mmfile_format_read_frame_mp3;
71         formatContext->ReadTag      = mmfile_format_read_tag_mp3;
72         formatContext->Close        = mmfile_format_close_mp3;
73
74         formatContext->videoTotalTrackNum = 0;
75         formatContext->audioTotalTrackNum = 1;
76
77         privateData = g_new0(AvFileContentInfo, 1);
78
79         formatContext->privateFormatData = privateData;
80
81         return MMFILE_FORMAT_SUCCESS;
82 }
83
84
85 int mmfile_format_read_stream_mp3(MMFileFormatContext *formatContext)
86 {
87         AvFileContentInfo *privateData = NULL;
88
89         debug_fenter(RELEASE);
90
91         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
92         mm_file_retvm_if_fails(DEBUG, formatContext->privateFormatData, MMFILE_FORMAT_FAIL);
93
94         if (!__get_stream_info(formatContext->uriFileName, formatContext->privateFormatData)) {
95                 debug_error(DEBUG, "getting stream information is failed");
96                 return MMFILE_FORMAT_FAIL;
97         }
98
99         privateData = formatContext->privateFormatData;
100
101         formatContext->duration = privateData->duration;
102         formatContext->videoTotalTrackNum = 0;
103         formatContext->audioTotalTrackNum = 1;
104         formatContext->nbStreams = 1;
105         formatContext->streams[MMFILE_AUDIO_STREAM] = g_new0(MMFileFormatStream, 1);
106         formatContext->streams[MMFILE_AUDIO_STREAM]->streamType = MMFILE_AUDIO_STREAM;
107         formatContext->streams[MMFILE_AUDIO_STREAM]->codecId = MM_AUDIO_CODEC_MP3;
108         formatContext->streams[MMFILE_AUDIO_STREAM]->bitRate = (privateData->bitRate * 1000);
109         formatContext->streams[MMFILE_AUDIO_STREAM]->framePerSec = (privateData->duration == 0 ? 0 : privateData->frameNum / privateData->duration);
110         formatContext->streams[MMFILE_AUDIO_STREAM]->width = 0;
111         formatContext->streams[MMFILE_AUDIO_STREAM]->height = 0;
112         formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = privateData->channels;
113         formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = privateData->sampleRate;
114
115         return MMFILE_FORMAT_SUCCESS;
116 }
117
118
119 int mmfile_format_read_frame_mp3(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
120 {
121         return MMFILE_FORMAT_SUCCESS;
122 }
123
124
125 int mmfile_format_read_tag_mp3(MMFileFormatContext *formatContext)
126 {
127         AvFileContentInfo *privateData = NULL;
128
129         debug_fenter(RELEASE);
130
131         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
132         mm_file_retvm_if_fails(DEBUG, formatContext->privateFormatData, MMFILE_FORMAT_FAIL);
133
134         if (!__get_tag_info(formatContext->uriFileName, formatContext->privateFormatData, formatContext->extract_artwork)) {
135                 debug_error(DEBUG, "getting tag information is failed");
136                 return MMFILE_FORMAT_FAIL;
137         }
138
139         privateData = formatContext->privateFormatData;
140
141         formatContext->title = g_strdup(privateData->tagInfo[AV_ID3TAG_TITLE].value);
142         formatContext->artist = g_strdup(privateData->tagInfo[AV_ID3TAG_ARTIST].value);
143         formatContext->copyright = g_strdup(privateData->tagInfo[AV_ID3TAG_COPYRIGHT].value);
144         formatContext->comment = g_strdup(privateData->tagInfo[AV_ID3TAG_COMMENT].value);
145         formatContext->album = g_strdup(privateData->tagInfo[AV_ID3TAG_ALBUM].value);
146         formatContext->album_artist = g_strdup(privateData->tagInfo[AV_ID3TAG_ALBUM_ARTIST].value);
147         formatContext->year = g_strdup(privateData->tagInfo[AV_ID3TAG_YEAR].value);
148         formatContext->genre = g_strdup(privateData->tagInfo[AV_ID3TAG_GENRE].value);
149         formatContext->tagTrackNum = g_strdup(privateData->tagInfo[AV_ID3TAG_TRACKNUM].value);
150         formatContext->composer = g_strdup(privateData->tagInfo[AV_ID3TAG_COMPOSER].value);
151         formatContext->classification = g_strdup(privateData->tagInfo[AV_ID3TAG_CONTENT_GROUP].value);
152         formatContext->conductor = g_strdup(privateData->tagInfo[AV_ID3TAG_CONDUCTOR].value);
153         formatContext->unsyncLyrics = g_strdup(privateData->tagInfo[AV_ID3TAG_UNSYNCLYRICS].value);
154         formatContext->syncLyrics = privateData->pSyncLyrics;
155         formatContext->syncLyricsNum = g_list_length(formatContext->syncLyrics);
156         formatContext->recDate = g_strdup(privateData->tagInfo[AV_ID3TAG_RECDATE].value);
157
158         if (privateData->imageInfo.imageLen > 0) {
159                 formatContext->artworkSize = privateData->imageInfo.imageLen;
160                 formatContext->artwork = g_memdup2(privateData->imageInfo.pImageBuf, privateData->imageInfo.imageLen);
161
162                 if (strlen(privateData->imageInfo.imageMIMEType) > 0)
163                         formatContext->artworkMime = g_strdup(privateData->imageInfo.imageMIMEType);
164                 else if (strlen(privateData->imageInfo.imageExt) > 0) {
165                         debug_msg(RELEASE, "ID3 tag V2 File");
166                         formatContext->artworkMime = g_strdup(privateData->imageInfo.imageExt);
167                 } else {
168                         debug_error(DEBUG, "Album art image exist but there is no type information of album art");
169                 }
170         }
171
172         return MMFILE_FORMAT_SUCCESS;
173 }
174
175
176 int mmfile_format_close_mp3(MMFileFormatContext *formatContext)
177 {
178         AvFileContentInfo *privateData = NULL;
179
180         if (formatContext) {
181                 privateData = formatContext->privateFormatData;
182                 if (privateData) {
183                         mm_file_free_AvFileContentInfo(privateData);
184                         mmfile_free(privateData);
185                         formatContext->privateFormatData = NULL;
186                 }
187         }
188
189         return MMFILE_FORMAT_SUCCESS;
190 }
191
192 static bool __AvGetXingHeader(AvXHeadData *headData,  unsigned char *buf)
193 {
194         int headFlags;
195         int hId, hMode, hSrIndex;
196         int mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
197
198         /* get Xing header data */
199         headData->flags = 0;
200
201         /* get selected MP3 header data */
202         hId                     = (buf[1] >> 3) & 1;
203         hSrIndex        = (buf[2] >> 2) & 3;
204         hMode           = (buf[3] >> 6) & 3;
205
206
207         /* determine offset of header */
208         if (hId) {      /* mpeg1 */
209                 if (hMode != 3)
210                         buf += (32 + 4);
211                 else
212                         buf += (17 + 4);
213         } else {        /* mpeg2 */
214                 if (hMode != 3)
215                         buf += (17 + 4);
216                 else
217                         buf += (9 + 4);
218         }
219
220         /* There could be 2 attrs in this header : Xing or Info */
221         if (buf[0] == 'X') {
222                 mm_file_retv_if_fails(buf[1] == 'i', false);
223                 mm_file_retv_if_fails(buf[2] == 'n', false);
224                 mm_file_retv_if_fails(buf[3] == 'g', false);
225         } else if (buf[0] == 'I') {
226                 mm_file_retv_if_fails(buf[1] == 'n', false);
227                 mm_file_retv_if_fails(buf[2] == 'f', false);
228                 mm_file_retv_if_fails(buf[3] == 'o', false);
229         } else {
230                 return false;
231         }
232
233         buf += 4;
234
235         headData->hId = hId;
236         headData->sampRate = mp3SampleRateTable[hSrIndex];
237         if (hId == 0)
238                 headData->sampRate >>= 1;
239
240         headFlags = headData->flags = MMFILE_CONVERT_INT(buf);          /* get flags */
241         buf += 4;
242
243         if (headFlags & FRAMES_FLAG) {
244                 headData->frames = MMFILE_CONVERT_INT(buf);
245                 buf += 4;
246         }
247         if (headFlags & BYTES_FLAG) {
248                 headData->bytes = MMFILE_CONVERT_INT(buf);
249                 buf += 4;
250         }
251
252         if (headFlags & TOC_FLAG)
253                 buf += 100;
254
255         headData->vbrScale = -1;
256         if (headFlags & VBR_SCALE_FLAG)
257                 headData->vbrScale = MMFILE_CONVERT_INT(buf);
258
259         debug_msg(RELEASE, "Xing header: sampling-rate:%d, stream-size:%d, frame-number:%d",
260                                                 headData->sampRate, headData->bytes, headData->frames);
261
262         return true;       /* success */
263 }
264
265 static bool __AvGetVBRIHeader(AvVBRIHeadData *headData,  unsigned char *buf)
266 {
267         int                     hId, hSrIndex;
268         int     mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
269
270
271         /* get selected MP3 header data */
272         hId                     = (buf[1] >> 3) & 1;
273         hSrIndex        = (buf[2] >> 2) & 3;
274
275         buf += (32 + 4);
276
277         mm_file_retv_if_fails(buf[0] == 'V', false);
278         mm_file_retv_if_fails(buf[1] == 'B', false);
279         mm_file_retv_if_fails(buf[2] == 'R', false);
280         mm_file_retv_if_fails(buf[3] == 'I', false);
281
282         buf += 4;
283
284         headData->hId = hId;
285         headData->sampRate = mp3SampleRateTable[hSrIndex];
286         if (hId == 0)
287                 headData->sampRate >>= 1;
288
289         headData->vID = MMFILE_CONVERT_SHORT(buf);              /* get ver ID */
290         buf += 2;
291         headData->delay = MMFILE_CONVERT_SHORT(buf);
292         buf += 2;
293         headData->qualityIndicator = buf[0];
294         buf += 2;
295         headData->bytes = MMFILE_CONVERT_INT(buf);
296         buf += 4;
297         headData->frames = MMFILE_CONVERT_INT(buf);
298         buf += 4;
299         headData->numOfTOC = MMFILE_CONVERT_SHORT(buf);
300         buf += 2;
301         headData->vbriScale = MMFILE_CONVERT_SHORT(buf);
302         buf += 2;
303         headData->sizePerTable = MMFILE_CONVERT_SHORT(buf);
304         buf += 2;
305         headData->framesPerTable = MMFILE_CONVERT_SHORT(buf);
306
307         debug_msg(RELEASE, "Vbri header: sampling-rate:%d, stream-size:%d, frame-number:%d", headData->sampRate, headData->bytes, headData->frames);
308
309         return true;       /* success */
310 }
311
312 static bool __AvIsValidHeader(AvFileContentInfo *pInfo, unsigned char *buf)
313 {
314         bool bSync = false;
315
316         mm_file_retv_if_fails(VALID_SYNC(buf), false);
317
318         /*
319         * MPEG Audio Layer I/II/III frame header
320         * from : http://www.mp3-tech.org/programmer/frame_header.html           *
321         *
322         * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
323         *
324         * A             11      (31-21) Frame sync (all bits must be set)
325         * B             2       (20,19) MPEG Audio version ID
326         * C             2       (18,17) Layer description
327         * D             1       (16)            Protection bit
328         * E             4       (15,12) Bitrate index
329         * F     2       (11,10) Sampling rate frequency index
330         * G     1       (9)             Padding bit
331         * H     1       (8)             Private bit. This one is only informative.
332         * I     2       (7,6)           Channel Mode
333         * J     2       (5,4)           Mode extension (Only used in Joint stereo)
334         * K     1       (3)             Copyright
335         * L     1       (2)             Original
336         * M     2       (1,0)   Emphasis
337         *
338         */
339
340         /* Simple check for version, layer, bitrate, samplerate */
341         if ((buf[1] & 0x18) != 0x08 && /* 000XX000 : MPEG Audio version ID, XX=01 - reserved => 00001000(0x08) */
342                 (buf[1] & 0x06) != 0x00 && /* 00000XX0 : Layer description, XX=00 - reserved => 00000000(0x00) */
343                 (buf[2] & 0xF0) != 0xF0 && /* XXXX0000 : Bitrate index, XX=1111 - bad => 11110000(0xF0) */
344                 (buf[2] & 0x0C) != 0x0C) { /* 0000XX00 : Sampling rate frequency index, XX=11 -reserved => 00001100(0x0C) */
345                 bSync = true;
346         }
347         debug_msg(RELEASE, "=> %s", bSync ? "Good!" : "Bad...");
348
349         return bSync;
350 }
351
352 static bool __AvParseMp3Header(AvFileContentInfo *pInfo,  unsigned char *header)
353 {
354         unsigned char   result;
355
356         debug_msg(RELEASE, "### [%02x][%02x][%02x][%02x] ###", header[0], header[1], header[2], header[3]);
357
358         /* 1. Check the version of mp3 */
359         result = header[1] & MASK_MPEG;
360         switch (result) {
361         case MASK_MPEG_1:
362                 pInfo->mpegVersion = AV_MPEG_VER_1;
363                 break;
364         case MASK_MPEG_2:
365                 pInfo->mpegVersion = AV_MPEG_VER_2;
366                 break;
367         case MASK_MPEG_25:
368                 pInfo->mpegVersion = AV_MPEG_VER_25;
369                 break;
370         default:
371                 return false;
372         }
373
374         /* 2. Get a layer */
375         result = header[1] & MASK_LAYER;
376         switch (result) {
377         case MASK_LAYER_1:
378                 pInfo->layer = AV_MP3_LAYER_1;
379                 break;
380         case MASK_LAYER_2:
381                 pInfo->layer = AV_MP3_LAYER_2;
382                 break;
383         case MASK_LAYER_3:
384                 pInfo->layer = AV_MP3_LAYER_3;
385                 break;
386         default:
387                 return false;
388         }
389
390         /* 3. bitrate */
391         result = header[2] >> 4;
392         if (pInfo->mpegVersion == AV_MPEG_VER_1)
393                 pInfo->bitRate = mp3BitRateTable[0][pInfo->layer - 1][(int)result] ;
394         else
395                 pInfo->bitRate = mp3BitRateTable[1][pInfo->layer - 1][(int)result] ;
396
397         /* 4. samplerate */
398         result = (header[2] & MASK_SAMPLERATE) >> 2;
399         if (result == 0x03)
400                 return false;
401         else
402                 pInfo->sampleRate = mp3SamRateTable[pInfo->mpegVersion - 1][(int)result];
403
404         /* 5. channel */
405         result = header[3] & MASK_CHANNEL;
406         switch (result) {
407         case MASK_CHANNEL_ST:
408                 pInfo->channelIndex = 0;
409                 pInfo->channels = 2;
410                 break;
411         case MASK_CHANNEL_JS:
412                 pInfo->channelIndex = 1;
413                 pInfo->channels = 2;
414                 break;
415         case MASK_CHANNEL_DC:
416                 pInfo->channelIndex = 2;
417                 pInfo->channels = 2;
418                 break;
419         case MASK_CHANNEL_MN:
420                 pInfo->channelIndex = 3;;
421                 pInfo->channels = 1;
422                 break;
423         default:
424                 return false;
425         }
426
427         /*      6. padding */
428         result = header[2] & MASK_PADDING;
429         if (result == MASK_PADDING)
430                 pInfo->bPadding = true;
431         else
432                 pInfo->bPadding = false;
433
434         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);
435
436         return true;
437 }
438
439 static bool __AvParseXingHeader(AvFileContentInfo *pInfo, unsigned char *buf)
440 {
441         AvXHeadData data = {0, };
442         unsigned int pos = 0;
443
444         /*      1. Xing Header */
445         /* There could be 2 attrs in this header : Xing or Info */
446         if ((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2))
447                 pos = 36;
448         else if ((pInfo->mpegVersion == AV_MPEG_VER_2 || pInfo->mpegVersion == AV_MPEG_VER_25) && (pInfo->channels == 1))
449                 pos = 13;
450         else
451                 pos = 21;
452
453         if (buf[pos] == 'X') {
454                 mm_file_retv_if_fails(buf[pos + 1] == 'i', false);
455                 mm_file_retv_if_fails(buf[pos + 2] == 'n', false);
456                 mm_file_retv_if_fails(buf[pos + 3] == 'g', false);
457         } else if (buf[pos] == 'I') {
458                 mm_file_retv_if_fails(buf[pos + 1] == 'n', false);
459                 mm_file_retv_if_fails(buf[pos + 2] == 'f', false);
460                 mm_file_retv_if_fails(buf[pos + 3] == 'o', false);
461         } else {
462                 return false;
463         }
464
465         if (__AvGetXingHeader(&data, (unsigned char *)buf)) {   /* VBR. */
466                 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
467                         debug_error(DEBUG, "invalid Xing header");
468                         return false;
469                 }
470
471                 pInfo->datafileLen = data.bytes;
472                 pInfo->frameNum = data.frames;
473                 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames);
474                 pInfo->bVbr = true;
475                 return true;
476         } else
477                 return false;
478 }
479
480 static bool __AvParseVBRIHeader(AvFileContentInfo *pInfo, unsigned char *buf)
481 {
482         AvVBRIHeadData data = {0, };
483
484         /*      1. Xing Header */
485         mm_file_retv_if_fails(buf[36] == 'V', false);
486         mm_file_retv_if_fails(buf[37] == 'B', false);
487         mm_file_retv_if_fails(buf[38] == 'R', false);
488         mm_file_retv_if_fails(buf[39] == 'I', false);
489
490         mm_file_retvm_if_fails(DEBUG, __AvGetVBRIHeader(&data, buf), false);
491         mm_file_retvm_if_fails(DEBUG, data.sampRate > 0, false);
492         mm_file_retvm_if_fails(DEBUG, data.bytes > 0, false);
493         mm_file_retvm_if_fails(DEBUG, data.frames > 0, false);
494
495         pInfo->sampleRate = data.sampRate;
496         pInfo->datafileLen = data.bytes;
497         pInfo->frameNum = data.frames;
498         pInfo->frameSize = (int)((float) data.bytes / (float) data.frames)  ;
499         pInfo->bVbr = true;
500
501         return true;
502 }
503
504 static bool __AvGetMp3FrameSize(AvFileContentInfo *pInfo)
505 {
506         unsigned int frameSize = 0;
507         if (pInfo == NULL)
508                 return false;
509
510         frameSize =  pInfo->bPadding;
511         if (pInfo->bitRate == 0) {
512                 if (pInfo->layer == 1) {
513                         frameSize *= 4;
514                         frameSize += 0/* FIXME: possible_free_framelen*/;
515                         pInfo->bitRate = frameSize * pInfo->sampleRate / 48000;
516                 } else {
517                         frameSize += 0/* FIXME: possible_free_framelen*/;
518                         pInfo->bitRate = frameSize * pInfo->sampleRate / ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000);
519                 }
520         } else {
521                 /* calculating */
522                 if (pInfo->layer == 1) {
523                         frameSize = ((12000 * pInfo->bitRate / pInfo->sampleRate) + frameSize) * 4;
524                 } else {
525                         frameSize += ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000) * pInfo->bitRate / pInfo->sampleRate;
526                 }
527         }
528
529         pInfo->frameSize = (int)frameSize;
530
531         return true;
532 }
533
534 static bool __AvGetBitrate(AvFileContentInfo *pInfo)
535 {
536         float   br, factor;
537         int             padding = 0;
538
539         mm_file_retv_if_fails(pInfo, false);
540         mm_file_retv_if_fails(pInfo->bVbr, false);
541
542         if (pInfo->bPadding)
543                 padding = 1;
544
545         if (pInfo->mpegVersion == AV_MPEG_VER_1) {      /* MPEG version 1 */
546                 if (pInfo->layer == AV_MP3_LAYER_1)     /* Layer 1 */
547                         factor = 48000.0;
548                 else                                            /* Layer 2, 3 */
549                         factor = 144000.0;
550         } else {                                                /* MPEG version 2 */
551                 if (pInfo->layer == AV_MP3_LAYER_1)     /*      Layer 1 */
552                         factor = 24000.0;
553                 else                                            /*      Layer 2, 3 */
554                         factor = 72000.0;
555         }
556
557         br = (pInfo->frameSize - padding) * pInfo->sampleRate / factor;
558
559         pInfo->bitRate = (int) br;
560
561         return true;
562 }
563
564 static bool __AvGetID3v1Header(unsigned char *buf, size_t buf_size, int *offset)
565 {
566         unsigned char TagV1ID[4] = { 0x54, 0x41, 0x47}; /* TAG */
567         int id3v1_offset = 0;
568
569         mm_file_retvm_if_fails(DEBUG, buf, false);
570         mm_file_retvm_if_fails(DEBUG, buf_size >= 3, false);
571
572         id3v1_offset = __AvMemstr(buf, TagV1ID, 3, TAGV1_SEEK_GAP + 5);
573         mm_file_retv_if_fails(id3v1_offset >= 0, false);
574
575         if (offset)
576                 *offset = id3v1_offset;
577
578         debug_msg(RELEASE, "ID3v1 is existing");
579         return true;
580 }
581
582 static bool __AvGetID3v2Header(unsigned char *buf, size_t buf_size, AvTagVer2AdditionalData *id3v2info)
583 {
584         mm_file_retvm_if_fails(DEBUG, buf, false);
585         mm_file_retvm_if_fails(DEBUG, buf_size >= MP3_TAGv2_HEADER_LEN, false);
586         mm_file_retvm_if_fails(DEBUG, id3v2info, false);
587         mm_file_retvm_if_fails(DEBUG, IS_ID3V2_TAG(buf), false);
588
589         /* weak id3v2 tag check */
590         if (buf[3] == 0xFF || buf[4] == 0xFF || buf[6] >= 0x80 || buf[7] >= 0x80 || buf[8] >= 0x80 || buf[9] >= 0x80) {
591                 debug_error(RELEASE, "Invalid ID3v2 base header!");
592                 return false;
593         }
594
595         if (buf[3] > 0x04) {
596                 debug_error(RELEASE, "Invalid or not supported ID3v2 version(%d)!", buf[3]);
597                 return false;
598         }
599
600         id3v2info->tagVersion = buf[3];
601         id3v2info->tagLen = MP3_TAGv2_HEADER_LEN;
602         id3v2info->tagLen += (unsigned long)buf[6] << 21 | (unsigned long)buf[7] << 14 | (unsigned long)buf[8] << 7  | (unsigned long)buf[9];
603         debug_msg(RELEASE, "ID3v2 version(%d), length (%d)", id3v2info->tagVersion, id3v2info->tagLen);
604
605         return true;
606 }
607
608 static bool __AvGetMp3HeaderInfo(MMFileIOHandle *hFile, AvFileContentInfo *pInfo)
609 {
610         long preHeaderGap = 0;
611         unsigned char header[MP3_FORMAT_HEADER_LEN] = {0, };
612
613         mm_file_retvm_if_fails(DEBUG, hFile, false);
614         mm_file_retvm_if_fails(DEBUG, pInfo, false);
615
616         preHeaderGap = pInfo->tagV2Info.tagLen;
617
618         while (preHeaderGap < pInfo->fileLen - MP3_FORMAT_HEADER_LEN) {
619                 if (mmfile_seek(hFile, preHeaderGap, SEEK_SET) < 0)
620                         return false;
621
622                 if (mmfile_read(hFile, header, MP3_FORMAT_HEADER_LEN) != MP3_FORMAT_HEADER_LEN)
623                         return false;
624
625                 if (!__AvIsValidHeader(pInfo, header)) {
626                         preHeaderGap++;
627                         continue;
628                 }
629
630                 if (!__AvParseMp3Header(pInfo, header)) {
631                         debug_warning(DEBUG, "Mp3 parse header failed & preHeaderGap(%ld)", preHeaderGap);
632                         preHeaderGap++;
633                         continue;
634                 }
635
636                 debug_msg(RELEASE, "This header is valid. preHeaderGap(%ld)", preHeaderGap);
637                 pInfo->headerPos = preHeaderGap;
638
639                 if (__AvParseXingHeader(pInfo, header) || __AvParseVBRIHeader(pInfo, header)) {
640                         __AvGetBitrate(pInfo);
641                 } else {
642                         __AvGetMp3FrameSize(pInfo);
643                         pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
644                         debug_msg(RELEASE, "Mp3 File FrameSize (%d) pInfo->headerPos(%ld)", pInfo->frameSize, pInfo->headerPos);
645                 }
646
647                 return true;
648         }
649
650         return false;
651 }
652
653 /*
654  * MP3 file structure
655  *
656  * -----------------------------------------------------
657  * |  Start Offset: 0                                  |
658  * |  ID3(ID3v2)                                       |
659  * |  Length: variable                                 |
660  * -----------------------------------------------------
661  * |  Start Offset: at the end of Last ID3             |
662  * |  MP3(Mpeg audio)                                  |
663  * |  Length: variable                                 |
664  * -----------------------------------------------------
665  * |  Start Offset: -(128byte + a) at the end of file  |
666  * |  TAG(ID3v1)                                       |
667  * |  Length: Fixed 128byte                            |
668  * -----------------------------------------------------
669  */
670 /*
671  *      This function retrieves the ID3 tag information.
672  *      Param   filename [in] Specifies a mp3 file path.
673  *      Param   pInfo [out]     Specifies a struct pointer for ID3 tag information.
674  *      This function returns true on success, or false on failure.
675  */
676 static bool __get_tag_info(char *filename, AvFileContentInfo *pInfo, bool extract_artwork)
677 {
678         MMFileIOHandle *hFile;
679         unsigned char *buf = NULL;
680         unsigned char tag_v1[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP] = {0, };
681         unsigned char check_tag_v2[MP3_TAGv2_HEADER_LEN] = {0, };
682         int tagHeaderPos = 0;
683
684         debug_fenter(RELEASE);
685
686         mm_file_retv_if_fails(pInfo, false);
687         mm_file_retv_if_fails(filename, false);
688
689         memset(pInfo, 0x00, sizeof(AvFileContentInfo));
690
691         pInfo->tagV2Info.tagLen = 0;
692         pInfo->headerPos = 0;
693         pInfo->genre = 148;
694
695         /*open*/
696         mm_file_retvm_if_fails(DEBUG, mmfile_open(&hFile, filename, MMFILE_RDONLY) == MMFILE_UTIL_SUCCESS, false);
697
698         pInfo->fileLen = mmfile_get_size(hFile);
699         if (pInfo->fileLen <= 0) {
700                 debug_error(DEBUG, "file is too small.");
701                 goto EXCEPTION;
702         }
703
704         /* read file to check ID3v2 header */
705         if (mmfile_read(hFile, check_tag_v2, MP3_TAGv2_HEADER_LEN) != MP3_TAGv2_HEADER_LEN) {
706                 debug_error(DEBUG, "ID3v2 check fail!");
707                 goto EXCEPTION;
708         }
709
710         /* check ID3v2 header */
711         __AvGetID3v2Header(check_tag_v2, MP3_TAGv2_HEADER_LEN, &pInfo->tagV2Info);
712
713         if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
714                 goto EXCEPTION;
715
716         debug_msg(RELEASE, "pInfo->fileLen(%lld)", pInfo->fileLen);
717
718         /* read file to get ID3v2 tags from offset 0 */
719         if (pInfo->fileLen <= (long long)pInfo->tagV2Info.tagLen)
720                 pInfo->tagV2Info.tagLen = pInfo->fileLen;
721
722         debug_msg(RELEASE, "buf size(%d)", pInfo->tagV2Info.tagLen);
723
724         buf = g_malloc0(pInfo->tagV2Info.tagLen);
725
726         if (mmfile_read(hFile, buf, pInfo->tagV2Info.tagLen) != pInfo->tagV2Info.tagLen) {
727                 mmfile_free(buf);
728                 goto EXCEPTION;
729         }
730
731         if (pInfo->tagV2Info.tagVersion == 0x02)
732                 mm_file_id3tag_parse_v222(pInfo, buf, extract_artwork);
733         else if (pInfo->tagV2Info.tagVersion == 0x03)
734                 mm_file_id3tag_parse_v223(pInfo, buf, extract_artwork);
735         else if (pInfo->tagV2Info.tagVersion == 0x04)
736                 mm_file_id3tag_parse_v224(pInfo, buf, extract_artwork); /* currently 2.4 ver parsed by 2.3 routine */
737         else
738                 debug_msg(RELEASE, "Invalid tag version(%d)", pInfo->tagV2Info.tagVersion);
739
740         mmfile_free(buf);
741
742         /* locate fp to read TAG(ID3v1) information */
743         if (mmfile_seek(hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
744                 goto EXCEPTION;
745
746         pInfo->bV1tagFound = false;
747
748         /* read ID3v1 */
749         if (mmfile_read(hFile, tag_v1, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) != MP3TAGINFO_SIZE + TAGV1_SEEK_GAP)
750                 goto EXCEPTION;
751
752         /* check and get ID3v1 information */
753         if (__AvGetID3v1Header(tag_v1, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP, &tagHeaderPos)) {
754                 pInfo->bV1tagFound = true;
755                 if (tagHeaderPos == TAGV1_SEEK_GAP) {
756                         if (!mm_file_id3tag_parse_v110(pInfo, tag_v1 + tagHeaderPos))
757                                 debug_msg(RELEASE, "mm_file_id3tag_parse_v110 fails");
758                 }
759         }
760
761         mm_file_id3tag_restore_content_info(pInfo);
762
763         mmfile_close(hFile);
764
765         /*debug print*/
766         debug_msg(RELEASE, "Title       : %s", pInfo->tagInfo[AV_ID3TAG_TITLE].value);
767         debug_msg(RELEASE, "Artist      : %s", pInfo->tagInfo[AV_ID3TAG_ARTIST].value);
768         debug_msg(RELEASE, "Album       : %s", pInfo->tagInfo[AV_ID3TAG_ALBUM].value);
769         debug_msg(RELEASE, "Album_Artist: %s", pInfo->tagInfo[AV_ID3TAG_ALBUM_ARTIST].value);
770         debug_msg(RELEASE, "Year        : %s", pInfo->tagInfo[AV_ID3TAG_YEAR].value);
771         debug_msg(RELEASE, "Comment     : %s", pInfo->tagInfo[AV_ID3TAG_COMMENT].value);
772         debug_msg(RELEASE, "TrackNum    : %s", pInfo->tagInfo[AV_ID3TAG_TRACKNUM].value);
773         debug_msg(RELEASE, "Genre       : %s", pInfo->tagInfo[AV_ID3TAG_GENRE].value);
774         debug_msg(RELEASE, "Copyright   : %s", pInfo->tagInfo[AV_ID3TAG_COPYRIGHT].value);
775         debug_msg(RELEASE, "RecDate     : %s", pInfo->tagInfo[AV_ID3TAG_RECDATE].value);
776         debug_msg(RELEASE, "Composer    : %s", pInfo->tagInfo[AV_ID3TAG_COMPOSER].value);
777         debug_msg(RELEASE, "Conductor   : %s", pInfo->tagInfo[AV_ID3TAG_CONDUCTOR].value);
778         debug_msg(RELEASE, "Artwork     : mime(%s) addr(%p) size(%d)", pInfo->imageInfo.imageMIMEType, pInfo->imageInfo.pImageBuf, pInfo->imageInfo.imageLen);
779         debug_msg(RELEASE, "UnsyncLyrics   : %s", pInfo->tagInfo[AV_ID3TAG_UNSYNCLYRICS].value);
780
781         return true;
782
783 EXCEPTION:
784         debug_error(DEBUG, "Error occured!");
785         mmfile_close(hFile);
786         return false;
787 }
788
789 /*
790  *      This function retrieves the MP3 stream information.
791  *      Param   filename [in] Specifies a mp3 file path.
792  *      Param   pInfo [out]     Specifies a struct pointer for MP3 stream information.
793  *      This function returns true on success, or false on failure.
794  */
795 static bool __get_stream_info(char *filename, AvFileContentInfo *pInfo)
796 {
797         MMFileIOHandle *hFile;
798         unsigned long frameSamples = 0;
799         AvTagVer2AdditionalData tagInfo = { 0, };
800         unsigned char check_v1[TAGV1_SEEK_GAP + 5] = {0, };
801         unsigned char check_v2[MP3_TAGv2_HEADER_LEN] = {0, };
802
803         debug_fenter(RELEASE);
804
805         mm_file_retv_if_fails(pInfo, false);
806         mm_file_retv_if_fails(filename, false);
807
808         memset(pInfo, 0x00, sizeof(AvFileContentInfo));
809
810         pInfo->tagV2Info.tagLen = 0;
811         pInfo->headerPos = 0;
812         pInfo->genre = 148;
813
814         mm_file_retvm_if_fails(DEBUG, mmfile_open(&hFile, filename, MMFILE_RDONLY) == MMFILE_UTIL_SUCCESS, false);
815
816         pInfo->fileLen = mmfile_get_size(hFile);
817         if (pInfo->fileLen <= 0) {
818                 debug_error(DEBUG, "file is too small.");
819                 goto EXCEPTION;
820         }
821
822         /* Find the end of ID3v2 */
823         while (pInfo->tagV2Info.tagLen < pInfo->fileLen - MP3_TAGv2_HEADER_LEN) {
824                 mmfile_seek(hFile, pInfo->tagV2Info.tagLen, SEEK_SET);
825
826                 if (mmfile_read(hFile, check_v2, MP3_TAGv2_HEADER_LEN) != MP3_TAGv2_HEADER_LEN)
827                         goto EXCEPTION;
828
829                 if (!__AvGetID3v2Header(check_v2, MP3_TAGv2_HEADER_LEN, &tagInfo))
830                         break;
831
832                 /* Some contents may have multiple id3 tags */
833                 pInfo->tagV2Info.tagLen += tagInfo.tagLen;
834                 debug_msg(RELEASE, "ID3 size[%u] Total size[%u]", tagInfo.tagLen, pInfo->tagV2Info.tagLen);
835         }
836
837         debug_msg(RELEASE, "ID3 Len[%u] File Len[%lld]", pInfo->tagV2Info.tagLen, pInfo->fileLen);
838
839         if (!__AvGetMp3HeaderInfo(hFile, pInfo))
840                 goto EXCEPTION;
841
842         if (pInfo->mpegVersion == 1)
843                 frameSamples = (pInfo->layer == 1) ? MPEG_1_SIZE_LAYER_1 : MPEG_1_SIZE_LAYER_2_3;
844         else
845                 frameSamples = (pInfo->layer == 1) ? MPEG_2_SIZE_LAYER_1 : MPEG_2_SIZE_LAYER_2_3;
846
847         /* check TAG(ID3v1) exist due to duration */
848         if (mmfile_seek(hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
849                 goto EXCEPTION;
850
851         pInfo->bV1tagFound = false;
852
853         if (mmfile_read(hFile, check_v1, TAGV1_SEEK_GAP + 5) != TAGV1_SEEK_GAP + 5)
854                 goto EXCEPTION;
855
856         mmfile_close(hFile);
857
858         /* Check if id3v1 tag exists for duration calculation. */
859         if (__AvGetID3v1Header(check_v1, TAGV1_SEEK_GAP + 5, NULL))
860                 pInfo->bV1tagFound = true;
861
862         /* get MP3 duration */
863         if (pInfo->bVbr) {
864                 pInfo->duration = ((double)(frameSamples * 1000) / pInfo->sampleRate) * pInfo->frameNum;
865                 debug_msg(DEBUG, "duration for VBR : %lld", pInfo->duration);
866         } else {
867                 unsigned long long frame_duration = (((unsigned long long)frameSamples * 1000000000) / pInfo->sampleRate / 1000);
868                 int file_size_except_header = pInfo->fileLen - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0));
869                 pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * frame_duration / 1000;
870                 /*pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * (frameSamples * 1000 / pInfo->sampleRate); */
871                 debug_msg(DEBUG, "duration from new algorithm : %lld", pInfo->duration);
872         }
873
874         /*debug print*/
875         debug_msg(RELEASE, "Mp3 File pInfo->duration (%lld) ", pInfo->duration);
876         debug_msg(RELEASE, "** MP3 **");
877         debug_msg(RELEASE, "Version    : %u", pInfo->mpegVersion);
878         debug_msg(RELEASE, "Layer      : %u", pInfo->layer);
879         debug_msg(RELEASE, "Channel idx: %u", pInfo->channelIndex);
880         debug_msg(RELEASE, "Is VBR     : %d", (pInfo->bVbr == true ? 1 : 0));
881         debug_msg(RELEASE, "Bitrate    : %u", pInfo->bitRate);
882         debug_msg(RELEASE, "SampleRate : %u", pInfo->sampleRate);
883         debug_msg(RELEASE, "Channels   : %u", pInfo->channels);
884
885         return true;
886
887 EXCEPTION:
888         debug_error(DEBUG, "Error occured!");
889         mmfile_close(hFile);
890         return false;
891 }