0584f0da728c4c8ac95139e936cb9739ce602e78
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_format_mp3.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <string.h>     /*memcmp*/
23
24 #include <sys/types.h>
25 #include <sys/stat.h>   /*stat*/
26 #include <unistd.h>
27
28 #include <stdlib.h>     /*malloc*/
29
30 #include "mm_debug.h"
31 #include "mm_file_utils.h"
32 #include "mm_file_format_private.h"
33 #include "mm_file_format_audio.h"
34 #include "mm_file_format_mp3.h"
35
36
37 #define __MMFILE_NEW_FRAME_FUNC
38
39 #ifdef __MMFILE_NEW_TAGLIBS__
40 #include "mm_file_format_tags.h"
41 #endif
42
43
44 #define AV_MP3_FIND_SYNC_LEN            1024*30
45 #undef MIN 
46 #define MIN(a, b) ((a) < (b) ? (a) : (b))
47
48
49 static const unsigned char mp3FrameMasking[4] = {0xFF,0xFE,0x0C,0x00};
50 static unsigned char mp3FrameDataValid[4];
51
52 static const int mp3BitRateTable[2][3][16] = {
53         {       {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
54                 {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
55                 {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,}       },
56
57         {       {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,}       }
60 };
61
62 static const int mp3SamRateTable[3][3] = 
63 {       {44100, 48000, 32000},
64         {22050, 24000, 16000} ,
65         {11025, 12000, 8000} 
66 };
67
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])) 
73
74
75
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);
81
82 /* internal */
83 static int mmf_file_mp3_get_infomation (char *src, AvFileContentInfo* pInfo );
84
85 EXPORT_API
86 int mmfile_format_open_mp3 (MMFileFormatContext *formatContext)
87 {
88     AvFileContentInfo *privateData = NULL;;
89     int ret = 0;
90
91         debug_fenter();
92         
93     if (NULL == formatContext)
94     {
95         debug_error("formatContext is NULL\n");
96         return MMFILE_FORMAT_FAIL;
97     }
98
99         if (formatContext->pre_checked == 0) {
100                 ret = MMFileFormatIsValidMP3 (formatContext->uriFileName,5);
101                 if ( ret == 0 )
102                 {
103                         debug_error("It is not mp3 file\n");
104                         return MMFILE_FORMAT_FAIL;        
105                 }
106         }
107
108     
109     formatContext->ReadStream   = mmfile_format_read_stream_mp3;
110     formatContext->ReadFrame    = mmfile_format_read_frame_mp3;
111     formatContext->ReadTag      = mmfile_format_read_tag_mp3;
112     formatContext->Close        = mmfile_format_close_mp3;
113
114     formatContext->videoTotalTrackNum = 0;
115     formatContext->audioTotalTrackNum = 1;
116
117     privateData = mmfile_malloc (sizeof (AvFileContentInfo));
118     if (!privateData)
119     {
120         debug_error ("error: mmfile_malloc MP3 privateData\n");
121         return MMFILE_FORMAT_FAIL;
122     }
123
124     formatContext->privateFormatData = privateData;
125
126     ret = mmf_file_mp3_get_infomation (formatContext->uriFileName, privateData);
127     if ( ret == -1 )
128     {
129         debug_error ("error: mmfile_format_read_stream_mp3\n");
130         goto exception;
131     }
132    
133     return MMFILE_FORMAT_SUCCESS;
134     
135 exception:
136     mmfile_format_close_mp3 (formatContext);
137     return MMFILE_FORMAT_FAIL;    
138 }
139
140
141 EXPORT_API
142 int mmfile_format_read_stream_mp3 (MMFileFormatContext *formatContext)
143 {
144     AvFileContentInfo *privateData = NULL;
145         debug_fenter();
146
147     if (!formatContext || !formatContext->privateFormatData)
148     {
149         debug_error("formatContext is NULL\n");
150         return MMFILE_FORMAT_FAIL;
151     }
152
153     privateData = formatContext->privateFormatData;
154
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])
161     {
162         debug_error ("formatContext->streams[MMFILE_AUDIO_STREAM] is NULL\n");
163         return MMFILE_FORMAT_FAIL;
164     }
165     
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;
174     
175     return MMFILE_FORMAT_SUCCESS;  
176 }
177
178
179 EXPORT_API
180 int mmfile_format_read_frame_mp3  (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
181 {
182     return MMFILE_FORMAT_SUCCESS;    
183 }
184
185 EXPORT_API
186 int mmfile_format_read_tag_mp3    (MMFileFormatContext *formatContext)
187 {
188     AvFileContentInfo *privateData = NULL;
189         debug_fenter();
190
191     if (!formatContext || !formatContext->privateFormatData)
192     {
193         debug_error("formatContext is NULL\n");
194         return MMFILE_FORMAT_FAIL;
195     }
196
197     privateData = formatContext->privateFormatData;
198
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);
215
216         if(privateData->imageInfo.imageLen > 0)
217         {
218                 formatContext->artwork = mmfile_malloc (privateData->imageInfo.imageLen);
219                 if(formatContext->artwork)
220                 {
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);
228                         }
229                         else {
230                                 debug_error("Album art image exist but there is no type information of album art\n");
231                         }
232                 }
233         }
234
235         return MMFILE_FORMAT_SUCCESS;
236 }
237
238 EXPORT_API
239 int mmfile_format_close_mp3 (MMFileFormatContext *formatContext)
240 {
241     AvFileContentInfo *privateData = NULL;
242
243     if (formatContext)
244     {
245         privateData = formatContext->privateFormatData;
246         if (privateData)
247         {
248             mm_file_free_AvFileContentInfo (privateData);
249             mmfile_free (privateData);
250             formatContext->privateFormatData = NULL;
251         }
252     }
253
254     return MMFILE_FORMAT_SUCCESS;      
255 }
256
257 static int
258 __AvExtractI4(unsigned char *buf)
259 {
260         int I4;
261
262         I4 = buf[0];
263         I4 <<= 8;
264         I4 |= buf[1];
265         I4 <<= 8;
266         I4 |= buf[2];
267         I4 <<= 8;
268         I4 |= buf[3];
269
270         return I4;
271 }
272
273 static int
274 __AvExtractI2(unsigned char *buf)
275 {
276         int I2;
277
278         I2 = buf[0];
279         I2 <<= 8;
280         I2 |= buf[1];
281         I2 <<= 8;
282
283         return I2;
284 }
285
286 static int
287 __AvGetXingHeader( AvXHeadData* headData,  unsigned char *buf )
288 {
289         int                     index, headFlags;
290         int                     hId, hMode, hSrIndex;
291         static int      mp3SamRateTable[4] = { 44100, 48000, 32000, 99999 };
292
293         // get Xing header data
294         headData->flags = 0;
295
296         // get selected MP3 header data
297         hId                     = (buf[1] >> 3) & 1;
298         hSrIndex        = (buf[2] >> 2) & 3;
299         hMode           = (buf[3] >> 6) & 3;
300
301
302         // determine offset of header
303         if( hId )       // mpeg1
304         {
305                 if( hMode != 3 ) 
306                         buf += (32+4);
307                 else
308                         buf += (17+4);
309         }
310         else            // mpeg2
311         {
312                 if( hMode != 3 )
313                         buf += (17+4);
314                 else
315                         buf += (9+4);
316         }
317
318         /* There could be 2 attrs in this header : Xing or Info */
319         if (buf[0] == 'X') {
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;
327         } else {
328                 return 0;
329         }
330
331         buf += 4;
332
333         headData->hId = hId;
334         headData->sampRate = mp3SamRateTable[hSrIndex];
335         if( hId == 0 )
336                 headData->sampRate >>= 1;
337
338         headFlags = headData->flags = __AvExtractI4( buf );             // get flags
339         buf+=4;
340
341         if( headFlags & FRAMES_FLAG )
342         {
343                 headData->frames   = __AvExtractI4( buf );
344                 buf+=4;
345         }
346         if( headFlags & BYTES_FLAG )
347         {
348                 headData->bytes = __AvExtractI4( buf ); 
349                 buf+=4;
350         }
351
352         if( headFlags & TOC_FLAG ) 
353         {
354                 if( headData->toc != NULL ) 
355                 {
356                         for( index = 0; index < 100; index++ )
357                                 headData->toc[index] = buf[index];
358                 }
359                 buf+=100;
360         }
361
362         headData->vbrScale = -1;
363         if( headFlags & VBR_SCALE_FLAG )
364         {
365                 headData->vbrScale = __AvExtractI4( buf );
366                 buf+=4;
367         }
368
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);
372         #endif
373
374         return 1;       // success
375 }
376
377 static int
378 __AvGetVBRIHeader( AvVBRIHeadData* headData,  unsigned char *buf )
379 {
380         int                     hId, hSrIndex;
381         static int      mp3SamRateTable[4] = { 44100, 48000, 32000, 99999 };
382
383
384         // get selected MP3 header data
385         hId                     = (buf[1] >> 3) & 1;
386         hSrIndex        = (buf[2] >> 2) & 3;
387
388         buf += (32+4);
389
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;
394         buf += 4;
395
396         headData->hId = hId;
397         headData->sampRate = mp3SamRateTable[hSrIndex];
398         if( hId == 0 )
399                 headData->sampRate >>= 1;
400
401         headData->vID = __AvExtractI2( buf );           // get ver ID
402         buf+=2;
403         headData->delay = __AvExtractI2( buf );
404         buf+=2;
405         headData->qualityIndicator = buf[0];
406         buf+=2;
407         headData->bytes = __AvExtractI4( buf );
408         buf+=4;
409         headData->frames= __AvExtractI4( buf );
410         buf+=4;
411         headData->numOfTOC = __AvExtractI2( buf );
412         buf+=2;
413         headData->vbriScale = __AvExtractI2( buf );
414         buf+=2;
415         headData->sizePerTable = __AvExtractI2( buf );
416         buf+=2;
417         headData->framesPerTable = __AvExtractI2( buf );
418         buf+=2;
419
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);
423         #endif
424
425         return true;       // success
426 }
427 static bool
428 __AvIsValidHeader(AvFileContentInfo* pInfo, unsigned char *buf)
429 {
430         bool    bSync = false;
431
432         if (VALID_SYNC(buf))
433         {
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]);
441
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]);
446                 #endif
447
448                 /*
449                  * MPEG Audio Layer I/II/III frame header
450                  * from : http://www.mp3-tech.org/programmer/frame_header.html           *
451                  *
452                  * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
453                  *
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)
464                  * K    1       (3)     Copyright
465                  * L    1       (2)     Original
466                  * M    2       (1,0)   Emphasis
467                  *
468                  */
469
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) */
475                 {
476                         bSync = true;
477                 }
478                 #ifdef __MMFILE_TEST_MODE__
479                 debug_msg ("=> %s\n", bSync? "Good!":"Bad...");
480                 #endif
481         }
482
483         if(bSync == true)
484                 return true;
485         else 
486                 return false;
487 }
488
489 static bool
490 __AvParseMp3Header( AvFileContentInfo* pInfo,  unsigned char* header )
491 {
492         unsigned char   result;
493
494         #ifdef __MMFILE_TEST_MODE__
495         debug_msg  ("### [%02x][%02x][%02x][%02x] ###\n", header[0], header[1], header[2],header[3]);
496         #endif
497
498         // 1. Check the version of mp3
499         result = header[1] & MASK_MPEG;
500         switch (result)
501         {
502         case MASK_MPEG_1:
503                 pInfo->mpegVersion = AV_MPEG_VER_1;
504                 break;
505         case MASK_MPEG_2:
506                 pInfo->mpegVersion = AV_MPEG_VER_2;
507                 break;
508         case MASK_MPEG_25:
509                 pInfo->mpegVersion = AV_MPEG_VER_25;
510                 break;
511         default:
512                 return false;
513         }
514
515         // 2. Get a layer
516         result = header[1] & MASK_LAYER;
517         switch (result)
518         {
519         case MASK_LAYER_1:
520                 pInfo->layer = AV_MP3_LAYER_1;
521                 break;
522         case MASK_LAYER_2:
523                 pInfo->layer = AV_MP3_LAYER_2;
524                 break;
525         case MASK_LAYER_3:
526                 pInfo->layer = AV_MP3_LAYER_3;
527                 break;
528         default:
529                 return false;
530         }
531         
532         // 3. bitrate
533         result = header[2] >> 4;
534         if ( pInfo->mpegVersion == AV_MPEG_VER_1 )
535                 pInfo->bitRate = mp3BitRateTable[0][pInfo->layer-1][(int)result] ;
536         else
537                 pInfo->bitRate = mp3BitRateTable[1][pInfo->layer-1][(int)result] ;
538
539         // 4. samplerate
540         result = ( header[2] & MASK_SAMPLERATE ) >> 2;
541         if ( result == 0x03 )
542                 return false;
543         else
544                 pInfo->sampleRate = mp3SamRateTable[pInfo->mpegVersion - 1][(int)result];
545         
546         // 5. channel
547         result = header[3] & MASK_CHANNEL;
548         switch (result)
549         {
550         case MASK_CHANNEL_ST:
551                 pInfo->channelIndex = 0;
552                 pInfo->channels = 2;
553                 break;
554         case MASK_CHANNEL_JS:
555                 pInfo->channelIndex = 1;
556                 pInfo->channels = 2;
557                 break;
558         case MASK_CHANNEL_DC:
559                 pInfo->channelIndex = 2;
560                 pInfo->channels = 2;
561                 break;
562         case MASK_CHANNEL_MN:
563                 pInfo->channelIndex = 3;;
564                 pInfo->channels = 1;
565                 break;
566         default:
567                 return false;
568         }
569
570         //      6. padding
571         result = header[2] & MASK_PADDING;
572         if ( result == MASK_PADDING )
573                 pInfo->bPadding = true;
574         else
575                 pInfo->bPadding = false;
576
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  );
580         #endif
581         
582         return true;
583 }
584
585 static bool
586 __AvParseXingHeader( AvFileContentInfo* pInfo, unsigned char* buf )
587 {
588         AvXHeadData data;
589         memset( &data, 0x00, sizeof(AvXHeadData) );
590
591         //      1. Xing Header
592         /* There could be 2 attrs in this header : Xing or Info */
593         if((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2))
594         {
595                 if (buf[36] =='X') {
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;
603                 } else {
604                         return false;
605                 }
606         }
607         else
608         if((pInfo->mpegVersion == AV_MPEG_VER_2) && (pInfo->channels == 1))
609         {
610                 if (buf[13] =='X') {
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;
618                 } else {
619                         return false;
620                 }
621         }
622         else
623         if((pInfo->mpegVersion == AV_MPEG_VER_25) && (pInfo->channels == 1))
624         {
625                 if (buf[13] =='X') {
626                         if( buf[14] != 'i' ) return false;
627                         if( buf[15] != 'n' ) return false;
628                         if( buf[16] != 'g' ) return false;
629                 } else if (buf[13] == 'I') {
630                         if( buf[14] != 'n' ) return false;
631                         if( buf[15] != 'f' ) return false;
632                         if( buf[16] != 'o' ) return false;
633                 } else {
634                         return false;
635                 }
636         }
637         else
638         {
639                 if (buf[21] =='X') {
640                         if( buf[22] != 'i' ) return false;
641                         if( buf[23] != 'n' ) return false;
642                         if( buf[24] != 'g' ) return false;
643                 } else if (buf[21] == 'I') {
644                         if( buf[22] != 'n' ) return false;
645                         if( buf[23] != 'f' ) return false;
646                         if( buf[24] != 'o' ) return false;
647                 } else {
648                         return false;
649                 }
650         }
651
652         //      2. TOC
653         if ( pInfo->pToc )
654                 data.toc = (unsigned char *)(pInfo->pToc);
655
656         if ( __AvGetXingHeader( &data, (unsigned char *)buf ) == 1 ) // VBR.
657         {
658                 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
659                         debug_error ("invalid Xing header\n");
660                         return false;
661                 }
662         
663                 /* Temporary fix code for MPEG 2.5 */
664                 if (pInfo->mpegVersion != AV_MPEG_VER_25) {
665                         pInfo->sampleRate = data.sampRate;
666                 }
667                 pInfo->datafileLen = data.bytes;
668                 pInfo->frameNum = data.frames;
669                 pInfo->frameSize = (int) ( (float) data.bytes / (float) data.frames )  ;
670                 pInfo->bVbr = true;
671                 return true;
672         }
673         else
674                 return false;
675 }
676
677 static bool
678 __AvParseVBRIHeader( AvFileContentInfo* pInfo, unsigned char* buf )
679 {
680         AvVBRIHeadData data;
681         memset( &data, 0x00, sizeof(AvVBRIHeadData) );
682
683         //      1. Xing Header
684         if((pInfo->mpegVersion == AV_MPEG_VER_1) && (pInfo->channels == 2))
685         {
686                 if( buf[36] != 'V' ) return false;   
687                 if( buf[37] != 'B' ) return false;   
688                 if( buf[38] != 'R' ) return false;
689                 if( buf[39] != 'I' ) return false;
690         }
691         else
692         if((pInfo->mpegVersion == AV_MPEG_VER_2) && (pInfo->channels == 1))
693         {
694                 if( buf[36] != 'V' ) return false;   
695                 if( buf[37] != 'B' ) return false;   
696                 if( buf[38] != 'R' ) return false;
697                 if( buf[39] != 'I' ) return false;
698         }
699         else
700         {
701                 if( buf[36] != 'V' ) return false;   
702                 if( buf[37] != 'B' ) return false;   
703                 if( buf[38] != 'R' ) return false;
704                 if( buf[39] != 'I' ) return false;      
705         }
706
707         //      2. TOC
708         if ( pInfo->pToc )
709                 data.toc = (unsigned char*)(pInfo->pToc);
710
711         if ( __AvGetVBRIHeader( &data, (unsigned char*)buf ) == 1 ) // VBR.
712         {
713                 if (data.sampRate == 0 || data.bytes == 0 || data.frames == 0) {
714                         debug_error ("invalid Vbri header\n");
715                         return false;
716                 }
717
718                 pInfo->sampleRate = data.sampRate;
719                 pInfo->datafileLen = data.bytes;
720                 pInfo->frameNum = data.frames;
721                 pInfo->frameSize = (int) ( (float) data.bytes / (float) data.frames )  ;
722                 pInfo->bVbr = true;
723                 return true;
724         }
725         else
726                 return false;
727 }
728
729 #ifdef __MMFILE_NEW_FRAME_FUNC // from gst
730 static bool
731 __AvGetMp3FrameSize( AvFileContentInfo* pInfo )
732 {
733         unsigned int frameSize = 0;
734         if ( pInfo == NULL )
735                 return false;
736
737         frameSize =  pInfo->bPadding;
738          if (pInfo->bitRate == 0) {
739            if (pInfo->layer == 1) {
740                    frameSize *= 4;
741                    frameSize += 0/* FIXME: possible_free_framelen*/;
742                    pInfo->bitRate = frameSize * pInfo->sampleRate / 48000;
743            } else {
744                    frameSize += 0/* FIXME: possible_free_framelen*/;
745                    pInfo->bitRate = frameSize * pInfo->sampleRate /
746                  ((pInfo->layer == AV_MP3_LAYER_3 && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000);
747            }
748          } else {
749            /* calculating */
750            if (pInfo->layer == 1) {
751                    frameSize = ((12000 * pInfo->bitRate / pInfo->sampleRate) + frameSize) * 4;
752            } else {
753                    frameSize += ((pInfo->layer == AV_MP3_LAYER_3
754                      && pInfo->mpegVersion != AV_MPEG_VER_1) ? 72000 : 144000) * pInfo->bitRate / pInfo->sampleRate;
755            }
756          }
757
758         pInfo->frameSize = (int)frameSize;
759
760         return true;
761 }
762 #endif
763
764
765 static bool 
766 __AvGetXingBitrate( AvFileContentInfo* pInfo )
767 {
768         float   br, factor;
769         int             padding;
770
771         if ( pInfo == NULL || pInfo->bVbr == false )
772                 return false;
773
774         if ( pInfo->bPadding )
775                 padding = 1;
776         else
777                 padding = 0;
778
779         if (pInfo->mpegVersion == AV_MPEG_VER_1 )       // MPEG version 1
780         {
781                 if (pInfo->layer == AV_MP3_LAYER_1 )    // Layer 1
782                         factor = 48000.0;
783                 else                                            // Layer 2, 3
784                         factor = 144000.0;
785         }
786         else                                                    // MPEG version 2
787         {
788                 if (pInfo->layer == AV_MP3_LAYER_1 )    //      Layer 1
789                         factor = 24000.0;
790                 else                                            //      Layer 2, 3
791                         factor = 72000.0;
792         }
793
794         br = ( pInfo->frameSize - padding ) * pInfo->sampleRate / factor;
795
796         pInfo->bitRate = (int) br;
797
798         return true;
799 }
800
801 static bool
802 __AvGetVBRIBitrate( AvFileContentInfo* pInfo )
803 {
804         float   br, factor;
805         int             padding;
806
807         if ( pInfo == NULL || pInfo->bVbr == false )
808                 return false;
809
810         if ( pInfo->bPadding )
811                 padding = 1;
812         else
813                 padding = 0;
814
815         if (pInfo->mpegVersion == AV_MPEG_VER_1 )       // MPEG version 1
816         {
817                 if (pInfo->layer == AV_MP3_LAYER_1 )    // Layer 1
818                         factor = 48000.0;
819                 else                                            // Layer 2, 3
820                         factor = 144000.0;
821         }
822         else                                                    // MPEG version 2
823         {
824                 if (pInfo->layer == AV_MP3_LAYER_1 )    //      Layer 1
825                         factor = 24000.0;
826                 else                                            //      Layer 2, 3
827                         factor = 72000.0;
828         }
829
830         br = ( pInfo->frameSize - padding ) * pInfo->sampleRate / factor;
831
832         pInfo->bitRate = (int) br;
833
834         return true;
835 }
836
837 static int __AvGetLastID3offset (MMFileIOHandle *fp, unsigned int *offset)
838 {
839 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
840 #define _MMFILE_GET_INT_NUMBER(buff) (int)( (((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
841
842         unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0,};
843         unsigned int tagInfoSize = 0;
844         unsigned int acc_tagsize = 0;
845         int tagVersion = 0;
846         int encSize = 0;
847         int readed = 0;
848
849         /*init offset*/
850         *offset = 0;
851
852         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
853         
854 _START_TAG_SEARCH:
855
856         readed = mmfile_read (fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
857         if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
858                 debug_error ("read error occured.\n");
859                 return 0;
860         }
861
862         if (memcmp (tagHeader, "ID3", 3) == 0) {
863                 #ifdef __MMFILE_TEST_MODE__
864                 debug_msg ("'ID3' found.\n");
865                 #endif
866         } else {
867                 #ifdef __MMFILE_TEST_MODE__
868                 debug_msg ("'ID3' not found.\n");
869                 #endif
870                 goto search_end;
871         }
872
873         /**@note weak id3v2 tag checking*/
874         if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
875                 (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
876                 (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
877                 #ifdef __MMFILE_TEST_MODE__
878                 debug_msg ("good ID3V2 tag.\n");
879                 #endif
880         } else {
881                 debug_warning ("It's bad ID3V2 tag.\n");
882                 goto search_end;
883         }
884
885         tagVersion = tagHeader[3];
886
887         if (tagVersion > 4) {
888                 #ifdef __MMFILE_TEST_MODE__
889                 debug_msg("Tag version not supported\n");
890                 #endif
891                 goto search_end;
892         }
893
894         encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
895         tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
896         tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
897
898         /**@note unfortunately, some contents has many id3 tag.*/
899         acc_tagsize += tagInfoSize;
900         #ifdef __MMFILE_TEST_MODE__
901         debug_msg("tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
902         #endif
903
904         mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
905         *offset = acc_tagsize;
906         goto _START_TAG_SEARCH;
907
908 search_end:
909         return 1;
910 }
911
912
913
914 /*
915  *      This fuction retrieves the start position of header.
916  *      Param   _pFile [in]     Specifies the file pointer of mp3 file.
917  *      This function returns the start position of header.
918  */
919 static int
920 __AvFindStartOfMp3Header(MMFileIOHandle *hFile,  unsigned char *buf, AvFileContentInfo* pInfo)
921 {
922         int             index=0;
923         long    readLen;
924         unsigned long   id3v2TagLen = 0;
925         unsigned char   *pHeader = NULL;
926         unsigned long  preHeaderGap = 0;
927         unsigned long  frameLen = 0;
928         unsigned long  nextFrameOff = 0;     /* Offset to the start of the next frame */
929         unsigned long  nextFrameOffEnd = 0;
930         unsigned long  bufLen = 0;
931         bool bFoundSync = false;
932         unsigned long  minLen;
933
934         
935
936         if(pInfo->fileLen > (_AV_MP3_HEADER_POSITION_MAX+ pInfo->tagV2Info.tagLen))
937                 bufLen = _AV_MP3_HEADER_POSITION_MAX;
938         else
939                 bufLen = pInfo ->fileLen - pInfo->tagV2Info.tagLen;
940
941         if(IS_ID3V2_TAG(buf))
942         {
943                 
944
945                 if(pInfo->tagV2Info.tagVersion == 0x02)
946                 {
947                         
948                         if(!mm_file_id3tag_parse_v222(pInfo, buf))
949                                 pInfo->tagV2Info.tagLen = 0;
950                 }
951                 else if (pInfo->tagV2Info.tagVersion == 0x03)
952                 {
953                         
954                         if(!mm_file_id3tag_parse_v223(pInfo, buf))
955                                 pInfo->tagV2Info.tagLen = 0;
956                 }
957                 else if (pInfo->tagV2Info.tagVersion == 0x04)
958                 {
959                         
960                         if(!mm_file_id3tag_parse_v224(pInfo, buf)) // currently 2.4 ver pased by 2.3 routine
961                                 pInfo->tagV2Info.tagLen = 0;
962                 }
963                 else
964                 {
965                         #ifdef __MMFILE_TEST_MODE__
966                         debug_msg ( "pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagVersion);
967                         #endif
968                 }
969
970                 id3v2TagLen = pInfo->tagV2Info.tagLen;
971
972                 #ifdef __MMFILE_TEST_MODE__
973                 debug_msg ( "id3v2TagLen(%d)\n", id3v2TagLen);
974                 #endif
975
976                 if(id3v2TagLen)
977                 {
978                         if (mmfile_seek (hFile, id3v2TagLen, SEEK_SET) < 0) {
979                                 debug_error ( "seek failed.\n");
980                                 return -1;
981                         }
982                         if ((readLen = mmfile_read (hFile, buf, bufLen)) <= 0) {
983                                 debug_error ( "seek failed.\n");
984                                 return -1;
985                         }
986                 }
987                 while(1)
988                 {
989                         if (preHeaderGap == bufLen -2)
990                                 break;
991                         if(__AvIsValidHeader(pInfo, buf+preHeaderGap))
992                                 break;
993                         preHeaderGap++;
994                 }
995                 
996         }
997         else
998         {
999                 while(1)
1000                 {
1001                         if (preHeaderGap == bufLen -2)
1002                                 break;
1003                         if(__AvIsValidHeader(pInfo, buf+preHeaderGap))
1004                                 break;                  
1005                         preHeaderGap++;
1006                 }
1007
1008         }
1009         minLen = 4;
1010
1011         buf += preHeaderGap;
1012         index += preHeaderGap;
1013         while (index <= (bufLen - minLen)) 
1014         {
1015                 if(buf[0] == 0xff)
1016                 {
1017                         if(VALID_SYNC(buf))
1018                         {
1019                                 if(bufLen - index > 256)
1020                                 {
1021                                         pHeader = mmfile_malloc (256);
1022                                         if (pHeader == NULL)
1023                                         {
1024                                                 debug_error ( "malloc failed.\n");
1025                                                 return -1;
1026                                         }
1027                                         strncpy((char *)pHeader, (char *)buf, 256);
1028                                 }
1029                                 else
1030                                 {
1031                                         debug_error ( "Header field is not exist\n");
1032                                         return -1;
1033                                 }
1034                                 if ( __AvParseMp3Header( pInfo, pHeader ) == false)
1035                                 {
1036                                         //return -1;
1037                                         if(pHeader)
1038                                                 _FREE_EX(pHeader);
1039                                         debug_warning ( "Mp3 parse header failed & index(%d)\n", index);
1040                                         buf++;
1041                                         index++;
1042                                         continue;
1043                                 }
1044                                 else
1045                                 {
1046                                         #ifdef __MMFILE_TEST_MODE__
1047                                         debug_msg ( "This header is valid. index(%d)\n", index);
1048                                         #endif
1049                                 }
1050
1051                                 if ( __AvParseXingHeader( pInfo, pHeader ) )
1052                                 {
1053                                         __AvGetXingBitrate( pInfo );
1054                                 }
1055                                 else if(__AvParseVBRIHeader( pInfo, pHeader ))
1056                                 {
1057                                         __AvGetVBRIBitrate( pInfo );
1058                                 }
1059                                 
1060                                 if (pInfo->bVbr)
1061                                 {
1062                                         if(pHeader)
1063                                                 _FREE_EX(pHeader);
1064                                         bFoundSync = true;
1065                                         break;
1066                                 }
1067                                 else
1068                                 {
1069                                         if(__AvIsValidHeader(pInfo, pHeader))
1070                                         {
1071                                                 if(pHeader)
1072                                                         _FREE_EX(pHeader);
1073                                                 
1074                                                 __AvGetMp3FrameSize( pInfo );
1075                                                 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1076                                                 frameLen = pInfo->frameSize;
1077                                                 if (frameLen) 
1078                                                 {
1079                                                         #ifdef __MMFILE_TEST_MODE__
1080                                                         debug_msg ("<<< frameLen=[%d] >>> \n", frameLen);
1081                                                         #endif
1082
1083                                                         #ifndef __MMFILE_NEW_FRAME_FUNC // FIXME : what purpose to do this?
1084                                                         /* Account for loss of precision in the frame length calculation*/
1085                                                         frameLen--;
1086                                                         #endif
1087
1088                                                         /* Check if the remaining buffer size is large enough to
1089                                                         * look for another sync */
1090                                                         if ((index + frameLen) < (bufLen - (minLen - 1))) 
1091                                                         {
1092                                                                 nextFrameOff = frameLen;
1093                                                                 nextFrameOffEnd = nextFrameOff +MIN(6, bufLen - (index+frameLen) - (minLen - 1));
1094
1095                                                                 /* Search the next few bytes for the next sync */
1096                                                                 while (nextFrameOff < nextFrameOffEnd) 
1097                                                                 {
1098                                                                         if (VALID_SYNC(buf+nextFrameOff)) 
1099                                                                         {
1100                                                                                 if(IS_VALID_FRAME_MP3(buf+nextFrameOff)) 
1101                                                                                 {
1102                                                                                         bFoundSync = true;
1103                                                                                         break;
1104                                                                                 }
1105                                                                         }
1106                                                                         nextFrameOff++;
1107                                                                 }
1108                                                                 if (bFoundSync == true) 
1109                                                                         break;
1110                                                         }
1111                                                         else 
1112                                                         {
1113                                                                 /* Assume that the first sync is valid, since there is not
1114                                                                 * enough data in the buffer to look for the next sync */
1115                                                                 bFoundSync = true;
1116                                                         break;
1117                                                         }
1118                                                 }
1119
1120                                         }                               
1121                                         else
1122                                         {
1123                                                 debug_warning ( "Is not vaild header pHeader\n");
1124                                         }
1125                                 }
1126                                 if(pHeader)
1127                                         _FREE_EX(pHeader);
1128                         }
1129                         else
1130                         {
1131                                 debug_warning ( "Mp3 file frist byte is 0xff, but not header sync\n");
1132                         }
1133                 }
1134                 buf++;
1135                 index++;
1136         }
1137
1138         _FREE_EX (pHeader);
1139
1140         if (mmfile_seek(hFile, 0, SEEK_SET) < 0) {
1141                 debug_error ( "seek error!\n");
1142                 return -1;
1143         }
1144         if(index > (bufLen - minLen))
1145         {
1146                  debug_warning ( "Mp3 file sync is not found : index(%d) bufLen(%d), minLen(%d)\n", index, bufLen, minLen); 
1147                 return -1;
1148         }
1149         
1150         if(bFoundSync == true)
1151         {
1152                 #ifdef __MMFILE_TEST_MODE__
1153                 debug_msg ( "Mp3 file found a sync Success!\n"); 
1154                 #endif
1155         }
1156         else
1157         {
1158                 #ifdef __MMFILE_TEST_MODE__
1159                 debug_msg ( "Mp3 file found a sync Failed!\n");
1160                 #endif
1161                 return -1;
1162         }
1163
1164         return index+id3v2TagLen;
1165 }
1166
1167 /*
1168  *      This function retrieves the mp3 information.
1169  *      Param   szFileName [in] Specifies a mp3 file path.
1170  *      Param   _frame [out]    Specifies a struct pointer for mp3 information.
1171  *      This function returns true on success, or false on failure.
1172  */
1173 static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo )
1174 {
1175         MMFileIOHandle  *hFile;
1176         unsigned char   header[256];
1177         unsigned long   numOfFrames=0;
1178         unsigned long   frameSamples=0;
1179         unsigned char   *buf = NULL;    
1180         unsigned char*  v2TagExistCheck = NULL;
1181         unsigned int            tempNumFrames = 0;
1182         int     readAmount = 0, readedDataLen = 0;
1183         unsigned long long      tempduration = 0;
1184         unsigned char   TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
1185         unsigned char           TagV1ID[4] = { 0x54, 0x41, 0x47}; //TAG
1186         int             tagHeaderPos = 0;
1187         int ret = 0;
1188         unsigned int head_offset = 0;
1189         debug_fenter();
1190         
1191         if (pInfo == NULL || filename == NULL)
1192                 return -1;
1193
1194         memset( pInfo, 0x00, sizeof(AvFileContentInfo) );
1195
1196         pInfo->tagV2Info.tagLen = 0;
1197         pInfo->headerPos = 0;
1198         pInfo->genre = 148;
1199
1200         /*open*/
1201         ret = mmfile_open (&hFile, filename, MMFILE_RDONLY);
1202         if (ret == MMFILE_UTIL_FAIL) 
1203         {
1204                 debug_error ( "open failed.\n");
1205                 return -1;
1206         }
1207
1208         mmfile_seek (hFile, 0L, SEEK_END);
1209         pInfo->fileLen = mmfile_tell (hFile);
1210         if (pInfo->fileLen <= 0) 
1211         {
1212                 debug_error ( "file is too small.\n");
1213                 goto EXCEPTION;
1214         }
1215         mmfile_seek (hFile, 0L, SEEK_SET);
1216
1217         v2TagExistCheck = mmfile_malloc (MP3_TAGv2_HEADER_LEN);
1218         if (v2TagExistCheck == NULL) {
1219                 debug_error ( "malloc failed.\n");
1220                 goto EXCEPTION;
1221         }
1222
1223         if (mmfile_read (hFile, v2TagExistCheck, MP3_TAGv2_HEADER_LEN) > 0)
1224         {
1225                 if(IS_ID3V2_TAG(v2TagExistCheck))
1226                 {
1227                         if(!(v2TagExistCheck[3] == 0xFF || v2TagExistCheck[4] == 0xFF ||v2TagExistCheck[6] >= 0x80 || v2TagExistCheck[7] >= 0x80 || v2TagExistCheck[8] >= 0x80 || v2TagExistCheck[9] >= 0x80)) 
1228                         {
1229                                 if(!(v2TagExistCheck[3] > 0x04))
1230                                 {
1231                                         pInfo->tagV2Info.tagVersion = v2TagExistCheck[3];
1232                                         pInfo->tagV2Info.tagLen = MP3_TAGv2_HEADER_LEN;
1233                                         pInfo->tagV2Info.tagLen += (unsigned long)v2TagExistCheck[6] << 21 | (unsigned long)v2TagExistCheck[7] << 14 |(unsigned long)v2TagExistCheck[8] << 7  | (unsigned long)v2TagExistCheck[9];
1234                                         #ifdef __MMFILE_TEST_MODE__
1235                                         debug_msg ( "pInfo->tagV2Info.tagLen(%d), pInfo->tagV2Info.tagVersion(%d)\n", pInfo->tagV2Info.tagLen, pInfo->tagV2Info.tagVersion);
1236                                         #endif
1237                                 }
1238                                 else
1239                                 {
1240                                         #ifdef __MMFILE_TEST_MODE__
1241                                         debug_msg ( "tag is a not supported version(%d)\n", v2TagExistCheck[3]);
1242                                         #endif
1243                                 }
1244                         }
1245                         else
1246                         {
1247                                 #ifdef __MMFILE_TEST_MODE__
1248                                 debug_msg ( "tag is a tag data is valid.\n");
1249                                 #endif
1250                         }
1251                 }
1252                 else
1253                 {
1254                         #ifdef __MMFILE_TEST_MODE__
1255                         debug_msg ( "this mp3 file is not included ID3v2 tag info!\n");
1256                         #endif
1257                 }
1258         }
1259         else
1260         {
1261                 debug_error ( "v2TagExistCheck value read fail!\n");
1262                 if(v2TagExistCheck)
1263                         _FREE_EX(v2TagExistCheck);
1264                 goto EXCEPTION;
1265         }
1266
1267         if(v2TagExistCheck)
1268                 _FREE_EX(v2TagExistCheck);
1269
1270         if(!(pInfo->fileLen > pInfo->tagV2Info.tagLen ))
1271                 pInfo->tagV2Info.tagLen = 0;
1272
1273         if (mmfile_seek(hFile, 0L, SEEK_SET) < 0)
1274                 goto EXCEPTION;
1275
1276         #ifdef __MMFILE_TEST_MODE__
1277         debug_msg ( "pInfo->fileLen(%lld)\n", pInfo->fileLen);
1278         #endif
1279
1280         if(pInfo->fileLen > (_AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen))
1281         {
1282                 readAmount = _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen;
1283                 buf = mmfile_malloc (readAmount);
1284                 if (buf == NULL) {
1285                         debug_error ( "malloc failed.\n");
1286                         goto EXCEPTION;
1287                 }
1288
1289                 while(readAmount > 0)
1290                 {
1291                         if(readAmount >= AV_MP3_HEADER_READ_MAX)
1292                         {
1293                                 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1294                                         &&(mmfile_read(hFile, buf+readedDataLen, AV_MP3_HEADER_READ_MAX) <= 0))
1295                                 {
1296                                         if(buf)
1297                                                 _FREE_EX(buf);
1298                                         
1299                                         goto EXCEPTION;
1300                                 }
1301                                 else
1302                                 {
1303                                         #ifdef __MMFILE_TEST_MODE__
1304                                         debug_msg ( "Reading buf readedDataLen(%d) readAmount (%d)\n", readedDataLen,readAmount);
1305                                         #endif
1306                                 }
1307                         }
1308                         else
1309                         {
1310                                 if ((readedDataLen <= _AV_MP3_HEADER_POSITION_MAX + pInfo->tagV2Info.tagLen)
1311                                         &&(mmfile_read(hFile, buf+readedDataLen, readAmount) <= 0))
1312                                 {
1313                                         if(buf)
1314                                                 _FREE_EX(buf);
1315                                         
1316                                         goto EXCEPTION;
1317                                 }
1318                                 else
1319                                 {
1320                                         #ifdef __MMFILE_TEST_MODE__
1321                                         debug_msg ( "The remained buf readed! readedDataLen(%d) readAmount (%d)\n", readedDataLen,readAmount);
1322                                         #endif
1323                                 }
1324                         }
1325
1326                         readAmount -= AV_MP3_HEADER_READ_MAX;
1327                         readedDataLen += AV_MP3_HEADER_READ_MAX;
1328                         
1329                         if(readAmount <= 0)
1330                                 break;
1331                 }
1332         }
1333         else
1334         {
1335                 buf = mmfile_malloc (pInfo->fileLen);
1336                 if (buf == NULL)
1337                 {
1338                          goto EXCEPTION;
1339                 }
1340
1341                 if (mmfile_read(hFile, buf, pInfo->fileLen) <= 0)
1342                 {
1343                         if(buf)
1344                                 _FREE_EX(buf);
1345                         goto EXCEPTION;
1346                 }
1347         }
1348
1349         
1350         if (__AvGetLastID3offset (hFile, &head_offset)) {
1351                 #ifdef __MMFILE_TEST_MODE__
1352                 debug_msg ( "search start offset: %u\n", head_offset);
1353                 #endif
1354                 pInfo->tagV2Info.tagLen = head_offset;
1355         }
1356         
1357         pInfo->headerPos = (long) __AvFindStartOfMp3Header(hFile, buf, pInfo);
1358
1359         #ifdef __MMFILE_TEST_MODE__
1360         debug_msg ( "Header Pos: %ld\n", pInfo->headerPos);
1361         #endif
1362
1363         if(buf)
1364                 _FREE_EX(buf);
1365
1366         if (pInfo->headerPos == -1)
1367                 goto EXCEPTION;
1368
1369         if (mmfile_seek(hFile, pInfo->headerPos, SEEK_SET) < 0)
1370                 goto EXCEPTION;
1371
1372         if (mmfile_read (hFile, header, 256) <= 0)
1373                 goto EXCEPTION;
1374
1375         if ( __AvParseMp3Header( pInfo, header ) == false)
1376                 goto EXCEPTION;
1377
1378         if ( __AvParseXingHeader( pInfo, header ) )
1379         {
1380                 __AvGetXingBitrate( pInfo );
1381         }
1382         else if(__AvParseVBRIHeader( pInfo, header ))
1383         {
1384                 __AvGetVBRIBitrate( pInfo );
1385         }
1386         else
1387         {
1388                 __AvGetMp3FrameSize( pInfo );
1389                 pInfo->datafileLen = pInfo->fileLen - pInfo->headerPos;
1390                 #ifdef __MMFILE_TEST_MODE__
1391                 debug_msg ( "Mp3 File FrameSize (%d) pInfo->headerPos(%d)\n", pInfo->frameSize,pInfo->headerPos);
1392                 #endif
1393         }
1394
1395         if (mmfile_seek (hFile, -(MP3TAGINFO_SIZE + TAGV1_SEEK_GAP), SEEK_END) < 0)
1396                 goto EXCEPTION;
1397
1398
1399         pInfo ->bV1tagFound = false;
1400
1401         if (mmfile_read (hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) <= 0)
1402                 goto EXCEPTION;
1403
1404         if ((tagHeaderPos = __AvMemstr(TagBuff, TagV1ID, 3, TAGV1_SEEK_GAP+5)) >= 0)
1405         {
1406                 #ifdef __MMFILE_TEST_MODE__
1407                 debug_msg ( "Mp3 File Tag is existing\n");
1408                 #endif
1409
1410                 pInfo ->bV1tagFound = true;
1411                 memcpy(TagBuff, (TagBuff + tagHeaderPos), MP3TAGINFO_SIZE);
1412
1413                 if(!mm_file_id3tag_parse_v110(pInfo, TagBuff))
1414                         goto EXCEPTION;
1415         }
1416
1417         mm_file_id3tag_restore_content_info (pInfo);
1418
1419         if(pInfo->bVbr) 
1420                 numOfFrames = pInfo->frameNum*10;
1421         else
1422         {
1423                 numOfFrames = ((pInfo->fileLen
1424                 -(pInfo->headerPos + (pInfo ->bV1tagFound ? MP3TAGINFO_SIZE : 0) ) )*10) / pInfo->frameSize;
1425         }
1426         tempNumFrames = (unsigned int)(numOfFrames/10);
1427
1428         
1429
1430         if((numOfFrames - tempNumFrames * 10 ) > 5)
1431                 numOfFrames = (numOfFrames/10) + 1;
1432         else
1433                 numOfFrames = numOfFrames/10;
1434
1435         
1436
1437         tempduration = (unsigned long long)(numOfFrames *1000);
1438         
1439         if(pInfo->mpegVersion== 1) 
1440         {
1441                 if(pInfo->layer== 1) 
1442                         frameSamples = MPEG_1_SIZE_LAYER_1;
1443                 else 
1444                         frameSamples = MPEG_1_SIZE_LAYER_2_3;
1445         }
1446         else 
1447         {
1448                 if(pInfo->layer == 1) 
1449                         frameSamples = MPEG_2_SIZE_LAYER_1;
1450                 else 
1451                         frameSamples = MPEG_2_SIZE_LAYER_2_3;
1452         }
1453
1454         debug_msg("frameSamples : %d, tempduration : %ld", frameSamples, tempduration);
1455
1456         if(tempduration < (unsigned long long)pInfo->sampleRate)
1457         {
1458                 tempduration = (tempduration*frameSamples*10)/pInfo->sampleRate;
1459                 tempduration = (tempduration/10);
1460         }
1461         else
1462                 tempduration = (tempduration*frameSamples)/pInfo->sampleRate;
1463
1464         pInfo->duration = tempduration;
1465
1466         mmfile_close(hFile);
1467         
1468         /*debug print*/
1469         #ifdef __MMFILE_TEST_MODE__
1470         debug_msg ( "Mp3 File pInfo->duration (%lld) \n", pInfo->duration);
1471         debug_msg ( "** MP3 **\n");
1472         debug_msg ( "Version    : %u\n", pInfo->mpegVersion);
1473         debug_msg ( "Layer      : %u\n", pInfo->layer);
1474         debug_msg ( "Channel idx: %u\n", pInfo->channelIndex);
1475         debug_msg ( "Is VBR     : %d\n", (pInfo->bVbr == true ? 1 : 0));
1476         debug_msg ( "Bitrate    : %u\n", pInfo->bitRate);
1477         debug_msg ( "SampleRate : %u\n", pInfo->sampleRate);
1478         debug_msg ( "Channels   : %u\n", pInfo->channels);
1479         debug_msg ( "**** Info #1 ****\n");
1480         debug_msg ( "Title       : %s\n", pInfo->pTitle);
1481         debug_msg ( "Artist      : %s\n", pInfo->pArtist);
1482         debug_msg ( "Album       : %s\n", pInfo->pAlbum);
1483         debug_msg ( "Year        : %s\n", pInfo->pYear);
1484         debug_msg ( "Comment     : %s\n", pInfo->pComment);
1485         debug_msg ( "TrackNum    : %s\n", pInfo->pTrackNum);
1486         debug_msg ( "Genre       : %s\n", pInfo->pGenre);
1487         debug_msg ( "**** Info #2 ****\n");
1488         debug_msg ( "Author      : %s\n", pInfo->pAuthor);
1489         debug_msg ( "Copyright   : %s\n", pInfo->pCopyright);
1490         debug_msg ( "Comment : %s\n", pInfo->pComment);
1491         debug_msg ( "Rating      : %s\n", pInfo->pRating);
1492         debug_msg ( "RecDate     : %s\n", pInfo->pRecDate);
1493         debug_msg ( "Encoded by  : %s\n", pInfo->pEncBy);
1494         debug_msg ( "URL         : %s\n", pInfo->pURL);
1495         debug_msg ( "Ori. Artist : %s\n", pInfo->pOriginArtist);
1496         debug_msg ( "Composer    : %s\n", pInfo->pComposer);
1497         debug_msg ( "Conductor   : %s\n", pInfo->pConductor);
1498         debug_msg ( "Artwork     : mime(%s) addr(%p) size(%d)\n", pInfo->imageInfo.imageMIMEType, pInfo->imageInfo.pImageBuf, pInfo->imageInfo.imageLen);
1499         debug_msg ( "UnsyncLyrics   : %s\n", pInfo->pUnsyncLyrics);
1500         debug_msg ( "SyncLyrics size  : %d\n", pInfo->syncLyricsNum);
1501
1502         #endif
1503
1504         return 0;
1505
1506 EXCEPTION:
1507         debug_error ("Error occured!\n");
1508         mmfile_close(hFile);
1509         return -1;
1510 }