You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FFmpeg RTSP推流fwrite优化:批量写入效率提升方案问询

问题描述

我已经搭建了FFmpeg流水线将视频帧推流至RTSP服务器,初始化代码如下:

FILE* openPipeLine =  _popen("ffmpeg -f rawvideo -r 10 -video_size 1280x720 -pixel_format bgr24 -i pipe: -vcodec libx264 -crf 25 -pix_fmt yuv420p -f rtsp rtsp://localHost:8554/mystream", "wb");

随后通过循环处理视频帧,得到存储720x1280图像的Mat变量,使用fwrite逐帧写入管道的代码如下:

string filename = "file.mp4";
VideoCapture capture(filename);
Mat frame;
for( ; ; )
{
    capture >> frame;
    if(frame.empty())
        break;
    fwrite(frame.data, 1, 1280 * 720 * 3, openPipeLine);
}

目前运行正常,但单次fwrite耗时约0.1秒,需大幅提升效率。能否通过缓存多帧批量写入替代逐帧调用fwrite?或修改fwrite第二个参数实现优化?

优化方案

1. 多帧缓存批量写入

这是提升写入效率的核心有效方法,通过减少IO调用次数降低系统开销。具体实现思路:

  • 预先分配一块足够大的内存缓冲区,比如一次性缓存8帧、16帧(可根据可用内存调整)
  • 循环读取视频帧,将每帧数据复制到缓冲区的对应位置
  • 当缓冲区存满设定的帧数,或者视频读取到末尾时,调用一次fwrite将整个缓冲区数据写入管道
  • 写完后重置缓冲区计数,继续循环处理剩余帧

示例代码片段:

const int BATCH_FRAMES = 8; // 批量写入的帧数
const int FRAME_SIZE = 1280 * 720 * 3;
vector<uchar> buffer(BATCH_FRAMES * FRAME_SIZE);
int frame_count = 0;

string filename = "file.mp4";
VideoCapture capture(filename);
Mat frame;

for( ; ; )
{
    capture >> frame;
    if(frame.empty())
        break;
    
    // 将当前帧数据复制到缓冲区
    memcpy(buffer.data() + frame_count * FRAME_SIZE, frame.data, FRAME_SIZE);
    frame_count++;
    
    // 缓冲区满则批量写入
    if(frame_count == BATCH_FRAMES)
    {
        fwrite(buffer.data(), 1, BATCH_FRAMES * FRAME_SIZE, openPipeLine);
        frame_count = 0;
    }
}

// 写入剩余的不足一整批的帧
if(frame_count > 0)
{
    fwrite(buffer.data(), 1, frame_count * FRAME_SIZE, openPipeLine);
}

2. 调整fwrite参数的实际作用

fwrite的参数格式是fwrite(ptr, size, count, stream),总写入字节数为size*count。你当前的调用是按1字节为单位写入FRAME_SIZE个元素,若修改为fwrite(frame.data, FRAME_SIZE, 1, openPipeLine),只是参数组合方式不同,总写入字节数完全一致,底层IO逻辑没有本质变化,对性能提升几乎可以忽略,不是核心优化手段。

3. 额外优化建议

  • 关闭用户态缓冲:调用setvbuf(openPipeLine, NULL, _IONBF, 0)关闭FILE*的用户态缓冲,避免额外内存拷贝,让数据直接写入内核态管道(批量写入场景下收益会被弱化,但仍有帮助)
  • 替换底层IO函数:如果批量写入后效率仍不满足,可以考虑用WriteFile(Windows)或write(Linux)替代fwrite,减少标准库封装开销,但要注意跨平台兼容性
  • 优化FFmpeg编码参数:给FFmpeg添加-preset ultrafast参数,让x264编码更快,避免编码端阻塞管道间接影响写入速度

内容的提问来源于stack exchange,提问作者user20623229

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:30:50