使用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
相关产品推荐
相关产品推荐

