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_infomation(char *src, AvFileContentInfo *pInfo);
88 int mmfile_format_open_mp3(MMFileFormatContext *formatContext)
90 AvFileContentInfo *privateData = NULL;;
93 #ifdef __MMFILE_TEST_MODE__
97 if (NULL == formatContext) {
98 debug_error("formatContext is NULL\n");
99 return MMFILE_FORMAT_FAIL;
102 if (formatContext->pre_checked == 0) {
103 ret = MMFileFormatIsValidMP3(NULL, formatContext->uriFileName, 5);
105 debug_error("It is not mp3 file\n");
106 return MMFILE_FORMAT_FAIL;
111 formatContext->ReadStream = mmfile_format_read_stream_mp3;
112 formatContext->ReadFrame = mmfile_format_read_frame_mp3;
113 formatContext->ReadTag = mmfile_format_read_tag_mp3;
114 formatContext->Close = mmfile_format_close_mp3;
116 formatContext->videoTotalTrackNum = 0;
117 formatContext->audioTotalTrackNum = 1;
119 privateData = mmfile_malloc(sizeof(AvFileContentInfo));
121 debug_error("error: mmfile_malloc MP3 privateData\n");
122 return MMFILE_FORMAT_FAIL;
125 formatContext->privateFormatData = privateData;
127 ret = mmf_file_mp3_get_infomation(formatContext->uriFileName, privateData);
129 debug_error("error: mmfile_format_read_stream_mp3\n");
133 return MMFILE_FORMAT_SUCCESS;
136 mmfile_format_close_mp3(formatContext);
137 return MMFILE_FORMAT_FAIL;
142 int mmfile_format_read_stream_mp3(MMFileFormatContext *formatContext)
144 AvFileContentInfo *privateData = NULL;
146 #ifdef __MMFILE_TEST_MODE__
150 if (!formatContext || !formatContext->privateFormatData) {
151 debug_error("formatContext is NULL\n");
152 return MMFILE_FORMAT_FAIL;
155 privateData = formatContext->privateFormatData;
157 formatContext->duration = privateData->duration;
158 formatContext->videoTotalTrackNum = 0;
159 formatContext->audioTotalTrackNum = 1;
160 formatContext->nbStreams = 1;
161 formatContext->streams[MMFILE_AUDIO_STREAM] = mmfile_malloc(sizeof(MMFileFormatStream));
162 if (NULL == formatContext->streams[MMFILE_AUDIO_STREAM]) {
163 debug_error("formatContext->streams[MMFILE_AUDIO_STREAM] is NULL\n");
164 return MMFILE_FORMAT_FAIL;
167 formatContext->streams[MMFILE_AUDIO_STREAM]->streamType = MMFILE_AUDIO_STREAM;
168 formatContext->streams[MMFILE_AUDIO_STREAM]->codecId = MM_AUDIO_CODEC_MP3;
169 formatContext->streams[MMFILE_AUDIO_STREAM]->bitRate = (privateData->bitRate * 1000);
170 formatContext->streams[MMFILE_AUDIO_STREAM]->framePerSec = (privateData->duration == 0 ? 0 : privateData->frameNum / privateData->duration);
171 formatContext->streams[MMFILE_AUDIO_STREAM]->width = 0;
172 formatContext->streams[MMFILE_AUDIO_STREAM]->height = 0;
173 formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = privateData->channels;
174 formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = privateData->sampleRate;
176 return MMFILE_FORMAT_SUCCESS;
181 int mmfile_format_read_frame_mp3(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
183 return MMFILE_FORMAT_SUCCESS;
187 int mmfile_format_read_tag_mp3(MMFileFormatContext *formatContext)
189 AvFileContentInfo *privateData = NULL;
191 #ifdef __MMFILE_TEST_MODE__
195 if (!formatContext || !formatContext->privateFormatData) {
196 debug_error("formatContext is NULL\n");
197 return MMFILE_FORMAT_FAIL;
200 privateData = formatContext->privateFormatData;
202 if (privateData->pTitle) formatContext->title = mmfile_strdup(privateData->pTitle);
203 if (privateData->pArtist) formatContext->artist = mmfile_strdup(privateData->pArtist);
204 if (privateData->pAuthor) formatContext->author = mmfile_strdup(privateData->pAuthor);
205 if (privateData->pCopyright) formatContext->copyright = mmfile_strdup(privateData->pCopyright);
206 if (privateData->pComment) formatContext->comment = mmfile_strdup(privateData->pComment);
207 if (privateData->pAlbum) formatContext->album = mmfile_strdup(privateData->pAlbum);
208 if (privateData->pAlbum_Artist) formatContext->album_artist = mmfile_strdup(privateData->pAlbum_Artist);
209 if (privateData->pYear) formatContext->year = mmfile_strdup(privateData->pYear);
210 if (privateData->pGenre) formatContext->genre = mmfile_strdup(privateData->pGenre);
211 if (privateData->pTrackNum) formatContext->tagTrackNum = mmfile_strdup(privateData->pTrackNum);
212 if (privateData->pComposer) formatContext->composer = mmfile_strdup(privateData->pComposer);
213 if (privateData->pContentGroup) formatContext->classification = mmfile_strdup(privateData->pContentGroup);
214 if (privateData->pConductor) formatContext->conductor = mmfile_strdup(privateData->pConductor);
215 if (privateData->pUnsyncLyrics) formatContext->unsyncLyrics = mmfile_strdup(privateData->pUnsyncLyrics);
216 if (privateData->pSyncLyrics) formatContext->syncLyrics = privateData->pSyncLyrics;
217 if (privateData->syncLyricsNum) formatContext->syncLyricsNum = privateData->syncLyricsNum;
218 if (privateData->pRecDate) formatContext->recDate = mmfile_strdup(privateData->pRecDate);
220 if (privateData->imageInfo.imageLen > 0) {
221 formatContext->artwork = mmfile_malloc(privateData->imageInfo.imageLen);
222 if (formatContext->artwork) {
223 formatContext->artworkSize = privateData->imageInfo.imageLen;
224 memcpy(formatContext->artwork, privateData->imageInfo.pImageBuf, privateData->imageInfo.imageLen);
225 if (strlen(privateData->imageInfo.imageMIMEType) > 0)
226 formatContext->artworkMime = mmfile_strdup(privateData->imageInfo.imageMIMEType);
227 else if (strlen(privateData->imageInfo.imageExt) > 0) {
228 #ifdef __MMFILE_TEST_MODE__
229 debug_msg("ID3 tag V2 File");
231 formatContext->artworkMime = mmfile_strdup(privateData->imageInfo.imageExt);
233 debug_error("Album art image exist but there is no type information of album art\n");
238 return MMFILE_FORMAT_SUCCESS;
242 int mmfile_format_close_mp3(MMFileFormatContext *formatContext)
244 AvFileContentInfo *privateData = NULL;
247 privateData = formatContext->privateFormatData;
249 mm_file_free_AvFileContentInfo(privateData);
250 mmfile_free(privateData);
251 formatContext->privateFormatData = NULL;
255 return MMFILE_FORMAT_SUCCESS;
259 __AvExtractI4(unsigned char *buf)
275 __AvExtractI2(unsigned char *buf)
288 __AvGetXingHeader(AvXHeadData *headData, unsigned char *buf)
290 int index, headFlags;
291 int hId, hMode, hSrIndex;
292 int mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
294 /* get Xing header data */
297 /* get selected MP3 header data */
298 hId = (buf[1] >> 3) & 1;
299 hSrIndex = (buf[2] >> 2) & 3;
300 hMode = (buf[3] >> 6) & 3;
303 /* determine offset of header */
304 if (hId) { /* mpeg1 */
316 /* There could be 2 attrs in this header : Xing or Info */
318 if (buf[1] != 'i') return 0;
319 if (buf[2] != 'n') return 0;
320 if (buf[3] != 'g') return 0;
321 } else if (buf[0] == 'I') {
322 if (buf[1] != 'n') return 0;
323 if (buf[2] != 'f') return 0;
324 if (buf[3] != 'o') return 0;
332 headData->sampRate = mp3SampleRateTable[hSrIndex];
334 headData->sampRate >>= 1;
336 headFlags = headData->flags = __AvExtractI4(buf); /* get flags */
339 if (headFlags & FRAMES_FLAG) {
340 headData->frames = __AvExtractI4(buf);
343 if (headFlags & BYTES_FLAG) {
344 headData->bytes = __AvExtractI4(buf);
348 if (headFlags & TOC_FLAG) {
349 if (headData->toc != NULL) {
350 for (index = 0; index < 100; index++)
351 headData->toc[index] = buf[index];
356 headData->vbrScale = -1;
357 if (headFlags & VBR_SCALE_FLAG) {
358 headData->vbrScale = __AvExtractI4(buf);
361 #ifdef __MMFILE_TEST_MODE__
362 debug_msg("Xing header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
363 headData->sampRate, headData->bytes, headData->frames);
366 return 1; /* success */
370 __AvGetVBRIHeader(AvVBRIHeadData *headData, unsigned char *buf)
373 int mp3SampleRateTable[4] = { 44100, 48000, 32000, 99999 };
376 /* get selected MP3 header data */
377 hId = (buf[1] >> 3) & 1;
378 hSrIndex = (buf[2] >> 2) & 3;
382 if (buf[0] != 'V') return 0; /* fail */
383 if (buf[1] != 'B') return 0; /* header not found */
384 if (buf[2] != 'R') return 0;
385 if (buf[3] != 'I') return 0;
389 headData->sampRate = mp3SampleRateTable[hSrIndex];
391 headData->sampRate >>= 1;
393 headData->vID = __AvExtractI2(buf); /* get ver ID */
395 headData->delay = __AvExtractI2(buf);
397 headData->qualityIndicator = buf[0];
399 headData->bytes = __AvExtractI4(buf);
401 headData->frames = __AvExtractI4(buf);
403 headData->numOfTOC = __AvExtractI2(buf);
405 headData->vbriScale = __AvExtractI2(buf);
407 headData->sizePerTable = __AvExtractI2(buf);
409 headData->framesPerTable = __AvExtractI2(buf);
411 #ifdef __MMFILE_TEST_MODE__
412 debug_msg("Vbri header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
413 headData->sampRate, headData->bytes, headData->frames);
416 return true; /* success */
419 __AvIsValidHeader(AvFileContentInfo *pInfo, unsigned char *buf)
423 if (VALID_SYNC(buf)) {
424 mp3FrameDataValid[0] = (0xFF) & (mp3FrameMasking[0]);
425 mp3FrameDataValid[1] = (0xE0 | (buf[AV_MP3HDR_VERSION_OFS] & AV_MP3HDR_VERSION_M)
426 | (buf[AV_MP3HDR_LAYER_OFS] & AV_MP3HDR_LAYER_M)) & (mp3FrameMasking[1]);
427 mp3FrameDataValid[2] = (buf[AV_MP3HDR_SAMPLERATE_OFS] & AV_MP3HDR_SAMPLERATE_M) &
428 (mp3FrameMasking[2]);
429 mp3FrameDataValid[3] = (buf[AV_MP3HDR_CHANNEL_OFS] & AV_MP3HDR_CHANNEL_M) &
430 (mp3FrameMasking[3]);
432 #ifdef __MMFILE_TEST_MODE__
433 debug_msg("*** [%02x][%02x][%02x][%02x] : [%02x][%02x][%02x][%02x]",
434 buf[0], buf[1], buf[2], buf[3],
435 mp3FrameDataValid[0], mp3FrameDataValid[1], mp3FrameDataValid[2], mp3FrameDataValid[3]);
439 * MPEG Audio Layer I/II/III frame header
440 * from : http://www.mp3-tech.org/programmer/frame_header.html *
442 * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
444 * A 11 (31-21) Frame sync (all bits must be set)
445 * B 2 (20,19) MPEG Audio version ID
446 * C 2 (18,17) Layer description
447 * D 1 (16) Protection bit
448 * E 4 (15,12) Bitrate index
449 * F 2 (11,10) Sampling rate frequency index
450 * G 1 (9) Padding bit
451 * H 1 (8) Private bit. This one is only informative.
452 * I 2 (7,6) Channel Mode
453 * J 2 (5,4) Mode extension (Only used in Joint stereo)
460 /* Simple check for version, layer, bitrate, samplerate */
461 if ((buf[1] & 0x18) != 0x08 && /* 000XX000 : MPEG Audio version ID, XX=01 - reserved => 00001000(0x08) */
462 (buf[1] & 0x06) != 0x00 && /* 00000XX0 : Layer description, XX=00 - reserved => 00000000(0x00) */
463 (buf[2] & 0xF0) != 0xF0 && /* XXXX0000 : Bitrate index, XX=1111 - bad => 11110000(0xF0) */
464 (buf[2] & 0x0C) != 0x0C) { /* 0000XX00 : Sampling rate frequency index, XX=11 -reserved => 00001100(0x0C) */
467 #ifdef __MMFILE_TEST_MODE__
468 debug_msg("=> %s\n", bSync ? "Good!" : "Bad...");
479 __AvParseMp3Header(AvFileContentInfo *pInfo, unsigned char *header)
481 unsigned char result;
483 #ifdef __MMFILE_TEST_MODE__
484 debug_msg("### [%02x][%02x][%02x][%02x] ###\n", header[0], header[1], header[2], header[3]);
487 /* 1. Check the version of mp3 */
488 result = header[1] & MASK_MPEG;
491 pInfo->mpegVersion = AV_MPEG_VER_1;
494 pInfo->mpegVersion = AV_MPEG_VER_2;
497 pInfo->mpegVersion = AV_MPEG_VER_25;
504 result = header[1] & MASK_LAYER;
507 pInfo->layer = AV_MP3_LAYER_1;
510 pInfo->layer = AV_MP3_LAYER_2;
513 pInfo->layer = AV_MP3_LAYER_3;
520 result = header[2] >> 4;
521 if (pInfo->mpegVersion == AV_MPEG_VER_1)
522 pInfo->bitRate = mp3BitRateTable[0][pInfo->layer - 1][(int)result] ;
524 pInfo->bitRate = mp3BitRateTable[1][pInfo->layer - 1][(int)result] ;
527 result = (header[2] & MASK_SAMPLERATE) >> 2;
531 pInfo->sampleRate = mp3SamRateTable[pInfo->mpegVersion - 1][(int)result];
534 result = header[3] & MASK_CHANNEL;
536 case MASK_CHANNEL_ST:
537 pInfo->channelIndex = 0;
540 case MASK_CHANNEL_JS:
541 pInfo->channelIndex = 1;
544 case MASK_CHANNEL_DC:
545 pInfo->channelIndex = 2;
548 case MASK_CHANNEL_MN:
549 pInfo->channelIndex = 3;;
557 result = header[2] & MASK_PADDING;
558 if (result == MASK_PADDING)
559 pInfo->bPadding = true;
561 pInfo->bPadding = false;
563 #ifdef __MMFILE_TEST_MODE__
564 debug_msg("=> samplerate=%d, bitrate=%d, layer=%d, version=%d, channel=%d, padding=%d",
565 pInfo->sampleRate, pInfo->bitRate, pInfo->layer, pInfo->mpegVersion, pInfo->channels, pInfo->bPadding);
572 __AvParseXingHeader(AvFileContentInfo *pInfo, unsigned char *buf)
575 memset(&data, 0x00, sizeof(AvXHeadData));
578 /* There could be 2 attrs in this header : Xing or Info */
579 if ((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2)) {
580 if (buf[36] == 'X') {
581 if (buf[37] != 'i') return false;
582 if (buf[38] != 'n') return false;
583 if (buf[39] != 'g') return false;
584 } else if (buf[36] == 'I') {
585 if (buf[37] != 'n') return false;
586 if (buf[38] != 'f') return false;
587 if (buf[39] != 'o') return false;
591 } else if ((pInfo->mpegVersion == AV_MPEG_VER_2 || pInfo->mpegVersion == AV_MPEG_VER_25) && (pInfo->channels == 1)) {
592 if (buf[13] == 'X') {
593 if (buf[14] != 'i') return false;
594 if (buf[15] != 'n') return false;
595 if (buf[16] != 'g') return false;
596 } else if (buf[13] == 'I') {
597 if (buf[14] != 'n') return false;
598 if (buf[15] != 'f') return false;
599 if (buf[16] != 'o') return false;
604 if (buf[21] == 'X') {
605 if (buf[22] != 'i') return false;
606 if (buf[23] != 'n') return false;
607 if (buf[24] != 'g') return false;
608 } else if (buf[21] == 'I') {
609 if (buf[22] != 'n') return false;
610 if (buf[23] != 'f') return false;
611 if (buf[24] != 'o') return false;
619 data.toc = (unsigned char *)(pInfo->pToc);
621 if (__AvGetXingHeader(&data, (unsigned char *)buf) == 1) { /* VBR. */
622 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
623 debug_error("invalid Xing header\n");
627 pInfo->datafileLen = data.bytes;
628 pInfo->frameNum = data.frames;
629 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames) ;
637 __AvParseVBRIHeader(AvFileContentInfo *pInfo, unsigned char *buf)
640 memset(&data, 0x00, sizeof(AvVBRIHeadData));
643 if ((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2)) {
644 if (buf[36] != 'V') return false;
645 if (buf[37] != 'B') return false;
646 if (buf[38] != 'R') return false;
647 if (buf[39] != 'I') return false;
648 } else if ((pInfo->mpegVersion == AV_MPEG_VER_2) && (pInfo->channels == 1)) {
649 if (buf[36] != 'V') return false;
650 if (buf[37] != 'B') return false;
651 if (buf[38] != 'R') return false;
652 if (buf[39] != 'I') return false;
654 if (buf[36] != 'V') return false;
655 if (buf[37] != 'B') return false;
656 if (buf[38] != 'R') return false;
657 if (buf[39] != 'I') return false;
662 data.toc = (unsigned char *)(pInfo->pToc);
664 if (__AvGetVBRIHeader(&data, (unsigned char *)buf) == 1) { /* VBR. */
665 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
666 debug_error("invalid Vbri header\n");
670 pInfo->sampleRate = data.sampRate;
671 pInfo->datafileLen = data.bytes;
672 pInfo->frameNum = data.frames;
673 pInfo->frameSize = (int)((float) data.bytes / (float) data.frames) ;
680 #ifdef __MMFILE_NEW_FRAME_FUNC /* from gst */
682 __AvGetMp3FrameSize(AvFileContentInfo *pInfo)
684 unsigned int frameSize = 0;
688 frameSize = pInfo->bPadding;
689 if (pInfo->bitRate == 0) {
690 if (pInfo->layer == 1) {
692 frameSize += 0/* FIXME: possible_free_framelen*/;
693 pInfo->bitRate = frameSize * pInfo->sampleRate / 48000;
695 frameSize += 0/* FIXME: possible_free_framelen*/;
696 pInfo->bitRate = frameSize * pInfo->sampleRate /
697 ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000);
701 if (pInfo->layer == 1) {
702 frameSize = ((12000 * pInfo->bitRate / pInfo->sampleRate) + frameSize) * 4;
704 frameSize += ((pInfo->layer == AV_MP3_LAYER_3
705 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000) * pInfo->bitRate / pInfo->sampleRate;
709 pInfo->frameSize = (int)frameSize;
717 __AvGetXingBitrate(AvFileContentInfo *pInfo)
722 if (pInfo == NULL || pInfo->bVbr == false)
730 if (pInfo->mpegVersion == AV_MPEG_VER_1) { /* MPEG version 1 */
731 if (pInfo->layer == AV_MP3_LAYER_1) /* Layer 1 */
733 else /* Layer 2, 3 */
735 } else { /* MPEG version 2 */
736 if (pInfo->layer == AV_MP3_LAYER_1) /* Layer 1 */
738 else /* Layer 2, 3 */
742 br = (pInfo->frameSize - padding) * pInfo->sampleRate / factor;
744 pInfo->bitRate = (int) br;
750 __AvGetVBRIBitrate(AvFileContentInfo *pInfo)
755 if (pInfo == NULL || pInfo->bVbr == false)
763 if (pInfo->mpegVersion == AV_MPEG_VER_1) { /* MPEG version 1 */
764 if (pInfo->layer == AV_MP3_LAYER_1) /* Layer 1 */
766 else /* Layer 2, 3 */
768 } else { /* MPEG version 2 */
769 if (pInfo->layer == AV_MP3_LAYER_1) /* Layer 1 */
771 else /* Layer 2, 3 */
775 br = (pInfo->frameSize - padding) * pInfo->sampleRate / factor;
777 pInfo->bitRate = (int) br;
782 static int __AvGetLastID3offset(MMFileIOHandle *fp, unsigned int *offset)
784 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
785 #define _MMFILE_GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
787 unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0, };
788 unsigned int tagInfoSize = 0;
789 unsigned int acc_tagsize = 0;
797 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
801 readed = mmfile_read(fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
802 if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
803 debug_error("read error occured.\n");
807 if (memcmp(tagHeader, "ID3", 3) == 0) {
808 #ifdef __MMFILE_TEST_MODE__
809 debug_msg("'ID3' found.\n");
812 #ifdef __MMFILE_TEST_MODE__
813 debug_msg("'ID3' not found.\n");
818 /**@note weak id3v2 tag checking*/
819 if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
820 (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
821 (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
822 #ifdef __MMFILE_TEST_MODE__
823 debug_msg("good ID3V2 tag.\n");
826 debug_warning("It's bad ID3V2 tag.\n");
830 tagVersion = tagHeader[3];
832 if (tagVersion > 4) {
833 #ifdef __MMFILE_TEST_MODE__
834 debug_msg("Tag version not supported\n");
839 encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
840 tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
841 tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
843 /**@note unfortunately, some contents has many id3 tag.*/
844 acc_tagsize += tagInfoSize;
845 #ifdef __MMFILE_TEST_MODE__
846 debug_msg("tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
849 mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
850 *offset = acc_tagsize;
851 goto _START_TAG_SEARCH;
860 * This fuction retrieves the start position of header.
861 * Param _pFile [in] Specifies the file pointer of mp3 file.
862 * This function returns the start position of header.
865 __AvFindStartOfMp3Header(MMFileIOHandle *hFile, unsigned char *buf, AvFileContentInfo *pInfo)
867 unsigned int index = 0;
869 unsigned long id3v2TagLen = 0;
870 unsigned char *pHeader = NULL;
871 unsigned long preHeaderGap = 0;
872 unsigned long frameLen = 0;
873 unsigned long nextFrameOff = 0; /* Offset to the start of the next frame */
874 unsigned long nextFrameOffEnd = 0;
875 unsigned long bufLen = 0;
876 bool bFoundSync = false;
877 unsigned long minLen;
879 if (pInfo->fileLen > (long long)(_AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen))
880 bufLen = _AV_MP3_HEADER_POSITION_MAX;
882 bufLen = pInfo->fileLen - pInfo->tagV2Info.tagLen;
884 if (IS_ID3V2_TAG(buf)) {
887 if (pInfo->tagV2Info.tagVersion == 0x02) {
889 if (!mm_file_id3tag_parse_v222(pInfo, buf))
890 pInfo->tagV2Info.tagLen = 0;
891 } else if (pInfo->tagV2Info.tagVersion == 0x03) {
893 if (!mm_file_id3tag_parse_v223(pInfo, buf))
894 pInfo->tagV2Info.tagLen = 0;
895 } else if (pInfo->tagV2Info.tagVersion == 0x04) {
897 if (!mm_file_id3tag_parse_v224(pInfo, buf)) /* currently 2.4 ver pased by 2.3 routine */
898 pInfo->tagV2Info.tagLen = 0;
900 #ifdef __MMFILE_TEST_MODE__
901 debug_msg("pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagVersion);
905 id3v2TagLen = pInfo->tagV2Info.tagLen;
907 #ifdef __MMFILE_TEST_MODE__
908 debug_msg("id3v2TagLen(%d)\n", id3v2TagLen);
912 if (mmfile_seek(hFile, id3v2TagLen, SEEK_SET) < 0) {
913 debug_error("seek failed.\n");
916 if ((readLen = mmfile_read(hFile, buf, bufLen)) <= 0) {
917 debug_error("seek failed.\n");
922 if (preHeaderGap == bufLen - 2)
924 if (__AvIsValidHeader(pInfo, buf + preHeaderGap))
931 if (preHeaderGap == bufLen - 2)
933 if (__AvIsValidHeader(pInfo, buf + preHeaderGap))
942 index += preHeaderGap;
943 while (index <= (bufLen - minLen)) {
944 if (buf[0] == 0xff) {
945 if (VALID_SYNC(buf)) {
946 if (bufLen - index > 256) {
947 pHeader = mmfile_malloc(256);
948 if (pHeader == NULL) {
949 debug_error("malloc failed.\n");
952 strncpy((char *)pHeader, (char *)buf, 256);
954 debug_error("Header field is not exist\n");
957 if (__AvParseMp3Header(pInfo, pHeader) == false) {
961 debug_warning("Mp3 parse header failed & index(%d)\n", index);
966 #ifdef __MMFILE_TEST_MODE__
967 debug_msg("This header is valid. index(%d)\n", index);
971 if (__AvParseXingHeader(pInfo, pHeader)) {
972 __AvGetXingBitrate(pInfo);
973 } else if (__AvParseVBRIHeader(pInfo, pHeader)) {
974 __AvGetVBRIBitrate(pInfo);
983 if (__AvIsValidHeader(pInfo, pHeader)) {
987 __AvGetMp3FrameSize(pInfo);
988 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
989 frameLen = pInfo->frameSize;
991 #ifdef __MMFILE_TEST_MODE__
992 debug_msg("<<< frameLen=[%d] >>> \n", frameLen);
995 #ifndef __MMFILE_NEW_FRAME_FUNC /* FIXME : what purpose to do this? */
996 /* Account for loss of precision in the frame length calculation*/
1000 /* Check if the remaining buffer size is large enough to
1001 * look for another sync */
1002 if ((index + frameLen) < (bufLen - (minLen - 1))) {
1003 nextFrameOff = frameLen;
1004 nextFrameOffEnd = nextFrameOff + MIN(6, bufLen - (index + frameLen) - (minLen - 1));
1006 /* Search the next few bytes for the next sync */
1007 while (nextFrameOff < nextFrameOffEnd) {
1008 if (VALID_SYNC(buf + nextFrameOff)) {
1009 if (IS_VALID_FRAME_MP3(buf + nextFrameOff)) {
1016 if (bFoundSync == true)
1019 /* Assume that the first sync is valid, since there is not
1020 * enough data in the buffer to look for the next sync */
1027 debug_warning("Is not vaild header pHeader\n");
1033 debug_warning("Mp3 file frist byte is 0xff, but not header sync\n");
1042 if (mmfile_seek(hFile, 0, SEEK_SET) < 0) {
1043 debug_error("seek error!\n");
1046 if (index > (bufLen - minLen)) {
1047 debug_warning("Mp3 file sync is not found : index(%d) bufLen(%d), minLen(%d)\n", index, bufLen, minLen);
1051 if (bFoundSync == true) {
1052 #ifdef __MMFILE_TEST_MODE__
1053 debug_msg("Mp3 file found a sync Success!\n");
1056 #ifdef __MMFILE_TEST_MODE__
1057 debug_msg("Mp3 file found a sync Failed!\n");
1062 return index + id3v2TagLen;
1066 * This function retrieves the mp3 information.
1067 * Param szFileName [in] Specifies a mp3 file path.
1068 * Param _frame [out] Specifies a struct pointer for mp3 information.
1069 * This function returns true on success, or false on failure.
1071 static int mmf_file_mp3_get_infomation(char *filename, AvFileContentInfo *pInfo)
1073 MMFileIOHandle *hFile;
1074 unsigned char header[256];
1075 unsigned long frameSamples = 0;
1076 unsigned char *buf = NULL;
1077 unsigned char *v2TagExistCheck = NULL;
1078 int readAmount = 0, readedDataLen = 0;
1079 unsigned char TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
1080 unsigned char TagV1ID[4] = { 0x54, 0x41, 0x47}; /*TAG */
1081 int tagHeaderPos = 0;
1083 unsigned int head_offset = 0;
1085 #ifdef __MMFILE_TEST_MODE__
1089 if (pInfo == NULL || filename == NULL)
1092 memset(pInfo, 0x00, sizeof(AvFileContentInfo));
1094 pInfo->tagV2Info.tagLen = 0;
1095 pInfo->headerPos = 0;
1099 ret = mmfile_open(&hFile, filename, MMFILE_RDONLY);
1100 if (ret == MMFILE_UTIL_FAIL) {
1101 debug_error("open failed.\n");
1105 mmfile_seek(hFile, 0L, SEEK_END);
1106 pInfo->fileLen = mmfile_tell(hFile);
1107 if (pInfo->fileLen <= 0) {
1108 debug_error("file is too small.\n");
1111 mmfile_seek(hFile, 0L, SEEK_SET);
1113 v2TagExistCheck = mmfile_malloc(MP3_TAGv2_HEADER_LEN);
1114 if (v2TagExistCheck == NULL) {
1115 debug_error("malloc failed.\n");
1119 if (mmfile_read(hFile, v2TagExistCheck, MP3_TAGv2_HEADER_LEN) > 0) {
1120 if (IS_ID3V2_TAG(v2TagExistCheck)) {
1121 if (!(v2TagExistCheck[3] == 0xFF || v2TagExistCheck[4] == 0xFF || v2TagExistCheck[6] >= 0x80 || v2TagExistCheck[7] >= 0x80 || v2TagExistCheck[8] >= 0x80 || v2TagExistCheck[9] >= 0x80)) {
1122 if (!(v2TagExistCheck[3] > 0x04)) {
1123 pInfo->tagV2Info.tagVersion = v2TagExistCheck[3];
1124 pInfo->tagV2Info.tagLen = MP3_TAGv2_HEADER_LEN;
1125 pInfo->tagV2Info.tagLen += (unsigned long)v2TagExistCheck[6] << 21 | (unsigned long)v2TagExistCheck[7] << 14 | (unsigned long)v2TagExistCheck[8] << 7 | (unsigned long)v2TagExistCheck[9];
1126 #ifdef __MMFILE_TEST_MODE__
1127 debug_msg("pInfo->tagV2Info.tagLen(%d), pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagLen, pInfo->tagV2Info.tagVersion);
1130 #ifdef __MMFILE_TEST_MODE__
1131 debug_msg("tag is a not supported version(%d)\n", v2TagExistCheck[3]);
1135 #ifdef __MMFILE_TEST_MODE__
1136 debug_msg("tag is a tag data is valid.\n");
1140 #ifdef __MMFILE_TEST_MODE__
1141 debug_msg("this mp3 file is not included ID3v2 tag info!\n");
1145 debug_error("v2TagExistCheck value read fail!\n");
1146 if (v2TagExistCheck)
1147 _FREE_EX(v2TagExistCheck);
1151 if (v2TagExistCheck)
1152 _FREE_EX(v2TagExistCheck);
1154 if (!(pInfo->fileLen > pInfo->tagV2Info.tagLen))
1155 pInfo->tagV2Info.tagLen = 0;
1157 if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
1160 #ifdef __MMFILE_TEST_MODE__
1161 debug_msg("pInfo->fileLen(%lld)\n", pInfo->fileLen);
1164 if (pInfo->fileLen > (long long)(_AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)) {
1165 readAmount = _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen;
1166 buf = mmfile_malloc(readAmount);
1168 debug_error("malloc failed.\n");
1172 while (readAmount > 0) {
1173 if (readAmount >= AV_MP3_HEADER_READ_MAX) {
1174 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1175 && (mmfile_read(hFile, buf + readedDataLen, AV_MP3_HEADER_READ_MAX) <= 0)) {
1181 #ifdef __MMFILE_TEST_MODE__
1182 debug_msg("Reading buf readedDataLen(%d) readAmount (%d)\n", readedDataLen, readAmount);
1186 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1187 && (mmfile_read(hFile, buf + readedDataLen, readAmount) <= 0)) {
1193 #ifdef __MMFILE_TEST_MODE__
1194 debug_msg("The remained buf readed! readedDataLen(%d) readAmount (%d)\n", readedDataLen, readAmount);
1199 readAmount -= AV_MP3_HEADER_READ_MAX;
1200 readedDataLen += AV_MP3_HEADER_READ_MAX;
1202 if (readAmount <= 0)
1206 buf = mmfile_malloc(pInfo->fileLen);
1211 if (mmfile_read(hFile, buf, pInfo->fileLen) <= 0) {
1219 if (__AvGetLastID3offset(hFile, &head_offset)) {
1220 #ifdef __MMFILE_TEST_MODE__
1221 debug_msg("search start offset: %u\n", head_offset);
1223 pInfo->tagV2Info.tagLen = head_offset;
1226 pInfo->headerPos = (long) __AvFindStartOfMp3Header(hFile, buf, pInfo);
1228 #ifdef __MMFILE_TEST_MODE__
1229 debug_msg("Header Pos: %ld\n", pInfo->headerPos);
1235 if (pInfo->headerPos == -1)
1238 if (mmfile_seek(hFile, pInfo->headerPos, SEEK_SET) < 0)
1241 if (mmfile_read(hFile, header, 256) <= 0)
1244 if (__AvParseMp3Header(pInfo, header) == false)
1247 if (__AvParseXingHeader(pInfo, header)) {
1248 __AvGetXingBitrate(pInfo);
1249 } else if (__AvParseVBRIHeader(pInfo, header)) {
1250 __AvGetVBRIBitrate(pInfo);
1252 __AvGetMp3FrameSize(pInfo);
1253 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1254 #ifdef __MMFILE_TEST_MODE__
1255 debug_msg("Mp3 File FrameSize (%d) pInfo->headerPos(%d)\n", pInfo->frameSize, pInfo->headerPos);
1259 if (mmfile_seek(hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
1263 pInfo->bV1tagFound = false;
1265 if (mmfile_read(hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) <= 0)
1268 if ((tagHeaderPos = __AvMemstr(TagBuff, TagV1ID, 3, TAGV1_SEEK_GAP + 5)) >= 0) {
1269 #ifdef __MMFILE_TEST_MODE__
1270 debug_msg("Mp3 File Tag is existing\n");
1273 pInfo->bV1tagFound = true;
1274 /* In this case, V2 Tag alreay exist So, ignore V1 tag */
1275 if (pInfo->tagV2Info.tagLen == 0) {
1276 memcpy(TagBuff, (TagBuff + tagHeaderPos), MP3TAGINFO_SIZE);
1277 if (!mm_file_id3tag_parse_v110(pInfo, TagBuff))
1282 mm_file_id3tag_restore_content_info(pInfo);
1284 if (pInfo->mpegVersion == 1) {
1285 if (pInfo->layer == 1)
1286 frameSamples = MPEG_1_SIZE_LAYER_1;
1288 frameSamples = MPEG_1_SIZE_LAYER_2_3;
1290 if (pInfo->layer == 1)
1291 frameSamples = MPEG_2_SIZE_LAYER_1;
1293 frameSamples = MPEG_2_SIZE_LAYER_2_3;
1297 unsigned long numOfFrames = 0;
1298 unsigned long long tempduration = 0;
1299 unsigned int tempNumFrames = 0;
1302 numOfFrames = pInfo->frameNum * 10;
1304 numOfFrames = ((pInfo->fileLen
1305 - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0))) * 10) / pInfo->frameSize;
1307 tempNumFrames = (unsigned int)(numOfFrames / 10);
1309 if ((numOfFrames - tempNumFrames * 10) > 5)
1310 numOfFrames = (numOfFrames / 10) + 1;
1312 numOfFrames = numOfFrames / 10;
1316 tempduration = (unsigned long long)(numOfFrames * 1000);
1318 if (pInfo->mpegVersion == 1) {
1319 if (pInfo->layer == 1)
1320 frameSamples = MPEG_1_SIZE_LAYER_1;
1322 frameSamples = MPEG_1_SIZE_LAYER_2_3;
1324 if (pInfo->layer == 1)
1325 frameSamples = MPEG_2_SIZE_LAYER_1;
1327 frameSamples = MPEG_2_SIZE_LAYER_2_3;
1330 #ifdef __MMFILE_TEST_MODE__
1331 debug_msg("frameSamples : %d, tempduration : %ld", frameSamples, tempduration);
1334 if (tempduration < (unsigned long long)pInfo->sampleRate) {
1335 tempduration = (tempduration * frameSamples * 10) / pInfo->sampleRate;
1336 tempduration = (tempduration / 10);
1338 tempduration = (tempduration * frameSamples) / pInfo->sampleRate;
1340 pInfo->duration = tempduration;
1343 pInfo->duration = ((double)(frameSamples * 1000) / pInfo->sampleRate) * pInfo->frameNum;
1344 debug_msg("duration for VBR : %lld", pInfo->duration);
1346 unsigned long long frame_duration = (((unsigned long long)frameSamples * 1000000000) / pInfo->sampleRate / 1000);
1347 int file_size_except_header = pInfo->fileLen - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0));
1348 pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * frame_duration / 1000;
1349 /*pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * (frameSamples * 1000 / pInfo->sampleRate); */
1350 debug_msg("duration from new algorithm : %lld", pInfo->duration);
1354 mmfile_close(hFile);
1357 #ifdef __MMFILE_TEST_MODE__
1358 debug_msg("Mp3 File pInfo->duration (%lld) \n", pInfo->duration);
1359 debug_msg("** MP3 **\n");
1360 debug_msg("Version : %u\n", pInfo->mpegVersion);
1361 debug_msg("Layer : %u\n", pInfo->layer);
1362 debug_msg("Channel idx: %u\n", pInfo->channelIndex);
1363 debug_msg("Is VBR : %d\n", (pInfo->bVbr == true ? 1 : 0));
1364 debug_msg("Bitrate : %u\n", pInfo->bitRate);
1365 debug_msg("SampleRate : %u\n", pInfo->sampleRate);
1366 debug_msg("Channels : %u\n", pInfo->channels);
1367 debug_msg("**** Info #1 ****\n");
1368 debug_msg("Title : %s\n", pInfo->pTitle);
1369 debug_msg("Artist : %s\n", pInfo->pArtist);
1370 debug_msg("Album : %s\n", pInfo->pAlbum);
1371 debug_msg("Album_Artist: %s\n", pInfo->pAlbum_Artist);
1372 debug_msg("Year : %s\n", pInfo->pYear);
1373 debug_msg("Comment : %s\n", pInfo->pComment);
1374 debug_msg("TrackNum : %s\n", pInfo->pTrackNum);
1375 debug_msg("Genre : %s\n", pInfo->pGenre);
1376 debug_msg("**** Info #2 ****\n");
1377 debug_msg("Author : %s\n", pInfo->pAuthor);
1378 debug_msg("Copyright : %s\n", pInfo->pCopyright);
1379 debug_msg("Comment : %s\n", pInfo->pComment);
1380 debug_msg("Rating : %s\n", pInfo->pRating);
1381 debug_msg("RecDate : %s\n", pInfo->pRecDate);
1382 debug_msg("Encoded by : %s\n", pInfo->pEncBy);
1383 debug_msg("URL : %s\n", pInfo->pURL);
1384 debug_msg("Ori. Artist : %s\n", pInfo->pOriginArtist);
1385 debug_msg("Composer : %s\n", pInfo->pComposer);
1386 debug_msg("Conductor : %s\n", pInfo->pConductor);
1387 debug_msg("Artwork : mime(%s) addr(%p) size(%d)\n", pInfo->imageInfo.imageMIMEType, pInfo->imageInfo.pImageBuf, pInfo->imageInfo.imageLen);
1388 debug_msg("UnsyncLyrics : %s\n", pInfo->pUnsyncLyrics);
1389 debug_msg("SyncLyrics size : %d\n", pInfo->syncLyricsNum);
1396 debug_error("Error occured!\n");
1397 mmfile_close(hFile);