4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Haejeong Kim <backto.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <string.h> /*memcmp*/
24 #include <sys/types.h>
25 #include <sys/stat.h> /*stat*/
28 #include <stdlib.h> /*malloc*/
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"
37 #define __MMFILE_NEW_FRAME_FUNC
39 #ifdef __MMFILE_NEW_TAGLIBS__
40 #include "mm_file_format_tags.h"
44 #define AV_MP3_FIND_SYNC_LEN 1024*30
46 #define MIN(a, b) ((a) < (b) ? (a) : (b))
49 static const unsigned char mp3FrameMasking[4] = {0xFF, 0xFE, 0x0C, 0x00};
50 static unsigned char mp3FrameDataValid[4];
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,}
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,}
64 static const int mp3SamRateTable[3][3] = {
65 {44100, 48000, 32000},
66 {22050, 24000, 16000},
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]))
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);
85 static int mmf_file_mp3_get_tag_info(char *src, AvFileContentInfo *pInfo);
86 static int mmf_file_mp3_get_stream_info(char *src, AvFileContentInfo *pInfo);
90 int mmfile_format_open_mp3(MMFileFormatContext *formatContext)
92 AvFileContentInfo *privateData = NULL;;
95 debug_fenter(RELEASE);
97 if (NULL == formatContext) {
98 debug_error(DEBUG, "formatContext is NULL\n");
99 return MMFILE_FORMAT_FAIL;
102 ret = MMFileFormatIsValidMP3(NULL, formatContext->uriFileName, 5);
104 debug_error(DEBUG, "It is not mp3 file\n");
105 return MMFILE_FORMAT_FAIL;
108 formatContext->ReadStream = mmfile_format_read_stream_mp3;
109 formatContext->ReadFrame = mmfile_format_read_frame_mp3;
110 formatContext->ReadTag = mmfile_format_read_tag_mp3;
111 formatContext->Close = mmfile_format_close_mp3;
113 formatContext->videoTotalTrackNum = 0;
114 formatContext->audioTotalTrackNum = 1;
116 privateData = mmfile_malloc(sizeof(AvFileContentInfo));
118 debug_error(DEBUG, "error: mmfile_malloc MP3 privateData\n");
119 return MMFILE_FORMAT_FAIL;
122 formatContext->privateFormatData = privateData;
124 return MMFILE_FORMAT_SUCCESS;
129 int mmfile_format_read_stream_mp3(MMFileFormatContext *formatContext)
131 AvFileContentInfo *privateData = NULL;
133 debug_fenter(RELEASE);
135 if (!formatContext || !formatContext->privateFormatData) {
136 debug_error(DEBUG, "formatContext is NULL\n");
137 return MMFILE_FORMAT_FAIL;
140 if (mmf_file_mp3_get_stream_info(formatContext->uriFileName, formatContext->privateFormatData) < 0) {
141 debug_error(DEBUG, "getting stream information is failed");
142 return MMFILE_FORMAT_FAIL;
145 privateData = formatContext->privateFormatData;
147 formatContext->duration = privateData->duration;
148 formatContext->videoTotalTrackNum = 0;
149 formatContext->audioTotalTrackNum = 1;
150 formatContext->nbStreams = 1;
151 formatContext->streams[MMFILE_AUDIO_STREAM] = mmfile_malloc(sizeof(MMFileFormatStream));
152 if (!formatContext->streams[MMFILE_AUDIO_STREAM]) {
153 debug_error(DEBUG, "formatContext->streams[MMFILE_AUDIO_STREAM] is NULL\n");
154 return MMFILE_FORMAT_FAIL;
157 formatContext->streams[MMFILE_AUDIO_STREAM]->streamType = MMFILE_AUDIO_STREAM;
158 formatContext->streams[MMFILE_AUDIO_STREAM]->codecId = MM_AUDIO_CODEC_MP3;
159 formatContext->streams[MMFILE_AUDIO_STREAM]->bitRate = (privateData->bitRate * 1000);
160 formatContext->streams[MMFILE_AUDIO_STREAM]->framePerSec = (privateData->duration == 0 ? 0 : privateData->frameNum / privateData->duration);
161 formatContext->streams[MMFILE_AUDIO_STREAM]->width = 0;
162 formatContext->streams[MMFILE_AUDIO_STREAM]->height = 0;
163 formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = privateData->channels;
164 formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = privateData->sampleRate;
166 return MMFILE_FORMAT_SUCCESS;
171 int mmfile_format_read_frame_mp3(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
173 return MMFILE_FORMAT_SUCCESS;
177 int mmfile_format_read_tag_mp3(MMFileFormatContext *formatContext)
179 AvFileContentInfo *privateData = NULL;
181 debug_fenter(RELEASE);
183 if (!formatContext || !formatContext->privateFormatData) {
184 debug_error(DEBUG, "formatContext is NULL\n");
185 return MMFILE_FORMAT_FAIL;
188 if (mmf_file_mp3_get_tag_info(formatContext->uriFileName, formatContext->privateFormatData) < 0) {
189 debug_error(DEBUG, "getting tag information is failed");
190 return MMFILE_FORMAT_FAIL;
193 privateData = formatContext->privateFormatData;
195 formatContext->title = mmfile_strdup(privateData->pTitle);
196 formatContext->artist = mmfile_strdup(privateData->pArtist);
197 formatContext->copyright = mmfile_strdup(privateData->pCopyright);
198 formatContext->comment = mmfile_strdup(privateData->pComment);
199 formatContext->album = mmfile_strdup(privateData->pAlbum);
200 formatContext->album_artist = mmfile_strdup(privateData->pAlbum_Artist);
201 formatContext->year = mmfile_strdup(privateData->pYear);
202 formatContext->genre = mmfile_strdup(privateData->pGenre);
203 formatContext->tagTrackNum = mmfile_strdup(privateData->pTrackNum);
204 formatContext->composer = mmfile_strdup(privateData->pComposer);
205 formatContext->classification = mmfile_strdup(privateData->pContentGroup);
206 formatContext->conductor = mmfile_strdup(privateData->pConductor);
207 formatContext->unsyncLyrics = mmfile_strdup(privateData->pUnsyncLyrics);
208 formatContext->syncLyrics = privateData->pSyncLyrics;
209 formatContext->syncLyricsNum = privateData->syncLyricsNum;
210 formatContext->recDate = mmfile_strdup(privateData->pRecDate);
211 formatContext->part_of_set = mmfile_strdup(privateData->pPartOfASet);
213 if (privateData->imageInfo.imageLen > 0) {
214 formatContext->artwork = mmfile_malloc(privateData->imageInfo.imageLen);
215 if (formatContext->artwork) {
216 formatContext->artworkSize = privateData->imageInfo.imageLen;
217 memcpy(formatContext->artwork, privateData->imageInfo.pImageBuf, privateData->imageInfo.imageLen);
218 if (strlen(privateData->imageInfo.imageMIMEType) > 0)
219 formatContext->artworkMime = mmfile_strdup(privateData->imageInfo.imageMIMEType);
220 else if (strlen(privateData->imageInfo.imageExt) > 0) {
221 debug_msg(RELEASE, "ID3 tag V2 File");
222 formatContext->artworkMime = mmfile_strdup(privateData->imageInfo.imageExt);
224 debug_error(DEBUG, "Album art image exist but there is no type information of album art\n");
229 return MMFILE_FORMAT_SUCCESS;
233 int mmfile_format_close_mp3(MMFileFormatContext *formatContext)
235 AvFileContentInfo *privateData = NULL;
238 privateData = formatContext->privateFormatData;
240 mm_file_free_AvFileContentInfo(privateData);
241 mmfile_free(privateData);
242 formatContext->privateFormatData = NULL;
246 return MMFILE_FORMAT_SUCCESS;
250 __AvExtractI4(unsigned char *buf)
266 __AvExtractI2(unsigned char *buf)
279 __AvGetXingHeader(AvXHeadData *headData, unsigned char *buf)
281 int index, headFlags;
282 int hId, hMode, hSrIndex;
283 int mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
285 /* get Xing header data */
288 /* get selected MP3 header data */
289 hId = (buf[1] >> 3) & 1;
290 hSrIndex = (buf[2] >> 2) & 3;
291 hMode = (buf[3] >> 6) & 3;
294 /* determine offset of header */
295 if (hId) { /* mpeg1 */
307 /* There could be 2 attrs in this header : Xing or Info */
309 if (buf[1] != 'i') return 0;
310 if (buf[2] != 'n') return 0;
311 if (buf[3] != 'g') return 0;
312 } else if (buf[0] == 'I') {
313 if (buf[1] != 'n') return 0;
314 if (buf[2] != 'f') return 0;
315 if (buf[3] != 'o') return 0;
323 headData->sampRate = mp3SampleRateTable[hSrIndex];
325 headData->sampRate >>= 1;
327 headFlags = headData->flags = __AvExtractI4(buf); /* get flags */
330 if (headFlags & FRAMES_FLAG) {
331 headData->frames = __AvExtractI4(buf);
334 if (headFlags & BYTES_FLAG) {
335 headData->bytes = __AvExtractI4(buf);
339 if (headFlags & TOC_FLAG) {
340 if (headData->toc != NULL) {
341 for (index = 0; index < 100; index++)
342 headData->toc[index] = buf[index];
347 headData->vbrScale = -1;
348 if (headFlags & VBR_SCALE_FLAG) {
349 headData->vbrScale = __AvExtractI4(buf);
352 debug_msg(RELEASE, "Xing header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
353 headData->sampRate, headData->bytes, headData->frames);
355 return 1; /* success */
359 __AvGetVBRIHeader(AvVBRIHeadData *headData, unsigned char *buf)
362 int mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
365 /* get selected MP3 header data */
366 hId = (buf[1] >> 3) & 1;
367 hSrIndex = (buf[2] >> 2) & 3;
371 if (buf[0] != 'V') return 0; /* fail */
372 if (buf[1] != 'B') return 0; /* header not found */
373 if (buf[2] != 'R') return 0;
374 if (buf[3] != 'I') return 0;
378 headData->sampRate = mp3SampleRateTable[hSrIndex];
380 headData->sampRate >>= 1;
382 headData->vID = __AvExtractI2(buf); /* get ver ID */
384 headData->delay = __AvExtractI2(buf);
386 headData->qualityIndicator = buf[0];
388 headData->bytes = __AvExtractI4(buf);
390 headData->frames = __AvExtractI4(buf);
392 headData->numOfTOC = __AvExtractI2(buf);
394 headData->vbriScale = __AvExtractI2(buf);
396 headData->sizePerTable = __AvExtractI2(buf);
398 headData->framesPerTable = __AvExtractI2(buf);
400 debug_msg(RELEASE, "Vbri header: sampling-rate:%d, stream-size:%d, frame-number:%d\n", headData->sampRate, headData->bytes, headData->frames);
402 return true; /* success */
405 __AvIsValidHeader(AvFileContentInfo *pInfo, unsigned char *buf)
409 if (VALID_SYNC(buf)) {
410 mp3FrameDataValid[0] = (0xFF) & (mp3FrameMasking[0]);
411 mp3FrameDataValid[1] = (0xE0 | (buf[AV_MP3HDR_VERSION_OFS] & AV_MP3HDR_VERSION_M) | (buf[AV_MP3HDR_LAYER_OFS] & AV_MP3HDR_LAYER_M)) & (mp3FrameMasking[1]);
412 mp3FrameDataValid[2] = (buf[AV_MP3HDR_SAMPLERATE_OFS] & AV_MP3HDR_SAMPLERATE_M) & (mp3FrameMasking[2]);
413 mp3FrameDataValid[3] = (buf[AV_MP3HDR_CHANNEL_OFS] & AV_MP3HDR_CHANNEL_M) & (mp3FrameMasking[3]);
415 debug_msg(RELEASE, "*** [%02x][%02x][%02x][%02x] : [%02x][%02x][%02x][%02x]", buf[0], buf[1], buf[2], buf[3], mp3FrameDataValid[0], mp3FrameDataValid[1], mp3FrameDataValid[2], mp3FrameDataValid[3]);
418 * MPEG Audio Layer I/II/III frame header
419 * from : http://www.mp3-tech.org/programmer/frame_header.html *
421 * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
423 * A 11 (31-21) Frame sync (all bits must be set)
424 * B 2 (20,19) MPEG Audio version ID
425 * C 2 (18,17) Layer description
426 * D 1 (16) Protection bit
427 * E 4 (15,12) Bitrate index
428 * F 2 (11,10) Sampling rate frequency index
429 * G 1 (9) Padding bit
430 * H 1 (8) Private bit. This one is only informative.
431 * I 2 (7,6) Channel Mode
432 * J 2 (5,4) Mode extension (Only used in Joint stereo)
439 /* Simple check for version, layer, bitrate, samplerate */
440 if ((buf[1] & 0x18) != 0x08 && /* 000XX000 : MPEG Audio version ID, XX=01 - reserved => 00001000(0x08) */
441 (buf[1] & 0x06) != 0x00 && /* 00000XX0 : Layer description, XX=00 - reserved => 00000000(0x00) */
442 (buf[2] & 0xF0) != 0xF0 && /* XXXX0000 : Bitrate index, XX=1111 - bad => 11110000(0xF0) */
443 (buf[2] & 0x0C) != 0x0C) { /* 0000XX00 : Sampling rate frequency index, XX=11 -reserved => 00001100(0x0C) */
446 debug_msg(RELEASE, "=> %s\n", bSync ? "Good!" : "Bad...");
456 __AvParseMp3Header(AvFileContentInfo *pInfo, unsigned char *header)
458 unsigned char result;
460 debug_msg(RELEASE, "### [%02x][%02x][%02x][%02x] ###\n", header[0], header[1], header[2], header[3]);
462 /* 1. Check the version of mp3 */
463 result = header[1] & MASK_MPEG;
466 pInfo->mpegVersion = AV_MPEG_VER_1;
469 pInfo->mpegVersion = AV_MPEG_VER_2;
472 pInfo->mpegVersion = AV_MPEG_VER_25;
479 result = header[1] & MASK_LAYER;
482 pInfo->layer = AV_MP3_LAYER_1;
485 pInfo->layer = AV_MP3_LAYER_2;
488 pInfo->layer = AV_MP3_LAYER_3;
495 result = header[2] >> 4;
496 if (pInfo->mpegVersion == AV_MPEG_VER_1)
497 pInfo->bitRate = mp3BitRateTable[0][pInfo->layer - 1][(int)result] ;
499 pInfo->bitRate = mp3BitRateTable[1][pInfo->layer - 1][(int)result] ;
502 result = (header[2] & MASK_SAMPLERATE) >> 2;
506 pInfo->sampleRate = mp3SamRateTable[pInfo->mpegVersion - 1][(int)result];
509 result = header[3] & MASK_CHANNEL;
511 case MASK_CHANNEL_ST:
512 pInfo->channelIndex = 0;
515 case MASK_CHANNEL_JS:
516 pInfo->channelIndex = 1;
519 case MASK_CHANNEL_DC:
520 pInfo->channelIndex = 2;
523 case MASK_CHANNEL_MN:
524 pInfo->channelIndex = 3;;
532 result = header[2] & MASK_PADDING;
533 if (result == MASK_PADDING)
534 pInfo->bPadding = true;
536 pInfo->bPadding = false;
538 debug_msg(RELEASE, "=> samplerate=%d, bitrate=%d, layer=%d, version=%d, channel=%d, padding=%d", pInfo->sampleRate, pInfo->bitRate, pInfo->layer, pInfo->mpegVersion, pInfo->channels, pInfo->bPadding);
544 __AvParseXingHeader(AvFileContentInfo *pInfo, unsigned char *buf)
547 memset(&data, 0x00, sizeof(AvXHeadData));
550 /* There could be 2 attrs in this header : Xing or Info */
551 if ((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2)) {
552 if (buf[36] == 'X') {
553 if (buf[37] != 'i') return false;
554 if (buf[38] != 'n') return false;
555 if (buf[39] != 'g') return false;
556 } else if (buf[36] == 'I') {
557 if (buf[37] != 'n') return false;
558 if (buf[38] != 'f') return false;
559 if (buf[39] != 'o') return false;
563 } else if ((pInfo->mpegVersion == AV_MPEG_VER_2 || pInfo->mpegVersion == AV_MPEG_VER_25) && (pInfo->channels == 1)) {
564 if (buf[13] == 'X') {
565 if (buf[14] != 'i') return false;
566 if (buf[15] != 'n') return false;
567 if (buf[16] != 'g') return false;
568 } else if (buf[13] == 'I') {
569 if (buf[14] != 'n') return false;
570 if (buf[15] != 'f') return false;
571 if (buf[16] != 'o') return false;
576 if (buf[21] == 'X') {
577 if (buf[22] != 'i') return false;
578 if (buf[23] != 'n') return false;
579 if (buf[24] != 'g') return false;
580 } else if (buf[21] == 'I') {
581 if (buf[22] != 'n') return false;
582 if (buf[23] != 'f') return false;
583 if (buf[24] != 'o') return false;
591 data.toc = (unsigned char *)(pInfo->pToc);
593 if (__AvGetXingHeader(&data, (unsigned char *)buf) == 1) { /* VBR. */
594 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
595 debug_error(DEBUG, "invalid Xing header\n");
599 pInfo->datafileLen = data.bytes;
600 pInfo->frameNum = data.frames;
601 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames) ;
609 __AvParseVBRIHeader(AvFileContentInfo *pInfo, unsigned char *buf)
612 memset(&data, 0x00, sizeof(AvVBRIHeadData));
615 if (buf[36] != 'V') return false;
616 if (buf[37] != 'B') return false;
617 if (buf[38] != 'R') return false;
618 if (buf[39] != 'I') return false;
622 data.toc = (unsigned char *)(pInfo->pToc);
624 if (__AvGetVBRIHeader(&data, (unsigned char *)buf) == 1) { /* VBR. */
625 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
626 debug_error(DEBUG, "invalid Vbri header\n");
630 pInfo->sampleRate = data.sampRate;
631 pInfo->datafileLen = data.bytes;
632 pInfo->frameNum = data.frames;
633 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames) ;
640 #ifdef __MMFILE_NEW_FRAME_FUNC /* from gst */
642 __AvGetMp3FrameSize(AvFileContentInfo *pInfo)
644 unsigned int frameSize = 0;
648 frameSize = pInfo->bPadding;
649 if (pInfo->bitRate == 0) {
650 if (pInfo->layer == 1) {
652 frameSize += 0/* FIXME: possible_free_framelen*/;
653 pInfo->bitRate = frameSize * pInfo->sampleRate / 48000;
655 frameSize += 0/* FIXME: possible_free_framelen*/;
656 pInfo->bitRate = frameSize * pInfo->sampleRate / ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000);
660 if (pInfo->layer == 1) {
661 frameSize = ((12000 * pInfo->bitRate / pInfo->sampleRate) + frameSize) * 4;
663 frameSize += ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000) * pInfo->bitRate / pInfo->sampleRate;
667 pInfo->frameSize = (int)frameSize;
674 __AvGetBitrate(AvFileContentInfo *pInfo)
679 if (pInfo == NULL || pInfo->bVbr == false)
687 if (pInfo->mpegVersion == AV_MPEG_VER_1) { /* MPEG version 1 */
688 if (pInfo->layer == AV_MP3_LAYER_1) /* Layer 1 */
690 else /* Layer 2, 3 */
692 } else { /* MPEG version 2 */
693 if (pInfo->layer == AV_MP3_LAYER_1) /* Layer 1 */
695 else /* Layer 2, 3 */
699 br = (pInfo->frameSize - padding) * pInfo->sampleRate / factor;
701 pInfo->bitRate = (int) br;
707 static bool __AvGetFileSize(MMFileIOHandle *hFile, long long *file_size)
709 long long fileLen = 0;
711 mmfile_seek(hFile, 0L, SEEK_END);
712 fileLen = mmfile_tell(hFile);
714 debug_error(DEBUG, "file is too small.\n");
717 mmfile_seek(hFile, 0L, SEEK_SET);
719 *file_size = fileLen;
724 static bool __AvGetID3v1Header(unsigned char *buf, size_t buf_size, int *offset)
726 unsigned char TagV1ID[4] = { 0x54, 0x41, 0x47}; /* TAG */
727 int id3v1_offset = 0;
729 if (!buf || buf_size < 3) {
730 debug_error(DEBUG, "Invalid parameters!");
734 id3v1_offset = __AvMemstr(buf, TagV1ID, 3, TAGV1_SEEK_GAP + 5);
735 if (id3v1_offset < 0) {
736 debug_msg(RELEASE, "ID3v1 is not existing");
741 *offset = id3v1_offset;
743 debug_msg(RELEASE, "ID3v1 is existing");
747 static bool __AvGetID3v2Header(unsigned char *buf, size_t buf_size, AvTagVer2AdditionalData *id3v2info)
749 if (!buf || buf_size < MP3_TAGv2_HEADER_LEN || !id3v2info) {
750 debug_error(DEBUG, "Invalid parameters!");
754 if (!IS_ID3V2_TAG(buf)) { /* ID3 */
755 debug_error(RELEASE, "Invalid ID3v2 identifier !");
759 /* weak id3v2 tag check */
760 if (buf[3] == 0xFF || buf[4] == 0xFF || buf[6] >= 0x80 || buf[7] >= 0x80 || buf[8] >= 0x80 || buf[9] >= 0x80) {
761 debug_error(RELEASE, "Invalid ID3v2 base header!");
766 debug_error(RELEASE, "Invalid or not supported ID3v2 version(%d)!", buf[3]);
770 id3v2info->tagVersion = buf[3];
771 id3v2info->tagLen = MP3_TAGv2_HEADER_LEN;
772 id3v2info->tagLen += (unsigned long)buf[6] << 21 | (unsigned long)buf[7] << 14 | (unsigned long)buf[8] << 7 | (unsigned long)buf[9];
773 debug_msg(RELEASE, "ID3v2 version(%d), length (%d)\n", id3v2info->tagVersion, id3v2info->tagLen);
778 static int __AvGetLastID3v2offset(MMFileIOHandle *fp, unsigned int *offset)
780 unsigned char tagHeader[MP3_TAGv2_HEADER_LEN] = {0, };
781 unsigned int total_taglen = 0;
783 AvTagVer2AdditionalData tagInfo = { 0, };
788 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
792 read = mmfile_read(fp, tagHeader, MP3_TAGv2_HEADER_LEN);
793 if (read != MP3_TAGv2_HEADER_LEN) {
794 debug_error(DEBUG, "read error occured.\n");
798 if (!__AvGetID3v2Header(tagHeader, MP3_TAGv2_HEADER_LEN, &tagInfo)) {
799 debug_msg(RELEASE, "Invalid ID3 header\n");
803 /**@note unfortunately, some contents has many id3 tag.*/
804 total_taglen += tagInfo.tagLen;
805 debug_msg(RELEASE, "tag size: %u, offset: %u\n", tagInfo.tagLen, total_taglen);
807 mmfile_seek(fp, total_taglen, MMFILE_SEEK_SET);
808 *offset = total_taglen;
809 goto _START_TAG_SEARCH;
815 static bool __AvGetID3v1Tags(unsigned char *buf, int offset, AvFileContentInfo *pInfo)
817 unsigned char TmpBuff[MP3TAGINFO_SIZE] = {0, };
819 if (!buf || !pInfo || offset < 0) {
820 debug_error(DEBUG, "Invalid parameters!");
824 if (pInfo->tagV2Info.tagLen != 0 || offset != TAGV1_SEEK_GAP) {
825 debug_msg(RELEASE, "No need to check id3v1");
829 memcpy(TmpBuff, buf, MP3TAGINFO_SIZE);
831 return mm_file_id3tag_parse_v110(pInfo, TmpBuff);
834 static void __AvGetID3v2Tags(unsigned char *buf, AvFileContentInfo *pInfo)
836 if (!buf || !pInfo || pInfo->tagV2Info.tagLen == 0) {
837 debug_error(DEBUG, "Invalid parameters!");
841 if (pInfo->tagV2Info.tagVersion == 0x02) {
842 mm_file_id3tag_parse_v222(pInfo, buf);
843 } else if (pInfo->tagV2Info.tagVersion == 0x03) {
844 mm_file_id3tag_parse_v223(pInfo, buf);
845 } else if (pInfo->tagV2Info.tagVersion == 0x04) {
846 mm_file_id3tag_parse_v224(pInfo, buf); /* currently 2.4 ver pased by 2.3 routine */
848 debug_msg(RELEASE, "Invalid tag version(%d)\n", pInfo->tagV2Info.tagVersion);
853 * This fuction retrieves the start position of header.
854 * Param _pFile [in] Specifies the file pointer of mp3 file.
855 * This function returns the start position of header.
858 __AvFindStartOfMp3Header(unsigned char *buf, unsigned long bufLen, AvFileContentInfo *pInfo)
860 unsigned int index = 0;
861 unsigned long id3v2TagLen = 0;
862 unsigned char *pHeader = NULL;
863 unsigned long preHeaderGap = 0;
864 unsigned long frameLen = 0;
865 unsigned long nextFrameOff = 0; /* Offset to the start of the next frame */
866 unsigned long nextFrameOffEnd = 0;
867 bool bFoundSync = false;
868 unsigned long minLen;
870 if (!buf || !pInfo) {
871 debug_error(DEBUG, "Invalid parameters");
875 id3v2TagLen = pInfo->tagV2Info.tagLen;
877 debug_msg(RELEASE, "id3v2TagLen(%lu)\n", id3v2TagLen);
880 if (preHeaderGap == bufLen - 2)
882 if (__AvIsValidHeader(pInfo, buf + preHeaderGap))
890 index += preHeaderGap;
891 while (index <= (bufLen - minLen)) {
892 if (buf[0] == 0xff) {
893 if (VALID_SYNC(buf)) {
894 if (bufLen - index > 256) {
895 pHeader = mmfile_malloc(256);
896 if (pHeader == NULL) {
897 debug_error(DEBUG, "malloc failed.\n");
900 strncpy((char *)pHeader, (char *)buf, 256);
902 debug_error(DEBUG, "Header field is not exist\n");
905 if (__AvParseMp3Header(pInfo, pHeader) == false) {
907 mmfile_free(pHeader);
908 debug_warning(DEBUG, "Mp3 parse header failed & index(%d)\n", index);
913 debug_msg(RELEASE, "This header is valid. index(%d)\n", index);
916 if (__AvParseXingHeader(pInfo, pHeader) || __AvParseVBRIHeader(pInfo, pHeader))
917 __AvGetBitrate(pInfo);
920 mmfile_free(pHeader);
924 if (__AvIsValidHeader(pInfo, pHeader)) {
925 mmfile_free(pHeader);
927 __AvGetMp3FrameSize(pInfo);
928 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
929 frameLen = pInfo->frameSize;
931 debug_msg(RELEASE, "<<< frameLen=[%lu] >>> \n", frameLen);
933 #ifndef __MMFILE_NEW_FRAME_FUNC /* FIXME : what purpose to do this? */
934 /* Account for loss of precision in the frame length calculation*/
938 /* Check if the remaining buffer size is large enough to
939 * look for another sync */
940 if ((index + frameLen) < (bufLen - (minLen - 1))) {
941 nextFrameOff = frameLen;
942 nextFrameOffEnd = nextFrameOff + MIN(6, bufLen - (index + frameLen) - (minLen - 1));
944 /* Search the next few bytes for the next sync */
945 while (nextFrameOff < nextFrameOffEnd) {
946 if (VALID_SYNC(buf + nextFrameOff)) {
947 if (IS_VALID_FRAME_MP3(buf + nextFrameOff)) {
954 if (bFoundSync == true)
957 /* Assume that the first sync is valid, since there is not
958 * enough data in the buffer to look for the next sync */
965 debug_warning(DEBUG, "Is not vaild header pHeader\n");
968 mmfile_free(pHeader);
970 debug_warning(RELEASE, "Mp3 file frist byte is 0xff, but not header sync\n");
977 mmfile_free(pHeader);
979 if (index > (bufLen - minLen)) {
980 debug_warning(DEBUG, "Mp3 file sync is not found : index(%u) bufLen(%lu), minLen(%lu)\n", index, bufLen, minLen);
984 if (bFoundSync == true) {
985 debug_msg(RELEASE, "Mp3 file found a sync Success!\n");
987 debug_msg(RELEASE, "Mp3 file found a sync Failed!\n");
991 return index + id3v2TagLen;
995 * This function retrieves the ID3 tag information.
996 * Param filename [in] Specifies a mp3 file path.
997 * Param pInfo [out] Specifies a struct pointer for ID3 tag information.
998 * This function returns true on success, or false on failure.
1000 static int mmf_file_mp3_get_tag_info(char *filename, AvFileContentInfo *pInfo)
1002 MMFileIOHandle *hFile;
1003 unsigned char *buf = NULL;
1004 unsigned char *v2TagExistCheck = NULL;
1005 unsigned char TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
1006 int tagHeaderPos = 0;
1008 unsigned int head_offset = 0;
1010 debug_fenter(RELEASE);
1012 if (pInfo == NULL || filename == NULL)
1015 memset(pInfo, 0x00, sizeof(AvFileContentInfo));
1017 pInfo->tagV2Info.tagLen = 0;
1018 pInfo->headerPos = 0;
1022 ret = mmfile_open(&hFile, filename, MMFILE_RDONLY);
1023 if (ret == MMFILE_UTIL_FAIL) {
1024 debug_error(DEBUG, "open failed.\n");
1028 if (!__AvGetFileSize(hFile, &pInfo->fileLen)) {
1029 debug_error(DEBUG, "file is too small.\n");
1033 v2TagExistCheck = mmfile_malloc(MP3_TAGv2_HEADER_LEN);
1034 if (!v2TagExistCheck) {
1035 debug_error(DEBUG, "malloc failed.\n");
1039 /* check ID3v2 header */
1040 if (mmfile_read(hFile, v2TagExistCheck, MP3_TAGv2_HEADER_LEN) != MP3_TAGv2_HEADER_LEN) {
1041 debug_error(DEBUG, "v2TagExistCheck value read fail!\n");
1042 mmfile_free(v2TagExistCheck);
1046 __AvGetID3v2Header(v2TagExistCheck, MP3_TAGv2_HEADER_LEN, &pInfo->tagV2Info);
1047 mmfile_free(v2TagExistCheck);
1049 if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
1052 debug_msg(RELEASE, "pInfo->fileLen(%lld)\n", pInfo->fileLen);
1054 /* read file to get ID3v2 */
1055 if (pInfo->fileLen <= (long long)pInfo->tagV2Info.tagLen)
1056 pInfo->tagV2Info.tagLen = pInfo->fileLen;
1058 debug_msg(RELEASE, "buf size(%d)\n", pInfo->tagV2Info.tagLen);
1060 buf = mmfile_malloc(pInfo->tagV2Info.tagLen);
1062 debug_error(DEBUG, "malloc failed.\n");
1066 if (mmfile_read(hFile, buf, pInfo->tagV2Info.tagLen) != pInfo->tagV2Info.tagLen) {
1071 /* Is this needed? */
1072 if (__AvGetLastID3v2offset(hFile, &head_offset)) {
1073 debug_msg(RELEASE, "search start offset: %u\n", head_offset);
1074 pInfo->tagV2Info.tagLen = head_offset;
1077 /* get ID3v2 information */
1078 __AvGetID3v2Tags(buf, pInfo);
1080 /* relocate file to read TAG(ID3v1) information */
1081 if (mmfile_seek(hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
1085 pInfo->bV1tagFound = false;
1087 /* read with TAG(ID3v1) length */
1088 if (mmfile_read(hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) != MP3TAGINFO_SIZE + TAGV1_SEEK_GAP)
1091 /* check and get TAG(ID3v1) information */
1092 if (__AvGetID3v1Header(TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP, &tagHeaderPos)) {
1093 pInfo->bV1tagFound = true;
1094 if (!__AvGetID3v1Tags((TagBuff + tagHeaderPos), tagHeaderPos, pInfo))
1098 mm_file_id3tag_restore_content_info(pInfo);
1100 mmfile_close(hFile);
1103 debug_msg(RELEASE, "**** Info #1 ****\n");
1104 debug_msg(RELEASE, "Title : %s\n", pInfo->pTitle);
1105 debug_msg(RELEASE, "Artist : %s\n", pInfo->pArtist);
1106 debug_msg(RELEASE, "Album : %s\n", pInfo->pAlbum);
1107 debug_msg(RELEASE, "Album_Artist: %s\n", pInfo->pAlbum_Artist);
1108 debug_msg(RELEASE, "Year : %s\n", pInfo->pYear);
1109 debug_msg(RELEASE, "Comment : %s\n", pInfo->pComment);
1110 debug_msg(RELEASE, "TrackNum : %s\n", pInfo->pTrackNum);
1111 debug_msg(RELEASE, "Genre : %s\n", pInfo->pGenre);
1112 debug_msg(RELEASE, "**** Info #2 ****\n");
1113 debug_msg(RELEASE, "Copyright : %s\n", pInfo->pCopyright);
1114 debug_msg(RELEASE, "Comment : %s\n", pInfo->pComment);
1115 debug_msg(RELEASE, "RecDate : %s\n", pInfo->pRecDate);
1116 debug_msg(RELEASE, "PartOfASet : %s\n", pInfo->pPartOfASet);
1117 debug_msg(RELEASE, "Encoded by : %s\n", pInfo->pEncBy);
1118 debug_msg(RELEASE, "URL : %s\n", pInfo->pURL);
1119 debug_msg(RELEASE, "Ori. Artist : %s\n", pInfo->pOriginArtist);
1120 debug_msg(RELEASE, "Composer : %s\n", pInfo->pComposer);
1121 debug_msg(RELEASE, "Conductor : %s\n", pInfo->pConductor);
1122 debug_msg(RELEASE, "Artwork : mime(%s) addr(%p) size(%d)\n", pInfo->imageInfo.imageMIMEType, pInfo->imageInfo.pImageBuf, pInfo->imageInfo.imageLen);
1123 debug_msg(RELEASE, "UnsyncLyrics : %s\n", pInfo->pUnsyncLyrics);
1124 debug_msg(RELEASE, "SyncLyrics size : %d\n", pInfo->syncLyricsNum);
1129 debug_error(DEBUG, "Error occured!\n");
1130 mmfile_close(hFile);
1135 * This function retrieves the MP3 stream information.
1136 * Param filename [in] Specifies a mp3 file path.
1137 * Param pInfo [out] Specifies a struct pointer for MP3 stream information.
1138 * This function returns true on success, or false on failure.
1140 static int mmf_file_mp3_get_stream_info(char *filename, AvFileContentInfo *pInfo)
1142 MMFileIOHandle *hFile;
1143 unsigned char header[256];
1144 unsigned long frameSamples = 0;
1145 unsigned char *buf = NULL;
1146 unsigned char *v2TagExistCheck = NULL;
1147 unsigned char TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
1149 unsigned int head_offset = 0;
1150 unsigned long bufLen = 0;
1152 debug_fenter(RELEASE);
1154 if (pInfo == NULL || filename == NULL)
1157 memset(pInfo, 0x00, sizeof(AvFileContentInfo));
1159 pInfo->tagV2Info.tagLen = 0;
1160 pInfo->headerPos = 0;
1164 ret = mmfile_open(&hFile, filename, MMFILE_RDONLY);
1165 if (ret == MMFILE_UTIL_FAIL) {
1166 debug_error(DEBUG, "open failed.\n");
1170 if (!__AvGetFileSize(hFile, &pInfo->fileLen)) {
1171 debug_error(DEBUG, "file is too small.\n");
1175 v2TagExistCheck = mmfile_malloc(MP3_TAGv2_HEADER_LEN);
1176 if (!v2TagExistCheck) {
1177 debug_error(DEBUG, "malloc failed.\n");
1181 if (mmfile_read(hFile, v2TagExistCheck, MP3_TAGv2_HEADER_LEN) != MP3_TAGv2_HEADER_LEN) {
1182 debug_error(DEBUG, "v2TagExistCheck value read fail!\n");
1183 mmfile_free(v2TagExistCheck);
1187 __AvGetID3v2Header(v2TagExistCheck, MP3_TAGv2_HEADER_LEN, &pInfo->tagV2Info);
1188 mmfile_free(v2TagExistCheck);
1190 if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
1193 debug_msg(RELEASE, "pInfo->fileLen(%lld)\n", pInfo->fileLen);
1195 /* read file to get MP3 stream info */
1196 if (pInfo->fileLen - (long long)pInfo->tagV2Info.tagLen > (long long)_AV_MP3_HEADER_POSITION_MAX) {
1197 if (mmfile_seek(hFile, pInfo->tagV2Info.tagLen, SEEK_SET) < 0)
1200 bufLen = _AV_MP3_HEADER_POSITION_MAX;
1201 } else if (pInfo->fileLen - (long long)pInfo->tagV2Info.tagLen > 0) {
1202 if (mmfile_seek(hFile, pInfo->tagV2Info.tagLen, SEEK_SET) < 0)
1205 bufLen = pInfo->fileLen - (long long)pInfo->tagV2Info.tagLen;
1207 /* if taglen is invlaid, check whole file to get MP3 info */
1208 pInfo->tagV2Info.tagLen = 0;
1209 bufLen = pInfo->fileLen;
1212 debug_msg(RELEASE, "buf size(%lu)\n", bufLen);
1214 buf = mmfile_malloc(bufLen);
1219 if (mmfile_read(hFile, buf, bufLen) != (int)bufLen) {
1224 if (__AvGetLastID3v2offset(hFile, &head_offset)) {
1225 debug_msg(RELEASE, "search start offset: %u\n", head_offset);
1226 pInfo->tagV2Info.tagLen = head_offset;
1229 /* get position of MP3 header */
1230 pInfo->headerPos = (long) __AvFindStartOfMp3Header(buf, bufLen, pInfo);
1232 debug_msg(RELEASE, "Header Pos: %ld\n", pInfo->headerPos);
1236 /* get MP3 stream information from MP3 header */
1237 if (pInfo->headerPos == -1)
1240 if (mmfile_seek(hFile, pInfo->headerPos, SEEK_SET) < 0)
1243 if (mmfile_read(hFile, header, 256) != 256)
1246 if (!__AvParseMp3Header(pInfo, header))
1249 if (__AvParseXingHeader(pInfo, header) || __AvParseVBRIHeader(pInfo, header)) {
1250 __AvGetBitrate(pInfo);
1252 __AvGetMp3FrameSize(pInfo);
1253 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1254 debug_msg(RELEASE, "Mp3 File FrameSize (%d) pInfo->headerPos(%ld)\n", pInfo->frameSize, pInfo->headerPos);
1257 if (pInfo->mpegVersion == 1) {
1258 if (pInfo->layer == 1)
1259 frameSamples = MPEG_1_SIZE_LAYER_1;
1261 frameSamples = MPEG_1_SIZE_LAYER_2_3;
1263 if (pInfo->layer == 1)
1264 frameSamples = MPEG_2_SIZE_LAYER_1;
1266 frameSamples = MPEG_2_SIZE_LAYER_2_3;
1269 /* check TAG(ID3v1) exist due to duration */
1270 if (mmfile_seek(hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
1273 pInfo->bV1tagFound = false;
1275 if (mmfile_read(hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) != MP3TAGINFO_SIZE + TAGV1_SEEK_GAP)
1278 if (__AvGetID3v1Header(TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP, NULL))
1279 pInfo->bV1tagFound = true;
1282 pInfo->duration = ((double)(frameSamples * 1000) / pInfo->sampleRate) * pInfo->frameNum;
1283 debug_msg(DEBUG, "duration for VBR : %lld", pInfo->duration);
1285 unsigned long long frame_duration = (((unsigned long long)frameSamples * 1000000000) / pInfo->sampleRate / 1000);
1286 int file_size_except_header = pInfo->fileLen - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0));
1287 pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * frame_duration / 1000;
1288 /*pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * (frameSamples * 1000 / pInfo->sampleRate); */
1289 debug_msg(DEBUG, "duration from new algorithm : %lld", pInfo->duration);
1292 mmfile_close(hFile);
1295 debug_msg(RELEASE, "Mp3 File pInfo->duration (%lld) \n", pInfo->duration);
1296 debug_msg(RELEASE, "** MP3 **\n");
1297 debug_msg(RELEASE, "Version : %u\n", pInfo->mpegVersion);
1298 debug_msg(RELEASE, "Layer : %u\n", pInfo->layer);
1299 debug_msg(RELEASE, "Channel idx: %u\n", pInfo->channelIndex);
1300 debug_msg(RELEASE, "Is VBR : %d\n", (pInfo->bVbr == true ? 1 : 0));
1301 debug_msg(RELEASE, "Bitrate : %u\n", pInfo->bitRate);
1302 debug_msg(RELEASE, "SampleRate : %u\n", pInfo->sampleRate);
1303 debug_msg(RELEASE, "Channels : %u\n", pInfo->channels);
1308 debug_error(DEBUG, "Error occured!\n");
1309 mmfile_close(hFile);