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.
25 #include <libavformat/avformat.h>
26 #include <libavcodec/avcodec.h>
27 #ifdef __MMFILE_FFMPEG_V085__
28 #include <libswscale/swscale.h>
33 #include "mm_file_formats.h"
34 #include "mm_file_utils.h"
35 #include "mm_file_format_ffmpeg.h"
37 #include "mm_file_format_ffmpeg_mem.h"
42 #define _SHORT_MEDIA_LIMIT 2000 /* under X seconds duration*/
44 extern int img_convert (AVPicture *dst, int dst_pix_fmt, const AVPicture *src, int src_pix_fmt,int src_width, int src_height);
46 /* internal functions */
47 static int _is_good_pgm (unsigned char *buf, int wrap, int xsize, int ysize);
48 #ifdef MMFILE_FORMAT_DEBUG_DUMP
49 static void _save_pgm (unsigned char *buf, int wrap, int xsize, int ysize, char *filename);
51 #ifdef __MMFILE_TEST_MODE__
52 static void _dump_av_packet (AVPacket *pkt);
55 static int _get_video_fps (int frame_cnt, int duration, AVRational r_frame_rate, int is_roundup);
56 static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame);
58 static int ConvertVideoCodecEnum (int AVVideoCodecID);
59 static int ConvertAudioCodecEnum (int AVAudioCodecID);
61 /* plugin manadatory API */
62 int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext);
63 int mmfile_format_read_frame_ffmpg (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
64 int mmfile_format_read_tag_ffmpg (MMFileFormatContext *formatContext);
65 int mmfile_format_close_ffmpg (MMFileFormatContext *formatContext);
66 static int getMimeType(int formatId, char *mimeType);
71 int mmfile_format_open_ffmpg (MMFileFormatContext *formatContext)
73 AVFormatContext *pFormatCtx = NULL;
74 AVInputFormat *grab_iformat = NULL;
77 char ffmpegFormatName[MMFILE_FILE_FMT_MAX_LEN] = {0,};
78 char mimeType[MMFILE_MIMETYPE_MAX_LEN] = {0,};
80 formatContext->ReadStream = mmfile_format_read_stream_ffmpg;
81 formatContext->ReadFrame = mmfile_format_read_frame_ffmpg;
82 formatContext->ReadTag = mmfile_format_read_tag_ffmpg;
83 formatContext->Close = mmfile_format_close_ffmpg;
85 #ifdef __MMFILE_TEST_MODE__
86 debug_msg ("ffmpeg version: %d\n", avformat_version ());
97 av_log_set_level (AV_LOG_DEBUG);
99 av_log_set_level (AV_LOG_QUIET);
104 if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_MEMORY) {
106 #ifdef __MMFILE_FFMPEG_V085__
107 ffurl_register_protocol(&MMFileMEMProtocol, sizeof (URLProtocol));
109 register_protocol (&MMFileMEMProtocol);
111 if(getMimeType(formatContext->filesrc->memory.format,mimeType)< 0) {
112 debug_error ("error: Error in MIME Type finding\n");
113 return MMFILE_FORMAT_FAIL;
116 memset (ffmpegFormatName, 0x00, MMFILE_FILE_FMT_MAX_LEN);
118 ret = mmfile_util_get_ffmpeg_format (mimeType,ffmpegFormatName);
120 if (MMFILE_UTIL_SUCCESS != ret) {
121 debug_error ("error: mmfile_util_get_ffmpeg_format\n");
122 return MMFILE_FORMAT_FAIL;
125 grab_iformat = av_find_input_format (ffmpegFormatName);
127 if (NULL == grab_iformat) {
128 debug_error ("error: cannot find format\n");
132 #ifdef __MMFILE_FFMPEG_V085__
133 ret = avformat_open_input (&pFormatCtx, formatContext->uriFileName, grab_iformat, NULL);
135 ret = av_open_input_file (&pFormatCtx, formatContext->uriFileName, grab_iformat, 0, NULL);
138 debug_error("error: cannot open %s %d\n", formatContext->uriFileName, ret);
141 formatContext->privateFormatData = pFormatCtx;
144 if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_FILE) {
146 if (formatContext->isdrm == MM_FILE_DRM_OMA) {
147 debug_error ("error: drm content\n");
151 #ifdef __MMFILE_FFMPEG_V085__
152 ret = avformat_open_input(&pFormatCtx, formatContext->filesrc->file.path, NULL, NULL);
154 ret = av_open_input_file(&pFormatCtx, formatContext->filesrc->file.path, NULL, 0, NULL);
157 debug_error("error: cannot open %s %d\n", formatContext->filesrc->file.path, ret);
160 formatContext->privateFormatData = pFormatCtx;
164 if (!pFormatCtx || !(pFormatCtx->nb_streams > 0)) {
165 debug_warning ("failed to find av stream. maybe corrupted data.\n");
169 #ifdef __MMFILE_TEST_MODE__
170 debug_msg ("number of stream: %d\n", pFormatCtx->nb_streams);
173 formatContext->videoTotalTrackNum = 0;
174 formatContext->audioTotalTrackNum = 0;
176 for(i = 0; i < pFormatCtx->nb_streams; i++) {
177 #ifdef __MMFILE_FFMPEG_V085__
178 if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
179 #ifdef __MMFILE_TEST_MODE__
180 debug_msg ("FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
182 formatContext->videoTotalTrackNum += 1;
184 if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
185 #ifdef __MMFILE_TEST_MODE__
186 debug_msg ("FFMPEG audio codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
188 formatContext->audioTotalTrackNum += 1;
191 if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
192 #ifdef __MMFILE_TEST_MODE__
193 debug_msg ("FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
195 formatContext->videoTotalTrackNum += 1;
197 if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
198 #ifdef __MMFILE_TEST_MODE__
199 debug_msg ("FFMPEG audio codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
201 formatContext->audioTotalTrackNum += 1;
206 #ifdef __MMFILE_TEST_MODE__
207 debug_msg ("format: %s (%s)\n", pFormatCtx->iformat->name, pFormatCtx->iformat->long_name);
208 #ifdef __MMFILE_FFMPEG_V085__
209 av_dump_format (pFormatCtx, 0, formatContext->filesrc->file.path, 0);
211 dump_format (pFormatCtx, 0, formatContext->filesrc->file.path, 0);
215 return MMFILE_FORMAT_SUCCESS;
217 exception: /* fail to get content information */
219 mmfile_format_close_ffmpg (formatContext);
220 formatContext->privateFormatData = NULL;
222 return MMFILE_FORMAT_FAIL;
227 int mmfile_format_read_stream_ffmpg (MMFileFormatContext * formatContext)
229 AVFormatContext *pFormatCtx = NULL;
230 AVCodecContext *pAudioCodecCtx = NULL;
231 AVCodecContext *pVideoCodecCtx = NULL;
233 MMFileFormatStream *videoStream = NULL;
234 MMFileFormatStream *audioStream = NULL;
237 if (NULL == formatContext || NULL == formatContext->privateFormatData) {
238 debug_error ("invalid param\n");
239 return MMFILE_FORMAT_FAIL;
242 pFormatCtx = formatContext->privateFormatData;
245 *@important if data is corrupted, occur segment fault by av_find_stream_info().
246 * - fixed 2009-06-25.
248 #ifdef __MMFILE_FFMPEG_V100__
249 ret = avformat_find_stream_info (pFormatCtx, NULL);
251 ret = av_find_stream_info (pFormatCtx);
254 debug_warning ("failed to find stream info. errcode = %d\n", ret);
258 #ifdef __MMFILE_TEST_MODE__
259 debug_msg ("FFMPEG: dur %lld, start %lld\n", pFormatCtx->duration, pFormatCtx->start_time);
263 *@note asf has long duration bug. and Some content's start time is wrong(negative number).
265 if(pFormatCtx->start_time < 0) {
266 debug_warning ("Wrong Start time = %lld\n", pFormatCtx->start_time);
267 formatContext->duration = (long long)(pFormatCtx->duration) * 1000 / AV_TIME_BASE;
270 formatContext->duration = (long long)(pFormatCtx->duration + pFormatCtx->start_time) * 1000 / AV_TIME_BASE;
273 formatContext->videoStreamId = -1;
274 formatContext->audioStreamId = -1;
275 formatContext->nbStreams = 0;
278 for ( i = 0; i < pFormatCtx->nb_streams; i++ ) {
279 #ifdef __MMFILE_FFMPEG_V085__
280 if ( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
282 if ( pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
284 if (formatContext->videoStreamId == -1) {
285 videoStream = mmfile_malloc (sizeof(MMFileFormatStream));
286 if (NULL == videoStream) {
287 debug_error ("mmfile_malloc error\n");
291 videoStream->streamType = MMFILE_VIDEO_STREAM;
292 formatContext->streams[MMFILE_VIDEO_STREAM] = videoStream;
293 formatContext->nbStreams += 1;
294 formatContext->videoStreamId = i;
296 pVideoCodecCtx = pFormatCtx->streams[i]->codec;
297 if (pVideoCodecCtx) {
298 videoStream->codecId = ConvertVideoCodecEnum (pVideoCodecCtx->codec_id);
302 * 1. try to get average fps of video stream.
303 * 2. if (1) failed, try to get fps of media container.
305 videoStream->framePerSec = _get_video_fps (pFormatCtx->streams[i]->nb_frames,
306 pFormatCtx->streams[i]->duration,
307 pFormatCtx->streams[i]->time_base,
310 if (videoStream->framePerSec == 0)
311 videoStream->framePerSec = av_q2d (pFormatCtx->streams[i]->r_frame_rate);
313 videoStream->width = pVideoCodecCtx->width;
314 videoStream->height = pVideoCodecCtx->height;
315 videoStream->bitRate = pVideoCodecCtx->bit_rate;
319 #ifdef __MMFILE_FFMPEG_V085__
320 else if ( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO ) {
322 else if ( pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO ) {
324 if (formatContext->audioStreamId == -1) {
325 audioStream = mmfile_malloc (sizeof(MMFileFormatStream));
326 if (NULL == audioStream) {
327 debug_error ("mmfile_malloc error\n");
331 audioStream->streamType = MMFILE_AUDIO_STREAM;
332 formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
333 formatContext->nbStreams += 1;
334 formatContext->audioStreamId = i;
336 pAudioCodecCtx = pFormatCtx->streams[i]->codec;
337 if (pAudioCodecCtx) {
338 audioStream->codecId = ConvertAudioCodecEnum (pAudioCodecCtx->codec_id);
339 audioStream->bitRate = pAudioCodecCtx->bit_rate;
340 audioStream->nbChannel = pAudioCodecCtx->channels;
341 audioStream->samplePerSec = pAudioCodecCtx->sample_rate;
347 if ( formatContext->nbStreams == 0 ) {
348 debug_error("error: there is no audio and video track\n");
352 #ifdef __MMFILE_TEST_MODE__
353 mmfile_format_print_contents (formatContext);
356 return MMFILE_FORMAT_SUCCESS;
360 mmfile_free (videoStream);
361 formatContext->streams[MMFILE_VIDEO_STREAM] = NULL;
365 mmfile_free (audioStream);
366 formatContext->streams[MMFILE_AUDIO_STREAM] = NULL;
370 #ifdef __MMFILE_FFMPEG_V100__
371 avformat_close_input (&pFormatCtx);
373 av_close_input_file (pFormatCtx);
375 formatContext->privateFormatData = NULL;
378 formatContext->audioTotalTrackNum = 0;
379 formatContext->videoTotalTrackNum = 0;
380 formatContext->nbStreams = 0;
382 return MMFILE_FORMAT_FAIL;
387 int mmfile_format_read_tag_ffmpg (MMFileFormatContext *formatContext)
389 AVFormatContext *pFormatCtx = NULL;
391 if (NULL == formatContext || NULL == formatContext->privateFormatData) {
392 debug_error ("invalid param\n");
393 return MMFILE_FORMAT_FAIL;
396 pFormatCtx = formatContext->privateFormatData;
398 if (formatContext->formatType == MM_FILE_FORMAT_3GP ||formatContext->formatType == MM_FILE_FORMAT_MP4) {
399 MMFileUtilGetMetaDataFromMP4 (formatContext);
402 #ifdef __MMFILE_FFMPEG_V085__
403 /*metadata extracted by ffmpeg*/
406 if(pFormatCtx != NULL) {
407 for(idx = 0; idx < pFormatCtx->nb_streams + 1; idx++) {
408 AVDictionary *metainfo = NULL;
411 if(idx < pFormatCtx->nb_streams) { //Check metadata of normal stream like audio, video, video cover art(cover art saved in new stream). refer to mov_read_covr() in ffmpeg.
412 st = pFormatCtx->streams[idx];
414 metainfo = st->metadata;
415 } else { //Check metadata of Content
416 if(pFormatCtx->metadata != NULL) {
417 metainfo = pFormatCtx->metadata;
423 /*refer to mov_read_covr() in ffmpeg.*/
425 AVPacket pkt = st->attached_pic;
426 int codec_id = st->codec->codec_id;
428 if((pkt.data != NULL) && (pkt.size > 0)) {
430 if (formatContext->artworkMime) mmfile_free (formatContext->artworkMime);
432 if(codec_id == AV_CODEC_ID_MJPEG)
433 formatContext->artworkMime = mmfile_strdup("image/jpeg");
434 else if(codec_id == AV_CODEC_ID_PNG)
435 formatContext->artworkMime = mmfile_strdup("image/png");
436 else if(codec_id == AV_CODEC_ID_BMP)
437 formatContext->artworkMime = mmfile_strdup("image/bmp");
439 debug_error ("Unknown cover type: 0x%x\n", codec_id);
442 if (formatContext->artwork) mmfile_free (formatContext->artwork);
444 formatContext->artworkSize = pkt.size;
445 formatContext->artwork = mmfile_malloc (pkt.size);
446 memcpy (formatContext->artwork, pkt.data, pkt.size);
450 if(metainfo != NULL) {
451 AVDictionaryEntry *tag = NULL;
452 while((tag=av_dict_get(metainfo, "", tag, AV_DICT_IGNORE_SUFFIX))) {
453 if(tag->key != NULL) {
454 if(!strcasecmp(tag->key, "title")) {
455 if (formatContext->title) free (formatContext->title);
456 formatContext->title = mmfile_strdup (tag->value);
457 } else if(!strcasecmp(tag->key, "artist")) {
458 if (formatContext->artist) free (formatContext->artist);
459 formatContext->artist = mmfile_strdup (tag->value);
460 } else if(!strcasecmp(tag->key, "composer")) {
461 if (formatContext->composer) free (formatContext->composer);
462 formatContext->composer = mmfile_strdup (tag->value);
463 } else if(!strcasecmp(tag->key, "album")) {
464 if (formatContext->album) free (formatContext->album);
465 formatContext->album = mmfile_strdup (tag->value);
466 } else if(!strcasecmp(tag->key, "copyright")) {
467 if (formatContext->copyright) free (formatContext->copyright);
468 formatContext->copyright = mmfile_strdup (tag->value);
469 } else if(!strcasecmp(tag->key, "comment")) {
470 if (formatContext->comment) free (formatContext->comment);
471 formatContext->comment = mmfile_strdup (tag->value);
472 } else if(!strcasecmp(tag->key, "description")) {
473 if (formatContext->description) free (formatContext->description);
474 formatContext->description = mmfile_strdup (tag->value);
475 } else if(!strcasecmp(tag->key, "genre")) {
476 if (formatContext->genre) free (formatContext->genre);
477 formatContext->genre = mmfile_strdup (tag->value);
478 } else if(!strcasecmp(tag->key, "date")) {
479 if (formatContext->year) free (formatContext->year);
480 formatContext->year = mmfile_strdup (tag->value);
481 } else if((!strcasecmp(tag->key, "track")) || (!strcasecmp(tag->key, "tracknumber"))) {
482 if (formatContext->tagTrackNum) free (formatContext->tagTrackNum);
483 formatContext->tagTrackNum = mmfile_strdup (tag->value);
484 } else if(!strcasecmp(tag->key, "lyrics")) {
485 if (formatContext->unsyncLyrics) free (formatContext->unsyncLyrics);
486 formatContext->unsyncLyrics= mmfile_strdup (tag->value);
487 } else if(!strcasecmp(tag->key, "rotate")) { //can be "90", "180", "270"
488 if (formatContext->rotate) free (formatContext->rotate);
489 formatContext->rotate= mmfile_strdup (tag->value);
491 debug_log("Not support metadata. [%s:%s]", tag->key, tag->value);
496 #ifdef __MMFILE_TEST_MODE__
497 mmfile_format_print_tags (formatContext);
502 if (pFormatCtx->title[0]) {
503 if (formatContext->title)
504 free (formatContext->title);
505 formatContext->title = mmfile_strdup (pFormatCtx->title);
507 if (pFormatCtx->author[0]){
508 if (formatContext->author)
509 free (formatContext->author);
510 formatContext->author = mmfile_strdup (pFormatCtx->author);
512 if (pFormatCtx->copyright[0]) {
513 if (formatContext->copyright)
514 free (formatContext->copyright);
515 formatContext->copyright = mmfile_strdup (pFormatCtx->copyright);
517 if (pFormatCtx->comment[0]) {
518 if (formatContext->comment)
519 free (formatContext->comment);
520 formatContext->comment = mmfile_strdup (pFormatCtx->comment);
522 if (pFormatCtx->album[0]) {
523 if (formatContext->album)
524 free (formatContext->album);
525 formatContext->album = mmfile_strdup (pFormatCtx->album);
527 if (pFormatCtx->genre[0]) {
528 if (formatContext->genre)
529 free (formatContext->genre);
530 formatContext->genre = mmfile_strdup (pFormatCtx->genre);
533 if (pFormatCtx->year) {
534 char year[10] = {0,};
535 snprintf (year, 10, "%d", pFormatCtx->year);
537 if (formatContext->year)
538 free (formatContext->year);
539 formatContext->year = mmfile_strdup (year);
542 if (pFormatCtx->track) {
543 char tracknum[10] = {0,};
544 snprintf (tracknum, 10, "%d", pFormatCtx->track);
546 if (formatContext->tagTrackNum)
547 free (formatContext->tagTrackNum);
548 formatContext->tagTrackNum = mmfile_strdup (tracknum);
552 return MMFILE_FORMAT_SUCCESS;
557 int mmfile_format_read_frame_ffmpg (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
559 AVFormatContext *pFormatCtx = NULL;
560 AVCodecContext *pVideoCodecCtx = NULL;
561 AVCodec *pVideoCodec = NULL;
562 AVFrame *pFrame = NULL;
563 AVFrame *pFrameRGB = NULL;
570 if (NULL == formatContext ||
572 NULL == formatContext->privateFormatData ||
573 formatContext->videoTotalTrackNum <= 0) {
575 debug_error ("invalid param\n");
576 return MMFILE_FORMAT_FAIL;
579 pFormatCtx = formatContext->privateFormatData;
581 if (formatContext->videoStreamId != -1) {
582 pVideoCodecCtx = pFormatCtx->streams[formatContext->videoStreamId]->codec;
583 if (NULL == pVideoCodecCtx) {
584 debug_error ("invalid param\n");
585 return MMFILE_FORMAT_FAIL;
588 pVideoCodec = avcodec_find_decoder (pVideoCodecCtx->codec_id);
589 if ( NULL == pVideoCodec ) {
590 debug_error ("error: avcodec_find_decoder failed\n");
591 return MMFILE_FORMAT_FAIL;
594 #ifdef __MMFILE_TEST_MODE__
595 debug_msg ("flag: 0x%08X\n", pVideoCodec->capabilities);
596 // debug_msg (" DRAW_HORIZ_BAND : %d\n", pVideoCodec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND ? 1 : 0);
597 // debug_msg (" DR1 : %d\n", pVideoCodec->capabilities & CODEC_CAP_DR1 ? 1 : 0);
598 // debug_msg (" PARSE_ONLY : %d\n", pVideoCodec->capabilities & CODEC_CAP_PARSE_ONLY ? 1 : 0);
599 // debug_msg (" TRUNCATED : %d\n", pVideoCodec->capabilities & CODEC_CAP_TRUNCATED ? 1 : 0);
600 // debug_msg (" HWACCEL : %d\n", pVideoCodec->capabilities & CODEC_CAP_HWACCEL ? 1 : 0);
601 // debug_msg (" DELAY : %d\n", pVideoCodec->capabilities & CODEC_CAP_DELAY ? 1 : 0);
602 // debug_msg (" SMALL_LAST_FRAME: %d\n", pVideoCodec->capabilities & CODEC_CAP_SMALL_LAST_FRAME ? 1 : 0);
603 // debug_msg (" HWACCEL_VDPAU : %d\n", pVideoCodec->capabilities & CODEC_CAP_HWACCEL_VDPAU ? 1 : 0);
606 if (pVideoCodec->capabilities & CODEC_CAP_TRUNCATED) {
607 pVideoCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
610 /*set workaround bug flag*/
611 pVideoCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
612 #ifdef __MMFILE_FFMPEG_V100__
613 ret = avcodec_open2 (pVideoCodecCtx, pVideoCodec, NULL);
615 ret = avcodec_open (pVideoCodecCtx, pVideoCodec);
618 debug_error ("error: avcodec_open fail.\n");
619 return MMFILE_FORMAT_FAIL;
622 pFrameRGB = avcodec_alloc_frame ();
625 debug_error ("error: pFrame or pFrameRGB is NULL\n");
626 ret = MMFILE_FORMAT_FAIL;
630 /* search & decode */
631 // seek_ts = formatContext->duration > _SHORT_MEDIA_LIMIT ? seek_ts : 0; /*if short media, seek first key frame*/
632 ret = _get_first_good_video_frame (pFormatCtx, pVideoCodecCtx, formatContext->videoStreamId, &pFrame);
633 if ( ret != MMFILE_FORMAT_SUCCESS ) {
634 debug_error ("error: get key frame\n");
635 ret = MMFILE_FORMAT_FAIL;
639 #ifdef __MMFILE_TEST_MODE__
640 debug_msg ("Video default resolution = [%dx%d]\n", pVideoCodecCtx->coded_width, pVideoCodecCtx->coded_height);
641 debug_msg ("Video coded resolution = [%dx%d]\n", pVideoCodecCtx->width, pVideoCodecCtx->height);
644 /*sometimes, ffmpeg's width/height is wrong*/
645 #if 0 /*coded_width/height sometimes wrong. so use width/height*/
646 width = pVideoCodecCtx->coded_width == 0 ? pVideoCodecCtx->width : pVideoCodecCtx->coded_width;
647 height = pVideoCodecCtx->coded_height == 0 ? pVideoCodecCtx->height : pVideoCodecCtx->coded_height;
649 if((pVideoCodecCtx->width == 0) || (pVideoCodecCtx->height == 0)) {
650 width = pVideoCodecCtx->coded_width;
651 height = pVideoCodecCtx->coded_height;
653 width = pVideoCodecCtx->width;
654 height = pVideoCodecCtx->height;
657 numBytes = avpicture_get_size(PIX_FMT_RGB24, width, height);
659 debug_error ("error: avpicture_get_size. [%d x %d]\n", width, height);
660 ret = MMFILE_FORMAT_FAIL;
664 frame->frameData = mmfile_malloc (numBytes);
665 if (NULL == frame->frameData) {
666 debug_error ("error: avpicture_get_size. [%d]\n", numBytes);
667 ret = MMFILE_FORMAT_FAIL;
671 ret = avpicture_fill ((AVPicture *)pFrameRGB, frame->frameData, PIX_FMT_RGB24, width, height);
673 debug_error ("error: avpicture_fill fail. errcode = 0x%08X\n", ret);
674 ret = MMFILE_FORMAT_FAIL;
678 #ifdef __MMFILE_FFMPEG_V085__
679 struct SwsContext *img_convert_ctx = NULL;
681 img_convert_ctx = sws_getContext (width, height, pVideoCodecCtx->pix_fmt,
682 width, height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
684 if (NULL == img_convert_ctx) {
685 debug_error ("failed to get img convet ctx\n");
686 ret = MMFILE_FORMAT_FAIL;
690 ret = sws_scale (img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize,
691 0, height, pFrameRGB->data, pFrameRGB->linesize);
693 debug_error ("failed to convet image\n");
694 ret = MMFILE_FORMAT_FAIL;
695 sws_freeContext(img_convert_ctx);
696 img_convert_ctx = NULL;
700 sws_freeContext(img_convert_ctx);
701 img_convert_ctx = NULL;
703 ret = img_convert ((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame, pVideoCodecCtx->pix_fmt, width, height);
705 debug_error ("failed to convet image\n");
706 ret = MMFILE_FORMAT_FAIL;
710 frame->frameSize = numBytes;
711 frame->frameWidth = width;
712 frame->frameHeight = height;
713 frame->configLenth = 0;
714 frame->bCompressed = 0; /* false */
716 if (pFrame) av_free (pFrame);
717 if (pFrameRGB) av_free (pFrameRGB);
719 avcodec_close(pVideoCodecCtx);
721 return MMFILE_FORMAT_SUCCESS;
726 if (pVideoCodecCtx) avcodec_close (pVideoCodecCtx);
727 if (frame->frameData) { mmfile_free (frame->frameData); frame->frameData = NULL; }
728 if (pFrame) av_free (pFrame);
729 if (pFrameRGB) av_free (pFrameRGB);
735 int mmfile_format_close_ffmpg(MMFileFormatContext *formatContext)
738 AVFormatContext *pFormatCtx = formatContext->privateFormatData;
741 #ifdef __MMFILE_FFMPEG_V100__
742 avformat_close_input(&pFormatCtx);
744 av_close_input_file (pFormatCtx);
746 formatContext->privateFormatData = NULL;
750 return MMFILE_FORMAT_SUCCESS;
754 * return average of difference
756 static unsigned int _diff_memory (const void *s1, const void *s2, unsigned int n)
758 char *s = (char *)s1;
759 char *d = (char *)s2;
764 for (i = 0, ret = 0; i < n; i++) {
767 ret += (tmp < 0 ? -tmp : tmp);
774 int64_t gettime(void)
777 gettimeofday(&tv,NULL);
778 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
782 #define IS_GOOD_OLD_METHOD
783 #ifdef IS_GOOD_OLD_METHOD
785 * compare with center line.
787 static int _is_good_pgm (unsigned char *buf, int wrap, int xsize, int ysize)
789 #define _MM_CHUNK_NUM 8 /*FIXME*/
790 #define _MM_CHUNK_LIMIT (_MM_CHUNK_NUM / 2)
791 #define _MM_CHUNK_DIFF_LIMIT (_MM_CHUNK_LIMIT * 2 + 1) /*FIXME*/
796 unsigned char *cnt; /*center line of image*/
798 unsigned int sum_diff;
802 step = ysize / _MM_CHUNK_NUM;
803 cnt_offset = (ysize / 2);
804 cnt = buf + cnt_offset * wrap;
806 #ifdef __MMFILE_TEST_MODE__
807 debug_msg ("checking frame. %p, %d, %d, %d\n", buf, wrap, xsize, ysize);
810 /*if too small, always ok return.*/
811 if (ysize < _MM_CHUNK_NUM)
814 for (point = 0, sum_diff = 0, i = step; i < ysize; i += step) {
815 if (i != cnt_offset) {
818 is_different = _diff_memory (cnt, buf + i * wrap, xsize);
819 point += (is_different == 0 ? 0 : 1);
820 sum_diff += is_different;
822 #ifdef __MMFILE_TEST_MODE__
823 debug_msg ("check %04d line. %s [%d]\n", i, (is_different == 0 ? "same" : "different"), is_different);
826 if (point >= _MM_CHUNK_LIMIT) {
827 if (sum_diff > _MM_CHUNK_DIFF_LIMIT) {
828 #ifdef __MMFILE_TEST_MODE__
829 debug_msg ("Good :-)\n");
833 #ifdef __MMFILE_TEST_MODE__
834 debug_msg ("Bad :-(\n");
844 #else // IS_GOOD_OLD_METHOD
845 /* ToDo : for enhancement */
846 #endif // IS_GOOD_OLD_METHOD
851 _get_video_fps (int frame_cnt, int duration, AVRational r_frame_rate, int is_roundup)
855 #ifdef __MMFILE_TEST_MODE__
856 debug_msg ("frame count: %d, dur: %d, num: %d, den: %d\n", frame_cnt, duration, r_frame_rate.num, r_frame_rate.den)
859 if (duration <= 0 || r_frame_rate.num <= 0 || r_frame_rate.den <= 0)
862 round = (is_roundup != 0 ? 0.50f : 0.00f);
864 fps = (double)frame_cnt / ((double)(duration * r_frame_rate.num) / r_frame_rate.den) + round;
869 #ifdef MMFILE_FORMAT_DEBUG_DUMP
870 static void _save_pgm (unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
875 f = fopen(filename,"w");
877 fprintf (f,"P5\n%d %d\n%d\n",xsize,ysize,255);
878 for (i = 0; i < ysize; i++)
879 fwrite (buf + i * wrap, 1, xsize, f);
885 #ifdef __MMFILE_TEST_MODE__
886 static void _dump_av_packet (AVPacket *pkt)
888 debug_msg ("--------- AV Packet -----------\n");
889 debug_msg (" pts: %lld\n", pkt->pts);
890 debug_msg (" dts: %lld\n", pkt->dts);
891 debug_msg (" data: %p\n", pkt->data);
892 debug_msg (" size: %d\n", pkt->size);
893 debug_msg (" stream_index: %d\n", pkt->stream_index);
894 #ifdef __MMFILE_FFMPEG_V085__
895 debug_msg (" flags: 0x%08X, %s\n", pkt->flags, (pkt->flags & AV_PKT_FLAG_KEY) ? "Keyframe" : "_");
897 debug_msg (" flags: 0x%08X, %s\n", pkt->flags, (pkt->flags & PKT_FLAG_KEY) ? "Keyframe" : "_");
899 debug_msg (" duration: %d\n", pkt->duration);
900 debug_msg (" destruct: %p\n", pkt->destruct);
901 debug_msg (" priv: %p\n", pkt->priv);
902 debug_msg (" pos: %lld\n", pkt->pos);
903 debug_msg (" convergence_duration: %lld\n", pkt->convergence_duration);
904 debug_msg ("-------------------------------\n");
908 static int _get_first_good_video_frame (AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame)
910 // AVStream *st = NULL;
913 AVFrame *frame = NULL;
914 AVFrame *tmp_frame = NULL;
915 AVFrame *first_frame = NULL;
917 // long long timestamp;
918 int stream_id = videoStream;
921 int i,v, len, got_picture;
924 #ifdef MMFILE_FORMAT_DEBUG_DUMP
925 char pgm_name[256] = {0,};
928 #define _RETRY_SEARCH_LIMIT 150
929 #define _KEY_SEARCH_LIMIT (_RETRY_SEARCH_LIMIT*2) /*2 = 1 read. some frame need to read one more*/
930 #define _FRAME_SEARCH_LIMIT 1000
932 first_frame = avcodec_alloc_frame ();
933 tmp_frame = avcodec_alloc_frame ();
935 if (!first_frame || !tmp_frame) {
936 debug_error ("failed to alloc frame.\n");
937 if (first_frame) av_free (first_frame);
938 if (tmp_frame) av_free (tmp_frame);
939 return MMFILE_FORMAT_FAIL;
942 #ifdef __MMFILE_TEST_MODE__
943 debug_msg ("frame: 1. %p, 2. %p\n", first_frame, tmp_frame);
946 #ifdef __MMFILE_FFMPEG_V085__
947 pCodecCtx->skip_frame = AVDISCARD_BIDIR;
949 pCodecCtx->hurry_up = 1;
952 for(i = 0, v = 0, key_detected = 0, frame = first_frame; i < _KEY_SEARCH_LIMIT && v < _FRAME_SEARCH_LIMIT;) {
953 av_init_packet (&pkt);
956 ret = av_read_frame (pFormatCtx, &pkt);
958 debug_error ("read failed. (maybe EOF or broken)\n");
961 if (pkt.stream_index == stream_id) {
963 #ifdef __MMFILE_FFMPEG_V085__
964 if ((pkt.flags & AV_PKT_FLAG_KEY ) || (key_detected == 1))
966 if ((pkt.flags & PKT_FLAG_KEY ) || (key_detected == 1))
969 #ifdef __MMFILE_TEST_MODE__
970 debug_msg ("video frame: %d, %d, %d\n", retry, i, v);
971 _dump_av_packet (&pkt);
976 #ifdef __MMFILE_FFMPEG_V085__
977 len = avcodec_decode_video2 (pCodecCtx, frame, &got_picture, &pkt);
979 len = avcodec_decode_video (pCodecCtx, frame, &got_picture, pkt.data, pkt.size);
982 debug_warning ("Error while decoding frame %dth\n", i);
983 } else if (got_picture) {
984 if (frame->key_frame) {
985 #ifdef __MMFILE_TEST_MODE__
986 debug_msg ("key frame!\n");
988 #ifdef MMFILE_FORMAT_DEBUG_DUMP
989 sprintf (pgm_name, "./key_%d_%d_%d.pgm", retry, i, v);
990 _save_pgm (frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
995 #ifdef __MMFILE_TEST_MODE__
999 ret = _is_good_pgm (frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height);
1000 #ifdef __MMFILE_TEST_MODE__
1001 ti = gettime() - ti;
1002 debug_msg ("Elapsed time = %lld\n", ti);
1005 #ifdef __MMFILE_TEST_MODE__
1006 debug_msg ("is good frame.\n");
1010 /*reset video frame count & retry searching*/
1011 debug_warning ("not good fame. retry scanning.\n");
1017 /*set buffer frame*/
1021 if (retry > _RETRY_SEARCH_LIMIT) break;
1024 #ifdef __MMFILE_TEST_MODE__
1025 debug_msg ("skip (not key frame).\n");
1027 #ifdef MMFILE_FORMAT_DEBUG_DUMP
1028 sprintf (pgm_name, "./not_key_%d_%d_%d.pgm", retry, i, v);
1029 _save_pgm (frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
1033 #ifdef __MMFILE_TEST_MODE__
1034 debug_msg ("decode not completed.\n");
1041 av_free_packet (&pkt);
1044 /*free pkt after loop breaking*/
1045 if (pkt.data) av_free_packet (&pkt);
1047 #ifdef __MMFILE_TEST_MODE__
1048 debug_msg ("found: %d, retry: %d\n", found, retry);
1051 /*set decode frame to output*/
1053 ret = MMFILE_FORMAT_SUCCESS;
1054 if (retry == 0 || found == retry) {
1055 *pFrame = first_frame;
1056 if (tmp_frame) av_free (tmp_frame);
1058 *pFrame = tmp_frame;
1059 if (first_frame) av_free (first_frame);
1062 ret = MMFILE_FORMAT_FAIL;
1063 if (first_frame) av_free (first_frame);
1064 if (tmp_frame) av_free (tmp_frame);
1067 #ifdef __MMFILE_TEST_MODE__
1068 debug_msg ("out frame: %p\n", *pFrame);
1071 #ifdef __MMFILE_FFMPEG_V085__
1072 pCodecCtx->skip_frame = AVDISCARD_NONE;
1074 pCodecCtx->hurry_up = 0;
1080 static int ConvertVideoCodecEnum (int AVVideoCodecID)
1082 int ret_codecid = 0;
1084 switch (AVVideoCodecID)
1086 case AV_CODEC_ID_NONE:
1087 ret_codecid = MM_VIDEO_CODEC_NONE;
1089 case AV_CODEC_ID_MPEG1VIDEO:
1090 ret_codecid = MM_VIDEO_CODEC_MPEG1;
1092 case AV_CODEC_ID_MPEG2VIDEO: ///< preferred ID for MPEG-1/2 video decoding
1093 ret_codecid = MM_VIDEO_CODEC_MPEG2;
1095 case AV_CODEC_ID_MPEG2VIDEO_XVMC:
1096 ret_codecid = MM_VIDEO_CODEC_MPEG2;
1098 case AV_CODEC_ID_H261:
1099 ret_codecid = MM_VIDEO_CODEC_H261;
1101 case AV_CODEC_ID_H263:
1102 ret_codecid = MM_VIDEO_CODEC_H263;
1104 case AV_CODEC_ID_MPEG4:
1105 ret_codecid = MM_VIDEO_CODEC_MPEG4;
1107 case AV_CODEC_ID_MSMPEG4V1:
1108 ret_codecid = MM_VIDEO_CODEC_MPEG4;
1110 case AV_CODEC_ID_MSMPEG4V2:
1111 ret_codecid = MM_VIDEO_CODEC_MPEG4;
1113 case AV_CODEC_ID_MSMPEG4V3:
1114 ret_codecid = MM_VIDEO_CODEC_MPEG4;
1116 case AV_CODEC_ID_WMV1:
1117 ret_codecid = MM_VIDEO_CODEC_WMV;
1119 case AV_CODEC_ID_WMV2:
1120 ret_codecid = MM_VIDEO_CODEC_WMV;
1122 case AV_CODEC_ID_H263P:
1123 ret_codecid = MM_VIDEO_CODEC_H263;
1125 case AV_CODEC_ID_H263I:
1126 ret_codecid = MM_VIDEO_CODEC_H263;
1128 case AV_CODEC_ID_FLV1:
1129 ret_codecid = MM_VIDEO_CODEC_FLV;
1131 case AV_CODEC_ID_H264:
1132 ret_codecid = MM_VIDEO_CODEC_H264;
1134 case AV_CODEC_ID_INDEO2:
1135 case AV_CODEC_ID_INDEO3:
1136 case AV_CODEC_ID_INDEO4:
1137 case AV_CODEC_ID_INDEO5:
1138 ret_codecid = MM_VIDEO_CODEC_INDEO;
1140 case AV_CODEC_ID_THEORA:
1141 ret_codecid = MM_VIDEO_CODEC_THEORA;
1143 case AV_CODEC_ID_CINEPAK:
1144 ret_codecid = MM_VIDEO_CODEC_CINEPAK;
1146 #ifndef __MMFILE_FFMPEG_V085__
1148 ret_codecid = MM_VIDEO_CODEC_XVID;
1151 case AV_CODEC_ID_VC1:
1152 ret_codecid = MM_VIDEO_CODEC_VC1;
1154 case AV_CODEC_ID_WMV3:
1155 ret_codecid = MM_VIDEO_CODEC_WMV;
1157 case AV_CODEC_ID_AVS:
1158 ret_codecid = MM_VIDEO_CODEC_AVS;
1160 case AV_CODEC_ID_RL2:
1161 ret_codecid = MM_VIDEO_CODEC_REAL;
1164 ret_codecid = MM_VIDEO_CODEC_NONE;
1172 static int ConvertAudioCodecEnum (int AVAudioCodecID)
1174 int ret_codecid = 0;
1176 switch (AVAudioCodecID)
1178 case AV_CODEC_ID_AMR_NB:
1179 case AV_CODEC_ID_AMR_WB:
1180 ret_codecid = MM_AUDIO_CODEC_AMR;
1182 /* RealAudio codecs*/
1183 case AV_CODEC_ID_RA_144:
1184 case AV_CODEC_ID_RA_288:
1185 ret_codecid = MM_AUDIO_CODEC_REAL;
1187 case AV_CODEC_ID_MP2:
1188 ret_codecid = MM_AUDIO_CODEC_MP2;
1190 case AV_CODEC_ID_MP3:
1191 case AV_CODEC_ID_MP3ADU:
1192 case AV_CODEC_ID_MP3ON4:
1193 ret_codecid = MM_AUDIO_CODEC_MP3;
1195 case AV_CODEC_ID_AAC:
1196 ret_codecid = MM_AUDIO_CODEC_AAC;
1198 case AV_CODEC_ID_AC3:
1199 ret_codecid = MM_AUDIO_CODEC_AC3;
1201 case AV_CODEC_ID_VORBIS:
1202 ret_codecid = MM_AUDIO_CODEC_VORBIS;
1204 case AV_CODEC_ID_WMAV1:
1205 case AV_CODEC_ID_WMAV2:
1206 case AV_CODEC_ID_WMAVOICE:
1207 case AV_CODEC_ID_WMAPRO:
1208 case AV_CODEC_ID_WMALOSSLESS:
1209 ret_codecid = MM_AUDIO_CODEC_WMA;
1211 case AV_CODEC_ID_FLAC:
1212 ret_codecid = MM_AUDIO_CODEC_FLAC;
1214 case AV_CODEC_ID_ALAC:
1215 ret_codecid = MM_AUDIO_CODEC_ALAC;
1217 case AV_CODEC_ID_WAVPACK:
1218 ret_codecid = MM_AUDIO_CODEC_WAVE;
1220 case AV_CODEC_ID_ATRAC3:
1221 case AV_CODEC_ID_ATRAC3P:
1222 case AV_CODEC_ID_EAC3:
1223 ret_codecid = MM_AUDIO_CODEC_AC3;
1226 ret_codecid = MM_AUDIO_CODEC_NONE;
1235 static int getMimeType(int formatId, char *mimeType)
1237 int ret = 0; /*default: success*/
1240 case MM_FILE_FORMAT_3GP:
1241 case MM_FILE_FORMAT_MP4:
1242 sprintf(mimeType,"video/3gpp");
1244 case MM_FILE_FORMAT_ASF:
1245 case MM_FILE_FORMAT_WMA:
1246 case MM_FILE_FORMAT_WMV:
1247 sprintf(mimeType,"video/x-ms-asf");
1249 case MM_FILE_FORMAT_AVI:
1250 sprintf(mimeType,"video/avi");
1252 case MM_FILE_FORMAT_OGG:
1253 sprintf(mimeType,"video/ogg");
1255 case MM_FILE_FORMAT_REAL:
1256 sprintf(mimeType,"video/vnd.rn-realvideo");
1258 case MM_FILE_FORMAT_AMR:
1259 sprintf(mimeType,"audio/AMR");
1261 case MM_FILE_FORMAT_AAC:
1262 sprintf(mimeType,"audio/aac");
1264 case MM_FILE_FORMAT_MP3:
1265 sprintf(mimeType,"audio/mp3");
1267 case MM_FILE_FORMAT_AIFF:
1268 case MM_FILE_FORMAT_WAV:
1269 sprintf(mimeType,"audio/wave");
1271 case MM_FILE_FORMAT_MID:
1272 sprintf(mimeType,"audio/midi");
1274 case MM_FILE_FORMAT_MMF:
1275 sprintf(mimeType,"audio/mmf");
1277 case MM_FILE_FORMAT_DIVX:
1278 sprintf(mimeType,"video/divx");
1280 case MM_FILE_FORMAT_IMELODY:
1281 sprintf(mimeType,"audio/iMelody");
1283 case MM_FILE_FORMAT_JPG:
1284 sprintf(mimeType,"image/jpeg");
1286 case MM_FILE_FORMAT_AU:
1287 sprintf(mimeType,"audio/basic");
1289 case MM_FILE_FORMAT_VOB:
1290 sprintf(mimeType,"video/mpeg");
1292 case MM_FILE_FORMAT_FLV:
1293 sprintf(mimeType,"video/x-flv");
1295 case MM_FILE_FORMAT_QT:
1296 sprintf(mimeType,"video/quicktime");
1298 case MM_FILE_FORMAT_MATROSKA:
1299 sprintf(mimeType,"video/x-matroska");
1301 case MM_FILE_FORMAT_FLAC:
1302 sprintf(mimeType,"audio/x-flac");
1308 debug_msg ("id: %d, mimetype: %s\n", formatId, mimeType);