Fix hang on stream termination if no frames can be captured (#709)
This commit is contained in:
@@ -216,7 +216,8 @@ enum class capture_e : int {
|
|||||||
class display_t {
|
class display_t {
|
||||||
public:
|
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 -->
|
* On Break Request -->
|
||||||
* Returns nullptr
|
* Returns nullptr
|
||||||
@@ -225,7 +226,7 @@ public:
|
|||||||
* Returns the image object that should be filled next.
|
* Returns the image object that should be filled next.
|
||||||
* This may or may not be the image send with the callback
|
* 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 } {}
|
display_t() noexcept : offset_x { 0 }, offset_y { 0 } {}
|
||||||
|
|
||||||
|
|||||||
@@ -505,10 +505,10 @@ public:
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
std::this_thread::sleep_for(1ms);
|
img = snapshot_cb(img, false);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
|
|||||||
@@ -684,10 +684,10 @@ public:
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
std::this_thread::sleep_for(1ms);
|
img = snapshot_cb(img, false);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
@@ -805,10 +805,10 @@ public:
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
std::this_thread::sleep_for(1ms);
|
img = snapshot_cb(img, false);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
|
|||||||
@@ -134,9 +134,10 @@ public:
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
continue;
|
img = snapshot_cb(img, false);
|
||||||
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
@@ -239,9 +240,10 @@ public:
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
continue;
|
img = snapshot_cb(img, false);
|
||||||
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
|
|||||||
@@ -476,10 +476,10 @@ struct x11_attr_t : public display_t {
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
std::this_thread::sleep_for(1ms);
|
img = snapshot_cb(img, false);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
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:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
std::this_thread::sleep_for(1ms);
|
img = snapshot_cb(img, false);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
|
|||||||
@@ -60,11 +60,12 @@ struct av_display_t : public display_t {
|
|||||||
img_next->row_pitch = CVPixelBufferGetBytesPerRow(pixelBuffer);
|
img_next->row_pitch = CVPixelBufferGetBytesPerRow(pixelBuffer);
|
||||||
img_next->pixel_pitch = img_next->row_pitch / img_next->width;
|
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;
|
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);
|
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
|
||||||
|
|
||||||
return capture_e::ok;
|
return capture_e::ok;
|
||||||
|
|||||||
@@ -181,10 +181,11 @@ capture_e display_ram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
|
img = snapshot_cb(img, false);
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
|
|||||||
@@ -652,10 +652,11 @@ capture_e display_vram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<:
|
|||||||
case platf::capture_e::error:
|
case platf::capture_e::error:
|
||||||
return status;
|
return status;
|
||||||
case platf::capture_e::timeout:
|
case platf::capture_e::timeout:
|
||||||
|
img = snapshot_cb(img, false);
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
continue;
|
break;
|
||||||
case platf::capture_e::ok:
|
case platf::capture_e::ok:
|
||||||
img = snapshot_cb(img);
|
img = snapshot_cb(img, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int)status << ']';
|
||||||
|
|||||||
@@ -707,7 +707,7 @@ void captureThread(
|
|||||||
while(capture_ctx_queue->running()) {
|
while(capture_ctx_queue->running()) {
|
||||||
bool artificial_reinit = false;
|
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), {
|
KITTY_WHILE_LOOP(auto capture_ctx = std::begin(capture_ctxs), capture_ctx != std::end(capture_ctxs), {
|
||||||
if(!capture_ctx->images->running()) {
|
if(!capture_ctx->images->running()) {
|
||||||
capture_ctx = capture_ctxs.erase(capture_ctx);
|
capture_ctx = capture_ctxs.erase(capture_ctx);
|
||||||
@@ -715,7 +715,10 @@ void captureThread(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
capture_ctx->images->raise(img);
|
if(frame_captured) {
|
||||||
|
capture_ctx->images->raise(img);
|
||||||
|
}
|
||||||
|
|
||||||
++capture_ctx;
|
++capture_ctx;
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1274,7 +1277,7 @@ encode_e encode_run_sync(
|
|||||||
|
|
||||||
auto ec = platf::capture_e::ok;
|
auto ec = platf::capture_e::ok;
|
||||||
while(encode_session_ctx_queue.running()) {
|
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()) {
|
while(encode_session_ctx_queue.peek()) {
|
||||||
auto encode_session_ctx = encode_session_ctx_queue.pop();
|
auto encode_session_ctx = encode_session_ctx_queue.pop();
|
||||||
if(!encode_session_ctx) {
|
if(!encode_session_ctx) {
|
||||||
@@ -1318,7 +1321,7 @@ encode_e encode_run_sync(
|
|||||||
ctx->idr_events->pop();
|
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;
|
BOOST_LOG(error) << "Could not convert image"sv;
|
||||||
ctx->shutdown_event->raise(true);
|
ctx->shutdown_event->raise(true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user