support some format. 85/41385/5 submit/tizen/20150617.061651 submit/tizen/20150617.113051
authorji.yong.seo <ji.yong.seo@samsung.com>
Mon, 15 Jun 2015 01:38:20 +0000 (10:38 +0900)
committerji.yong.seo <ji.yong.seo@samsung.com>
Tue, 16 Jun 2015 07:02:56 +0000 (16:02 +0900)
Change-Id: If1b51132a4cd4065bf0bf40498ae386c5035f427

30 files changed:
configure.ac
formats/ffmpeg/Makefile.am
formats/ffmpeg/include/mm_file_format_id3tag.h
formats/ffmpeg/mm_file_format_aac.c
formats/ffmpeg/mm_file_format_ffmpeg.c
formats/ffmpeg/mm_file_format_ffmpeg_drm.c [new file with mode: 0755]
formats/ffmpeg/mm_file_format_frame.c
formats/ffmpeg/mm_file_format_imelody.c
formats/ffmpeg/mm_file_format_midi.c
formats/ffmpeg/mm_file_format_mmf.c
formats/ffmpeg/mm_file_format_mp3.c
formats/ffmpeg/mm_file_format_wav.c
formats/ffmpeg/mm_file_formats.c
include/mm_file.h
include/mm_file_formats.h
mm_file.c
packaging/libmm-fileinfo.spec
tests/Makefile.am
tests/mm_file_test.c
tests/mm_file_traverser.c
utils/Makefile.am
utils/include/mm_file_utils.h
utils/mm_file_util_io.c
utils/mm_file_util_io_drm.c [new file with mode: 0755]
utils/mm_file_util_locale.c
utils/mm_file_util_memory.c
utils/mm_file_util_mime.c
utils/mm_file_util_string.c
utils/mm_file_util_tag.c
utils/mm_file_util_validity.c

index 40c9395..0109c79 100755 (executable)
@@ -10,6 +10,7 @@ AC_CONFIG_MACRO_DIR([m4])
 
 # Checks for programs.
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+AM_PROG_AR
 AC_PROG_CC
 AM_PROG_CC_C_O
 AC_PROG_LIBTOOL
@@ -85,6 +86,14 @@ PKG_CHECK_MODULES(SWSCALE, libswscale)
 AC_SUBST(SWSCALE_CFLAGS)
 AC_SUBST(SWSACLE_LIBS)
 
+PKG_CHECK_MODULES(ICU, icu-i18n)
+AC_SUBST(ICU_CFLAGS)
+AC_SUBST(ICU_LIBS)
+
+PKG_CHECK_MODULES(VCONF, vconf)
+AC_SUBST(VCONF_CFLAGS)
+AC_SUBST(VCONF_LIBS)
+
 dnl use drm  --------------------------------------------------------------------------
 AC_ARG_ENABLE(drm, AC_HELP_STRING([--enable-drm], [using drm]),
 [
@@ -98,9 +107,13 @@ if test "x$USE_DRM" = "xyes"; then
      PKG_CHECK_MODULES(DRMCLIENT, drm-client)
      AC_SUBST(DRMCLIENT_CFLAGS)
      AC_SUBST(DRMCLIENT_LIBS)
+
+     PKG_CHECK_MODULES(DRMTRUSTED, drm-trusted)
+     AC_SUBST(DRMTRUSTED_CFLAGS)
+     AC_SUBST(DRMTRUSTED_LIBS)
 fi
 AM_CONDITIONAL(USE_DRM, test "x$USE_DRM" = "xyes")
+
 dnl use dyn --------------------------------------------------------------------------
 AC_ARG_ENABLE(dyn, AC_HELP_STRING([--enable-dyn], [using dyn]),
 [
index 8783dca..380277c 100755 (executable)
@@ -41,19 +41,21 @@ libmmfile_formats_la_CFLAGS = -I$(srcdir)/include \
 
 if USE_TESTMODE
 libmmfile_formats_la_CFLAGS += -D__MMFILE_TEST_MODE__
-endif  
+endif
 
 if USE_DUMP
 libmmfile_formats_la_CFLAGS += -DMMFILE_FORMAT_DEBUG_DUMP
-endif  
+endif
 
 if USE_DRM
-libmmfile_formats_la_CFLAGS += $(DRMCLIENT_CFLAGS) -DDRM_SUPPORT
+noinst_HEADERS += include/mm_file_format_ffmpeg_drm.h
+libmmfile_formats_la_SOURCES += mm_file_format_ffmpeg_drm.c
+libmmfile_formats_la_CFLAGS += $(DRMCLIENT_CFLAGS) $(DRMTRUSTED_CFLAGS) -DDRM_SUPPORT
 endif
 
 if USE_IOMMAP
 libmmfile_formats_la_CFLAGS += -D__MMFILE_MMAP_MODE__
-endif  
+endif
 
 
 libmmfile_formats_la_LIBADD = $(MMCOMMON_LIBS) \
@@ -61,10 +63,10 @@ libmmfile_formats_la_LIBADD = $(MMCOMMON_LIBS) \
                                $(AVCODEC_LIBS) \
                                $(AVFORMAT_LIBS) \
                                $(SWSCALE_LIBS) \
-                         $(top_builddir)/utils/libmmfile_utils.la 
+                         $(top_builddir)/utils/libmmfile_utils.la
 
 if USE_DRM
-libmmfile_formats_la_LIBADD += $(DRMCLIENT_LIBS)
+libmmfile_formats_la_LIBADD += $(DRMCLIENT_LIBS) $(DRMTRUSTTED_LIBS)
 endif
 
 libmmfile_formats_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x040 -DMMF_DEBUG_PREFIX=\"MMF-FILE-FORMAT-FFMPEG\"
index 042d474..6e747e6 100755 (executable)
@@ -98,11 +98,11 @@ typedef enum {
 
 
 typedef enum {
-       AV_ID3V2_ISO_8859,
+       AV_ID3V2_ISO_8859 = 0,
        AV_ID3V2_UTF16,
        AV_ID3V2_UTF16_BE,
-       AV_ID3V2_UTF8
-       
+       AV_ID3V2_UTF8,
+       AV_ID3V2_MAX
 } AvID3v2EncodingType;
 
 
@@ -128,6 +128,7 @@ typedef struct{
        bool    bTitleMarked;
        bool    bArtistMarked;
        bool    bAlbumMarked;
+       bool    bAlbum_ArtistMarked;
        bool    bYearMarked;
        bool    bDescriptionMarked;
        bool    bGenreMarked;
index 11d19f8..095efff 100755 (executable)
@@ -259,6 +259,7 @@ int _parse_id3_tag(tMMFILE_AAC_HANDLE* pData)
   pData->tagInfo.author = hTag->pAuthor;
   pData->tagInfo.artist = hTag->pArtist;
   pData->tagInfo.album = hTag->pAlbum;
+  pData->tagInfo.album_artist = hTag->pAlbum_Artist;
   pData->tagInfo.year = hTag->pYear;
   pData->tagInfo.copyright = hTag->pCopyright;
   pData->tagInfo.comment = hTag->pComment;
@@ -267,23 +268,23 @@ int _parse_id3_tag(tMMFILE_AAC_HANDLE* pData)
   pData->tagInfo.composer = hTag->pComposer;
   pData->tagInfo.classification = hTag->pContentGroup;
   pData->tagInfo.rating = hTag->pRating;
-  pData->tagInfo.recordDate = hTag->pRecDate;  
-  pData->tagInfo.conductor = hTag->pConductor;  
-  pData->tagInfo.artworkMime = hTag->imageInfo.imageMIMEType;  
+  pData->tagInfo.recordDate = hTag->pRecDate;
+  pData->tagInfo.conductor = hTag->pConductor;
+  pData->tagInfo.artworkMime = hTag->imageInfo.imageMIMEType;
   pData->tagInfo.artworkSize = hTag->imageInfo.imageLen;
   pData->tagInfo.artwork = hTag->imageInfo.pImageBuf;
 
   ret = MMFILE_AAC_PARSER_SUCCESS;
 
-  
+
 failure:
   if(tagBuff) {
     mmfile_free(tagBuff);
     tagBuff = NULL;
   }
-  
+
   return ret;
-  
+
 }
 
 
@@ -291,9 +292,9 @@ int _get_range_bits_value (unsigned char* buff, int fieldOffset, int fieldSize)
 {
   int pos = 0;
   unsigned int srcByteStartOff = 0;
-  unsigned int srcByteEndOff = 0;  
+  unsigned int srcByteEndOff = 0;
   unsigned int srcBitStartOff = 0;
-  unsigned int srcBitEndOff = 0;  
+  unsigned int srcBitEndOff = 0;
   unsigned char dest[4] = {0,};
   unsigned int res = 0;
   unsigned int i,j, temp;
@@ -852,7 +853,7 @@ exception:
 EXPORT_API
 int mmfile_format_read_tag_aac (MMFileFormatContext *formatContext)
 {
-  MMFileAACHandle     handle = NULL;  
+  MMFileAACHandle     handle = NULL;
   tMMFILE_AAC_TAG_INFO  aacinfo = {0,};
   int ret= MMFILE_FORMAT_FAIL;
 
@@ -861,9 +862,9 @@ int mmfile_format_read_tag_aac (MMFileFormatContext *formatContext)
     ret = MMFILE_FORMAT_FAIL;
     goto exception;
   }
-    
+
   handle = formatContext->privateFormatData;
-  
+
   ret = mmfile_aacparser_get_tag_info (handle, &aacinfo);
   if (MMFILE_FORMAT_SUCCESS != ret) {
     debug_warning ("error: mmfile_aacparser_get_tag_info\n");
@@ -872,34 +873,36 @@ int mmfile_format_read_tag_aac (MMFileFormatContext *formatContext)
   }
 
   if(aacinfo.title)
-    formatContext->title = mmfile_strdup(aacinfo.title); 
+    formatContext->title = mmfile_strdup(aacinfo.title);
   if(aacinfo.author)
     formatContext->author = mmfile_strdup(aacinfo.author);
-  if(aacinfo.artist) 
-    formatContext->artist = mmfile_strdup(aacinfo.artist); 
-  if(aacinfo.album) 
+  if(aacinfo.artist)
+    formatContext->artist = mmfile_strdup(aacinfo.artist);
+  if(aacinfo.album)
     formatContext->album = mmfile_strdup(aacinfo.album);
-  if(aacinfo.year) 
+  if(aacinfo.album_artist)
+    formatContext->album_artist = mmfile_strdup(aacinfo.album_artist);
+  if(aacinfo.year)
     formatContext->year = mmfile_strdup(aacinfo.year);
-  if(aacinfo.copyright) 
-    formatContext->copyright = mmfile_strdup(aacinfo.copyright); 
-  if(aacinfo.comment) 
+  if(aacinfo.copyright)
+    formatContext->copyright = mmfile_strdup(aacinfo.copyright);
+  if(aacinfo.comment)
     formatContext->comment = mmfile_strdup(aacinfo.comment);
-  if(aacinfo.genre) 
+  if(aacinfo.genre)
     formatContext->genre = mmfile_strdup(aacinfo.genre);
   if(aacinfo.tracknum)
     formatContext->tagTrackNum= mmfile_strdup(aacinfo.tracknum);
-  if(aacinfo.composer) 
+  if(aacinfo.composer)
     formatContext->composer = mmfile_strdup(aacinfo.composer);
-  if(aacinfo.classification) 
+  if(aacinfo.classification)
     formatContext->classification = mmfile_strdup(aacinfo.classification);
-  if(aacinfo.rating) 
+  if(aacinfo.rating)
     formatContext->rating = mmfile_strdup(aacinfo.rating);     /*not exist rating tag in id3*/
-  if(aacinfo.conductor) 
+  if(aacinfo.conductor)
     formatContext->conductor = mmfile_strdup(aacinfo.conductor);
-  if(aacinfo.artworkMime) 
+  if(aacinfo.artworkMime)
     formatContext->artworkMime = mmfile_strdup(aacinfo.artworkMime);
-  if(aacinfo.artwork) { 
+  if(aacinfo.artwork) {
     formatContext->artworkSize = aacinfo.artworkSize;
     formatContext->artwork = mmfile_malloc(aacinfo.artworkSize);
     if(formatContext->artwork == NULL) {
@@ -933,28 +936,28 @@ int mmfile_format_read_frame_aac (MMFileFormatContext *formatContext,
 EXPORT_API
 int mmfile_format_close_aac (MMFileFormatContext *formatContext)
 {
-  MMFileAACHandle  handle = NULL;  
+  MMFileAACHandle  handle = NULL;
   int ret = MMFILE_FORMAT_FAIL;
-   
+
   if (NULL == formatContext ) {
     debug_error ("error: invalid params\n");
     return MMFILE_FORMAT_FAIL;
   }
-    
+
   handle = formatContext->privateFormatData;
-   
+
   if(NULL != handle) {
     ret = mmfile_aacparser_close(handle);
     if(ret == MMFILE_AAC_PARSER_FAIL) {
       debug_error("error: mmfile_format_close_aac\n");
     }
   }
-  
+
   if(formatContext->streams[MMFILE_AUDIO_STREAM]) {
     mmfile_free(formatContext->streams[MMFILE_AUDIO_STREAM]);
     formatContext->streams[MMFILE_AUDIO_STREAM] = NULL;
   }
-  
+
   formatContext->ReadStream   = NULL;
   formatContext->ReadFrame    = NULL;
   formatContext->ReadTag      = NULL;
index dd6542f..a79e25a 100755 (executable)
  * limitations under the License.
  *
  */
+
 #include <string.h>
 #include <stdlib.h>
 
 #include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
+#include <libavutil/samplefmt.h>
 #ifdef __MMFILE_FFMPEG_V085__
 #include <libswscale/swscale.h>
 #endif
 #include <mm_error.h>
 #include <mm_types.h>
+
+#ifdef DRM_SUPPORT
+#include <drm_client.h>
+#endif
+
 #include "mm_debug.h"
 #include "mm_file_formats.h"
 #include "mm_file_utils.h"
 #include "mm_file_format_ffmpeg.h"
 
+#ifdef DRM_SUPPORT
+#include "mm_file_format_ffmpeg_drm.h"
+#endif
+
 #include "mm_file_format_ffmpeg_mem.h"
 #include <sys/time.h>
 
@@ -51,7 +61,7 @@ static void _dump_av_packet (AVPacket *pkt);
 #endif
 
 static int     _get_video_fps (int frame_cnt, int duration, AVRational r_frame_rate, int is_roundup);
-static int     _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame);
+static int     _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame, int cdis);
 
 static int     ConvertVideoCodecEnum (int AVVideoCodecID);
 static int     ConvertAudioCodecEnum (int AVAudioCodecID);
@@ -61,7 +71,7 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext);
 int mmfile_format_read_frame_ffmpg  (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
 int mmfile_format_read_tag_ffmpg    (MMFileFormatContext *formatContext);
 int mmfile_format_close_ffmpg       (MMFileFormatContext *formatContext);
-static int getMimeType(int formatId, char *mimeType); 
+static int getMimeType(int formatId, char *mimeType, int buf_size);
 
 
 
@@ -72,6 +82,9 @@ int mmfile_format_open_ffmpg (MMFileFormatContext *formatContext)
        AVInputFormat       *grab_iformat = NULL;
        int ret = 0;
        int i;
+#ifdef DRM_SUPPORT
+       drm_content_info_s contentInfo = {0,};
+#endif
        char ffmpegFormatName[MMFILE_FILE_FMT_MAX_LEN] = {0,};
        char mimeType[MMFILE_MIMETYPE_MAX_LEN] = {0,};
 
@@ -105,14 +118,14 @@ int mmfile_format_open_ffmpg (MMFileFormatContext *formatContext)
                ffurl_register_protocol(&MMFileMEMProtocol, sizeof (URLProtocol));
 #else
                register_protocol (&MMFileMEMProtocol);
-#endif 
-               if(getMimeType(formatContext->filesrc->memory.format,mimeType)< 0) {
+#endif
+               if(getMimeType(formatContext->filesrc->memory.format,mimeType, MMFILE_MIMETYPE_MAX_LEN)< 0) {
                        debug_error ("error: Error in MIME Type finding\n");
                        return MMFILE_FORMAT_FAIL;
                }
 
                memset (ffmpegFormatName, 0x00, MMFILE_FILE_FMT_MAX_LEN);
-               
+
                ret = mmfile_util_get_ffmpeg_format (mimeType,ffmpegFormatName);
 
                if (MMFILE_UTIL_SUCCESS != ret) {
@@ -138,12 +151,58 @@ int mmfile_format_open_ffmpg (MMFileFormatContext *formatContext)
                }
                formatContext->privateFormatData = pFormatCtx;
        }
-       
+
        if (formatContext->filesrc->type  == MM_FILE_SRC_TYPE_FILE) {
 
                if (formatContext->isdrm == MM_FILE_DRM_OMA) {
-                       debug_error ("error: drm content\n");
-                       goto exception;
+#ifdef DRM_SUPPORT
+                       if (formatContext->formatType == MM_FILE_FORMAT_DIVX || formatContext->formatType == MM_FILE_FORMAT_AVI) {
+                               goto HANDLING_DRM_DIVX;
+                       }
+
+#ifdef __MMFILE_FFMPEG_V085__
+                       ffurl_register_protocol(&MMFileDRMProtocol, sizeof (URLProtocol));
+#else
+                       register_protocol (&MMFileDRMProtocol);
+#endif
+                       memset(&contentInfo, 0x0, sizeof(drm_content_info_s));
+                       if (DRM_RETURN_SUCCESS != drm_get_content_info (formatContext->filesrc->file.path, &contentInfo)) {
+                               debug_error ("error: drm_get_content_info\n");
+                               return MMFILE_FORMAT_FAIL;
+                       }
+
+                       memset (ffmpegFormatName, 0x00, MMFILE_FILE_FMT_MAX_LEN);
+
+                       ret = mmfile_util_get_ffmpeg_format (contentInfo.mime_type, ffmpegFormatName);
+                       if (MMFILE_UTIL_SUCCESS != ret) {
+                               debug_error ("error: mmfile_util_get_ffmpeg_format\n");
+                               return MMFILE_FORMAT_FAIL;
+                       }
+
+                       #ifdef __MMFILE_TEST_MODE__
+                       debug_warning ("FFMPEG: test........... : %s\n", ffmpegFormatName);
+                       debug_warning ("FFMPEG: DRM URI = %s\n", formatContext->uriFileName);
+                       debug_warning ("FFMPEG: ffmpeg name = %s\n", ffmpegFormatName);
+                       #endif
+
+                       grab_iformat = av_find_input_format (ffmpegFormatName);
+
+                       if (NULL == grab_iformat) {
+                               debug_error ("error: cannot find format\n");
+                               goto exception;
+                       }
+
+#ifdef __MMFILE_FFMPEG_V085__
+                       ret = avformat_open_input (&pFormatCtx, formatContext->uriFileName, grab_iformat, NULL);
+#else
+                       ret = av_open_input_file (&pFormatCtx, formatContext->uriFileName, grab_iformat, 0, NULL);
+#endif
+                       if (ret < 0) {
+                               debug_error("error: cannot open %s %d\n", formatContext->uriFileName, ret);
+                               goto exception;
+                       }
+                       formatContext->privateFormatData = pFormatCtx;
+#endif
                } else {
 HANDLING_DRM_DIVX:
 #ifdef __MMFILE_FFMPEG_V085__
@@ -155,11 +214,12 @@ HANDLING_DRM_DIVX:
                                debug_error("error: cannot open %s %d\n", formatContext->filesrc->file.path, ret);
                                goto exception;
                        }
+
                        formatContext->privateFormatData = pFormatCtx;
                }
        }
 
-       if (!pFormatCtx || !(pFormatCtx->nb_streams > 0)) {
+       if (!pFormatCtx/* || !(pFormatCtx->nb_streams > 0)*/) {
                debug_warning ("failed to find av stream. maybe corrupted data.\n");
                goto exception;
        }
@@ -172,13 +232,18 @@ HANDLING_DRM_DIVX:
        formatContext->audioTotalTrackNum = 0;
 
        for(i = 0; i < pFormatCtx->nb_streams; i++) {
-#ifdef __MMFILE_FFMPEG_V085__          
+#ifdef __MMFILE_FFMPEG_V085__
                if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
                        #ifdef __MMFILE_TEST_MODE__
                        debug_msg ("FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
                        #endif
-                       if (ConvertVideoCodecEnum(pFormatCtx->streams[i]->codec->codec_id) != MM_VIDEO_CODEC_NONE)
-                               formatContext->videoTotalTrackNum += 1;
+
+                       AVPacket pkt = pFormatCtx->streams[i]->attached_pic;
+                       if((pkt.data != NULL) && (pkt.size > 0))
+                               continue;
+
+                       //eventhough codec_id is 0, avformat_find_stream_info() can find proper codec_id.
+                       formatContext->videoTotalTrackNum += 1;
                }
                if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
                        #ifdef __MMFILE_TEST_MODE__
@@ -186,7 +251,7 @@ HANDLING_DRM_DIVX:
                        #endif
                        formatContext->audioTotalTrackNum += 1;
                }
-#else  
+#else
                if (pFormatCtx->streams[i]->codec->codec_type == AV_CODEC_TYPE_VIDEO) {
                        #ifdef __MMFILE_TEST_MODE__
                        debug_msg ("FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
@@ -221,6 +286,25 @@ exception: /* fail to get content information */
        return MMFILE_FORMAT_FAIL;
 }
 
+static bool __check_uhqa(int sample_rate,  enum AVSampleFormat sample_fmt_info)
+{
+       bool ret = FALSE;
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_error("[sample rate %d, sample format %d]", sample_rate, sample_fmt_info);
+#endif
+
+       if ((sample_rate >= 44100) && (sample_fmt_info >= AV_SAMPLE_FMT_S32)) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg("UHQA CONTENT");
+#endif
+               ret = TRUE;
+       } else {
+               ret = FALSE;
+       }
+
+       return ret;
+}
 
 EXPORT_API
 int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
@@ -239,13 +323,17 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
        }
 
        pFormatCtx = formatContext->privateFormatData;
+       pFormatCtx->start_time = -1;
 
        /**
         *@important if data is corrupted, occur segment fault by av_find_stream_info().
         *                      - fixed 2009-06-25.
         */
 #ifdef __MMFILE_FFMPEG_V100__
-       ret = avformat_find_stream_info (pFormatCtx, NULL);
+       if (formatContext->cdis != 1)
+               ret = avformat_find_stream_info (pFormatCtx, NULL);
+       else
+               ret = 0;
 #else
        ret = av_find_stream_info (pFormatCtx);
 #endif
@@ -272,10 +360,12 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
        formatContext->videoStreamId = -1;
        formatContext->audioStreamId = -1;
        formatContext->nbStreams = 0;
+       formatContext->videoTotalTrackNum = 0;
+       formatContext->audioTotalTrackNum = 0;
 
        int i = 0;
        for ( i = 0; i < pFormatCtx->nb_streams; i++ ) {
-#ifdef __MMFILE_FFMPEG_V085__          
+#ifdef __MMFILE_FFMPEG_V085__
                if ( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 #else
                if ( pFormatCtx->streams[i]->codec->codec_type == AV_CODEC_TYPE_VIDEO) {
@@ -291,6 +381,7 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
                                formatContext->streams[MMFILE_VIDEO_STREAM] = videoStream;
                                formatContext->nbStreams += 1;
                                formatContext->videoStreamId = i;
+                               formatContext->videoTotalTrackNum += 1;
 
                                pVideoCodecCtx = pFormatCtx->streams[i]->codec;
                                if (pVideoCodecCtx) {
@@ -313,6 +404,7 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
                                                                                                                                        pFormatCtx->streams[i]->duration,
                                                                                                                                        pFormatCtx->streams[i]->time_base,
                                                                                                                                        1);
+
                                        if (videoStream->framePerSec == 0) {
 #ifndef __MMFILE_LIBAV_VERSION__
                                                videoStream->framePerSec = av_q2d (pFormatCtx->streams[i]->r_frame_rate);
@@ -343,6 +435,7 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
                                formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
                                formatContext->nbStreams += 1;
                                formatContext->audioStreamId = i;
+                               formatContext->audioTotalTrackNum += 1;
 
                                pAudioCodecCtx = pFormatCtx->streams[i]->codec;
                                if (pAudioCodecCtx) {
@@ -350,6 +443,11 @@ int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
                                        audioStream->bitRate            = pAudioCodecCtx->bit_rate;
                                        audioStream->nbChannel          = pAudioCodecCtx->channels;
                                        audioStream->samplePerSec       = pAudioCodecCtx->sample_rate;
+                                       if (audioStream->codecId == MM_AUDIO_CODEC_FLAC)
+                                               audioStream->bitPerSample = pAudioCodecCtx->bits_per_raw_sample;
+                                       else
+                                               audioStream->bitPerSample = pAudioCodecCtx->bits_per_coded_sample;
+                                       audioStream->is_uhqa = __check_uhqa(audioStream->samplePerSec, pFormatCtx->streams[i]->codec->sample_fmt);
                                }
                        }
                }
@@ -495,6 +593,9 @@ int mmfile_format_read_tag_ffmpg (MMFileFormatContext *formatContext)
                                                } else if(!strcasecmp(tag->key, "date")) {
                                                        if (formatContext->year)        free (formatContext->year);
                                                        formatContext->year = mmfile_strdup (tag->value);
+                                               } else if(!strcasecmp(tag->key, "creation_time")) {
+                                                       if (formatContext->recDate)     free (formatContext->recDate);
+                                                       formatContext->recDate = mmfile_strdup (tag->value);
                                                } else if((!strcasecmp(tag->key, "track")) || (!strcasecmp(tag->key, "tracknumber"))) {
                                                        if (formatContext->tagTrackNum) free (formatContext->tagTrackNum);
                                                        formatContext->tagTrackNum = mmfile_strdup (tag->value);
@@ -544,13 +645,17 @@ int mmfile_format_read_tag_ffmpg (MMFileFormatContext *formatContext)
                                                                /* set art work data */
                                                                current_pos = mime_len  + description_len + (DATA_LENGTH * 8); /*current position is picture data */
                                                                if (formatContext->artwork) mmfile_free (formatContext->artwork);
+
                                                                formatContext->artwork = mmfile_malloc (data_len);
-                                                               memcpy(formatContext->artwork, meta_data + current_pos, data_len);
+                                                               if(formatContext->artwork != NULL)
+                                                                       memcpy(formatContext->artwork, meta_data + current_pos, data_len);
 
                                                                g_free(meta_data);
                                                        }
                                                } else {
+                                                       #ifdef __MMFILE_TEST_MODE__
                                                        debug_log("Not support metadata. [%s:%s]", tag->key, tag->value);
+                                                       #endif
                                                }
                                        }
                                }
@@ -638,6 +743,11 @@ int mmfile_format_read_frame_ffmpg  (MMFileFormatContext *formatContext, unsigne
                return MMFILE_FORMAT_FAIL;
        }
 
+       if (formatContext->isdrm == MM_FILE_DRM_PROTECTED) {
+               debug_error ("This is protected drm file\n");
+               return MMFILE_FORMAT_FAIL;
+       }
+
        pFormatCtx = formatContext->privateFormatData;
 
        if (formatContext->videoStreamId != -1) {
@@ -672,6 +782,11 @@ int mmfile_format_read_frame_ffmpg  (MMFileFormatContext *formatContext, unsigne
                /*set workaround bug flag*/
                pVideoCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
 #ifdef __MMFILE_FFMPEG_V100__
+               /* this is solution for PLM issue P13091703323 */
+               /* If using thread when decoding frame, the result of decoding is not always same.
+                   Thumbnail of video content is different with original file when copying file. */
+               pVideoCodecCtx->thread_type = 0;
+               pVideoCodecCtx->thread_count = 0;
                ret = avcodec_open2 (pVideoCodecCtx, pVideoCodec, NULL);
 #else
                ret = avcodec_open (pVideoCodecCtx, pVideoCodec);
@@ -691,7 +806,7 @@ int mmfile_format_read_frame_ffmpg  (MMFileFormatContext *formatContext, unsigne
 
                /* search & decode */
                // seek_ts = formatContext->duration > _SHORT_MEDIA_LIMIT ? seek_ts : 0;        /*if short media, seek first key frame*/
-               ret = _get_first_good_video_frame (pFormatCtx, pVideoCodecCtx, formatContext->videoStreamId, &pFrame);
+               ret = _get_first_good_video_frame (pFormatCtx, pVideoCodecCtx, formatContext->videoStreamId, &pFrame, formatContext->cdis);
                if ( ret != MMFILE_FORMAT_SUCCESS ) {
                        debug_error ("error: get key frame\n");
                        ret = MMFILE_FORMAT_FAIL;
@@ -915,7 +1030,7 @@ _get_video_fps (int frame_cnt, int duration, AVRational r_frame_rate, int is_rou
        double fps, round;
 
        #ifdef __MMFILE_TEST_MODE__
-       debug_msg ("frame count: %d, dur: %d, num: %d, den: %d\n", frame_cnt, duration, r_frame_rate.num, r_frame_rate.den)
+       debug_msg ("frame count: %d, dur: %d, num: %d, den: %d\n", frame_cnt, duration, r_frame_rate.num, r_frame_rate.den);
        #endif
 
        if (duration <= 0 || r_frame_rate.num <= 0 || r_frame_rate.den <= 0)
@@ -967,7 +1082,7 @@ static void _dump_av_packet (AVPacket *pkt)
 }
 #endif
 
-static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame)
+static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame, int cdis)
 {
        // AVStream *st = NULL;
        AVPacket pkt;
@@ -986,10 +1101,16 @@ static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecCont
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
        char pgm_name[256] = {0,};
 #endif
+       int key_search_limit = 0;
+       int frame_search_limit = 0;
 
-#define        _RETRY_SEARCH_LIMIT             150
+#define        _RETRY_SEARCH_LIMIT             75
 #define        _KEY_SEARCH_LIMIT               (_RETRY_SEARCH_LIMIT*2)         /*2 = 1 read. some frame need to read one more*/
-#define        _FRAME_SEARCH_LIMIT             1000
+#define        _FRAME_SEARCH_LIMIT             500
+
+#define        _RETRY_SEARCH_LIMIT_CDIS                10
+#define        _KEY_SEARCH_LIMIT_CDIS          (_RETRY_SEARCH_LIMIT*2)         /*2 = 1 read. some frame need to read one more*/
+#define        _FRAME_SEARCH_LIMIT_CDIS                10
 
        first_frame = avcodec_alloc_frame ();
        tmp_frame = avcodec_alloc_frame ();
@@ -1011,7 +1132,15 @@ static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecCont
        pCodecCtx->hurry_up = 1;
 #endif
 
-       for(i = 0, v = 0, key_detected = 0, frame = first_frame; i < _KEY_SEARCH_LIMIT && v < _FRAME_SEARCH_LIMIT;) {
+       if (cdis == 1) {
+               key_search_limit = _KEY_SEARCH_LIMIT_CDIS;
+               frame_search_limit = _FRAME_SEARCH_LIMIT_CDIS;
+       } else {
+               key_search_limit = _KEY_SEARCH_LIMIT;
+               frame_search_limit = _FRAME_SEARCH_LIMIT;
+       }
+
+       for(i = 0, v = 0, key_detected = 0, frame = first_frame; i < key_search_limit && v < frame_search_limit;) {
                av_init_packet (&pkt);
                got_picture = 0;
 
@@ -1070,7 +1199,9 @@ static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecCont
                                                                break;
                                                        } else {
                                                                /*reset video frame count & retry searching*/
+                                                               #ifdef __MMFILE_TEST_MODE__
                                                                debug_warning ("not good fame. retry scanning.\n");
+                                                               #endif
                                                                i = 0;
                                                                v = 0;
                                                                retry++;
@@ -1152,9 +1283,8 @@ static int ConvertVideoCodecEnum (int AVVideoCodecID)
                        ret_codecid = MM_VIDEO_CODEC_MPEG1;
                        break;
                case AV_CODEC_ID_MPEG2VIDEO:  ///< preferred ID for MPEG-1/2 video decoding
-                       ret_codecid = MM_VIDEO_CODEC_MPEG2;
-                       break;
                case AV_CODEC_ID_MPEG2VIDEO_XVMC:
+               case AV_CODEC_ID_MPEG2TS:
                        ret_codecid = MM_VIDEO_CODEC_MPEG2;
                        break;
                case AV_CODEC_ID_H261:
@@ -1220,8 +1350,15 @@ static int ConvertVideoCodecEnum (int AVVideoCodecID)
                        ret_codecid = MM_VIDEO_CODEC_AVS;
                        break;
                case AV_CODEC_ID_RL2:
+               case AV_CODEC_ID_RV10:  // RealVideo 1
+               case AV_CODEC_ID_RV20:  // RealVideo 2
+               case AV_CODEC_ID_RV30:  // RealVideo 3
+               case AV_CODEC_ID_RV40:  // RealVideo 4
                        ret_codecid = MM_VIDEO_CODEC_REAL;
                        break;
+               case AV_CODEC_ID_HEVC:
+                       ret_codecid = MM_VIDEO_CODEC_MPEG4;
+                       break;
                default:
                        ret_codecid = MM_VIDEO_CODEC_NONE;
                        break;
@@ -1242,8 +1379,9 @@ static int ConvertAudioCodecEnum (int AVAudioCodecID)
                        ret_codecid = MM_AUDIO_CODEC_AMR;
                        break;
                /* RealAudio codecs*/
-               case AV_CODEC_ID_RA_144:
-               case AV_CODEC_ID_RA_288:
+               case AV_CODEC_ID_RA_144:        // RealAudio 1
+               case AV_CODEC_ID_RA_288:        // RealAudio 2
+               case AV_CODEC_ID_COOK:          // RealAudio 6
                        ret_codecid = MM_AUDIO_CODEC_REAL;
                        break;
                case AV_CODEC_ID_MP2:
@@ -1284,6 +1422,12 @@ static int ConvertAudioCodecEnum (int AVAudioCodecID)
                case AV_CODEC_ID_EAC3:
                        ret_codecid = MM_AUDIO_CODEC_AC3;
                        break;
+               case AV_CODEC_ID_PCM_S8:
+               case AV_CODEC_ID_PCM_S16BE:
+               case AV_CODEC_ID_PCM_S24BE:
+               case AV_CODEC_ID_PCM_S32BE:
+                       ret_codecid = MM_AUDIO_CODEC_PCM;
+                       break;
                default:
                        ret_codecid = MM_AUDIO_CODEC_NONE;
                        break;
@@ -1294,80 +1438,94 @@ static int ConvertAudioCodecEnum (int AVAudioCodecID)
 
 
 
-static int getMimeType(int formatId, char *mimeType)
+static int getMimeType(int formatId, char *mimeType, int buf_size)
 {
        int ret = 0;    /*default: success*/
 
        switch(formatId) {
                case MM_FILE_FORMAT_3GP:
                case MM_FILE_FORMAT_MP4:
-                       sprintf(mimeType,"video/3gpp");
+                       snprintf(mimeType, buf_size, "video/3gpp");
                        break;
                case MM_FILE_FORMAT_ASF:
                case MM_FILE_FORMAT_WMA:
                case MM_FILE_FORMAT_WMV:
-                       sprintf(mimeType,"video/x-ms-asf");
+                       snprintf(mimeType, buf_size, "video/x-ms-asf");
                        break;
                case  MM_FILE_FORMAT_AVI:
-                       sprintf(mimeType,"video/avi");
+                       snprintf(mimeType, buf_size, "video/avi");
                        break;
                case MM_FILE_FORMAT_OGG:
-                       sprintf(mimeType,"video/ogg");
+                       snprintf(mimeType, buf_size, "video/ogg");
                        break;
                case MM_FILE_FORMAT_REAL:
-                       sprintf(mimeType,"video/vnd.rn-realvideo");
+                       snprintf(mimeType, buf_size, "video/vnd.rn-realmedia");
                        break;
                case MM_FILE_FORMAT_AMR:
-                       sprintf(mimeType,"audio/AMR");
+                       snprintf(mimeType, buf_size, "audio/AMR");
                        break;
                case MM_FILE_FORMAT_AAC:
-                       sprintf(mimeType,"audio/aac");
+                       snprintf(mimeType, buf_size, "audio/aac");
                        break;
                case MM_FILE_FORMAT_MP3:
-                       sprintf(mimeType,"audio/mp3");
+                       snprintf(mimeType, buf_size, "audio/mp3");
                        break;
                case MM_FILE_FORMAT_AIFF:
                case MM_FILE_FORMAT_WAV:
-                       sprintf(mimeType,"audio/wave");
+                       snprintf(mimeType, buf_size, "audio/wave");
                        break;
                case MM_FILE_FORMAT_MID:
-                       sprintf(mimeType,"audio/midi");
+                       snprintf(mimeType, buf_size, "audio/midi");
                        break;
                case MM_FILE_FORMAT_MMF:
-                       sprintf(mimeType,"audio/mmf");
+                       snprintf(mimeType, buf_size, "audio/mmf");
                        break;
                case MM_FILE_FORMAT_DIVX:
-                       sprintf(mimeType,"video/divx");
+                       snprintf(mimeType, buf_size, "video/divx");
                        break;
                case MM_FILE_FORMAT_IMELODY:
-                       sprintf(mimeType,"audio/iMelody");
+                       snprintf(mimeType, buf_size, "audio/iMelody");
                        break;
                case MM_FILE_FORMAT_JPG:
-                       sprintf(mimeType,"image/jpeg");
+                       snprintf(mimeType, buf_size, "image/jpeg");
                        break;
                case MM_FILE_FORMAT_AU:
-                       sprintf(mimeType,"audio/basic");
+                       snprintf(mimeType, buf_size, "audio/basic");
                        break;
                case MM_FILE_FORMAT_VOB:
-                       sprintf(mimeType,"video/mpeg");
+                       snprintf(mimeType, buf_size, "video/dvd");
                        break;
                case MM_FILE_FORMAT_FLV:
-                       sprintf(mimeType,"video/x-flv");
+                       snprintf(mimeType, buf_size, "video/x-flv");
                        break;
                case MM_FILE_FORMAT_QT:
-                       sprintf(mimeType,"video/quicktime");
+                       snprintf(mimeType, buf_size, "video/quicktime");
                        break;
                case MM_FILE_FORMAT_MATROSKA:
-                       sprintf(mimeType,"video/x-matroska");
+                       snprintf(mimeType, buf_size, "video/x-matroska");
                        break;
                case MM_FILE_FORMAT_FLAC:
-                       sprintf(mimeType,"audio/x-flac");
+                       snprintf(mimeType, buf_size, "audio/x-flac");
+                       break;
+               case MM_FILE_FORMAT_M2TS:
+                       snprintf(mimeType, buf_size, "video/MP2T");
+                       break;
+               case MM_FILE_FORMAT_M2PS:
+                       snprintf(mimeType, buf_size, "video/MP2P");
+                       break;
+               case MM_FILE_FORMAT_M1AUDIO:
+                       snprintf(mimeType, buf_size, "audio/x-mpegaudio");
+                       break;
+               case MM_FILE_FORMAT_M1VIDEO:
+                       snprintf(mimeType, buf_size, "video/mpeg");
                        break;
                default:
                        ret = -1;
        }
 
+#ifdef __MMFILE_TEST_MODE__
        debug_msg ("id: %d, mimetype: %s\n", formatId, mimeType);
+#endif
 
        return ret;
 }
diff --git a/formats/ffmpeg/mm_file_format_ffmpeg_drm.c b/formats/ffmpeg/mm_file_format_ffmpeg_drm.c
new file mode 100755 (executable)
index 0000000..07d7ad4
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * libmm-fileinfo
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Haejeong Kim <backto.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libavformat/avformat.h>
+#include <drm_client.h>
+#include <drm_trusted_client.h>
+#include "mm_file_utils.h"
+#include "mm_file_debug.h"
+
+typedef struct
+{
+    DRM_DECRYPT_HANDLE hfile;
+    long long offset;
+    long long fsize;
+} MMFileDRMHandle;
+
+static int mmfile_drm_open(URLContext *h, const char *pseudofilename, int flags)
+{
+       MMFileDRMHandle *drmHandle = NULL;
+       drm_bool_type_e res = DRM_TRUE;
+       drm_file_type_e file_type = DRM_TYPE_UNDEFINED;
+       drm_trusted_open_decrypt_info_s open_input_data;
+       drm_trusted_open_decrypt_resp_data_s open_output_data;
+       drm_trusted_seek_decrypt_info_s seek_input_data;
+       drm_trusted_tell_decrypt_resp_data_s tell_output_data;
+       drm_trusted_set_consumption_state_info_s state_input_data;
+       int ret = 0;
+
+       pseudofilename += strlen(h->prot->name) + 3; /* :// */
+
+       ret = drm_is_drm_file (pseudofilename, &res);
+       if (DRM_FALSE == res)
+       {
+               debug_error ("error: %s is not DRM file\n", pseudofilename);
+               return -2;
+       }
+       if(ret != DRM_RETURN_SUCCESS)
+       {
+               debug_error ("error: %s is not DRM file. ret[%x]\n", pseudofilename, ret);
+               return -2;
+       }
+
+       /* Checks the DRM file type (supports only for OMA) if it is DRM */
+       ret = drm_get_file_type(pseudofilename, &file_type);
+       if(ret != DRM_RETURN_SUCCESS)
+       {
+               debug_error ("error: %s is not DRM file. ret[%x]\n", pseudofilename, ret);
+               return -2;
+       }
+       if((file_type != DRM_TYPE_OMA_V1) && (file_type != DRM_TYPE_OMA_V2))
+       {
+               debug_error ("error: %s is not DRM file. file_type[%d]\n", pseudofilename, file_type);
+               return -2;
+       }
+
+       drmHandle = mmfile_malloc (sizeof(MMFileDRMHandle));
+       if (NULL == drmHandle)
+       {
+               debug_error ("error: mmfile_malloc\n");
+               return -2;
+       }
+
+       drmHandle->hfile = NULL;
+       drmHandle->offset = 0;
+
+       /* Open DRM File*/
+       memset(&open_input_data, 0x0, sizeof(drm_trusted_open_decrypt_info_s));
+       memset(&open_output_data, 0x0, sizeof(drm_trusted_open_decrypt_resp_data_s));
+
+       memcpy(open_input_data.filePath, pseudofilename, strlen(pseudofilename));
+       if(file_type == DRM_TYPE_OMA_V1)        open_input_data.file_type = DRM_TRUSTED_TYPE_OMA_V1;
+       else    open_input_data.file_type = DRM_TRUSTED_TYPE_OMA_V2;
+       open_input_data.permission = DRM_TRUSTED_PERMISSION_TYPE_DISPLAY;
+
+       ret = drm_trusted_open_decrypt_session(&open_input_data,&open_output_data, &drmHandle->hfile);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_open_decrypt_session() [%x]\n", ret);
+               ret = -2;
+               goto exception;
+       }
+
+       /* Seek End*/
+       memset(&seek_input_data, 0x0, sizeof(drm_trusted_seek_decrypt_info_s));
+       seek_input_data.offset = 0;
+       seek_input_data.seek_mode = DRM_SEEK_END; /* Set cursor to end */
+
+       ret = drm_trusted_seek_decrypt_session(drmHandle->hfile, &seek_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_seek_decrypt_session() [%x]\n", ret);
+               ret = -2;
+               goto exception;
+       }
+
+       /* Tell to get the file size */
+       memset(&tell_output_data, 0x0, sizeof(drm_trusted_tell_decrypt_resp_data_s));
+       ret = drm_trusted_tell_decrypt_session(drmHandle->hfile, &tell_output_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_tell_decrypt_session() [%x]\n", ret);
+               ret = -2;
+               goto exception;
+       }
+
+       drmHandle->fsize = tell_output_data.offset;
+
+       /* Seek Set*/
+       memset(&seek_input_data, 0x0, sizeof(drm_trusted_seek_decrypt_info_s));
+       seek_input_data.offset = 0;
+       seek_input_data.seek_mode = DRM_SEEK_SET;
+
+       ret = drm_trusted_seek_decrypt_session(drmHandle->hfile, &seek_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_seek_decrypt_session() [%x]\n", ret);
+               ret = -2;
+               goto exception;
+       }
+
+       h->priv_data = (void *) drmHandle;
+       h->is_streamed = 0; /*FALSE*/
+       h->max_packet_size = 0;
+
+       /* Set Consumption state*/
+       memset(&state_input_data,0x0,sizeof(drm_trusted_set_consumption_state_info_s));
+       state_input_data.state = DRM_CONSUMPTION_PREVIEW;
+       ret = drm_trusted_set_decrypt_state(drmHandle->hfile, &state_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_set_decrypt_state [%x]\n", ret);
+               ret = -2;
+               goto exception;
+       }
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg ("ffmpeg drm open success==============\n");
+#endif
+
+       return 0;
+
+exception:
+       if (drmHandle)
+       {
+               if (drmHandle->hfile)
+               {
+                       drm_trusted_close_decrypt_session(&drmHandle->hfile);
+               }
+
+               mmfile_free(drmHandle);
+               h->priv_data = NULL;
+       }
+       return ret;
+
+}
+
+static int mmfile_drm_read(URLContext *h, unsigned char *buf, int size)
+{
+       //unsigned int readSize = 0;
+       MMFileDRMHandle *drmHandle = h->priv_data;
+       drm_trusted_payload_info_s read_input_data;
+       drm_trusted_read_decrypt_resp_data_s read_output_data;
+       int ret = 0;
+
+       memset(&read_input_data,0x0,sizeof(drm_trusted_payload_info_s));
+       memset(&read_output_data,0x0,sizeof(drm_trusted_read_decrypt_resp_data_s));
+
+       read_input_data.payload_data = buf;
+       read_input_data.payload_data_len = (unsigned int)size;
+       read_input_data.payload_data_output = buf;
+
+       if (drmHandle)
+       {
+               ret = drm_trusted_read_decrypt_session(drmHandle->hfile, &read_input_data, &read_output_data);
+               if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+               {
+                       debug_error ("error: drm_trusted_read_decrypt_session() [%x]\n", ret);
+                       return -2;
+               }
+               drmHandle->offset += read_output_data.read_size;
+               return read_output_data.read_size;
+       }
+
+       return 0;
+}
+
+static int mmfile_drm_write(URLContext *h, const unsigned char *buf, int size)
+{
+    debug_warning ("Permission Deny: DRM writing\n");
+    return 0;
+}
+
+static long long mmfile_drm_seek(URLContext *h, long long pos, int whence)
+{
+       MMFileDRMHandle *drmHandle = h->priv_data;
+       drm_trusted_seek_mode_e drm_whence;
+       drm_trusted_seek_decrypt_info_s seek_input_data;
+       int ret = 0;
+
+       if (drmHandle) {
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg ("handle:%p, pos:%lld, whence:%d\n", h, pos, whence);
+               #endif
+
+               switch (whence) {
+                       case SEEK_SET:
+                               drm_whence = DRM_SEEK_SET;
+                               break;
+                       case SEEK_CUR:
+                               drm_whence = DRM_SEEK_CUR;
+                               break;
+                       case SEEK_END:
+                               drm_whence = DRM_SEEK_END;
+                               break;
+                       case AVSEEK_SIZE:       /*FFMPEG specific*/
+                               return drmHandle->fsize;
+                       default:
+                               debug_error ("invalid whence[%d]\n", whence);
+                               return -2;
+               }
+
+               memset(&seek_input_data, 0x0, sizeof(drm_trusted_seek_decrypt_info_s));
+               seek_input_data.offset = pos;
+               seek_input_data.seek_mode = drm_whence;
+
+               ret = drm_trusted_seek_decrypt_session(drmHandle->hfile, &seek_input_data);
+               if (ret != DRM_TRUSTED_RETURN_SUCCESS) {
+                       debug_error ("error: drm_trusted_seek_decrypt_session() [%x] [mode=%d]\n", ret, drm_whence);
+                       return -2;
+               }
+
+               switch (drm_whence) {
+                       case DRM_SEEK_SET: {
+                               drmHandle->offset = pos;
+                               break;
+                       }
+                       case DRM_SEEK_CUR: {
+                               drmHandle->offset += pos;
+                               break;
+                       }
+                       case DRM_SEEK_END: {
+                               drmHandle->offset = drmHandle->fsize + pos;
+                               break;
+                       }
+               }
+
+               if (drmHandle->offset > drmHandle->fsize) {
+                       return -1;
+               }
+
+               return drmHandle->offset;
+       }
+
+       return -1;
+}
+
+static int mmfile_drm_close(URLContext* h)
+{
+       MMFileDRMHandle *drmHandle = NULL;
+       drm_trusted_set_consumption_state_info_s state_input_data;
+       int ret = 0;
+
+       if (!h || !h->priv_data)
+       {
+               debug_error ("invalid para\n");
+               return MMFILE_UTIL_FAIL;
+       }
+
+       drmHandle = h->priv_data;
+
+       /* Set Consumption state*/
+       memset(&state_input_data,0x0,sizeof(drm_trusted_set_consumption_state_info_s));
+       state_input_data.state = DRM_CONSUMPTION_STOPPED;
+       ret = drm_trusted_set_decrypt_state(drmHandle->hfile, &state_input_data);
+       if(ret != DRM_TRUSTED_RETURN_SUCCESS) {
+               debug_error ("error: drm_trusted_set_decrypt_state() [%x]\n", ret);
+       } else {
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg ("Success : drm_trusted_set_decrypt_state\n");
+               #endif
+       }
+
+       if (drmHandle)
+       {
+               if (drmHandle->hfile)
+               {
+                       ret = drm_trusted_close_decrypt_session(&drmHandle->hfile);
+                       if(ret != DRM_TRUSTED_RETURN_SUCCESS) {
+                               debug_error ("error: drm_trusted_close_decrypt_session() [%x]\n", ret);
+                       } else {
+                               #ifdef __MMFILE_TEST_MODE__
+                               debug_msg ("Success : drm_trusted_close_decrypt_session\n");
+                               #endif
+                       }
+
+                       drmHandle->hfile = NULL;
+               }
+
+               mmfile_free (drmHandle);
+               h->priv_data = NULL;
+       }
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg ("ffmpeg drm close success==============\n");
+#endif
+
+       return 0;
+}
+
+URLProtocol MMFileDRMProtocol = {
+       .name                           = "drm",
+       .url_open                       = mmfile_drm_open,
+       .url_read                               = mmfile_drm_read,
+       .url_write                              = mmfile_drm_write,
+       .url_seek                               = mmfile_drm_seek,
+       .url_close                              = mmfile_drm_close,
+};
index eb28c73..a976c3d 100755 (executable)
 #include "mm_file_format_ffmpeg_mem.h"
 #include "mm_file_format_frame.h"
 
+#ifdef DRM_SUPPORT
+#include <drm_client.h>
+#endif
+
 #define MILLION 1000000
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
 static void __save_frame(AVFrame *pFrame, int width, int height, int iFrame);
@@ -55,80 +59,95 @@ void __save_frame(AVFrame *pFrame, int width, int height, int iFrame) {
 }
 #endif
 
-static int __getMimeType(int formatId, char *mimeType)
+static int __getMimeType(int formatId, char *mimeType, int buf_size)
 {
        int ret = 0;    /*default: success*/
 
        switch(formatId) {
                case MM_FILE_FORMAT_3GP:
                case MM_FILE_FORMAT_MP4:
-                       sprintf(mimeType,"video/3gpp");
+                       snprintf(mimeType, buf_size, "video/3gpp");
                        break;
                case MM_FILE_FORMAT_ASF:
                case MM_FILE_FORMAT_WMA:
                case MM_FILE_FORMAT_WMV:
-                       sprintf(mimeType,"video/x-ms-asf");
+                       snprintf(mimeType, buf_size, "video/x-ms-asf");
                        break;
                case  MM_FILE_FORMAT_AVI:
-                       sprintf(mimeType,"video/avi");
+                       snprintf(mimeType, buf_size, "video/avi");
                        break;
                case MM_FILE_FORMAT_OGG:
-                       sprintf(mimeType,"video/ogg");
+                       snprintf(mimeType, buf_size, "video/ogg");
                        break;
                case MM_FILE_FORMAT_REAL:
-                       sprintf(mimeType,"video/vnd.rn-realvideo");
+                       snprintf(mimeType, buf_size, "video/vnd.rn-realmedia");
                        break;
                case MM_FILE_FORMAT_AMR:
-                       sprintf(mimeType,"audio/AMR");
+                       snprintf(mimeType, buf_size, "audio/AMR");
                        break;
                case MM_FILE_FORMAT_AAC:
-                       sprintf(mimeType,"audio/aac");
+                       snprintf(mimeType, buf_size, "audio/aac");
                        break;
                case MM_FILE_FORMAT_MP3:
-                       sprintf(mimeType,"audio/mp3");
+                       snprintf(mimeType, buf_size, "audio/mp3");
                        break;
                case MM_FILE_FORMAT_AIFF:
                case MM_FILE_FORMAT_WAV:
-                       sprintf(mimeType,"audio/wave");
+                       snprintf(mimeType, buf_size, "audio/wave");
                        break;
                case MM_FILE_FORMAT_MID:
-                       sprintf(mimeType,"audio/midi");
+                       snprintf(mimeType, buf_size, "audio/midi");
                        break;
                case MM_FILE_FORMAT_MMF:
-                       sprintf(mimeType,"audio/mmf");
+                       snprintf(mimeType, buf_size, "audio/mmf");
                        break;
                case MM_FILE_FORMAT_DIVX:
-                       sprintf(mimeType,"video/divx");
+                       snprintf(mimeType, buf_size, "video/divx");
                        break;
                case MM_FILE_FORMAT_IMELODY:
-                       sprintf(mimeType,"audio/iMelody");
+                       snprintf(mimeType, buf_size, "audio/iMelody");
                        break;
                case MM_FILE_FORMAT_JPG:
-                       sprintf(mimeType,"image/jpeg");
+                       snprintf(mimeType, buf_size, "image/jpeg");
                        break;
                case MM_FILE_FORMAT_AU:
-                       sprintf(mimeType,"audio/basic");
+                       snprintf(mimeType, buf_size, "audio/basic");
                        break;
                case MM_FILE_FORMAT_VOB:
-                       sprintf(mimeType,"video/mpeg");
+                       snprintf(mimeType, buf_size, "video/dvd");
                        break;
                case MM_FILE_FORMAT_FLV:
-                       sprintf(mimeType,"video/x-flv");
+                       snprintf(mimeType, buf_size, "video/x-flv");
                        break;
                case MM_FILE_FORMAT_QT:
-                       sprintf(mimeType,"video/quicktime");
+                       snprintf(mimeType, buf_size, "video/quicktime");
                        break;
                case MM_FILE_FORMAT_MATROSKA:
-                       sprintf(mimeType,"video/x-matroska");
+                       snprintf(mimeType, buf_size, "video/x-matroska");
                        break;
                case MM_FILE_FORMAT_FLAC:
-                       sprintf(mimeType,"audio/x-flac");
+                       snprintf(mimeType, buf_size, "audio/x-flac");
+                       break;
+               case MM_FILE_FORMAT_M2TS:
+                       snprintf(mimeType, buf_size, "video/MP2T");
+                       break;
+               case MM_FILE_FORMAT_M2PS:
+                       snprintf(mimeType, buf_size, "video/MP2P");
+                       break;
+               case MM_FILE_FORMAT_M1VIDEO:
+                       snprintf(mimeType, buf_size, "video/mpeg");
+                       break;
+               case MM_FILE_FORMAT_M1AUDIO:
+                       snprintf(mimeType, buf_size, "audio/x-mpegaudio");
                        break;
                default:
                        ret = -1;
+                       break;
        }
 
+#ifdef __MMFILE_TEST_MODE__
        debug_msg ("id: %d, mimetype: %s\n", formatId, mimeType);
+#endif
 
        return ret;
 }
@@ -150,7 +169,9 @@ static int __get_fileformat(const char *urifilename, int *format)
        }
 
        for (index = 0; index < MM_FILE_FORMAT_NUM; index++) {
+               #ifdef __MMFILE_TEST_MODE__
                debug_msg ("search index = [%d]\n", index);
+               #endif
                switch (index) {
                        case MM_FILE_FORMAT_QT:
                        case MM_FILE_FORMAT_3GP:
@@ -197,6 +218,46 @@ static int __get_fileformat(const char *urifilename, int *format)
                                break;
                        }
 
+                       case MM_FILE_FORMAT_M2TS: {
+                               if (MMFileFormatIsValidMPEGTS(fp, NULL)) {
+                                       *format = MM_FILE_FORMAT_M2TS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M2PS: {
+                               if (MMFileFormatIsValidMPEGPS(fp, NULL)) {
+                                       *format = MM_FILE_FORMAT_M2PS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_REAL: {
+                               if (MMFileFormatIsValidREAL (fp, NULL)) {
+                                       *format = MM_FILE_FORMAT_REAL;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M1AUDIO: {
+                               if (MMFileFormatIsValidMPEGAUDIO (fp, NULL)) {
+                                       *format = MM_FILE_FORMAT_M1AUDIO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M1VIDEO: {
+                               if (MMFileFormatIsValidMPEGVIDEO (fp, NULL)) {
+                                       *format = MM_FILE_FORMAT_M1VIDEO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
                        /* this is not video file format */
                        case MM_FILE_FORMAT_OGG:
                        case MM_FILE_FORMAT_AMR:
@@ -210,7 +271,6 @@ static int __get_fileformat(const char *urifilename, int *format)
                                break;
                        /* not supported file */
                        case MM_FILE_FORMAT_NUT:
-                       case MM_FILE_FORMAT_REAL:
                        case MM_FILE_FORMAT_AIFF:
                        case MM_FILE_FORMAT_AU:
                        case MM_FILE_FORMAT_VOB:
@@ -249,9 +309,9 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
        int ret = MMFILE_FORMAT_SUCCESS;
        int videoStream = -1;
        int key_detected = 0;
-       int frameFinished = 0;
+       int got_picture = 0;
        double pos = timestamp;
-       bool find = false ;
+       bool find = false;
        bool first_seek = true;
        int64_t pts = 0;
        AVCodecContext *pVideoCodecCtx = NULL;
@@ -302,6 +362,8 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
 
        /* Open codec */
 #ifdef __MMFILE_FFMPEG_V100__
+       pVideoCodecCtx->thread_type = 0;
+       pVideoCodecCtx->thread_count = 0;
        if(avcodec_open2(pVideoCodecCtx, pVideoCodec, NULL) < 0) {
 #else
        if(avcodec_open(pVideoCodecCtx, pVideoCodec) < 0) {
@@ -365,7 +427,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
        av_init_packet(&packet);
 
        while(av_read_frame(pFormatCtx, &packet) >= 0) {
-               frameFinished = 0;
+               got_picture = 0;
 
                // Is this a packet from the video stream?
                if(packet.stream_index == videoStream) {
@@ -373,7 +435,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
                        debug_msg("find Video Stream+++++++[%2d]", idx++);
 #endif
                        /* Decode video frame*/
-                       len = avcodec_decode_video2(pVideoCodecCtx, pFrame, &frameFinished, &packet);
+                       len = avcodec_decode_video2(pVideoCodecCtx, pFrame, &got_picture, &packet);
                        if (len < 0) {
                                        debug_warning ("Error while decoding frame");
                        } else if ((packet.flags & AV_PKT_FLAG_KEY) || (key_detected == 1)) {
@@ -382,22 +444,24 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
 
                                if (first_seek || !is_accurate) {
                                        /* This is first seeking or not accurate mode.
-                                       Sometimes flag is AV_PKT_FLAG_KEY but frameFinished is NULL.
+                                       Sometimes flag is AV_PKT_FLAG_KEY but got_picture is NULL.
                                        first_seek is used when accurate mode and when time stamp's frame is not key frame.
                                        Go back to previousto Key frame and decode frame until time stamp's frame*/
 
-                                       if (frameFinished) {
+                                       if (got_picture) {
                                                if(pFrame->key_frame) {
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg("find Video Stream+++++++Find key frame");
                                                        #endif
-
-                                                       find = true;
                                                } else {
                                                #ifdef __MMFILE_TEST_MODE__
-                                                       debug_msg("find Video Stream+++++++skip (not key frame)");
+                                                       debug_msg("find Video Stream+++++++ not key frame");
                                                #endif
                                                }
+
+                                               /*eventhough decoded pFrame is not key frame, if packet.flags is AV_PKT_FLAG_KEY then can extract frame*/
+                                               find = true;
+
                                        } else {
                                                #ifdef __MMFILE_TEST_MODE__
                                                debug_msg("find Video Stream+++++++Find key but no frame");
@@ -406,19 +470,21 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
                                        }
                                }
                        } else {
-                               if (first_seek) {
-                                       pts = (packet.pts == AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
-                                       first_seek = false;
-
-                                       av_seek_frame(pFormatCtx, -1, pos, AVSEEK_FLAG_BACKWARD);
-                               } else {
-                                       tmpPts = (packet.pts == AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
-                                       if (pts == tmpPts)
-                                               find = true;
+                               if(is_accurate) {
+                                       if (first_seek) {
+                                               pts = (packet.pts == AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
+                                               first_seek = false;
+
+                                               av_seek_frame(pFormatCtx, -1, pos, AVSEEK_FLAG_BACKWARD);
+                                       } else {
+                                               tmpPts = (packet.pts == AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
+                                               if (pts == tmpPts)
+                                                       find = true;
+                                       }
                                }
                        }
 
-                       if(find && frameFinished) {
+                       if(find && got_picture) {
                                break;
                        }
                }
@@ -432,7 +498,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
        av_free_packet (&packet);
 
        /* Did we get a video frame?*/
-       if(frameFinished && find) {
+       if(got_picture && find) {
 
 #ifdef __MMFILE_TEST_MODE__
                debug_msg("Find Frame");
@@ -506,7 +572,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, double timestamp, boo
        }
        else
        {
-               debug_error("Not Found Proper Frame[%d][%d]", frameFinished, find);
+               debug_error("Not Found Proper Frame[%d][%d]", got_picture, find);
                ret = MMFILE_FORMAT_FAIL;
                goto exception;
        }
@@ -535,6 +601,16 @@ int mmfile_format_get_frame(const char* path, double timestamp, bool is_accurate
                return MMFILE_FORMAT_FAIL;
        }
 
+#ifdef DRM_SUPPORT
+       drm_bool_type_e res = DRM_FALSE;
+
+       ret = drm_is_drm_file (path, &res);
+       if (DRM_TRUE == res)
+       {
+               debug_error ("Not support DRM Contents\n");
+               return MMFILE_FORMAT_FAIL;
+       }
+#endif
        av_register_all();
 
        /* Open video file */
@@ -575,7 +651,7 @@ int mmfile_format_get_frame_from_memory(const void *data, unsigned int datasize,
 
        av_register_all();
 
-       sprintf (tempURIBuffer, "%s%u:%u", MMFILE_MEM_URI, (unsigned int)data, datasize);
+       snprintf (tempURIBuffer, MMFILE_URI_MAX_LEN,  "%s%u:%u", MMFILE_MEM_URI, (unsigned int)data, datasize);
        urifilename = mmfile_strdup (tempURIBuffer);
        if (!urifilename) {
                debug_error ("error: uri is NULL\n");
@@ -596,7 +672,7 @@ int mmfile_format_get_frame_from_memory(const void *data, unsigned int datasize,
        register_protocol (&MMFileMEMProtocol);
 #endif
 
-       if(__getMimeType(format,mimeType)< 0) {
+       if(__getMimeType(format, mimeType, MMFILE_MIMETYPE_MAX_LEN)< 0) {
                debug_error ("error: Error in MIME Type finding\n");
                return MMFILE_FORMAT_FAIL;
        }
index eda11f2..c78aa4a 100755 (executable)
@@ -162,10 +162,10 @@ int mmfile_format_read_stream_imy (MMFileFormatContext *formatContext)
                debug_error ("failed to convert.");
                goto exception;
        }
-       
+
        /*make uri*/
        memset (src2, 0x00, MMFILE_URI_MAX_LEN);
-       sprintf (src2, "%s%u:%u", MMFILE_MEM_URI, (unsigned int)midi, midi_size);
+       snprintf (src2, sizeof(src2), "%s%u:%u", MMFILE_MEM_URI, (unsigned int)midi, midi_size);
 
        /*get infomation*/
        info = mmfile_format_get_midi_infomation (src2);
@@ -416,29 +416,35 @@ static int __get_imelody_tag (const char *uriname, tMMFileImelodyTagInfo *tags)
             {
                 if (!strncmp (imy_key_buffer, "NAME", 4))
                 {
+                    if(tags->title != NULL)
+                                               mmfile_free(tags->title);
                     tags->title = mmfile_strdup (imy_value_buffer);
                 }
                 else if (!strncmp (imy_key_buffer, "COMPOSER", 8))
                 {
+                    if(tags->composer != NULL)
+                                               mmfile_free(tags->composer);
                     tags->composer = mmfile_strdup (imy_value_buffer);
                 }
                 else if (!strncmp (imy_key_buffer, "COPYRIGHT", 9))
                 {
+                    if(tags->copyright != NULL)
+                                               mmfile_free(tags->copyright);
                     tags->copyright = mmfile_strdup (imy_value_buffer);
                 }
-                                
+
                 memset (imy_key_buffer, 0x00, _MMFILE_IMY_KEY_BUFFER_LENGTH);
                 memset (imy_value_buffer, 0x00, _MMFILE_IMY_VALUE_BUFFER_LENGTH);
                 imy_key_buffer_index = 0;
                 imy_value_buffer_index = 0;
                 isDone = 0;
             }
-                        
+
             j++;
         }
-        
+
         memset (buffer, 0x00, _MMFILE_IMY_TAG_BUFFER_LENGTH);
-        
+
         i = i + j;
     }
 
@@ -722,6 +728,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case 'g': noteData[number].note = octaveValue + 8;
                                          break;
                        case 'a': noteData[number].note = octaveValue + 10;
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -739,6 +748,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case 'a': noteData[number].note = octaveValue + 8;
                                          break;
                        case 'b': noteData[number].note = octaveValue + 10;
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -759,6 +771,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case 'a': noteData[number].note = octaveValue + 9;
                                          break;
                        case 'b': noteData[number].note = octaveValue + 11;
+                                         break;
+                       default :
+                                         break;
                        }
                }
        }
@@ -790,6 +805,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                          break;
                        case '5': noteData[number].duration_on = 5;
                                          noteData[number].duration_off = 1;
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -815,6 +833,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                          break;
                        case '5': noteData[number].duration_on = 6;
                                          noteData[number].duration_off = 0;
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -839,6 +860,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                          break;
                        case '5': noteData[number].duration_on = 3;
                                          noteData[number].duration_off = 3;
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -855,6 +879,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                case '4': durationSpec[number] = 12;
                                  break;
                case '5': durationSpec[number] = 6;
+                                 break;
+               default :
+                                 break;
                }
 
                if(Melody[number].duration_specifier != '%')
@@ -866,6 +893,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case ':': noteData[number].duration_on += durationSpec[number];
                                          break;
                        case ';': noteData[number].duration_on -= (durationSpec[number] / 3);
+                                         break;
+                       default :
+                                         break;
                        }
 
                        if(noteData[number].duration_on > MIDI_MAX)
@@ -896,6 +926,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                          break;
                        case '5': noteData[number-1].duration_off += 6;
                                          restSpec[number] = 6;
+                                         break;
+                       default :
+                                         break;
                        }
 
                        if(noteData[number-1].duration_off > MIDI_MAX && Melody[number].rest_specifier == '%')
@@ -911,6 +944,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case ':': noteData[number-1].duration_off += restSpec[number];
                                          break;
                        case ';': noteData[number-1].duration_off -= (restSpec[number] / 3);
+                                         break;
+                       default :
+                                         break;
                        }
 
                        if(noteData[number-1].duration_off > MIDI_MAX)
@@ -939,8 +975,11 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                  break;
                case '5': midiData[50] += 6;
                                  restSpec[0] = 6;
+                                 break;
+               default :
+                                 break;
                }
-       
+
                if(Melody[0].rest_specifier != '%')
                {
                        switch(Melody[0].rest_specifier)
@@ -950,6 +989,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case ':': midiData[50] += restSpec[0];
                                          break;
                        case ';': midiData[50] -= (restSpec[0] / 3);
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -995,6 +1037,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                case '+': noteTotal[6*number+1] = noteTotal[6*(number-1)+1] + VOL_INTERVAL;
                                  break;
                case '-': noteTotal[6*number+1] = noteTotal[6*(number-1)+1] - VOL_INTERVAL;
+                                 break;
+               default :
+                                 break;
                }
 
                if(noteTotal[6*number+1] > MIDI_LIMIT)
@@ -1027,6 +1072,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                case '+': midiData[52+(6*noteCount+1)] = midiData[52+(6*(noteCount-1)+1)] + VOL_INTERVAL;
                                  break;
                case '-': midiData[52+(6*noteCount+1)] = midiData[52+(6*(noteCount-1)+1)] - VOL_INTERVAL;
+                                 break;
+               default :
+                                 break;
                }
 
                if(Melody[0].vol != '%')
@@ -1036,6 +1084,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case '+': midiData[52+(6*noteCount+1)] += VOL_INTERVAL;
                                          break;
                        case '-': midiData[52+(6*noteCount+1)] -= VOL_INTERVAL;
+                                         break;
+                       default :
+                                         break;
                        }
                }
 
@@ -1062,6 +1113,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                case '+': midiData[52+(6*noteCount+1)] = midiData[52+(6*(noteCount-1)+1)] + VOL_INTERVAL;
                                  break;
                case '-': midiData[52+(6*noteCount+1)] = midiData[52+(6*(noteCount-1)+1)] - VOL_INTERVAL;
+                                 break;
+               default :
+                                 break;
                }
 
                if(midiData[52+(6*noteCount+1)] > MIDI_LIMIT)
@@ -1180,13 +1234,13 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        }
                }
 
-               for(octaveCount = count;octaveCount < noteCount;octaveCount++)
+               for(octaveCount = count; octaveCount < noteCount && octaveCount < AV_MIDI_NOTE_MAX; octaveCount++)
                {
-               if(octave[octaveCount] == '%')
-                       octave[octaveCount] = octave[octaveCount-1];
+                       if(octave[octaveCount] == '%')
+                               octave[octaveCount] = octave[octaveCount-1];
                }
-       
-               for(number = count;number < noteCount;number++)
+
+               for(number = count; number < noteCount && number < AV_MIDI_NOTE_MAX; number++)
                {
                        octaveValue = octave[number] - '0';
 
@@ -1205,6 +1259,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                case 'g': noteData[number].note = octaveValue + 8;
                                                  break;
                                case 'a': noteData[number].note = octaveValue + 10;
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
 
@@ -1222,6 +1279,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                case 'a': noteData[number].note = octaveValue + 8;
                                                  break;
                                case 'b': noteData[number].note = octaveValue + 10;
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
 
@@ -1242,6 +1302,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                case 'a': noteData[number].note = octaveValue + 9;
                                                  break;
                                case 'b': noteData[number].note = octaveValue + 11;
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
 
@@ -1267,6 +1330,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                                  break;
                                case '5': noteData[number].duration_on = 5;
                                                  noteData[number].duration_off = 1;
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
 
@@ -1292,6 +1358,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                                  break;
                                case '5': noteData[number].duration_on = 6;
                                                  noteData[number].duration_off = 0;
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
 
@@ -1316,9 +1385,12 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                                  break;
                                case '5': noteData[number].duration_on = 3;
                                                  noteData[number].duration_off = 3;
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
-               
+
                        switch(Melody[number].duration)
                        {
                        case '0': durationSpec[number] = 192;
@@ -1332,6 +1404,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case '4': durationSpec[number] = 12;
                                          break;
                        case '5': durationSpec[number] = 6;
+                                         break;
+                       default :
+                                         break;
                        }
 
                        if(Melody[number].duration_specifier != '%')
@@ -1343,6 +1418,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                case ':': noteData[number].duration_on += durationSpec[number];
                                                  break;
                                case ';': noteData[number].duration_on -= (durationSpec[number] / 3);
+                                                 break;
+                               default :
+                                                 break;
                                }
 
                        if(noteData[number].duration_on > MIDI_MAX)
@@ -1350,7 +1428,7 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        }
                }
 
-               for(number = count + 1;number < noteCount;number++)
+               for(number = count + 1; number < noteCount && number < AV_MIDI_NOTE_MAX; number++)
                {
                        if(Melody[number].rest >= '0' && Melody[number].rest <= '5')
                        {
@@ -1373,6 +1451,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                                  break;
                                case '5': noteData[number-1].duration_off += 6;
                                                  restSpec[number] = 6;
+                                                 break;
+                               default :
+                                                 break;
                                }
 
                        if(noteData[number-1].duration_off > MIDI_MAX && Melody[number].rest_specifier == '%')
@@ -1388,6 +1469,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                case ':': noteData[number-1].duration_off += restSpec[number];
                                                  break;
                                case ';': noteData[number-1].duration_off -= (restSpec[number] / 3);
+                                                 break;
+                               default :
+                                                 break;
                                }
 
                                if(noteData[number-1].duration_off > MIDI_MAX)
@@ -1416,6 +1500,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                          break;
                        case '5': midiData[52+(6*count*(repeat+1)-1)] += 6;
                                          restSpec[count] = 6;
+                                         break;
+                       default :
+                                         break;
                        }
 
                        if(Melody[count].rest_specifier != '%')
@@ -1427,6 +1514,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                                case ':': midiData[52+(6*count*(repeat+1)-1)] += restSpec[count];
                                                  break;
                                case ';': midiData[52+(6*count*(repeat+1)-1)] -= (restSpec[count] / 3);
+                                                 break;
+                               default :
+                                                 break;
                                }
                        }
 
@@ -1478,6 +1568,9 @@ __AvConvertIMelody2MIDI(char* pMelodyBuf, unsigned int* pBufLen)
                        case '+': noteTotal[6*number+1] = noteTotal[6*(number-1)+1] + VOL_INTERVAL;
                                          break;
                        case '-': noteTotal[6*number+1] = noteTotal[6*(number-1)+1] - VOL_INTERVAL;
+                                         break;
+                       default :
+                                         break;
                        }
 
                        if(noteTotal[6*number+1] > MIDI_LIMIT)
@@ -1569,9 +1662,10 @@ __AvMIDISetVolume(char* pMelodyBuf)
                        case '5': midiVol = AV_MIDI_VOL_MAX;
                                          break;
                        default : midiVol = AV_MIDI_VOL_MAX;
+                                         break;
                        }
                }
-               
+
                else
                switch(*pMelodyBuf)
                {
@@ -1594,6 +1688,7 @@ __AvMIDISetVolume(char* pMelodyBuf)
                case '9': midiVol = AV_MIDI_VOL_MAX;
                                  break;
                default : midiVol = AV_MIDI_VOL_MAX;
+                                 break;
                }
        }
 
index f919fb3..8c6d345 100755 (executable)
@@ -532,7 +532,7 @@ __AvGetMidiDuration(char* szFileName, MIDI_INFO_SIMPLE *info)
        if ( szFileName == NULL ||  info == NULL)
                return -1;
 
-       // printf ("URI: %s\n", szFileName);
+       // debug_msg ("URI: %s\n", szFileName);
        /*open*/
        ret = mmfile_open (&hFile, szFileName, MMFILE_RDONLY);
        if (ret == MMFILE_UTIL_FAIL) {
@@ -823,7 +823,7 @@ __AvMidGetTrackTime(PMIDINFO pI, UINT32 dTrack)
                dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
                dTime = (dTime << 7) + (dTemp & 0x7f);
        } while (dTemp >= 0x80);
-       //printf("dTime is %d\n", dTime);
+       //debug_msg("dTime is %d\n", dTime);
        pMt->sdTicks += dTime;
 
        return (0);
@@ -1152,21 +1152,23 @@ __AvGetSizeOfFileInfo(PMIDINFO pI)
                        case 0xD0:      /* Channel pressure */
                                pMt->dOffset++;
                                break;
-                       
+
                        case 0xB0:      /* Control Change */
                                switch (pMt->pbBase[pMt->dOffset])
                                {
                                case 0x00:      /* Bank select(MSB) */
                                        dBank[dCh] = (dBank[dCh] & 0x00FF) | (pMt->pbBase[pMt->dOffset + 1] << 8);
                                        break;
-    
+
                        case 0x20:      /* Bank select (LSB) */
                                        dBank[dCh] = (dBank[dCh] & 0xFF00) | pMt->pbBase[pMt->dOffset + 1];
                                        break;
+                               default :
+                                       break;
                                }
                                pMt->dOffset += 2;
                                break;
-                       
+
                        default:
                                pMt->dOffset += 2;
                        }
@@ -1260,7 +1262,7 @@ __AvGetSizeOfFileInfo(PMIDINFO pI)
                                        }
                                        break;
 
-                               case 0x03:      /* Title */
+                               case 0x06:      /* Title */
                                        if (pI->pbTitle == NULL)
                                        {
                                                pI->pbTitle = &pMt->pbBase[pMt->dOffset];
@@ -1277,37 +1279,41 @@ __AvGetSizeOfFileInfo(PMIDINFO pI)
                                        {
                                        case 3:
                                        case 4:
-                                               dTime = ((UINT32)pMt->pbBase[pMt->dOffset] << 16) + 
+                                               dTime = ((UINT32)pMt->pbBase[pMt->dOffset] << 16) +
                                                        ((UINT32)pMt->pbBase[pMt->dOffset + 1] << 8) +
                                                         (UINT32)pMt->pbBase[pMt->dOffset + 2];
                                                if ((sdTotalTicks == 0) && (dTime == 250000)) dSetup |= 0x02;
                                                if (sdTotalTicks == (UINT32)pI->dTimeResolution) dSetup |= 0x08;
-                       
+
                                                /*<== I Think that Below Code is Trash!! and Erase it! (Actually I Don Know ^^)
                                                dTime = (dTime << 7) / 125; */
-                                               
+
                                                sdDelta = (UINT32)(dTime / pI->dTimeResolution);
                                        }
                                        break;
-                                       
+
                                case 0x58:              /* Set TimeSignature */
-                                       if ((sdTotalTicks == 0) && 
+                                       if ((sdTotalTicks == 0) &&
                                            (pMt->pbBase[pMt->dOffset] == 1) &&
                                            (pMt->pbBase[pMt->dOffset + 1] == 2)) dSetup |= 0x01;
                                        break;
+                               default :
+                                       break;
                                }
                                pMt->dOffset += dSize;
                                break;
+                       default :
+                               break;
                        }
                }
-               
+
                if((UINT32)sdTr >= MAX_SMF_TRACKS)
                {
                        debug_error ("__AvGetSizeOfFileInfo:  Num of tracks is over MAX track number. !!\n");
                        return AvSMW_ERROR_SMF_CMD;
                }
                __AvMidUpdateTrackTime(pI, (UINT32)sdTr);
-               
+
                if (dSetup == 0x0F)
                {
                        dSetup |= 0x10;
@@ -1340,7 +1346,7 @@ __AvGetSizeOfFileInfo(PMIDINFO pI)
        }
        if ((pI->sdDataEndTime >> 10) <= MINIMUM_LENGTH) return (AvSMW_ERROR_SHORT_LENGTH);
 
-       // printf("__AvGetSizeOfFileInfo/Done\n");
+       // debug_msg("__AvGetSizeOfFileInfo/Done\n");
 
        return pI->sdDataEndTime;
 }
@@ -1368,7 +1374,7 @@ __AvCheckSizeOfMidFile(UINT8* src_fp, UINT32 dFsize)
        UINT32  dNumOfTracks;
        UINT32  i;
        UINT8 *fp = src_fp;
-       // printf ("input param: %p, %d\n", fp , dFsize);
+       // debug_msg ("input param: %p, %d\n", fp , dFsize);
        while (dFsize >= 22)
        {
                dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
@@ -1377,10 +1383,10 @@ __AvCheckSizeOfMidFile(UINT8* src_fp, UINT32 dFsize)
                fp ++;
                dFsize --;
        }
-       
-       // printf("__AvCheckSizeOfMidFile(): MThd Position is dFsize(%d)\n", dFsize);
-       
-       if (dFsize < 22) 
+
+       // debug_msg("__AvCheckSizeOfMidFile(): MThd Position is dFsize(%d)\n", dFsize);
+
+       if (dFsize < 22)
        {
                debug_error ("__AvCheckSizeOfMidFile Error / Too small size\n");
                return (AvSMW_ERROR_FILE);
@@ -1511,8 +1517,8 @@ __AvParseSkipXmf2Mid(UINT8* pbFile, UINT32 dFSize)
                }
        }
 
-       // printf("__AvParseSkipForXMF : skip value(%d)\n", skipVal);
-       
+       // debug_msg("__AvParseSkipForXMF : skip value(%d)\n", skipVal);
+
        return skipVal;
 }
 
index e5ed1ae..ab15333 100755 (executable)
@@ -969,6 +969,8 @@ _mmf_MTRCheck(PTRACKINFO psTrack, unsigned char     bSmafType)
                        return AV_MMF_ERR_CHUNK;
                }
                break;
+       default :
+               break;
        }
 
 /* Check Sequence Type         */
@@ -2491,6 +2493,8 @@ _mmf_GetHvData(PLOADINFO psLoad, unsigned char bCType)
                        pbScript        = &(pbHvData[dIndex]);
                        dScriptSize     = (unsigned int)sdChunkSize;
                        break;
+               default :
+                       break;
                }
                dIndex  += sdChunkSize;
        }
@@ -2720,7 +2724,9 @@ _mmf_MALoad(      unsigned char* pbFile, unsigned int dFSize)
 /* check playback time                 */
        if (sdResult != AV_MMF_FUNC_SUCCESS)            return sdResult;
 
+       #ifdef __MMFILE_TEST_MODE__
        debug_msg ( "SUM %ld\n", psLoad_Info->dPlayTime * psLoad_Info->dTimeBase);
+       #endif
 
        if ((psLoad_Info->dPlayTime * psLoad_Info->dTimeBase) <= AV_MMF_PLAY_TIME_MIN)
        {
@@ -2810,7 +2816,7 @@ _mmf_ParseSkipXmf2Mmf(unsigned char* pbFile, unsigned int dFSize)
                memcpy(cmpXmfCMMD, pbFile, 4);
        else
        {
-               debug_msg ( "NULL pointer!\n");
+               debug_error ( "NULL pointer!\n");
                return -1;
        }
 
@@ -2822,7 +2828,9 @@ _mmf_ParseSkipXmf2Mmf(unsigned char* pbFile, unsigned int dFSize)
                {
                        if (pbFile[skipVal] == 'M' && pbFile[skipVal+1] == 'M' && pbFile[skipVal+2] == 'M' && pbFile[skipVal+3] == 'D')
                        {
+                               #ifdef __MMFILE_TEST_MODE__
                                debug_msg ( "MMMD Header found!\n");
+                               #endif
                                break;
                        }
                        else
@@ -2830,7 +2838,9 @@ _mmf_ParseSkipXmf2Mmf(unsigned char* pbFile, unsigned int dFSize)
                                skipVal++;
                                if (skipVal >= sizeOfpbFile)
                                {
+                                       #ifdef __MMFILE_TEST_MODE__
                                        debug_msg ( "MMMD Header is not found!\n");
+                                       #endif
                                        return -1;
                                }
                        }
@@ -2838,9 +2848,15 @@ _mmf_ParseSkipXmf2Mmf(unsigned char* pbFile, unsigned int dFSize)
                }
        }
        else
+       {
+               #ifdef __MMFILE_TEST_MODE__
                debug_msg ( "File header is not started CMMD\n");
+               #endif
+       }
 
+       #ifdef __MMFILE_TEST_MODE__
        debug_msg ( "skip value: %d\n", skipVal);
+       #endif
 
        return skipVal;
 }
@@ -2862,11 +2878,13 @@ mmf_file_mmf_get_duration (char *src, int is_xmf)
        /*total time (millisecond)*/
        int     ret_msec = 0;
 
-       debug_msg ( "\n");
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        /*open*/
        ret = mmfile_open (&fp, src, MMFILE_RDONLY);
-       if (ret == MMFILE_UTIL_FAIL) 
+       if (ret == MMFILE_UTIL_FAIL)
      {
                debug_error ( "open failed.\n");
                return -1;
@@ -2878,7 +2896,7 @@ mmf_file_mmf_get_duration (char *src, int is_xmf)
        mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
 
        if (src_size <= 0) {
-               debug_msg ( "failed to get file size.\n");
+               debug_error ( "failed to get file size.\n");
                ret_msec = -1;
                goto _RELEASE_RESOURCE;
        }
index f8c35d8..b3c65d3 100755 (executable)
@@ -88,7 +88,9 @@ int mmfile_format_open_mp3 (MMFileFormatContext *formatContext)
     AvFileContentInfo *privateData = NULL;;
     int ret = 0;
 
+#ifdef __MMFILE_TEST_MODE__
        debug_fenter();
+#endif
 
     if (NULL == formatContext)
     {
@@ -105,6 +107,7 @@ int mmfile_format_open_mp3 (MMFileFormatContext *formatContext)
                }
        }
 
+
     formatContext->ReadStream   = mmfile_format_read_stream_mp3;
     formatContext->ReadFrame    = mmfile_format_read_frame_mp3;
     formatContext->ReadTag      = mmfile_format_read_tag_mp3;
@@ -128,12 +131,12 @@ int mmfile_format_open_mp3 (MMFileFormatContext *formatContext)
         debug_error ("error: mmfile_format_read_stream_mp3\n");
         goto exception;
     }
-   
+
     return MMFILE_FORMAT_SUCCESS;
-    
+
 exception:
     mmfile_format_close_mp3 (formatContext);
-    return MMFILE_FORMAT_FAIL;    
+    return MMFILE_FORMAT_FAIL;
 }
 
 
@@ -141,7 +144,10 @@ EXPORT_API
 int mmfile_format_read_stream_mp3 (MMFileFormatContext *formatContext)
 {
     AvFileContentInfo *privateData = NULL;
+
+#ifdef __MMFILE_TEST_MODE__
        debug_fenter();
+#endif
 
     if (!formatContext || !formatContext->privateFormatData)
     {
@@ -170,22 +176,25 @@ int mmfile_format_read_stream_mp3 (MMFileFormatContext *formatContext)
     formatContext->streams[MMFILE_AUDIO_STREAM]->height = 0;
     formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = privateData->channels;
     formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = privateData->sampleRate;
-    
-    return MMFILE_FORMAT_SUCCESS;  
+
+    return MMFILE_FORMAT_SUCCESS;
 }
 
 
 EXPORT_API
 int mmfile_format_read_frame_mp3  (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
 {
-    return MMFILE_FORMAT_SUCCESS;    
+    return MMFILE_FORMAT_SUCCESS;
 }
 
 EXPORT_API
 int mmfile_format_read_tag_mp3    (MMFileFormatContext *formatContext)
 {
     AvFileContentInfo *privateData = NULL;
+
+#ifdef __MMFILE_TEST_MODE__
        debug_fenter();
+#endif
 
     if (!formatContext || !formatContext->privateFormatData)
     {
@@ -223,7 +232,9 @@ int mmfile_format_read_tag_mp3    (MMFileFormatContext *formatContext)
                        if (strlen(privateData->imageInfo.imageMIMEType) > 0)
                                formatContext->artworkMime= mmfile_strdup(privateData->imageInfo.imageMIMEType);
                        else if(strlen(privateData->imageInfo.imageExt) > 0) {
+                               #ifdef __MMFILE_TEST_MODE__
                                debug_msg("ID3 tag V2 File");
+                               #endif
                                formatContext->artworkMime= mmfile_strdup(privateData->imageInfo.imageExt);
                        }
                        else {
@@ -1155,20 +1166,20 @@ static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo
 {
        MMFileIOHandle  *hFile;
        unsigned char   header[256];
-       unsigned long   numOfFrames=0;
        unsigned long   frameSamples=0;
-       unsigned char   *buf = NULL;    
+       unsigned char   *buf = NULL;
        unsigned char*  v2TagExistCheck = NULL;
-       unsigned int            tempNumFrames = 0;
        int     readAmount = 0, readedDataLen = 0;
-       unsigned long long      tempduration = 0;
        unsigned char   TagBuff[MP3TAGINFO_SIZE + TAGV1_SEEK_GAP];
        unsigned char           TagV1ID[4] = { 0x54, 0x41, 0x47}; //TAG
        int             tagHeaderPos = 0;
        int ret = 0;
        unsigned int head_offset = 0;
+
+#ifdef __MMFILE_TEST_MODE__
        debug_fenter();
-       
+#endif
+
        if (pInfo == NULL || filename == NULL)
                return -1;
 
@@ -1382,22 +1393,44 @@ static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo
        if (mmfile_read (hFile, TagBuff, MP3TAGINFO_SIZE + TAGV1_SEEK_GAP) <= 0)
                goto EXCEPTION;
 
-       if ((tagHeaderPos = __AvMemstr(TagBuff, TagV1ID, 3, TAGV1_SEEK_GAP+5)) >= 0)
-       {
-               #ifdef __MMFILE_TEST_MODE__
-               debug_msg ( "Mp3 File Tag is existing\n");
-               #endif
+               if ((tagHeaderPos = __AvMemstr(TagBuff, TagV1ID, 3, TAGV1_SEEK_GAP+5)) >= 0)
+               {
+                       #ifdef __MMFILE_TEST_MODE__
+                       debug_msg ( "Mp3 File Tag is existing\n");
+                       #endif
 
-               pInfo ->bV1tagFound = true;
-               memcpy(TagBuff, (TagBuff + tagHeaderPos), MP3TAGINFO_SIZE);
+                       pInfo ->bV1tagFound = true;
+                       /* In this case, V2 Tag alreay exist So, ignore V1 tag  */
+                       if (pInfo->tagV2Info.tagLen == 0) {
+                               memcpy(TagBuff, (TagBuff + tagHeaderPos), MP3TAGINFO_SIZE);
+                               if(!mm_file_id3tag_parse_v110(pInfo, TagBuff))
+                                       goto EXCEPTION;
+                       }
+               }
 
-               if(!mm_file_id3tag_parse_v110(pInfo, TagBuff))
-                       goto EXCEPTION;
+       mm_file_id3tag_restore_content_info (pInfo);
+
+       if(pInfo->mpegVersion== 1)
+       {
+               if(pInfo->layer== 1)
+                       frameSamples = MPEG_1_SIZE_LAYER_1;
+               else
+                       frameSamples = MPEG_1_SIZE_LAYER_2_3;
+       }
+       else
+       {
+               if(pInfo->layer == 1)
+                       frameSamples = MPEG_2_SIZE_LAYER_1;
+               else
+                       frameSamples = MPEG_2_SIZE_LAYER_2_3;
        }
 
-       mm_file_id3tag_restore_content_info (pInfo);
+#if 0
+       unsigned long   numOfFrames=0;
+       unsigned long long      tempduration = 0;
+       unsigned int            tempNumFrames = 0;
 
-       if(pInfo->bVbr) 
+       if(pInfo->bVbr)
                numOfFrames = pInfo->frameNum*10;
        else
        {
@@ -1406,33 +1439,33 @@ static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo
        }
        tempNumFrames = (unsigned int)(numOfFrames/10);
 
-       
-
        if((numOfFrames - tempNumFrames * 10 ) > 5)
                numOfFrames = (numOfFrames/10) + 1;
        else
                numOfFrames = numOfFrames/10;
 
-       
+
 
        tempduration = (unsigned long long)(numOfFrames *1000);
-       
-       if(pInfo->mpegVersion== 1) 
+
+       if(pInfo->mpegVersion== 1)
        {
-               if(pInfo->layer== 1) 
+               if(pInfo->layer== 1)
                        frameSamples = MPEG_1_SIZE_LAYER_1;
-               else 
+               else
                        frameSamples = MPEG_1_SIZE_LAYER_2_3;
        }
-       else 
+       else
        {
-               if(pInfo->layer == 1) 
+               if(pInfo->layer == 1)
                        frameSamples = MPEG_2_SIZE_LAYER_1;
-               else 
+               else
                        frameSamples = MPEG_2_SIZE_LAYER_2_3;
        }
 
+#ifdef __MMFILE_TEST_MODE__
        debug_msg("frameSamples : %d, tempduration : %ld", frameSamples, tempduration);
+#endif
 
        if(tempduration < (unsigned long long)pInfo->sampleRate)
        {
@@ -1443,9 +1476,21 @@ static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo
                tempduration = (tempduration*frameSamples)/pInfo->sampleRate;
 
        pInfo->duration = tempduration;
+#else
+       if(pInfo->bVbr) {
+               pInfo->duration =  ((double)(frameSamples * 1000) / pInfo->sampleRate) * pInfo->frameNum;
+               debug_msg("duration for VBR : %lld", pInfo->duration);
+       } else {
+               unsigned long long frame_duration = (((unsigned long long)frameSamples * 1000000000) / pInfo->sampleRate / 1000);
+               int file_size_except_header = pInfo->fileLen - (pInfo->headerPos + (pInfo->bV1tagFound ? MP3TAGINFO_SIZE : 0));
+               pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * frame_duration / 1000;
+               //pInfo->duration = ((double)file_size_except_header / (double)pInfo->frameSize) * (frameSamples * 1000 / pInfo->sampleRate);
+               debug_msg("duration from new algorithm : %lld", pInfo->duration);
+       }
+#endif
 
        mmfile_close(hFile);
-       
+
        /*debug print*/
        #ifdef __MMFILE_TEST_MODE__
        debug_msg ( "Mp3 File pInfo->duration (%lld) \n", pInfo->duration);
@@ -1461,6 +1506,7 @@ static int mmf_file_mp3_get_infomation (char *filename, AvFileContentInfo* pInfo
        debug_msg ( "Title       : %s\n", pInfo->pTitle);
        debug_msg ( "Artist      : %s\n", pInfo->pArtist);
        debug_msg ( "Album       : %s\n", pInfo->pAlbum);
+       debug_msg ( "Album_Artist: %s\n", pInfo->pAlbum_Artist);
        debug_msg ( "Year        : %s\n", pInfo->pYear);
        debug_msg ( "Comment     : %s\n", pInfo->pComment);
        debug_msg ( "TrackNum    : %s\n", pInfo->pTrackNum);
index 8d6cdfe..0e045c6 100755 (executable)
@@ -222,17 +222,38 @@ int mmfile_format_open_wav (MMFileFormatContext *formatContext)
        return MMFILE_FORMAT_SUCCESS;
 }
 
+static bool __check_uhqa(int sample_rate,  short bits_per_sample)
+{
+       bool ret = FALSE;
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_error("[sample rate %d, sample format %d]", sample_rate, bits_per_sample);
+#endif
+
+       if ((sample_rate >= 44100) && (bits_per_sample >= 24)) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg("UHQA CONTENT");
+#endif
+               ret = TRUE;
+       } else {
+               ret = FALSE;
+       }
+
+       return ret;
+}
 
 EXPORT_API
 int mmfile_format_read_stream_wav (MMFileFormatContext *formatContext)
 {
        unsigned char *header = NULL;
        MM_FILE_WAVE_INFO *waveinfo = NULL;
+       long long     filesize = 0;
+       MMFileIOHandle *fp = NULL;
        int ret = 0;
 
        if (formatContext == NULL) {
                debug_error("formatContext is NULL\n");
-               return MMFILE_FORMAT_FAIL;    
+               return MMFILE_FORMAT_FAIL;
        }
 
        header = mmf_file_wave_get_header (formatContext->uriFileName);
@@ -255,16 +276,31 @@ int mmfile_format_read_stream_wav (MMFileFormatContext *formatContext)
 
        mmfile_free (header);
 
+        /* Get file size. because sometimes waveinfo->size is wrong */
+       ret = mmfile_open (&fp, formatContext->uriFileName, MMFILE_RDONLY);
+       if(fp) {
+               mmfile_seek (fp, 0, MMFILE_SEEK_END);
+               filesize = mmfile_tell(fp);
+               mmfile_seek (fp, 0, MMFILE_SEEK_SET);
+               mmfile_close (fp);
+       }
+
        formatContext->privateFormatData = waveinfo;
 
-       formatContext->duration = (int)(((float)(waveinfo->size) / (float)(waveinfo->byte_rate)) * 1000.0F);
+       if(waveinfo->size > filesize) {
+               /*Wrong information*/
+               formatContext->duration = (int)((((float)filesize - MMF_FILE_WAVE_HEADER_LEN) / (float)(waveinfo->byte_rate)) * 1000.0F);
+       } else {
+               formatContext->duration = (int)(((float)(waveinfo->size) / (float)(waveinfo->byte_rate)) * 1000.0F);
+       }
+
        formatContext->audioTotalTrackNum = 1;
        formatContext->nbStreams = 1;
        formatContext->streams[MMFILE_AUDIO_STREAM] = mmfile_malloc (sizeof(MMFileFormatStream));
 
        if (!formatContext->streams[MMFILE_AUDIO_STREAM]) {
                debug_error("error: mmfile_malloc audio stream for wav\n");
-               return MMFILE_FORMAT_FAIL;        
+               return MMFILE_FORMAT_FAIL;
        }
 
        formatContext->streams[MMFILE_AUDIO_STREAM]->streamType = MMFILE_AUDIO_STREAM;
@@ -294,6 +330,8 @@ int mmfile_format_read_stream_wav (MMFileFormatContext *formatContext)
        formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = waveinfo->channel;
        formatContext->streams[MMFILE_AUDIO_STREAM]->framePerSec = 0;
        formatContext->streams[MMFILE_AUDIO_STREAM]->samplePerSec = waveinfo->sample_rate;
+       formatContext->streams[MMFILE_AUDIO_STREAM]->bitPerSample = waveinfo->bits_per_sample;
+       formatContext->streams[MMFILE_AUDIO_STREAM]->is_uhqa = __check_uhqa(waveinfo->sample_rate, waveinfo->bits_per_sample);
 
        return MMFILE_FORMAT_SUCCESS;
 
index cac4fed..556c057 100755 (executable)
 #define MMFILE_EXT_MOV         0x6D6F76
 #define MMFILE_EXT_FLAC                0x666C6163
 #define MMFILE_EXT_FLV         0x666C76
+#define MMFILE_EXT_AIF         0x616966
+#define MMFILE_EXT_AIFF                0x61696666
+#define MMFILE_EXT_RMVB                0x726D7662
+#define MMFILE_EXT_RM          0x726D
+#define MMFILE_EXT_M2TS                0x6D327473
+#define MMFILE_EXT_MTS         0x6D7473
+#define MMFILE_EXT_TS          0x7473
+#define MMFILE_EXT_TP          0x7470
+#define MMFILE_EXT_MPEG                0x6D706567
 
 int (*MMFileOpenFunc[MM_FILE_FORMAT_NUM+1]) (MMFileFormatContext *fileContext) = {
        mmfile_format_open_ffmpg,       /* 3GP */
@@ -75,12 +84,12 @@ int (*MMFileOpenFunc[MM_FILE_FORMAT_NUM+1]) (MMFileFormatContext *fileContext) =
        mmfile_format_open_ffmpg,       /* MP4 */
        mmfile_format_open_ffmpg,       /* OGG */
        NULL,                                           /* NUT */
-       mmfile_format_open_ffmpg,                                               /* QT */
-       NULL,                                           /* REAL */
+       mmfile_format_open_ffmpg,       /* QT */
+       mmfile_format_open_ffmpg,       /* REAL */
        mmfile_format_open_amr,         /* AMR */
        mmfile_format_open_aac,         /* AAC */
        mmfile_format_open_mp3,         /* MP3 */
-       NULL,                                           /* AIFF */
+       mmfile_format_open_ffmpg,       /* AIFF */
        NULL,                                           /* AU */
        mmfile_format_open_wav,         /* WAV */
        mmfile_format_open_mid,         /* MID */
@@ -93,6 +102,10 @@ int (*MMFileOpenFunc[MM_FILE_FORMAT_NUM+1]) (MMFileFormatContext *fileContext) =
        mmfile_format_open_ffmpg,       /* WMV */
        NULL,                                           /* JPG */
        mmfile_format_open_ffmpg,       /* FLAC */
+       mmfile_format_open_ffmpg,       /* MPEG-TS */
+       mmfile_format_open_ffmpg,       /* MPEG-PS */
+       mmfile_format_open_ffmpg,       /* MPEG 1 VIDEO*/
+       mmfile_format_open_ffmpg,       /* MPEG 1 AUDIO */
        NULL,
 };
 
@@ -135,7 +148,12 @@ static int _CleanupFrameContext (MMFileFormatContext *formatContext, bool clean_
 
                if (formatContext->nbStreams > 0) {
                        int i = 0;
-                       for (i = 0; (i < formatContext->nbStreams) && (i < MAXSTREAMS); i++) {
+
+                       /*formatContext->streams[0] is video, formatContext->streams[1] is audio.*/
+                       if (formatContext->streams[0]) mmfile_free(formatContext->streams[0]);
+                       if (formatContext->streams[1]) mmfile_free(formatContext->streams[1]);
+
+                       for (i = 2; (i < formatContext->nbStreams) && (i < MAXSTREAMS); i++) {
                                if (formatContext->streams[i]) mmfile_free(formatContext->streams[i]);
                        }
                }
@@ -149,6 +167,10 @@ static int _CleanupFrameContext (MMFileFormatContext *formatContext, bool clean_
 
                        mmfile_free (formatContext->thumbNail);
                }
+
+               formatContext->videoTotalTrackNum = 0;
+               formatContext->audioTotalTrackNum = 0;
+               formatContext->nbStreams = 0;
        }
 
        return MMFILE_FORMAT_SUCCESS;
@@ -160,6 +182,9 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
        const char      *fileName = NULL;
        int                     filename_len = 0;
        int                     index = 0, skip_index = 0;
+#ifdef DRM_SUPPORT
+       drm_content_info_s      contentInfo;
+#endif
        int ret = 0;
        MMFileIOHandle *fp = NULL;
 
@@ -176,7 +201,6 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
                drm_bool_type_e res = DRM_TRUE;
                drm_file_type_e file_type = DRM_TYPE_UNDEFINED;
                int ret = 0;
-               bool is_drm = FALSE;
 
                ret = drm_is_drm_file (fileSrc->file.path, &res);
                if (ret == DRM_RETURN_SUCCESS && DRM_TRUE == res)
@@ -186,7 +210,11 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
                        {
                                char extansion_name[_MMF_FILE_FILEEXT_MAX];
                                int i = 0;
-                               is_drm = TRUE;
+
+                               *isdrm = MM_FILE_DRM_OMA;
+                               #ifdef __MMFILE_TEST_MODE__
+                               debug_msg ("OMA DRM detected.\n");
+                               #endif
 
                                memset(&contentInfo, 0x0, sizeof(drm_content_info_s));
 
@@ -218,13 +246,11 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
                                strncat (*urifilename, fileName, filename_len);
                                (*urifilename)[MMFILE_DRM_URI_LEN + filename_len] = '\0';
                        }
-               }
-
-               if (is_drm)
-               {
-                       *isdrm = MM_FILE_DRM_OMA;
-                       debug_error ("OMA DRM detected. Not Support DRM Content\n");
-                       goto FILE_FORMAT_FAIL;          /*Not Support DRM Content*/
+                       else if ((ret == DRM_RETURN_SUCCESS) &&
+                               ((file_type == DRM_TYPE_PLAYREADY) ||(file_type == DRM_TYPE_PLAYREADY_ENVELOPE) ||(file_type == DRM_TYPE_PIFF)))
+                       {
+                               *isdrm = MM_FILE_DRM_PROTECTED;
+                       }
                }
                else
 #endif // DRM_SUPPORT
@@ -278,7 +304,7 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
                ///////////////////////////////////////////////////////////////////////
 
                #ifdef __MMFILE_TEST_MODE__
-               debug_msg ("Get codec type of [%s].\n", extansion_name);
+               //debug_msg ("Get codec type of [%s].\n", extansion_name);
                #endif
 
                switch(file_extansion) {
@@ -474,6 +500,46 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
                                goto PROBE_PROPER_FILE_TYPE;
                                break;
 
+                       case MMFILE_EXT_RM:
+                       case MMFILE_EXT_RMVB:
+                               if (MMFileFormatIsValidREAL (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_REAL;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_REAL;
+                               goto PROBE_PROPER_FILE_TYPE;
+                               break;
+
+                       case MMFILE_EXT_M2TS:
+                       case MMFILE_EXT_MTS:
+                       case MMFILE_EXT_TP:
+                       case MMFILE_EXT_TS:
+                               if (MMFileFormatIsValidMPEGTS (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M2TS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_M2TS;
+                               goto PROBE_PROPER_FILE_TYPE;
+                               break;
+
+                       case MMFILE_EXT_MPEG:
+                               if (MMFileFormatIsValidMPEGPS (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M2PS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               } else if (MMFileFormatIsValidMPEGVIDEO (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M1VIDEO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_M2PS;
+                               goto PROBE_PROPER_FILE_TYPE;
+                               break;
+
+                       case MMFILE_EXT_AIF:
+                       case MMFILE_EXT_AIFF:
+                               *formatEnum = MM_FILE_FORMAT_AIFF;
+                               goto FILE_FORMAT_SUCCESS;
+                               break;
+
                        default :
                                debug_warning ("probe file type=%s\n", fileName);
                                skip_index = -1;
@@ -687,6 +753,51 @@ _PreprocessFile (MMFileSourceType *fileSrc, char **urifilename, int *formatEnum,
                                goto PROBE_PROPER_FILE_TYPE;
                        }
 
+                       case MM_FILE_FORMAT_REAL: {
+                               if (MMFileFormatIsValidREAL (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_REAL;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_REAL;
+                               goto PROBE_PROPER_FILE_TYPE;
+                       }
+
+                       case MM_FILE_FORMAT_M2TS: {
+                               if (MMFileFormatIsValidMPEGTS (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M2TS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_M2TS;
+                               goto PROBE_PROPER_FILE_TYPE;
+                       }
+
+                       case MM_FILE_FORMAT_M2PS: {
+                               if (MMFileFormatIsValidMPEGPS (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M2PS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_M2PS;
+                               goto PROBE_PROPER_FILE_TYPE;
+                       }
+
+                       case MM_FILE_FORMAT_M1AUDIO: {
+                               if (MMFileFormatIsValidMPEGAUDIO (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M1AUDIO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_M1AUDIO;
+                               goto PROBE_PROPER_FILE_TYPE;
+                       }
+
+                       case MM_FILE_FORMAT_M1VIDEO: {
+                               if (MMFileFormatIsValidMPEGVIDEO (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M1VIDEO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               skip_index = MM_FILE_FORMAT_M1VIDEO;
+                               goto PROBE_PROPER_FILE_TYPE;
+                       }
+
                        default: {
                                debug_warning ("probe fileformat type=%d (%d: autoscan)\n", fileSrc->memory.format, MM_FILE_FORMAT_INVALID);
                                skip_index = -1;
@@ -704,7 +815,10 @@ PROBE_PROPER_FILE_TYPE:
                if (index == skip_index)
                        continue;
 
+               #ifdef __MMFILE_TEST_MODE__
                debug_msg ("search index = [%d]\n", index);
+               #endif
+
                switch (index) {
                        case MM_FILE_FORMAT_QT:
                        case MM_FILE_FORMAT_3GP:
@@ -846,9 +960,53 @@ PROBE_PROPER_FILE_TYPE:
                                break;
                        }
 
+                       case MM_FILE_FORMAT_REAL: {
+                               if (MMFileFormatIsValidREAL (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_REAL;
+                                       if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) fileSrc->memory.format = MM_FILE_FORMAT_REAL;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M2TS: {
+                               if (MMFileFormatIsValidMPEGTS (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M2TS;
+                                       if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) fileSrc->memory.format = MM_FILE_FORMAT_M2TS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M2PS: {
+                               if (MMFileFormatIsValidMPEGPS (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M2PS;
+                                       if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) fileSrc->memory.format = MM_FILE_FORMAT_M2PS;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M1AUDIO: {
+                               if (MMFileFormatIsValidMPEGAUDIO (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M1AUDIO;
+                                       if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) fileSrc->memory.format = MM_FILE_FORMAT_M1AUDIO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
+                       case MM_FILE_FORMAT_M1VIDEO: {
+                               if (MMFileFormatIsValidMPEGVIDEO (fp, NULL)) {
+                                       *formatEnum = MM_FILE_FORMAT_M1VIDEO;
+                                       if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) fileSrc->memory.format = MM_FILE_FORMAT_M1VIDEO;
+                                       goto FILE_FORMAT_SUCCESS;
+                               }
+                               break;
+                       }
+
                        /* not supported file */
                        case MM_FILE_FORMAT_NUT:
-                       case MM_FILE_FORMAT_REAL:
                        case MM_FILE_FORMAT_AIFF:
                        case MM_FILE_FORMAT_AU:
                        case MM_FILE_FORMAT_VOB:
@@ -955,7 +1113,8 @@ int mmfile_format_open (MMFileFormatContext **formatContext, MMFileSourceType *f
        if (MMFILE_FORMAT_FAIL == ret) {
                debug_error ("error: Try other formats\n");
                ret = MMFILE_FORMAT_FAIL;
-               goto find_valid_handler;
+//             goto find_valid_handler;
+               goto exception;
        }
 
        *formatContext = formatObject;
index 86af2e7..f752690 100755 (executable)
@@ -98,6 +98,8 @@ extern "C" {
 #define        MM_FILE_TAG_SYNCLYRICS_NUM      "tag-synclyrics-num"    /**< Synchronized Lyrics Information*/
 #define        MM_FILE_TAG_RECDATE                     "tag-recdate"                   /**< Recoding date */
 #define        MM_FILE_TAG_ROTATE                      "tag-rotate"                    /**< Rotate(Orientation) Information*/
+#define        MM_FILE_TAG_CDIS                        "tag-cdis"                              /**< CDIS in User Data Information*/
+#define        MM_FILE_TAG_SMTA                        "tag-smta"                              /**< SMTA in User Data Information*/
 
 
 
@@ -130,6 +132,7 @@ ret = mm_file_get_attrs( tag_attrs,
                                                        MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
                                                        MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
                                                        MM_FILE_TAG_TITLE, &ctag.title.value.s_val, &ctag.title.len,
+                                                       MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
                                                        MM_FILE_TAG_GENRE, &ctag.genre.value.s_val, &ctag.genre.len,
                                                        NULL);
 if (ret != MM_ERROR_NONE)
@@ -173,6 +176,7 @@ ret = mm_file_get_attrs( tag_attrs,
                                                        MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
                                                        MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
                                                        MM_FILE_TAG_TITLE, &ctag.title.value.s_val, &ctag.title.len,
+                                                       MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
                                                        MM_FILE_TAG_GENRE, &ctag.genre.value.s_val, &ctag.genre.len,
                                                        NULL);
 if (ret != MM_ERROR_NONE)
@@ -450,6 +454,7 @@ mm_file_get_attrs(tag_attrs,
                                NULL,
                                MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
                                MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
+                               MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
                                NULL);
 
 // Destory tag handle
@@ -555,10 +560,12 @@ mm_file_destroy_content_attrs(content_attrs);
    */
 int mm_file_create_content_attrs_simple(MMHandleType *content_attrs, const char *filename);
 
+int mm_file_create_content_attrs_safe(MMHandleType *content_attrs, const char *filename);
+
 int mm_file_get_synclyrics_info(MMHandleType tag_attrs, int index, unsigned long *time_info, char **lyrics);
 
 /**
- * @brief Get a frame of video media
+ * @brief Get a frame of video media. Not support for DRM Contents.
  *
  * @remarks @a frame must be released with @c free() by you
  *
@@ -583,6 +590,8 @@ int mm_file_get_video_frame(const char* path, double timestamp, bool is_accurate
 
 int mm_file_get_video_frame_from_memory(const void *data, unsigned int datasize, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height);
 
+int mm_file_check_uhqa(const char* filename, bool *is_uhqa);
+
 /**
        @}
  */
index da3ea62..fbf9028 100755 (executable)
@@ -55,9 +55,10 @@ enum {
 };
 
 enum {
-       MM_FILE_DRM_NONE = 0,   /*not drm file*/
-       MM_FILE_DRM_OMA,                /*oma drm*/
-       MM_FILE_DRM_DIVX,               /*divx drm*/
+       MM_FILE_DRM_NONE = 0,           /*not drm file*/
+       MM_FILE_DRM_OMA,                        /*oma drm*/
+       MM_FILE_DRM_DIVX,                       /*divx drm*/
+       MM_FILE_DRM_PROTECTED,  /*This is drm file but not oma or divx*/
 };
 
 
@@ -86,6 +87,8 @@ typedef struct _mmfilesteam {
        int     height;
        int     nbChannel;
        int     samplePerSec;
+       int     bitPerSample;
+       bool is_uhqa;
 } MMFileFormatStream;
 
 typedef struct _mmfileformatframe {
@@ -154,7 +157,9 @@ struct _MMFileFormatContext {
        char *rotate;
        GList *syncLyrics;
        int syncLyricsNum;
-       
+       int cdis;
+       int smta;
+
        /* private data */
        void *privateFormatData;
        void *privateCodecData;
index 1ea2584..e7484d6 100755 (executable)
--- a/mm_file.c
+++ b/mm_file.c
@@ -78,12 +78,14 @@ enum {
        MM_FILE_PARSE_TYPE_SIMPLE,              /*parse audio/video track num only*/
        MM_FILE_PARSE_TYPE_NORMAL,              /*parse infomation without thumbnail*/
        MM_FILE_PARSE_TYPE_ALL,                 /*parse all infomation*/
+       MM_FILE_PARSE_TYPE_SAFE,                /*parse infomation without both thumbnail and stream full-searching*/
 };
 
 typedef struct {
        int     type;
        int     audio_track_num;
        int     video_track_num;
+       bool is_uhqa;
 } MMFILE_PARSE_INFO;
 
 typedef struct {
@@ -97,49 +99,52 @@ typedef struct {
  * global values.
  */
 static mmf_attrs_construct_info_t g_tag_attrs[] = {
-       {"tag-artist",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-title",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-album",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-album-artist",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-genre",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-author",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-copyright",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-date",                    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-description",             MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-comment",         MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-artwork",         MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-artwork-size",    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"tag-artwork-mime",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-track-num",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-classification",  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-rating",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-longitude",               MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
-       {"tag-latitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
-       {"tag-altitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
-       {"tag-conductor",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-unsynclyrics",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-synclyrics-num",  MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"tag-synclyrics",              MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-recdate",         MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"tag-rotate",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-artist",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-title",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-album",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-album-artist",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-genre",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-author",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-copyright",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-date",                    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-description",             MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-comment",         MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-artwork",         MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-artwork-size",    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"tag-artwork-mime",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-track-num",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-classification",  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-rating",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-longitude",               MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"tag-latitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"tag-altitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"tag-conductor",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-unsynclyrics",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-synclyrics-num",  MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"tag-synclyrics",              MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-recdate",         MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-rotate",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"tag-cdis",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"tag-smta",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
 };
 
 static mmf_attrs_construct_info_t g_content_attrs[] = {
-       {"content-duration",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-codec",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-bitrate",               MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-fps",                   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-width",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-height",                MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-thumbnail",             MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
-       {"content-video-track-index",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-video-track-count",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-audio-codec",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-audio-bitrate",               MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-audio-channels",              MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-audio-samplerate",    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-audio-track-index",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
-       {"content-audio-track-count",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-duration",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-codec",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-bitrate",               MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-fps",                   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-width",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-height",                MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-thumbnail",             MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
+       {(char *)"content-video-track-index",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-video-track-count",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-codec",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-bitrate",               MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-channels",              MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-samplerate",    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-track-index",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-track-count",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
+       {(char *)"content-audio-bitpersample",  MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
 };
 
 #ifdef __MMFILE_DYN_LOADING__
@@ -238,18 +243,22 @@ exception:
 
 static void _unload_dynamic_functions (MMFILE_FUNC_HANDLE* pHandle)
 {
-       debug_fenter ();        
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
-       if (pHandle->formatFuncHandle) 
+       if (pHandle->formatFuncHandle)
        {
-               dlclose (pHandle->formatFuncHandle);            
+               dlclose (pHandle->formatFuncHandle);    
        }
-       if (pHandle->codecFuncHandle)  
+       if (pHandle->codecFuncHandle)
        {
-               dlclose (pHandle->codecFuncHandle);             
+               dlclose (pHandle->codecFuncHandle);
        }
-       
-       debug_fleave ();
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 }
 
 
@@ -302,12 +311,14 @@ _info_set_attr_media (mmf_attrs_t *attrs, MMFileFormatContext *formatContext)
                                                                                        mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_LATIDUE, formatContext->latitude);
                                                                                        mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_ALTIDUE, formatContext->altitude); 
                                                                                        mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_SYNCLYRICS_NUM, formatContext->syncLyricsNum);
+                                                                                       mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_CDIS, formatContext->cdis);
+                                                                                       mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_SMTA, formatContext->smta);
 
                if ((formatContext->syncLyricsNum > 0) && (formatContext->syncLyrics))
                        mm_attrs_set_data_by_name (hattrs, MM_FILE_TAG_SYNCLYRICS, formatContext->syncLyrics, formatContext->syncLyricsNum);
 
                if (formatContext->unsyncLyrics)                mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_UNSYNCLYRICS, formatContext->unsyncLyrics);
-               
+
                if (formatContext->artwork && formatContext->artworkSize > 0) {
                        void *artworkCopy = NULL;
                        artworkCopy = mmfile_malloc ((formatContext->artworkSize));
@@ -361,9 +372,10 @@ _info_set_attr_media (mmf_attrs_t *attrs, MMFileFormatContext *formatContext)
                        mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_CHANNELS, audioStream->nbChannel);
                        mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_BITRATE, audioStream->bitRate);
                        mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_SAMPLERATE, audioStream->samplePerSec);
-               }       
-       } 
-       else 
+                       mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, audioStream->bitPerSample);
+               }
+       }
+       else
        {
                ret = -1;
        }
@@ -395,13 +407,9 @@ _get_contents_info (mmf_attrs_t *attrs, MMFileSourceType *src, MMFILE_PARSE_INFO
                goto exception;
        }
 
-       /**
-        * if MM_FILE_PARSE_TYPE_SIMPLE, just get number of each stream.
-        */
-       parse->audio_track_num = formatContext->audioTotalTrackNum;
-       parse->video_track_num = formatContext->videoTotalTrackNum;
-
        if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL) {
+               if (parse->type == MM_FILE_PARSE_TYPE_SAFE)
+                       formatContext->cdis = 1;
                ret = mmfile_format_read_stream (formatContext);
                if (MMFILE_FORMAT_FAIL == ret) {
                        debug_error ("error: mmfile_format_read_stream\n");
@@ -409,8 +417,21 @@ _get_contents_info (mmf_attrs_t *attrs, MMFileSourceType *src, MMFILE_PARSE_INFO
                        goto exception;
                }
 
+               parse->audio_track_num = formatContext->audioTotalTrackNum;
+               parse->video_track_num = formatContext->videoTotalTrackNum;
+
+               /* check uhqa content*/
+               if (parse->is_uhqa = formatContext->streams[MMFILE_AUDIO_STREAM] != NULL)
+                       parse->is_uhqa = formatContext->streams[MMFILE_AUDIO_STREAM]->is_uhqa;
+
                if (parse->type >= MM_FILE_PARSE_TYPE_ALL) {
                        if (formatContext->videoTotalTrackNum > 0) {
+
+                               if (parse->type != MM_FILE_PARSE_TYPE_SAFE) {
+                                       if (formatContext->formatType == MM_FILE_FORMAT_3GP ||formatContext->formatType == MM_FILE_FORMAT_MP4) {
+                                               MMFileUtilGetMetaDataFromMP4 (formatContext);
+                                       }
+                               }
                                MMFileFormatStream *videoStream = formatContext->streams[MMFILE_VIDEO_STREAM];
                                unsigned int timestamp = _SEEK_POINT_;
 
@@ -475,6 +496,12 @@ _get_contents_info (mmf_attrs_t *attrs, MMFileSourceType *src, MMFILE_PARSE_INFO
                                }
                        }
                }
+       } else {
+               /**
+                * if MM_FILE_PARSE_TYPE_SIMPLE, just get number of each stream.
+                */
+               parse->audio_track_num = formatContext->audioTotalTrackNum;
+               parse->video_track_num = formatContext->videoTotalTrackNum;
        }
 
 #ifdef __MMFILE_TEST_MODE__
@@ -666,8 +693,10 @@ int mm_file_get_synclyrics_info(MMHandleType tag_attrs, int index, unsigned long
        int ret = MM_ERROR_NONE;
        AvSynclyricsInfo* sync_lyric_item = NULL;
        GList *synclyrics_list = NULL;
-       
-       debug_fenter ();
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        if ( (mmf_attrs_t*)tag_attrs == NULL) {
                debug_error ("invalid handle");
@@ -702,9 +731,9 @@ int mm_file_get_synclyrics_info(MMHandleType tag_attrs, int index, unsigned long
                #endif
                return MM_ERROR_COMMON_ATTR_NOT_EXIST;
        }
-       
+
        return ret;
-       
+
 }
 
 int mm_file_create_tag_attrs(MMHandleType *tag_attrs, const char *filename)
@@ -713,7 +742,9 @@ int mm_file_create_tag_attrs(MMHandleType *tag_attrs, const char *filename)
        mmf_attrs_t *attrs = NULL;
        MMFileSourceType src;
 
-       debug_fenter ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        /* Check argument here */
        if (tag_attrs == NULL) {
@@ -744,31 +775,36 @@ int mm_file_create_tag_attrs(MMHandleType *tag_attrs, const char *filename)
        MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
 
        ret = _is_file_exist (filename);
-       if (!ret)
-               return MM_ERROR_FILE_NOT_FOUND;
+       if (!ret) {
+               ret = MM_ERROR_FILE_NOT_FOUND;
+               goto END;
+       }
 
        /*set attrs*/
        attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("tag", g_tag_attrs, ARRAY_SIZE (g_tag_attrs), NULL, NULL);
        if (!attrs) {
                debug_error ("attribute internal error.\n");
-               return MM_ERROR_FILE_INTERNAL;
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
        }
 
        ret = _get_tag_info (attrs, &src);
-
-#ifdef __MMFILE_TEST_MODE__
        if (ret != MM_ERROR_NONE) {
+               mmf_attrs_free ((MMHandleType)attrs);
+               attrs = NULL;
                debug_error ("failed to get tag: %s\n", filename);
        }
-#endif
 
        *tag_attrs = (MMHandleType)attrs;
 
+END:
 #ifdef __MMFILE_DYN_LOADING__
        _unload_dynamic_functions (&func_handle);
 #endif
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -780,7 +816,10 @@ int mm_file_destroy_tag_attrs(MMHandleType tag_attrs)
        void *artwork = NULL;
        GList *synclyrics_list = NULL;
        int ret = MM_ERROR_NONE;
-       debug_fenter ();
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        if ( (mmf_attrs_t*)tag_attrs == NULL) {
                debug_error ("invalid handle.\n");
@@ -788,7 +827,7 @@ int mm_file_destroy_tag_attrs(MMHandleType tag_attrs)
        }
 
        ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_ARTWORK, &artwork);
-       
+
        if (artwork != NULL) {
                mmfile_free (artwork);
        }
@@ -801,7 +840,9 @@ int mm_file_destroy_tag_attrs(MMHandleType tag_attrs)
 
        mmf_attrs_free (tag_attrs);
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -814,7 +855,9 @@ int mm_file_create_content_attrs (MMHandleType *contents_attrs, const char *file
        MMFILE_PARSE_INFO parse = {0,};
        int ret = 0;
 
-       debug_fenter ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        /* Check argument here */
        if (contents_attrs == NULL) {
@@ -837,8 +880,8 @@ int mm_file_create_content_attrs (MMHandleType *contents_attrs, const char *file
        #ifdef CHECK_TIME
         int64_t ti;
        ti = gettime();
-       #endif 
-       
+       #endif
+
        ret = _load_dynamic_functions (&func_handle);
        if (ret == 0) {
                debug_error ("load library error\n");
@@ -846,51 +889,58 @@ int mm_file_create_content_attrs (MMHandleType *contents_attrs, const char *file
        }
 
        #ifdef CHECK_TIME
-       printf ("%s, %d, _load_dynamic_functions() = %lld\n", __func__, __LINE__, gettime() - ti);
+       debug_msg("_load_dynamic_functions() = %lld\n", gettime() - ti);
        #endif
-        
+
 #endif
 
        /*set source file infomation*/
        MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
 
        ret = _is_file_exist (filename);
-       if (!ret)
-               return MM_ERROR_FILE_NOT_FOUND;
+       if (!ret) {
+               ret = MM_ERROR_FILE_NOT_FOUND;
+               goto END;
+       }
 
        /*set attrs*/
        attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
        if (!attrs) {
                debug_error ("attribute internal error.\n");
-               return MM_ERROR_FILE_INTERNAL;
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
        }
-       
+
 
        parse.type = MM_FILE_PARSE_TYPE_ALL;
        ret = _get_contents_info (attrs, &src, &parse);
        if (ret != MM_ERROR_NONE) {
+               mmf_attrs_free ((MMHandleType)attrs);
+               attrs = NULL;
                debug_error ("failed to get contents: %s\n", filename);
        }
 
        *contents_attrs = (MMHandleType) attrs;
 
 
+END:
 #ifdef __MMFILE_DYN_LOADING__
 
-       #ifdef CHECK_TIME 
+       #ifdef CHECK_TIME
        ti = gettime();
        #endif
 
        _unload_dynamic_functions (&func_handle);
 
        #ifdef CHECK_TIME
-       printf ("%s, %d, _unload_dynamic_functions() = %lld\n", __func__, __LINE__, gettime() - ti);
+       debug_msg("_unload_dynamic_functions() = %lld\n", gettime() - ti);
        #endif
 
 #endif
 
-
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -904,7 +954,9 @@ int mm_file_create_tag_attrs_from_memory (MMHandleType *tag_attrs, const void *d
        MMFILE_PARSE_INFO parse = {0,};
        int ret = 0;
 
-       debug_fenter ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        /* Check argument here */
        if (tag_attrs == NULL || data == NULL) {
@@ -928,19 +980,28 @@ int mm_file_create_tag_attrs_from_memory (MMHandleType *tag_attrs, const void *d
        attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("tag", g_tag_attrs, ARRAY_SIZE (g_tag_attrs), NULL, NULL);
        if (!attrs) {
                debug_error ("attribute internal error.\n");
-               return MM_ERROR_FILE_INTERNAL;
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
        }
 
        parse.type = MM_FILE_PARSE_TYPE_ALL;
        ret = _get_tag_info (attrs, &src);
+       if (ret != MM_ERROR_NONE) {
+               mmf_attrs_free ((MMHandleType)attrs);
+               attrs = NULL;
+               debug_error ("failed to get tag");
+       }
 
        *tag_attrs = (MMHandleType)attrs;
 
+END:
 #ifdef __MMFILE_DYN_LOADING__
        _unload_dynamic_functions (&func_handle);
 #endif
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -954,7 +1015,9 @@ int mm_file_create_content_attrs_from_memory (MMHandleType *contents_attrs, cons
        MMFILE_PARSE_INFO parse = {0,};
        int ret = 0;
 
-       debug_fenter ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        /* Check argument here */
        if (contents_attrs == NULL || data == NULL) {
@@ -964,7 +1027,7 @@ int mm_file_create_content_attrs_from_memory (MMHandleType *contents_attrs, cons
 
 #ifdef __MMFILE_DYN_LOADING__
        MMFILE_FUNC_HANDLE func_handle;
-       
+
        ret = _load_dynamic_functions (&func_handle);
        if (ret == 0) {
                debug_error ("load library error\n");
@@ -978,22 +1041,28 @@ int mm_file_create_content_attrs_from_memory (MMHandleType *contents_attrs, cons
        attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
        if (!attrs) {
                debug_error ("attribute internal error.\n");
-               return MM_ERROR_FILE_INTERNAL;
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
        }
 
        parse.type = MM_FILE_PARSE_TYPE_ALL;
        ret = _get_contents_info (attrs, &src, &parse);
        if (ret != MM_ERROR_NONE) {
+               mmf_attrs_free ((MMHandleType)attrs);
+               attrs = NULL;
                debug_error ("failed to get contents");
        }
 
        *contents_attrs = (MMHandleType)attrs;
 
+END:
 #ifdef __MMFILE_DYN_LOADING__
        _unload_dynamic_functions (&func_handle);
 #endif
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -1004,7 +1073,10 @@ int mm_file_destroy_content_attrs (MMHandleType contents_attrs)
 {
        void *thumbnail = NULL;
        int ret = MM_ERROR_NONE;
-       debug_fenter ();
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        if ((mmf_attrs_t*)contents_attrs == NULL) {
                debug_error ("invalid handle.\n");
@@ -1018,7 +1090,9 @@ int mm_file_destroy_content_attrs (MMHandleType contents_attrs)
 
        mmf_attrs_free (contents_attrs);
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -1032,7 +1106,9 @@ int mm_file_get_stream_info(const char* filename, int *audio_stream_num, int *vi
 
        int ret = 0;
 
-       debug_fenter ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
        if (filename == NULL || strlen (filename) == 0 || audio_stream_num == NULL || video_stream_num == NULL) {
                debug_error ("Invalid arguments\n");
@@ -1053,24 +1129,35 @@ int mm_file_get_stream_info(const char* filename, int *audio_stream_num, int *vi
        MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
 
        ret = _is_file_exist (filename);
-       if (!ret)
-               return MM_ERROR_FILE_NOT_FOUND;
+       if (!ret) {
+               ret = MM_ERROR_FILE_NOT_FOUND;
+               goto END;
+       }
 
        parse.type = MM_FILE_PARSE_TYPE_SIMPLE;
        ret = _get_contents_info (NULL, &src, &parse);
        if (ret != MM_ERROR_NONE) {
                debug_error ("failed to get stream info: %s\n", filename);
+       } else {
+               if(parse.audio_track_num == 0 && parse.video_track_num == 0) {
+                       debug_error ("empty header. retry to get stream info: %s\n", filename);
+                       parse.type = MM_FILE_PARSE_TYPE_NORMAL;
+                       ret = _get_contents_info (NULL, &src, &parse);
+               }
        }
 
        /*set number of each stream*/
        *audio_stream_num = parse.audio_track_num;
        *video_stream_num = parse.video_track_num;
 
+END:
 #ifdef __MMFILE_DYN_LOADING__
        _unload_dynamic_functions (&func_handle);
 #endif
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -1083,51 +1170,134 @@ int mm_file_create_content_attrs_simple(MMHandleType *contents_attrs, const char
        MMFILE_PARSE_INFO parse = {0,};
        int ret = 0;
 
-       debug_fenter ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
 
 #ifdef __MMFILE_DYN_LOADING__
        MMFILE_FUNC_HANDLE func_handle;
-       
+
        ret = _load_dynamic_functions (&func_handle);
        if (ret == 0) {
                debug_error ("load library error\n");
                return MM_ERROR_FILE_INTERNAL;
        }
 #endif
-       if (filename == NULL) { 
-               return MM_ERROR_INVALID_ARGUMENT;
+       if (filename == NULL) {
+               ret =  MM_ERROR_INVALID_ARGUMENT;
+               goto END;
        } else {
-               if (strlen (filename) == 0)
-                       return MM_ERROR_INVALID_ARGUMENT;
+               if (strlen (filename) == 0) {
+                       ret =  MM_ERROR_INVALID_ARGUMENT;
+                       goto END;
+               }
        }
 
        /*set source file infomation*/
        MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
 
        ret = _is_file_exist (filename);
-       if (!ret)
-               return MM_ERROR_FILE_NOT_FOUND;
+       if (!ret) {
+               ret = MM_ERROR_FILE_NOT_FOUND;
+               goto END;
+       }
 
        /*set attrs*/
        attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
        if (!attrs) {
                debug_error ("attribute internal error.\n");
-               return MM_ERROR_FILE_INTERNAL;
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
        }
 
        parse.type = MM_FILE_PARSE_TYPE_NORMAL;
        ret = _get_contents_info (attrs, &src, &parse);
        if (ret != MM_ERROR_NONE) {
+               mmf_attrs_free ((MMHandleType)attrs);
+               attrs = NULL;
+               debug_error ("failed to get contents: %s\n", filename);
+       }
+
+       *contents_attrs = (MMHandleType) attrs;
+
+END:
+#ifdef __MMFILE_DYN_LOADING__
+       _unload_dynamic_functions (&func_handle);
+#endif
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
+
+       return ret;
+}
+
+EXPORT_API
+int mm_file_create_content_attrs_safe(MMHandleType *contents_attrs, const char *filename)
+{
+       mmf_attrs_t *attrs = NULL;
+       MMFileSourceType src = {0,};
+       MMFILE_PARSE_INFO parse = {0,};
+       int ret = 0;
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fenter();
+#endif
+
+#ifdef __MMFILE_DYN_LOADING__
+       MMFILE_FUNC_HANDLE func_handle;
+
+       ret = _load_dynamic_functions (&func_handle);
+       if (ret == 0) {
+               debug_error ("load library error\n");
+               return MM_ERROR_FILE_INTERNAL;
+       }
+#endif
+       if (filename == NULL) {
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto END;
+       } else {
+               if (strlen (filename) == 0) {
+                       ret = MM_ERROR_INVALID_ARGUMENT;
+                       goto END;
+               }
+       }
+
+       /*set source file infomation*/
+       MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
+
+       ret = _is_file_exist (filename);
+       if (!ret) {
+               ret = MM_ERROR_FILE_NOT_FOUND;
+               goto END;
+       }
+
+       /*set attrs*/
+       attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
+       if (!attrs) {
+               debug_error ("attribute internal error.\n");
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
+       }
+
+       parse.type = MM_FILE_PARSE_TYPE_SAFE;
+       ret = _get_contents_info (attrs, &src, &parse);
+       if (ret != MM_ERROR_NONE) {
+               mmf_attrs_free ((MMHandleType)attrs);
+               attrs = NULL;
                debug_error ("failed to get contents: %s\n", filename);
        }
 
        *contents_attrs = (MMHandleType) attrs;
 
+END:
 #ifdef __MMFILE_DYN_LOADING__
        _unload_dynamic_functions (&func_handle);
 #endif
 
-       debug_fleave ();
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
 
        return ret;
 }
@@ -1227,4 +1397,72 @@ exception:
        if (formatFuncHandle) dlclose (formatFuncHandle);
 
        return MM_ERROR_FILE_INTERNAL;
+}
+
+EXPORT_API
+int mm_file_check_uhqa(const char* filename, bool *is_uhqa)
+{
+       mmf_attrs_t *attrs = NULL;
+       MMFileSourceType src = {0,};
+       MMFILE_PARSE_INFO parse = {0,};
+       int ret = 0;
+
+#ifdef __MMFILE_DYN_LOADING__
+       MMFILE_FUNC_HANDLE func_handle;
+
+       ret = _load_dynamic_functions (&func_handle);
+       if (ret == 0) {
+               debug_error ("load library error\n");
+               return MM_ERROR_FILE_INTERNAL;
+       }
+#endif
+       if (filename == NULL) {
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto END;
+       } else {
+               if (strlen (filename) == 0) {
+                       ret = MM_ERROR_INVALID_ARGUMENT;
+                       goto END;
+               }
+       }
+
+       /*set source file infomation*/
+       MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
+
+       ret = _is_file_exist (filename);
+       if (!ret) {
+               ret = MM_ERROR_FILE_NOT_FOUND;
+               goto END;
+       }
+
+       /*set attrs*/
+       attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
+       if (!attrs) {
+               debug_error ("attribute internal error.\n");
+               ret = MM_ERROR_FILE_INTERNAL;
+               goto END;
+       }
+
+       parse.type = MM_FILE_PARSE_TYPE_NORMAL;
+       ret = _get_contents_info (attrs, &src, &parse);
+       if (ret == MM_ERROR_NONE) {
+               *is_uhqa = parse.is_uhqa;
+       } else {
+               debug_error ("_get_contents_info failed\n");
+               *is_uhqa = FALSE;
+       }
+
+       mmf_attrs_free ((MMHandleType)attrs);
+       attrs = NULL;
+
+END:
+#ifdef __MMFILE_DYN_LOADING__
+       _unload_dynamic_functions (&func_handle);
+#endif
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_fleave();
+#endif
+
+       return ret;
 }
\ No newline at end of file
index 071a605..de83df9 100755 (executable)
@@ -6,6 +6,9 @@ Group:      System/Libraries
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 Source1001:    libmm-fileinfo.manifest
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
 BuildRequires: pkgconfig(mm-common)
 BuildRequires: pkgconfig(mm-log)
 BuildRequires: pkgconfig(libswscale)
@@ -13,12 +16,15 @@ BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(libavcodec)
 BuildRequires: pkgconfig(libavutil)
 BuildRequires: pkgconfig(libavformat)
+BuildRequires: pkgconfig(icu-i18n)
+BuildRequires: pkgconfig(vconf)
 
 %define use_drm 0
 
 %if %{use_drm}
 BuildRequires: libss-client-devel
-BuildRequires: pkgconfig(drm-client)
+#BuildRequires: pkgconfig(drm-client)
+#BuildRequires: pkgconfig(drm-trusted)
 %endif
 
 %description
@@ -47,9 +53,9 @@ export CFLAGS
     --disable-iommap \
     --disable-gtk \
 %if %{use_drm}
-    --enable-drm
+CFLAGS="${CFLAGS} -D_MM_PROJECT_FLOATER -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" " LDFLAGS="${LDFLAGS}" ./configure  --disable-testmode --disable-dump --enable-dyn --disable-iommap --prefix=/usr --enable-drm --disable-gtk
 %else
-    --disable-drm
+CFLAGS="${CFLAGS} -D_MM_PROJECT_FLOATER -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" " LDFLAGS="${LDFLAGS}" ./configure --disable-testmode --disable-dump --enable-dyn --disable-iommap --prefix=/usr --disable-drm --disable-gtk
 %endif
 
 %__make
index 94bfa72..c28a25b 100755 (executable)
@@ -4,35 +4,37 @@ mm_file_test_DEPENDENCIES = $(top_builddir)/libmmffile.la
 
 mm_file_test_SOURCES = mm_file_test.c \
                   mm_file_traverser.c
-       
+
 mm_file_test_CFLAGS = -I$(top_builddir)/include \
                      $(MMCOMMON_CFLAGS) \
                      -I$(includedir) \
                      -D_LARGEFILE64_SOURCE \
                       -D_FILE_OFFSET_BITS=64 \
-                     $(GLIB_CFLAGS) 
+                     $(GLIB_CFLAGS)
+mm_file_test_CFLAGS += -fPIE
+
+mm_file_test_LDFLAGS = -pie
 
 mm_file_test_LDADD =   $(MMCOMMON_LIBS) \
                        $(top_builddir)/libmmffile.la \
                        $(top_builddir)/utils/libmmfile_utils.la \
-                        $(GLIB_LIBS) 
+                        $(GLIB_LIBS)
 
 
 if USE_DYN
 else
 mm_file_test_LDADD += $(top_builddir)/codecs/ffmpeg/libmmfile_codecs.la  \
-                                         $(top_builddir)/formats/ffmpeg/libmmfile_formats.la 
+                                         $(top_builddir)/formats/ffmpeg/libmmfile_formats.la
 endif
 
 
-bin_PROGRAMS += memtrace_reader
+#bin_PROGRAMS += memtrace_reader
 
-memtrace_reader_SOURCES = mm_file_memtrace_reader.c
+#memtrace_reader_SOURCES = mm_file_memtrace_reader.c
 
-memtrace_reader_CFLAGS = -I/$(srcdir)/include \
-                     -D_LARGEFILE64_SOURCE \
-                      -D_FILE_OFFSET_BITS=64 
-                               
-memtrace_reader_DEPENDENCIES = 
-memtrace_reader_LDADD = 
+#memtrace_reader_CFLAGS = -I/$(srcdir)/include \
+#                    -D_LARGEFILE64_SOURCE \
+#                      -D_FILE_OFFSET_BITS=64
 
+#memtrace_reader_DEPENDENCIES =
+#memtrace_reader_LDADD =
index d13d78a..455287d 100755 (executable)
 gettimeofday(&finish, NULL); \
 double end_time = (finish.tv_sec + 1e-6*finish.tv_usec); \
 double start_time = (start.tv_sec + 1e-6*start.tv_usec); \
+if(msg_tmp_fp != NULL) { \
 fprintf(msg_tmp_fp, "%s\n", title); \
 fprintf(msg_tmp_fp, " - start_time:   %3.5lf sec\n", start_time); \
 fprintf(msg_tmp_fp, " - finish_time:  %3.5lf sec\n", end_time); \
 fprintf(msg_tmp_fp, " - elapsed time: %3.5lf sec\n", end_time - start_time); \
-fflush(msg_tmp_fp); fclose(msg_tmp_fp); }
+fflush(msg_tmp_fp); fclose(msg_tmp_fp); }}
 
 typedef struct _mmfile_value {
        int len;
@@ -53,7 +54,7 @@ typedef struct _mmfile_value {
                double d_val;
                char *s_val;
                void *p_val;
-       } value;
+       }value;
 }mmfile_value_t;
 
 typedef struct _TagContext {
@@ -98,26 +99,31 @@ typedef struct _ContentContext {
        int audio_samplerate;
        int audio_track_id;
        int audio_track_num;
+       int audio_bitpersample;
        mmfile_value_t thumbnail;
 }ContentContext_t;
 
 
 char * AudioCodecTypeString [] = {
-       "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW", "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",
-       "G711", "G722", "G722.1",       "G722.2  (AMR-WB)",     "G723 wideband speech", "G726 (ADPCM)", "G728 speech",  "G729", "G729a",        "G729.1",
-       "Real",
-       "AAC-Low complexity",   "AAC-Main profile",     "AAC-Scalable sample rate",     "AAC-Long term prediction",     "AAC-High Efficiency v1",       "AAC-High efficiency v2",
-       "DolbyDigital", "Apple Lossless",       "Sony proprietary",     "SPEEX",        "Vorbis",       "AIFF", "AU",   "None (will be deprecated)",
-       "PCM",  "ALAW", "MULAW",        "MS ADPCM",     "FLAC"
+       "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW",        // 0~9
+       "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",  // 10~14
+       "G711", "G722", "G722.1", "G722.2  (AMR-WB)", "G723 wideband speech",   // 15~19
+       "G726 (ADPCM)", "G728 speech", "G729", "G729a", "G729.1",       // 20~24
+       "Real", "AAC-Low complexity", "AAC-Main profile", "AAC-Scalable sample rate", "AAC-Long term prediction",       // 25~29
+       "AAC-High Efficiency v1", "AAC-High efficiency v2",     "DolbyDigital", "Apple Lossless", "Sony proprietary",   // 30~34
+       "SPEEX", "Vorbis", "AIFF", "AU", "None (will be deprecated)",   //35~39
+       "PCM", "ALAW", "MULAW", "MS ADPCM", "FLAC"      // 40~44
 };
 
 
 char * VideoCodecTypeString [] = {
-       "None (will be deprecated)",
-       "H263", "H264", "H26L", "MPEG4", "MPEG1", "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2", "H263v2",  "H263v3",
-       "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",  "MPEG4 part-2 Advanced Simple profile", "MPEG4 part-2 Main profile",
-       "MPEG4 part-2 Core profile", "MPEG4 part-2 Adv Coding Eff profile",     "MPEG4 part-2 Adv RealTime Simple profile",
-       "MPEG4 part-10 (h.264)",        "Real", "VC-1", "AVS",  "Cinepak",      "Indeo",        "Theora", "Flv"
+       "None (will be deprecated)",    // 0
+       "H263", "H264", "H26L", "MPEG4", "MPEG1",       // 1~5
+       "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2",      // 6~10
+       "H263v2", "H263v3", "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",      // 11~15
+       "MPEG4 part-2 Advanced Simple profile", "MPEG4 part-2 Main profile", "MPEG4 part-2 Core profile", "MPEG4 part-2 Adv Coding Eff profile", "MPEG4 part-2 Adv RealTime Simple profile",    // 16~20
+       "MPEG4 part-10 (h.264)", "Real", "VC-1", "AVS", "Cinepak",      // 21~25
+       "Indeo", "Theora", "Flv"        // 26~28
 };
 
 
@@ -139,8 +145,8 @@ do{ \
                        fseek (fp, 0, SEEK_END);        \
                        size = ftell(fp);       \
                        fseek (fp, 0, SEEK_SET);        \
-                       data = malloc (size);   \
-                       if (fread (data, size, sizeof(char), fp) != size) { printf("fread error\n"); }  \
+                       if(size > 0) data = malloc (size);      \
+                       if(data != NULL ) { if (fread (data, size, sizeof(char), fp) != size) { printf("fread error\n"); } }    \
                        fclose (fp);    \
                        printf("file size = %d\n", size );      \
        }       \
@@ -189,7 +195,7 @@ int main(int argc, char **argv)
                }
     }
 
-    exit(0);
+    return 0;//exit(0);
 }
 
 static int mmfile_get_file_infomation (void *data, void* user_data, bool file_test)
@@ -252,6 +258,7 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                                                                        MM_FILE_CONTENT_AUDIO_CHANNELS, &ccontent.audio_channel,
                                                                        MM_FILE_CONTENT_AUDIO_TRACK_INDEX, &ccontent.audio_track_id,
                                                                        MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &ccontent.audio_track_num,
+                                                                       MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, &ccontent.audio_bitpersample,
                                                                        NULL);
 
                        if(ret != MM_ERROR_NONE) {
@@ -265,6 +272,7 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                                printf("# audio channel: %d\n", ccontent.audio_channel);
                                printf("# audio track id: %d\n", ccontent.audio_track_id);
                                printf("# audio track num: %d\n", ccontent.audio_track_num);
+                               printf("# audio bit per sample: %d\n", ccontent.audio_bitpersample);
                        }
                }
        
@@ -354,7 +362,7 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                                fclose (msg_tmp_fp);
                                msg_tmp_fp = NULL;
                        }
-
+                       mm_file_destroy_tag_attrs(tag_attrs);
                        return -1;
                }
 
@@ -405,7 +413,15 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                }
                
                /* release tag */
-               mm_file_destroy_tag_attrs(tag_attrs);
+               ret = mm_file_destroy_tag_attrs(tag_attrs);
+               if (ret != MM_ERROR_NONE) {
+                       printf("Error mm_file_destroy_tag_attrs: %d", ret);
+                       if (msg_tmp_fp) {
+                               fclose (msg_tmp_fp);
+                               msg_tmp_fp = NULL;
+                       }
+                       return -1;
+               }
        } else {
                printf ("Failed to mm_file_create_tag_attrs() error=[%x]\n", ret);
        }
index 994f91f..000ee9c 100755 (executable)
@@ -36,7 +36,8 @@ static GList *g_directories = NULL;
 int mmfile_get_file_names (char *root_dir, MMFunc cbfunc, void* user_data)
 {
        struct stat     statbuf;
-       struct dirent   *dirp;
+       struct dirent   dirp;
+       struct dirent *result = NULL;
        DIR                             *dp;
 
        char pdirname[MMFILE_PATH_MAX+1];
@@ -64,24 +65,24 @@ int mmfile_get_file_names (char *root_dir, MMFunc cbfunc, void* user_data)
        {
                if (strlen ((char*) element_data) > 0 && strlen ((char*) element_data) <= MMFILE_PATH_MAX)
                {
-                       strcpy (pdirname, (char*) element_data);
+                       strncpy (pdirname, (char*) element_data, strlen((char*) element_data));
                                
                        if ( (dp = opendir (pdirname)) != NULL )
                        {
-                               while ( (dirp = readdir (dp)) != NULL )
+                               while (!readdir_r(dp, &dirp, &result))
                                {
                                        char cdirname[MMFILE_PATH_MAX+1];
                                        
-                                       if ( strcmp (dirp->d_name, ".") == 0 ||
-                                                strcmp (dirp->d_name, "..") == 0 )
+                                       if ( strcmp (dirp.d_name, ".") == 0 ||
+                                                strcmp (dirp.d_name, "..") == 0 )
                                        {
                                                continue;
                                        }
 
                                        memset (cdirname, 0x00, MMFILE_PATH_MAX+1);
-                                       strcpy (cdirname, pdirname);
-                                       strcat (cdirname, "/");
-                                       strcat (cdirname, dirp->d_name);
+                                       strncpy (cdirname, pdirname, strlen(pdirname));
+                                       strncat (cdirname, "/", 1);
+                                       strncat (cdirname, dirp.d_name, strlen(dirp.d_name));
                                                
                                        if ( lstat (cdirname, &statbuf) < 0 )
                                        {
index a47d845..43a6cb3 100755 (executable)
@@ -19,12 +19,22 @@ libmmfile_utils_la_CFLAGS = -I$(srcdir)/include \
                       -I$(srcdir)/../include \
                       $(MMCOMMON_CFLAGS) \
                       -D_LARGEFILE64_SOURCE \
-                      -D_FILE_OFFSET_BITS=64
+                      -D_FILE_OFFSET_BITS=64 \
+                      $(ICU_CFLAGS) \
+                      $(VCONF_CFLAGS)
 if USE_TESTMODE
 libmmfile_utils_la_CFLAGS += -D__MMFILE_TEST_MODE__
 endif  
 
-libmmfile_utils_la_LIBADD = $(MMCOMMON_LIBS)
+libmmfile_utils_la_LIBADD = $(MMCOMMON_LIBS) \
+                           $(ICU_LIBS) \
+                           $(VCONF_LIBS)
+
+if USE_DRM
+libmmfile_utils_la_SOURCES += mm_file_util_io_drm.c 
+libmmfile_utils_la_CFLAGS += $(DRMCLIENT_CFLAGS) $(DRMTRUSTED_CFLAGS) -DDRM_SUPPORT
+libmmfile_utils_la_LIBADD += $(DRMCLIENT_LIBS) $(DRMTRUSTED_LIBS)
+endif
 
 libmmfile_utils_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x040 -DMMF_DEBUG_PREFIX=\"MMF-FILE-UTILS\"
 libmmfile_utils_la_LIBADD += $(MMLOG_LIBS)
index ce11701..64d8e23 100755 (executable)
@@ -90,10 +90,15 @@ int MMFileFormatIsValidIMY (MMFileIOHandle *pFileIO, const char *mmfileuri);
 int MMFileFormatIsValidWMA (MMFileIOHandle *pFileIO, const char *mmfileuri);
 int MMFileFormatIsValidWMV (MMFileIOHandle *pFileIO, const char *mmfileuri);
 int MMFileFormatIsValidOGG (MMFileIOHandle *pFileIO, const char *mmfileuri);
+int MMFileFormatIsValidREAL(MMFileIOHandle *pFileIO, const char * mmfileuri);
 int MMFileFormatIsValidMatroska (MMFileIOHandle *pFileIO, const char *mmfileuri);
 int MMFileFormatIsValidQT (MMFileIOHandle *pFileIO, const char *mmfileuri);
 int MMFileFormatIsValidFLAC (MMFileIOHandle *pFileIO, const char *mmfileuri);
 int MMFileFormatIsValidFLV (MMFileIOHandle *pFileIO, const char *mmfileuri);
+int MMFileFormatIsValidMPEGTS (MMFileIOHandle *pFileIO, const char *mmfileuri);
+int MMFileFormatIsValidMPEGPS (MMFileIOHandle *pFileIO, const char *mmfileuri);
+int MMFileFormatIsValidMPEGVIDEO (MMFileIOHandle *pFileIO, const char *mmfileuri);
+int MMFileFormatIsValidMPEGAUDIO (MMFileIOHandle *pFileIO, const char *mmfileuri);
 
 
 ////////////////////////////////////////////////////////////////////////
@@ -172,6 +177,7 @@ char **mmfile_strsplit (const char *string, const char *delimiter);
 void mmfile_strfreev (char **str_array);
 int  mmfile_util_wstrlen (unsigned short *wText);
 short* mmfile_swap_2byte_string (short* mszOutput, short* mszInput, int length);
+char *mmfile_get_charset(const char *str);
 char *mmfile_string_convert (const char *str, unsigned int len,
                              const char *to_codeset, const char *from_codeset,
                              unsigned int *bytes_read,
@@ -363,17 +369,18 @@ typedef enum {
 
 
 typedef enum {
-       AV_ID3V2_ISO_8859,
+       AV_ID3V2_ISO_8859 = 0,
        AV_ID3V2_UTF16,
        AV_ID3V2_UTF16_BE,
-       AV_ID3V2_UTF8
+       AV_ID3V2_UTF8,
+       AV_ID3V2_MAX
        
 } AvID3v2EncodingType;
 
 
 typedef struct{
        char    *pImageBuf;
-       char    imageDescription[MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH];
+       char    *imageDescription;
        char    imageMIMEType[MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH];
        char    imageExt[MP3_ID3_IMAGE_EXT_MAX_LENGTH];
        int             pictureType;
@@ -393,6 +400,7 @@ typedef struct{
        bool    bTitleMarked;
        bool    bArtistMarked;
        bool    bAlbumMarked;
+       bool    bAlbum_ArtistMarked;
        bool    bYearMarked;
        bool    bDescriptionMarked;
        bool    bGenreMarked;
@@ -430,8 +438,8 @@ typedef struct
        int             genreLen;
        int             tracknumLen;
        int             recdateLen;
-       
        int             conductorLen;
+       int             album_artistLen;
        
 // for PC Studio Podcast
        int     contentGroupLen;
@@ -547,6 +555,7 @@ inline static void mm_file_free_AvFileContentInfo (AvFileContentInfo *pInfo)
                if (pInfo->pComposer) mmfile_free (pInfo->pComposer);
                if (pInfo->pUnsyncLyrics) mmfile_free (pInfo->pUnsyncLyrics);
                if (pInfo->imageInfo.pImageBuf) mmfile_free (pInfo->imageInfo.pImageBuf);
+               if (pInfo->imageInfo.imageDescription) mmfile_free (pInfo->imageInfo.imageDescription);
                if (strlen(pInfo->imageInfo.imageMIMEType)>0) memset(pInfo->imageInfo.imageMIMEType, 0, MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH);
                if (pInfo->pTransactionID) mmfile_free (pInfo->pTransactionID);
 
index adc8f0a..f915b5a 100755 (executable)
@@ -302,10 +302,16 @@ int mmfile_register_io_all ()
        initialized = 1;
 
        extern MMFileIOFunc mmfile_file_io_handler;
+#ifdef DRM_SUPPORT
+       extern MMFileIOFunc mmfile_drm_io_handler;
+#endif
        extern MMFileIOFunc mmfile_mem_io_handler;
        extern MMFileIOFunc mmfile_mmap_io_handler;
 
        mmfile_register_io_func (&mmfile_file_io_handler);
+#ifdef DRM_SUPPORT
+       mmfile_register_io_func (&mmfile_drm_io_handler);
+#endif
        mmfile_register_io_func (&mmfile_mem_io_handler);    
        mmfile_register_io_func (&mmfile_mmap_io_handler);
 
diff --git a/utils/mm_file_util_io_drm.c b/utils/mm_file_util_io_drm.c
new file mode 100755 (executable)
index 0000000..a989903
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * libmm-fileinfo
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Haejeong Kim <backto.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <drm_client.h>
+#include <drm_trusted_client.h>
+#include "mm_file_debug.h"
+#include "mm_file_utils.h"
+
+typedef struct
+{
+    DRM_DECRYPT_HANDLE hfile;
+    long long offset;
+    long long fsize;
+} MMFileDRMHandle;
+
+
+static int mmfile_drm_open(MMFileIOHandle *h, const char *pseudofilename, int flags)
+{
+       MMFileDRMHandle *drmHandle = NULL;
+       drm_bool_type_e res = DRM_TRUE;
+       drm_file_type_e file_type = DRM_TYPE_UNDEFINED;
+       drm_trusted_open_decrypt_info_s open_input_data;
+       drm_trusted_open_decrypt_resp_data_s open_output_data;
+       drm_trusted_seek_decrypt_info_s seek_input_data;
+       drm_trusted_tell_decrypt_resp_data_s tell_output_data;
+       drm_trusted_set_consumption_state_info_s state_input_data;
+       int ret = 0;
+
+       if (!h || !pseudofilename || !h->iofunc || !h->iofunc->handleName)
+       {
+               debug_error ("invalid param\n");
+               return MMFILE_IO_FAILED;
+       }
+
+       pseudofilename += strlen(h->iofunc->handleName) + 3; /* :// */
+
+       /* Check is DRM */
+       ret = drm_is_drm_file (pseudofilename, &res);
+       if (DRM_FALSE == res)
+       {
+               debug_error ("error: %s is not DRM file. ret[%x]\n", pseudofilename, ret);
+               return MMFILE_IO_FAILED;
+       }
+       if(ret != DRM_RETURN_SUCCESS)
+       {
+               debug_error ("error: %s is not DRM file. ret[%x]\n", pseudofilename, ret);
+               return MMFILE_IO_FAILED;
+       }
+
+       /* Checks the DRM file type (supports only for OMA) if it is DRM */
+       ret = drm_get_file_type(pseudofilename, &file_type);
+       if(ret != DRM_RETURN_SUCCESS)
+       {
+               debug_error ("error: %s is not DRM file. ret[%x]\n", pseudofilename, ret);
+               return MMFILE_IO_FAILED;
+       }
+       if((file_type != DRM_TYPE_OMA_V1) && (file_type != DRM_TYPE_OMA_V2))
+       {
+               debug_error ("error: %s is not DRM file. file_type[%d]\n", pseudofilename, file_type);
+               return MMFILE_IO_FAILED;
+       }
+
+       /* Set DRM handle*/
+       drmHandle = mmfile_malloc (sizeof(MMFileDRMHandle));
+       if (NULL == drmHandle)
+       {
+               debug_error ("error: mmfile_malloc\n");
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle->hfile = NULL;
+       drmHandle->offset = 0;
+
+       /* Open DRM File*/
+       memset(&open_input_data, 0x0, sizeof(drm_trusted_open_decrypt_info_s));
+       memset(&open_output_data, 0x0, sizeof(drm_trusted_open_decrypt_resp_data_s));
+
+       memcpy(open_input_data.filePath, pseudofilename, strlen(pseudofilename));
+       if(file_type == DRM_TYPE_OMA_V1)        open_input_data.file_type = DRM_TRUSTED_TYPE_OMA_V1;
+       else    open_input_data.file_type = DRM_TRUSTED_TYPE_OMA_V2;
+       open_input_data.permission = DRM_TRUSTED_PERMISSION_TYPE_DISPLAY;
+       //open_input_data.operation_callback.callback;
+
+       ret = drm_trusted_open_decrypt_session(&open_input_data,&open_output_data, &drmHandle->hfile);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_open_decrypt_session() [%x]\n", ret);
+               ret = MMFILE_IO_FAILED;
+               goto exception;
+       }
+
+       /* Seek End*/
+       memset(&seek_input_data, 0x0, sizeof(drm_trusted_seek_decrypt_info_s));
+       seek_input_data.offset = 0;
+       seek_input_data.seek_mode = DRM_SEEK_END; /* Set cursor to end */
+
+       ret = drm_trusted_seek_decrypt_session(drmHandle->hfile, &seek_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_seek_decrypt_session() [%x]\n", ret);
+               ret = MMFILE_IO_FAILED;
+               goto exception;
+       }
+
+       /* Tell to get the file size */
+       memset(&tell_output_data, 0x0, sizeof(drm_trusted_tell_decrypt_resp_data_s));
+       ret = drm_trusted_tell_decrypt_session(drmHandle->hfile, &tell_output_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_tell_decrypt_session() [%x]\n", ret);
+               ret = MMFILE_IO_FAILED;
+               goto exception;
+       }
+
+       drmHandle->fsize = tell_output_data.offset;
+
+       /* Seek Set*/
+       memset(&seek_input_data, 0x0, sizeof(drm_trusted_seek_decrypt_info_s));
+       seek_input_data.offset = 0;
+       seek_input_data.seek_mode = DRM_SEEK_SET;
+       ret = drm_trusted_seek_decrypt_session(drmHandle->hfile, &seek_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_seek_decrypt_session() [%x]\n", ret);
+               ret = MMFILE_IO_FAILED;
+               goto exception;
+       }
+
+       h->privateData = (void *) drmHandle;
+
+       /* Set Consumption state*/
+       memset(&state_input_data, 0x0, sizeof(drm_trusted_set_consumption_state_info_s));
+       state_input_data.state = DRM_CONSUMPTION_PREVIEW;
+       ret = drm_trusted_set_decrypt_state(drmHandle->hfile, &state_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_set_decrypt_state [%x]\n", ret);
+               ret = MMFILE_IO_FAILED;
+               goto exception;
+       }
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg ("drm open success===============\n");
+#endif
+
+       return MMFILE_IO_SUCCESS;
+
+exception:
+       if (drmHandle)
+       {
+               if (drmHandle->hfile)
+               {
+                   drm_trusted_close_decrypt_session(&drmHandle->hfile);
+               }
+
+               mmfile_free(drmHandle);
+               h->privateData = NULL;
+       }
+
+       return ret;
+}
+
+static int mmfile_drm_read(MMFileIOHandle *h, unsigned char *buf, int size)
+{
+       MMFileDRMHandle *drmHandle =NULL;
+       drm_trusted_payload_info_s read_input_data;
+       drm_trusted_read_decrypt_resp_data_s read_output_data;
+       int ret = 0;
+
+       if (!h || !h->privateData || !buf)
+       {
+               debug_error ("invalid param\n");
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle = h->privateData;
+
+       memset(&read_input_data,0x0,sizeof(drm_trusted_payload_info_s));
+       memset(&read_output_data,0x0,sizeof(drm_trusted_read_decrypt_resp_data_s));
+
+       read_input_data.payload_data = buf;
+       read_input_data.payload_data_len = (unsigned int)size;
+       read_input_data.payload_data_output = buf;
+
+       ret = drm_trusted_read_decrypt_session(drmHandle->hfile, &read_input_data, &read_output_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_read_decrypt_session() [%x]\n", ret);
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle->offset += read_output_data.read_size;
+
+       return read_output_data.read_size;
+}
+
+
+static long long mmfile_drm_seek(MMFileIOHandle *h, long long pos, int whence)
+{
+       MMFileDRMHandle *drmHandle = NULL;
+       drm_trusted_seek_mode_e drm_whence;
+       drm_trusted_seek_decrypt_info_s seek_input_data;
+       int ret = 0;
+
+       if (!h || !h->privateData) {
+               debug_error ("invalid param\n");
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle = h->privateData;
+
+       switch (whence) {
+               case MMFILE_SEEK_SET:
+                       drm_whence = DRM_SEEK_SET;
+                       break;
+               case MMFILE_SEEK_CUR:
+                       drm_whence = DRM_SEEK_CUR;
+                       break;
+               case MMFILE_SEEK_END:
+                       drm_whence = DRM_SEEK_END;
+                       break;
+               default:
+                       debug_error ("invalid whence[%d]\n", whence);
+                       return MMFILE_IO_FAILED;
+       }
+
+       memset(&seek_input_data, 0x0, sizeof(drm_trusted_seek_decrypt_info_s));
+       seek_input_data.offset = pos;
+       seek_input_data.seek_mode = drm_whence;
+
+       ret = drm_trusted_seek_decrypt_session(drmHandle->hfile, &seek_input_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_seek_decrypt_session() [%x] [mode=%d]\n", ret, drm_whence);
+               return MMFILE_IO_FAILED;
+       }
+
+       switch (drm_whence) {
+               case DRM_SEEK_SET: {
+                       drmHandle->offset = pos;
+                       break;
+               }
+               case DRM_SEEK_CUR: {
+                       drmHandle->offset += pos;
+                       break;
+               }
+               case DRM_SEEK_END: {
+                       drmHandle->offset = drmHandle->fsize + pos;
+                       break;
+               }
+       }
+
+       if (drmHandle->offset > drmHandle->fsize) {
+               return MMFILE_IO_FAILED;
+       }
+
+       return drmHandle->offset;
+}
+
+static long long mmfile_drm_tell (MMFileIOHandle *h)
+{
+       MMFileDRMHandle *drmHandle = NULL;
+       drm_trusted_tell_decrypt_resp_data_s tell_output_data;
+       int ret = 0;
+
+       if (!h || !h->privateData)
+       {
+               debug_error ("invalid param\n");
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle = h->privateData;
+
+       memset(&tell_output_data, 0x0, sizeof(drm_trusted_tell_decrypt_resp_data_s));
+       ret = drm_trusted_tell_decrypt_session(drmHandle->hfile, &tell_output_data);
+       if (ret != DRM_TRUSTED_RETURN_SUCCESS)
+       {
+               debug_error ("error: drm_trusted_tell_decrypt_session() [%x]\n", ret);
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle->offset = tell_output_data.offset;
+
+       return drmHandle->offset;
+}
+
+static int mmfile_drm_close(MMFileIOHandle* h)
+{
+       MMFileDRMHandle *drmHandle = NULL;
+       drm_trusted_set_consumption_state_info_s state_input_data;
+       int ret = 0;
+
+       if (!h || !h->privateData)
+       {
+               debug_error ("invalid param\n");
+               return MMFILE_IO_FAILED;
+       }
+
+       drmHandle = h->privateData;
+
+       /* Set Consumption state*/
+       memset(&state_input_data,0x0,sizeof(drm_trusted_set_consumption_state_info_s));
+       state_input_data.state = DRM_CONSUMPTION_STOPPED;
+       ret = drm_trusted_set_decrypt_state(drmHandle->hfile, &state_input_data);
+       if(ret != DRM_TRUSTED_RETURN_SUCCESS) {
+               debug_error ("error: drm_trusted_set_decrypt_state() [%x]\n", ret);
+       } else {
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg ("Success : drm_trusted_set_decrypt_state\n");
+               #endif
+       }
+
+       if (drmHandle)
+       {
+               if (drmHandle->hfile)
+               {
+                       ret = drm_trusted_close_decrypt_session(&drmHandle->hfile);
+                       if(ret != DRM_TRUSTED_RETURN_SUCCESS) {
+                               debug_error ("error: drm_trusted_close_decrypt_session() [%x]\n", ret);
+                       } else {
+                               #ifdef __MMFILE_TEST_MODE__
+                               debug_msg ("Success : drm_trusted_close_decrypt_session\n");
+                               #endif
+                       }
+
+                       drmHandle->hfile = NULL;
+               }
+
+               mmfile_free (drmHandle);
+               h->privateData = NULL;
+       }
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg ("drm close success===============\n");
+#endif
+
+       return MMFILE_IO_SUCCESS;
+}
+
+
+MMFileIOFunc mmfile_drm_io_handler = {
+       "drm",
+       mmfile_drm_open,
+       mmfile_drm_read,
+       NULL,
+       mmfile_drm_seek,
+       mmfile_drm_tell,
+       mmfile_drm_close
+};
index 6d23d1a..a8bba4e 100755 (executable)
@@ -21,6 +21,7 @@
  
 #include <stdlib.h> 
 #include <string.h>
+#include <vconf.h>
 
 #ifdef GCONF_SUPPORT
 #include <gconf/gconf-client.h>
 #define MMFILE_LANGUAGETYPE_REPOSITORY      "/Apps/Settings/language_type"
 typedef enum
 {
-    MMFILE_LANGUAGE_ENGLISH = 0x00,     /**<Language - English*/
-    MMFILE_LANGUAGE_GERMAN,             /**<Language - German*/
-    MMFILE_LANGUAGE_FRENCH,             /**<Language - French*/
-    MMFILE_LANGUAGE_ITALIAN,            /**<Language - Italian*/
-    MMFILE_LANGUAGE_DUTCH,              /**<Language - Dutch*/
-    MMFILE_LANGUAGE_SPANISH,            /**<Language - Spanish*/
-    MMFILE_LANGUAGE_GREEK,              /**<Language - Greek*/
-    MMFILE_LANGUAGE_PORTUGUESE,         /**<Language - Portuguese*/
-    MMFILE_LANGUAGE_TURKISH,            /**<Language - Turkish*/
+       MMFILE_LANGUAGE_ENGLISH = 0x00, /**<Language - English*/
+       MMFILE_LANGUAGE_GERMAN,                 /**<Language - German*/
+       MMFILE_LANGUAGE_FRENCH,                 /**<Language - French*/
+       MMFILE_LANGUAGE_ITALIAN,                        /**<Language - Italian*/
+       MMFILE_LANGUAGE_DUTCH,                  /**<Language - Dutch*/
+       MMFILE_LANGUAGE_SPANISH,                        /**<Language - Spanish*/
+       MMFILE_LANGUAGE_GREEK,                  /**<Language - Greek*/
+       MMFILE_LANGUAGE_PORTUGUESE,             /**<Language - Portuguese*/
+       MMFILE_LANGUAGE_TURKISH,                        /**<Language - Turkish*/
+       MMFILE_LANGUAGE_JAPAN_CP932,            /**<Language - Japanease for CP932*/
+       MMFILE_LANGUAGE_SIM_CHINA,              /**<Language - Simplified Chinese*/
+       MMFILE_LANGUAGE_TRA_CHINA,              /**<Language - Traditional Chinese*/
+       MMFILE_LANGUAGE_JAPAN,                  /**<Language - Japanease*/
 #if 0        
-    MMFILE_LANGUAGE_BULGARIAN,          /**<Language - Bulgarian*/
-    MMFILE_LANGUAGE_ARABIC,             /**<Language - Arabic*/
+       MMFILE_LANGUAGE_BULGARIAN,              /**<Language - Bulgarian*/
+       MMFILE_LANGUAGE_ARABIC,                 /**<Language - Arabic*/
 #endif
     MMFILE_LANGUAGE_MAX
 } eMMFileSettingPhoneLanguage;
 
 const char *MMFILE_LOCALE_TABLE [MMFILE_LANGUAGE_MAX] =
 {
-    "EUC-KR",       /* Temporally - Language - English */
-    "ISO8859-1",       /* Language - German */
-    "ISO8859-1",       /* Language - French */
-    "ISO8859-1",       /* Language - Italian */
-    "ISO8859-1",       /* Temporally -  Language - Dutch */
-    "ISO8859-1",       /* Language - Spanish */
-    "ISO8859-7",    /* Language - Greek */
-    "ISO8859-1",       /* Language - Portuguese */
-    "ISO8859-3",       /* Language - Turkish */
+       "EUC-KR",               /* Temporally - Language - English */
+       "ISO8859-1",            /* Language - German */
+       "ISO8859-1",            /* Language - French */
+       "ISO8859-1",            /* Language - Italian */
+       "ISO8859-1",            /* Temporally -  Language - Dutch */
+       "ISO8859-1",            /* Language - Spanish */
+       "ISO8859-7",            /* Language - Greek */
+       "ISO8859-1",            /* Language - Portuguese */
+       "ISO8859-3",            /* Language - Turkish */
+       "CP932",                        /* Language - Japan*/
+       "GBK",                  /* Language - Simplified Chinese */
+       "BIG5",                 /* Language - Traditional Chinese */
+       "SHIFT_JIS"             /* Language - Japanease */
 #if 0
-                    /* Language - Bulgarian */
-                    /* Language - Arabic */
+                                       /* Language - Bulgarian */
+                                       /* Language - Arabic */
 #endif
 };
 
 
+static int _MMFileUtilGetLocaleindex()
+{
+       int index = MMFILE_LANGUAGE_ENGLISH;
+       char *lang = NULL;
+
+       const char *china_prefix = "zh";
+       const char *eng_prefix = "en";
+
+       const char *china_lang = "zh_CN";
+       const char *hongkong_lang = "zh_HK";
+       const char *taiwan_lang = "zh_TW";
+       const char *jpn_lang = "ja_JP";
+
+       lang = vconf_get_str(VCONFKEY_LANGSET);
+
+       if (lang != NULL) {
+               if (strncmp(lang,china_prefix, strlen(china_prefix)) == 0) {
+                       /* This case is selected language is china */
+                       if (strncmp(lang, china_lang, strlen(china_lang)) == 0) {
+                               debug_msg("[%s]character set is simplified chinese", lang);
+                               index = MMFILE_LANGUAGE_SIM_CHINA;
+                       } else {
+                               debug_msg("[%s]character set is traditional chinese", lang);
+                               index = MMFILE_LANGUAGE_TRA_CHINA;
+                       }
+               } else if (strncmp(lang, eng_prefix, strlen(eng_prefix)) == 0) {
+                       /* This case is selected language is engilish
+                            In case of engilish, the character set is related with region of target binary */
+                       debug_msg("[%s]character set is engilish", lang);
+                       index = MMFILE_LANGUAGE_ENGLISH;
+               } else if (strncmp(lang, jpn_lang, strlen(jpn_lang)) == 0) {
+                       /* This case is selected language is japanease */
+                       debug_msg("[%s]character set is japanease", lang);
+                       index = MMFILE_LANGUAGE_JAPAN;
+               } else {
+                       debug_error("use default character set");
+                       index = MMFILE_LANGUAGE_ENGLISH;
+               }
+       } else {
+               debug_error("language value is NULL, use default character set");
+               index = MMFILE_LANGUAGE_ENGLISH;
+       }
+
+       if(lang) {
+               free(lang);
+               lang = NULL;
+       }
+
+       return index;
+}
+
 EXPORT_API
 char *MMFileUtilGetLocale (int *error)
 {
-#ifdef GCONF_SUPPORT
-    GConfClient *client = NULL;
-#endif
-    int index = 0;
-    int err = 0;
-   
-    /* get enum of language through gconf*/
-#ifdef GCONF_SUPPORT
-    g_type_init();
-#endif
-    
-#ifdef GCONF_SUPPORT
-    client = gconf_client_get_default ();
-    if (client)
-    {
-        index = gconf_client_get_int (client, MMFILE_LANGUAGETYPE_REPOSITORY, NULL);
-        g_object_unref (client);
-    }
-    else
-#endif
-    {
-        index = 0;
-        //debug_warning ("fail to get gconf-client\n");
-    }
-    
-    if (index < 0 || index >= MMFILE_LANGUAGE_MAX)
-    {
-        debug_error ("invalid index\n");
-        err = MMFILE_UTIL_FAIL;
-        return NULL;
-    }
-
-    err = MMFILE_UTIL_SUCCESS;
-    if (error)
-    {
-        *error = err;
-    }
-    
-    return (char *)MMFILE_LOCALE_TABLE[index];
+       int index = 0;
+       int err = 0;
+       index = _MMFileUtilGetLocaleindex();
+
+       if (index < 0 || index >= MMFILE_LANGUAGE_MAX)
+       {
+               debug_error ("invalid index\n");
+               err = MMFILE_UTIL_FAIL;
+               return NULL;
+       }
+
+       err = MMFILE_UTIL_SUCCESS;
+       if (error)
+       {
+               *error = err;
+       }
+
+       return (char *)MMFILE_LOCALE_TABLE[index];
 }
 
index 70bfb51..b88733c 100755 (executable)
@@ -32,7 +32,9 @@ void *mmfile_malloc_debug (unsigned int size, const char *func, unsigned int lin
 
        if (tmp) {
                memset (tmp, 0x00, size);
-               fprintf (stderr, "## DEBUG ## %p = malloc (%d) by %s() %d\n", tmp, size, func, line);
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg("## DEBUG ## %p = malloc (%d) by %s() %d\n", tmp, size, func, line);
+               #endif
        }
        return tmp;
 }
@@ -43,7 +45,9 @@ void *mmfile_calloc_debug (unsigned int nmemb, unsigned int size, const char *fu
        void *tmp = calloc (nmemb, size);
 
        if (tmp) {
-               fprintf (stderr, "## DEBUG ## %p = calloc (%d, %d) by %s() %d\n", tmp, nmemb, size, func, line);
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg("## DEBUG ## %p = calloc (%d, %d) by %s() %d\n", tmp, nmemb, size, func, line);
+               #endif
        }
        return tmp;
 }
@@ -52,7 +56,9 @@ EXPORT_API
 void mmfile_free_debug (void *ptr, const char *func, unsigned int line)
 {
        if (ptr) {
-               fprintf (stderr, "## DEBUG ## free (%p) by %s() %d\n", ptr, func, line);
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg("## DEBUG ## free (%p) by %s() %d\n", ptr, func, line);
+               #endif
                free (ptr);
        }
 }
@@ -64,7 +70,9 @@ void *mmfile_realloc_debug (void *ptr, unsigned int size, const char *func, unsi
        void *tmp = realloc (ptr, size);
 
        if (tmp) {
-               fprintf (stderr, "## DEBUG ## %p = realloc (%p, %d) by %s() %d\n", tmp, ptr, size, func, line);
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg("## DEBUG ## %p = realloc (%p, %d) by %s() %d\n", tmp, ptr, size, func, line);
+               #endif
        }
        return tmp;
 }
@@ -72,14 +80,18 @@ void *mmfile_realloc_debug (void *ptr, unsigned int size, const char *func, unsi
 EXPORT_API
 void *mmfile_memset_debug (void *s, int c, unsigned int n, const char *func, unsigned int line)
 {
-       fprintf (stderr, "## DEBUG ## memset (%p, %d, %d) by %s() %d\n", s, c, n, func, line);
+       #ifdef __MMFILE_TEST_MODE__
+       debug_msg("## DEBUG ## memset (%p, %d, %d) by %s() %d\n", s, c, n, func, line);
+       #endif
        return memset (s, c, n);
 }
 
 EXPORT_API
 void *mmfile_memcpy_debug (void *dest, const void *src, unsigned int n, const char *func, unsigned int line)
 {
-       fprintf (stderr, "## DEBUG ## memcpy (%p, %p, %d) by %s() %d\n", dest, src, n, func, line);
+       #ifdef __MMFILE_TEST_MODE__
+       debug_msg("## DEBUG ## memcpy (%p, %p, %d) by %s() %d\n", dest, src, n, func, line);
+       #endif
        return memcpy (dest, src, n);
 }
 
index a461f3e..6e447e8 100755 (executable)
@@ -24,7 +24,6 @@
 #include "mm_debug.h"
 #include "mm_file_utils.h"
 
-
 typedef struct _mmfileavmimetype
 {
     char    mimetype[MMFILE_MIMETYPE_MAX_LEN];    
@@ -32,7 +31,6 @@ typedef struct _mmfileavmimetype
     char    extension[MMFILE_FILE_EXT_MAX_LEN];
 } MMFileAVMimeType;
 
-#define __FFMPEG_MIME_TABLE_SIZE 75
 const MMFileAVMimeType MMFILE_FFMPEG_MIME_TABLE [] =
 {
     {"audio/mpeg",          "mp3",      "mp3"},
@@ -52,6 +50,7 @@ const MMFileAVMimeType MMFILE_FFMPEG_MIME_TABLE [] =
     {"video/3gpp",          "mov,mp4,m4a,3gp,3g2,mj2",      "3gp"},
     {"video/mp4v-es",       "mov,mp4,m4a,3gp,3g2,mj2",      "mp4"},
     {"video/mpeg",          "mov,mp4,m4a,3gp,3g2,mj2",      "mpeg"},
+    {"video/dvd",          "mov,mp4,m4a,3gp,3g2,mj2",      "mpeg"},
     {"audio/3gpp",          "mov,mp4,m4a,3gp,3g2,mj2",      "3gp"},  //17
 
     {"video/mpeg4",         "mov,mp4,m4a,3gp,3g2,mj2",      "mp4"},
@@ -124,8 +123,11 @@ const MMFileAVMimeType MMFILE_FFMPEG_MIME_TABLE [] =
     {"audio/x-ogg",         "ogg",      "ogg"},
     {"audio/vorbis",        "ogg",      "ogg"},  //73
 
-       {"audio/x-flac",        "flac",      "flac"},  //74
-       {"video/x-flv",        "flv",      "flv"},  //75
+    {"audio/x-flac",        "flac",      "flac"},  //74
+    {"video/x-flv",        "flv",      "flv"},  //75
+    {"video/MP2T",        "mpegts",      "ts"},
+    {"video/MP2P",        "mpeg",      "mpg"},
+    {"video/mpeg",          "mpegvideo",      "mpeg"}, //mpeg 1 video
 };
 
 
@@ -133,6 +135,7 @@ EXPORT_API
 int mmfile_util_get_ffmpeg_format (const char *mime, char *ffmpegFormat)
 {
     int i = 0;
+       int table_size = sizeof(MMFILE_FFMPEG_MIME_TABLE) / sizeof(MMFileAVMimeType);
 
     if ( NULL == mime || NULL == ffmpegFormat)
     {
@@ -140,7 +143,7 @@ int mmfile_util_get_ffmpeg_format (const char *mime, char *ffmpegFormat)
         return MMFILE_UTIL_FAIL;
     }
 
-    for (i = 0; i < __FFMPEG_MIME_TABLE_SIZE; i++)
+    for (i = 0; i < table_size; i++)
     {
         if (!strcasecmp (MMFILE_FFMPEG_MIME_TABLE[i].mimetype, mime))
         {
@@ -148,7 +151,7 @@ int mmfile_util_get_ffmpeg_format (const char *mime, char *ffmpegFormat)
         }
     }
 
-    if (i == __FFMPEG_MIME_TABLE_SIZE)
+    if (i == table_size)
     {
         debug_error ("error: not found[%s]\n", mime);
         return MMFILE_UTIL_FAIL;    
@@ -164,6 +167,7 @@ EXPORT_API
 int mmfile_util_get_file_ext (const char *mime, char *ext)
 {
     int i = 0;
+       int table_size = sizeof(MMFILE_FFMPEG_MIME_TABLE) / sizeof(MMFileAVMimeType);
 
     if ( NULL == mime || NULL == ext)
     {
@@ -171,7 +175,7 @@ int mmfile_util_get_file_ext (const char *mime, char *ext)
         return MMFILE_UTIL_FAIL;
     }
 
-    for (i = 0; i < __FFMPEG_MIME_TABLE_SIZE; i++)
+    for (i = 0; i < table_size; i++)
     {
         if (!strcasecmp (MMFILE_FFMPEG_MIME_TABLE[i].mimetype, mime))
         {
@@ -179,7 +183,7 @@ int mmfile_util_get_file_ext (const char *mime, char *ext)
         }
     }
 
-    if (i == __FFMPEG_MIME_TABLE_SIZE)
+    if (i == table_size)
     {
         debug_error ("error: not found[%s]\n", mime);
         return MMFILE_UTIL_FAIL;    
index c8bf28b..41432f1 100755 (executable)
@@ -22,6 +22,7 @@
 #include <stdlib.h> 
 #include <string.h>
 #include <glib.h>
+#include <unicode/ucsdet.h>
 #include "mm_debug.h"
 #include "mm_file_utils.h"
 
@@ -83,8 +84,10 @@ char *mmfile_string_convert_debug (const char *str, unsigned int len,
 
     if (tmp)
     {
-        fprintf (stderr, "## DEBUG ## %p = g_convert (%p, %u, %p, %p, %p ,%p, %p, %u) by %s() %d\n",
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg("## DEBUG ## %p = g_convert (%p, %u, %p, %p, %p ,%p, %p, %u) by %s() %d\n",
                           tmp, str, len, to_codeset, from_codeset, bytes_read, bytes_written, func, line);
+#endif
     }
 
     return tmp;
@@ -114,7 +117,9 @@ char *mmfile_strdup_debug (const char *str, const char *func, unsigned int line)
     temp = strdup (str);
 
     if (temp) {
-        fprintf (stderr, "## DEBUG ## %p = strdup (%p) by %s() %d\n", temp, str, func, line);
+#ifdef __MMFILE_TEST_MODE__
+        debug_msg("## DEBUG ## %p = strdup (%p) by %s() %d\n", temp, str, func, line);
+#endif
     }
 
     return temp; 
@@ -145,20 +150,97 @@ int  mmfile_util_wstrlen (unsigned short *wText)
 }
 
 EXPORT_API
+char *mmfile_get_charset(const char *str)
+{
+       UCharsetDetector* ucsd = NULL;
+       const UCharsetMatch* ucm = NULL;
+       UErrorCode status = U_ZERO_ERROR;
+
+       const char* charset = NULL;
+       char *ret_charset = NULL;
+
+       ucsd = ucsdet_open( &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_open\n");
+               return NULL;
+       }
+
+       ucsdet_enableInputFilter( ucsd, TRUE );
+
+       ucsdet_setText( ucsd, str, strlen(str), &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_setText\n");
+               goto done;
+       }
+
+       ucm = ucsdet_detect( ucsd, &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_detect\n");
+               goto done;
+       }
+
+       if (ucm == NULL) {
+               debug_error("fail to ucsdet_detect\n");
+               goto done;
+       }
+
+       charset = ucsdet_getName( ucm, &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_getName\n");
+               charset = NULL;
+               goto done;
+       }
+
+done:
+
+       if (charset != NULL)
+               ret_charset = strdup(charset);
+
+       ucsdet_close( ucsd );
+
+       return ret_charset;
+}
+
+EXPORT_API
 char *mmfile_string_convert (const char *str, unsigned int len,
                              const char *to_codeset, const char *from_codeset,
                              unsigned int *bytes_read,
                              unsigned int *bytes_written)
 {
        char *result = NULL;
+       GError *err = NULL;
+       int i = 0;
+       unsigned int written_len = 0;
 
-       result = g_convert (str, len, to_codeset, from_codeset, bytes_read, bytes_written, NULL);  
+       if (len != 0) {
+               result = g_convert (str, len, to_codeset, from_codeset, bytes_read, &written_len, &err);
 
-       /*if converting failed, return duplicated source string.*/
-       if (result == NULL) {
+               /*if converting failed, return duplicated source string.*/
+               if (result == NULL) {
 #ifdef __MMFILE_TEST_MODE__
-               debug_warning ("text encoding failed.[%s][%d]\n", str, len);
+                       debug_warning ("text encoding failed.[%s][%d]\n", str, len);
+                       if(err != NULL) {
+                               debug_warning ("Error msg [%s]", err->message);
+                               g_error_free(err);
+                       }
 #endif
+                       written_len = 0;
+               } else {
+                       /* check carrige return */
+                       int i = 0;
+                       for (i = 0; i < written_len; i++) {
+                               if (result[i] == 13){
+                                       if (result[i+1] != 10)
+                                               result[i] = 10;
+                               }
+                       }
+               }
+       } else {
+               written_len = 0;
+       }
+
+       if(bytes_written != NULL) {
+               *bytes_written = written_len;
        }
 
        return result;
index ca4e4f7..d33475b 100755 (executable)
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <ctype.h>
+#include <vconf.h>
+
 #include "mm_debug.h"
 #include "mm_file_utils.h"
 
-//#define ENABLE_ITUNES_META           //All itunes metadata extracted by ffmpeg. see mov_read_udta_string()
+#define ENABLE_ITUNES_META             //All itunes metadata extracted by ffmpeg. see mov_read_udta_string() but Some cover art not support.
 
 typedef struct _mmfilemp4basicboxheader {
        unsigned int size;
@@ -116,6 +119,13 @@ typedef struct _mmfilelocibox {
        unsigned char *additional_notes;
 } MMFILE_3GP_LOCATION_TAGBOX;
 
+typedef struct _mmfilesmtabox {
+       unsigned int tmp;
+       unsigned int length;
+       unsigned char saut[4];
+       unsigned int value;
+} MMFILE_M4A_SMTA_TAGBOX;
+
 #define MMFILE_MP4_BASIC_BOX_HEADER_LEN 8
 #define MMFILE_MP4_MOVIE_HEADER_BOX_LEN 96
 #define MMFILE_MP4_HDLR_BOX_LEN         24
@@ -138,7 +148,7 @@ typedef struct _mmfilelocibox {
 
 #define GENRE_COUNT    149
 
-static char* MpegAudio_Genre[GENRE_COUNT] = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal",
+static const char* MpegAudio_Genre[GENRE_COUNT] = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal",
 "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial",
 "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
 "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise",
@@ -706,6 +716,96 @@ exception:
        return MMFILE_UTIL_FAIL;
 }
 
+static int GetSAUTInfoFromSMTATagBox(MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
+{
+       MMFILE_M4A_SMTA_TAGBOX smtaTag = {0,};
+       int readed = 0;
+
+       if (!formatContext || !fp || !basic_header) {
+               debug_error ("invalid param\n");
+               return MMFILE_UTIL_FAIL;
+       }
+
+       readed = mmfile_read (fp, (unsigned char *)&smtaTag, sizeof(MMFILE_M4A_SMTA_TAGBOX));
+       if (readed != sizeof(MMFILE_M4A_SMTA_TAGBOX)) {
+               debug_error ("read smta tag header fail\n");
+               goto exception;
+       }
+
+       smtaTag.length = mmfile_io_be_uint32(smtaTag.length);
+       smtaTag.value = mmfile_io_be_uint32(smtaTag.value);
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg("Len : 0x%x", smtaTag.length);
+       debug_msg("Saut : 0x%x 0x%x 0x%x 0x%x", smtaTag.saut[0], smtaTag.saut[1], smtaTag.saut[2], smtaTag.saut[3]);
+       debug_msg("Value : 0x%x", smtaTag.value);
+#endif
+
+       if (smtaTag.saut[0] == 's'
+               && smtaTag.saut[1] == 'a'
+               && smtaTag.saut[2] == 'u'
+               && smtaTag.saut[3] == 't') {
+               if (smtaTag.value == 0x01) {
+                       #ifdef __MMFILE_TEST_MODE__
+                       debug_msg("This has saut tag and valid value");
+                       #endif
+                       formatContext->smta = 1;
+               } else {
+                       debug_error("This has saut tag and but invalid value");
+                       goto exception;
+               }
+       } else {
+               debug_error("This hasn't saut tag and valid value");
+               goto exception;
+       }
+
+       return MMFILE_UTIL_SUCCESS;
+
+exception:
+       mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
+
+       return MMFILE_UTIL_FAIL;
+}
+
+static int GetValueFromCDISTagBox(MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
+{
+       unsigned int value = 0;
+       int readed = 0;
+
+       if (!formatContext || !fp || !basic_header) {
+               debug_error ("invalid param\n");
+               return MMFILE_UTIL_FAIL;
+       }
+
+       readed = mmfile_read (fp, (unsigned char *)&value, sizeof(unsigned int));
+       if (readed != sizeof(unsigned int)) {
+               debug_error ("read cdis tag header fail\n");
+               goto exception;
+       }
+
+       value = mmfile_io_be_uint32(value);
+
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg("Value : 0x%x", value);
+#endif
+
+       if (value == 0x01) {
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg("This has cdis tag and valid value");
+               #endif
+               formatContext->cdis = 1;
+       } else {
+               debug_error("This has cdis tag and but invalid value");
+               goto exception;
+       }
+
+       return MMFILE_UTIL_SUCCESS;
+
+exception:
+       mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
+
+       return MMFILE_UTIL_FAIL;
+}
+
 static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
 {
        int readed = 0;
@@ -791,7 +891,7 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                most of contents has 'mdir' + 'appl'. but some contents just has 'mdir'
                but 'ilst' is meta for iTunes. so find 'ilst' is more correct to check if this contents has iTunes meta or not.*/
 
-               char *ilst_box = "ilst";
+               const char *ilst_box = "ilst";
                int buf_size = strlen(ilst_box);
 
                unsigned char read_buf[buf_size+1];
@@ -836,18 +936,21 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                unsigned char read_buf[_ITUNES_READ_BUF_SZ];
                int i = 0;
                int cover_sz = 0, cover_type = 0, cover_found = 0;
-               int track_num = 0, track_found = 0;
-               int genre_index = 0, genre_found = 0;
-               int artist_sz = 0, artist_found = 0;
+               //int track_found = 0; //, track_num = 0;
+               //int genre_found = 0; //, genre_index = 0;
+               //int artist_found = 0; //, artist_sz = 0;
                int limit = basic_header->size - hdlrBoxHeader.size;
-               long long cover_offset = 0, track_offset =0 , genre_offset = 0, artist_offset = 0;
+               long long cover_offset = 0; //, track_offset =0 , genre_offset = 0, artist_offset = 0;
 
-               for (i = 0, cover_found = 0, track_found = 0, genre_found = 0, artist_found = 0; i < limit && (cover_found == 0 || track_found == 0 || genre_found == 0 || artist_found == 0) ; i++) {
+//             for (i = 0, cover_found = 0, track_found = 0, genre_found = 0, artist_found = 0; i < limit && (cover_found == 0 || track_found == 0 || genre_found == 0 || artist_found == 0) ; i++) {
+               for (i = 0; (i < limit) && (cover_found == 0) ; i++) {
                        readed = mmfile_read (fp, read_buf, _ITUNES_READ_BUF_SZ);
                        if (readed != _ITUNES_READ_BUF_SZ)
                                goto exception;
 
-/*ffmpeg extract artist, tracknum, excep cover image. see mov_read_udta_string()*/
+/*ffmpeg extract artist, tracknum, genre and cover image. see mov_read_udta_string().
+but ffmpeg does not support strange cover image.
+only support covr type 0xd(JPEG), 0xe(PNG), 0x1b(BMP). but we support other type*/
 #if 0
                        /**
                         * Artist : Added 2010.10.28
@@ -861,7 +964,7 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                artist_sz = mmfile_io_be_uint32 (*(int*)(read_buf + 4)) - 16; /* atom len(4)+data(4)+atom verion(1)+flag(3)+null(4) = 16 */
 
                                #ifdef __MMFILE_TEST_MODE__
-                               debug_msg ("[%s][%d]----------------------------------- artist found, offset=[%lld], size=[%d]\n", __func__, __LINE__, artist_offset, artist_sz);
+                               debug_msg ("----------------------------------- artist found, offset=[%lld], size=[%d]\n", artist_offset, artist_sz);
                                #endif
                        }
 
@@ -876,10 +979,10 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                track_offset = mmfile_tell (fp);
 
                                #ifdef __MMFILE_TEST_MODE__
-                               debug_msg ("[%s][%d]----------------------------------- Track found, offset=[%lld]\n", __func__, __LINE__, track_offset);
+                               debug_msg ("----------------------------------- Track found, offset=[%lld]\n", track_offset);
                                #endif
                        }
-#endif
+
                        /**
                         * Genre : Added 2010.10.27
                         */
@@ -892,9 +995,10 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                genre_offset = mmfile_tell (fp);
 
                                #ifdef __MMFILE_TEST_MODE__
-                               debug_msg ("[%s][%d]----------------------------------- genre found, offset=[%lld]\n", __func__, __LINE__, genre_offset);
+                               debug_msg ("----------------------------------- genre found, offset=[%lld]\n", genre_offset);
                                #endif
                        }
+#endif
 
                        /**
                         * Cover image
@@ -911,7 +1015,7 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                cover_offset = mmfile_tell (fp);
 
                                #ifdef __MMFILE_TEST_MODE__
-                               debug_msg ("[%s][%d]----------------------------------- cover_found found,  offset=[%lld]\n", __func__, __LINE__, cover_offset);
+                               debug_msg ("----------------------------------- cover_found found,  offset=[%lld]\n", cover_offset);
                                #endif
                        }
 
@@ -926,12 +1030,12 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
 
                                if (formatContext->artist) {
                                        #ifdef __MMFILE_TEST_MODE__
-                                       debug_msg ("[%s][%d]----------------------------------- previous artist was [%s] \n", __func__, __LINE__, formatContext->artist);
+                                       debug_msg ("----------------------------------- previous artist was [%s] \n", formatContext->artist);
                                        #endif
                                        free (formatContext->artist);
                                }
                                #ifdef __MMFILE_TEST_MODE__
-                               debug_msg ("[%s][%d]----------------------------------- new artist will be allocated with size (len+1) [%d] \n", __func__, __LINE__, artist_sz+1);
+                               debug_msg ("----------------------------------- new artist will be allocated with size (len+1) [%d] \n", artist_sz+1);
                                #endif
                                formatContext->artist = mmfile_malloc (artist_sz+1);
 
@@ -940,7 +1044,7 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                        formatContext->artist[artist_sz] = '\0';
 
                                        #ifdef __MMFILE_TEST_MODE__
-                                       debug_msg ("[%s][%d]----------------------------------- new artist is [%s] \n", __func__, __LINE__, formatContext->artist);
+                                       debug_msg ("----------------------------------- new artist is [%s] \n", formatContext->artist);
                                        #endif
 
                                        if (readed != artist_sz) {
@@ -960,12 +1064,12 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                track_num = mmfile_io_be_uint32 (*(int*)read_buf);
                                if (!formatContext->tagTrackNum) {
                                        memset (read_buf, 0x00, _ITUNES_READ_BUF_SZ);
-                                       sprintf ((char*)read_buf, "%d", track_num);
+                                       snprintf ((char*)read_buf, sizeof(read_buf), "%d", track_num);
                                        formatContext->tagTrackNum = mmfile_strdup ((const char*)read_buf);
                                }
                        }
                }
-#endif
+
                if (genre_found) {
                        mmfile_seek (fp, genre_offset, SEEK_SET);
                        readed = mmfile_read (fp, read_buf, _ITUNES_GENRE_NUM_SZ);
@@ -974,20 +1078,22 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                        } else {
                                genre_index = mmfile_io_be_uint16 (*(int*)read_buf);
                                #ifdef __MMFILE_TEST_MODE__
-                               debug_msg ("[%s][%d] genre index=[%d] \n", __func__, __LINE__, genre_index);
+                               debug_msg ("genre index=[%d] \n", genre_index);
                                #endif
                                if (genre_index > 0 && genre_index < GENRE_COUNT)       {
                                        if (!formatContext->genre) {
                                                memset (read_buf, 0x00, _ITUNES_READ_BUF_SZ);
                                                snprintf ((char*)read_buf, sizeof(read_buf),"%s", MpegAudio_Genre[genre_index-1]);
                                                #ifdef __MMFILE_TEST_MODE__
-                                               debug_msg ("[%s][%d] genre string=[%s] \n", __func__, __LINE__, read_buf);
+                                               debug_msg ("genre string=[%s] \n", read_buf);
                                                #endif
                                                formatContext->genre = mmfile_strdup ((const char*)read_buf);
                                        }
                                }
                        }
                }
+#endif
+
 /*
        1) below spec is in "iTunes Package Asset Specification 4.3" published by apple.
        Music Cover Art Image Profile
@@ -1014,7 +1120,7 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
                                /*} else if(cover_type == _ITUNES_COVER_TYPE_TIF) {
                                        formatContext->artworkMime = mmfile_strdup("image/tif");*/
                                } else {
-                                       debug_error("Not proper cover image type, but set to jpeg. cover_type[%d]", cover_type);
+                                       debug_warning("Not proper cover image type, but set to jpeg. cover_type[%d]", cover_type);
                                        formatContext->artworkMime = mmfile_strdup("image/jpeg");
                                }
 
@@ -1180,6 +1286,7 @@ static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle
 exception:
        mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
        mmfile_free (id3v2Box.id3v2Data);
+       mm_file_free_AvFileContentInfo (&tagInfo);
 
        return MMFILE_UTIL_FAIL;
 }
@@ -1317,6 +1424,22 @@ EXPORT_API int MMFileUtilGetMetaDataFromMP4 (MMFileFormatContext * formatContext
                                GetLocationFromLociTagBox (formatContext, fp, &basic_header);
                                break;
                        }
+                       /* Check smta in user data field to be compatible with android */
+                       case FOURCC ('s', 'm', 't', 'a'): {
+                               #ifdef __MMFILE_TEST_MODE__
+                               debug_msg ("MPEG4: [smta] SIZE: [%d]Byte\n", basic_header.size);
+                               #endif
+                               GetSAUTInfoFromSMTATagBox (formatContext, fp, &basic_header);
+                               break;
+                       }
+                       /* Check smta in user data field to be compatible with android */
+                       case FOURCC ('c', 'd', 'i', 's'): {
+                               #ifdef __MMFILE_TEST_MODE__
+                               debug_msg ("MPEG4: [smta] SIZE: [%d]Byte\n", basic_header.size);
+                               #endif
+                               GetValueFromCDISTagBox (formatContext, fp, &basic_header);
+                               break;
+                       }
                        /////////////////////////////////////////////////////////////////
                        //                  Extracting ID3 Tag Data                    //
                        /////////////////////////////////////////////////////////////////
@@ -1350,55 +1473,234 @@ exit:
        return ret;
 }
 
+static char * get_string(const char *buf, int buf_size, int *bytes_written)
+{
+       int i = 0, c = 0;
+       char *q = NULL;
+       char str[512] = {0, };
+
+       q = str;
+       for(i = 0; i < buf_size; i++) {
+               c = buf[i];
+               if (c == '\0')
+                       break;
+               if ((q - str) >= sizeof(str) - 1)
+               break;
+               *q++ = c;
+       }
+       *q = '\0';
+
+       if(strlen(str) > 0) {
+               *bytes_written = strlen(str);
+               return strdup(str);
+       } else {
+               *bytes_written = 0;
+               return NULL;
+       }
+}
+
+static bool is_numeric(const char *buf, int buf_size)
+{
+       int idx = 0;
+       bool is_num = true;
+
+       for(idx = 0; idx < buf_size; idx++) {
+               if(isdigit((int)buf[idx])) {
+                       continue;
+               }
+               else {
+                       is_num = false;
+                       break;
+               }
+       }
+
+       return is_num;
+}
+
+char* rtrimN(char* pStr)
+{
+       int pos = 0;
+       pos = strlen(pStr)-1;
+       for (; pos>=0; pos--)
+       {
+               if (pStr[pos] == 0x20)
+               {
+                       pStr[pos] = 0x00;
+               }
+               else
+               {
+                       break;
+               }
+       }
+
+       return strdup(pStr);
+}
+
+static bool make_characterset_array(char ***charset_array)
+{
+       char *locale = MMFileUtilGetLocale (NULL);
+
+       *charset_array = calloc(AV_ID3V2_MAX, sizeof(char*));
+
+       if(*charset_array == NULL) {
+               debug_error("calloc failed ");
+               if(locale != NULL)
+                       free(locale);
+               return false;
+       }
+
+       if (locale != NULL) {
+               (*charset_array)[AV_ID3V2_ISO_8859] = strdup(locale);
+       } else {
+               debug_error("get locale failed");
+               (*charset_array)[AV_ID3V2_ISO_8859] = NULL;
+       }
+
+       (*charset_array)[AV_ID3V2_UTF16] = strdup("UCS2");
+       (*charset_array)[AV_ID3V2_UTF16_BE] = strdup("UTF16-BE");
+       (*charset_array)[AV_ID3V2_UTF8] = strdup("UTF-8");
+
+       return true;
+}
+
+static bool release_characterset_array(char **charset_array)
+{
+       int i = 0;
+
+       for (i = 0; i < AV_ID3V2_MAX; i++) {
+               if (charset_array[i] != NULL)
+               {
+                       free(charset_array[i]);
+                       charset_array[i] = NULL;
+               }
+       }
+
+       if( charset_array != NULL ){
+               free(charset_array);
+               charset_array = NULL;
+       }
+
+       return true;
+}
+
+static void init_content_info(AvFileContentInfo* pInfo)
+{
+       pInfo->tagV2Info.bTitleMarked = false;
+       pInfo->tagV2Info.bArtistMarked= false;
+       pInfo->tagV2Info.bAlbumMarked= false;
+       pInfo->tagV2Info.bAlbum_ArtistMarked= false;
+       pInfo->tagV2Info.bYearMarked= false;
+       pInfo->tagV2Info.bDescriptionMarked= false;
+       pInfo->tagV2Info.bGenreMarked= false;
+       pInfo->tagV2Info.bTrackNumMarked= false;
+       pInfo->tagV2Info.bEncByMarked= false;
+       pInfo->tagV2Info.bURLMarked= false;
+       pInfo->tagV2Info.bCopyRightMarked= false;
+       pInfo->tagV2Info.bOriginArtistMarked= false;
+       pInfo->tagV2Info.bComposerMarked= false;
+       pInfo->tagV2Info.bImageMarked= false;
+
+       pInfo->tagV2Info.bRecDateMarked= false;
+       pInfo->tagV2Info.bContentGroupMarked= false;
+
+       pInfo->tagV2Info.bUnsyncLyricsMarked = false;
+       pInfo->tagV2Info.bSyncLyricsMarked = false;
+       pInfo->tagV2Info.bConductorMarked = false;
+       pInfo->tagV2Info.bGenreUTF16 = false;
+
+       pInfo->imageInfo.bURLInfo = false;
+       pInfo->imageInfo.pImageBuf = NULL;
+       pInfo->imageInfo.imageLen = 0;
+}
+
 EXPORT_API
 bool mm_file_id3tag_parse_v110(AvFileContentInfo* pInfo,  unsigned char *buffer)
 {
        const char *locale = MMFileUtilGetLocale (NULL);
+       char* pFullStr = NULL;
 
 #ifdef __MMFILE_TEST_MODE__
        debug_msg ("ID3tag v110--------------------------------------------------------------\n");
 #endif
 
        if(pInfo->tagV2Info.bTitleMarked == false) {
-               pInfo->pTitle = mmfile_string_convert ((const char*)&buffer[3], MP3_ID3_TITLE_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
+               pFullStr = mmfile_string_convert ((const char*)&buffer[3], MP3_ID3_TITLE_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
+               if (pFullStr !=NULL)
+               {
+                       pInfo->pTitle = rtrimN(pFullStr);
+                       free(pFullStr);
+               }
+
                #ifdef __MMFILE_TEST_MODE__
                debug_msg ( "pInfo->pTitle returned =(%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
                #endif
        }
 
        if(pInfo->tagV2Info.bArtistMarked == false) {
-               pInfo->pArtist = mmfile_string_convert ((const char*)&buffer[33], MP3_ID3_ARTIST_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
+               pFullStr = mmfile_string_convert ((const char*)&buffer[33], MP3_ID3_ARTIST_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
+               if (pFullStr !=NULL)
+               {
+                       pInfo->pArtist = rtrimN(pFullStr);
+                       free(pFullStr);
+               }
+
                #ifdef __MMFILE_TEST_MODE__
                debug_msg ( "pInfo->pArtist returned =(%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
                #endif
        }
+
        if(pInfo->tagV2Info.bAlbumMarked == false) {
-               pInfo->pAlbum = mmfile_string_convert ((const char*)&buffer[63], MP3_ID3_ALBUM_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
+               pFullStr = mmfile_string_convert ((const char*)&buffer[63], MP3_ID3_ALBUM_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
+               if (pFullStr !=NULL)
+               {
+                       pInfo->pAlbum = rtrimN(pFullStr);
+                       free(pFullStr);
+               }
+
                #ifdef __MMFILE_TEST_MODE__
                debug_msg (  "pInfo->pAlbum returned =(%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
                #endif
        }
+
        if(pInfo->tagV2Info.bYearMarked == false) {
+
                pInfo->pYear = mmfile_string_convert ((const char*)&buffer[93], MP3_ID3_YEAR_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
                #ifdef __MMFILE_TEST_MODE__
                debug_msg (  "pInfo->pYear returned =(%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
                #endif
+
+               if(pInfo->pYear == NULL) {      /*Use same logic with ffmpeg*/
+                       pInfo->pYear = get_string((const char*)&buffer[93], MP3_ID3_YEAR_LENGTH, (int*)&pInfo->yearLen);
+                       #ifdef __MMFILE_TEST_MODE__
+                       debug_msg (  "pInfo->pYear returned =(%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
+                       #endif
+               }
        }
+
        if(pInfo->tagV2Info.bDescriptionMarked == false) {
                pInfo->pComment = mmfile_string_convert ((const char*)&buffer[97], MP3_ID3_DESCRIPTION_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
                #ifdef __MMFILE_TEST_MODE__
                debug_msg (  "pInfo->pComment returned =(%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
                #endif
+
+               if(pInfo->pComment == NULL) {   /*Use same logic with ffmpeg*/
+                       pInfo->pComment = get_string((const char*)&buffer[97], MP3_ID3_DESCRIPTION_LENGTH, (int*)&pInfo->commentLen);
+                       #ifdef __MMFILE_TEST_MODE__
+                       debug_msg (  "pInfo->pComment returned =(%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
+                       #endif
+               }
        }
 
        if(pInfo->tagV2Info.bTrackNumMarked== false) {
                pInfo->pTrackNum = mmfile_malloc (5);
-               pInfo->pTrackNum[4] = 0;
-               snprintf(pInfo->pTrackNum, 4, "%04d", (int)buffer[126]);
-               pInfo->tracknumLen = strlen(pInfo->pTrackNum);
-               #ifdef __MMFILE_TEST_MODE__
-               debug_msg (  "pInfo->pTrackNum returned =(%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
-               #endif
+               if(pInfo->pTrackNum != NULL) {
+                       pInfo->pTrackNum[4] = 0;
+                       snprintf(pInfo->pTrackNum, 4, "%04d", (int)buffer[126]);
+                       pInfo->tracknumLen = strlen(pInfo->pTrackNum);
+                       #ifdef __MMFILE_TEST_MODE__
+                       debug_msg (  "pInfo->pTrackNum returned =(%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
+                       #endif
+               }
        }
 
        if(pInfo->tagV2Info.bGenreMarked == false) {
@@ -1422,35 +1724,17 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
        char CompTmp[4];
        char *pExtContent = NULL;
        unsigned long purelyFramelen = 0;
-       char *tmpConvert2Pcode = NULL;
        int inx=0, encodingOffSet=0, realCpyFrameNum=0,
-               checkImgMimeTypeMax=0, checkImgDescriptionMax=0, checkImgExtMax=0,
+               checkImgMimeTypeMax=0, checkImgExtMax=0,
                imgstartOffset=0, tmp = 0;
 
        int textEncodingType = 0;
-       const char *locale = NULL;
 
-       pInfo->tagV2Info.bTitleMarked = false;
-       pInfo->tagV2Info.bAlbumMarked= false;
-       pInfo->tagV2Info.bArtistMarked= false;
-       pInfo->tagV2Info.bDescriptionMarked= false;
-       pInfo->tagV2Info.bGenreMarked= false;
-       pInfo->tagV2Info.bYearMarked= false;
-       pInfo->tagV2Info.bTrackNumMarked= false;
-       pInfo->tagV2Info.bEncByMarked= false;
-       pInfo->tagV2Info.bURLMarked= false;
-       pInfo->tagV2Info.bCopyRightMarked= false;
-       pInfo->tagV2Info.bOriginArtistMarked= false;
-       pInfo->tagV2Info.bComposerMarked= false;
-       pInfo->tagV2Info.bImageMarked= false;
-       pInfo->imageInfo.bURLInfo = false;
-       pInfo->tagV2Info.bGenreUTF16 = false;
-       pInfo->tagV2Info.bConductorMarked = false;
+       char **charset_array = NULL;
 
-       pInfo->imageInfo.pImageBuf = NULL;
-       pInfo->imageInfo.imageLen = 0;
+       make_characterset_array(&charset_array);
 
-       locale = MMFileUtilGetLocale (NULL);
+       init_content_info(pInfo);
 
        taglen = pInfo->tagV2Info.tagLen;
        needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
@@ -1493,6 +1777,11 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                        textEncodingType = AV_ID3V2_UTF16;
                                }
 
+                               if (textEncodingType > AV_ID3V2_MAX) {
+                                       debug_msg ( "WRONG ENCOIDNG TYPE [%d], FRAME[%s]\n", textEncodingType, (char*)CompTmp);
+                                       continue;
+                               }
+
                                //in order to deliver valid string to MP
                                while((buffer[curPos-purelyFramelen+encodingOffSet] < 0x20) && (encodingOffSet < purelyFramelen))
                                        encodingOffSet++;
@@ -1502,14 +1791,6 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                        realCpyFrameNum = purelyFramelen - encodingOffSet;
                                        pExtContent = mmfile_malloc (realCpyFrameNum+3);
                                        memset(pExtContent, '\0', realCpyFrameNum+3);
-                                       if(textEncodingType == AV_ID3V2_ISO_8859)
-                                       {
-                                               if(strncmp((char *)CompTmp, "PIC", 3) != 0)
-                                               {
-                                                       tmpConvert2Pcode = mmfile_malloc ((realCpyFrameNum)*2+2);
-                                                       memset(tmpConvert2Pcode, 0, (realCpyFrameNum)*2+2);
-                                               }
-                                       }
 
                                        memcpy(pExtContent, &buffer[curPos-purelyFramelen+encodingOffSet], purelyFramelen-encodingOffSet);
 
@@ -1517,14 +1798,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                        {
                                                if(strncmp((char *)CompTmp, "TT2", 3) == 0 && pInfo->tagV2Info.bTitleMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->titleLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
-                                                       }
+                                                       pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->titleLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pTitle returned = (%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
@@ -1533,29 +1807,26 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TP1", 3) == 0 && pInfo->tagV2Info.bArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->artistLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
-                                                       }
+                                                       pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->artistLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pArtist returned = (%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
                                                        #endif
                                                        pInfo->tagV2Info.bArtistMarked = true;
                                                }
+                                               else if(strncmp((char *)CompTmp, "TP2", 3) == 0 && pInfo->tagV2Info.bAlbum_ArtistMarked == false)
+                                               {
+                                                       pInfo->pAlbum_Artist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->album_artistLen);
+
+                                                       #ifdef __MMFILE_TEST_MODE__
+                                                       debug_msg ( "pInfo->pAlbum_Artist returned = (%s), pInfo->album_artistLen(%d)\n", pInfo->pAlbum_Artist, pInfo->album_artistLen);
+                                                       #endif
+                                                       pInfo->tagV2Info.bAlbum_ArtistMarked = true;
+                                               }
                                                else if(strncmp((char *)CompTmp, "TP3", 3) == 0 && pInfo->tagV2Info.bConductorMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->conductorLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->conductorLen);
-                                                       }
+                                                       pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->conductorLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pConductor returned = (%s), pInfo->conductorLen(%d)\n", pInfo->pConductor, pInfo->conductorLen);
                                                        #endif
@@ -1563,14 +1834,8 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TAL", 3) == 0 && pInfo->tagV2Info.bAlbumMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->albumLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
-                                                       }
+                                                       pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->albumLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pAlbum returned = (%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
                                                        #endif
@@ -1578,14 +1843,8 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TYE", 3) == 0 && pInfo->tagV2Info.bYearMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->yearLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
-                                                       }
+                                                       pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->yearLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pYear returned = (%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
                                                        #endif
@@ -1607,14 +1866,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                        else
                                                                                textEncodingType = AV_ID3V2_UTF16;
 
-                                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                                       {
-                                                                               pInfo->pComment = mmfile_string_convert ((char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->commentLen);
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               pInfo->pComment = mmfile_string_convert ((char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
-                                                                       }
+                                                                       pInfo->pComment = mmfile_string_convert ((char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->commentLen);
 
                                                                        #ifdef __MMFILE_TEST_MODE__
                                                                        debug_msg ( "pInfo->pComment returned = (%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
@@ -1639,26 +1891,20 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCO", 3) == 0 && pInfo->tagV2Info.bGenreMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->genreLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->genreLen);
-                                                       }
+                                                       pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->genreLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pGenre returned = (%s), pInfo->genreLen(%d)\n", pInfo->pGenre, pInfo->genreLen);
                                                        #endif
 
                                                        if((pInfo->pGenre != NULL) && (pInfo->genreLen > 0)) {
-                                                               int ret = 0;
+                                                               bool ret = FALSE;
                                                                int int_genre = -1;
 
-                                                               ret = sscanf( pInfo->pGenre, "%d", &int_genre);
+                                                               ret = is_numeric(pInfo->pGenre, pInfo->genreLen);
 
-                                                               if(ret == 1) {
+                                                               if(ret == TRUE) {
+                                                                       sscanf( pInfo->pGenre, "%d", &int_genre);
                                                                        #ifdef __MMFILE_TEST_MODE__
                                                                        debug_msg("genre information is inteager [%d]\n", int_genre);
                                                                        #endif
@@ -1690,14 +1936,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TRK", 3) == 0 && pInfo->tagV2Info.bTrackNumMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->tracknumLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->tracknumLen);
-                                                       }
+                                                       pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->tracknumLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pTrackNum returned = (%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
@@ -1706,14 +1945,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TEN", 3) == 0 && pInfo->tagV2Info.bEncByMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->encbyLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->encbyLen);
-                                                       }
+                                                       pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->encbyLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pEncBy returned = (%s), pInfo->encbyLen(%d)\n", pInfo->pEncBy, pInfo->encbyLen);
@@ -1736,14 +1968,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                        else
                                                                                textEncodingType = AV_ID3V2_UTF16;
 
-                                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                                       {
-                                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->urlLen);
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->urlLen);
-                                                                       }
+                                                                       pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->urlLen);
 
                                                                        #ifdef __MMFILE_TEST_MODE__
                                                                        debug_msg ( "pInfo->pURL returned = (%s), pInfo->urlLen(%d)\n", pInfo->pURL, pInfo->urlLen);
@@ -1767,14 +1992,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCR", 3) == 0 && pInfo->tagV2Info.bCopyRightMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->copyrightLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->copyrightLen);
-                                                       }
+                                                       pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->copyrightLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pCopyright returned = (%s), pInfo->copyrightLen(%d)\n", pInfo->pCopyright, pInfo->copyrightLen);
@@ -1783,14 +2001,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TOA", 3) == 0 && pInfo->tagV2Info.bOriginArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->originartistLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->originartistLen);
-                                                       }
+                                                       pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->originartistLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pOriginArtist returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pOriginArtist, pInfo->originartistLen);
@@ -1799,14 +2010,8 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCM", 3) == 0 && pInfo->tagV2Info.bComposerMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->composerLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->composerLen);
-                                                       }
+                                                       pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->composerLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pComposer returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pComposer, pInfo->composerLen);
                                                        #endif
@@ -1814,14 +2019,8 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TRD", 3) == 0 && pInfo->tagV2Info.bRecDateMarked== false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->recdateLen);
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->recdateLen);
-                                                       }
+                                                       pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->recdateLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pRecDate returned = (%s), pInfo->recdateLen(%d)\n", pInfo->pRecDate, pInfo->recdateLen);
                                                        #endif
@@ -1829,94 +2028,115 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "PIC", 3) == 0 && pInfo->tagV2Info.bImageMarked == false && realCpyFrameNum <= 2000000)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
+                                                       if(pExtContent[0] != 0)
+                                                       {
+                                                               for(inx = 0; inx < MP3_ID3_IMAGE_EXT_MAX_LENGTH; inx++)
+                                                                       pInfo->imageInfo.imageExt[inx] = '\0';//ini mimetype variable
+
+                                                               while((checkImgExtMax < MP3_ID3_IMAGE_EXT_MAX_LENGTH-1) && pExtContent[checkImgExtMax] != '\0')
+                                                               {
+                                                                       pInfo->imageInfo.imageExt[checkImgExtMax] = pExtContent[checkImgExtMax];
+                                                                       checkImgExtMax++;
+                                                               }
+                                                       }
+                                                       else
                                                        {
                                                                #ifdef __MMFILE_TEST_MODE__
-                                                               debug_msg ("mmf_file_id3tag_parse_v222: this is abnormal case!!\n");
+                                                                debug_msg ( "mmf_file_id3tag_parse_v222: PIC image's not included to image Extention\n");
                                                                #endif
                                                        }
-                                                       else
+
+                                                       imgstartOffset += checkImgExtMax;
+
+                                                       if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
                                                        {
-                                                               if(pExtContent[0] != 0)
-                                                               {
-                                                                       for(inx = 0; inx < MP3_ID3_IMAGE_EXT_MAX_LENGTH; inx++)
-                                                                               pInfo->imageInfo.imageExt[inx] = '\0';//ini mimetype variable
+                                                               pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
+                                                       }
+                                                       imgstartOffset++;//PictureType(1byte)
 
-                                                                       while((checkImgExtMax < MP3_ID3_IMAGE_EXT_MAX_LENGTH-1) && pExtContent[checkImgExtMax] != '\0')
-                                                                       {
-                                                                               pInfo->imageInfo.imageExt[checkImgExtMax] = pExtContent[checkImgExtMax];
-                                                                               checkImgExtMax++;
+                                                       if(pExtContent[imgstartOffset] != 0x0)
+                                                       {
+                                                               int cur_pos = 0;
+                                                               int dis_len = 0;
+                                                               int new_dis_len = 0;
+                                                               char jpg_sign[3] = {0xff, 0xd8, 0xff};
+                                                               char png_sign[8] = {0x80, 0x50, 0x4e, 0x47,0x0d, 0x0a, 0x1a, 0x0a};
+                                                               char *tmp_desc = NULL;
+
+                                                               while (1) {
+                                                                       if (pExtContent[imgstartOffset + cur_pos] == '\0') {
+                                                                               if (realCpyFrameNum < imgstartOffset + cur_pos) {
+                                                                                               debug_error("End of APIC Tag %d %d %d\n", realCpyFrameNum, imgstartOffset, cur_pos);
+                                                                                               break;
+                                                                               }
+                                                                               /*check end of image description*/
+                                                                               if ((pExtContent[imgstartOffset + cur_pos + 1] == jpg_sign[0]) ||
+                                                                                       (pExtContent[imgstartOffset + cur_pos + 1] == png_sign[0])) {
+                                                                                       #ifdef __MMFILE_TEST_MODE__
+                                                                                       debug_msg ( "length of description (%d)", cur_pos);
+                                                                                       #endif
+
+                                                                                       break;
+                                                                               }
                                                                        }
-                                                               }
-                                                               else
-                                                               {
-                                                                       #ifdef __MMFILE_TEST_MODE__
-                                                                        debug_msg ( "mmf_file_id3tag_parse_v222: PIC image's not included to image Extention\n");
-                                                                       #endif
+                                                                       cur_pos ++;
                                                                }
 
-                                                               imgstartOffset += checkImgExtMax;
+                                                               dis_len = cur_pos + 1;
 
-                                                               if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
-                                                               {
-                                                                       pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
-                                                               }
-                                                               imgstartOffset++;//PictureType(1byte)
+                                                               tmp_desc = mmfile_malloc(sizeof(char) * dis_len);
+                                                               memcpy(tmp_desc, pExtContent + imgstartOffset, dis_len);
 
-                                                               if(pExtContent[imgstartOffset] != 0x0)
-                                                               {
-                                                                       for(inx = 0; inx < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1; inx++)
-                                                                               pInfo->imageInfo.imageDescription[inx] = '\0';//ini imgdescripiton variable
+                                                               /*convert description*/
+                                                               pInfo->imageInfo.imageDescription = mmfile_string_convert (tmp_desc, dis_len, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&new_dis_len);
+                                                               mmfile_free(tmp_desc);
 
-                                                                       while((checkImgDescriptionMax < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1) && pExtContent[imgstartOffset+checkImgDescriptionMax] != '\0')
-                                                                       {
-                                                                               pInfo->imageInfo.imageDescription[checkImgDescriptionMax] = pExtContent[imgstartOffset+checkImgDescriptionMax];
-                                                                               checkImgDescriptionMax++;
-                                                                       }
-                                                                       pInfo->imageInfo.imgDesLen= checkImgDescriptionMax;
-                                                               }
-                                                               else
+                                                               #ifdef __MMFILE_TEST_MODE__
+                                                               debug_msg ( "new_desc %s(%d)\n", pInfo->imageInfo.imageDescription, new_dis_len);
+                                                               #endif
+                                                               pInfo->imageInfo.imgDesLen = new_dis_len; /**/
+                                                               imgstartOffset += cur_pos;
+                                                       }
+                                                       else
+                                                       {
+                                                               pInfo->imageInfo.imgDesLen= 0;
+                                                       }
+
+                                                       if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
+                                                       {
+                                                               imgstartOffset ++; // endofDesceriptionType(1byte)
+
+                                                               while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
                                                                {
-                                                                       pInfo->imageInfo.imgDesLen= 0;
+                                                                       imgstartOffset ++;
                                                                }
 
-                                                               imgstartOffset += checkImgDescriptionMax;
+                                                               #ifdef __MMFILE_TEST_MODE__
+                                                               debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
+                                                               #endif
 
-                                                               if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
+                                                               if(realCpyFrameNum - imgstartOffset > 0)
                                                                {
-                                                                       imgstartOffset ++; // endofDesceriptionType(1byte)
+                                                                       pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
+                                                                       pInfo->imageInfo.pImageBuf= mmfile_malloc (pInfo->imageInfo.imageLen + 1);
 
-                                                                       while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
-                                                                       {
-                                                                               imgstartOffset ++;
+                                                                       if(pInfo->imageInfo.pImageBuf != NULL) {
+                                                                               memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
+                                                                               pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
                                                                        }
 
+                                                                       if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
+                                                                               pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
+                                                               }
+                                                               else
+                                                               {
                                                                        #ifdef __MMFILE_TEST_MODE__
-                                                                       debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
+                                                                       debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
                                                                        #endif
-
-                                                                       if(realCpyFrameNum - imgstartOffset > 0)
-                                                                       {
-                                                                               pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
-                                                                               pInfo->imageInfo.pImageBuf= mmfile_malloc (pInfo->imageInfo.imageLen + 1);
-                                                                               memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
-                                                                               pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
-
-                                                                               if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
-                                                                                       pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
-                                                                               #endif
-                                                                       }
                                                                }
-
                                                        }
 
                                                        checkImgMimeTypeMax = 0;
-                                                       checkImgDescriptionMax = 0;
                                                        checkImgExtMax = 0;
                                                        inx = 0;
                                                        imgstartOffset = 0;
@@ -1935,7 +2155,6 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                        }
 
                        if(pExtContent) _FREE_EX(pExtContent);
-                       if(tmpConvert2Pcode)    _FREE_EX(tmpConvert2Pcode);
                        memset(CompTmp, 0, 4);
                        if(curPos < taglen)
                        {
@@ -1953,7 +2172,7 @@ bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
                }
        }
 
-
+       release_characterset_array(charset_array);
 
        if(taglen) {
                return true;
@@ -1973,35 +2192,14 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
        char CompTmp[5];
        unsigned char *pExtContent = NULL;
        unsigned long purelyFramelen = 0;
-       char *tmpConvert2Pcode = NULL;
-       int inx=0, encodingOffSet=0, realCpyFrameNum=0, checkImgMimeTypeMax=0, checkImgDescriptionMax=0, imgstartOffset=0,  tmp = 0;
+       int inx=0, encodingOffSet=0, realCpyFrameNum=0, checkImgMimeTypeMax=0, imgstartOffset=0,  tmp = 0;
        int textEncodingType = 0;
-       const char *locale = NULL;
-
-       locale = MMFileUtilGetLocale (NULL);
-
-       pInfo->tagV2Info.bTitleMarked = false;
-       pInfo->tagV2Info.bAlbumMarked= false;
-       pInfo->tagV2Info.bArtistMarked= false;
-       pInfo->tagV2Info.bDescriptionMarked= false;
-       pInfo->tagV2Info.bGenreMarked= false;
-       pInfo->tagV2Info.bYearMarked= false;
-       pInfo->tagV2Info.bTrackNumMarked= false;
-       pInfo->tagV2Info.bEncByMarked= false;
-       pInfo->tagV2Info.bURLMarked= false;
-       pInfo->tagV2Info.bCopyRightMarked= false;
-       pInfo->tagV2Info.bOriginArtistMarked= false;
-       pInfo->tagV2Info.bComposerMarked= false;
-       pInfo->tagV2Info.bImageMarked= false;
-       pInfo->imageInfo.bURLInfo = false;
-       pInfo->tagV2Info.bConductorMarked = false;
-       pInfo->tagV2Info.bUnsyncLyricsMarked = false;
-       pInfo->tagV2Info.bSyncLyricsMarked = false;
+       char **charset_array = NULL;
+       char *MIME_PRFIX = "image/";
 
-       pInfo->tagV2Info.bGenreUTF16 = false;
+       make_characterset_array(&charset_array);
 
-       pInfo->imageInfo.pImageBuf = NULL;
-       pInfo->imageInfo.imageLen = 0;
+       init_content_info(pInfo);
 
        taglen = pInfo->tagV2Info.tagLen;
        needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
@@ -2011,6 +2209,20 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
        debug_msg ("ID3tag v223--------------------------------------------------------------\n");
 #endif
 
+       /* check Extended Header */
+       if (buffer[5] & 0x40)
+       {
+               /* if extended header exists, skip it*/
+               int extendedHeaderLen = (unsigned long)buffer[10] << 21 | (unsigned long)buffer[11] << 14 | (unsigned long)buffer[12] << 7  | (unsigned long)buffer[13];
+
+               #ifdef __MMFILE_TEST_MODE__
+               debug_msg ("--------------- extendedHeaderLen = %d\n", extendedHeaderLen);
+               #endif
+
+               curPos += extendedHeaderLen;
+               curPos += 4;
+       }
+
        if(needToloopv2taglen -MP3_TAGv2_23_TXT_HEADER_LEN > MP3_TAGv2_23_TXT_HEADER_LEN)
        {
                v2numOfFrames = 1;
@@ -2103,32 +2315,27 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                        realCpyFrameNum = purelyFramelen - encodingOffSet;
                                        pExtContent = mmfile_malloc (realCpyFrameNum+3);
                                        memset(pExtContent, '\0', realCpyFrameNum+3);
-                                       if(textEncodingType == AV_ID3V2_ISO_8859)
-                                       {
-                                               if(strncmp((char *)CompTmp, "APIC", 4) != 0)
-                                               {
-                                                       tmpConvert2Pcode = mmfile_malloc ((realCpyFrameNum)*2+2);
-                                                       memset(tmpConvert2Pcode, 0, (realCpyFrameNum)*2+2);
+
+                                       if (textEncodingType != AV_ID3V2_UTF16 && textEncodingType != AV_ID3V2_UTF16_BE) {
+                                               if (CompTmp[0] == 'T' ||(strcmp(CompTmp, "APIC")==0)) {
+                                                       #ifdef __MMFILE_TEST_MODE__
+                                                       debug_msg ( "get the new text ecoding type\n");
+                                                       #endif
+                                                       textEncodingType = buffer[curPos-purelyFramelen+encodingOffSet -1];
                                                }
                                        }
 
+                                       if (textEncodingType > AV_ID3V2_MAX) {
+                                               debug_msg ( "WRONG ENCOIDNG TYPE [%d], FRAME[%s]\n", textEncodingType, (char*)CompTmp);
+                                               continue;
+                                       }
+
                                        memcpy(pExtContent, &buffer[curPos-purelyFramelen+encodingOffSet], purelyFramelen-encodingOffSet);
                                        if(realCpyFrameNum > 0)
                                        {
                                                if(strncmp((char *)CompTmp, "TIT2", 4) == 0 && pInfo->tagV2Info.bTitleMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pTitle = mmfile_string_convert ((char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->titleLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
-                                                       }
+                                                       pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->titleLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pTitle returned = (%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
@@ -2138,38 +2345,25 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TPE1", 4) == 0 && pInfo->tagV2Info.bArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->artistLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
-                                                       }
+                                                       pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->artistLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pArtist returned = (%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
                                                        #endif
                                                        pInfo->tagV2Info.bArtistMarked = true;
                                                }
+                                               else if(strncmp((char *)CompTmp, "TPE2", 4) == 0 && pInfo->tagV2Info.bAlbum_ArtistMarked == false)
+                                               {
+                                                       pInfo->pAlbum_Artist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->album_artistLen);
+
+                                                       #ifdef __MMFILE_TEST_MODE__
+                                                       debug_msg ( "pInfo->pAlbum_Artist returned = (%s), pInfo->album_artistLen(%d)\n", pInfo->pAlbum_Artist, pInfo->album_artistLen);
+                                                       #endif
+                                                       pInfo->tagV2Info.bAlbum_ArtistMarked = true;
+                                               }
                                                else if(strncmp((char *)CompTmp, "TPE3", 4) == 0 && pInfo->tagV2Info.bConductorMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->conductorLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->conductorLen);
-                                                       }
+                                                       pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->conductorLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pConductor returned = (%s), pInfo->conductorLen(%d)\n", pInfo->pConductor, pInfo->conductorLen);
@@ -2178,18 +2372,8 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TALB", 4) == 0 && pInfo->tagV2Info.bAlbumMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->albumLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
-                                                       }
+                                                       pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->albumLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pAlbum returned = (%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
                                                        #endif
@@ -2197,18 +2381,7 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TYER", 4) == 0 && pInfo->tagV2Info.bYearMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->yearLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
-                                                       }
+                                                       pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->yearLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pYear returned = (%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
@@ -2278,18 +2451,7 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                        debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
                                                                        #endif
 
-                                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                                       {
-                                                                               pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->commentLen);
-                                                                       }
-                                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                                       {
-                                                                               debug_warning ("not implemented\n");
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
-                                                                       }
+                                                                       pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->commentLen);
                                                                }
                                                                else
                                                                {
@@ -2407,22 +2569,28 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                                                {
                                                                                                        synclyrics_info = (AvSynclyricsInfo *)malloc(sizeof(AvSynclyricsInfo));
 
-                                                                                                       if(textEncodingType == AV_ID3V2_UTF8) {
-                                                                                                               synclyrics_info->lyric_info= mmfile_malloc(copy_len+1);
-                                                                                                               memset(synclyrics_info->lyric_info, 0, copy_len+1);
-                                                                                                               memcpy(synclyrics_info->lyric_info, pExtContent+copy_start_pos, copy_len);
-                                                                                                               synclyrics_info->lyric_info[copy_len+1] = '\0';
-                                                                                                       }
-                                                                                                       else {
-                                                                                                               synclyrics_info->lyric_info = mmfile_string_convert ((const char*)&pExtContent[copy_start_pos], copy_len, "UTF-8", locale, NULL, NULL);
+                                                                                                       if(synclyrics_info != NULL) {
+                                                                                                               if(textEncodingType == AV_ID3V2_UTF8) {
+                                                                                                                       synclyrics_info->lyric_info= mmfile_malloc(copy_len+1);
+                                                                                                                       if(synclyrics_info->lyric_info != NULL) {
+                                                                                                                               memset(synclyrics_info->lyric_info, 0, copy_len+1);
+                                                                                                                               memcpy(synclyrics_info->lyric_info, pExtContent+copy_start_pos, copy_len);
+                                                                                                                               synclyrics_info->lyric_info[copy_len+1] = '\0';
+                                                                                                                       }
+                                                                                                               }
+                                                                                                               else {
+                                                                                                                       synclyrics_info->lyric_info = mmfile_string_convert ((const char*)&pExtContent[copy_start_pos], copy_len, "UTF-8", charset_array[AV_ID3V2_ISO_8859], NULL, NULL);
+                                                                                                               }
+
+                                                                                                               synclyrics_info->time_info= (unsigned long)pExtContent[tmp+idx+1] << 24 | (unsigned long)pExtContent[tmp+idx+2] << 16 | (unsigned long)pExtContent[tmp+idx+3] << 8  | (unsigned long)pExtContent[tmp+idx+4];
+                                                                                                               idx += 4;
+                                                                                                               copy_start_pos = tmp + idx + 1;
+                                                                                                               #ifdef __MMFILE_TEST_MODE__
+                                                                                                               debug_msg("[%d][%s] idx[%d], copy_len[%d] copy_start_pos[%d]", synclyrics_info->time_info, synclyrics_info->lyric_info, idx, copy_len, copy_start_pos);
+                                                                                                               #endif
+                                                                                                               copy_len = 0;
+                                                                                                               synclyrics_info_list = g_list_append(synclyrics_info_list, synclyrics_info);
                                                                                                        }
-
-                                                                                                       synclyrics_info->time_info= (unsigned long)pExtContent[tmp+idx+1] << 24 | (unsigned long)pExtContent[tmp+idx+2] << 16 | (unsigned long)pExtContent[tmp+idx+3] << 8  | (unsigned long)pExtContent[tmp+idx+4];
-                                                                                                       idx += 4;
-                                                                                                       copy_start_pos = tmp + idx + 1;
-                                                                                                       debug_msg("[%d][%s] idx[%d], copy_len[%d] copy_start_pos[%d]", synclyrics_info->time_info, synclyrics_info->lyric_info, idx, copy_len, copy_start_pos);
-                                                                                                       copy_len = 0;
-                                                                                                       synclyrics_info_list = g_list_append(synclyrics_info_list, synclyrics_info);
                                                                                                }
                                                                                                copy_len ++;
                                                                                        }
@@ -2455,19 +2623,33 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "USLT", 4) == 0 && pInfo->tagV2Info.bUnsyncLyricsMarked == false)
                                                {
+                                                       char *lang_info = strndup((char*)pExtContent, 3);
+
                                                        if(realCpyFrameNum > 3)
                                                        {
                                                                realCpyFrameNum -= 3;
                                                                tmp = 3;
 
-                                                               //pExtContent[tmp+1] value should't have encoding value
-                                                               if(pExtContent[tmp] == 0x00 || pExtContent[tmp] == 0xFF|| pExtContent[tmp] == 0xFE)
-                                                               {
+                                                               /*find start of lyrics */
+                                                               while(1) {
                                                                        if (pExtContent[tmp] == 0x00) {
-                                                                               realCpyFrameNum -= 2;
-                                                                               tmp = 5;
+                                                                               if (pExtContent[tmp+1] == 0x00) {
+                                                                                       realCpyFrameNum -=2;
+                                                                                       tmp +=2;
+                                                                               }
+                                                                               break;
+                                                                       } else {
+                                                                               realCpyFrameNum--;
+                                                                               tmp++;
                                                                        }
+                                                               }
 
+                                                               //pExtContent[tmp+1] value should't have encoding value
+                                                               #ifdef __MMFILE_TEST_MODE__
+                                                               debug_msg ( "tpExtContent[%d] %x\n", tmp, pExtContent[tmp]);
+                                                               #endif
+                                                               if(pExtContent[tmp] == 0x00 || pExtContent[tmp] == 0xFF|| pExtContent[tmp] == 0xFE)
+                                                               {
                                                                        if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
                                                                        {
                                                                                while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
@@ -2521,17 +2703,21 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                        debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
                                                                        #endif
 
-                                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                                       {
-                                                                               pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->unsynclyricsLen);
-                                                                       }
-                                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                                       {
-                                                                               debug_warning ("not implemented\n");
+                                                                       char *char_set = NULL;
+                                                                       if (textEncodingType == AV_ID3V2_ISO_8859) {
+                                                                               if (lang_info != NULL && !strcasecmp(lang_info, "KOR")) {
+                                                                                       char_set = strdup("EUC-KR");
+                                                                               } else {
+                                                                                       char_set = mmfile_get_charset((const char*)&pExtContent[tmp]);
+                                                                               }
+                                                                               _FREE_EX(lang_info);
                                                                        }
-                                                                       else
-                                                                       {
-                                                                               pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->unsynclyricsLen);
+
+                                                                       if (char_set == NULL) {
+                                                                               pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->unsynclyricsLen);
+                                                                       } else {
+                                                                               pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", char_set, NULL, (unsigned int*)&pInfo->unsynclyricsLen);
+                                                                               _FREE_EX(char_set);
                                                                        }
                                                                }
                                                                else
@@ -2555,33 +2741,24 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        debug_msg ( "pInfo->pUnsyncLyrics returned = (%s), pInfo->unsynclyricsLen(%d)\n", pInfo->pUnsyncLyrics, pInfo->unsynclyricsLen);
                                                        #endif
                                                        pInfo->tagV2Info.bUnsyncLyricsMarked = true;
+                                                       mmfile_free(lang_info);
                                                }
                                                else if(strncmp((char *)CompTmp, "TCON", 4) == 0 && pInfo->tagV2Info.bGenreMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->genreLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->genreLen);
-                                                       }
+                                                       pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->genreLen);
 
-                                                               #ifdef __MMFILE_TEST_MODE__
-                                                                       debug_msg ( "pInfo->pGenre returned = (%s), pInfo->genreLen(%d)\n", pInfo->pGenre, pInfo->genreLen);
-                                                               #endif
+                                                       #ifdef __MMFILE_TEST_MODE__
+                                                       debug_msg ( "pInfo->pGenre returned = (%s), pInfo->genreLen(%d)\n", pInfo->pGenre, pInfo->genreLen);
+                                                       #endif
 
                                                        if((pInfo->pGenre != NULL) && (pInfo->genreLen > 0)) {
-                                                               int ret = 0;
+                                                               bool ret = FALSE;
                                                                int int_genre = -1;
 
-                                                               ret = sscanf( pInfo->pGenre, "%d", &int_genre);
+                                                               ret = is_numeric(pInfo->pGenre, pInfo->genreLen);
 
-                                                               if(ret == 1) {
+                                                               if(ret == TRUE) {
+                                                                       sscanf( pInfo->pGenre, "%d", &int_genre);
                                                                        #ifdef __MMFILE_TEST_MODE__
                                                                        debug_msg("genre information is inteager [%d]\n", int_genre);
                                                                        #endif
@@ -2613,18 +2790,7 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TRCK", 4) == 0 && pInfo->tagV2Info.bTrackNumMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->tracknumLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->tracknumLen);
-                                                       }
+                                                       pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->tracknumLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pTrackNum returned = (%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
@@ -2633,18 +2799,8 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TENC", 4) == 0 && pInfo->tagV2Info.bEncByMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pEncBy = mmfile_string_convert ((char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->encbyLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->encbyLen);
-                                                       }
+                                                       pInfo->pEncBy = mmfile_string_convert ((char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->encbyLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pEncBy returned = (%s), pInfo->encbyLen(%d)\n", pInfo->pEncBy, pInfo->encbyLen);
                                                        #endif
@@ -2652,18 +2808,7 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "WXXX", 4) == 0 && pInfo->tagV2Info.bURLMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->urlLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->urlLen);
-                                                       }
+                                                       pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->urlLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pURL returned = (%s), pInfo->urlLen(%d)\n", pInfo->pURL, pInfo->urlLen);
@@ -2672,18 +2817,7 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCOP", 4) == 0 && pInfo->tagV2Info.bCopyRightMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->copyrightLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->copyrightLen);
-                                                       }
+                                                       pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->copyrightLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pCopyright returned = (%s), pInfo->copyrightLen(%d)\n", pInfo->pCopyright, pInfo->copyrightLen);
@@ -2692,18 +2826,8 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TOPE", 4) == 0 && pInfo->tagV2Info.bOriginArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->originartistLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->originartistLen);
-                                                       }
+                                                       pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->originartistLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pOriginArtist returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pOriginArtist, pInfo->originartistLen);
                                                        #endif
@@ -2711,18 +2835,7 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCOM", 4) == 0 && pInfo->tagV2Info.bComposerMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->composerLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->composerLen);
-                                                       }
+                                                       pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->composerLen);
 
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pComposer returned = (%s), pInfo->composerLen(%d)\n", pInfo->pComposer, pInfo->composerLen);
@@ -2731,18 +2844,8 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TRDA", 4) == 0 && pInfo->tagV2Info.bRecDateMarked== false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->recdateLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else
-                                                       {
-                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->recdateLen);
-                                                       }
+                                                       pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->recdateLen);
+
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pRecDate returned = (%s), pInfo->recdateLen(%d)\n", pInfo->pRecDate, pInfo->recdateLen);
                                                        #endif
@@ -2750,132 +2853,162 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "APIC", 4) == 0 && pInfo->tagV2Info.bImageMarked == false && realCpyFrameNum <= 2000000)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
+                                                       debug_msg ( "text encoding %d \n", textEncodingType);
+
+                                                       if(pExtContent[0] != '\0')
+                                                       {
+                                                               for(inx = 0; inx < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1; inx++)
+                                                                       pInfo->imageInfo.imageMIMEType[inx] = '\0';//ini mimetype variable
+
+                                                               while((checkImgMimeTypeMax < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1) && pExtContent[checkImgMimeTypeMax] != '\0')
+                                                               {
+                                                                       pInfo->imageInfo.imageMIMEType[checkImgMimeTypeMax] = pExtContent[checkImgMimeTypeMax];
+                                                                       checkImgMimeTypeMax++;
+                                                               }
+                                                               pInfo->imageInfo.imgMimetypeLen = checkImgMimeTypeMax;
+                                                       }
+                                                       else
                                                        {
+                                                               pInfo->imageInfo.imgMimetypeLen = 0;
                                                                #ifdef __MMFILE_TEST_MODE__
-                                                               debug_msg ( "mmf_file_id3tag_parse_v223: this is abnormal case!!\n");
+                                                               debug_msg ( "APIC image's not included to MIME type\n");
                                                                #endif
+                                                       }
 
+                                                       imgstartOffset += checkImgMimeTypeMax;
+
+                                                       if (strncmp(pInfo->imageInfo.imageMIMEType, MIME_PRFIX, strlen(MIME_PRFIX)) != 0) {
+                                                               pInfo->imageInfo.imgMimetypeLen = 0;
+                                                               debug_error("APIC NOT VALID");
+                                                               continue;
                                                        }
-                                                       else
+
+                                                       if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
                                                        {
-                                                               if(pExtContent[0] != '\0')
-                                                               {
-                                                                       for(inx = 0; inx < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1; inx++)
-                                                                               pInfo->imageInfo.imageMIMEType[inx] = '\0';//ini mimetype variable
+                                                               imgstartOffset++;//endofMIME(1byte)
+                                                               #ifdef __MMFILE_TEST_MODE__
+                                                               debug_msg ( "after scaning Mime type imgstartOffset(%d) value!\n", imgstartOffset);
+                                                               #endif
 
-                                                                       while((checkImgMimeTypeMax < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1) && pExtContent[checkImgMimeTypeMax] != '\0')
-                                                                       {
-                                                                               pInfo->imageInfo.imageMIMEType[checkImgMimeTypeMax] = pExtContent[checkImgMimeTypeMax];
-                                                                               checkImgMimeTypeMax++;
-                                                                       }
-                                                                       pInfo->imageInfo.imgMimetypeLen = checkImgMimeTypeMax;
+                                                               if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
+                                                               {
+                                                                       pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
                                                                }
                                                                else
                                                                {
-                                                                       pInfo->imageInfo.imgMimetypeLen = 0;
                                                                        #ifdef __MMFILE_TEST_MODE__
-                                                                       debug_msg ( "APIC image's not included to MIME type\n");
+                                                                       debug_msg ( "APIC image has invalid picture type(0x%x)\n", pExtContent[imgstartOffset]);
                                                                        #endif
                                                                }
+                                                               imgstartOffset++;//PictureType(1byte)
+                                                               #ifdef __MMFILE_TEST_MODE__
+                                                               debug_msg ( "after scaning PictureType imgstartOffset(%d) value!\n", imgstartOffset);
+                                                               #endif
 
-                                                               imgstartOffset += checkImgMimeTypeMax;
-
-                                                               if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
+                                                               if(pExtContent[imgstartOffset] != 0x0)
                                                                {
-                                                                       imgstartOffset++;//endofMIME(1byte)
+                                                                       int cur_pos = 0;
+                                                                       int dis_len = 0;
+                                                                       int new_dis_len = 0;
+                                                                       char jpg_sign[3] = {0xff, 0xd8, 0xff};
+                                                                       char png_sign[8] = {0x80, 0x50, 0x4e, 0x47,0x0d, 0x0a, 0x1a, 0x0a};
+                                                                       char *tmp_desc = NULL;
+
+                                                                       while (1) {
+                                                                               if (pExtContent[imgstartOffset + cur_pos] == '\0') {
+                                                                                       if (realCpyFrameNum < imgstartOffset + cur_pos) {
+                                                                                               debug_error("End of APIC Tag %d %d %d\n", realCpyFrameNum, imgstartOffset, cur_pos);
+                                                                                               break;
+                                                                                       }
+                                                                                       /*check end of image description*/
+                                                                                       if ((pExtContent[imgstartOffset + cur_pos + 1] == jpg_sign[0]) ||
+                                                                                               (pExtContent[imgstartOffset + cur_pos + 1] == png_sign[0])) {
+                                                                                               #ifdef __MMFILE_TEST_MODE__
+                                                                                               debug_msg ( "length of description (%d)", cur_pos);
+                                                                                               #endif
+
+                                                                                               break;
+                                                                                       }
+                                                                               }
+                                                                               cur_pos ++;
+                                                                       }
+
+                                                                       dis_len = cur_pos + 1;
+
+                                                                       tmp_desc = mmfile_malloc(sizeof(char) * dis_len);
+                                                                       memcpy(tmp_desc, pExtContent + imgstartOffset, dis_len);
+
+                                                                       /*convert description*/
+                                                                       pInfo->imageInfo.imageDescription = mmfile_string_convert (tmp_desc, dis_len, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&new_dis_len);
                                                                        #ifdef __MMFILE_TEST_MODE__
-                                                                       debug_msg ( "after scaning Mime type imgstartOffset(%d) value!\n", imgstartOffset);
+                                                                       debug_msg ( "new_desc %s(%d)\n", pInfo->imageInfo.imageDescription, new_dis_len);
                                                                        #endif
+                                                                       mmfile_free(tmp_desc);
 
-                                                                       if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
-                                                                       {
-                                                                               pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "APIC image has invalid picture type(0x%x)\n", pExtContent[imgstartOffset]);
-                                                                               #endif
-                                                                       }
-                                                                       imgstartOffset++;//PictureType(1byte)
+                                                                       pInfo->imageInfo.imgDesLen = new_dis_len; /**/
+                                                                       imgstartOffset += cur_pos;
+                                                               }
+                                                               else
+                                                               {
+                                                                       pInfo->imageInfo.imgDesLen= 0;
                                                                        #ifdef __MMFILE_TEST_MODE__
-                                                                       debug_msg ( "after scaning PictureType imgstartOffset(%d) value!\n", imgstartOffset);
+                                                                       debug_msg ( "APIC image's not included to Description!!!\n");
                                                                        #endif
+                                                               }
 
-                                                                       if(pExtContent[imgstartOffset] != 0x0)
-                                                                       {
-                                                                               for(inx = 0; inx < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1; inx++)
-                                                                                       pInfo->imageInfo.imageDescription[inx] = '\0';//ini imgdescripiton variable
+                                                               if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
+                                                               {
+                                                                       imgstartOffset ++; // endofDesceriptionType(1byte)
 
-                                                                               while((checkImgDescriptionMax < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1) && pExtContent[imgstartOffset+checkImgDescriptionMax] != '\0')
-                                                                               {
-                                                                                       pInfo->imageInfo.imageDescription[checkImgDescriptionMax] = pExtContent[imgstartOffset+checkImgDescriptionMax];
-                                                                                       checkImgDescriptionMax++;
-                                                                               }
-                                                                               pInfo->imageInfo.imgDesLen= checkImgDescriptionMax;
-                                                                       }
-                                                                       else
+                                                                       while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
                                                                        {
-                                                                               pInfo->imageInfo.imgDesLen= 0;
-                                                                               #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "APIC image's not included to Description!!!\n");
-                                                                               #endif
+                                                                               imgstartOffset ++;
                                                                        }
 
-                                                                       imgstartOffset += checkImgDescriptionMax;
-                                                                       if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
-                                                                       {
-                                                                               imgstartOffset ++; // endofDesceriptionType(1byte)
-
-                                                                               while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
-                                                                               {
-                                                                                       imgstartOffset ++;
-                                                                               }
+                                                                       #ifdef __MMFILE_TEST_MODE__
+                                                                       debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
+                                                                       #endif
 
-                                                                               #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
-                                                                               #endif
+                                                                       if(realCpyFrameNum - imgstartOffset > 0)
+                                                                       {
+                                                                               pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
+                                                                               pInfo->imageInfo.pImageBuf = mmfile_malloc (pInfo->imageInfo.imageLen + 1);
 
-                                                                               if(realCpyFrameNum - imgstartOffset > 0)
-                                                                               {
-                                                                                       pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
-                                                                                       pInfo->imageInfo.pImageBuf = mmfile_malloc (pInfo->imageInfo.imageLen + 1);
+                                                                               if(pInfo->imageInfo.pImageBuf != NULL ) {
                                                                                        memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
                                                                                        pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
-                                                                                       if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
-                                                                                               pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       #ifdef __MMFILE_TEST_MODE__
-                                                                                       debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
-                                                                                       #endif
                                                                                }
-                                                                               #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "pInfo->imageInfo.imageLen(%d), imgstartOffset(%d)!\n", pInfo->imageInfo.imageLen, imgstartOffset);
-                                                                               #endif
+
+                                                                               if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
+                                                                                       pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
                                                                        }
                                                                        else
                                                                        {
                                                                                #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "pExtContent[imgstartOffset](%d) value should setted NULL value for end of description! realCpyFrameNum - imgstartOffset(%d)\n",
-                                                                                                       pExtContent[imgstartOffset], realCpyFrameNum - imgstartOffset);
+                                                                               debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
                                                                                #endif
                                                                        }
+                                                                       #ifdef __MMFILE_TEST_MODE__
+                                                                       debug_msg ( "pInfo->imageInfo.imageLen(%d), imgstartOffset(%d)!\n", pInfo->imageInfo.imageLen, imgstartOffset);
+                                                                       #endif
                                                                }
                                                                else
                                                                {
                                                                        #ifdef __MMFILE_TEST_MODE__
-                                                                       debug_msg ( "pExtContent[imgstartOffset](%d) value should setted NULL value for end of mimetype! realCpyFrameNum - imgstartOffset(%d)\n",
-                                                                                       pExtContent[imgstartOffset], realCpyFrameNum - imgstartOffset);
+                                                                       debug_msg ( "pExtContent[imgstartOffset](%d) value should setted NULL value for end of description! realCpyFrameNum - imgstartOffset(%d)\n",
+                                                                                               pExtContent[imgstartOffset], realCpyFrameNum - imgstartOffset);
                                                                        #endif
                                                                }
-
+                                                       }
+                                                       else
+                                                       {
+                                                               #ifdef __MMFILE_TEST_MODE__
+                                                               debug_msg ( "pExtContent[imgstartOffset](%d) value should setted NULL value for end of mimetype! realCpyFrameNum - imgstartOffset(%d)\n",
+                                                                               pExtContent[imgstartOffset], realCpyFrameNum - imgstartOffset);
+                                                               #endif
                                                        }
 
                                                        checkImgMimeTypeMax = 0;
-                                                       checkImgDescriptionMax = 0;
                                                        inx = 0;
                                                        imgstartOffset = 0;
                                                        pInfo->tagV2Info.bImageMarked= true;
@@ -2908,7 +3041,6 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                        }
 
                        if(pExtContent) _FREE_EX(pExtContent);
-                       if(tmpConvert2Pcode)    _FREE_EX(tmpConvert2Pcode);
                        memset(CompTmp, 0, 4);
 
                        if(curPos < taglen)
@@ -2927,6 +3059,8 @@ bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
                }
        }
 
+       release_characterset_array(charset_array);
+
        if(taglen)
                return true;
        else
@@ -2945,34 +3079,14 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
        char CompTmp[5];
        unsigned char *pExtContent = NULL;
        unsigned long purelyFramelen = 0;
-       char *tmpConvert2Pcode = NULL;
-       int inx=0, encodingOffSet=0, realCpyFrameNum=0, checkImgMimeTypeMax=0, checkImgDescriptionMax=0, imgstartOffset=0,  tmp = 0;
+       int inx=0, encodingOffSet=0, realCpyFrameNum=0, checkImgMimeTypeMax=0, imgstartOffset=0,  tmp = 0;
        int textEncodingType = 0;
-       const char *locale = NULL;
+       char **charset_array = NULL;
+       char *MIME_PRFIX = "image/";
 
-       locale = MMFileUtilGetLocale (NULL);
-
-       pInfo->tagV2Info.bTitleMarked = false;
-       pInfo->tagV2Info.bAlbumMarked= false;
-       pInfo->tagV2Info.bArtistMarked= false;
-       pInfo->tagV2Info.bDescriptionMarked= false;
-       pInfo->tagV2Info.bGenreMarked= false;
-       pInfo->tagV2Info.bYearMarked= false;
-       pInfo->tagV2Info.bTrackNumMarked= false;
-       pInfo->tagV2Info.bEncByMarked= false;
-       pInfo->tagV2Info.bURLMarked= false;
-       pInfo->tagV2Info.bCopyRightMarked= false;
-       pInfo->tagV2Info.bOriginArtistMarked= false;
-       pInfo->tagV2Info.bComposerMarked= false;
-       pInfo->tagV2Info.bImageMarked= false;
-       pInfo->imageInfo.bURLInfo = false;
-       pInfo->tagV2Info.bConductorMarked = false;
-       pInfo->tagV2Info.bGenreUTF16 = false;
-       pInfo->tagV2Info.bUnsyncLyricsMarked = false;
-       pInfo->tagV2Info.bSyncLyricsMarked = false;
+       make_characterset_array(&charset_array);
 
-       pInfo->imageInfo.pImageBuf = NULL;
-       pInfo->imageInfo.imageLen = 0;
+       init_content_info(pInfo);
 
        taglen = pInfo->tagV2Info.tagLen;
        needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
@@ -2989,7 +3103,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                int extendedHeaderLen = (unsigned long)buffer[10] << 21 | (unsigned long)buffer[11] << 14 | (unsigned long)buffer[12] << 7  | (unsigned long)buffer[13];
 
                #ifdef __MMFILE_TEST_MODE__
-               debug_msg ("[%s][%d]--------------- extendedHeaderLen = %d\n",__func__,__LINE__, extendedHeaderLen);
+               debug_msg ("--------------- extendedHeaderLen = %d\n", extendedHeaderLen);
                #endif 
 
                curPos += extendedHeaderLen;
@@ -3080,30 +3194,28 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                        realCpyFrameNum = purelyFramelen - encodingOffSet;
                                        pExtContent = mmfile_malloc (realCpyFrameNum+3);
                                        memset(pExtContent, '\0', realCpyFrameNum+3);
-                                       if(textEncodingType == AV_ID3V2_ISO_8859)
-                                       {
-                                               if(strncmp((char *)CompTmp, "APIC", 4) != 0)
-                                               {
-                                                       tmpConvert2Pcode = mmfile_malloc ((realCpyFrameNum)*2+2);
-                                                       memset(tmpConvert2Pcode, 0, (realCpyFrameNum)*2+2);
+
+                                       if (textEncodingType != AV_ID3V2_UTF16 && textEncodingType != AV_ID3V2_UTF16_BE) {
+                                               if (CompTmp[0] == 'T' ||(strcmp(CompTmp, "APIC")==0)) {
+                                                       #ifdef __MMFILE_TEST_MODE__
+                                                       debug_msg ( "get the new text ecoding type\n");
+                                                       #endif
+                                                       textEncodingType = buffer[curPos-purelyFramelen+encodingOffSet -1];
                                                }
                                        }
 
+                                       if (textEncodingType > AV_ID3V2_MAX) {
+                                               debug_msg ( "WRONG ENCOIDNG TYPE [%d], FRAME[%s]\n", textEncodingType, (char*)CompTmp);
+                                               continue;
+                                       }
+
                                        memcpy(pExtContent, &buffer[curPos-purelyFramelen+encodingOffSet], purelyFramelen-encodingOffSet);
 
                                        if(realCpyFrameNum > 0)
                                        {
                                                if(strncmp((char *)CompTmp, "TIT2", 4) == 0 && pInfo->tagV2Info.bTitleMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->titleLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pTitle= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pTitle, pExtContent, realCpyFrameNum);
@@ -3114,7 +3226,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
+                                                               pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->titleLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3125,15 +3237,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TPE1", 4) == 0 && pInfo->tagV2Info.bArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->artistLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pArtist= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pArtist, pExtContent, realCpyFrameNum);
@@ -3144,7 +3248,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
+                                                               pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->artistLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3152,17 +3256,30 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        #endif
                                                        pInfo->tagV2Info.bArtistMarked = true;
                                                }
-                                               else if(strncmp((char *)CompTmp, "TPE3", 4) == 0 && pInfo->tagV2Info.bConductorMarked == false)
+                                               else if(strncmp((char *)CompTmp, "TPE2", 4) == 0 && pInfo->tagV2Info.bAlbum_ArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
-                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->conductorLen);
+                                                               pInfo->pAlbum_Artist= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
+                                                               memcpy(pInfo->pAlbum_Artist, pExtContent, realCpyFrameNum);
+                                                               pInfo->pAlbum_Artist[realCpyFrameNum] = '\0';
+                                                               /*string copy with '\0'*/
+                                                               pInfo->album_artistLen = realCpyFrameNum;
+                                                               _STRNCPY_EX (pInfo->pAlbum_Artist, pExtContent, pInfo->album_artistLen);
                                                        }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
+                                                       else
                                                        {
-                                                               debug_warning ("not implemented\n");
+                                                               pInfo->pAlbum_Artist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->album_artistLen);
                                                        }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+
+                                                       #ifdef __MMFILE_TEST_MODE__
+                                                       debug_msg ( "pInfo->pAlbum_Artist returned = (%s), pInfo->album_artistLen(%d)\n", pInfo->pAlbum_Artist, pInfo->album_artistLen);
+                                                       #endif
+                                                       pInfo->tagV2Info.bAlbum_ArtistMarked = true;
+                                               }
+                                               else if(strncmp((char *)CompTmp, "TPE3", 4) == 0 && pInfo->tagV2Info.bConductorMarked == false)
+                                               {
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pConductor= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pConductor, pExtContent, realCpyFrameNum);
@@ -3173,7 +3290,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->conductorLen);
+                                                               pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->conductorLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3183,15 +3300,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TALB", 4) == 0 && pInfo->tagV2Info.bAlbumMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->albumLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pAlbum= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pAlbum, pExtContent, realCpyFrameNum);
@@ -3202,7 +3311,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
+                                                               pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->albumLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3212,15 +3321,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TYER", 4) == 0 && pInfo->tagV2Info.bYearMarked == false)      //TODO. TYER is replaced by the TDRC. but many files use TYER in v2.4
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->yearLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pYear= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pYear, pExtContent, realCpyFrameNum);
@@ -3231,7 +3332,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
+                                                               pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->yearLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3290,15 +3391,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
                                                                #endif
 
-                                                               if(textEncodingType == AV_ID3V2_UTF16)
-                                                               {
-                                                                       pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->commentLen);
-                                                               }
-                                                               else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                               {
-                                                                       debug_warning ("not implemented\n");
-                                                               }
-                                                               else if(textEncodingType == AV_ID3V2_UTF8)
+                                                               if(textEncodingType == AV_ID3V2_UTF8)
                                                                {
                                                                        pInfo->pComment= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                        memset(pInfo->pComment, 0, (realCpyFrameNum+2));
@@ -3310,7 +3403,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                }
                                                                else
                                                                {
-                                                                       pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
+                                                                       pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->commentLen);
                                                                }
                                                        }
                                                        else
@@ -3416,7 +3509,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                                                        synclyrics_info->lyric_info[copy_len+1] = '\0';
                                                                                                }
                                                                                                else {
-                                                                                                       synclyrics_info->lyric_info = mmfile_string_convert ((const char*)&pExtContent[copy_start_pos], copy_len, "UTF-8", locale, NULL, NULL);
+                                                                                                       synclyrics_info->lyric_info = mmfile_string_convert ((const char*)&pExtContent[copy_start_pos], copy_len, "UTF-8", charset_array[textEncodingType], NULL, NULL);
                                                                                                }
 
                                                                                                synclyrics_info->time_info= (unsigned long)pExtContent[tmp+idx+1] << 24 | (unsigned long)pExtContent[tmp+idx+2] << 16 | (unsigned long)pExtContent[tmp+idx+3] << 8  | (unsigned long)pExtContent[tmp+idx+4];
@@ -3496,15 +3589,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
                                                                #endif
 
-                                                               if(textEncodingType == AV_ID3V2_UTF16)
-                                                               {
-                                                                       pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->unsynclyricsLen);
-                                                               }
-                                                               else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                               {
-                                                                       debug_warning ("not implemented\n");
-                                                               }
-                                                               else if(textEncodingType == AV_ID3V2_UTF8)
+                                                               if(textEncodingType == AV_ID3V2_UTF8)
                                                                {
                                                                        pInfo->pUnsyncLyrics= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                        memset(pInfo->pUnsyncLyrics, 0, (realCpyFrameNum+2));
@@ -3516,7 +3601,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                                }
                                                                else
                                                                {
-                                                                       pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->unsynclyricsLen);
+                                                                       pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->unsynclyricsLen);
                                                                }
                                                        }
                                                        else
@@ -3535,15 +3620,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCON", 4) == 0 && pInfo->tagV2Info.bGenreMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->genreLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pGenre= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pGenre, pExtContent, realCpyFrameNum);
@@ -3554,7 +3631,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->genreLen);
+                                                               pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->genreLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3562,12 +3639,13 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        #endif
 
                                                        if((pInfo->pGenre != NULL) && (pInfo->genreLen > 0)) {
-                                                               int ret = 0;
+                                                               bool ret = FALSE;
                                                                int int_genre = -1;
 
-                                                               ret = sscanf( pInfo->pGenre, "%d", &int_genre);
+                                                               ret = is_numeric(pInfo->pGenre, pInfo->genreLen);
 
-                                                               if(ret == 1) {
+                                                               if(ret == TRUE) {
+                                                                       sscanf( pInfo->pGenre, "%d", &int_genre);
                                                                        #ifdef __MMFILE_TEST_MODE__
                                                                        debug_msg("genre information is inteager [%d]\n", int_genre);
                                                                        #endif
@@ -3599,15 +3677,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TRCK", 4) == 0 && pInfo->tagV2Info.bTrackNumMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->tracknumLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pTrackNum= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pTrackNum, pExtContent, realCpyFrameNum);
@@ -3618,7 +3688,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->tracknumLen);
+                                                               pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->tracknumLen);
                                                        }
 
 
@@ -3629,15 +3699,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TENC", 4) == 0 && pInfo->tagV2Info.bEncByMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->encbyLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pEncBy= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pEncBy, pExtContent, realCpyFrameNum);
@@ -3648,7 +3710,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->encbyLen);
+                                                               pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->encbyLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3658,15 +3720,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "WXXX", 4) == 0 && pInfo->tagV2Info.bURLMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->urlLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pURL= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pURL, pExtContent, realCpyFrameNum);
@@ -3677,7 +3731,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->urlLen);
+                                                               pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->urlLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3687,15 +3741,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCOP", 4) == 0 && pInfo->tagV2Info.bCopyRightMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->copyrightLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pCopyright= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pCopyright, pExtContent, realCpyFrameNum);
@@ -3706,7 +3752,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->copyrightLen);
+                                                               pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->copyrightLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3716,15 +3762,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TOPE", 4) == 0 && pInfo->tagV2Info.bOriginArtistMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->originartistLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pOriginArtist= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pOriginArtist, pExtContent, realCpyFrameNum);
@@ -3735,7 +3773,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->originartistLen);
+                                                               pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->originartistLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3745,15 +3783,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TCOM", 4) == 0 && pInfo->tagV2Info.bComposerMarked == false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->composerLen);
-                                                       }
-                                                       else if (textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pComposer= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pComposer, pExtContent, realCpyFrameNum);
@@ -3764,7 +3794,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->composerLen);
+                                                               pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->composerLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3774,15 +3804,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TDRC", 4) == 0 && pInfo->tagV2Info.bRecDateMarked== false)    //TYER(year) and TRDA are replaced by the TDRC
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->recdateLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pRecDate= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pRecDate, pExtContent, realCpyFrameNum);
@@ -3793,7 +3815,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->recdateLen);
+                                                               pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->recdateLen);
                                                        }
 
                                                        #ifdef __MMFILE_TEST_MODE__
@@ -3803,15 +3825,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "TIT1", 4) == 0 && pInfo->tagV2Info.bContentGroupMarked== false)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16)
-                                                       {
-                                                               pInfo->pContentGroup = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->contentGroupLen);
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF16_BE)
-                                                       {
-                                                               debug_warning ("not implemented\n");
-                                                       }
-                                                       else if(textEncodingType == AV_ID3V2_UTF8)
+                                                       if(textEncodingType == AV_ID3V2_UTF8)
                                                        {
                                                                pInfo->pContentGroup= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
                                                                memcpy(pInfo->pContentGroup, pExtContent, realCpyFrameNum);
@@ -3822,7 +3836,7 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                        }
                                                        else
                                                        {
-                                                               pInfo->pContentGroup = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->contentGroupLen);
+                                                               pInfo->pContentGroup = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&pInfo->contentGroupLen);
                                                        }
                                                        #ifdef __MMFILE_TEST_MODE__
                                                        debug_msg ( "pInfo->pContentGroup returned = (%s), pInfo->contentGroupLen(%d)\n", pInfo->pContentGroup, pInfo->contentGroupLen);
@@ -3831,95 +3845,124 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                                                }
                                                else if(strncmp((char *)CompTmp, "APIC", 4) == 0 && pInfo->tagV2Info.bImageMarked == false && realCpyFrameNum <= 2000000)
                                                {
-                                                       if(textEncodingType == AV_ID3V2_UTF16 || textEncodingType == AV_ID3V2_UTF16_BE || textEncodingType == AV_ID3V2_UTF8)
+                                                       if(pExtContent[0] != '\0')
                                                        {
-                                                               #ifdef __MMFILE_TEST_MODE__
-                                                               debug_msg ( "mmf_file_id3tag_parse_v224: this is abnormal case!!\n");
-                                                               #endif
+                                                               for(inx = 0; inx < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1; inx++)
+                                                                       pInfo->imageInfo.imageMIMEType[inx] = '\0';//ini mimetype variable
+
+                                                               while((checkImgMimeTypeMax < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1) && pExtContent[checkImgMimeTypeMax] != '\0')
+                                                               {
+                                                                       pInfo->imageInfo.imageMIMEType[checkImgMimeTypeMax] = pExtContent[checkImgMimeTypeMax];
+                                                                       checkImgMimeTypeMax++;
+                                                               }
+                                                               pInfo->imageInfo.imgMimetypeLen = checkImgMimeTypeMax;
                                                        }
                                                        else
                                                        {
-                                                               if(pExtContent[0] != '\0')
+                                                               pInfo->imageInfo.imgMimetypeLen = 0;
+                                                       }
+
+                                                       imgstartOffset += checkImgMimeTypeMax;
+
+                                                       if (strncmp(pInfo->imageInfo.imageMIMEType, MIME_PRFIX, strlen(MIME_PRFIX)) != 0) {
+                                                               pInfo->imageInfo.imgMimetypeLen = 0;
+                                                               debug_error("APIC NOT VALID");
+                                                               continue;
+                                                       }
+
+                                                       if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
+                                                       {
+                                                               imgstartOffset++;//endofMIME(1byte)
+
+                                                               if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
                                                                {
-                                                                       for(inx = 0; inx < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1; inx++)
-                                                                               pInfo->imageInfo.imageMIMEType[inx] = '\0';//ini mimetype variable
+                                                                       pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
+                                                               }
+                                                               imgstartOffset++;//PictureType(1byte)
 
-                                                                       while((checkImgMimeTypeMax < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1) && pExtContent[checkImgMimeTypeMax] != '\0')
-                                                                       {
-                                                                               pInfo->imageInfo.imageMIMEType[checkImgMimeTypeMax] = pExtContent[checkImgMimeTypeMax];
-                                                                               checkImgMimeTypeMax++;
+                                                               if(pExtContent[imgstartOffset] != 0x0)
+                                                               {
+                                                                       int cur_pos = 0;
+                                                                       int dis_len = 0;
+                                                                       int new_dis_len = 0;
+                                                                       char jpg_sign[3] = {0xff, 0xd8, 0xff};
+                                                                       char png_sign[8] = {0x80, 0x50, 0x4e, 0x47,0x0d, 0x0a, 0x1a, 0x0a};
+                                                                       char *tmp_desc = NULL;
+
+                                                                       while (1) {
+                                                                               if (pExtContent[imgstartOffset + cur_pos] == '\0') {
+                                                                                       if (realCpyFrameNum < imgstartOffset + cur_pos) {
+                                                                                               debug_error("End of APIC Tag %d %d %d\n", realCpyFrameNum, imgstartOffset, cur_pos);
+                                                                                               break;
+                                                                                       }
+                                                                                       /*check end of image description*/
+                                                                                       if ((pExtContent[imgstartOffset + cur_pos + 1] == jpg_sign[0]) ||
+                                                                                               (pExtContent[imgstartOffset + cur_pos + 1] == png_sign[0])) {
+                                                                                               #ifdef __MMFILE_TEST_MODE__
+                                                                                               debug_msg ( "length of description (%d)", cur_pos);
+                                                                                               #endif
+
+                                                                                               break;
+                                                                                       }
+                                                                               }
+                                                                               cur_pos ++;
                                                                        }
-                                                                       pInfo->imageInfo.imgMimetypeLen = checkImgMimeTypeMax;
+
+                                                                       dis_len = cur_pos + 1;
+
+                                                                       tmp_desc = mmfile_malloc(sizeof(char) * dis_len);
+                                                                       memcpy(tmp_desc, pExtContent + imgstartOffset, dis_len);
+                                                                       debug_msg ( "tmp_desc %s\n", tmp_desc);
+
+                                                                       /*convert description*/
+                                                                       pInfo->imageInfo.imageDescription = mmfile_string_convert (tmp_desc, dis_len, "UTF-8", charset_array[textEncodingType], NULL, (unsigned int*)&new_dis_len);
+                                                                       debug_msg ( "new_desc %s(%d)\n", pInfo->imageInfo.imageDescription, new_dis_len);
+                                                                       mmfile_free(tmp_desc);
+
+                                                                       pInfo->imageInfo.imgDesLen = new_dis_len; /**/
+                                                                       imgstartOffset += cur_pos;
                                                                }
                                                                else
                                                                {
-                                                                       pInfo->imageInfo.imgMimetypeLen = 0;
+                                                                       pInfo->imageInfo.imgDesLen= 0;
                                                                }
 
-                                                               imgstartOffset += checkImgMimeTypeMax;
-
                                                                if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
                                                                {
-                                                                       imgstartOffset++;//endofMIME(1byte)
+                                                                       imgstartOffset ++; // endofDesceriptionType(1byte)
 
-                                                                       if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
+                                                                       while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
                                                                        {
-                                                                               pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
+                                                                               imgstartOffset ++;
                                                                        }
-                                                                       imgstartOffset++;//PictureType(1byte)
 
-                                                                       if(pExtContent[imgstartOffset] != 0x0)
+                                                                       #ifdef __MMFILE_TEST_MODE__
+                                                                       debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
+                                                                       #endif
+
+                                                                       if(realCpyFrameNum - imgstartOffset > 0)
                                                                        {
-                                                                               for(inx = 0; inx < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1; inx++)
-                                                                                       pInfo->imageInfo.imageDescription[inx] = '\0';//ini imgdescripiton variable
+                                                                               pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
+                                                                               pInfo->imageInfo.pImageBuf= mmfile_malloc (pInfo->imageInfo.imageLen+1);
 
-                                                                               while((checkImgDescriptionMax < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1) && pExtContent[imgstartOffset+checkImgDescriptionMax] != '\0')
-                                                                               {
-                                                                                       pInfo->imageInfo.imageDescription[checkImgDescriptionMax] = pExtContent[imgstartOffset+checkImgDescriptionMax];
-                                                                                       checkImgDescriptionMax++;
+                                                                               if(pInfo->imageInfo.pImageBuf != NULL) {
+                                                                                       memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
+                                                                                       pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
                                                                                }
-                                                                               pInfo->imageInfo.imgDesLen= checkImgDescriptionMax;
+
+                                                                               if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
+                                                                                       pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
                                                                        }
                                                                        else
                                                                        {
-                                                                               pInfo->imageInfo.imgDesLen= 0;
-                                                                       }
-
-                                                                       imgstartOffset += checkImgDescriptionMax;
-                                                                       if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
-                                                                       {
-                                                                               imgstartOffset ++; // endofDesceriptionType(1byte)
-
-                                                                               while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
-                                                                               {
-                                                                                       imgstartOffset ++;
-                                                                               }
-
                                                                                #ifdef __MMFILE_TEST_MODE__
-                                                                               debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
+                                                                               debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
                                                                                #endif
-
-                                                                               if(realCpyFrameNum - imgstartOffset > 0)
-                                                                               {
-                                                                                       pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
-                                                                                       pInfo->imageInfo.pImageBuf= mmfile_malloc (pInfo->imageInfo.imageLen+1);
-                                                                                       memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
-                                                                                       pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
-                                                                                       if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
-                                                                                               pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       #ifdef __MMFILE_TEST_MODE__
-                                                                                       debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
-                                                                                       #endif
-                                                                               }
                                                                        }
                                                                }
                                                        }
 
                                                        checkImgMimeTypeMax = 0;
-                                                       checkImgDescriptionMax = 0;
                                                        inx = 0;
                                                        imgstartOffset = 0;
                                                        pInfo->tagV2Info.bImageMarked= true;
@@ -3949,7 +3992,6 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                        }
 
                        if(pExtContent) _FREE_EX(pExtContent);
-                       if(tmpConvert2Pcode)    _FREE_EX(tmpConvert2Pcode);
                        memset(CompTmp, 0, 4);
                        if(curPos < taglen)
                        {
@@ -3968,6 +4010,8 @@ bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
                }
        }
 
+       release_characterset_array(charset_array);
+
        if(taglen)
                return true;
        else
@@ -4045,8 +4089,10 @@ void mm_file_id3tag_restore_content_info(AvFileContentInfo* pInfo)
                        if (pInfo->pGenre) {
                                pInfo->genreLen = strlen(pInfo->pGenre);
                                mpegAudioGenre = mmfile_malloc (sizeof(char) * (pInfo->genreLen + 1) );
-                               mpegAudioGenre[pInfo->genreLen] = '\0';
-                               strncpy(mpegAudioGenre, pInfo->pGenre, pInfo->genreLen);
+                               if(mpegAudioGenre != NULL) {
+                                       mpegAudioGenre[pInfo->genreLen] = '\0';
+                                       strncpy(mpegAudioGenre, pInfo->pGenre, pInfo->genreLen);
+                               }
                        } else {
                                pInfo->genreLen = 0;
                        }
index 06cd0dd..6f48dbd 100755 (executable)
@@ -36,6 +36,7 @@
 static int _MMFileSearchID3Tag (MMFileIOHandle *fp, unsigned int *offset);
 static int _MMFileIsMP3Header  (void *header);
 static int _MMFileIsOGGHeader  (void *header);
+static int _MMFileIsREALHeader  (void *header);
 static int _MMFileIsMP4Header  (void *header);
 static int _MMFileIsWAVHeader  (void *header);
 static int _MMFileIsAVIHeader  (void *header);
@@ -46,8 +47,10 @@ static int _MMFileIsASFHeader  (void *header);
 static int _MMFileIsAMRHeader  (void *header);
 static int _MMFileIsFLACHeader  (void *header);
 static int _MMFileIsFLVHeader  (void *header);
-
-
+static int _MMFileIsMPEGTSHeader (MMFileIOHandle *fp);
+static int _MMFileIsMPEGPSHeader (void *header);
+static int _MMFileIsMPEGAUDIOHeader (void *header);
+static int _MMFileIsMPEGVIDEOHeader (void *header);
 
 /***********************************************************************/
 /*                     MP3 Header Check API                            */
@@ -92,7 +95,7 @@ int MMFileFormatIsValidMP3 (MMFileIOHandle *pFileIO, const char *mmfileuri, int
        ret = _MMFileSearchID3Tag (fp, &sizeID3);
        if (ret == 0) {
                debug_error("Error in searching the ID3 tag\n");
-               goto exit;
+//             goto exit;
        }
 
        ret = 0;
@@ -102,11 +105,11 @@ int MMFileFormatIsValidMP3 (MMFileIOHandle *pFileIO, const char *mmfileuri, int
        endoffset = startoffset + 102400;
        if(endoffset > filesize - _MMFILE_MP3_HEADER_LENGTH)
                endoffset = filesize - _MMFILE_MP3_HEADER_LENGTH;
-
+       
        /* find sync bit */
        i = startoffset;
        count = 0;
-
+       
        while (i < endoffset) {
                mmfile_seek (fp, i, MMFILE_SEEK_SET);
                readed = mmfile_read (fp, buffer, _MMFILE_MP3_BUFFER_LENGTH);
@@ -152,6 +155,10 @@ int MMFileFormatIsValidMP3 (MMFileIOHandle *pFileIO, const char *mmfileuri, int
                                }
                        }
                }
+
+               /*If j is zero, this loop is infinite */
+               if (j ==0) j++;
+
                i = i + j;
        }
 
@@ -213,7 +220,7 @@ int MMFileFormatIsValidAAC (MMFileIOHandle *pFileIO, const char *mmfileuri)
        ret = _MMFileSearchID3Tag (fp, &sizeID3);
        if (ret == 0) {
                debug_error("Error in searching the ID3 tag\n");
-               goto exit;
+//             goto exit;
        }
 
        ret = 0;
@@ -223,14 +230,14 @@ int MMFileFormatIsValidAAC (MMFileIOHandle *pFileIO, const char *mmfileuri)
        endoffset = startoffset + 10240;
        if(endoffset > filesize - _MMFILE_AAC_HEADER_LENGTH)
                endoffset = filesize - _MMFILE_AAC_HEADER_LENGTH;
-
+       
        i = startoffset;
 
        while (i < endoffset) {
                mmfile_seek (fp, i, MMFILE_SEEK_SET);
 
                readed = mmfile_read (fp, buffer, _MMFILE_AAC_BUFFER_LENGTH);
-
+       
                if (readed < _MMFILE_AAC_HEADER_LENGTH) {
                        debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
                        ret = 0;
@@ -278,6 +285,9 @@ int MMFileFormatIsValidAAC (MMFileIOHandle *pFileIO, const char *mmfileuri)
                                goto exit;
                        }
                }
+               /*If j is zero, this loop is infinite */
+               if (j ==0) j++;
+
                i = i + j;
        }
 
@@ -343,7 +353,7 @@ int MMFileFormatIsValidOGG (MMFileIOHandle *pFileIO, const char *mmfileuri)
        ret = _MMFileSearchID3Tag (fp, &sizeID3);
        if(ret == 0) {
                debug_error("Error in searching the ID3 tag\n");
-               goto exit;
+//             goto exit;
        }
 
        ret = 0;
@@ -494,6 +504,7 @@ int MMFileFormatIsValidWAV (MMFileIOHandle *pFileIO, const char *mmfileuri)
        mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
 
        readed = mmfile_read (fp, buffer, _MMFILE_WAV_HEADER_LENGTH);
+
        if (_MMFILE_WAV_HEADER_LENGTH != readed) {
                debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
                ret = 0;
@@ -922,9 +933,10 @@ EXPORT_API
 int MMFileFormatIsValidMatroska (MMFileIOHandle *pFileIO, const char *mmfileuri)
 {
 #define _MMFILE_EBML_MARKER_LENGTH     4
+#define _MMFILE_MKV_READ_BUFFER_LENGTH 2048
 
        MMFileIOHandle *fp = pFileIO;
-       unsigned char* buffer = NULL;
+       unsigned char buffer[_MMFILE_MKV_READ_BUFFER_LENGTH] = {0,};
        int           readed = 0;
        int ret = 0;
        int len_mask = 0x80, size = 1, n = 1, total = 0;
@@ -940,62 +952,67 @@ int MMFileFormatIsValidMatroska (MMFileIOHandle *pFileIO, const char *mmfileuri)
 
        mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
 
-       buffer = mmfile_malloc (_MMFILE_EBML_MARKER_LENGTH * sizeof(char));
-       readed = mmfile_read (fp, buffer, _MMFILE_EBML_MARKER_LENGTH);
-       if (_MMFILE_EBML_MARKER_LENGTH != readed) {
+       readed = mmfile_read (fp, buffer, _MMFILE_MKV_READ_BUFFER_LENGTH);
+
+       if (_MMFILE_MKV_READ_BUFFER_LENGTH != readed) {
                debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
                ret = 0;
                goto exit;
        }
 
        /* ebml header? */
-         if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
+       if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
+#ifdef __MMFILE_TEST_MODE__
                debug_msg ("This is not a EBML format\n");
-           ret = 0;
-           goto exit;
-         }
-
-         /* length of header */
-           mmfile_read (fp, (unsigned char*)(&total), 1);
-           debug_msg ("Initial total header size = [0x%x]\n", total);
-
-           while (size <= 8 && !(total & len_mask)) {
-             debug_error ("This case can not be handled yet....");
-             size++;
-             len_mask >>= 1;
-           }
-           if (size > 8) {
-               debug_error ("This case can not be handled yet....");
-               ret = 0;
-               goto exit;
-           }
-           total &= (len_mask - 1);
-           while (n < size) {
-             debug_error ("This case can not be handled yet....");
-             ret = 0;
-             goto exit;
-           }
-
-           debug_msg ("Final total header size = [%d]\n", total);
-
-           if (buffer)
-               mmfile_free (buffer);
-           buffer = mmfile_malloc (total * sizeof(char));
-           mmfile_read (fp, buffer, total);
-
-           for (n = 0; n <= total - sizeof (probe_data); n++) {
-             if (!memcmp (&buffer[n], probe_data, sizeof (probe_data))) {
-               debug_msg ("String matroska found!!!\n");
-               ret = 1;
-               goto exit;
-             }
-           }
+#endif
+               ret = 0;
+               goto exit;
+       }
 
-exit:
-       if (buffer) {
-               mmfile_free (buffer);
+       /* length of header */
+       total = buffer[4];
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg ("Initial total header size = [0x%x]\n", total);
+#endif
+
+       while (size <= 8 && !(total & len_mask)) {
+               debug_error ("This case can not be handled yet....");
+               size++;
+               len_mask >>= 1;
        }
 
+#ifdef __MMFILE_TEST_MODE__
+       debug_msg ("Final total header size = [%d]\n", total);
+#endif
+
+       if (size > 8) {
+               debug_error ("This case can not be handled yet....");
+               ret = 0;
+               goto exit;
+       }
+
+       total &= (len_mask - 1);
+
+       while (n < size) {
+               total = (total << 8) | buffer[4 + n++];
+               debug_error ("This case can not be handled yet....");
+       }
+
+       /* Does the probe data contain the whole header? */
+       if (_MMFILE_MKV_READ_BUFFER_LENGTH < 4 + size + total)
+               return 0;
+
+       for (n = 4+size ; n <= 4+size+total - sizeof (probe_data); n++) {
+               if (!memcmp (&buffer[n], probe_data, sizeof (probe_data))) {
+#ifdef __MMFILE_TEST_MODE__
+                       debug_msg ("String matroska found!!!\n");
+#endif
+                       ret = 1;
+                       goto exit;
+               }
+       }
+
+exit:
        if(pFileIO == NULL && fp != NULL)
                mmfile_close(fp);
 
@@ -1105,11 +1122,252 @@ exit:
 
 
 /***********************************************************************/
+/*                     REAL Header Check API                            */
+/***********************************************************************/
+EXPORT_API
+int MMFileFormatIsValidREAL (MMFileIOHandle *pFileIO, const char *mmfileuri)
+{
+#define _MMFILE_RMVB_HEADER_LENGTH 4   /*RMF*/
+
+       MMFileIOHandle *fp = pFileIO;
+       unsigned char buffer[_MMFILE_RMVB_HEADER_LENGTH] = {0,};
+       int               readed = 0;
+       int ret = 0;
+
+       if(fp == NULL) {
+               ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
+               if (ret == MMFILE_IO_FAILED) {
+                       debug_error ("error: mmfile_open\n");
+                       goto exit;
+               }
+       }
+
+       mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
+
+       readed = mmfile_read (fp, buffer, _MMFILE_RMVB_HEADER_LENGTH);
+
+       if (_MMFILE_RMVB_HEADER_LENGTH != readed) {
+               debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
+               ret = 0;
+               goto exit;
+       }
+
+       if (1 == _MMFileIsREALHeader (buffer)) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg ( "Header Detected\n");
+#endif
+               ret = 1;
+               goto exit;
+       }
+
+exit:
+       if(pFileIO == NULL && fp != NULL)
+               mmfile_close(fp);
+
+       return ret;
+}
+
+/***********************************************************************/
+/*                     MPEGTS Header Check API                            */
+/***********************************************************************/
+#define MPEGTS_NONE            0x00
+#define MPEGTS_FECE            0x10
+#define MPEGTS_DVHS    0x20
+#define MPEGTS_PACKET  0x40
+
+#define TS_PACKET_SIZE         188
+#define TS_DVHS_PACKET_SIZE    192
+#define TS_FEC_PACKET_SIZE     204
+#define TS_MAX_PACKET_SIZE     204
+
+EXPORT_API
+int MMFileFormatIsValidMPEGTS (MMFileIOHandle *pFileIO, const char *mmfileuri)
+{
+       MMFileIOHandle *fp = pFileIO;
+       unsigned char buffer[TS_MAX_PACKET_SIZE] = {0,};
+       int               readed = 0;
+       int ret = 0;
+
+       if(fp == NULL) {
+               ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
+               if (ret == MMFILE_IO_FAILED) {
+                       debug_error ("error: mmfile_open\n");
+                       goto exit;
+               }
+       }
+
+       mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
+
+       readed = mmfile_read (fp, buffer, TS_MAX_PACKET_SIZE);
+
+       if (TS_MAX_PACKET_SIZE != readed) {
+               debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
+               ret = 0;
+               goto exit;
+       }
+
+       if (_MMFileIsMPEGTSHeader(fp) != MPEGTS_NONE) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg ( "Header Detected\n");
+#endif
+               ret = 1;
+               goto exit;
+       }
+
+exit:
+       if(pFileIO == NULL && fp != NULL)
+               mmfile_close(fp);
+
+       return ret;
+}
+
+/***********************************************************************/
+/*                     MPEG-PS Header Check API                            */
+/***********************************************************************/
+EXPORT_API
+int MMFileFormatIsValidMPEGPS (MMFileIOHandle *pFileIO, const char *mmfileuri)
+{
+#define _MMFILE_MPEGPS_HEADER_LENGTH 4
+
+       MMFileIOHandle *fp = pFileIO;
+       unsigned char buffer[_MMFILE_MPEGPS_HEADER_LENGTH] = {0,};
+       int               readed = 0;
+       int ret = 0;
+
+       if(fp == NULL) {
+               ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
+               if (ret == MMFILE_IO_FAILED) {
+                       debug_error ("error: mmfile_open\n");
+                       goto exit;
+               }
+       }
+
+       mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
+
+       readed = mmfile_read (fp, buffer, _MMFILE_MPEGPS_HEADER_LENGTH);
+
+       if (_MMFILE_MPEGPS_HEADER_LENGTH != readed) {
+               debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
+               ret = 0;
+               goto exit;
+       }
+
+       if (1 == _MMFileIsMPEGPSHeader (buffer)) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg ( "Header Detected\n");
+#endif
+               ret = 1;
+               goto exit;
+       }
+
+exit:
+       if(pFileIO == NULL && fp != NULL)
+               mmfile_close(fp);
+
+       return ret;
+}
+
+/***********************************************************************/
+/*                     MPEG AUDIO Header Check API                            */
+/***********************************************************************/
+EXPORT_API
+int MMFileFormatIsValidMPEGAUDIO (MMFileIOHandle *pFileIO, const char *mmfileuri)
+{
+#define _MMFILE_MPEGAUDIO_HEADER_LENGTH 4
+
+       MMFileIOHandle *fp = pFileIO;
+       unsigned char buffer[_MMFILE_MPEGAUDIO_HEADER_LENGTH] = {0,};
+       int               readed = 0;
+       int ret = 0;
+
+       if(fp == NULL) {
+               ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
+               if (ret == MMFILE_IO_FAILED) {
+                       debug_error ("error: mmfile_open\n");
+                       goto exit;
+               }
+       }
+
+       mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
+
+       readed = mmfile_read (fp, buffer, _MMFILE_MPEGAUDIO_HEADER_LENGTH);
+
+       if (_MMFILE_MPEGAUDIO_HEADER_LENGTH != readed) {
+               debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
+               ret = 0;
+               goto exit;
+       }
+
+       if (1 == _MMFileIsMPEGAUDIOHeader (buffer)) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg ( "Header Detected\n");
+#endif
+               ret = 1;
+               goto exit;
+       }
+
+exit:
+       if(pFileIO == NULL && fp != NULL)
+               mmfile_close(fp);
+
+       return ret;
+}
+
+/***********************************************************************/
+/*                     MPEG VIDEO Header Check API                            */
+/***********************************************************************/
+EXPORT_API
+int MMFileFormatIsValidMPEGVIDEO (MMFileIOHandle *pFileIO, const char *mmfileuri)
+{
+#define _MMFILE_MPEGVIDEO_HEADER_LENGTH 4
+
+       MMFileIOHandle *fp = pFileIO;
+       unsigned char buffer[_MMFILE_MPEGVIDEO_HEADER_LENGTH] = {0,};
+       int               readed = 0;
+       int ret = 0;
+
+       if(fp == NULL) {
+               ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
+               if (ret == MMFILE_IO_FAILED) {
+                       debug_error ("error: mmfile_open\n");
+                       goto exit;
+               }
+       }
+
+       mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
+
+       readed = mmfile_read (fp, buffer, _MMFILE_MPEGVIDEO_HEADER_LENGTH);
+
+       if (_MMFILE_MPEGVIDEO_HEADER_LENGTH != readed) {
+               debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
+               ret = 0;
+               goto exit;
+       }
+
+       if (1 == _MMFileIsMPEGVIDEOHeader (buffer)) {
+#ifdef __MMFILE_TEST_MODE__
+               debug_msg ( "Header Detected\n");
+#endif
+               ret = 1;
+               goto exit;
+       }
+
+exit:
+       if(pFileIO == NULL && fp != NULL)
+               mmfile_close(fp);
+
+       return ret;
+}
+
+
+
+
+/***********************************************************************/
 /*            Implementation of Internal Functions                     */
 /***********************************************************************/
 static int _MMFileIsASFHeader  (void *header)
 {
-       /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */
+       /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */    
        unsigned char *s = header;
 
        if ( (*(s +  0) == 0x30) &&
@@ -1266,6 +1524,100 @@ static int _MMFileIsOGGHeader (void *header)
        return 0;
 }
 
+static int _MMFileIsREALHeader (void *header)
+{
+       unsigned char *s = header;
+
+               if (!memcmp (s, ".RMF", 4)) {
+                       return 1;
+               }
+
+       return 0;
+}
+
+static int _MMFileIsMPEGTSHeader (MMFileIOHandle *fp)
+{
+       unsigned char header[TS_MAX_PACKET_SIZE] = {0,};
+       unsigned char *s = NULL;
+
+       mmfile_seek(fp, 0, MMFILE_SEEK_SET);
+       mmfile_read(fp, header, sizeof(header));
+
+       s = (unsigned char *)memchr(header, 0x47, sizeof(header));
+
+       if(s) {
+               unsigned char buffer[TS_PACKET_SIZE] = {0,};
+               unsigned int  startoffset = s - header + 1;
+
+               mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
+               mmfile_read(fp, buffer, sizeof(buffer));
+
+               if(buffer[sizeof(buffer)-1] & 0x47) {
+                       return MPEGTS_PACKET;
+               } else {
+                       unsigned char buffer[TS_DVHS_PACKET_SIZE] = {0,};
+
+                       mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
+                       mmfile_read (fp, buffer, sizeof(buffer));
+
+                       if(buffer[sizeof(buffer)-1] & 0x47) {
+                               return MPEGTS_DVHS;
+                       } else {
+                               unsigned char buffer[TS_FEC_PACKET_SIZE] = {0,};
+
+                               mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
+                               mmfile_read(fp, buffer, sizeof(buffer));
+
+                               if(buffer[sizeof(buffer)-1] & 0x47) {
+                                       return MPEGTS_FECE;
+                               }
+                       }
+               }
+       }
+
+       return MPEGTS_NONE;
+}
+
+static int _MMFileIsMPEGPSHeader (void *header)
+{
+       unsigned char *s = header;
+
+       if ((*(s +  0) == 0x00) &&
+               (*(s +  1) == 0x00) &&
+               (*(s +  2) == 0x01) &&
+               (*(s +  3) == 0xba)) {  // mpeg-ps header
+               return 1;
+       }
+
+       return 0;
+}
+
+static int _MMFileIsMPEGAUDIOHeader (void *header)
+{
+       unsigned char *s = header;
+
+       if ((*(s + 0) & 0xFF) && 
+               (*(s + 1) & 0xFE)){     // mpeg audio layer 1 header
+               return 1;
+       }
+
+       return 0;
+}
+
+static int _MMFileIsMPEGVIDEOHeader (void *header)
+{
+       unsigned char *s = header;
+
+       if ((*(s +  0) == 0x00) &&
+               (*(s +  1) == 0x00) &&
+               (*(s +  2) == 0x01) &&
+               (*(s +  3) == 0xb3)) {  // mpeg1 video header
+               return 1;
+       }
+
+       return 0;
+}
+
 static int _MMFileIsMP3Header (void *header)
 {
        unsigned long head = 0;
@@ -1365,6 +1717,7 @@ static int _MMFileSearchID3Tag (MMFileIOHandle *fp, unsigned int *offset)
        int tagVersion = 0;
        int encSize = 0;
        int readed = 0;
+       int ret = 0;
 
        /*init offset*/
        *offset = 0;
@@ -1423,10 +1776,13 @@ _START_TAG_SEARCH:
 
        mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
        *offset = acc_tagsize;
+
+       ret = 1;
+
        goto _START_TAG_SEARCH;
 
 search_end:
-       return 1;
+       return ret;
 }
 
 static int _MMFileIsFLACHeader  (void *header)