读取本地文件(网络流)信息
#include <iostream>
#include <stdio.h>
extern "C"
{
#include <libavformat\avformat.h>
#include <libavutil\avutil.h>
#include <libavutil\log.h>
#include <libavformat\avio.h>
#include <libavutil\file.h>
#include <libavcodec\avcodec.h>
#include <libavutil\error.h>
}
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
void readLoadHostFile()
{
avformat_network_init();
AVFormatContext* pAVFmtCtx = NULL;
AVInputFormat* pAVInputFmt = NULL;
pAVFmtCtx = avformat_alloc_context();
if (avformat_open_input(&pAVFmtCtx, "input_5s.mp4", pAVInputFmt, NULL))
{
av_log(pAVFmtCtx, AV_LOG_WARNING, "open file/networkStream faild!\n");
avformat_free_context(pAVFmtCtx);
avformat_network_deinit();
return;
}
av_log(pAVFmtCtx, AV_LOG_INFO, "open file/networkStream success!\n");
if (avformat_find_stream_info(pAVFmtCtx, NULL) < 0)
{
av_log(pAVFmtCtx, AV_LOG_WARNING, "find stream info faild!\n");
avformat_close_input(&pAVFmtCtx);
avformat_free_context(pAVFmtCtx);
avformat_network_deinit();
return;
}
av_log(pAVFmtCtx, AV_LOG_INFO, "find stream info success!\n");
av_log(pAVFmtCtx, AV_LOG_INFO, "nbstream: %d\n", pAVFmtCtx->nb_streams);
avformat_close_input(&pAVFmtCtx);
avformat_free_context(pAVFmtCtx);
avformat_network_deinit();
}
使AVIO获取视频文件信息
int read_callback(void *opaque, uint8_t *buf, int buf_size)
{
FILE* fp = (FILE*)opaque;
size_t size = fread(buf, sizeof(uint8_t), buf_size, fp);
printf("Read Bytes: %d\n", size);
return (int)size;
}
int64_t seek_callback(void *opaque, int64_t offset, int whence)
{
FILE *fp = (FILE*)opaque;
if (whence == AVSEEK_SIZE)
{
return -1;
}
fseek(fp, offset, whence);
return ftell(fp);
}
void selfDefAVIO()
{
AVFormatContext* pAVFmtCtx = NULL;
AVInputFormat* pAVInputFmt = NULL;
pAVFmtCtx = avformat_alloc_context();
FILE* fp = fopen("input_5s.mp4", "rb");
int nBuffSize = 1024;
uint8_t* buffer = (uint8_t*)av_malloc(nBuffSize);
AVIOContext* pAVIOCtx = avio_alloc_context(buffer,
nBuffSize,
0,
fp,
read_callback,
0,
seek_callback);
if (NULL == pAVIOCtx)
{
av_log(NULL, AV_LOG_WARNING, "AVIOContext alloc faild!\n");
av_free(pAVIOCtx);
return;
}
pAVFmtCtx->pb = pAVIOCtx;
pAVFmtCtx->flags = AVFMT_FLAG_CUSTOM_IO;
if (avformat_open_input(&pAVFmtCtx, "", pAVInputFmt, NULL) < 0)
{
av_log(pAVFmtCtx, AV_LOG_WARNING, "open file stream faild!\n");
av_free(pAVIOCtx);
avformat_free_context(pAVFmtCtx);
return;
}
av_log(pAVFmtCtx, AV_LOG_INFO, "open file stream success!\n");
if (avformat_find_stream_info(pAVFmtCtx, NULL) < 0)
{
av_log(pAVFmtCtx, AV_LOG_WARNING, "find stream info faild!\n");
avformat_close_input(&pAVFmtCtx);
av_free(pAVIOCtx);
avformat_free_context(pAVFmtCtx);
return;
}
av_log(pAVFmtCtx, AV_LOG_INFO, "find stream info success!\n");
av_log(pAVFmtCtx, AV_LOG_INFO, " nbstream: %d\n", pAVFmtCtx->nb_streams);
avformat_close_input(&pAVFmtCtx);
av_free(pAVIOCtx);
avformat_free_context(pAVFmtCtx);
}
使用AVIO和自定义数据类型获取视频文件信息
struct buffer_data
{
uint8_t *ptr;
size_t size;
};
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{
struct buffer_data *bd = (struct buffer_data*)opaque;
buf_size = FFMIN(buf_size, bd->size);
if (!buf_size)
return AVERROR_EOF;
printf("ptr:%p size:%d\n", bd->ptr, bd->size);
memcpy(buf, bd->ptr, buf_size);
bd->ptr += buf_size;
bd->size -= buf_size;
return buf_size;
}
void selfDefDataSrc()
{
struct buffer_data bd = { 0 };
int nRet = av_file_map("input_5s.mp4", &bd.ptr, &bd.size, 0, NULL);
if (nRet < 0)
{
av_log(NULL, AV_LOG_ERROR, "map file to memory faild!\n");
return;
}
av_log(NULL, AV_LOG_INFO, "map file to memory success!\n");
AVFormatContext* pAVFmtCtx = NULL;
pAVFmtCtx = avformat_alloc_context();
if (NULL == pAVFmtCtx)
{
av_log(NULL, AV_LOG_ERROR, "create AVFormatContext faild!\n");
av_file_unmap(bd.ptr, bd.size);
return;
}
av_log(NULL, AV_LOG_INFO, "create AVFormatContext success!\n");
uint8_t* avio_ctx_buffer = NULL;
size_t avio_ctx_buffer_size = 4096;
avio_ctx_buffer = (uint8_t*)av_malloc(avio_ctx_buffer_size);
if (!avio_ctx_buffer)
{
av_log(NULL, AV_LOG_ERROR, "av_malloc avio_ctx_buffer faild!\n");
avformat_free_context(pAVFmtCtx);
av_file_unmap(bd.ptr, bd.size);
return;
}
av_log(NULL, AV_LOG_INFO, "av_malloc avio_ctx_buffer success!\n");
AVIOContext* avio_ctx = avio_alloc_context(
avio_ctx_buffer,
avio_ctx_buffer_size,
0,
&bd,
&read_packet,
NULL,
NULL);
if (!avio_ctx)
{
av_log(NULL, AV_LOG_ERROR, "avio_alloc_context AVIOContext faild!\n");
av_freep(avio_ctx_buffer);
avformat_free_context(pAVFmtCtx);
av_file_unmap(bd.ptr, bd.size);
return;
}
pAVFmtCtx->pb = avio_ctx;
av_log(NULL, AV_LOG_INFO, "avio_alloc_context AVIOContext success!\n");
nRet = avformat_open_input(&pAVFmtCtx, NULL, NULL, NULL);
if (nRet)
{
av_log(NULL, AV_LOG_ERROR, "avformat_open_input faild!\n");
avio_context_free(&avio_ctx);
av_freep(avio_ctx_buffer);
avformat_free_context(pAVFmtCtx);
av_file_unmap(bd.ptr, bd.size);
return;
}
av_log(NULL, AV_LOG_INFO, "avformat_open_input success!\n");
nRet = avformat_find_stream_info(pAVFmtCtx, NULL);
if (nRet < 0)
{
av_log(NULL, AV_LOG_ERROR, "avformat_find_stream_info faild!\n");
avformat_close_input(&pAVFmtCtx);
avio_context_free(&avio_ctx);
av_freep(avio_ctx_buffer);
avformat_free_context(pAVFmtCtx);
av_file_unmap(bd.ptr, bd.size);
return;
}
av_log(NULL, AV_LOG_INFO, "avformat_find_stream_info success!\n");
printf(" 》》》nb_streams=%d\n", pAVFmtCtx->nb_streams);
av_dump_format(pAVFmtCtx, 0, "input_5s.mp4", 0);
avformat_close_input(&pAVFmtCtx);
if (avio_ctx)
av_freep(&avio_ctx->buffer);
avio_context_free(&avio_ctx);
av_file_unmap(bd.ptr, bd.size);
}