Add explicit bounded slice threading for software replay decoding

This commit is contained in:
firestar5683
2026-09-19 17:39:12 -07:00
parent 4dcde78413
commit e7b3b28849
3 changed files with 45 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// Zero means unspecified: preserve FFmpeg's existing default behavior.
inline int replay_decode_threads(const char *value) {
if (value == nullptr) return 0;
if (value[0] >= '1' && value[0] <= '4' && value[1] == '\0') return value[0] - '0';
return -1;
}
+25
View File
@@ -1,6 +1,8 @@
#include "tools/replay/framereader.h"
#include <map>
#include <cstdlib>
#include "tools/replay/decode_threads.h"
#include <memory>
#include <tuple>
#include <utility>
@@ -152,10 +154,33 @@ bool FFmpegVideoDecoder::open(AVCodecParameters *codecpar, bool hw_decoder) {
rWarning("No device with hardware decoder found. fallback to CPU decoding.");
}
const int slice_threads = replay_decode_threads(std::getenv("ROADSCORE_REPLAY_DECODE_THREADS"));
if (slice_threads < 0) {
rError("ROADSCORE_REPLAY_DECODE_THREADS must be an integer from 1 to 4");
return false;
}
const bool configure_slices = slice_threads > 0 && hw_device_ctx == nullptr;
if (configure_slices) {
if (!(decoder->capabilities & AV_CODEC_CAP_SLICE_THREADS)) {
rError("Requested software decoder does not support slice threading");
return false;
}
decoder_ctx->thread_count = slice_threads;
decoder_ctx->thread_type = FF_THREAD_SLICE;
}
if (avcodec_open2(decoder_ctx, decoder, nullptr) < 0) {
rError("Failed to open codec");
return false;
}
if (configure_slices) {
rInfo("REPLAY_SOFTWARE_DECODER requested_threads=%d threads=%d active_thread_type=%d", slice_threads,
decoder_ctx->thread_count, decoder_ctx->active_thread_type);
if (decoder_ctx->active_thread_type & FF_THREAD_FRAME) {
rError("Frame threading is incompatible with replay's immediate-frame decoder");
return false;
}
}
return true;
}
+12
View File
@@ -0,0 +1,12 @@
#include <cassert>
#include <initializer_list>
#include "tools/replay/decode_threads.h"
int main() {
assert(replay_decode_threads(nullptr) == 0);
assert(replay_decode_threads("1") == 1);
assert(replay_decode_threads("2") == 2);
assert(replay_decode_threads("4") == 4);
for (const char *value : {"", "0", "5", "-1", "2x", " 2", "2 ", "9999999999999999999"}) {
assert(replay_decode_threads(value) == -1);
}
}