diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index e8751da9..7dba7041 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -1054,15 +1054,16 @@ void FFmpegVideoDecoder::decoderThreadProc() frame->pkt_dts = SDL_GetTicks(); if (!m_FrameInfoQueue.isEmpty()) { - FrameInfoTuple infoTuple = m_FrameInfoQueue.dequeue(); + // Data buffers in the DU are not valid here! + DECODE_UNIT du = m_FrameInfoQueue.dequeue(); // Count time in avcodec_send_packet() and avcodec_receive_frame() // as time spent decoding. Also count time spent in the decode unit // queue because that's directly caused by decoder latency. - m_ActiveWndVideoStats.totalDecodeTime += LiGetMillis() - infoTuple.enqueueTimeMs; + m_ActiveWndVideoStats.totalDecodeTime += LiGetMillis() - du.enqueueTimeMs; // Store the presentation time - frame->pts = infoTuple.presentationTimeMs; + frame->pts = du.presentationTimeMs; } m_ActiveWndVideoStats.decodedFrames++; @@ -1087,9 +1088,14 @@ void FFmpegVideoDecoder::decoderThreadProc() } else { char errorstring[512]; + + // FIXME: Should we pop an entry off m_FrameInfoQueue here? + av_strerror(err, errorstring, sizeof(errorstring)); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "avcodec_receive_frame() failed: %s", errorstring); + "avcodec_receive_frame() failed: %s (frame %d)", + errorstring, + !m_FrameInfoQueue.isEmpty() ? m_FrameInfoQueue.head().frameNumber : -1); if (++m_ConsecutiveFailedDecodes == FAILED_DECODES_RESET_THRESHOLD) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -1197,7 +1203,9 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) char errorstring[512]; av_strerror(err, errorstring, sizeof(errorstring)); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "avcodec_send_packet() failed: %s", errorstring); + "avcodec_send_packet() failed: %s (frame %d)", + errorstring, + du->frameNumber); // If we've failed a bunch of decodes in a row, the decoder/renderer is // clearly unhealthy, so let's generate a synthetic reset event to trigger @@ -1217,7 +1225,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) return DR_NEED_IDR; } - m_FrameInfoQueue.enqueue({ du->enqueueTimeMs, du->presentationTimeMs}); + m_FrameInfoQueue.enqueue(*du); m_FramesIn++; return DR_OK; diff --git a/app/streaming/video/ffmpeg.h b/app/streaming/video/ffmpeg.h index a983569c..847bb406 100644 --- a/app/streaming/video/ffmpeg.h +++ b/app/streaming/video/ffmpeg.h @@ -84,11 +84,8 @@ private: SDL_Thread* m_DecoderThread; SDL_atomic_t m_DecoderThreadShouldQuit; - typedef struct { - uint64_t enqueueTimeMs; - uint32_t presentationTimeMs; - } FrameInfoTuple; - QQueue m_FrameInfoQueue; + // Data buffers in the queued DU are not valid + QQueue m_FrameInfoQueue; static const uint8_t k_H264TestFrame[]; static const uint8_t k_HEVCMainTestFrame[]; diff --git a/app/streaming/video/slvid.cpp b/app/streaming/video/slvid.cpp index d35b26a9..f270ba64 100644 --- a/app/streaming/video/slvid.cpp +++ b/app/streaming/video/slvid.cpp @@ -123,8 +123,9 @@ SLVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) err = SLVideo_BeginFrame(m_VideoStream, du->fullLength); if (err < 0) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "SLVideo_BeginFrame() failed: %d", - err); + "SLVideo_BeginFrame() failed: %d (frame %d)", + err, + du->frameNumber); // Need an IDR frame to resync return DR_NEED_IDR; @@ -137,8 +138,9 @@ SLVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) entry->length); if (err < 0) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "SLVideo_WriteFrameData() failed: %d", - err); + "SLVideo_WriteFrameData() failed: %d (frame %d)", + err, + du->frameNumber); // Need an IDR frame to resync return DR_NEED_IDR; @@ -150,8 +152,9 @@ SLVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) err = SLVideo_SubmitFrame(m_VideoStream); if (err < 0) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "SLVideo_SubmitFrame() failed: %d", - err); + "SLVideo_SubmitFrame() failed: %d (frame %d)", + err, + du->frameNumber); // Need an IDR frame to resync return DR_NEED_IDR;