之前采集或者播放音视频都是直接生成到文件,后面查询了可以写入或者从内存读取,其中有个很重要的结构体AVIOContext,
创建该结构体可以使用函数avio_alloc_context,声明如下:
AVIOContext *avio_alloc_context(
unsigned char *buffer,
int buffer_size,
int write_flag,
void *opaque,
int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
int64_t (*seek)(void *opaque, int64_t offset, int whence));
如果需要从内存读取进行解码等,就使用read_packet,其中的具体逻辑可以自己实现,反过来如果是将编码之后的数据写入内存,则可以使用write_packet,其中的逻辑也可以自己实现。
在测试将编码生成的数据写入内存,write_flag没有使用AVIO_FLAG_WRITE,而使用了0,导致持续的报错
[dshow @ 0000017e13ae8200] real-time buffer [USB2.0 Camera] [video input] too full or near too full (101% of size: 3041280 [rtbufsize parameter])! frame dropped!
[dshow @ 0000017e13ae8200] real-time buffer [USB2.0 Camera] [video input] too full or near too full (101% of size: 3041280 [rtbufsize parameter])! frame dropped!
上一次出现这个问题是因为调试的过程打了断点,如果没打断点正常运行没问题,但这次的问题显然是write_flag设置的问题,如果设置为AVIO_FLAG_WRITE,则没有报错。
然后使用创建的AVIOContext结构体变量
int ret = avformat_alloc_output_context2(&outputContext, nullptr, "mp4", NULL);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "open output context failed\n");
goto Error;
}
outputContext->pb = avio_out;
outputContext->flags = AVFMT_FLAG_CUSTOM_IO;
因为写入内存,所以输出文件不需要设置,如果是写入文件的,则需要设置