我使用ffmpeg将原始媒体文件转换为rawvideo yuv格式,将yuv连接到管道,然后我的命令工具接收原始yuv作为输入,进行一些处理。
e.g:
D:\huang_xuezhong\build_win32_VDNAGen>ffmpeg -i test.mkv -c:v rawvideo -s 320x240 -f rawvideo - | my_tool -o output
每次运行命令时,ffmpeg都会转储此av_interleaved_write_frame(): Broken pipe
错误消息:
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;
}
我的日志:
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下运行正常。