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

使用FFmpeg保存CUDA流体模拟数组流时出现无数据写入警告

解决FFmpeg接收CUDA流体模拟数据时无帧写入的问题

问题根源

你的代码在将pColors像素数据拷贝到data数组时存在数组索引越界问题,导致输出到标准输出的data数据无效,FFmpeg无法解析到有效视频帧。

错误分析

看这段拷贝逻辑:

for (int j = 0; j < SCR_WIDTH * SCR_HEIGHT * 4; j+=4)
{
    data[j] = pColors[j].x;
    data[j+1] = pColors[j].y;
    data[j+2] = pColors[j].z;
    data[j+3] = pColors[j].w;
}
  • pColors是uchar4类型数组,长度为SCR_WIDTH * SCR_HEIGHT,每个元素对应1个像素的RGBA四通道数据
  • 循环中j的范围是0到SCR_WIDTH*SCR_HEIGHT*4,步长为4,但直接用j作为pColors的索引会严重越界:比如j=4时,pColors[4]已经指向第5个像素,而实际应该访问pColors[1]
  • 越界访问会读取无效内存数据,导致data中的内容并非预期的像素值,FFmpeg收不到有效帧就会输出Finishing stream 0:0 without any data written to it警告

修正后的代码

改成按像素索引遍历,每个像素对应data中的4个字节:

unsigned char* data = new unsigned char[SCR_WIDTH * SCR_HEIGHT * 4];
uchar4* pColors = new uchar4[SCR_WIDTH * SCR_HEIGHT];

for (int i = 0; i < N_FRAMES; i ++)
{
    // 执行模拟步骤,生成当前帧的pColors数据
    on_frame(pColors, timeStepSize);
    // 按像素索引拷贝数据
    for (int idx = 0; idx < SCR_WIDTH * SCR_HEIGHT; idx++)
    {
        int byte_pos = idx * 4;
        data[byte_pos] = pColors[idx].x;
        data[byte_pos + 1] = pColors[idx].y;
        data[byte_pos + 2] = pColors[idx].z;
        data[byte_pos + 3] = pColors[idx].w;
    }
    std::cout.write(reinterpret_cast<char*>(data), SCR_WIDTH * SCR_HEIGHT * 4);
    // 强制刷新输出缓冲,避免数据滞留管道
    std::cout.flush();
}

额外注意事项

  • 参数一致性:确保FFmpeg命令中的-video_size参数和代码里的SCR_WIDTH、SCR_HEIGHT完全匹配(你的日志显示输入尺寸是128x128,但命令里写的是1024x1024,需统一)
  • 数据验证:可以在拷贝后打印几帧的像素值,确认data中的RGBA数据符合预期
  • 内存释放:记得在循环结束后释放data和pColors的内存,避免泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:20:21