Recover real GPU decoder failures on CPU without treating ordinary EAGAIN as frame loss

This commit is contained in:
evgeny committed 2026-10-19 19:14:03 +02:00
1 parent f9348ce36f
commit a4a687be4c
3 files changed
+25 -5

No files matched your search

+7
View File
@@ -82,6 +82,11 @@ unsigned CallVideoDecoder::pendingFrames() const { return static_cast<unsigned>(
unsigned CallVideoDecoder::pipelineFrames() const { return m->pipeline; }
bool CallVideoDecoder::hardware() const { return m->gpu; }
QString CallVideoDecoder::error() const { return m->error; }
void CallVideoDecoder::useSoftware() {
DEBUG_WARN(DEBUG_CATEGORY_CALL, "video decoder switching to CPU after device failure pending=%zu; next input must be KEY",
m->pending.size());
close(); m->backend = Backend::SoftwareOnly;
}
void CallVideoDecoder::close() {
#ifdef HAVE_FFMPEG
if (m->codec) DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "video decoder close generation=%llu pending=%zu eos=%d",
@@ -107,6 +112,8 @@ int CallVideoDecoder::submit(const call_video_frame& f) {
#ifdef HAVE_FFMPEG
if (!call_video_format_valid(&f.format) || !f.data || !f.size || f.size > CALL_VIDEO_MAX_FRAME)
return m->failed("input format", AVERROR_INVALIDDATA);
if (!m->pending.empty() && f.pts_us <= m->pending.back().pts_us)
return m->failed("non-monotonic input PTS", AVERROR_INVALIDDATA);
const uint8_t* data = f.data; unsigned size = f.size;
if (f.flags & CALL_VIDEO_KEY) {
if (call_video_check_key(&f.format, data, size)) return m->failed("KEY bitstream", AVERROR_INVALIDDATA);