ffmpeg 自定義資料來源, 可以是檔案,可以是記憶體,可以是網路, 愛咋的咋的
ffmpeg 自定義資料來源, 可以是檔案,可以是記憶體,可以是網路, 愛咋的咋的
// ffmpeg_custom_context.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
extern "C"
{
#include <libavformat/avformat.h>
};
#pragma comment(lib, "avformat.lib")
int ReadFunc(void* ptr, uint8_t* buf, int buf_size)
{
FILE* fp = (FILE*)ptr;
size_t size = fread(buf, 1, buf_size, fp);
int ret = size;
return ret;
} //這個函式你可以自由發揮。一定要自由發揮。我沒有網路流就從檔案讀了, 一般來說這裡不能返回-1 或者0, 否則ffmpeg認為結束、或失敗了。 你不想讀檔案,就直接從記憶體拷一段資料給buf即可。 接受的網路流、底層上採集卡上來的流都可以在這裡,,,,
//一定要注意這個函式,ffmpeg的實現就是一個坑,一不小心就中招了。
int64_t seek_func(void *opaque, int64_t offset, int whence)
{
int64_t ret;
FILE *fp = (FILE*)opaque;
if (whence == AVSEEK_SIZE) {
return -1;
}
fseek(fp, offset, whence);
return ftell(fp);
}
int _tmain(int argc, _TCHAR* argv[])
{
av_register_all();
int ret = 0;
FILE* fp = fopen("./BoyGirls.mp4", "rb");
int nBufferSize = 1024 * 1024;
unsigned char* pBuffer = new unsigned char[nBufferSize];
AVFormatContext* pFormatCtx = NULL;
AVInputFormat *piFmt = NULL;
AVCodecContext *vcodecCtx = NULL, *acodecCtx = NULL;
AVCodec *vdec = NULL, *adec = NULL;
int ai = -1, vi = -1;
// Allocate the AVIOContext:
AVIOContext* pIOCtx = avio_alloc_context(pBuffer, nBufferSize,
0,
fp,
ReadFunc,
0,
seek_func);
//step2:探測流格式
ret = av_probe_input_buffer(pIOCtx, &piFmt, "", NULL, 0, 0);
if (ret < 0) {
fprintf(stderr, "probe failed!\n");
goto quit;
}
else {
fprintf(stdout, "probe success!\n");
fprintf(stdout, "format: %s[%s]\n", piFmt->name, piFmt->long_name);
}
// Allocate the AVFormatContext:
pFormatCtx = avformat_alloc_context();
// Set the IOContext:
pFormatCtx->pb = pIOCtx;
pFormatCtx->flags = AVFMT_FLAG_CUSTOM_IO;
//step4:開啟流
if (avformat_open_input(&pFormatCtx, "", piFmt, NULL) < 0) {
fprintf(stderr, "avformat open failed.\n");
goto quit;
}
else {
fprintf(stdout, "open stream success!\n");
}
if (avformat_find_stream_info(pFormatCtx, NULL)<0)
{
printf("av_find_stream_info error \n");
goto quit;
}
//接下來該做什麼??? 喂,你要做什麼?
quit:
avformat_close_input(&pFormatCtx);
delete[]pBuffer;
return 0;
}
本來已經有一篇了:http://hi.baidu.com/mingyuejingque/item/34db89a7d16fc9706cd4559d
可是新乞丐王子說版式不方便閱讀,特別是在上面url的回帖我已經貼了程式碼,猥瑣的百度預設沒打開回帖,,,所以新貼了這篇方便大家。感謝祖國!