VNC-151 Fixed fallbac logic

This commit is contained in:
El 2026-02-26 09:41:07 +00:00
parent 10b1c632c2
commit 276b90b3ec
No known key found for this signature in database
GPG key ID: EB3F4C9EA29CDE59
3 changed files with 35 additions and 20 deletions

View file

@ -505,7 +505,8 @@ bool EncodeManager::updateVideo(const Region &changed, const ScreenSet &layout,
return false;
static const Palette palette;
screen_encoder_manager->writeRect(pb, palette);
if (!screen_encoder_manager->writeFrame(pb, palette))
return false;
std::vector<Rect> rects;
changed.get_rects(&rects);

View file

@ -30,7 +30,7 @@ namespace rfb {
static LogWriter vlog("ScreenEncoderManager");
template<uint8_t T>
ScreenEncoderManager<T>::ScreenEncoderManager(const FFmpeg &ffmpeg_, KasmVideoEncoders::EncoderConfig encoder,
ScreenEncoderManager<T>::ScreenEncoderManager(const FFmpeg &ffmpeg_, const KasmVideoEncoders::EncoderConfig &encoder,
const KasmVideoEncoders::EncoderConfigs &encoders, SConnection *conn, VideoEncoderParams params) :
Encoder(conn, encodingKasmVideo, static_cast<EncoderFlags>(EncoderUseNativePF | EncoderLossy), -1),
ffmpeg(ffmpeg_),
@ -55,7 +55,7 @@ namespace rfb {
}
template<uint8_t T>
void ScreenEncoderManager<T>::set_params(KasmVideoEncoders::EncoderConfig encoder,
void ScreenEncoderManager<T>::set_params(const KasmVideoEncoders::EncoderConfig &encoder,
const KasmVideoEncoders::EncoderConfigs &encoders, VideoEncoderParams params) {
base_video_encoder = encoder;
available_encoders = encoders;
@ -109,9 +109,9 @@ namespace rfb {
delete screens[index].encoder;
screens[index].encoder = nullptr;
mask &= ~(1 << index);
--count;
}
mask &= ~(1 << index);
screens[index] = {};
}
@ -131,8 +131,12 @@ namespace rfb {
template<uint8_t T>
void ScreenEncoderManager<T>::clear_screens() {
for (uint8_t i = 0; i < get_screen_count(); ++i)
remove_screen(i);
uint64_t remaining_mask = mask;
while (remaining_mask) {
const auto pos = __builtin_ctzll(remaining_mask);
remove_screen(pos);
remaining_mask &= remaining_mask - 1;
}
}
template<uint8_t T>
@ -149,8 +153,8 @@ namespace rfb {
for (uint8_t i = 0; i < static_cast<uint8_t>(layout.num_screens()); ++i) {
const auto &screen = layout.screens[i];
auto id = screen.id;
if (id > T) {
vlog.error("Wrong id");
if (id >= T) {
vlog.error("Wrong id");
id = 0;
}
@ -178,21 +182,16 @@ namespace rfb {
}
template<uint8_t T>
void ScreenEncoderManager<T>::writeRect(const PixelBuffer *pb, const Palette &palette) {
// if (!pb) {
// vlog.error("writeRect called with null PixelBuffer");
// return;
// }
bool ScreenEncoderManager<T>::writeFrame(const PixelBuffer *pb, const Palette &palette) {
if (screens_to_refresh.empty())
return;
return true;
const auto bpp = conn->cp.pf().bpp >> 3;
auto *out_conn = conn->getOutStream(conn->cp.supportsUdp);
if (!out_conn) {
vlog.error("writeRect: getOutStream returned NULL");
return;
return false;
}
const auto send_frame = [this, &bpp, out_conn, pb, &palette](screen_t &screen) {
@ -218,13 +217,23 @@ namespace rfb {
};
if (screens_to_refresh.size() > 1) {
tbb::parallel_for_each(screens_to_refresh.begin(), screens_to_refresh.end(), [this, pb, &send_frame](uint8_t index) {
tbb::task_group_context ctx;
tbb::parallel_for_each(screens_to_refresh.begin(), screens_to_refresh.end(), [this, pb, &ctx](uint8_t index) {
if (ctx.is_group_execution_cancelled())
return;
auto &screen = screens[index];
if (auto *encoder = screen.encoder; encoder) {
screen.dirty = encoder->render(pb);
if (!screen.dirty)
ctx.cancel_group_execution();
}
});
if (ctx.is_group_execution_cancelled())
return false;
for (auto index: screens_to_refresh) {
auto &screen = screens[index];
if (screen.dirty) {
@ -235,8 +244,12 @@ namespace rfb {
if (auto encoder = screens[head].encoder; encoder) {
if (encoder->render(pb))
send_frame(screens[head]);
else
return false;
}
}
return true;
}
template<uint8_t T>

View file

@ -83,7 +83,7 @@ namespace rfb {
return screens.end();
}
explicit ScreenEncoderManager(const FFmpeg &ffmpeg_, KasmVideoEncoders::EncoderConfig encoder,
explicit ScreenEncoderManager(const FFmpeg &ffmpeg_, const KasmVideoEncoders::EncoderConfig &encoder,
const KasmVideoEncoders::EncoderConfigs &encoders, SConnection *conn, VideoEncoderParams params);
~ScreenEncoderManager() override;
@ -93,7 +93,7 @@ namespace rfb {
ScreenEncoderManager &operator=(ScreenEncoderManager &&) = delete;
void clear();
void set_params(KasmVideoEncoders::EncoderConfig encoder, const KasmVideoEncoders::EncoderConfigs &encoders,
void set_params(const KasmVideoEncoders::EncoderConfig &encoder, const KasmVideoEncoders::EncoderConfigs &encoders,
VideoEncoderParams params);
bool sync_layout(const ScreenSet &layout, const Region &region);
@ -104,7 +104,8 @@ namespace rfb {
// Encoder
[[nodiscard]] bool isSupported() const override;
void writeRect(const PixelBuffer *pb, const Palette &palette) override;
bool writeFrame(const PixelBuffer *pb, const Palette &palette);
void writeRect(const PixelBuffer *pb, const Palette &palette) override {}
void writeSolidRect(int width, int height, const PixelFormat &pf, const rdr::U8 *colour) override;
private: