0%

Custom IO Context with FFMPEG

最近想從IP Camera和FFMpeg搭上陷,不過IP Cam走得不是標準的v4l2這套,只好另尋他路。
看了幾篇文章,時做了之後可以用,增添了自信心。
紀錄一下整個思路。

Step 1

仙分配一塊記憶體,當作IO Context的Buffer使用

1
2
const int iBufSize = 32 * 1024;
BYTE* pBuffer = new BYTE[iBufSize];

Step 2

向FFMpeg要求建立AVIOContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int ReadFunc(void* ptr, uint8_t* buf, int buf_size)
{
// Left to implement
}
int64_t SeekFunc(void* ptr, int64_t pos, int whence)
{
// Left to implement
}
AVIOContext* pIOCtx = avio_alloc_context(pBuffer, iBufSize, // internal Buffer and its size
0, // bWriteable (1=true,0=false)
pContext, // user data ; will be passed to our callback functions
ReadFunc,
0, // Write callback function (not used in this example)
SeekFunc);

上面的ReadFuncSeekFunc就代表Read和Seek的動作,而pContext就是有關的上下文,ReadFuncSeekFunc被呼叫時,pContext會被傳入ptr中。因此需要自行轉型成正確的上下文。

Step 3

建立AVFormatContex,這邊我是採用比較偷懶的作法,我已經知道InputFormat了,所以不需要Probe。如果要Probe可以參考Reference的連結。

1
2
3
4
AVFormatContext* pCtx = avformat_alloc_context();
pCtx->pb = pIOCtx;
pCtx->iformat = av_find_input_format("h264");
pCtx->flags = AVFMT_FLAG_CUSTOM_IO;

Step 4

依照FFMpeg正常的流程使用

1
2
if (avformat_open_input(&pCtx, "", 0, 0)) != 0)
// Error Handling

接著就跟一般無異了

Final

使用完後需要釋放資源

1
2
3
avformat_close_input(pCtx);  // AVFormatContext is released by avformat_close_input
av_free(pIOCtx); // AVIOContext is released by av_free
delete[] pBuffer;

Reference