Fix hang on stream termination if no frames can be captured (#709)

This commit is contained in:
Cameron Gutman 2023-01-05 10:21:38 -06:00 committed by GitHub
parent f1c225fccc
commit 00aa23b342
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 39 additions and 30 deletions

View File

@ -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_t>(std::shared_ptr<img_t> &img)>;
using snapshot_cb_t = std::function<std::shared_ptr<img_t>(std::shared_ptr<img_t> &img, bool frame_captured)>;
display_t() noexcept : offset_x { 0 }, offset_y { 0 } {}

View File

@ -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 << ']';

View File

@ -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 << ']';

View File

@ -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 << ']';

View File

@ -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 << ']';

View File

@ -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;

View File

@ -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 << ']';

View File

@ -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 << ']';

View File

@ -707,7 +707,7 @@ void captureThread(
while(capture_ctx_queue->running()) {
bool artificial_reinit = false;
auto status = disp->capture([&](std::shared_ptr<platf::img_t> &img) -> std::shared_ptr<platf::img_t> {
auto status = disp->capture([&](std::shared_ptr<platf::img_t> &img, bool frame_captured) -> std::shared_ptr<platf::img_t> {
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<platf::img_t> &img) -> std::shared_ptr<platf::img_t> {
auto snapshot_cb = [&](std::shared_ptr<platf::img_t> &img, bool frame_captured) -> std::shared_ptr<platf::img_t> {
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);