MayaFlux 0.4.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 368 of file VideoFileWriter.cpp.

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

References MayaFlux::IO::FFmpegMuxContext::close(), cmd, MayaFlux::IO::VideoEncodeContext::drain(), MayaFlux::IO::VideoEncodeContext::encode_frame(), MayaFlux::Journal::FileIO, MayaFlux::Journal::IO, MayaFlux::IO::FFmpegMuxContext::last_error(), MayaFlux::IO::VideoEncodeContext::last_error(), m_close_promise, m_open, m_queue, 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: