Windows ffmpeg av_交错_写入_帧():窗口下的断管
我正在使用ffmpeg将原始媒体文件转换为rawvideo yuv格式,将yuv输出到管道,然后我的命令工具接收原始yuv作为输入,进行一些处理 e、 g: 每次运行命令时,ffmpeg都会转储此Windows ffmpeg av_交错_写入_帧():窗口下的断管,windows,ffmpeg,pipe,broken-pipe,Windows,Ffmpeg,Pipe,Broken Pipe,我正在使用ffmpeg将原始媒体文件转换为rawvideo yuv格式,将yuv输出到管道,然后我的命令工具接收原始yuv作为输入,进行一些处理 e、 g: 每次运行命令时,ffmpeg都会转储此av\u interleaved\u write\u frame():断管error msg: Output #0, rawvideo, to 'pipe:': Metadata: encoder : Lavf56.4.101 Stream #0:0: Video: rawv
av\u interleaved\u write\u frame():断管error msg:
Output #0, rawvideo, to 'pipe:':
Metadata:
encoder : Lavf56.4.101
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240 [SAR 120:91 DAR 160:91], q=2-31, 200 kb/s, 24 fps, 24 tbn, 24 tbc (default)
Metadata:
encoder : Lavc56.1.100 rawvideo
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
av_interleaved_write_frame(): Broken pipe
frame= 1 fps=0.0 q=0.0 Lsize= 112kB time=00:00:00.04 bitrate=22118.2kbits/s
video:112kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing o
verhead: 0.000000%
Conversion failed!
在我的源代码中:它以stdin
作为输入文件,每次从中读取帧大小的内容,如果读取的内容小于帧大小,则继续读取,直到获取帧,然后使用帧内容生成内容
int do_work (int jpg_width, int jpg_height)
{
int ret = 0;
FILE *yuv_fp = NULL;
unsigned char * yuv_buf = NULL;
int frame_size = 0;
int count = 0;
int try_cnt = 0;
frame_size = jpg_width * jpg_height * 3 / 2;
va_log (vfp_log, "a frame size:%d\n", frame_size);
yuv_fp = stdin;
yuv_buf = (unsigned char *) aligned_malloc_int(
sizeof(char) * (jpg_width + 1) * (jpg_height + 1) * 3, 128);
if (!yuv_buf) {
fprintf (stderr, "malloc yuv buf error\n");
goto end;
}
memset (yuv_buf, 0, frame_size);
while (1) {
try_cnt++;
va_log (vfp_log, "try_cnt is %d\n", try_cnt);
//MAX_TRY_TIMES = 10
if (try_cnt > MAX_TRY_TIMES) {
va_log (vfp_log, "try time out\n");
break;
}
count = fread (yuv_buf + last_pos, 1, frame_size - last_pos, yuv_fp);
if (last_pos + count < frame_size) {
va_log (vfp_log, "already read yuv: %d, this time:%d\n", last_pos + count, count);
last_pos += count;
continue;
}
// do my work here
memset (yuv_buf, 0, frame_size);
last_pos = 0;
try_cnt = 0;
}
end:
if (yuv_buf) {
aligned_free_int (yuv_buf);
}
return ret;
}
int-do_-work(int-jpg_-width,int-jpg_-height)
{
int-ret=0;
文件*yuv_fp=NULL;
无符号字符*yuv_buf=NULL;
int frame_size=0;
整数计数=0;
int try_cnt=0;
框架尺寸=jpg_宽度*jpg_高度*3/2;
va_日志(vfp_日志,“帧大小:%d\n”,帧大小);
yuv_fp=stdin;
yuv_buf=(无符号字符*)对齐(
尺寸(字符)*(jpg_宽度+1)*(jpg_高度+1)*3128);
如果(!yuv_buf){
fprintf(标准,“malloc yuv buf错误”\n);
转到终点;
}
memset(yuv_buf,0,帧大小);
而(1){
试试看cnt++;
va_日志(vfp_日志,“try_cnt为%d\n”,try_cnt);
//最大尝试次数=10次
如果(尝试次数>最大尝试次数){
va_日志(vfp_日志,“尝试超时\n”);
打破
}
计数=fread(yuv\U buf+最后一个位置,1,帧大小-最后一个位置,yuv\U fp);
if(最后位置+计数<帧大小){
va_日志(vfp_日志,“已读yuv:%d,这次:%d\n”,最后一个位置+计数,计数);
最后一个位置+=计数;
继续;
}
//在这里做我的工作
memset(yuv_buf,0,帧大小);
最后的位置=0;
try_cnt=0;
}
完:
如果(yuv_buf){
对齐的自由整数(yuv_buf);
}
返回ret;
}
我的日志:
2016/04/05 15:20:38:框架尺寸:115200
2016/04/05 15:20:38:try_cnt是1
2016/04/05 15:20:38:已经读到yuv:49365,这次是:49365
2016/04/05 15:20:38:try_cnt是2
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是3
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是4
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是5
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是6
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是7
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是8
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是9
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是10
2016/04/05 15:20:38:已阅读yuv:49365,这次:0
2016/04/05 15:20:38:try_cnt是11
2016/04/05 15:20:38:尝试超时
```
我的问题:
使用管道时,ffmpeg是否会在有内容时立即将内容写入管道缓冲区,或者它会缓冲一些大小的内容,然后将它们刷新到管道?可能是我误解的一些内部逻辑,任何人都可以帮助解释或修复我的代码
PS:这个命令在linux下运行正常。我自己已经解决了这个问题:这只是一个windows问题,在Unix系统下,默认以二进制模式打开stdin/stdout/stderr,而在windows系统下是文本模式。因此,在yuv_fp=stdin之前添加“set_mode(fileno(stdin),O_BINARY)”代码>现在可以工作了。感谢您分享您的解决方案。我在我的应用程序中遇到了同样的问题,通过这一评论,我很快就解决了这个问题。
int do_work (int jpg_width, int jpg_height)
{
int ret = 0;
FILE *yuv_fp = NULL;
unsigned char * yuv_buf = NULL;
int frame_size = 0;
int count = 0;
int try_cnt = 0;
frame_size = jpg_width * jpg_height * 3 / 2;
va_log (vfp_log, "a frame size:%d\n", frame_size);
yuv_fp = stdin;
yuv_buf = (unsigned char *) aligned_malloc_int(
sizeof(char) * (jpg_width + 1) * (jpg_height + 1) * 3, 128);
if (!yuv_buf) {
fprintf (stderr, "malloc yuv buf error\n");
goto end;
}
memset (yuv_buf, 0, frame_size);
while (1) {
try_cnt++;
va_log (vfp_log, "try_cnt is %d\n", try_cnt);
//MAX_TRY_TIMES = 10
if (try_cnt > MAX_TRY_TIMES) {
va_log (vfp_log, "try time out\n");
break;
}
count = fread (yuv_buf + last_pos, 1, frame_size - last_pos, yuv_fp);
if (last_pos + count < frame_size) {
va_log (vfp_log, "already read yuv: %d, this time:%d\n", last_pos + count, count);
last_pos += count;
continue;
}
// do my work here
memset (yuv_buf, 0, frame_size);
last_pos = 0;
try_cnt = 0;
}
end:
if (yuv_buf) {
aligned_free_int (yuv_buf);
}
return ret;
}