MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ worker_loop()

void MayaFlux::IO::VideoFileWriter::worker_loop ( const std::string &  filepath,
uint32_t  width,
uint32_t  height,
double  frame_rate,
AVPixelFormat  src_fmt,
AVCodecID  codec_id 
)
private

Definition at line 369 of file VideoFileWriter.cpp.

375{
376 FFmpegMuxContext mux;
377 VideoEncodeContext enc;
378
379 auto fail = [&](std::string msg) {
380 set_error(std::move(msg));
381 m_open.store(false, std::memory_order_release);
382 m_close_promise.set_value(false);
383 };
384
385 if (!mux.open(filepath)) {
386 fail(mux.last_error());
387 return;
388 }
389 if (!enc.open(mux, width, height, frame_rate, src_fmt, codec_id)) {
390 fail(enc.last_error());
391 return;
392 }
393 if (!mux.write_header()) {
394 fail(mux.last_error());
395 return;
396 }
397
398 m_open.store(true, std::memory_order_release);
399
401 "[VideoFileWriter] worker started: '{}' {}x{} @{:.3f}fps",
402 filepath, width, height, frame_rate);
403
404 while (true) {
405 auto item_opt = m_queue->pop();
406 if (!item_opt) {
407 std::this_thread::sleep_for(std::chrono::microseconds(100));
408 continue;
409 }
410
411 bool done = std::visit([&](auto& cmd) -> bool {
412 using T = std::decay_t<decltype(cmd)>;
413
414 if constexpr (std::is_same_v<T, RawFrame>) {
415 if (!enc.encode_frame(cmd.pixels.data(), cmd.pixels.size(),
416 cmd.width, cmd.height, mux)) {
417 set_error(enc.last_error());
419 "[VideoFileWriter] encode_frame failed: {}", enc.last_error());
420 }
421 return false;
422 }
423
424 if constexpr (std::is_same_v<T, DownloadCmd>) {
425 const auto img_fmt = cmd.buffer->get_format();
426 const AVPixelFormat av_fmt = image_format_to_avpixfmt(img_fmt);
427 if (av_fmt == AV_PIX_FMT_NONE) {
429 "[VideoFileWriter] DownloadCmd: unsupported ImageFormat {}",
430 static_cast<int>(img_fmt));
431 return false;
432 }
433
434 const auto& cpu = cmd.buffer->get_pixel_data();
435 if (!cpu.empty()) {
436 if (!enc.encode_frame(cpu.data(), cpu.size(),
437 cmd.buffer->get_width(), cmd.buffer->get_height(), mux)) {
438 set_error(enc.last_error());
440 "[VideoFileWriter] encode_frame (cpu) failed: {}", enc.last_error());
441 }
442 return false;
443 }
444
445 auto tex = cmd.buffer->get_texture();
446 if (!tex) {
448 "[VideoFileWriter] DownloadCmd: no CPU pixels and no GPU texture");
449 return false;
450 }
451
452 using Portal::Graphics::TextureLoom;
453 const size_t mip0_bytes = static_cast<size_t>(tex->get_width())
454 * tex->get_height()
455 * TextureLoom::get_bytes_per_pixel(img_fmt);
456
457 if (mip0_bytes == 0)
458 return false;
459
460 std::vector<uint8_t> pixels(mip0_bytes);
461
462 if (!m_staging_buffer) {
464 }
465
466 TextureLoom::instance().download_data(tex, pixels.data(), mip0_bytes, m_staging_buffer, true);
467
468 if (!enc.encode_frame(pixels.data(), pixels.size(),
469 tex->get_width(), tex->get_height(), mux)) {
470 set_error(enc.last_error());
472 "[VideoFileWriter] encode_frame (gpu) failed: {}", enc.last_error());
473 }
474 return false;
475 }
476
477 return static_cast<bool>(std::is_same_v<T, CloseCmd>);
478 },
479 *item_opt);
480
481 if (done)
482 break;
483 }
484
485 bool ok = enc.drain(mux);
486 if (!ok) {
487 set_error(enc.last_error());
489 "[VideoFileWriter] drain failed: {}", enc.last_error());
490 }
491
492 mux.close();
493 m_open.store(false, std::memory_order_release);
494 m_close_promise.set_value(ok);
495
497 "[VideoFileWriter] worker finished: '{}' status={}",
498 filepath, ok ? "ok" : "error");
499}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
vk::CommandBuffer cmd
uint32_t width
Definition Decoder.cpp:66
const std::vector< float > * pixels
Definition Decoder.cpp:65
uint32_t height
std::shared_ptr< Buffers::VKBuffer > m_staging_buffer
void set_error(std::string msg)
std::unique_ptr< Memory::LockFreeQueue< WorkItem, k_queue_capacity > > m_queue
std::promise< bool > m_close_promise
std::shared_ptr< VKBuffer > create_image_staging_buffer(size_t size)
Allocate a persistent host-visible staging buffer sized for repeated streaming uploads to an image of...
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.

References MayaFlux::IO::FFmpegMuxContext::close(), cmd, MayaFlux::Buffers::create_image_staging_buffer(), MayaFlux::IO::VideoEncodeContext::drain(), MayaFlux::IO::VideoEncodeContext::encode_frame(), MayaFlux::Journal::FileIO, height, MayaFlux::Journal::IO, MayaFlux::IO::FFmpegMuxContext::last_error(), MayaFlux::IO::VideoEncodeContext::last_error(), m_close_promise, m_open, m_queue, m_staging_buffer, MF_ERROR, MF_INFO, MF_WARN, MayaFlux::IO::FFmpegMuxContext::open(), MayaFlux::IO::VideoEncodeContext::open(), pixels, set_error(), MayaFlux::IO::T, width, and MayaFlux::IO::FFmpegMuxContext::write_header().

Referenced by open().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: