From 74f43122539f36540c866b9930046187370686ff Mon Sep 17 00:00:00 2001 From: Minje Ahn Date: Tue, 26 May 2020 09:21:56 +0900 Subject: [PATCH] Code cleanup in mm_file_format_ffmpeg.c Change-Id: Ic722fe6e6d91f738edc9a9bdce3cfde33db5b7c8 Signed-off-by: Minje Ahn --- formats/ffmpeg/mm_file_format_ffmpeg.c | 1023 +++++++++++++------------------- formats/ffmpeg/mm_file_format_frame.c | 10 +- utils/include/mm_file_utils.h | 7 + utils/mm_file_util_io_mem.c | 7 - 4 files changed, 427 insertions(+), 620 deletions(-) diff --git a/formats/ffmpeg/mm_file_format_ffmpeg.c b/formats/ffmpeg/mm_file_format_ffmpeg.c index 189a2ec..d1a3a89 100644 --- a/formats/ffmpeg/mm_file_format_ffmpeg.c +++ b/formats/ffmpeg/mm_file_format_ffmpeg.c @@ -33,22 +33,138 @@ #include "mm_file_utils.h" #include "mm_file_format_ffmpeg.h" -#define _SHORT_MEDIA_LIMIT 2000 /* under X seconds duration*/ - -/* internal functions */ -static int _is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize); -#ifdef MMFILE_FORMAT_DEBUG_DUMP -static void _save_pgm(unsigned char *buf, int wrap, int xsize, int ysize, char *filename); -#endif #ifdef __MMFILE_TEST_MODE__ -static void _dump_av_packet(AVPacket *pkt); +static void _dump_av_packet(AVPacket *pkt) +{ + debug_msg(RELEASE, "--------- AV Packet -----------"); + debug_msg(RELEASE, " pts: %lld", pkt->pts); + debug_msg(RELEASE, " dts: %lld", pkt->dts); + debug_msg(RELEASE, " data: %p", pkt->data); + debug_msg(RELEASE, " size: %d", pkt->size); + debug_msg(RELEASE, " stream_index: %d", pkt->stream_index); + debug_msg(RELEASE, " flags: 0x%08X, %s", pkt->flags, (pkt->flags & AV_PKT_FLAG_KEY) ? "Keyframe" : "_"); + debug_msg(RELEASE, " duration: %lld", pkt->duration); + /*debug_msg(RELEASE, " destruct: %p", pkt->destruct);*/ + /*debug_msg(RELEASE, " priv: %p", pkt->priv);*/ + debug_msg(RELEASE, " pos: %lld", pkt->pos); + debug_msg(RELEASE, "-------------------------------"); +} #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, int cdis); -static int ConvertVideoCodecEnum(int AVVideoCodecID); -static int ConvertAudioCodecEnum(int AVAudioCodecID); +static int __convert_vidio_codec_type(int AVVideoCodecID) +{ + switch (AVVideoCodecID) { + case AV_CODEC_ID_MPEG1VIDEO: + return MM_VIDEO_CODEC_MPEG1; + case AV_CODEC_ID_MPEG2VIDEO: /*/< preferred ID for MPEG-1/2 video decoding */ + case AV_CODEC_ID_MPEG2VIDEO_XVMC: + case AV_CODEC_ID_MPEG2TS: + return MM_VIDEO_CODEC_MPEG2; + case AV_CODEC_ID_H261: + return MM_VIDEO_CODEC_H261; + case AV_CODEC_ID_H263: + return MM_VIDEO_CODEC_H263; + case AV_CODEC_ID_MPEG4: + case AV_CODEC_ID_MSMPEG4V1: + case AV_CODEC_ID_MSMPEG4V2: + case AV_CODEC_ID_MSMPEG4V3: + return MM_VIDEO_CODEC_MPEG4; + case AV_CODEC_ID_WMV1: + case AV_CODEC_ID_WMV2: + return MM_VIDEO_CODEC_WMV; + case AV_CODEC_ID_H263P: + case AV_CODEC_ID_H263I: + return MM_VIDEO_CODEC_H263; + case AV_CODEC_ID_FLV1: + return MM_VIDEO_CODEC_FLV; + case AV_CODEC_ID_H264: + return MM_VIDEO_CODEC_H264; + case AV_CODEC_ID_INDEO2: + case AV_CODEC_ID_INDEO3: + case AV_CODEC_ID_INDEO4: + case AV_CODEC_ID_INDEO5: + return MM_VIDEO_CODEC_INDEO; + case AV_CODEC_ID_THEORA: + return MM_VIDEO_CODEC_THEORA; + case AV_CODEC_ID_CINEPAK: + return MM_VIDEO_CODEC_CINEPAK; + case AV_CODEC_ID_VC1: + return MM_VIDEO_CODEC_VC1; + case AV_CODEC_ID_WMV3: + return MM_VIDEO_CODEC_WMV; + case AV_CODEC_ID_AVS: + return MM_VIDEO_CODEC_AVS; + 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 */ + return MM_VIDEO_CODEC_REAL; +#ifdef __MMFILE_LIBAV_VERSION__ + case AV_CODEC_ID_HEVC: + return MM_VIDEO_CODEC_MPEG4; +#endif +#ifdef USE_PRODUCT_FEATURE + case AV_CODEC_ID_VP8: + return MM_VIDEO_CODEC_VP8; + case AV_CODEC_ID_VP9: + return MM_VIDEO_CODEC_VP9; +#endif + default: + return MM_VIDEO_CODEC_NONE; + } +} + +static int __convert_audio_codec_type(int AVAudioCodecID) +{ + switch (AVAudioCodecID) { + case AV_CODEC_ID_AMR_NB: + case AV_CODEC_ID_AMR_WB: + return MM_AUDIO_CODEC_AMR; + /* RealAudio codecs*/ + case AV_CODEC_ID_RA_144: /* RealAudio 1 */ + case AV_CODEC_ID_RA_288: /* RealAudio 2 */ + case AV_CODEC_ID_COOK: /* RealAudio 6 */ + return MM_AUDIO_CODEC_REAL; + case AV_CODEC_ID_MP2: + return MM_AUDIO_CODEC_MP2; + case AV_CODEC_ID_MP3: + case AV_CODEC_ID_MP3ADU: + case AV_CODEC_ID_MP3ON4: + return MM_AUDIO_CODEC_MP3; + case AV_CODEC_ID_AAC: + return MM_AUDIO_CODEC_AAC; + case AV_CODEC_ID_AC3: + return MM_AUDIO_CODEC_AC3; + case AV_CODEC_ID_VORBIS: + return MM_AUDIO_CODEC_VORBIS; + case AV_CODEC_ID_WMAV1: + case AV_CODEC_ID_WMAV2: + case AV_CODEC_ID_WMAVOICE: + case AV_CODEC_ID_WMAPRO: + case AV_CODEC_ID_WMALOSSLESS: + return MM_AUDIO_CODEC_WMA; + case AV_CODEC_ID_FLAC: + return MM_AUDIO_CODEC_FLAC; + case AV_CODEC_ID_ALAC: + return MM_AUDIO_CODEC_ALAC; + case AV_CODEC_ID_WAVPACK: + return MM_AUDIO_CODEC_WAVE; + case AV_CODEC_ID_ATRAC3: + case AV_CODEC_ID_ATRAC3P: + case AV_CODEC_ID_EAC3: + return MM_AUDIO_CODEC_AC3; + case AV_CODEC_ID_PCM_S8: + case AV_CODEC_ID_PCM_S16BE: + case AV_CODEC_ID_PCM_S24BE: + case AV_CODEC_ID_PCM_S32BE: + return MM_AUDIO_CODEC_PCM; + default: + return MM_AUDIO_CODEC_NONE; + } +} /* plugin manadatory API */ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext); @@ -56,16 +172,6 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext); int mmfile_format_close_ffmpg(MMFileFormatContext *formatContext); -static int _mmf_mem_read(void *opaque, uint8_t *buf, int size); -static int64_t _mmf_mem_seek(void *opaque, int64_t pos, int whence); - -typedef struct { - unsigned char *ptr; - long long size; - long long offset; - int state; -} MMFmemIOHandle; - static void __count_stream_num(AVFormatContext *pFormatCtx, MMFileFormatContext *formatContext) { unsigned int i = 0; @@ -75,7 +181,7 @@ static void __count_stream_num(AVFormatContext *pFormatCtx, MMFileFormatContext for (i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - debug_msg(RELEASE, "FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codecpar->codec_id); + debug_msg(RELEASE, "FFMPEG video codec id: 0x%08X", pFormatCtx->streams[i]->codecpar->codec_id); AVPacket pkt = pFormatCtx->streams[i]->attached_pic; if ((pkt.data != NULL) && (pkt.size > 0)) @@ -85,30 +191,31 @@ static void __count_stream_num(AVFormatContext *pFormatCtx, MMFileFormatContext formatContext->videoTotalTrackNum += 1; } if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - debug_msg(RELEASE, "FFMPEG audio codec id: 0x%08X\n", pFormatCtx->streams[i]->codecpar->codec_id); + debug_msg(RELEASE, "FFMPEG audio codec id: 0x%08X", pFormatCtx->streams[i]->codecpar->codec_id); formatContext->audioTotalTrackNum += 1; } } } -static int _mmf_mem_open(MMFmemIOHandle **handle, const char *filename) +static bool __mmf_mem_open(MMFmemIOHandle **handle, const char *filename) { MMFmemIOHandle *memHandle = NULL; char **splitedString = NULL; filename += strlen(MMFILE_MEM_URI); - splitedString = g_strsplit(filename, ":", -1); - mm_file_retvm_if_fails(DEBUG, splitedString, MMFILE_UTIL_FAIL); - if (!splitedString[0] || !splitedString[1]) { - debug_error(DEBUG, "invalid param\n"); - goto exception; + if (g_strv_length(splitedString) < 2) { + debug_error(DEBUG, "invalid param"); + g_strfreev(splitedString); + + return false; } memHandle = g_new0(MMFmemIOHandle, 1); - memHandle->ptr = (unsigned char *)atoll(splitedString[0]); /*memory allocation address changed. memHandle->ptr = (unsigned char*)atoi(splitedString[0]); */ + /*memory allocation address changed. memHandle->ptr = (unsigned char*)atoi(splitedString[0]); */ + memHandle->ptr = (unsigned char *)atoll(splitedString[0]); memHandle->size = atoi(splitedString[1]); memHandle->offset = 0; memHandle->state = 0; @@ -117,68 +224,46 @@ static int _mmf_mem_open(MMFmemIOHandle **handle, const char *filename) g_strfreev(splitedString); - return MMFILE_UTIL_SUCCESS; - -exception: - g_strfreev(splitedString); - - return MMFILE_UTIL_FAIL; + return true; } -static int _mmf_mem_read(void *opaque, uint8_t *buf, int size) +static int __mmf_mem_read(void *opaque, uint8_t *buf, int size) { MMFmemIOHandle *memHandle = NULL; const unsigned char *c = NULL; int len = 0; - if (!opaque || !buf) { - debug_error(DEBUG, "invalid para\n"); - return MMFILE_UTIL_FAIL; - } + mm_file_retvm_if_fails(DEBUG, opaque, MMFILE_UTIL_FAIL); + mm_file_retvm_if_fails(DEBUG, buf, MMFILE_UTIL_FAIL); memHandle = opaque; - if (!memHandle->ptr) { - debug_error(DEBUG, "invalid para\n"); - return MMFILE_UTIL_FAIL; - } - - if (memHandle->offset >= memHandle->size) { - /* for some file formats last file read */ - debug_error(DEBUG, "File Read is beyond the file Size\n"); - return MMFILE_UTIL_FAIL; - - } + mm_file_retvm_if_fails(DEBUG, memHandle->ptr, MMFILE_UTIL_FAIL); + mm_file_retvm_if_fails(DEBUG, memHandle->offset < memHandle->size, MMFILE_UTIL_FAIL); c = memHandle->ptr + memHandle->offset; if (memHandle->state != EOF) { len = size; - if (len + memHandle->offset > memHandle->size) { + if (len + memHandle->offset > memHandle->size) len = memHandle->size - memHandle->offset; - } } memcpy(buf, c, len); - memHandle->offset += len; - if (memHandle->offset == memHandle->size) { + if (memHandle->offset == memHandle->size) memHandle->state = EOF; - } return len; } -static int64_t _mmf_mem_seek(void *opaque, int64_t pos, int whence) +static int64_t __mmf_mem_seek(void *opaque, int64_t pos, int whence) { MMFmemIOHandle *memHandle = NULL; long long tmp_offset = 0; - if (!opaque) { - debug_error(DEBUG, "invalid para\n"); - return MMFILE_UTIL_FAIL; - } + mm_file_retvm_if_fails(DEBUG, opaque, MMFILE_UTIL_FAIL); memHandle = opaque; @@ -199,10 +284,7 @@ static int64_t _mmf_mem_seek(void *opaque, int64_t pos, int whence) } /*check validation*/ - if (tmp_offset < 0 && tmp_offset > memHandle->size) { - debug_error(DEBUG, "invalid file offset\n"); - return MMFILE_UTIL_FAIL; - } + mm_file_retvm_if_fails(DEBUG, tmp_offset >= 0 && tmp_offset <= memHandle->size, MMFILE_UTIL_FAIL); /*set */ memHandle->state = (tmp_offset >= memHandle->size) ? EOF : !EOF; @@ -216,7 +298,6 @@ int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext) { AVFormatContext *pFormatCtx = NULL; AVInputFormat *grab_iformat = NULL; - int ret = 0; char ffmpegFormatName[MMFILE_FILE_FMT_MAX_LEN] = {0, }; char mimeType[MMFILE_MIMETYPE_MAX_LEN] = {0, }; AVIOContext *pIOCtx = NULL; @@ -228,7 +309,7 @@ int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext) formatContext->ReadTag = mmfile_format_read_tag_ffmpg; formatContext->Close = mmfile_format_close_ffmpg; - debug_msg(RELEASE, "ffmpeg version: %d\n", avformat_version()); + debug_msg(RELEASE, "ffmpeg version: %d", avformat_version()); /** * FFMPEG DEBUG LEVEL * AV_LOG_QUIET -1 @@ -248,55 +329,43 @@ int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext) av_register_all(); if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_MEMORY) { - if (mmfile_util_get_mimetype(formatContext->filesrc->memory.format, mimeType, MMFILE_MIMETYPE_MAX_LEN) < 0) { - debug_error(DEBUG, "error: Error in MIME Type finding\n"); + if (mmfile_util_get_mimetype(formatContext->filesrc->memory.format, mimeType, MMFILE_MIMETYPE_MAX_LEN) != MMFILE_UTIL_SUCCESS) { + debug_error(DEBUG, "error: Error in MIME Type finding"); 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) { - debug_error(DEBUG, "error: mmfile_util_get_ffmpeg_format\n"); + if (mmfile_util_get_ffmpeg_format(mimeType, ffmpegFormatName) != MMFILE_UTIL_SUCCESS) { + debug_error(DEBUG, "error: mmfile_util_get_ffmpeg_format"); return MMFILE_FORMAT_FAIL; } grab_iformat = av_find_input_format(ffmpegFormatName); - - if (NULL == grab_iformat) { - debug_error(DEBUG, "error: cannot find format\n"); - goto exception; - } + mm_file_retvm_if_fails(DEBUG, grab_iformat, MMFILE_UTIL_FAIL); avio_ctx_buffer = av_malloc(MMFILE_AVIO_BUFFER_LEN); - if (avio_ctx_buffer == NULL) { - debug_error(DEBUG, "error: cannot alloc avio_ctx_buffert\n"); - goto exception; - } + mm_file_retvm_if_fails(DEBUG, avio_ctx_buffer, MMFILE_UTIL_FAIL); - ret = _mmf_mem_open(&handle, formatContext->uriFileName); - if (ret != MMFILE_UTIL_SUCCESS) { - debug_warning(DEBUG, "failed to _mmf_mem_open.\n"); + if (__mmf_mem_open(&handle, formatContext->uriFileName)) { + debug_error(DEBUG, "failed to _mmf_mem_open."); goto exception; } - pIOCtx = avio_alloc_context(avio_ctx_buffer, MMFILE_AVIO_BUFFER_LEN, 0, handle, _mmf_mem_read, NULL, _mmf_mem_seek); - if (pIOCtx == NULL) { - debug_error(DEBUG, "error: cannot alloc io context\n"); + pIOCtx = avio_alloc_context(avio_ctx_buffer, MMFILE_AVIO_BUFFER_LEN, 0, handle, __mmf_mem_read, NULL, __mmf_mem_seek); + if (!pIOCtx) { + debug_error(DEBUG, "error: cannot alloc io context"); goto exception; } pFormatCtx = avformat_alloc_context(); - if (pFormatCtx == NULL) { - debug_warning(DEBUG, "failed to avformat_alloc_context\n"); + if (!pFormatCtx) { + debug_error(DEBUG, "failed to avformat_alloc_context"); goto exception; } pFormatCtx->pb = pIOCtx; - ret = avformat_open_input(&pFormatCtx, "", grab_iformat, NULL); - if (ret < 0) { - debug_error(DEBUG, "error: cannot open %s %d\n", formatContext->uriFileName, ret); + if (avformat_open_input(&pFormatCtx, "", grab_iformat, NULL) < 0) { + debug_error(DEBUG, "error: cannot open %s", formatContext->uriFileName); goto exception; } @@ -304,26 +373,24 @@ int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext) } if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_FILE) { - - ret = avformat_open_input(&pFormatCtx, formatContext->filesrc->file.path, NULL, NULL); - if (ret < 0) { - debug_error(DEBUG, "error: cannot open %s %d\n", formatContext->filesrc->file.path, ret); + if (avformat_open_input(&pFormatCtx, formatContext->filesrc->file.path, NULL, NULL) < 0) { + debug_error(DEBUG, "error: cannot open %s", formatContext->filesrc->file.path); goto exception; } formatContext->privateFormatData = pFormatCtx; } - if (!pFormatCtx/* || !(pFormatCtx->nb_streams > 0)*/) { - debug_warning(DEBUG, "failed to find av stream. maybe corrupted data.\n"); + if (!pFormatCtx) { + debug_warning(DEBUG, "failed to find av stream. maybe corrupted data."); goto exception; } - debug_msg(RELEASE, "number of stream: %d\n", pFormatCtx->nb_streams); + debug_msg(RELEASE, "number of stream: %d", pFormatCtx->nb_streams); __count_stream_num(pFormatCtx, formatContext); - debug_msg(RELEASE, "format: %s (%s)\n", pFormatCtx->iformat->name, pFormatCtx->iformat->long_name); + debug_msg(RELEASE, "format: %s (%s)", pFormatCtx->iformat->name, pFormatCtx->iformat->long_name); #ifdef __MMFILE_TEST_MODE__ av_dump_format(pFormatCtx, 0, formatContext->filesrc->file.path, 0); #endif @@ -350,11 +417,27 @@ exception: /* fail to get content information */ return MMFILE_FORMAT_FAIL; } -static bool __check_uhqa(int sample_rate, enum AVSampleFormat sample_fmt_info) +static int __get_video_fps(int frame_cnt, int duration, AVRational r_frame_rate, int is_roundup) +{ + double fps, round; + + debug_msg(RELEASE, "frame count: %d, dur: %d, num: %d, den: %d", frame_cnt, duration, r_frame_rate.num, r_frame_rate.den); + + if (duration <= 0 || r_frame_rate.num <= 0 || r_frame_rate.den <= 0) + return 0; + + round = (is_roundup != 0 ? 0.50f : 0.00f); + + fps = (double)frame_cnt / ((double)(duration * r_frame_rate.num) / r_frame_rate.den) + round; + + return (int)fps; +} + +static bool __check_uhqa(int sample_rate, enum AVSampleFormat sample_fmt_info) { debug_error(RELEASE, "[sample rate %d, sample format %d]", sample_rate, sample_fmt_info); - if ((sample_rate >= 44100) && (sample_fmt_info >= AV_SAMPLE_FMT_S32)) { + if (sample_rate >= 44100 && sample_fmt_info >= AV_SAMPLE_FMT_S32) { debug_msg(RELEASE, "UHQA CONTENT"); return true; } @@ -362,7 +445,6 @@ static bool __check_uhqa(int sample_rate, enum AVSampleFormat sample_fmt_info) return false; } - int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext) { AVFormatContext *pFormatCtx = NULL; @@ -371,7 +453,6 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext) MMFileFormatStream *videoStream = NULL; MMFileFormatStream *audioStream = NULL; unsigned int i = 0; - int ret = 0; mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL); mm_file_retvm_if_fails(DEBUG, formatContext->privateFormatData, MMFILE_FORMAT_FAIL); @@ -386,24 +467,21 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext) if (formatContext->formatType == MM_FILE_FORMAT_M2TS) pFormatCtx->max_analyze_duration = 100000; // MPEGTS file timeout set - if (formatContext->cdis != 1) - ret = avformat_find_stream_info(pFormatCtx, NULL); - else - ret = 0; - - if (ret < 0) { - debug_warning(DEBUG, "failed to find stream info. errcode = %d\n", ret); - goto exception; + if (formatContext->cdis != 1) { + if (avformat_find_stream_info(pFormatCtx, NULL) < 0) { + debug_warning(DEBUG, "failed to find stream info"); + goto exception; + } } - debug_msg(RELEASE, "FFMPEG: dur %"PRId64", start %"PRId64"\n", pFormatCtx->duration, pFormatCtx->start_time); + debug_msg(RELEASE, "FFMPEG: dur %"PRId64", start %"PRId64"", pFormatCtx->duration, pFormatCtx->start_time); /** *@note asf has long duration bug. and Some content's start time is wrong(negative number). * Generally, mpegts has wrong start time(positive large value). So skip start time for mpegts format. */ if (pFormatCtx->start_time < 0 || formatContext->formatType == MM_FILE_FORMAT_M2TS) { - debug_warning(DEBUG, "Wrong Start time = %"PRId64"\n", pFormatCtx->start_time); + debug_warning(DEBUG, "Wrong Start time = %"PRId64"", pFormatCtx->start_time); formatContext->duration = (long long)(pFormatCtx->duration) * 1000 / AV_TIME_BASE; } else { formatContext->duration = (long long)(pFormatCtx->duration + pFormatCtx->start_time) * 1000 / AV_TIME_BASE; @@ -416,81 +494,72 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext) formatContext->audioTotalTrackNum = 0; for (i = 0; i < pFormatCtx->nb_streams; i++) { - if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - if (formatContext->videoStreamId == -1) { - videoStream = g_new0(MMFileFormatStream, 1); - - videoStream->streamType = MMFILE_VIDEO_STREAM; - formatContext->streams[MMFILE_VIDEO_STREAM] = videoStream; - formatContext->nbStreams += 1; - formatContext->videoStreamId = i; - formatContext->videoTotalTrackNum += 1; - - pVideoCodecCtx = pFormatCtx->streams[i]->codecpar; - if (pVideoCodecCtx) { - videoStream->codecId = ConvertVideoCodecEnum(pVideoCodecCtx->codec_id); - if (videoStream->codecId == MM_VIDEO_CODEC_NONE) { - debug_error(RELEASE, "Proper codec is not found in [%d] stream", i); - formatContext->videoStreamId = -1; - mmfile_free(videoStream); - formatContext->streams[MMFILE_VIDEO_STREAM] = NULL; - videoStream = NULL; - continue; - } + if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && formatContext->videoStreamId == -1) { + videoStream = g_new0(MMFileFormatStream, 1); + + videoStream->streamType = MMFILE_VIDEO_STREAM; + formatContext->streams[MMFILE_VIDEO_STREAM] = videoStream; + formatContext->nbStreams += 1; + formatContext->videoStreamId = i; + formatContext->videoTotalTrackNum += 1; - /** - * Get FPS - * 1. try to get average fps of video stream. - * 2. if (1) failed, try to get fps of media container. - */ - videoStream->framePerSec = _get_video_fps(pFormatCtx->streams[i]->nb_frames, - pFormatCtx->streams[i]->duration, - pFormatCtx->streams[i]->time_base, - 1); - - if (videoStream->framePerSec == 0) { + pVideoCodecCtx = pFormatCtx->streams[i]->codecpar; + if (pVideoCodecCtx) { + videoStream->codecId = __convert_vidio_codec_type(pVideoCodecCtx->codec_id); + if (videoStream->codecId == MM_VIDEO_CODEC_NONE) { + debug_error(RELEASE, "Proper codec is not found in [%d] stream", i); + formatContext->videoStreamId = -1; + mmfile_free(videoStream); + formatContext->streams[MMFILE_VIDEO_STREAM] = NULL; + videoStream = NULL; + continue; + } + + /** + * Get FPS + * 1. try to get average fps of video stream. + * 2. if (1) failed, try to get fps of media container. + */ + videoStream->framePerSec = __get_video_fps(pFormatCtx->streams[i]->nb_frames, + 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); + videoStream->framePerSec = av_q2d(pFormatCtx->streams[i]->r_frame_rate); #else - videoStream->framePerSec = av_q2d(pFormatCtx->streams[i]->avg_frame_rate); + videoStream->framePerSec = av_q2d(pFormatCtx->streams[i]->avg_frame_rate); #endif - } - - videoStream->width = pVideoCodecCtx->width; - videoStream->height = pVideoCodecCtx->height; - videoStream->bitRate = pVideoCodecCtx->bit_rate; } + + videoStream->width = pVideoCodecCtx->width; + videoStream->height = pVideoCodecCtx->height; + videoStream->bitRate = pVideoCodecCtx->bit_rate; } - } else if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - if (formatContext->audioStreamId == -1) { - audioStream = g_new0(MMFileFormatStream, 1); - - audioStream->streamType = MMFILE_AUDIO_STREAM; - formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream; - formatContext->nbStreams += 1; - formatContext->audioStreamId = i; - formatContext->audioTotalTrackNum += 1; - - pAudioCodecCtx = pFormatCtx->streams[i]->codecpar; - if (pAudioCodecCtx) { - audioStream->codecId = ConvertAudioCodecEnum(pAudioCodecCtx->codec_id); - audioStream->bitRate = pAudioCodecCtx->bit_rate; - audioStream->nbChannel = pAudioCodecCtx->channels; - audioStream->samplePerSec = pAudioCodecCtx->sample_rate; -#if 0 - if (audioStream->codecId == MM_AUDIO_CODEC_FLAC) - audioStream->bitPerSample = pAudioCodecCtx->bits_per_raw_sample; - else -#endif - audioStream->bitPerSample = pAudioCodecCtx->bits_per_coded_sample; - audioStream->is_uhqa = __check_uhqa(audioStream->samplePerSec, pFormatCtx->streams[i]->codecpar->format); - } + } else if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && formatContext->audioStreamId == -1) { + audioStream = g_new0(MMFileFormatStream, 1); + + audioStream->streamType = MMFILE_AUDIO_STREAM; + formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream; + formatContext->nbStreams += 1; + formatContext->audioStreamId = i; + formatContext->audioTotalTrackNum += 1; + + pAudioCodecCtx = pFormatCtx->streams[i]->codecpar; + if (pAudioCodecCtx) { + audioStream->codecId = __convert_audio_codec_type(pAudioCodecCtx->codec_id); + audioStream->bitRate = pAudioCodecCtx->bit_rate; + audioStream->nbChannel = pAudioCodecCtx->channels; + audioStream->samplePerSec = pAudioCodecCtx->sample_rate; + audioStream->bitPerSample = pAudioCodecCtx->bits_per_coded_sample; + audioStream->is_uhqa = __check_uhqa(audioStream->samplePerSec, pFormatCtx->streams[i]->codecpar->format); } } } if (formatContext->nbStreams == 0) { - debug_error(DEBUG, "error: there is no audio and video track\n"); + debug_error(DEBUG, "error: there is no audio and video track"); goto exception; } @@ -520,13 +589,14 @@ exception: } #define DATA_LENGTH 4 -#define POS_OF_MIME_LEN DATA_LENGTH #define CONVERT_TO_INT(dest, src) {dest = 0; dest |= (0 | src[0] << 24) | (0 | src[1] << 16) | (0 | src[2] << 8) | (0 | src[3]); } static void __fill_picture_in_context(char *value, MMFileFormatContext *formatContext) { gsize len = 0; guchar *meta_data = NULL; + int current_pos = DATA_LENGTH; + unsigned char current_data[DATA_LENGTH] = {0, }; meta_data = g_base64_decode(value, &len); if (!meta_data) { @@ -534,43 +604,29 @@ static void __fill_picture_in_context(char *value, MMFileFormatContext *formatCo return; } - /* in METADATA_BLOCK_PICTURE, - the length of mime type and the length of description are flexible, - so, we have to get the length of their for getting correct postion of picture data. */ - int mime_len = 0; - int description_len = 0; - int data_len = 0; - int current_pos = 0; - unsigned char current_data[DATA_LENGTH] = {0}; - - /* get length of mime_type */ - memcpy(current_data, meta_data + POS_OF_MIME_LEN, DATA_LENGTH); - CONVERT_TO_INT(mime_len, current_data); - - /* get length of description */ - current_pos = mime_len + (DATA_LENGTH * 2); /*current position is length of description */ + /* get mime_type */ memcpy(current_data, meta_data + current_pos, DATA_LENGTH); - CONVERT_TO_INT(description_len, current_data); + CONVERT_TO_INT(len, current_data); + + current_pos += DATA_LENGTH; + mmfile_free(formatContext->artworkMime); + formatContext->artworkMime = g_strndup((const char *)meta_data + current_pos, len); - /* get length of picture data */ - current_pos = mime_len + description_len + (DATA_LENGTH * 7); /*current position is length of picture data */ + /* get description */ + current_pos += len; memcpy(current_data, meta_data + current_pos, DATA_LENGTH); - CONVERT_TO_INT(data_len, current_data); + CONVERT_TO_INT(len, current_data); - /* set the size of art work */ - formatContext->artworkSize = data_len; + /* get picture data */ + current_pos += len + (DATA_LENGTH * 5); + memcpy(current_data, meta_data + current_pos, DATA_LENGTH); + CONVERT_TO_INT(len, current_data); - /* set mime type */ - current_pos = POS_OF_MIME_LEN + DATA_LENGTH; /*current position is mime type */ - mmfile_free(formatContext->artworkMime); - formatContext->artworkMime = strndup((const char *)meta_data + current_pos, mime_len); + formatContext->artworkSize = len; - /* set art work data */ - current_pos = mime_len + description_len + (DATA_LENGTH * 8); /*current position is picture data */ + current_pos += DATA_LENGTH; mmfile_free(formatContext->artwork); - - formatContext->artwork = g_memdup(meta_data + current_pos, data_len); - + formatContext->artwork = g_memdup(meta_data + current_pos, formatContext->artworkSize); g_free(meta_data); } @@ -579,9 +635,8 @@ static void __fill_artwork_in_context(AVStream *st, MMFileFormatContext *formatC AVPacket pkt = st->attached_pic; int codec_id = st->codecpar->codec_id; - if (!pkt.data || pkt.size <= 0) { + if (!pkt.data || pkt.size <= 0) return; - } /*Set mime type*/ mmfile_free(formatContext->artworkMime); @@ -593,7 +648,7 @@ static void __fill_artwork_in_context(AVStream *st, MMFileFormatContext *formatC else if (codec_id == AV_CODEC_ID_BMP) formatContext->artworkMime = g_strdup("image/bmp"); else - debug_error(DEBUG, "Unknown cover type: 0x%x\n", codec_id); + debug_error(DEBUG, "Unknown cover type: 0x%x", codec_id); /*Copy artwork*/ mmfile_free(formatContext->artwork); @@ -607,9 +662,8 @@ static void __fill_metainfo_in_context(AVDictionary *metainfo, MMFileFormatConte AVDictionaryEntry *tag = NULL; while ((tag = av_dict_get(metainfo, "", tag, AV_DICT_IGNORE_SUFFIX))) { - if (!tag->key) { + if (!tag->key) continue; - } if (!g_ascii_strcasecmp(tag->key, "title")) { mmfile_free(formatContext->title); @@ -666,21 +720,17 @@ static void __fill_metainfo_in_context(AVDictionary *metainfo, MMFileFormatConte int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext) { - AVFormatContext *pFormatCtx = NULL; + AVFormatContext *pFormatCtx = NULL; unsigned int idx = 0; - if (!formatContext || !formatContext->privateFormatData) { - debug_error(DEBUG, "invalid param\n"); - return MMFILE_FORMAT_FAIL; - } + mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL); + mm_file_retvm_if_fails(DEBUG, formatContext->privateFormatData, MMFILE_FORMAT_FAIL); - if (formatContext->formatType == MM_FILE_FORMAT_3GP || formatContext->formatType == MM_FILE_FORMAT_MP4) { + if (formatContext->formatType == MM_FILE_FORMAT_3GP || formatContext->formatType == MM_FILE_FORMAT_MP4) MMFileUtilGetMetaDataFromMP4(formatContext); - } - if (formatContext->formatType == MM_FILE_FORMAT_MATROSKA) { + if (formatContext->formatType == MM_FILE_FORMAT_MATROSKA) MMFileUtilGetMetaDataFromMKV(formatContext); - } pFormatCtx = formatContext->privateFormatData; @@ -719,8 +769,6 @@ int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext) return MMFILE_FORMAT_SUCCESS; } - - int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame) { AVFormatContext *pFormatCtx = NULL; @@ -734,158 +782,138 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned int numBytes = 0; int ret = 0; - if (NULL == formatContext || - NULL == frame || - NULL == formatContext->privateFormatData || - formatContext->videoTotalTrackNum <= 0) { - - debug_error(DEBUG, "invalid param\n"); - return MMFILE_FORMAT_FAIL; - } + mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL); + mm_file_retvm_if_fails(DEBUG, formatContext->privateFormatData, MMFILE_FORMAT_FAIL); + mm_file_retvm_if_fails(DEBUG, formatContext->videoTotalTrackNum > 0, MMFILE_FORMAT_FAIL); + mm_file_retvm_if_fails(DEBUG, frame, MMFILE_FORMAT_FAIL); pFormatCtx = formatContext->privateFormatData; - if (formatContext->videoStreamId != -1) { - pVideoCodecPar = pFormatCtx->streams[formatContext->videoStreamId]->codecpar; - if (NULL == pVideoCodecPar) { - debug_error(DEBUG, "invalid param\n"); - return MMFILE_FORMAT_FAIL; - } - - pVideoCodec = avcodec_find_decoder(pVideoCodecPar->codec_id); - if (NULL == pVideoCodec) { - debug_error(DEBUG, "error: avcodec_find_decoder failed\n"); - return MMFILE_FORMAT_FAIL; - } + mm_file_retvm_if_fails(DEBUG, formatContext->videoStreamId != -1, MMFILE_FORMAT_FAIL); - pVideoCodecCtx = avcodec_alloc_context3(pVideoCodec); - if (NULL == pVideoCodecCtx) { - debug_error(DEBUG, "error: avcodec_alloc_context3 failed\n"); - return MMFILE_FORMAT_FAIL; - } + pVideoCodecPar = pFormatCtx->streams[formatContext->videoStreamId]->codecpar; + mm_file_retvm_if_fails(DEBUG, pVideoCodecPar, MMFILE_FORMAT_FAIL); - ret = avcodec_parameters_to_context(pVideoCodecCtx, pVideoCodecPar); - if (ret < 0) { - debug_error(DEBUG, "error: avcodec_parameters_to_context\n"); - avcodec_free_context(&pVideoCodecCtx); - return MMFILE_FORMAT_FAIL; - } - - debug_msg(RELEASE, "flag: 0x%08X\n", pVideoCodec->capabilities); - /* debug_msg(RELEASE, " DRAW_HORIZ_BAND : %d\n", pVideoCodec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND ? 1 : 0); */ - /* debug_msg(RELEASE, " DR1 : %d\n", pVideoCodec->capabilities & CODEC_CAP_DR1 ? 1 : 0); */ - /* debug_msg(RELEASE, " PARSE_ONLY : %d\n", pVideoCodec->capabilities & CODEC_CAP_PARSE_ONLY ? 1 : 0); */ - /* debug_msg(RELEASE, " TRUNCATED : %d\n", pVideoCodec->capabilities & CODEC_CAP_TRUNCATED ? 1 : 0); */ - /* debug_msg(RELEASE, " HWACCEL : %d\n", pVideoCodec->capabilities & CODEC_CAP_HWACCEL ? 1 : 0); */ - /* debug_msg(RELEASE, " DELAY : %d\n", pVideoCodec->capabilities & CODEC_CAP_DELAY ? 1 : 0); */ - /* debug_msg(RELEASE, " SMALL_LAST_FRAME: %d\n", pVideoCodec->capabilities & CODEC_CAP_SMALL_LAST_FRAME ? 1 : 0); */ - /* debug_msg(RELEASE, " HWACCEL_VDPAU : %d\n", pVideoCodec->capabilities & CODEC_CAP_HWACCEL_VDPAU ? 1 : 0); */ - - if (pVideoCodec->capabilities & CODEC_CAP_TRUNCATED) { - pVideoCodecCtx->flags |= CODEC_FLAG_TRUNCATED; - } + pVideoCodec = avcodec_find_decoder(pVideoCodecPar->codec_id); + mm_file_retvm_if_fails(DEBUG, pVideoCodec, MMFILE_FORMAT_FAIL); - /*set workaround bug flag*/ - pVideoCodecCtx->workaround_bugs = FF_BUG_AUTODETECT; + pVideoCodecCtx = avcodec_alloc_context3(pVideoCodec); + mm_file_retvm_if_fails(DEBUG, pVideoCodecCtx, MMFILE_FORMAT_FAIL); - /* 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); - if (ret < 0) { - debug_error(DEBUG, "error: avcodec_open fail.\n"); - return MMFILE_FORMAT_FAIL; - } + if (avcodec_parameters_to_context(pVideoCodecCtx, pVideoCodecPar) < 0) { + debug_error(DEBUG, "error: avcodec_parameters_to_context"); + avcodec_free_context(&pVideoCodecCtx); + return MMFILE_FORMAT_FAIL; + } - /* 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, formatContext->cdis); - if (ret != MMFILE_FORMAT_SUCCESS) { - debug_error(DEBUG, "error: get key frame\n"); - ret = MMFILE_FORMAT_FAIL; - goto exception; - } + debug_msg(RELEASE, "flag: 0x%08X", pVideoCodec->capabilities); + /* debug_msg(RELEASE, " DRAW_HORIZ_BAND : %d", pVideoCodec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND ? 1 : 0); */ + /* debug_msg(RELEASE, " DR1 : %d", pVideoCodec->capabilities & CODEC_CAP_DR1 ? 1 : 0); */ + /* debug_msg(RELEASE, " PARSE_ONLY : %d", pVideoCodec->capabilities & CODEC_CAP_PARSE_ONLY ? 1 : 0); */ + /* debug_msg(RELEASE, " TRUNCATED : %d", pVideoCodec->capabilities & CODEC_CAP_TRUNCATED ? 1 : 0); */ + /* debug_msg(RELEASE, " HWACCEL : %d", pVideoCodec->capabilities & CODEC_CAP_HWACCEL ? 1 : 0); */ + /* debug_msg(RELEASE, " DELAY : %d", pVideoCodec->capabilities & CODEC_CAP_DELAY ? 1 : 0); */ + /* debug_msg(RELEASE, " SMALL_LAST_FRAME: %d", pVideoCodec->capabilities & CODEC_CAP_SMALL_LAST_FRAME ? 1 : 0); */ + /* debug_msg(RELEASE, " HWACCEL_VDPAU : %d", pVideoCodec->capabilities & CODEC_CAP_HWACCEL_VDPAU ? 1 : 0); */ + + if (pVideoCodec->capabilities & CODEC_CAP_TRUNCATED) + pVideoCodecCtx->flags |= CODEC_FLAG_TRUNCATED; + + /*set workaround bug flag*/ + pVideoCodecCtx->workaround_bugs = FF_BUG_AUTODETECT; + + /* 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; + if (avcodec_open2(pVideoCodecCtx, pVideoCodec, NULL) < 0) { + debug_error(DEBUG, "error: avcodec_open fail."); + return MMFILE_FORMAT_FAIL; + } - debug_msg(RELEASE, "Video default resolution = [%dx%d]\n", pVideoCodecCtx->coded_width, pVideoCodecCtx->coded_height); - debug_msg(RELEASE, "Video coded resolution = [%dx%d]\n", pVideoCodecCtx->width, pVideoCodecCtx->height); + /* search & decode */ + ret = _get_first_good_video_frame(pFormatCtx, pVideoCodecCtx, formatContext->videoStreamId, &pFrame, formatContext->cdis); + if (ret != MMFILE_FORMAT_SUCCESS) { + debug_error(DEBUG, "error: get key frame"); + ret = MMFILE_FORMAT_FAIL; + goto exception; + } - /*sometimes, ffmpeg's width/height is wrong*/ -#if 0 /*coded_width/height sometimes wrong. so use width/height*/ - width = pVideoCodecCtx->coded_width == 0 ? pVideoCodecCtx->width : pVideoCodecCtx->coded_width; - height = pVideoCodecCtx->coded_height == 0 ? pVideoCodecCtx->height : pVideoCodecCtx->coded_height; -#endif - if ((pVideoCodecCtx->width == 0) || (pVideoCodecCtx->height == 0)) { - width = pVideoCodecCtx->coded_width; - height = pVideoCodecCtx->coded_height; - } else { - width = pVideoCodecCtx->width; - height = pVideoCodecCtx->height; - } + debug_msg(RELEASE, "Video default resolution = [%dx%d]", pVideoCodecCtx->coded_width, pVideoCodecCtx->coded_height); + debug_msg(RELEASE, "Video coded resolution = [%dx%d]", pVideoCodecCtx->width, pVideoCodecCtx->height); - numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, height, 1); - if (numBytes <= 0) { - debug_error(DEBUG, "error: av_image_get_buffer_size. [%d x %d]\n", width, height); - ret = MMFILE_FORMAT_FAIL; - goto exception; - } + if ((pVideoCodecCtx->width == 0) || (pVideoCodecCtx->height == 0)) { + width = pVideoCodecCtx->coded_width; + height = pVideoCodecCtx->coded_height; + } else { + width = pVideoCodecCtx->width; + height = pVideoCodecCtx->height; + } - frame->frameData = g_malloc0(numBytes); + numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, height, 1); + if (numBytes <= 0) { + debug_error(DEBUG, "error: av_image_get_buffer_size. [%d x %d]", width, height); + ret = MMFILE_FORMAT_FAIL; + goto exception; + } - uint8_t *dst_data[4]; - int dst_linesize[4]; + frame->frameData = g_malloc0(numBytes); - ret = av_image_fill_arrays(dst_data, dst_linesize, frame->frameData, AV_PIX_FMT_RGB24, width, height, 1); - if (ret < 0) { - debug_error(DEBUG, "error: avpicture_fill fail. errcode = 0x%08X\n", ret); - ret = MMFILE_FORMAT_FAIL; - goto exception; - } + uint8_t *dst_data[4]; + int dst_linesize[4]; - struct SwsContext *img_convert_ctx = NULL; + ret = av_image_fill_arrays(dst_data, dst_linesize, frame->frameData, AV_PIX_FMT_RGB24, width, height, 1); + if (ret < 0) { + debug_error(DEBUG, "error: avpicture_fill fail. errcode = 0x%08X", ret); + ret = MMFILE_FORMAT_FAIL; + goto exception; + } - img_convert_ctx = sws_getContext(width, height, pVideoCodecCtx->pix_fmt, width, height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); + struct SwsContext *img_convert_ctx = NULL; - if (NULL == img_convert_ctx) { - debug_error(DEBUG, "failed to get img convet ctx\n"); - ret = MMFILE_FORMAT_FAIL; - goto exception; - } + img_convert_ctx = sws_getContext(width, height, pVideoCodecCtx->pix_fmt, width, height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); - ret = sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize, 0, height, dst_data, dst_linesize); - if (ret < 0) { - debug_error(DEBUG, "failed to convet image\n"); - ret = MMFILE_FORMAT_FAIL; - sws_freeContext(img_convert_ctx); - img_convert_ctx = NULL; - goto exception; - } + if (NULL == img_convert_ctx) { + debug_error(DEBUG, "failed to get img convet ctx"); + ret = MMFILE_FORMAT_FAIL; + goto exception; + } + ret = sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize, 0, height, dst_data, dst_linesize); + if (ret < 0) { + debug_error(DEBUG, "failed to convet image"); + ret = MMFILE_FORMAT_FAIL; sws_freeContext(img_convert_ctx); img_convert_ctx = NULL; + goto exception; + } - frame->frameSize = numBytes; - frame->frameWidth = width; - frame->frameHeight = height; - frame->configLenth = 0; + sws_freeContext(img_convert_ctx); + img_convert_ctx = NULL; - if (pFrame) av_frame_free(&pFrame); + frame->frameSize = numBytes; + frame->frameWidth = width; + frame->frameHeight = height; + frame->configLenth = 0; - avcodec_free_context(&pVideoCodecCtx); + if (pFrame) + av_frame_free(&pFrame); - return MMFILE_FORMAT_SUCCESS; - } + avcodec_free_context(&pVideoCodecCtx); + return MMFILE_FORMAT_SUCCESS; exception: - if (pVideoCodecCtx) avcodec_free_context(&pVideoCodecCtx); + if (pVideoCodecCtx) + avcodec_free_context(&pVideoCodecCtx); mmfile_free(frame->frameData); - if (pFrame) av_frame_free(&pFrame); + if (pFrame) + av_frame_free(&pFrame); - return ret; + return MMFILE_FORMAT_FAIL; } @@ -928,13 +956,10 @@ static unsigned int _diff_memory(const void *s1, const void *s2, unsigned int n) return ret; } - -#define IS_GOOD_OLD_METHOD -#ifdef IS_GOOD_OLD_METHOD /** * compare with center line. */ -static int _is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize) +static int __is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize) { #define _MM_CHUNK_NUM 8 /*FIXME*/ #define _MM_CHUNK_LIMIT (_MM_CHUNK_NUM / 2) @@ -953,7 +978,7 @@ static int _is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize) cnt_offset = (ysize / 2); cnt = buf + cnt_offset * wrap; - debug_msg(RELEASE, "checking frame. %p, %d, %d, %d\n", buf, wrap, xsize, ysize); + debug_msg(RELEASE, "checking frame. %p, %d, %d, %d", buf, wrap, xsize, ysize); /*if too small, always ok return.*/ if (ysize < _MM_CHUNK_NUM) @@ -967,14 +992,14 @@ static int _is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize) point += (is_different == 0 ? 0 : 1); sum_diff += is_different; - debug_msg(RELEASE, "check %04d line. %s [%d]\n", i, (is_different == 0 ? "same" : "different"), is_different); + debug_msg(RELEASE, "check %04d line. %s [%d]", i, (is_different == 0 ? "same" : "different"), is_different); if (point >= _MM_CHUNK_LIMIT) { if (sum_diff > _MM_CHUNK_DIFF_LIMIT) { - debug_msg(RELEASE, "Good :-)\n"); + debug_msg(RELEASE, "Good :-)"); return 1; } else { - debug_msg(RELEASE, "Bad :-(\n"); + debug_msg(RELEASE, "Bad :-("); return 0; } } @@ -983,28 +1008,6 @@ static int _is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize) } return 0; } -#else /* IS_GOOD_OLD_METHOD */ -/* ToDo : for enhancement */ -#endif /* IS_GOOD_OLD_METHOD */ - - - -static int -_get_video_fps(int frame_cnt, int duration, AVRational r_frame_rate, int is_roundup) -{ - double fps, round; - - debug_msg(RELEASE, "frame count: %d, dur: %d, num: %d, den: %d\n", frame_cnt, duration, r_frame_rate.num, r_frame_rate.den); - - if (duration <= 0 || r_frame_rate.num <= 0 || r_frame_rate.den <= 0) - return 0; - - round = (is_roundup != 0 ? 0.50f : 0.00f); - - fps = (double)frame_cnt / ((double)(duration * r_frame_rate.num) / r_frame_rate.den) + round; - - return (int)fps; -} #ifdef MMFILE_FORMAT_DEBUG_DUMP static void _save_pgm(unsigned char *buf, int wrap, int xsize, int ysize, char *filename) @@ -1022,26 +1025,16 @@ static void _save_pgm(unsigned char *buf, int wrap, int xsize, int ysize, char * } #endif -#ifdef __MMFILE_TEST_MODE__ -static void _dump_av_packet(AVPacket *pkt) -{ - debug_msg(RELEASE, "--------- AV Packet -----------\n"); - debug_msg(RELEASE, " pts: %lld\n", pkt->pts); - debug_msg(RELEASE, " dts: %lld\n", pkt->dts); - debug_msg(RELEASE, " data: %p\n", pkt->data); - debug_msg(RELEASE, " size: %d\n", pkt->size); - debug_msg(RELEASE, " stream_index: %d\n", pkt->stream_index); - debug_msg(RELEASE, " flags: 0x%08X, %s\n", pkt->flags, (pkt->flags & AV_PKT_FLAG_KEY) ? "Keyframe" : "_"); - debug_msg(RELEASE, " duration: %lld\n", pkt->duration); - /*debug_msg(RELEASE, " destruct: %p\n", pkt->destruct);*/ - /*debug_msg(RELEASE, " priv: %p\n", pkt->priv);*/ - debug_msg(RELEASE, " pos: %lld\n", pkt->pos); - debug_msg(RELEASE, "-------------------------------\n"); -} -#endif - static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame **pFrame, int cdis) { +#define _RETRY_SEARCH_LIMIT 250 +#define _KEY_SEARCH_LIMIT (_RETRY_SEARCH_LIMIT*2) /*2 = 1 read. some frame need to read one more*/ +#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 + /* AVStream *st = NULL; */ AVPacket pkt; @@ -1059,56 +1052,42 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte #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 250 -#define _KEY_SEARCH_LIMIT (_RETRY_SEARCH_LIMIT*2) /*2 = 1 read. some frame need to read one more*/ -#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 + int key_search_limit = (cdis == 1) ? _KEY_SEARCH_LIMIT_CDIS : _KEY_SEARCH_LIMIT; + int frame_search_limit = (cdis == 1) ? _FRAME_SEARCH_LIMIT_CDIS : _FRAME_SEARCH_LIMIT; first_frame = av_frame_alloc(); tmp_frame = av_frame_alloc(); if (!first_frame || !tmp_frame) { - debug_error(DEBUG, "failed to alloc frame.\n"); - if (first_frame) av_frame_free(&first_frame); - if (tmp_frame) av_frame_free(&tmp_frame); + debug_error(DEBUG, "failed to alloc frame."); + if (first_frame) + av_frame_free(&first_frame); + if (tmp_frame) + av_frame_free(&tmp_frame); + return MMFILE_FORMAT_FAIL; } - debug_msg(RELEASE, "frame: 1. %p, 2. %p\n", first_frame, tmp_frame); + debug_msg(RELEASE, "frame: 1. %p, 2. %p", first_frame, tmp_frame); pCodecCtx->skip_frame = AVDISCARD_BIDIR; - 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); ret = av_read_frame(pFormatCtx, &pkt); if (ret < 0) { - debug_error(DEBUG, "read failed. (maybe EOF or broken)\n"); + debug_error(DEBUG, "read failed. (maybe EOF or broken)"); break; } if (avcodec_get_type(pFormatCtx->streams[pkt.stream_index]->codecpar->codec_id) == AVMEDIA_TYPE_VIDEO) { v++; if ((pkt.flags & AV_PKT_FLAG_KEY) || (key_detected == 1)) { - debug_msg(RELEASE, "video frame: %d, %d, %d\n", retry, i, v); + debug_msg(RELEASE, "video frame: %d, %d, %d", retry, i, v); #ifdef __MMFILE_TEST_MODE__ _dump_av_packet(&pkt); #endif - i++; key_detected = 0; @@ -1120,10 +1099,10 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte len = avcodec_receive_frame(pCodecCtx, frame); if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) { - debug_warning(DEBUG, "Error while decoding frame %dth\n", i); + debug_warning(DEBUG, "Error while decoding frame %dth", i); } else if (len >= 0) { if (frame->key_frame) { - debug_msg(RELEASE, "key frame!\n"); + debug_msg(RELEASE, "key frame!"); #ifdef MMFILE_FORMAT_DEBUG_DUMP memset(pgm_name, 0x00, sizeof(pgm_name)); snprintf(pgm_name, sizeof(pgm_name), "./key_%d_%d_%d.pgm", retry, i, v); @@ -1132,14 +1111,14 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte found++; - ret = _is_good_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height); + ret = __is_good_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height); if (ret != 0) { - debug_msg(RELEASE, "is good frame.\n"); + debug_msg(RELEASE, "is good frame."); break; } /*reset video frame count & retry searching*/ - debug_warning(RELEASE, "not good fame. retry scanning.\n"); + debug_warning(RELEASE, "not good fame. retry scanning."); i = 0; v = 0; retry++; @@ -1148,10 +1127,11 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte frame = tmp_frame; /*limit of retry.*/ - if (retry > _RETRY_SEARCH_LIMIT) break; + if (retry > _RETRY_SEARCH_LIMIT) + break; } else { - debug_msg(RELEASE, "skip (not key frame).\n"); + debug_msg(RELEASE, "skip (not key frame)."); #ifdef MMFILE_FORMAT_DEBUG_DUMP memset(pgm_name, 0x00, sizeof(pgm_name)); snprintf(pgm_name, sizeof(pgm_name), "./not_key_%d_%d_%d.pgm", retry, i, v); @@ -1159,7 +1139,7 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte #endif } } else { - debug_msg(RELEASE, "decode not completed.\n"); + debug_msg(RELEASE, "decode not completed."); key_detected = 1; } } @@ -1171,196 +1151,31 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte /*free pkt after loop breaking*/ av_packet_unref(&pkt); - debug_msg(RELEASE, "found: %d, retry: %d\n", found, retry); + debug_msg(RELEASE, "found: %d, retry: %d", found, retry); /*set decode frame to output*/ if (found > 0) { ret = MMFILE_FORMAT_SUCCESS; if (retry == 0 || found == retry) { *pFrame = first_frame; - if (tmp_frame) av_frame_free(&tmp_frame); + if (tmp_frame) + av_frame_free(&tmp_frame); } else { *pFrame = tmp_frame; - if (first_frame) av_frame_free(&first_frame); + if (first_frame) + av_frame_free(&first_frame); } } else { ret = MMFILE_FORMAT_FAIL; - if (first_frame) av_frame_free(&first_frame); - if (tmp_frame) av_frame_free(&tmp_frame); + if (first_frame) + av_frame_free(&first_frame); + if (tmp_frame) + av_frame_free(&tmp_frame); } - debug_msg(RELEASE, "out frame: %p\n", *pFrame); + debug_msg(RELEASE, "out frame: %p", *pFrame); pCodecCtx->skip_frame = AVDISCARD_NONE; return ret; } - -static int ConvertVideoCodecEnum(int AVVideoCodecID) -{ - int ret_codecid = 0; - - switch (AVVideoCodecID) { - case AV_CODEC_ID_NONE: - ret_codecid = MM_VIDEO_CODEC_NONE; - break; - case AV_CODEC_ID_MPEG1VIDEO: - ret_codecid = MM_VIDEO_CODEC_MPEG1; - break; - case AV_CODEC_ID_MPEG2VIDEO: /*/< preferred ID for MPEG-1/2 video decoding */ - case AV_CODEC_ID_MPEG2VIDEO_XVMC: - case AV_CODEC_ID_MPEG2TS: - ret_codecid = MM_VIDEO_CODEC_MPEG2; - break; - case AV_CODEC_ID_H261: - ret_codecid = MM_VIDEO_CODEC_H261; - break; - case AV_CODEC_ID_H263: - ret_codecid = MM_VIDEO_CODEC_H263; - break; - case AV_CODEC_ID_MPEG4: - ret_codecid = MM_VIDEO_CODEC_MPEG4; - break; - case AV_CODEC_ID_MSMPEG4V1: - ret_codecid = MM_VIDEO_CODEC_MPEG4; - break; - case AV_CODEC_ID_MSMPEG4V2: - ret_codecid = MM_VIDEO_CODEC_MPEG4; - break; - case AV_CODEC_ID_MSMPEG4V3: - ret_codecid = MM_VIDEO_CODEC_MPEG4; - break; - case AV_CODEC_ID_WMV1: - ret_codecid = MM_VIDEO_CODEC_WMV; - break; - case AV_CODEC_ID_WMV2: - ret_codecid = MM_VIDEO_CODEC_WMV; - break; - case AV_CODEC_ID_H263P: - ret_codecid = MM_VIDEO_CODEC_H263; - break; - case AV_CODEC_ID_H263I: - ret_codecid = MM_VIDEO_CODEC_H263; - break; - case AV_CODEC_ID_FLV1: - ret_codecid = MM_VIDEO_CODEC_FLV; - break; - case AV_CODEC_ID_H264: - ret_codecid = MM_VIDEO_CODEC_H264; - break; - case AV_CODEC_ID_INDEO2: - case AV_CODEC_ID_INDEO3: - case AV_CODEC_ID_INDEO4: - case AV_CODEC_ID_INDEO5: - ret_codecid = MM_VIDEO_CODEC_INDEO; - break; - case AV_CODEC_ID_THEORA: - ret_codecid = MM_VIDEO_CODEC_THEORA; - break; - case AV_CODEC_ID_CINEPAK: - ret_codecid = MM_VIDEO_CODEC_CINEPAK; - break; - case AV_CODEC_ID_VC1: - ret_codecid = MM_VIDEO_CODEC_VC1; - break; - case AV_CODEC_ID_WMV3: - ret_codecid = MM_VIDEO_CODEC_WMV; - break; - case AV_CODEC_ID_AVS: - 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; -#ifdef __MMFILE_LIBAV_VERSION__ - case AV_CODEC_ID_HEVC: - ret_codecid = MM_VIDEO_CODEC_MPEG4; - break; -#endif -#ifdef USE_PRODUCT_FEATURE - case AV_CODEC_ID_VP8: - ret_codecid = MM_VIDEO_CODEC_VP8; - break; - case AV_CODEC_ID_VP9: - ret_codecid = MM_VIDEO_CODEC_VP9; - break; -#endif - default: - ret_codecid = MM_VIDEO_CODEC_NONE; - break; - } - - return ret_codecid; -} - - -static int ConvertAudioCodecEnum(int AVAudioCodecID) -{ - int ret_codecid = 0; - - switch (AVAudioCodecID) { - case AV_CODEC_ID_AMR_NB: - case AV_CODEC_ID_AMR_WB: - ret_codecid = MM_AUDIO_CODEC_AMR; - break; - /* RealAudio codecs*/ - 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: - ret_codecid = MM_AUDIO_CODEC_MP2; - break; - case AV_CODEC_ID_MP3: - case AV_CODEC_ID_MP3ADU: - case AV_CODEC_ID_MP3ON4: - ret_codecid = MM_AUDIO_CODEC_MP3; - break; - case AV_CODEC_ID_AAC: - ret_codecid = MM_AUDIO_CODEC_AAC; - break; - case AV_CODEC_ID_AC3: - ret_codecid = MM_AUDIO_CODEC_AC3; - break; - case AV_CODEC_ID_VORBIS: - ret_codecid = MM_AUDIO_CODEC_VORBIS; - break; - case AV_CODEC_ID_WMAV1: - case AV_CODEC_ID_WMAV2: - case AV_CODEC_ID_WMAVOICE: - case AV_CODEC_ID_WMAPRO: - case AV_CODEC_ID_WMALOSSLESS: - ret_codecid = MM_AUDIO_CODEC_WMA; - break; - case AV_CODEC_ID_FLAC: - ret_codecid = MM_AUDIO_CODEC_FLAC; - break; - case AV_CODEC_ID_ALAC: - ret_codecid = MM_AUDIO_CODEC_ALAC; - break; - case AV_CODEC_ID_WAVPACK: - ret_codecid = MM_AUDIO_CODEC_WAVE; - break; - case AV_CODEC_ID_ATRAC3: - case AV_CODEC_ID_ATRAC3P: - 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; - } - - return ret_codecid; -} diff --git a/formats/ffmpeg/mm_file_format_frame.c b/formats/ffmpeg/mm_file_format_frame.c index 92cc079..86917b4 100755 --- a/formats/ffmpeg/mm_file_format_frame.c +++ b/formats/ffmpeg/mm_file_format_frame.c @@ -54,13 +54,6 @@ static void __save_frame(int width, int height, unsigned char *frame, int size, } #endif -typedef struct { - unsigned char *ptr; - long long size; - long long offset; - int state; -} MMFmemIOHandle; - static bool __mmf_mem_open(MMFmemIOHandle **handle, const char *filename) { MMFmemIOHandle *memHandle = NULL; @@ -69,9 +62,8 @@ static bool __mmf_mem_open(MMFmemIOHandle **handle, const char *filename) filename += strlen(MMFILE_MEM_URI); splitedString = g_strsplit(filename, ":", -1); - mm_file_retvm_if_fails(DEBUG, splitedString, MMFILE_UTIL_FAIL); - if (!splitedString[0] || !splitedString[1]) { + if (g_strv_length(splitedString) < 2) { debug_error(DEBUG, "invalid param"); g_strfreev(splitedString); diff --git a/utils/include/mm_file_utils.h b/utils/include/mm_file_utils.h index 928428a..68f0de1 100755 --- a/utils/include/mm_file_utils.h +++ b/utils/include/mm_file_utils.h @@ -66,6 +66,13 @@ typedef struct MMFileIOHandle { char *fileName; } MMFileIOHandle; +typedef struct { + unsigned char *ptr; + long long size; + long long offset; + int state; +} MMFmemIOHandle; + /*////////////////////////////////////////////////////////////////////// */ /* FILE HEADER CHECK API // */ /*////////////////////////////////////////////////////////////////////// */ diff --git a/utils/mm_file_util_io_mem.c b/utils/mm_file_util_io_mem.c index f5583ec..7ff63a6 100755 --- a/utils/mm_file_util_io_mem.c +++ b/utils/mm_file_util_io_mem.c @@ -27,13 +27,6 @@ #include "mm_file_utils.h" -typedef struct { - unsigned char *ptr; - long long size; - long long offset; - int state; -} MMFmemIOHandle; - static int mmf_mem_open(MMFileIOHandle *handle, const char *filename, int flags) { MMFmemIOHandle *memHandle = NULL; -- 2.7.4