基于FFmpeg(C++)的视频数据向量存储优化及编码问题咨询
FFmpeg 相关问题解答
问题1:为何调用avcodec_send_frame返回错误(-22)?
错误码-22对应EINVAL(无效参数),常见原因包括:
- 编码器未正确初始化:调用
avcodec_open2后必须确认返回值成功,编码器的核心参数(如codec_id、pix_fmt、width、height)必须和输入帧严格匹配。 - 输入
AVFrame属性不匹配:帧的像素格式、宽高与编码器设置不一致;或帧未正确填充数据(如data指针为空、linesize值异常)。 - 编码流程违规:在调用
avcodec_send_frame(NULL)结束编码后继续发送帧;或对依赖参考帧的编码器(如H.264/H.265)发送顺序错误(比如跳过关键帧直接发送P/B帧)。 - 帧引用计数异常:
AVFrame的引用计数错误,或未调用av_frame_make_writable确保帧处于可写状态。
问题2:如何存储包含多帧的编码AVPacket?
- 不能直接存入原始
AVPacket:解码输出的原始AVPacket复用FFmpeg内部内存缓冲区,直接存入vector会导致后续内存操作(如释放)出错,必须创建独立副本。
示例代码:AVPacket src_pkt; // 假设已成功获取编码后的src_pkt AVPacket* pkt_copy = av_packet_clone(&src_pkt); if (pkt_copy) { your_packet_vector.push_back(pkt_copy); } av_packet_unref(&src_pkt); // 释放原始包资源 - 内存清理:当
vector不再使用时,需遍历所有元素,调用av_packet_unref释放资源后删除指针,避免内存泄漏。 - 可选优化:若需长期存储,可将
AVPacket序列化为二进制文件写入磁盘,需要时再反序列化恢复,比内存存储更省空间。
问题3:是否有更省内存的视频处理方式?
- 优先存储编码后的
AVPacket:压缩后的包内存占用远低于解码帧(比如1080P H.264帧,AVPacket仅几KB,AVFrame需十几MB),后续编辑时按需解码即可。 - 按需解码,避免预加载全量帧:不一次性解码所有帧存入内存,而是记录关键帧位置和索引,当用户编辑某段内容时,再从对应位置解码所需帧。
- 用
AVFramePool复用缓冲区:通过av_frame_pool_init创建帧池,重复利用已分配的内存缓冲区,减少频繁内存分配开销与碎片。 - 硬件加速解码/编码:利用FFmpeg的硬件加速接口(如VAAPI、NVDEC),帧数据可存储在显存中,不占用系统内存,大幅降低内存压力。
- 降低帧规格:若场景允许,可先将视频转成更低分辨率或更紧凑的像素格式(如YUV420P),减少单帧内存占用。
内容的提问来源于stack exchange,提问作者nokla
相关产品推荐
相关产品推荐

