#include <stdlib.h>
#include <libavformat/avformat.h>
-#include <libavformat/url.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <mm_error.h>
#include "mm_file_formats.h"
#include "mm_file_utils.h"
#include "mm_file_format_ffmpeg.h"
-#include "mm_file_format_ffmpeg_mem.h"
#include <sys/time.h>
#define _SHORT_MEDIA_LIMIT 2000 /* under X seconds duration*/
int mmfile_format_close_ffmpg(MMFileFormatContext *formatContext);
static int getMimeType(int formatId, char *mimeType, int buf_size);
+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 int _mmf_mem_open(MMFmemIOHandle **handle, const char *filename)
+{
+ MMFmemIOHandle *memHandle = NULL;
+ char **splitedString = NULL;
+
+ filename += strlen(MMFILE_MEM_URI);
+
+ splitedString = mmfile_strsplit(filename, ":");
+ if (splitedString == NULL) {
+ debug_error(DEBUG, "invalid param\n");
+ return MMFILE_IO_FAILED;
+ }
+
+ if (!splitedString[0] || !splitedString[1]) {
+ debug_error(DEBUG, "invalid param\n");
+ goto exception;
+ }
+
+ memHandle = mmfile_malloc(sizeof(MMFmemIOHandle));
+ if (!memHandle) {
+ debug_error(DEBUG, "error: mmfile_malloc memHandle\n");
+ goto exception;
+ }
+
+ memHandle->ptr = (unsigned char *)atoll(splitedString[0]); /*memory allocation address changed. memHandle->ptr = (unsigned char*)atoi(splitedString[0]); */
+ memHandle->size = atoi(splitedString[1]);
+ memHandle->offset = 0;
+ memHandle->state = 0;
+
+ *handle = memHandle;
+
+ if (splitedString) {
+ mmfile_strfreev(splitedString);
+ }
+
+ return MMFILE_IO_SUCCESS;
+
+exception:
+
+ if (splitedString) {
+ mmfile_strfreev(splitedString);
+ }
+
+ return MMFILE_IO_FAILED;
+}
+
+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;
+ }
+
+ 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;
+
+ }
+
+ c = memHandle->ptr + memHandle->offset;
+
+ if (memHandle->state != EOF) {
+ len = size;
+ if (len + memHandle->offset > memHandle->size) {
+ len = memHandle->size - memHandle->offset;
+ }
+ }
+
+ memcpy(buf, c, len);
+
+ memHandle->offset += len;
+
+ if (memHandle->offset == memHandle->size) {
+ memHandle->state = EOF;
+ }
+
+ return len;
+}
+
+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;
+ }
+
+ memHandle = opaque;
+
+ switch (whence) {
+ case SEEK_SET:
+ tmp_offset = 0 + pos;
+ break;
+ case SEEK_CUR:
+ tmp_offset = memHandle->offset + pos;
+ break;
+ case SEEK_END:
+ tmp_offset = memHandle->size + pos;
+ break;
+ case AVSEEK_SIZE: /*FFMPEG specific*/
+ return memHandle->size;
+ default:
+ return MMFILE_UTIL_FAIL;
+ }
+
+ /*check validation*/
+ if (tmp_offset < 0 && tmp_offset > memHandle->size) {
+ debug_error(DEBUG, "invalid file offset\n");
+ return MMFILE_UTIL_FAIL;
+ }
+
+ /*set */
+ memHandle->state = (tmp_offset >= memHandle->size) ? EOF : !EOF;
+ memHandle->offset = (unsigned int) tmp_offset;
+
+ return tmp_offset;
+}
EXPORT_API
int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext)
unsigned int i;
char ffmpegFormatName[MMFILE_FILE_FMT_MAX_LEN] = {0, };
char mimeType[MMFILE_MIMETYPE_MAX_LEN] = {0, };
+ AVIOContext *pIOCtx = NULL;
+ MMFmemIOHandle *handle = NULL;
+ uint8_t *avio_ctx_buffer = NULL;
formatContext->ReadStream = mmfile_format_read_stream_ffmpg;
formatContext->ReadFrame = mmfile_format_read_frame_ffmpg;
av_register_all();
if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_MEMORY) {
-
- ffurl_register_protocol(&MMFileMEMProtocol);
-
if (getMimeType(formatContext->filesrc->memory.format, mimeType, MMFILE_MIMETYPE_MAX_LEN) < 0) {
debug_error(DEBUG, "error: Error in MIME Type finding\n");
return MMFILE_FORMAT_FAIL;
goto exception;
}
- ret = avformat_open_input(&pFormatCtx, formatContext->uriFileName, grab_iformat, NULL);
+ 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;
+ }
+
+ ret = _mmf_mem_open(&handle, formatContext->uriFileName);
+ if (ret != MMFILE_IO_SUCCESS) {
+ debug_warning(DEBUG, "failed to _mmf_mem_open.\n");
+ 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");
+ goto exception;
+ }
+
+ pFormatCtx = avformat_alloc_context();
+ if (pFormatCtx == NULL) {
+ debug_warning(DEBUG, "failed to avformat_alloc_context\n");
+ 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);
goto exception;
}
+
formatContext->privateFormatData = pFormatCtx;
}
return MMFILE_FORMAT_SUCCESS;
exception: /* fail to get content information */
+ if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_MEMORY) {
+ if (avio_ctx_buffer)
+ av_free(avio_ctx_buffer);
+ if (handle)
+ mmfile_free(handle);
+ if (pIOCtx)
+ av_free(pIOCtx);
+ if (pFormatCtx)
+ avformat_close_input(&pFormatCtx);
+ } else {
+ mmfile_format_close_ffmpg(formatContext);
+ }
- mmfile_format_close_ffmpg(formatContext);
formatContext->privateFormatData = NULL;
return MMFILE_FORMAT_FAIL;
avformat_close_input(&pFormatCtx);
formatContext->privateFormatData = NULL;
}
-
- if (formatContext->filesrc->type == MM_FILE_SRC_TYPE_MEMORY) {
- ffurl_deregister_protocol(&MMFileMEMProtocol);
- }
}
return MMFILE_FORMAT_SUCCESS;
if (frame->key_frame) {
debug_msg(RELEASE, "key frame!\n");
#ifdef MMFILE_FORMAT_DEBUG_DUMP
- sprintf(pgm_name, "./key_%d_%d_%d.pgm", retry, i, v);
+ memset(pgm_name, 0x00, sizeof(pgm_name));
+ snprintf(pgm_name, sizeof(pgm_name), "./key_%d_%d_%d.pgm", retry, i, v);
_save_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
#endif
} else {
debug_msg(RELEASE, "skip (not key frame).\n");
#ifdef MMFILE_FORMAT_DEBUG_DUMP
- sprintf(pgm_name, "./not_key_%d_%d_%d.pgm", retry, i, v);
+ memset(pgm_name, 0x00, sizeof(pgm_name));
+ snprintf(pgm_name, sizeof(pgm_name), "./not_key_%d_%d_%d.pgm", retry, i, v);
_save_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
#endif
}