如何通过管道传输到 ffmpeg RGB 值 10?
How to pipe to ffmpeg RGB value 10?
我正在尝试使用 ffmpeg 创建视频文件。我有每一帧的所有 RGB 像素数据,在 this 博文之后,我有代码通过管道逐帧发送数据。它主要起作用。但是,如果任何像素在 3 个通道(例如#00000A、#0AFFFF 等)中的任何一个中的值为 10,则会产生以下错误:
[rawvideo @ 0000020c3787f040] Packet corrupt (stream = 0, dts = 170)
pipe:: corrupt input packet in stream 0
[rawvideo @ 0000020c3789f100] Invalid buffer size, packet size 32768 < expected frame_size 49152
Error while decoding stream #0:0: Invalid argument
并且输出的视频是乱码。
现在我怀疑因为 ASCII 中的 10 是换行符,所以这会以某种方式混淆管道。
这里到底发生了什么,我该如何修复它以便我可以使用像 #00000a 这样的 RGB 值?
下面是 C 代码,它是一个例子
#include <stdio.h>
unsigned char frame[128][128][3];
int main() {
int x, y, i;
FILE *pipeout = popen("ffmpeg -y -f rawvideo -vcodec rawvideo -pix_fmt rgb24 -s 128x128 -r 24 -i - -f mp4 -q:v 1 -an -vcodec mpeg4 output.mp4", "w");
for (i = 0; i < 128; i++) {
for (x = 0; x < 128; ++x) {
for (y = 0; y < 128; ++y) {
frame[y][x][0] = 0;
frame[y][x][1] = 0;
frame[y][x][2] = 10;
}
}
fwrite(frame, 1, 128*128*3, pipeout);
}
fflush(pipeout);
pclose(pipeout);
return 0;
}
编辑:为清楚起见,我使用 Windows
我刚刚在 Linux 中尝试了您的代码,它对我有用。我认为@Craig Estey 的建议可能就是答案。
如果它不起作用,您可以尝试使用 write
而不是 fwrite
写入数据(如果可用)。 (我在过去使用 fread/fwrite
系列函数将二进制数据写入管道时遇到过问题。)
因此您可以尝试更改此行:
fwrite(frame, 1, 128*128*3, pipeout);
类似于:
int fd = fileno(pipeout);
write(fd, frame, sizeof(frame));
并删除以下行:
fflush(pipeout);
编辑:您链接的博客 post 的评论部分有一些故障排除提示。特别是关于此程序的 Windows 版本。
我正在尝试使用 ffmpeg 创建视频文件。我有每一帧的所有 RGB 像素数据,在 this 博文之后,我有代码通过管道逐帧发送数据。它主要起作用。但是,如果任何像素在 3 个通道(例如#00000A、#0AFFFF 等)中的任何一个中的值为 10,则会产生以下错误:
[rawvideo @ 0000020c3787f040] Packet corrupt (stream = 0, dts = 170)
pipe:: corrupt input packet in stream 0
[rawvideo @ 0000020c3789f100] Invalid buffer size, packet size 32768 < expected frame_size 49152
Error while decoding stream #0:0: Invalid argument
并且输出的视频是乱码。 现在我怀疑因为 ASCII 中的 10 是换行符,所以这会以某种方式混淆管道。 这里到底发生了什么,我该如何修复它以便我可以使用像 #00000a 这样的 RGB 值?
下面是 C 代码,它是一个例子
#include <stdio.h>
unsigned char frame[128][128][3];
int main() {
int x, y, i;
FILE *pipeout = popen("ffmpeg -y -f rawvideo -vcodec rawvideo -pix_fmt rgb24 -s 128x128 -r 24 -i - -f mp4 -q:v 1 -an -vcodec mpeg4 output.mp4", "w");
for (i = 0; i < 128; i++) {
for (x = 0; x < 128; ++x) {
for (y = 0; y < 128; ++y) {
frame[y][x][0] = 0;
frame[y][x][1] = 0;
frame[y][x][2] = 10;
}
}
fwrite(frame, 1, 128*128*3, pipeout);
}
fflush(pipeout);
pclose(pipeout);
return 0;
}
编辑:为清楚起见,我使用 Windows
我刚刚在 Linux 中尝试了您的代码,它对我有用。我认为@Craig Estey 的建议可能就是答案。
如果它不起作用,您可以尝试使用 write
而不是 fwrite
写入数据(如果可用)。 (我在过去使用 fread/fwrite
系列函数将二进制数据写入管道时遇到过问题。)
因此您可以尝试更改此行:
fwrite(frame, 1, 128*128*3, pipeout);
类似于:
int fd = fileno(pipeout);
write(fd, frame, sizeof(frame));
并删除以下行:
fflush(pipeout);
编辑:您链接的博客 post 的评论部分有一些故障排除提示。特别是关于此程序的 Windows 版本。