4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Haejeong Kim <backto.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 #include <unistd.h> /*for access*/
25 #include <string.h> /*for strXXX*/
28 /* exported MM header files */
33 /* internal MM header files */
34 #include <mm_attrs_private.h>
37 /* internal MM File headers */
38 #include "mm_file_formats.h"
39 #include "mm_file_format_frame.h"
40 #include "mm_file_codecs.h"
41 #include "mm_file_utils.h"
52 gettimeofday(&tv,NULL);
53 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
63 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
66 #define _SEEK_POINT_ 3000 /*1000 = 1 seconds*/
68 #define MM_FILE_TAG_SYNCLYRICS "tag-synclyrics" /**< Synchronized Lyrics Information*/
78 MM_FILE_PARSE_TYPE_SIMPLE, /*parse audio/video track num only*/
79 MM_FILE_PARSE_TYPE_NORMAL, /*parse infomation without thumbnail*/
80 MM_FILE_PARSE_TYPE_ALL, /*parse all infomation*/
90 void *formatFuncHandle;
91 void *codecFuncHandle;
99 static mmf_attrs_construct_info_t g_tag_attrs[] = {
100 {"tag-artist", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
101 {"tag-title", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
102 {"tag-album", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
103 {"tag-album-artist", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
104 {"tag-genre", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
105 {"tag-author", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
106 {"tag-copyright", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
107 {"tag-date", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
108 {"tag-description", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
109 {"tag-comment", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
110 {"tag-artwork", MMF_VALUE_TYPE_DATA, MM_ATTRS_FLAG_RW, (void *)NULL},
111 {"tag-artwork-size", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
112 {"tag-artwork-mime", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
113 {"tag-track-num", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
114 {"tag-classification", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
115 {"tag-rating", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
116 {"tag-longitude", MM_ATTRS_TYPE_DOUBLE, MM_ATTRS_FLAG_RW, (void *)0},
117 {"tag-latitude", MM_ATTRS_TYPE_DOUBLE, MM_ATTRS_FLAG_RW, (void *)0},
118 {"tag-altitude", MM_ATTRS_TYPE_DOUBLE, MM_ATTRS_FLAG_RW, (void *)0},
119 {"tag-conductor", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
120 {"tag-unsynclyrics", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
121 {"tag-synclyrics-num", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
122 {"tag-synclyrics", MMF_VALUE_TYPE_DATA, MM_ATTRS_FLAG_RW, (void *)NULL},
123 {"tag-recdate", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
124 {"tag-rotate", MMF_VALUE_TYPE_STRING, MM_ATTRS_FLAG_RW, (void *)NULL},
127 static mmf_attrs_construct_info_t g_content_attrs[] = {
128 {"content-duration", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
129 {"content-video-codec", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
130 {"content-video-bitrate", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
131 {"content-video-fps", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
132 {"content-video-width", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
133 {"content-video-height", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
134 {"content-video-thumbnail", MMF_VALUE_TYPE_DATA, MM_ATTRS_FLAG_RW, (void *)NULL},
135 {"content-video-track-index", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
136 {"content-video-track-count", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
137 {"content-audio-codec", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
138 {"content-audio-bitrate", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
139 {"content-audio-channels", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
140 {"content-audio-samplerate", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
141 {"content-audio-track-index", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
142 {"content-audio-track-count", MMF_VALUE_TYPE_INT, MM_ATTRS_FLAG_RW, (void *)0},
145 #ifdef __MMFILE_DYN_LOADING__
146 #define MMFILE_FORMAT_SO_FILE_NAME "libmmfile_formats.so"
147 #define MMFILE_CODEC_SO_FILE_NAME "libmmfile_codecs.so"
149 int (*mmfile_format_open) (MMFileFormatContext **formatContext, MMFileSourceType *fileSrc);
150 int (*mmfile_format_read_stream) (MMFileFormatContext *formatContext);
151 int (*mmfile_format_read_frame) (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
152 int (*mmfile_format_read_tag) (MMFileFormatContext *formatContext);
153 int (*mmfile_format_close) (MMFileFormatContext *formatContext);
154 int (*mmfile_codec_open) (MMFileCodecContext **codecContext, int codecType, int codecId, MMFileCodecFrame *input);
155 int (*mmfile_codec_decode) (MMFileCodecContext *codecContext, MMFileCodecFrame *output);
156 int (*mmfile_codec_close) (MMFileCodecContext *codecContext);
157 int (*mmfile_format_get_frame) (const char* path, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height);
158 int (*mmfile_format_get_frame_from_memory) (const void *data, unsigned int datasize, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height);
161 #ifdef __MMFILE_DYN_LOADING__
162 static int _load_dynamic_functions (MMFILE_FUNC_HANDLE* pHandle)
164 // static int dll_func_initialized = 0; //disabled
168 /* Get from function argument */
169 void *formatFuncHandle = NULL;
170 void *codecFuncHandle = NULL;
173 if (dll_func_initialized) {
178 formatFuncHandle = dlopen (MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
179 if (!formatFuncHandle) {
180 debug_error ("error: %s\n", dlerror());
185 mmfile_format_open = dlsym (formatFuncHandle, "mmfile_format_open");
186 mmfile_format_read_stream = dlsym (formatFuncHandle, "mmfile_format_read_stream");
187 mmfile_format_read_frame = dlsym (formatFuncHandle, "mmfile_format_read_frame");
188 mmfile_format_read_tag = dlsym (formatFuncHandle, "mmfile_format_read_tag");
189 mmfile_format_close = dlsym (formatFuncHandle, "mmfile_format_close");
191 if ( !mmfile_format_open ||
192 !mmfile_format_read_stream ||
193 !mmfile_format_read_frame ||
194 !mmfile_format_read_tag ||
195 !mmfile_format_close) {
197 debug_error ("error: %s\n", dlerror());
202 /*closed at app termination.*/
203 //dlclose (formatFuncHandle);
205 codecFuncHandle = dlopen (MMFILE_CODEC_SO_FILE_NAME, RTLD_LAZY | RTLD_GLOBAL);
206 if (!codecFuncHandle) {
207 debug_error ("error: %s\n", dlerror());
212 mmfile_codec_open = dlsym (codecFuncHandle, "mmfile_codec_open");
213 mmfile_codec_decode = dlsym (codecFuncHandle, "mmfile_codec_decode");
214 mmfile_codec_close = dlsym (codecFuncHandle, "mmfile_codec_close");
216 if ( !mmfile_codec_open || !mmfile_codec_decode || !mmfile_codec_close) {
217 debug_error ("error: %s\n", dlerror());
222 /*closed at app termination.*/
223 //dlclose (codecFuncHandle);
225 // dll_func_initialized = 1; // disabled
227 pHandle->codecFuncHandle = codecFuncHandle;
228 pHandle->formatFuncHandle = formatFuncHandle;
233 if (formatFuncHandle) dlclose (formatFuncHandle);
234 if (codecFuncHandle) dlclose (codecFuncHandle);
239 static void _unload_dynamic_functions (MMFILE_FUNC_HANDLE* pHandle)
243 if (pHandle->formatFuncHandle)
245 dlclose (pHandle->formatFuncHandle);
247 if (pHandle->codecFuncHandle)
249 dlclose (pHandle->codecFuncHandle);
256 #endif /* __MMFILE_DYN_LOADING__ */
262 _is_file_exist (const char *filename)
266 const char* to_access = (strstr(filename,"file://")!=NULL)? filename+7:filename;
267 ret = access (to_access, R_OK );
269 debug_error ("file [%s] not found.\n", to_access);
276 _info_set_attr_media (mmf_attrs_t *attrs, MMFileFormatContext *formatContext)
279 MMHandleType hattrs = CAST_MM_HANDLE(attrs);
281 if (formatContext->commandType == MM_FILE_TAG)
283 if (formatContext->title) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_TITLE, formatContext->title);
284 if (formatContext->artist) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ARTIST, formatContext->artist);
285 if (formatContext->author) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_AUTHOR, formatContext->author);
286 if (formatContext->composer && formatContext->author == NULL)
287 mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_AUTHOR, formatContext->composer);
288 if (formatContext->album) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ALBUM, formatContext->album);
289 if (formatContext->album_artist) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ALBUM_ARTIST, formatContext->album_artist);
290 if (formatContext->copyright) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_COPYRIGHT, formatContext->copyright);
291 if (formatContext->description) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_DESCRIPTION, formatContext->description);
292 if (formatContext->comment) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_COMMENT, formatContext->comment);
293 if (formatContext->genre) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_GENRE, formatContext->genre);
294 if (formatContext->classification) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_CLASSIFICATION, formatContext->classification);
295 if (formatContext->year) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_DATE, formatContext->year);
296 if (formatContext->tagTrackNum) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_TRACK_NUM, formatContext->tagTrackNum);
297 if (formatContext->rating) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_RATING, formatContext->rating);
298 if (formatContext->conductor) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_CONDUCTOR, formatContext->conductor);
299 if (formatContext->recDate) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_RECDATE, formatContext->recDate);
300 if (formatContext->rotate) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ROTATE, formatContext->rotate);
301 mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_LONGITUDE, formatContext->longitude);
302 mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_LATIDUE, formatContext->latitude);
303 mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_ALTIDUE, formatContext->altitude);
304 mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_SYNCLYRICS_NUM, formatContext->syncLyricsNum);
306 if ((formatContext->syncLyricsNum > 0) && (formatContext->syncLyrics))
307 mm_attrs_set_data_by_name (hattrs, MM_FILE_TAG_SYNCLYRICS, formatContext->syncLyrics, formatContext->syncLyricsNum);
309 if (formatContext->unsyncLyrics) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_UNSYNCLYRICS, formatContext->unsyncLyrics);
311 if (formatContext->artwork && formatContext->artworkSize > 0) {
312 void *artworkCopy = NULL;
313 artworkCopy = mmfile_malloc ((formatContext->artworkSize));
314 if ( NULL != artworkCopy ) {
315 memcpy (artworkCopy, formatContext->artwork, formatContext->artworkSize);
316 mm_attrs_set_data_by_name (hattrs, MM_FILE_TAG_ARTWORK,artworkCopy, formatContext->artworkSize);
317 mm_attrs_set_int_by_name (hattrs, MM_FILE_TAG_ARTWORK_SIZE, formatContext->artworkSize);
318 if (formatContext->artworkMime) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ARTWORK_MIME, formatContext->artworkMime);
322 else if (formatContext->commandType == MM_FILE_CONTENTS)
325 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_DURATION, formatContext->duration);
326 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_TRACK_COUNT, formatContext->audioTotalTrackNum);
327 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, formatContext->videoTotalTrackNum);
329 if (formatContext->videoTotalTrackNum > 0 &&
330 formatContext->nbStreams > 0 &&
331 formatContext->streams[MMFILE_VIDEO_STREAM]) {
333 MMFileFormatStream *videoStream = formatContext->streams[MMFILE_VIDEO_STREAM];
335 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_CODEC, videoStream->codecId);
336 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_BITRATE, videoStream->bitRate);
337 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_FPS, videoStream->framePerSec);
338 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_WIDTH, videoStream->width);
339 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_HEIGHT, videoStream->height);
341 if (formatContext->thumbNail && formatContext->thumbNail->frameData) {
342 void *thumbNailCopy = NULL;
343 thumbNailCopy = mmfile_malloc (formatContext->thumbNail->frameSize);
345 if (NULL != thumbNailCopy) {
346 memcpy (thumbNailCopy, formatContext->thumbNail->frameData, formatContext->thumbNail->frameSize);
347 mm_attrs_set_data_by_name (hattrs, MM_FILE_CONTENT_VIDEO_THUMBNAIL, thumbNailCopy, formatContext->thumbNail->frameSize);
348 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_WIDTH, formatContext->thumbNail->frameWidth);
349 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_HEIGHT, formatContext->thumbNail->frameHeight);
354 if (formatContext->audioTotalTrackNum > 0 &&
355 formatContext->nbStreams > 0 &&
356 formatContext->streams[MMFILE_AUDIO_STREAM]) {
358 MMFileFormatStream *audioStream = formatContext->streams[MMFILE_AUDIO_STREAM];
360 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_CODEC, audioStream->codecId);
361 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_CHANNELS, audioStream->nbChannel);
362 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_BITRATE, audioStream->bitRate);
363 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_SAMPLERATE, audioStream->samplePerSec);
372 ret = mmf_attrs_commit ((MMHandleType)hattrs);
378 _get_contents_info (mmf_attrs_t *attrs, MMFileSourceType *src, MMFILE_PARSE_INFO *parse)
380 MMFileFormatContext *formatContext = NULL;
381 MMFileCodecContext *codecContext = NULL;
382 MMFileFormatFrame frameContext = {0,};
383 MMFileCodecFrame codecFrame = {0,};
384 MMFileCodecFrame decodedFrame = {0,};
389 return MM_ERROR_FILE_INTERNAL;
391 ret = mmfile_format_open (&formatContext, src);
392 if (MMFILE_FORMAT_FAIL == ret || formatContext == NULL) {
393 debug_error ("error: mmfile_format_open\n");
394 ret = MM_ERROR_FILE_INTERNAL;
399 * if MM_FILE_PARSE_TYPE_SIMPLE, just get number of each stream.
401 parse->audio_track_num = formatContext->audioTotalTrackNum;
402 parse->video_track_num = formatContext->videoTotalTrackNum;
404 if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL) {
405 ret = mmfile_format_read_stream (formatContext);
406 if (MMFILE_FORMAT_FAIL == ret) {
407 debug_error ("error: mmfile_format_read_stream\n");
408 ret = MM_ERROR_FILE_INTERNAL;
412 if (parse->type >= MM_FILE_PARSE_TYPE_ALL) {
413 if (formatContext->videoTotalTrackNum > 0) {
414 MMFileFormatStream *videoStream = formatContext->streams[MMFILE_VIDEO_STREAM];
415 unsigned int timestamp = _SEEK_POINT_;
417 ret = mmfile_format_read_frame (formatContext, timestamp, &frameContext);
418 if (MMFILE_FORMAT_FAIL == ret) {
419 debug_error ("error: mmfile_format_read_frame\n");
420 ret = MM_ERROR_FILE_INTERNAL;
424 if (frameContext.bCompressed) {
425 codecFrame.frameDataSize = frameContext.frameSize;
426 codecFrame.width = frameContext.frameWidth;
427 codecFrame.height = frameContext.frameHeight;
428 codecFrame.frameData = frameContext.frameData;
429 codecFrame.configLen = frameContext.configLenth;
430 codecFrame.configData = frameContext.configData;
431 codecFrame.version = videoStream->version;
433 ret = mmfile_codec_open (&codecContext, MMFILE_VIDEO_DECODE, videoStream->codecId, &codecFrame);
434 if (MMFILE_FORMAT_FAIL == ret) {
435 debug_error ("error: mmfile_codec_open\n");
436 ret = MM_ERROR_FILE_INTERNAL;
440 ret = mmfile_codec_decode (codecContext, &decodedFrame);
441 if (MMFILE_FORMAT_FAIL == ret) {
442 debug_error ("error: mmfile_codec_decode\n");
443 ret = MM_ERROR_FILE_INTERNAL;
447 /* set video thumbnail */
448 formatContext->thumbNail = mmfile_malloc (sizeof(MMFileFormatFrame));
449 if (NULL == formatContext->thumbNail) {
450 debug_error ("error: mmfile_malloc\n");
451 ret = MM_ERROR_FILE_INTERNAL;
455 formatContext->thumbNail->frameSize = decodedFrame.frameDataSize;
456 formatContext->thumbNail->frameWidth = decodedFrame.width;
457 formatContext->thumbNail->frameHeight = decodedFrame.height;
458 formatContext->thumbNail->frameData = decodedFrame.frameData;
459 formatContext->thumbNail->configLenth = 0;
460 formatContext->thumbNail->configData = NULL;
462 formatContext->thumbNail = mmfile_malloc (sizeof(MMFileFormatFrame));
463 if (NULL == formatContext->thumbNail) {
464 debug_error ("error: mmfile_format_read_frame\n");
465 ret = MM_ERROR_FILE_INTERNAL;
469 formatContext->thumbNail->frameSize = frameContext.frameSize;
470 formatContext->thumbNail->frameWidth = frameContext.frameWidth;
471 formatContext->thumbNail->frameHeight = frameContext.frameHeight;
472 formatContext->thumbNail->frameData = frameContext.frameData;
473 formatContext->thumbNail->configLenth = 0;
474 formatContext->thumbNail->configData = NULL;
480 #ifdef __MMFILE_TEST_MODE__
481 mmfile_format_print_frame (&frameContext);
484 formatContext->commandType = MM_FILE_CONTENTS;
486 if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL)
487 _info_set_attr_media (attrs, formatContext);
489 if (frameContext.bCompressed) {
490 if (frameContext.frameData) mmfile_free (frameContext.frameData);
491 if (frameContext.configData) mmfile_free (frameContext.configData);
493 if (decodedFrame.frameData) {
494 mmfile_free (decodedFrame.frameData);
495 formatContext->thumbNail->frameData = NULL;
497 if (decodedFrame.configData) {
498 mmfile_free (decodedFrame.configData);
499 formatContext->thumbNail->configData = NULL;
502 if (frameContext.frameData) {
503 mmfile_free (frameContext.frameData);
504 formatContext->thumbNail->frameData = NULL;
506 if (frameContext.configData) {
507 mmfile_free (frameContext.configData);
508 formatContext->thumbNail->configData = NULL;
512 if (formatContext) { mmfile_format_close (formatContext); }
513 if (codecContext) { mmfile_codec_close (codecContext); }
515 return MM_ERROR_NONE;
518 formatContext->commandType = MM_FILE_CONTENTS;
520 if (frameContext.bCompressed) {
521 if (frameContext.frameData)
522 mmfile_free (frameContext.frameData);
524 if (frameContext.configData)
525 mmfile_free (frameContext.configData);
527 if (decodedFrame.frameData) {
528 mmfile_free (decodedFrame.frameData);
529 formatContext->thumbNail->frameData = NULL;
532 if (decodedFrame.configData) {
533 mmfile_free (decodedFrame.configData);
534 formatContext->thumbNail->configData = NULL;
537 if (frameContext.frameData) {
538 mmfile_free (frameContext.frameData);
539 formatContext->thumbNail->frameData = NULL;
542 if (frameContext.configData) {
543 mmfile_free (frameContext.configData);
544 formatContext->thumbNail->configData = NULL;
548 if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL)
549 _info_set_attr_media (attrs, formatContext);
551 if (formatContext) { mmfile_format_close (formatContext); }
552 if (codecContext) { mmfile_codec_close (codecContext); }
553 return MM_ERROR_NONE;
557 if (frameContext.bCompressed) {
558 if (frameContext.frameData)
559 mmfile_free (frameContext.frameData);
561 if (frameContext.configData)
562 mmfile_free (frameContext.configData);
564 if (decodedFrame.frameData) {
565 mmfile_free (decodedFrame.frameData);
566 formatContext->thumbNail->frameData = NULL;
569 if (decodedFrame.configData) {
570 mmfile_free (decodedFrame.configData);
571 formatContext->thumbNail->configData = NULL;
574 if (frameContext.frameData) {
575 mmfile_free (frameContext.frameData);
576 formatContext->thumbNail->frameData = NULL;
579 if (frameContext.configData) {
580 mmfile_free (frameContext.configData);
581 formatContext->thumbNail->configData = NULL;
585 if (formatContext) { mmfile_format_close (formatContext); }
586 // if (codecContext) { mmfile_codec_close (codecContext); } /*dead code*/
593 _get_tag_info (mmf_attrs_t *attrs, MMFileSourceType *src)
595 MMFileFormatContext *formatContext = NULL;
598 ret = mmfile_format_open (&formatContext, src);
599 if (MMFILE_FORMAT_FAIL == ret || formatContext == NULL) {
600 debug_error ("error: mmfile_format_open\n");
601 ret = MM_ERROR_FILE_INTERNAL;
605 ret = mmfile_format_read_tag (formatContext);
606 if (MMFILE_FORMAT_FAIL == ret) {
607 debug_warning ("reading tag is fail\n");
608 ret = MM_ERROR_FILE_INTERNAL;
612 formatContext->commandType = MM_FILE_TAG;
614 _info_set_attr_media (attrs, formatContext);
616 if (formatContext) { mmfile_format_close (formatContext); }
618 return MM_ERROR_NONE;
622 if (formatContext) { mmfile_format_close (formatContext); }
624 return MM_ERROR_FILE_INTERNAL;
631 int mm_file_get_attrs(MMHandleType attrs, char **err_attr_name, const char *first_attribute_name, ...)
633 int ret = MM_ERROR_NONE;
638 debug_error ("Invalid arguments [attrs 0]\n");
639 return MM_ERROR_INVALID_ARGUMENT;
642 if ( first_attribute_name == NULL)
644 debug_error ("Invalid arguments [first_attribute_name null]\n");
645 return MM_ERROR_INVALID_ARGUMENT;
648 /* get requested attributes */
649 va_start (var_args, first_attribute_name);
650 ret = mm_attrs_get_valist(attrs, err_attr_name, first_attribute_name, var_args);
653 if (ret != MM_ERROR_NONE)
657 debug_error ("failed to get %s\n", *err_attr_name);
664 int mm_file_get_synclyrics_info(MMHandleType tag_attrs, int index, unsigned long *time_info, char **lyrics)
666 int ret = MM_ERROR_NONE;
667 AvSynclyricsInfo* sync_lyric_item = NULL;
668 GList *synclyrics_list = NULL;
672 if ( (mmf_attrs_t*)tag_attrs == NULL) {
673 debug_error ("invalid handle");
674 return MM_ERROR_INVALID_ARGUMENT;
677 ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_SYNCLYRICS, (void **)&synclyrics_list);
678 if(ret != MM_ERROR_NONE) {
679 #ifdef __MMFILE_TEST_MODE__
680 debug_warning ( "get data fail");
685 if(synclyrics_list != NULL) {
687 sync_lyric_item = (AvSynclyricsInfo*)g_list_nth_data(synclyrics_list, index);
689 if(sync_lyric_item == NULL) {
690 #ifdef __MMFILE_TEST_MODE__
691 debug_warning ( "synclyric item is NULL");
693 return MM_ERROR_COMMON_ATTR_NOT_EXIST;
696 *time_info = sync_lyric_item->time_info;
697 *lyrics = sync_lyric_item->lyric_info;
700 #ifdef __MMFILE_TEST_MODE__
701 debug_warning ( "synclyrics_list is NULL");
703 return MM_ERROR_COMMON_ATTR_NOT_EXIST;
710 int mm_file_create_tag_attrs(MMHandleType *tag_attrs, const char *filename)
712 int ret = MM_ERROR_NONE;
713 mmf_attrs_t *attrs = NULL;
714 MMFileSourceType src;
718 /* Check argument here */
719 if (tag_attrs == NULL) {
720 debug_error ("Invalid arguments [tag null]\n");
721 return MM_ERROR_INVALID_ARGUMENT;
723 if (filename == NULL) {
724 debug_error ("Invalid arguments [filename null]\n");
725 return MM_ERROR_INVALID_ARGUMENT;
727 if ( strlen (filename) == 0) {
728 debug_error ("Invalid arguments [filename size 0]\n");
729 return MM_ERROR_INVALID_ARGUMENT;
733 #ifdef __MMFILE_DYN_LOADING__
734 MMFILE_FUNC_HANDLE func_handle;
736 ret = _load_dynamic_functions (&func_handle);
738 debug_error ("load library error\n");
739 return MM_ERROR_FILE_INTERNAL;
743 /*set source file infomation*/
744 MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
746 ret = _is_file_exist (filename);
748 return MM_ERROR_FILE_NOT_FOUND;
751 attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("tag", g_tag_attrs, ARRAY_SIZE (g_tag_attrs), NULL, NULL);
753 debug_error ("attribute internal error.\n");
754 return MM_ERROR_FILE_INTERNAL;
757 ret = _get_tag_info (attrs, &src);
759 #ifdef __MMFILE_TEST_MODE__
760 if (ret != MM_ERROR_NONE) {
761 debug_error ("failed to get tag: %s\n", filename);
765 *tag_attrs = (MMHandleType)attrs;
767 #ifdef __MMFILE_DYN_LOADING__
768 _unload_dynamic_functions (&func_handle);
778 int mm_file_destroy_tag_attrs(MMHandleType tag_attrs)
780 void *artwork = NULL;
781 GList *synclyrics_list = NULL;
782 int ret = MM_ERROR_NONE;
785 if ( (mmf_attrs_t*)tag_attrs == NULL) {
786 debug_error ("invalid handle.\n");
787 return MM_ERROR_INVALID_ARGUMENT;
790 ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_ARTWORK, &artwork);
792 if (artwork != NULL) {
793 mmfile_free (artwork);
796 ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_SYNCLYRICS, (void **)&synclyrics_list);
798 if(synclyrics_list != NULL) {
799 mm_file_free_synclyrics_list(synclyrics_list);
802 mmf_attrs_free (tag_attrs);
810 int mm_file_create_content_attrs (MMHandleType *contents_attrs, const char *filename)
812 mmf_attrs_t *attrs = NULL;
813 MMFileSourceType src = {0,};
814 MMFILE_PARSE_INFO parse = {0,};
819 /* Check argument here */
820 if (contents_attrs == NULL) {
821 debug_error ("Invalid arguments [contents null]\n");
822 return MM_ERROR_INVALID_ARGUMENT;
824 if (filename == NULL) {
825 debug_error ("Invalid arguments [filename null]\n");
826 return MM_ERROR_INVALID_ARGUMENT;
828 if ( strlen (filename) == 0) {
829 debug_error ("Invalid arguments [filename size 0]\n");
830 return MM_ERROR_INVALID_ARGUMENT;
834 #ifdef __MMFILE_DYN_LOADING__
835 MMFILE_FUNC_HANDLE func_handle;
842 ret = _load_dynamic_functions (&func_handle);
844 debug_error ("load library error\n");
845 return MM_ERROR_FILE_INTERNAL;
849 printf ("%s, %d, _load_dynamic_functions() = %lld\n", __func__, __LINE__, gettime() - ti);
854 /*set source file infomation*/
855 MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
857 ret = _is_file_exist (filename);
859 return MM_ERROR_FILE_NOT_FOUND;
862 attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
864 debug_error ("attribute internal error.\n");
865 return MM_ERROR_FILE_INTERNAL;
869 parse.type = MM_FILE_PARSE_TYPE_ALL;
870 ret = _get_contents_info (attrs, &src, &parse);
871 if (ret != MM_ERROR_NONE) {
872 debug_error ("failed to get contents: %s\n", filename);
875 *contents_attrs = (MMHandleType) attrs;
878 #ifdef __MMFILE_DYN_LOADING__
884 _unload_dynamic_functions (&func_handle);
887 printf ("%s, %d, _unload_dynamic_functions() = %lld\n", __func__, __LINE__, gettime() - ti);
900 int mm_file_create_tag_attrs_from_memory (MMHandleType *tag_attrs, const void *data, unsigned int size, int format)
902 mmf_attrs_t *attrs = NULL;
903 MMFileSourceType src;
904 MMFILE_PARSE_INFO parse = {0,};
909 /* Check argument here */
910 if (tag_attrs == NULL || data == NULL) {
911 debug_error ("Invalid arguments\n");
912 return MM_ERROR_INVALID_ARGUMENT;
915 #ifdef __MMFILE_DYN_LOADING__
916 MMFILE_FUNC_HANDLE func_handle;
918 ret = _load_dynamic_functions (&func_handle);
920 debug_error ("load library error\n");
921 return MM_ERROR_FILE_INTERNAL;
925 MM_FILE_SET_MEDIA_MEM_SRC (src, data, size, format);
928 attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("tag", g_tag_attrs, ARRAY_SIZE (g_tag_attrs), NULL, NULL);
930 debug_error ("attribute internal error.\n");
931 return MM_ERROR_FILE_INTERNAL;
934 parse.type = MM_FILE_PARSE_TYPE_ALL;
935 ret = _get_tag_info (attrs, &src);
937 *tag_attrs = (MMHandleType)attrs;
939 #ifdef __MMFILE_DYN_LOADING__
940 _unload_dynamic_functions (&func_handle);
950 int mm_file_create_content_attrs_from_memory (MMHandleType *contents_attrs, const void *data, unsigned int size, int format)
952 mmf_attrs_t *attrs = NULL;
953 MMFileSourceType src;
954 MMFILE_PARSE_INFO parse = {0,};
959 /* Check argument here */
960 if (contents_attrs == NULL || data == NULL) {
961 debug_error ("Invalid arguments\n");
962 return MM_ERROR_INVALID_ARGUMENT;
965 #ifdef __MMFILE_DYN_LOADING__
966 MMFILE_FUNC_HANDLE func_handle;
968 ret = _load_dynamic_functions (&func_handle);
970 debug_error ("load library error\n");
971 return MM_ERROR_FILE_INTERNAL;
975 MM_FILE_SET_MEDIA_MEM_SRC (src, data, size, format);
978 attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
980 debug_error ("attribute internal error.\n");
981 return MM_ERROR_FILE_INTERNAL;
984 parse.type = MM_FILE_PARSE_TYPE_ALL;
985 ret = _get_contents_info (attrs, &src, &parse);
986 if (ret != MM_ERROR_NONE) {
987 debug_error ("failed to get contents");
990 *contents_attrs = (MMHandleType)attrs;
992 #ifdef __MMFILE_DYN_LOADING__
993 _unload_dynamic_functions (&func_handle);
1003 int mm_file_destroy_content_attrs (MMHandleType contents_attrs)
1005 void *thumbnail = NULL;
1006 int ret = MM_ERROR_NONE;
1009 if ((mmf_attrs_t*)contents_attrs == NULL) {
1010 debug_error ("invalid handle.\n");
1011 return MM_ERROR_INVALID_ARGUMENT;
1014 ret = mm_attrs_get_data_by_name(contents_attrs, MM_FILE_CONTENT_VIDEO_THUMBNAIL, &thumbnail);
1015 if (thumbnail != NULL) {
1016 mmfile_free (thumbnail);
1019 mmf_attrs_free (contents_attrs);
1028 int mm_file_get_stream_info(const char* filename, int *audio_stream_num, int *video_stream_num)
1030 MMFileSourceType src = {0,};
1031 MMFILE_PARSE_INFO parse = {0,};
1037 if (filename == NULL || strlen (filename) == 0 || audio_stream_num == NULL || video_stream_num == NULL) {
1038 debug_error ("Invalid arguments\n");
1039 return MM_ERROR_INVALID_ARGUMENT;
1042 #ifdef __MMFILE_DYN_LOADING__
1043 MMFILE_FUNC_HANDLE func_handle;
1045 ret = _load_dynamic_functions (&func_handle);
1047 debug_error ("load library error\n");
1048 return MM_ERROR_FILE_INTERNAL;
1052 /*set source file infomation*/
1053 MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
1055 ret = _is_file_exist (filename);
1057 return MM_ERROR_FILE_NOT_FOUND;
1059 parse.type = MM_FILE_PARSE_TYPE_SIMPLE;
1060 ret = _get_contents_info (NULL, &src, &parse);
1061 if (ret != MM_ERROR_NONE) {
1062 debug_error ("failed to get stream info: %s\n", filename);
1065 /*set number of each stream*/
1066 *audio_stream_num = parse.audio_track_num;
1067 *video_stream_num = parse.video_track_num;
1069 #ifdef __MMFILE_DYN_LOADING__
1070 _unload_dynamic_functions (&func_handle);
1079 int mm_file_create_content_attrs_simple(MMHandleType *contents_attrs, const char *filename)
1081 mmf_attrs_t *attrs = NULL;
1082 MMFileSourceType src = {0,};
1083 MMFILE_PARSE_INFO parse = {0,};
1088 #ifdef __MMFILE_DYN_LOADING__
1089 MMFILE_FUNC_HANDLE func_handle;
1091 ret = _load_dynamic_functions (&func_handle);
1093 debug_error ("load library error\n");
1094 return MM_ERROR_FILE_INTERNAL;
1097 if (filename == NULL) {
1098 return MM_ERROR_INVALID_ARGUMENT;
1100 if (strlen (filename) == 0)
1101 return MM_ERROR_INVALID_ARGUMENT;
1104 /*set source file infomation*/
1105 MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
1107 ret = _is_file_exist (filename);
1109 return MM_ERROR_FILE_NOT_FOUND;
1112 attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
1114 debug_error ("attribute internal error.\n");
1115 return MM_ERROR_FILE_INTERNAL;
1118 parse.type = MM_FILE_PARSE_TYPE_NORMAL;
1119 ret = _get_contents_info (attrs, &src, &parse);
1120 if (ret != MM_ERROR_NONE) {
1121 debug_error ("failed to get contents: %s\n", filename);
1124 *contents_attrs = (MMHandleType) attrs;
1126 #ifdef __MMFILE_DYN_LOADING__
1127 _unload_dynamic_functions (&func_handle);
1136 int mm_file_get_video_frame(const char* path, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height)
1139 void *formatFuncHandle = NULL;
1142 debug_error ("Invalid arguments [Path is Null]\n");
1143 return MM_ERROR_INVALID_ARGUMENT;
1146 #ifdef __MMFILE_DYN_LOADING__
1147 /* Get from function argument */
1148 formatFuncHandle = dlopen (MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
1149 if (!formatFuncHandle) {
1150 debug_error ("error : dlopen");
1154 mmfile_format_get_frame = dlsym (formatFuncHandle, "mmfile_format_get_frame");
1155 if ( !mmfile_format_get_frame ) {
1156 debug_error ("error : load library");
1161 #ifdef __MMFILE_TEST_MODE__
1162 debug_msg("file path [%s] is_accurate [%d]", path, is_accurate);
1165 ret = mmfile_format_get_frame(path, timestamp, is_accurate, frame, size, width, height);
1166 if (ret == MMFILE_FORMAT_FAIL) {
1167 debug_error ("error : get frame");
1171 if (formatFuncHandle) dlclose (formatFuncHandle);
1173 return MM_ERROR_NONE;
1176 if (formatFuncHandle) dlclose (formatFuncHandle);
1178 return MM_ERROR_FILE_INTERNAL;
1182 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)
1185 void *formatFuncHandle = NULL;
1188 debug_error ("Invalid arguments [data is Null]\n");
1189 return MM_ERROR_INVALID_ARGUMENT;
1192 if (datasize == 0) {
1193 debug_error ("Invalid arguments [datasize is zero]\n");
1194 return MM_ERROR_INVALID_ARGUMENT;
1197 #ifdef __MMFILE_DYN_LOADING__
1198 /* Get from function argument */
1199 formatFuncHandle = dlopen (MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
1200 if (!formatFuncHandle) {
1201 debug_error ("error : dlopen");
1205 mmfile_format_get_frame_from_memory = dlsym (formatFuncHandle, "mmfile_format_get_frame_from_memory");
1206 if ( !mmfile_format_get_frame_from_memory ) {
1207 debug_error ("error : load library");
1212 #ifdef __MMFILE_TEST_MODE__
1213 debug_msg("data [%p], data_size[%d], is_accurate [%d]", data, datasize, is_accurate);
1216 ret = mmfile_format_get_frame_from_memory(data, datasize, timestamp, is_accurate, frame, size, width, height);
1217 if (ret == MMFILE_FORMAT_FAIL) {
1218 debug_error ("error : get frame");
1222 if (formatFuncHandle) dlclose (formatFuncHandle);
1224 return MM_ERROR_NONE;
1227 if (formatFuncHandle) dlclose (formatFuncHandle);
1229 return MM_ERROR_FILE_INTERNAL;