mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-19 19:12:56 +00:00
Properly support asynchronous decoders that return multiple frames at a time
This commit is contained in:
parent
9579b2c85e
commit
80128e8293
@ -902,6 +902,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
|||||||
{
|
{
|
||||||
PLENTRY entry = du->bufferList;
|
PLENTRY entry = du->bufferList;
|
||||||
int err;
|
int err;
|
||||||
|
bool submittedFrame = false;
|
||||||
|
|
||||||
SDL_assert(!m_TestOnly);
|
SDL_assert(!m_TestOnly);
|
||||||
|
|
||||||
@ -991,6 +992,10 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
|||||||
|
|
||||||
m_FramesIn++;
|
m_FramesIn++;
|
||||||
|
|
||||||
|
// We can receive 0 or more frames after submission of a packet, so we must
|
||||||
|
// try to read until we get EAGAIN to ensure the queue is drained. Some decoders
|
||||||
|
// run asynchronously and may return several frames at once after warming up.
|
||||||
|
do {
|
||||||
AVFrame* frame = av_frame_alloc();
|
AVFrame* frame = av_frame_alloc();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
// Failed to allocate a frame but we did submit,
|
// Failed to allocate a frame but we did submit,
|
||||||
@ -1011,6 +1016,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
|||||||
av_log_set_level(AV_LOG_INFO);
|
av_log_set_level(AV_LOG_INFO);
|
||||||
|
|
||||||
// Store the presentation time
|
// Store the presentation time
|
||||||
|
// FIXME: This is wrong when reading a batch of frames
|
||||||
frame->pts = du->presentationTimeMs;
|
frame->pts = du->presentationTimeMs;
|
||||||
|
|
||||||
// Capture a frame timestamp to measuring pacing delay
|
// Capture a frame timestamp to measuring pacing delay
|
||||||
@ -1029,10 +1035,18 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
|||||||
|
|
||||||
// Queue the frame for rendering (or render now if pacer is disabled)
|
// Queue the frame for rendering (or render now if pacer is disabled)
|
||||||
m_Pacer->submitFrame(frame);
|
m_Pacer->submitFrame(frame);
|
||||||
|
submittedFrame = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
|
}
|
||||||
|
} while (err == 0);
|
||||||
|
|
||||||
|
// Treat this as a failed decode if we don't manage to receive a single frame or
|
||||||
|
// if we finish the loop above with an error other than EAGAIN. Note that some
|
||||||
|
// limited number of "failed decodes" with EAGAIN are expected for asynchronous
|
||||||
|
// decoders, so we only reset the decoder if we get a ton of them in a row.
|
||||||
|
if (!submittedFrame || err != AVERROR(EAGAIN)) {
|
||||||
char errorstring[512];
|
char errorstring[512];
|
||||||
av_strerror(err, errorstring, sizeof(errorstring));
|
av_strerror(err, errorstring, sizeof(errorstring));
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user