diff --git a/src/platform/common.h b/src/platform/common.h index 4a778269..732b56bb 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -216,7 +216,8 @@ enum class capture_e : int { class display_t { public: /** - * When display has a new image ready, this callback will be called with the new image. + * When display has a new image ready or a timeout occurs, this callback will be called with the image. + * If a frame was captured, frame_captured will be true. If a timeout occurred, it will be false. * * On Break Request --> * Returns nullptr @@ -225,7 +226,7 @@ public: * Returns the image object that should be filled next. * This may or may not be the image send with the callback */ - using snapshot_cb_t = std::function(std::shared_ptr &img)>; + using snapshot_cb_t = std::function(std::shared_ptr &img, bool frame_captured)>; display_t() noexcept : offset_x { 0 }, offset_y { 0 } {} diff --git a/src/platform/linux/cuda.cpp b/src/platform/linux/cuda.cpp index faef891d..963d7c35 100644 --- a/src/platform/linux/cuda.cpp +++ b/src/platform/linux/cuda.cpp @@ -505,10 +505,10 @@ public: case platf::capture_e::error: return status; case platf::capture_e::timeout: - std::this_thread::sleep_for(1ms); - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index 8a756716..2c84baea 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -684,10 +684,10 @@ public: case platf::capture_e::error: return status; case platf::capture_e::timeout: - std::this_thread::sleep_for(1ms); - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; @@ -805,10 +805,10 @@ public: case platf::capture_e::error: return status; case platf::capture_e::timeout: - std::this_thread::sleep_for(1ms); - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; diff --git a/src/platform/linux/wlgrab.cpp b/src/platform/linux/wlgrab.cpp index 486ed8e4..20d89572 100644 --- a/src/platform/linux/wlgrab.cpp +++ b/src/platform/linux/wlgrab.cpp @@ -134,9 +134,10 @@ public: case platf::capture_e::error: return status; case platf::capture_e::timeout: - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; @@ -239,9 +240,10 @@ public: case platf::capture_e::error: return status; case platf::capture_e::timeout: - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; diff --git a/src/platform/linux/x11grab.cpp b/src/platform/linux/x11grab.cpp index c024f4d8..1f8f5b73 100644 --- a/src/platform/linux/x11grab.cpp +++ b/src/platform/linux/x11grab.cpp @@ -476,10 +476,10 @@ struct x11_attr_t : public display_t { case platf::capture_e::error: return status; case platf::capture_e::timeout: - std::this_thread::sleep_for(1ms); - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; @@ -587,10 +587,10 @@ struct shm_attr_t : public x11_attr_t { case platf::capture_e::error: return status; case platf::capture_e::timeout: - std::this_thread::sleep_for(1ms); - continue; + img = snapshot_cb(img, false); + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; diff --git a/src/platform/macos/display.mm b/src/platform/macos/display.mm index 8845fbac..a53ac0e6 100644 --- a/src/platform/macos/display.mm +++ b/src/platform/macos/display.mm @@ -60,11 +60,12 @@ struct av_display_t : public display_t { img_next->row_pitch = CVPixelBufferGetBytesPerRow(pixelBuffer); img_next->pixel_pitch = img_next->row_pitch / img_next->width; - img_next = snapshot_cb(img_next); + img_next = snapshot_cb(img_next, true); return img_next != nullptr; }]; + // FIXME: We should time out if an image isn't returned for a while dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER); return capture_e::ok; diff --git a/src/platform/windows/display_ram.cpp b/src/platform/windows/display_ram.cpp index b5c026db..c5ce6dc3 100644 --- a/src/platform/windows/display_ram.cpp +++ b/src/platform/windows/display_ram.cpp @@ -181,10 +181,11 @@ capture_e display_ram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<:: case platf::capture_e::error: return status; case platf::capture_e::timeout: + img = snapshot_cb(img, false); std::this_thread::sleep_for(1ms); - continue; + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index 75e77b6e..354942b4 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -652,10 +652,11 @@ capture_e display_vram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<: case platf::capture_e::error: return status; case platf::capture_e::timeout: + img = snapshot_cb(img, false); std::this_thread::sleep_for(1ms); - continue; + break; case platf::capture_e::ok: - img = snapshot_cb(img); + img = snapshot_cb(img, true); break; default: BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']'; diff --git a/src/video.cpp b/src/video.cpp index 89646dda..88962167 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -707,7 +707,7 @@ void captureThread( while(capture_ctx_queue->running()) { bool artificial_reinit = false; - auto status = disp->capture([&](std::shared_ptr &img) -> std::shared_ptr { + auto status = disp->capture([&](std::shared_ptr &img, bool frame_captured) -> std::shared_ptr { KITTY_WHILE_LOOP(auto capture_ctx = std::begin(capture_ctxs), capture_ctx != std::end(capture_ctxs), { if(!capture_ctx->images->running()) { capture_ctx = capture_ctxs.erase(capture_ctx); @@ -715,7 +715,10 @@ void captureThread( continue; } - capture_ctx->images->raise(img); + if(frame_captured) { + capture_ctx->images->raise(img); + } + ++capture_ctx; }) @@ -1274,7 +1277,7 @@ encode_e encode_run_sync( auto ec = platf::capture_e::ok; while(encode_session_ctx_queue.running()) { - auto snapshot_cb = [&](std::shared_ptr &img) -> std::shared_ptr { + auto snapshot_cb = [&](std::shared_ptr &img, bool frame_captured) -> std::shared_ptr { while(encode_session_ctx_queue.peek()) { auto encode_session_ctx = encode_session_ctx_queue.pop(); if(!encode_session_ctx) { @@ -1318,7 +1321,7 @@ encode_e encode_run_sync( ctx->idr_events->pop(); } - if(pos->session.device->convert(*img)) { + if(frame_captured && pos->session.device->convert(*img)) { BOOST_LOG(error) << "Could not convert image"sv; ctx->shutdown_event->raise(true);