Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ bl::sources::severity_logger<int> error(4); // Recoverable errors
bl::sources::severity_logger<int> fatal(5); // Unrecoverable errors

bool display_cursor = true;
bool force_callback = false;

using text_sink = bl::sinks::asynchronous_sink<bl::sinks::text_ostream_backend>;
boost::shared_ptr<text_sink> sink;
Expand Down
1 change: 1 addition & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

extern util::ThreadPool task_pool;
extern bool display_cursor;
extern bool force_callback;

extern boost::log::sources::severity_logger<int> verbose;
extern boost::log::sources::severity_logger<int> debug;
Expand Down
10 changes: 6 additions & 4 deletions src/platform/windows/display_vram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,14 +573,16 @@ capture_e display_vram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<:
}
next_frame = now + delay;

auto status = snapshot(img.get(), 1000ms, *cursor);
auto status = snapshot(img.get(), force_callback ? std::chrono::duration_cast<std::chrono::milliseconds>(delay * 2) : 1000ms, *cursor);
switch(status) {
case platf::capture_e::reinit:
case platf::capture_e::error:
return status;
case platf::capture_e::timeout:
std::this_thread::sleep_for(1ms);
continue;
if(!force_callback) {
std::this_thread::sleep_for(1ms);
continue;
}
case platf::capture_e::ok:
img = snapshot_cb(img);
break;
Expand Down Expand Up @@ -885,4 +887,4 @@ int init() {

return 0;
}
} // namespace platf::dxgi
} // namespace platf::dxgi
18 changes: 13 additions & 5 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_c
util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);

int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format);
int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format, bool amf_lowlatency);

class swdevice_t : public platf::hwdevice_t {
public:
Expand Down Expand Up @@ -240,6 +240,7 @@ enum flag_e {
H264_ONLY = 0x02, // When HEVC is too heavy
LIMITED_GOP_SIZE = 0x04, // Some encoders don't like it when you have an infinite GOP_SIZE. *cough* VAAPI *cough*
SINGLE_SLICE_ONLY = 0x08, // Never use multiple slices <-- Older intel iGPU's ruin it for everyone else :P
FORCE_CALLBACK = 0x10, // Force callbacks with short timeouts for encoders that don't perform well with callback-based capture
};

struct encoder_t {
Expand Down Expand Up @@ -438,7 +439,7 @@ static encoder_t nvenc {
"h264_nvenc"s,
},
#ifdef _WIN32
DEFAULT,
FORCE_CALLBACK,
dxgi_make_hwdevice_ctx
#else
PARALLEL_ENCODING,
Expand Down Expand Up @@ -474,7 +475,7 @@ static encoder_t amdvce {
std::make_optional<encoder_t::option_t>({ "qp_p"s, &config::video.qp }),
"h264_amf"s,
},
DEFAULT,
FORCE_CALLBACK,
dxgi_make_hwdevice_ctx
};
#endif
Expand Down Expand Up @@ -931,7 +932,7 @@ std::optional<session_t> make_session(const encoder_t &encoder, const config_t &
}

hwdevice_ctx = std::move(buf_or_error.left());
if(hwframe_ctx(ctx, hwdevice_ctx, sw_fmt)) {
if(hwframe_ctx(ctx, hwdevice_ctx, sw_fmt, (encoder.name == "amdvce"sv))) {
return std::nullopt;
}

Expand Down Expand Up @@ -1404,6 +1405,7 @@ void capture(
void *channel_data) {

auto idr_events = mail->event<bool>(mail::idr);
force_callback = encoders.front().flags & FORCE_CALLBACK;

idr_events->raise(true);
if(encoders.front().flags & PARALLEL_ENCODING) {
Expand Down Expand Up @@ -1680,7 +1682,7 @@ int init() {
return 0;
}

int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format) {
int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format, bool amf_lowlatency) {
buffer_t frame_ref { av_hwframe_ctx_alloc(hwdevice.get()) };

auto frame_ctx = (AVHWFramesContext *)frame_ref->data;
Expand All @@ -1694,6 +1696,12 @@ int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format) {
return err;
}

if(amf_lowlatency) {
// reduce amf encoder's hw buffers from 16 -> 2 to minimize buffered frames
// note: pool size is deliberately set after initialization
frame_ctx->initial_pool_size = 3;
}

ctx->hw_frames_ctx = av_buffer_ref(frame_ref.get());

return 0;
Expand Down