Verify startup codec preparation keeps GUI responsive and reuses probes
This commit is contained in:
1 parent
91478e2593
commit
36e8ab228c
2 files changed
+27
-1
No files matched your search
@@ -25,10 +25,15 @@ static int64_t start;
|
||||
static bool disturbed = false;
|
||||
static bool slowDecoder = false, holdAck = false, limitedDisplay = false;
|
||||
static std::atomic<unsigned> decodedFrames{0};
|
||||
static std::atomic<unsigned> codecOpens{0};
|
||||
static std::atomic<size_t> displayThread{0};
|
||||
static std::atomic<bool> unsafeTimer{false};
|
||||
static size_t threadId() { return std::hash<std::thread::id>{}(std::this_thread::get_id()); }
|
||||
static int64_t nowUs() { return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); }
|
||||
extern "C" int __real_avcodec_open2(AVCodecContext*, const AVCodec*, AVDictionary**);
|
||||
extern "C" int __wrap_avcodec_open2(AVCodecContext* context, const AVCodec* codec, AVDictionary** options) {
|
||||
++codecOpens; return __real_avcodec_open2(context, codec, options);
|
||||
}
|
||||
extern "C" int __real_avcodec_receive_frame(AVCodecContext*, AVFrame*);
|
||||
extern "C" int __wrap_avcodec_receive_frame(AVCodecContext* codec, AVFrame* frame) {
|
||||
if (threadId() == displayThread.load()) unsafeTimer = true;
|
||||
@@ -110,6 +115,27 @@ static bool queuePressure() {
|
||||
int main(int argc, char** argv) {
|
||||
QCoreApplication app(argc, argv); debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN);
|
||||
debug_set_category_level(DEBUG_CATEGORY_CALL, DEBUG_LEVEL_DEBUG);
|
||||
// Как при старте GUI: подготовка в worker, event loop работает, повторный вызов не открывает codec.
|
||||
std::atomic<bool> preparing{true}, prepared{false};
|
||||
call_video_caps ready{};
|
||||
std::thread warmup([&] { ready = CallVideoEngine::capabilities(&preparing); prepared = true; });
|
||||
QTimer pulse; pulse.setInterval(10); unsigned ticks = 0;
|
||||
QObject::connect(&pulse, &QTimer::timeout, [&] { ++ticks; }); pulse.start();
|
||||
const int64_t warming = nowUs();
|
||||
while (!prepared && nowUs() - warming < 10000000) { app.processEvents(); QThread::msleep(1); }
|
||||
preparing = false; warmup.join(); pulse.stop();
|
||||
if (!ticks || !ready.decode[0].profiles || !ready.decode[1].profiles || !codecOpens) return 1;
|
||||
const unsigned opened = codecOpens;
|
||||
const auto cancelled = CallVideoEngine::capabilities(&preparing);
|
||||
if (cancelled.encode[0].profiles || cancelled.decode[0].profiles) return 1;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const auto cached = CallVideoEngine::capabilities();
|
||||
uint8_t expected[CALL_VIDEO_CAPS_BYTES], actual[CALL_VIDEO_CAPS_BYTES];
|
||||
if (call_video_caps_encode(&ready, expected) || call_video_caps_encode(&cached, actual)
|
||||
|| memcmp(expected, actual, sizeof(actual)) || codecOpens != opened) return 1;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "PASS video background preparation elapsed_us=%lld gui_ticks=%u codec_opens=%u; "
|
||||
"cancelled access preserves cache, three warm accesses open no codecs", (long long)(nowUs() - warming), ticks, opened);
|
||||
if (!queuePressure()) return 1;
|
||||
CallVideoEncoder encoder; if (!encoder.open(format, 1000000, "libx264")) return 2;
|
||||
QImage image(640, 360, QImage::Format_RGB32); image.fill(Qt::blue);
|
||||
|
||||
Reference in new issue
Block a user