diff --git a/examples/grid_record.c b/examples/grid_record.c index d8e53d7..50a9f55 100644 --- a/examples/grid_record.c +++ b/examples/grid_record.c @@ -182,14 +182,25 @@ int main(int argc, char **argv) return 1; } - /* Output file. */ + /* Output: "-" / "/dev/stdout" / "pipe:1" = stdout (для pipe в ffmpeg). + * stdout не закрывается через fclose чтобы не убивать дочерний процесс + * raньше времени. */ write_ctx_t wctx = { 0 }; - wctx.fp = fopen(out_path, "wb"); - if (!wctx.fp) { - fprintf(stderr, "fopen(%s): %s\n", out_path, strerror(errno)); - cfc_encoder_destroy(enc); - cfc_composer_destroy(comp); - return 1; + int is_stdout = (!strcmp(out_path, "-") || !strcmp(out_path, "pipe:1") || + !strcmp(out_path, "/dev/stdout")); + if (is_stdout) { + wctx.fp = stdout; + /* line-buffer'инг disabled — пишем full-buffered для производительности. + * Caller'у нужно flush при exit. */ + setvbuf(stdout, NULL, _IOFBF, 1024 * 1024); + } else { + wctx.fp = fopen(out_path, "wb"); + if (!wctx.fp) { + fprintf(stderr, "fopen(%s): %s\n", out_path, strerror(errno)); + cfc_encoder_destroy(enc); + cfc_composer_destroy(comp); + return 1; + } } fprintf(stderr, "[grid_record] начало записи в %s (Ctrl+C для остановки)\n", out_path); @@ -261,7 +272,8 @@ int main(int argc, char **argv) (unsigned long long)wctx.idr_count, wctx.bytes_written / 1048576.0); - fclose(wctx.fp); + fflush(wctx.fp); + if (!is_stdout) fclose(wctx.fp); cfc_encoder_destroy(enc); cfc_composer_destroy(comp); cuCtxPopCurrent(NULL); diff --git a/examples/simple_record.c b/examples/simple_record.c index 3e5af66..242b8aa 100644 --- a/examples/simple_record.c +++ b/examples/simple_record.c @@ -180,13 +180,20 @@ int main(int argc, char **argv) goto cleanup_src; } - /* 5) Открыть выходной файл. */ + /* 5) Открыть выходной файл (или stdout если "-"/"pipe:1"). */ write_ctx_t wctx = { 0 }; - wctx.fp = fopen(out_path, "wb"); - if (!wctx.fp) { - fprintf(stderr, "[simple_record] fopen(%s) failed: %s\n", - out_path, strerror(errno)); - goto cleanup_enc; + int is_stdout = (!strcmp(out_path, "-") || !strcmp(out_path, "pipe:1") || + !strcmp(out_path, "/dev/stdout")); + if (is_stdout) { + wctx.fp = stdout; + setvbuf(stdout, NULL, _IOFBF, 1024 * 1024); + } else { + wctx.fp = fopen(out_path, "wb"); + if (!wctx.fp) { + fprintf(stderr, "[simple_record] fopen(%s) failed: %s\n", + out_path, strerror(errno)); + goto cleanup_enc; + } } /* 6) Главный цикл — забираем кадры по seq, кодируем. */ @@ -258,7 +265,8 @@ int main(int argc, char **argv) (unsigned long long)wctx.idr_count, wctx.bytes_written / 1048576.0); - fclose(wctx.fp); + fflush(wctx.fp); + if (!is_stdout) fclose(wctx.fp); cleanup_enc: cfc_encoder_destroy(enc);