Decrease normal capture buffer to single image
This commit is contained in:
@@ -125,8 +125,9 @@ namespace platf::dxgi {
|
||||
public:
|
||||
int
|
||||
init(const ::video::config_t &config, const std::string &display_name);
|
||||
|
||||
capture_e
|
||||
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
|
||||
capture(const push_captured_image_cb_t &push_captured_image_cb, const pull_free_image_cb_t &pull_free_image_cb, bool *cursor) override;
|
||||
|
||||
std::chrono::nanoseconds delay;
|
||||
|
||||
@@ -168,7 +169,7 @@ namespace platf::dxgi {
|
||||
colorspace_to_string(DXGI_COLOR_SPACE_TYPE type);
|
||||
|
||||
virtual capture_e
|
||||
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) = 0;
|
||||
snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor_visible) = 0;
|
||||
virtual int
|
||||
complete_img(img_t *img, bool dummy) = 0;
|
||||
virtual std::vector<DXGI_FORMAT>
|
||||
@@ -178,7 +179,7 @@ namespace platf::dxgi {
|
||||
class display_ram_t: public display_base_t {
|
||||
public:
|
||||
virtual capture_e
|
||||
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) override;
|
||||
snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor_visible) override;
|
||||
|
||||
std::shared_ptr<img_t>
|
||||
alloc_img() override;
|
||||
@@ -200,7 +201,7 @@ namespace platf::dxgi {
|
||||
class display_vram_t: public display_base_t, public std::enable_shared_from_this<display_vram_t> {
|
||||
public:
|
||||
virtual capture_e
|
||||
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) override;
|
||||
snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor_visible) override;
|
||||
|
||||
std::shared_ptr<img_t>
|
||||
alloc_img() override;
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace platf::dxgi {
|
||||
}
|
||||
|
||||
capture_e
|
||||
display_base_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::platf::img_t> img, bool *cursor) {
|
||||
display_base_t::capture(const push_captured_image_cb_t &push_captured_image_cb, const pull_free_image_cb_t &pull_free_image_cb, bool *cursor) {
|
||||
auto next_frame = std::chrono::steady_clock::now();
|
||||
|
||||
// Use CREATE_WAITABLE_TIMER_HIGH_RESOLUTION if supported (Windows 10 1809+)
|
||||
@@ -110,7 +110,7 @@ namespace platf::dxgi {
|
||||
CloseHandle(timer);
|
||||
});
|
||||
|
||||
while (img) {
|
||||
while (true) {
|
||||
// This will return false if the HDR state changes or for any number of other
|
||||
// display or GPU changes. We should reinit to examine the updated state of
|
||||
// the display subsystem. It is recommended to call this once per frame.
|
||||
@@ -135,16 +135,22 @@ namespace platf::dxgi {
|
||||
next_frame = std::chrono::steady_clock::now() + delay;
|
||||
}
|
||||
|
||||
auto status = snapshot(img.get(), 1000ms, *cursor);
|
||||
std::shared_ptr<img_t> img_out;
|
||||
auto status = snapshot(pull_free_image_cb, img_out, 1000ms, *cursor);
|
||||
switch (status) {
|
||||
case platf::capture_e::reinit:
|
||||
case platf::capture_e::error:
|
||||
case platf::capture_e::interrupted:
|
||||
return status;
|
||||
case platf::capture_e::timeout:
|
||||
img = snapshot_cb(img, false);
|
||||
if (!push_captured_image_cb(std::move(img_out), false)) {
|
||||
return capture_e::ok;
|
||||
}
|
||||
break;
|
||||
case platf::capture_e::ok:
|
||||
img = snapshot_cb(img, true);
|
||||
if (!push_captured_image_cb(std::move(img_out), true)) {
|
||||
return capture_e::ok;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int) status << ']';
|
||||
|
||||
@@ -171,9 +171,7 @@ namespace platf::dxgi {
|
||||
}
|
||||
|
||||
capture_e
|
||||
display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
|
||||
auto img = (img_t *) img_base;
|
||||
|
||||
display_ram_t::snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor_visible) {
|
||||
HRESULT status;
|
||||
|
||||
DXGI_OUTDUPL_FRAME_INFO frame_info;
|
||||
@@ -269,6 +267,11 @@ namespace platf::dxgi {
|
||||
}
|
||||
}
|
||||
|
||||
if (!pull_free_image_cb(img_out)) {
|
||||
return capture_e::interrupted;
|
||||
}
|
||||
auto img = (img_t *) img_out.get();
|
||||
|
||||
// If we don't know the final capture format yet, encode a dummy image
|
||||
if (capture_format == DXGI_FORMAT_UNKNOWN) {
|
||||
BOOST_LOG(debug) << "Capture format is still unknown. Encoding a blank image"sv;
|
||||
|
||||
@@ -311,6 +311,16 @@ namespace platf::dxgi {
|
||||
public:
|
||||
int
|
||||
convert(platf::img_t &img_base) override {
|
||||
// Garbage collect mapped capture images whose weak references have expired
|
||||
for (auto it = img_ctx_map.begin(); it != img_ctx_map.end();) {
|
||||
if (it->second.img_weak.expired()) {
|
||||
it = img_ctx_map.erase(it);
|
||||
}
|
||||
else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
auto &img = (img_d3d_t &) img_base;
|
||||
auto &img_ctx = img_ctx_map[img.id];
|
||||
|
||||
@@ -342,6 +352,9 @@ namespace platf::dxgi {
|
||||
// Release encoder mutex to allow capture code to reuse this image
|
||||
img_ctx.encoder_mutex->ReleaseSync(0);
|
||||
|
||||
ID3D11ShaderResourceView *emptyShaderResourceView = nullptr;
|
||||
device_ctx->PSSetShaderResources(0, 1, &emptyShaderResourceView);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -650,12 +663,15 @@ namespace platf::dxgi {
|
||||
shader_res_t encoder_input_res;
|
||||
keyed_mutex_t encoder_mutex;
|
||||
|
||||
std::weak_ptr<const platf::img_t> img_weak;
|
||||
|
||||
void
|
||||
reset() {
|
||||
capture_texture_p = nullptr;
|
||||
encoder_texture.reset();
|
||||
encoder_input_res.reset();
|
||||
encoder_mutex.reset();
|
||||
img_weak.reset();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -699,6 +715,9 @@ namespace platf::dxgi {
|
||||
}
|
||||
|
||||
img_ctx.capture_texture_p = img.capture_texture.get();
|
||||
|
||||
img_ctx.img_weak = img.weak_from_this();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -789,9 +808,7 @@ namespace platf::dxgi {
|
||||
}
|
||||
|
||||
capture_e
|
||||
display_vram_t::snapshot(platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
|
||||
auto img = (img_d3d_t *) img_base;
|
||||
|
||||
display_vram_t::snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor_visible) {
|
||||
HRESULT status;
|
||||
|
||||
DXGI_OUTDUPL_FRAME_INFO frame_info;
|
||||
@@ -839,6 +856,11 @@ namespace platf::dxgi {
|
||||
cursor_xor.set_pos(frame_info.PointerPosition.Position.x, frame_info.PointerPosition.Position.y, frame_info.PointerPosition.Visible);
|
||||
}
|
||||
|
||||
if (!pull_free_image_cb(img_out)) {
|
||||
return capture_e::interrupted;
|
||||
}
|
||||
auto img = (img_d3d_t *) img_out.get();
|
||||
|
||||
if (frame_update_flag) {
|
||||
texture2d_t src {};
|
||||
|
||||
@@ -969,6 +991,12 @@ namespace platf::dxgi {
|
||||
}
|
||||
|
||||
device_ctx->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu);
|
||||
|
||||
ID3D11RenderTargetView *emptyRenderTarget = nullptr;
|
||||
device_ctx->OMSetRenderTargets(1, &emptyRenderTarget, nullptr);
|
||||
device_ctx->RSSetViewports(0, nullptr);
|
||||
ID3D11ShaderResourceView *emptyShaderResourceView = nullptr;
|
||||
device_ctx->PSSetShaderResources(0, 1, &emptyShaderResourceView);
|
||||
}
|
||||
|
||||
// Release the mutex to allow encoding of this frame
|
||||
|
||||
Reference in New Issue
Block a user