ffmpeg av_interleaved_write_frame(): сломанная труба под окнами
Я использую ffmpeg для преобразования исходного медиа-файла в формат rawvideo yuv, передал yuv в pipe, затем мой инструмент командной строки получил необработанный yuv в качестве входных данных, выполнил некоторую обработку.
например:
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 is 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 is 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 is 11 2016/04/05 15:20:38: попробуйте тайм-аут ```
мой вопрос:
Когда используется конвейер, ffmpeg записывает контент в конвейерный буфер, как только он имеет контент, или он буферизует контент некоторого размера, а затем сбрасывает их в конвейер? Может быть, какая-то внутренняя логика, которую я неправильно понял, может помочь объяснить или исправить мой код?
PS: эта команда работает нормально под Linux.