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*/
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,} },
57 { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
58 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
59 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
62 static const int mp3SamRateTable[3][3] =
63 { {44100, 48000, 32000},
64 {22050, 24000, 16000} ,
68 #define IS_VALID_FRAME_MP3(x) \
69 ((((x)[0] & mp3FrameMasking[0]) == mp3FrameDataValid[0]) && \
70 (((x)[1] & mp3FrameMasking[1]) == mp3FrameDataValid[1]) && \
71 (((x)[2] & mp3FrameMasking[2]) == mp3FrameDataValid[2]) && \
72 (((x)[3] & mp3FrameMasking[3]) == mp3FrameDataValid[3]))
76 /* interface functions */
77 int mmfile_format_read_stream_mp3 (MMFileFormatContext *formatContext);
78 int mmfile_format_read_frame_mp3 (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
79 int mmfile_format_read_tag_mp3 (MMFileFormatContext *formatContext);
80 int mmfile_format_close_mp3 (MMFileFormatContext *formatContext);
83 static int mmf_file_mp3_get_infomation (char *src, AvFileContentInfo* pInfo );
86 int mmfile_format_open_mp3 (MMFileFormatContext *formatContext)
88 AvFileContentInfo *privateData = NULL;;
93 if (NULL == formatContext)
95 debug_error("formatContext is NULL\n");
96 return MMFILE_FORMAT_FAIL;
99 if (formatContext->pre_checked == 0) {
100 ret = MMFileFormatIsValidMP3 (formatContext->uriFileName,5);
103 debug_error("It is not mp3 file\n");
104 return MMFILE_FORMAT_FAIL;
109 formatContext->ReadStream = mmfile_format_read_stream_mp3;
110 formatContext->ReadFrame = mmfile_format_read_frame_mp3;
111 formatContext->ReadTag = mmfile_format_read_tag_mp3;
112 formatContext->Close = mmfile_format_close_mp3;
114 formatContext->videoTotalTrackNum = 0;
115 formatContext->audioTotalTrackNum = 1;
117 privateData = mmfile_malloc (sizeof (AvFileContentInfo));
120 debug_error ("error: mmfile_malloc MP3 privateData\n");
121 return MMFILE_FORMAT_FAIL;
124 formatContext->privateFormatData = privateData;
126 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;
147 if (!formatContext || !formatContext->privateFormatData)
149 debug_error("formatContext is NULL\n");
150 return MMFILE_FORMAT_FAIL;
153 privateData = formatContext->privateFormatData;
155 formatContext->duration = privateData->duration;
156 formatContext->videoTotalTrackNum = 0;
157 formatContext->audioTotalTrackNum = 1;
158 formatContext->nbStreams = 1;
159 formatContext->streams[MMFILE_AUDIO_STREAM] = mmfile_malloc (sizeof (MMFileFormatStream));
160 if (NULL == formatContext->streams[MMFILE_AUDIO_STREAM])
162 debug_error ("formatContext->streams[MMFILE_AUDIO_STREAM] is NULL\n");
163 return MMFILE_FORMAT_FAIL;
166 formatContext->streams[MMFILE_AUDIO_STREAM]->streamType = MMFILE_AUDIO_STREAM;
167 formatContext->streams[MMFILE_AUDIO_STREAM]->codecId = MM_AUDIO_CODEC_MP3;
168 formatContext->streams[MMFILE_AUDIO_STREAM]->bitRate = (privateData->bitRate*1000);
169 formatContext->streams[MMFILE_AUDIO_STREAM]->framePerSec = (privateData->duration == 0 ? 0 : privateData->frameNum/privateData->duration);
170 formatContext->streams[MMFILE_AUDIO_STREAM]->width = 0;
171 formatContext->streams[MMFILE_AUDIO_STREAM]->height = 0;
172 formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = privateData->channels;
173 formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = privateData->sampleRate;
175 return MMFILE_FORMAT_SUCCESS;
180 int mmfile_format_read_frame_mp3 (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
182 return MMFILE_FORMAT_SUCCESS;
186 int mmfile_format_read_tag_mp3 (MMFileFormatContext *formatContext)
188 AvFileContentInfo *privateData = NULL;
191 if (!formatContext || !formatContext->privateFormatData)
193 debug_error("formatContext is NULL\n");
194 return MMFILE_FORMAT_FAIL;
197 privateData = formatContext->privateFormatData;
199 if (privateData->pTitle) formatContext->title = mmfile_strdup(privateData->pTitle);
200 if (privateData->pArtist) formatContext->artist = mmfile_strdup(privateData->pArtist);
201 if (privateData->pAuthor) formatContext->author = mmfile_strdup(privateData->pAuthor);
202 if (privateData->pCopyright) formatContext->copyright = mmfile_strdup(privateData->pCopyright);
203 if (privateData->pComment) formatContext->comment = mmfile_strdup(privateData->pComment);
204 if (privateData->pAlbum) formatContext->album = mmfile_strdup(privateData->pAlbum);
205 if (privateData->pYear) formatContext->year = mmfile_strdup(privateData->pYear);
206 if (privateData->pGenre) formatContext->genre = mmfile_strdup(privateData->pGenre);
207 if (privateData->pTrackNum) formatContext->tagTrackNum = mmfile_strdup(privateData->pTrackNum);
208 if (privateData->pComposer) formatContext->composer = mmfile_strdup(privateData->pComposer);
209 if (privateData->pContentGroup) formatContext->classification = mmfile_strdup(privateData->pContentGroup);
210 if (privateData->pConductor) formatContext->conductor = mmfile_strdup(privateData->pConductor);
211 if (privateData->pUnsyncLyrics) formatContext->unsyncLyrics= mmfile_strdup(privateData->pUnsyncLyrics);
212 if (privateData->pSyncLyrics) formatContext->syncLyrics= privateData->pSyncLyrics;
213 if (privateData->syncLyricsNum) formatContext->syncLyricsNum= privateData->syncLyricsNum;
214 if (privateData->pRecDate) formatContext->recDate= mmfile_strdup(privateData->pRecDate);
216 if(privateData->imageInfo.imageLen > 0)
218 formatContext->artwork = mmfile_malloc (privateData->imageInfo.imageLen);
219 if(formatContext->artwork)
221 formatContext->artworkSize = privateData->imageInfo.imageLen;
222 memcpy (formatContext->artwork, privateData->imageInfo.pImageBuf, privateData->imageInfo.imageLen);
223 if (strlen(privateData->imageInfo.imageMIMEType) > 0)
224 formatContext->artworkMime= mmfile_strdup(privateData->imageInfo.imageMIMEType);
225 else if(strlen(privateData->imageInfo.imageExt) > 0) {
226 debug_msg("ID3 tag V2 File");
227 formatContext->artworkMime= mmfile_strdup(privateData->imageInfo.imageExt);
230 debug_error("Album art image exist but there is no type information of album art\n");
235 return MMFILE_FORMAT_SUCCESS;
239 int mmfile_format_close_mp3 (MMFileFormatContext *formatContext)
241 AvFileContentInfo *privateData = NULL;
245 privateData = formatContext->privateFormatData;
248 mm_file_free_AvFileContentInfo (privateData);
249 mmfile_free (privateData);
250 formatContext->privateFormatData = NULL;
254 return MMFILE_FORMAT_SUCCESS;
258 __AvExtractI4(unsigned char *buf)
274 __AvExtractI2(unsigned char *buf)
287 __AvGetXingHeader( AvXHeadData* headData, unsigned char *buf )
289 int index, headFlags;
290 int hId, hMode, hSrIndex;
291 static int mp3SamRateTable[4] = { 44100, 48000, 32000, 99999 };
293 // get Xing header data
296 // get selected MP3 header data
297 hId = (buf[1] >> 3) & 1;
298 hSrIndex = (buf[2] >> 2) & 3;
299 hMode = (buf[3] >> 6) & 3;
302 // determine offset of header
318 /* There could be 2 attrs in this header : Xing or Info */
320 if( buf[1] != 'i' ) return 0;
321 if( buf[2] != 'n' ) return 0;
322 if( buf[3] != 'g' ) return 0;
323 } else if (buf[0] == 'I') {
324 if( buf[1] != 'n' ) return 0;
325 if( buf[2] != 'f' ) return 0;
326 if( buf[3] != 'o' ) return 0;
334 headData->sampRate = mp3SamRateTable[hSrIndex];
336 headData->sampRate >>= 1;
338 headFlags = headData->flags = __AvExtractI4( buf ); // get flags
341 if( headFlags & FRAMES_FLAG )
343 headData->frames = __AvExtractI4( buf );
346 if( headFlags & BYTES_FLAG )
348 headData->bytes = __AvExtractI4( buf );
352 if( headFlags & TOC_FLAG )
354 if( headData->toc != NULL )
356 for( index = 0; index < 100; index++ )
357 headData->toc[index] = buf[index];
362 headData->vbrScale = -1;
363 if( headFlags & VBR_SCALE_FLAG )
365 headData->vbrScale = __AvExtractI4( buf );
369 #ifdef __MMFILE_TEST_MODE__
370 debug_msg ("Xing header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
371 headData->sampRate, headData->bytes, headData->frames);
378 __AvGetVBRIHeader( AvVBRIHeadData* headData, unsigned char *buf )
381 static int mp3SamRateTable[4] = { 44100, 48000, 32000, 99999 };
384 // get selected MP3 header data
385 hId = (buf[1] >> 3) & 1;
386 hSrIndex = (buf[2] >> 2) & 3;
390 if( buf[0] != 'V' ) return 0; // fail
391 if( buf[1] != 'B' ) return 0; // header not found
392 if( buf[2] != 'R' ) return 0;
393 if( buf[3] != 'I' ) return 0;
397 headData->sampRate = mp3SamRateTable[hSrIndex];
399 headData->sampRate >>= 1;
401 headData->vID = __AvExtractI2( buf ); // get ver ID
403 headData->delay = __AvExtractI2( buf );
405 headData->qualityIndicator = buf[0];
407 headData->bytes = __AvExtractI4( buf );
409 headData->frames= __AvExtractI4( buf );
411 headData->numOfTOC = __AvExtractI2( buf );
413 headData->vbriScale = __AvExtractI2( buf );
415 headData->sizePerTable = __AvExtractI2( buf );
417 headData->framesPerTable = __AvExtractI2( buf );
420 #ifdef __MMFILE_TEST_MODE__
421 debug_msg ("Vbri header: sampling-rate:%d, stream-size:%d, frame-number:%d\n",
422 headData->sampRate, headData->bytes, headData->frames);
425 return true; // success
428 __AvIsValidHeader(AvFileContentInfo* pInfo, unsigned char *buf)
434 mp3FrameDataValid[0] = (0xFF) & (mp3FrameMasking[0]);
435 mp3FrameDataValid[1] = (0xE0 | (buf[AV_MP3HDR_VERSION_OFS] & AV_MP3HDR_VERSION_M)
436 | (buf[AV_MP3HDR_LAYER_OFS] & AV_MP3HDR_LAYER_M)) & (mp3FrameMasking[1]);
437 mp3FrameDataValid[2] = (buf[AV_MP3HDR_SAMPLERATE_OFS] & AV_MP3HDR_SAMPLERATE_M) &
438 (mp3FrameMasking[2]);
439 mp3FrameDataValid[3] = (buf[AV_MP3HDR_CHANNEL_OFS] & AV_MP3HDR_CHANNEL_M) &
440 (mp3FrameMasking[3]);
442 #ifdef __MMFILE_TEST_MODE__
443 debug_msg ("*** [%02x][%02x][%02x][%02x] : [%02x][%02x][%02x][%02x]",
444 buf[0], buf[1], buf[2],buf[3],
445 mp3FrameDataValid[0], mp3FrameDataValid[1], mp3FrameDataValid[2],mp3FrameDataValid[3]);
449 * MPEG Audio Layer I/II/III frame header
450 * from : http://www.mp3-tech.org/programmer/frame_header.html *
452 * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
454 * A 11 (31-21) Frame sync (all bits must be set)
455 * B 2 (20,19) MPEG Audio version ID
456 * C 2 (18,17) Layer description
457 * D 1 (16) Protection bit
458 * E 4 (15,12) Bitrate index
459 * F 2 (11,10) Sampling rate frequency index
460 * G 1 (9) Padding bit
461 * H 1 (8) Private bit. This one is only informative.
462 * I 2 (7,6) Channel Mode
463 * J 2 (5,4) Mode extension (Only used in Joint stereo)
470 /* Simple check for version, layer, bitrate, samplerate */
471 if ( (buf[1] & 0x18) != 0x08 && /* 000XX000 : MPEG Audio version ID, XX=01 - reserved => 00001000(0x08) */
472 (buf[1] & 0x06) != 0x00 && /* 00000XX0 : Layer description, XX=00 - reserved => 00000000(0x00) */
473 (buf[2] & 0xF0) != 0xF0 && /* XXXX0000 : Bitrate index, XX=1111 - bad => 11110000(0xF0) */
474 (buf[2] & 0x0C) != 0x0C) /* 0000XX00 : Sampling rate frequency index , XX=11 -reserved => 00001100(0x0C) */
478 #ifdef __MMFILE_TEST_MODE__
479 debug_msg ("=> %s\n", bSync? "Good!":"Bad...");
490 __AvParseMp3Header( AvFileContentInfo* pInfo, unsigned char* header )
492 unsigned char result;
494 #ifdef __MMFILE_TEST_MODE__
495 debug_msg ("### [%02x][%02x][%02x][%02x] ###\n", header[0], header[1], header[2],header[3]);
498 // 1. Check the version of mp3
499 result = header[1] & MASK_MPEG;
503 pInfo->mpegVersion = AV_MPEG_VER_1;
506 pInfo->mpegVersion = AV_MPEG_VER_2;
509 pInfo->mpegVersion = AV_MPEG_VER_25;
516 result = header[1] & MASK_LAYER;
520 pInfo->layer = AV_MP3_LAYER_1;
523 pInfo->layer = AV_MP3_LAYER_2;
526 pInfo->layer = AV_MP3_LAYER_3;
533 result = header[2] >> 4;
534 if ( pInfo->mpegVersion == AV_MPEG_VER_1 )
535 pInfo->bitRate = mp3BitRateTable[0][pInfo->layer-1][(int)result] ;
537 pInfo->bitRate = mp3BitRateTable[1][pInfo->layer-1][(int)result] ;
540 result = ( header[2] & MASK_SAMPLERATE ) >> 2;
541 if ( result == 0x03 )
544 pInfo->sampleRate = mp3SamRateTable[pInfo->mpegVersion - 1][(int)result];
547 result = header[3] & MASK_CHANNEL;
550 case MASK_CHANNEL_ST:
551 pInfo->channelIndex = 0;
554 case MASK_CHANNEL_JS:
555 pInfo->channelIndex = 1;
558 case MASK_CHANNEL_DC:
559 pInfo->channelIndex = 2;
562 case MASK_CHANNEL_MN:
563 pInfo->channelIndex = 3;;
571 result = header[2] & MASK_PADDING;
572 if ( result == MASK_PADDING )
573 pInfo->bPadding = true;
575 pInfo->bPadding = false;
577 #ifdef __MMFILE_TEST_MODE__
578 debug_msg ("=> samplerate=%d, bitrate=%d, layer=%d, version=%d, channel=%d, padding=%d",
579 pInfo->sampleRate, pInfo->bitRate, pInfo->layer, pInfo->mpegVersion, pInfo->channels, pInfo->bPadding );
586 __AvParseXingHeader( AvFileContentInfo* pInfo, unsigned char* buf )
589 memset( &data, 0x00, sizeof(AvXHeadData) );
592 /* There could be 2 attrs in this header : Xing or Info */
593 if((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2))
596 if( buf[37] != 'i' ) return false;
597 if( buf[38] != 'n' ) return false;
598 if( buf[39] != 'g' ) return false;
599 } else if (buf[36] == 'I') {
600 if( buf[37] != 'n' ) return false;
601 if( buf[38] != 'f' ) return false;
602 if( buf[39] != 'o' ) return false;
608 if((pInfo->mpegVersion == AV_MPEG_VER_2 || pInfo->mpegVersion == AV_MPEG_VER_25) && (pInfo->channels == 1))
611 if( buf[14] != 'i' ) return false;
612 if( buf[15] != 'n' ) return false;
613 if( buf[16] != 'g' ) return false;
614 } else if (buf[13] == 'I') {
615 if( buf[14] != 'n' ) return false;
616 if( buf[15] != 'f' ) return false;
617 if( buf[16] != 'o' ) return false;
625 if( buf[22] != 'i' ) return false;
626 if( buf[23] != 'n' ) return false;
627 if( buf[24] != 'g' ) return false;
628 } else if (buf[21] == 'I') {
629 if( buf[22] != 'n' ) return false;
630 if( buf[23] != 'f' ) return false;
631 if( buf[24] != 'o' ) return false;
639 data.toc = (unsigned char *)(pInfo->pToc);
641 if ( __AvGetXingHeader( &data, (unsigned char *)buf ) == 1 ) // VBR.
643 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
644 debug_error ("invalid Xing header\n");
648 pInfo->datafileLen = data.bytes;
649 pInfo->frameNum = data.frames;
650 pInfo->frameSize = (int) ( (float) data.bytes / (float) data.frames ) ;
659 __AvParseVBRIHeader( AvFileContentInfo* pInfo, unsigned char* buf )
662 memset( &data, 0x00, sizeof(AvVBRIHeadData) );
665 if((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2))
667 if( buf[36] != 'V' ) return false;
668 if( buf[37] != 'B' ) return false;
669 if( buf[38] != 'R' ) return false;
670 if( buf[39] != 'I' ) return false;
673 if((pInfo->mpegVersion == AV_MPEG_VER_2) && (pInfo->channels == 1))
675 if( buf[36] != 'V' ) return false;
676 if( buf[37] != 'B' ) return false;
677 if( buf[38] != 'R' ) return false;
678 if( buf[39] != 'I' ) return false;
682 if( buf[36] != 'V' ) return false;
683 if( buf[37] != 'B' ) return false;
684 if( buf[38] != 'R' ) return false;
685 if( buf[39] != 'I' ) return false;
690 data.toc = (unsigned char*)(pInfo->pToc);
692 if ( __AvGetVBRIHeader( &data, (unsigned char*)buf ) == 1 ) // VBR.
694 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
695 debug_error ("invalid Vbri header\n");
699 pInfo->sampleRate = data.sampRate;
700 pInfo->datafileLen = data.bytes;
701 pInfo->frameNum = data.frames;
702 pInfo->frameSize = (int) ( (float) data.bytes / (float) data.frames ) ;
710 #ifdef __MMFILE_NEW_FRAME_FUNC // from gst
712 __AvGetMp3FrameSize( AvFileContentInfo* pInfo )
714 unsigned int frameSize = 0;
718 frameSize = pInfo->bPadding;
719 if (pInfo->bitRate == 0) {
720 if (pInfo->layer == 1) {
722 frameSize += 0/* FIXME: possible_free_framelen*/;
723 pInfo->bitRate = frameSize * pInfo->sampleRate / 48000;
725 frameSize += 0/* FIXME: possible_free_framelen*/;
726 pInfo->bitRate = frameSize * pInfo->sampleRate /
727 ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000);
731 if (pInfo->layer == 1) {
732 frameSize = ((12000 * pInfo->bitRate / pInfo->sampleRate) + frameSize) * 4;
734 frameSize += ((pInfo->layer == AV_MP3_LAYER_3
735 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000) * pInfo->bitRate / pInfo->sampleRate;
739 pInfo->frameSize = (int)frameSize;
747 __AvGetXingBitrate( AvFileContentInfo* pInfo )
752 if ( pInfo == NULL || pInfo->bVbr == false )
755 if ( pInfo->bPadding )
760 if (pInfo->mpegVersion == AV_MPEG_VER_1 ) // MPEG version 1
762 if (pInfo->layer == AV_MP3_LAYER_1 ) // Layer 1
767 else // MPEG version 2
769 if (pInfo->layer == AV_MP3_LAYER_1 ) // Layer 1
775 br = ( pInfo->frameSize - padding ) * pInfo->sampleRate / factor;
777 pInfo->bitRate = (int) br;
783 __AvGetVBRIBitrate( AvFileContentInfo* pInfo )
788 if ( pInfo == NULL || pInfo->bVbr == false )
791 if ( pInfo->bPadding )
796 if (pInfo->mpegVersion == AV_MPEG_VER_1 ) // MPEG version 1
798 if (pInfo->layer == AV_MP3_LAYER_1 ) // Layer 1
803 else // MPEG version 2
805 if (pInfo->layer == AV_MP3_LAYER_1 ) // Layer 1
811 br = ( pInfo->frameSize - padding ) * pInfo->sampleRate / factor;
813 pInfo->bitRate = (int) br;
818 static int __AvGetLastID3offset (MMFileIOHandle *fp, unsigned int *offset)
820 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
821 #define _MMFILE_GET_INT_NUMBER(buff) (int)( (((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
823 unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0,};
824 unsigned int tagInfoSize = 0;
825 unsigned int acc_tagsize = 0;
833 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
837 readed = mmfile_read (fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
838 if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
839 debug_error ("read error occured.\n");
843 if (memcmp (tagHeader, "ID3", 3) == 0) {
844 #ifdef __MMFILE_TEST_MODE__
845 debug_msg ("'ID3' found.\n");
848 #ifdef __MMFILE_TEST_MODE__
849 debug_msg ("'ID3' not found.\n");
854 /**@note weak id3v2 tag checking*/
855 if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
856 (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
857 (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
858 #ifdef __MMFILE_TEST_MODE__
859 debug_msg ("good ID3V2 tag.\n");
862 debug_warning ("It's bad ID3V2 tag.\n");
866 tagVersion = tagHeader[3];
868 if (tagVersion > 4) {
869 #ifdef __MMFILE_TEST_MODE__
870 debug_msg("Tag version not supported\n");
875 encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
876 tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
877 tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
879 /**@note unfortunately, some contents has many id3 tag.*/
880 acc_tagsize += tagInfoSize;
881 #ifdef __MMFILE_TEST_MODE__
882 debug_msg("tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
885 mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
886 *offset = acc_tagsize;
887 goto _START_TAG_SEARCH;
896 * This fuction retrieves the start position of header.
897 * Param _pFile [in] Specifies the file pointer of mp3 file.
898 * This function returns the start position of header.
901 __AvFindStartOfMp3Header(MMFileIOHandle *hFile, unsigned char *buf, AvFileContentInfo* pInfo)
905 unsigned long id3v2TagLen = 0;
906 unsigned char *pHeader = NULL;
907 unsigned long preHeaderGap = 0;
908 unsigned long frameLen = 0;
909 unsigned long nextFrameOff = 0; /* Offset to the start of the next frame */
910 unsigned long nextFrameOffEnd = 0;
911 unsigned long bufLen = 0;
912 bool bFoundSync = false;
913 unsigned long minLen;
917 if(pInfo->fileLen > (_AV_MP3_HEADER_POSITION_MAX+ pInfo->tagV2Info.tagLen))
918 bufLen = _AV_MP3_HEADER_POSITION_MAX;
920 bufLen = pInfo ->fileLen - pInfo->tagV2Info.tagLen;
922 if(IS_ID3V2_TAG(buf))
926 if(pInfo->tagV2Info.tagVersion == 0x02)
929 if(!mm_file_id3tag_parse_v222(pInfo, buf))
930 pInfo->tagV2Info.tagLen = 0;
932 else if (pInfo->tagV2Info.tagVersion == 0x03)
935 if(!mm_file_id3tag_parse_v223(pInfo, buf))
936 pInfo->tagV2Info.tagLen = 0;
938 else if (pInfo->tagV2Info.tagVersion == 0x04)
941 if(!mm_file_id3tag_parse_v224(pInfo, buf)) // currently 2.4 ver pased by 2.3 routine
942 pInfo->tagV2Info.tagLen = 0;
946 #ifdef __MMFILE_TEST_MODE__
947 debug_msg ( "pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagVersion);
951 id3v2TagLen = pInfo->tagV2Info.tagLen;
953 #ifdef __MMFILE_TEST_MODE__
954 debug_msg ( "id3v2TagLen(%d)\n", id3v2TagLen);
959 if (mmfile_seek (hFile, id3v2TagLen, SEEK_SET) < 0) {
960 debug_error ( "seek failed.\n");
963 if ((readLen = mmfile_read (hFile, buf, bufLen)) <= 0) {
964 debug_error ( "seek failed.\n");
970 if (preHeaderGap == bufLen -2)
972 if(__AvIsValidHeader(pInfo, buf+preHeaderGap))
982 if (preHeaderGap == bufLen -2)
984 if(__AvIsValidHeader(pInfo, buf+preHeaderGap))
993 index += preHeaderGap;
994 while (index <= (bufLen - minLen))
1000 if(bufLen - index > 256)
1002 pHeader = mmfile_malloc (256);
1003 if (pHeader == NULL)
1005 debug_error ( "malloc failed.\n");
1008 strncpy((char *)pHeader, (char *)buf, 256);
1012 debug_error ( "Header field is not exist\n");
1015 if ( __AvParseMp3Header( pInfo, pHeader ) == false)
1020 debug_warning ( "Mp3 parse header failed & index(%d)\n", index);
1027 #ifdef __MMFILE_TEST_MODE__
1028 debug_msg ( "This header is valid. index(%d)\n", index);
1032 if ( __AvParseXingHeader( pInfo, pHeader ) )
1034 __AvGetXingBitrate( pInfo );
1036 else if(__AvParseVBRIHeader( pInfo, pHeader ))
1038 __AvGetVBRIBitrate( pInfo );
1050 if(__AvIsValidHeader(pInfo, pHeader))
1055 __AvGetMp3FrameSize( pInfo );
1056 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1057 frameLen = pInfo->frameSize;
1060 #ifdef __MMFILE_TEST_MODE__
1061 debug_msg ("<<< frameLen=[%d] >>> \n", frameLen);
1064 #ifndef __MMFILE_NEW_FRAME_FUNC // FIXME : what purpose to do this?
1065 /* Account for loss of precision in the frame length calculation*/
1069 /* Check if the remaining buffer size is large enough to
1070 * look for another sync */
1071 if ((index + frameLen) < (bufLen - (minLen - 1)))
1073 nextFrameOff = frameLen;
1074 nextFrameOffEnd = nextFrameOff +MIN(6, bufLen - (index+frameLen) - (minLen - 1));
1076 /* Search the next few bytes for the next sync */
1077 while (nextFrameOff < nextFrameOffEnd)
1079 if (VALID_SYNC(buf+nextFrameOff))
1081 if(IS_VALID_FRAME_MP3(buf+nextFrameOff))
1089 if (bFoundSync == true)
1094 /* Assume that the first sync is valid, since there is not
1095 * enough data in the buffer to look for the next sync */
1104 debug_warning ( "Is not vaild header pHeader\n");
1112 debug_warning ( "Mp3 file frist byte is 0xff, but not header sync\n");
1121 if (mmfile_seek(hFile, 0, SEEK_SET) < 0) {
1122 debug_error ( "seek error!\n");
1125 if(index > (bufLen - minLen))
1127 debug_warning ( "Mp3 file sync is not found : index(%d) bufLen(%d), minLen(%d)\n", index, bufLen, minLen);
1131 if(bFoundSync == true)
1133 #ifdef __MMFILE_TEST_MODE__
1134 debug_msg ( "Mp3 file found a sync Success!\n");
1139 #ifdef __MMFILE_TEST_MODE__
1140 debug_msg ( "Mp3 file found a sync Failed!\n");
1145 return index+id3v2TagLen;
1149 * This function retrieves the mp3 information.
1150 * Param szFileName [in] Specifies a mp3 file path.
1151 * Param _frame [out] Specifies a struct pointer for mp3 information.
1152 * This function returns true on success, or false on failure.
1154 static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo )
1156 MMFileIOHandle *hFile;
1157 unsigned char header[256];
1158 unsigned long numOfFrames=0;
1159 unsigned long frameSamples=0;
1160 unsigned char *buf = NULL;
1161 unsigned char* v2TagExistCheck = NULL;
1162 unsigned int tempNumFrames = 0;
1163 int readAmount = 0, readedDataLen = 0;
1164 unsigned long long tempduration = 0;
1165 unsigned char TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
1166 unsigned char TagV1ID[4] = { 0x54, 0x41, 0x47}; //TAG
1167 int tagHeaderPos = 0;
1169 unsigned int head_offset = 0;
1172 if (pInfo == NULL || filename == NULL)
1175 memset( pInfo, 0x00, sizeof(AvFileContentInfo) );
1177 pInfo->tagV2Info.tagLen = 0;
1178 pInfo->headerPos = 0;
1182 ret = mmfile_open (&hFile, filename, MMFILE_RDONLY);
1183 if (ret == MMFILE_UTIL_FAIL)
1185 debug_error ( "open failed.\n");
1189 mmfile_seek (hFile, 0L, SEEK_END);
1190 pInfo->fileLen = mmfile_tell (hFile);
1191 if (pInfo->fileLen <= 0)
1193 debug_error ( "file is too small.\n");
1196 mmfile_seek (hFile, 0L, SEEK_SET);
1198 v2TagExistCheck = mmfile_malloc (MP3_TAGv2_HEADER_LEN);
1199 if (v2TagExistCheck == NULL) {
1200 debug_error ( "malloc failed.\n");
1204 if (mmfile_read (hFile, v2TagExistCheck, MP3_TAGv2_HEADER_LEN) > 0)
1206 if(IS_ID3V2_TAG(v2TagExistCheck))
1208 if(!(v2TagExistCheck[3] == 0xFF || v2TagExistCheck[4] == 0xFF ||v2TagExistCheck[6] >= 0x80 || v2TagExistCheck[7] >= 0x80 || v2TagExistCheck[8] >= 0x80 || v2TagExistCheck[9] >= 0x80))
1210 if(!(v2TagExistCheck[3] > 0x04))
1212 pInfo->tagV2Info.tagVersion = v2TagExistCheck[3];
1213 pInfo->tagV2Info.tagLen = MP3_TAGv2_HEADER_LEN;
1214 pInfo->tagV2Info.tagLen += (unsigned long)v2TagExistCheck[6] << 21 | (unsigned long)v2TagExistCheck[7] << 14 |(unsigned long)v2TagExistCheck[8] << 7 | (unsigned long)v2TagExistCheck[9];
1215 #ifdef __MMFILE_TEST_MODE__
1216 debug_msg ( "pInfo->tagV2Info.tagLen(%d), pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagLen, pInfo->tagV2Info.tagVersion);
1221 #ifdef __MMFILE_TEST_MODE__
1222 debug_msg ( "tag is a not supported version(%d)\n", v2TagExistCheck[3]);
1228 #ifdef __MMFILE_TEST_MODE__
1229 debug_msg ( "tag is a tag data is valid.\n");
1235 #ifdef __MMFILE_TEST_MODE__
1236 debug_msg ( "this mp3 file is not included ID3v2 tag info!\n");
1242 debug_error ( "v2TagExistCheck value read fail!\n");
1244 _FREE_EX(v2TagExistCheck);
1249 _FREE_EX(v2TagExistCheck);
1251 if(!(pInfo->fileLen > pInfo->tagV2Info.tagLen ))
1252 pInfo->tagV2Info.tagLen = 0;
1254 if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
1257 #ifdef __MMFILE_TEST_MODE__
1258 debug_msg ( "pInfo->fileLen(%lld)\n", pInfo->fileLen);
1261 if(pInfo->fileLen > (_AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen))
1263 readAmount = _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen;
1264 buf = mmfile_malloc (readAmount);
1266 debug_error ( "malloc failed.\n");
1270 while(readAmount > 0)
1272 if(readAmount >= AV_MP3_HEADER_READ_MAX)
1274 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1275 &&(mmfile_read(hFile, buf+readedDataLen, AV_MP3_HEADER_READ_MAX) <= 0))
1284 #ifdef __MMFILE_TEST_MODE__
1285 debug_msg ( "Reading buf readedDataLen(%d) readAmount (%d)\n", readedDataLen,readAmount);
1291 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1292 &&(mmfile_read(hFile, buf+readedDataLen, readAmount) <= 0))
1301 #ifdef __MMFILE_TEST_MODE__
1302 debug_msg ( "The remained buf readed! readedDataLen(%d) readAmount (%d)\n", readedDataLen,readAmount);
1307 readAmount -= AV_MP3_HEADER_READ_MAX;
1308 readedDataLen += AV_MP3_HEADER_READ_MAX;
1316 buf = mmfile_malloc (pInfo->fileLen);
1322 if (mmfile_read(hFile, buf, pInfo->fileLen) <= 0)
1331 if (__AvGetLastID3offset (hFile, &head_offset)) {
1332 #ifdef __MMFILE_TEST_MODE__
1333 debug_msg ( "search start offset: %u\n", head_offset);
1335 pInfo->tagV2Info.tagLen = head_offset;
1338 pInfo->headerPos = (long) __AvFindStartOfMp3Header(hFile, buf, pInfo);
1340 #ifdef __MMFILE_TEST_MODE__
1341 debug_msg ( "Header Pos: %ld\n", pInfo->headerPos);
1347 if (pInfo->headerPos == -1)
1350 if (mmfile_seek(hFile, pInfo->headerPos, SEEK_SET) < 0)
1353 if (mmfile_read (hFile, header, 256) <= 0)
1356 if ( __AvParseMp3Header( pInfo, header ) == false)
1359 if ( __AvParseXingHeader( pInfo, header ) )
1361 __AvGetXingBitrate( pInfo );
1363 else if(__AvParseVBRIHeader( pInfo, header ))
1365 __AvGetVBRIBitrate( pInfo );
1369 __AvGetMp3FrameSize( pInfo );
1370 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1371 #ifdef __MMFILE_TEST_MODE__
1372 debug_msg ( "Mp3 File FrameSize (%d) pInfo->headerPos(%d)\n", pInfo->frameSize,pInfo->headerPos);
1376 if (mmfile_seek (hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
1380 pInfo ->bV1tagFound = false;
1382 if (mmfile_read (hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) <= 0)
1385 if ((tagHeaderPos = __AvMemstr(TagBuff, TagV1ID, 3, TAGV1_SEEK_GAP+5)) >= 0)
1387 #ifdef __MMFILE_TEST_MODE__
1388 debug_msg ( "Mp3 File Tag is existing\n");
1391 pInfo ->bV1tagFound = true;
1392 memcpy(TagBuff, (TagBuff + tagHeaderPos), MP3TAGINFO_SIZE);
1394 if(!mm_file_id3tag_parse_v110(pInfo, TagBuff))
1398 mm_file_id3tag_restore_content_info (pInfo);
1401 numOfFrames = pInfo->frameNum*10;
1404 numOfFrames = ((pInfo->fileLen
1405 -(pInfo->headerPos + (pInfo ->bV1tagFound ? MP3TAGINFO_SIZE : 0) ) )*10) / pInfo->frameSize;
1407 tempNumFrames = (unsigned int)(numOfFrames/10);
1411 if((numOfFrames - tempNumFrames * 10 ) > 5)
1412 numOfFrames = (numOfFrames/10) + 1;
1414 numOfFrames = numOfFrames/10;
1418 tempduration = (unsigned long long)(numOfFrames *1000);
1420 if(pInfo->mpegVersion== 1)
1422 if(pInfo->layer== 1)
1423 frameSamples = MPEG_1_SIZE_LAYER_1;
1425 frameSamples = MPEG_1_SIZE_LAYER_2_3;
1429 if(pInfo->layer == 1)
1430 frameSamples = MPEG_2_SIZE_LAYER_1;
1432 frameSamples = MPEG_2_SIZE_LAYER_2_3;
1435 debug_msg("frameSamples : %d, tempduration : %ld", frameSamples, tempduration);
1437 if(tempduration < (unsigned long long)pInfo->sampleRate)
1439 tempduration = (tempduration*frameSamples*10)/pInfo->sampleRate;
1440 tempduration = (tempduration/10);
1443 tempduration = (tempduration*frameSamples)/pInfo->sampleRate;
1445 pInfo->duration = tempduration;
1447 mmfile_close(hFile);
1450 #ifdef __MMFILE_TEST_MODE__
1451 debug_msg ( "Mp3 File pInfo->duration (%lld) \n", pInfo->duration);
1452 debug_msg ( "** MP3 **\n");
1453 debug_msg ( "Version : %u\n", pInfo->mpegVersion);
1454 debug_msg ( "Layer : %u\n", pInfo->layer);
1455 debug_msg ( "Channel idx: %u\n", pInfo->channelIndex);
1456 debug_msg ( "Is VBR : %d\n", (pInfo->bVbr == true ? 1 : 0));
1457 debug_msg ( "Bitrate : %u\n", pInfo->bitRate);
1458 debug_msg ( "SampleRate : %u\n", pInfo->sampleRate);
1459 debug_msg ( "Channels : %u\n", pInfo->channels);
1460 debug_msg ( "**** Info #1 ****\n");
1461 debug_msg ( "Title : %s\n", pInfo->pTitle);
1462 debug_msg ( "Artist : %s\n", pInfo->pArtist);
1463 debug_msg ( "Album : %s\n", pInfo->pAlbum);
1464 debug_msg ( "Year : %s\n", pInfo->pYear);
1465 debug_msg ( "Comment : %s\n", pInfo->pComment);
1466 debug_msg ( "TrackNum : %s\n", pInfo->pTrackNum);
1467 debug_msg ( "Genre : %s\n", pInfo->pGenre);
1468 debug_msg ( "**** Info #2 ****\n");
1469 debug_msg ( "Author : %s\n", pInfo->pAuthor);
1470 debug_msg ( "Copyright : %s\n", pInfo->pCopyright);
1471 debug_msg ( "Comment : %s\n", pInfo->pComment);
1472 debug_msg ( "Rating : %s\n", pInfo->pRating);
1473 debug_msg ( "RecDate : %s\n", pInfo->pRecDate);
1474 debug_msg ( "Encoded by : %s\n", pInfo->pEncBy);
1475 debug_msg ( "URL : %s\n", pInfo->pURL);
1476 debug_msg ( "Ori. Artist : %s\n", pInfo->pOriginArtist);
1477 debug_msg ( "Composer : %s\n", pInfo->pComposer);
1478 debug_msg ( "Conductor : %s\n", pInfo->pConductor);
1479 debug_msg ( "Artwork : mime(%s) addr(%p) size(%d)\n", pInfo->imageInfo.imageMIMEType, pInfo->imageInfo.pImageBuf, pInfo->imageInfo.imageLen);
1480 debug_msg ( "UnsyncLyrics : %s\n", pInfo->pUnsyncLyrics);
1481 debug_msg ( "SyncLyrics size : %d\n", pInfo->syncLyricsNum);
1488 debug_error ("Error occured!\n");
1489 mmfile_close(hFile);