#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);
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;
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))
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;
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;
}
/*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;
{
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;
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
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;
}
}
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
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;
}
return false;
}
-
int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext)
{
AVFormatContext *pFormatCtx = NULL;
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);
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;
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;
}
}
#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) {
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);
}
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);
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);
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);
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;
return MMFILE_FORMAT_SUCCESS;
}
-
-
int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
{
AVFormatContext *pFormatCtx = NULL;
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;
}
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)
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)
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;
}
}
}
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)
}
#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;
#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;
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);
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++;
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);
#endif
}
} else {
- debug_msg(RELEASE, "decode not completed.\n");
+ debug_msg(RELEASE, "decode not completed.");
key_detected = 1;
}
}
/*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;
-}