From 084dcabe0a56339f1b6e3334ee4d7dafd6cc5e3e Mon Sep 17 00:00:00 2001 From: YuLi Date: Fri, 31 Jul 2026 06:57:40 +0000 Subject: [PATCH] fix --- ext-codec/VP9Rtp.cpp | 1 + tests/test_vp9_rtp.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ext-codec/VP9Rtp.cpp b/ext-codec/VP9Rtp.cpp index bec8659d..6f342c6f 100644 --- a/ext-codec/VP9Rtp.cpp +++ b/ext-codec/VP9Rtp.cpp @@ -251,6 +251,7 @@ bool VP9RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) { // descriptor must still leave at least one byte of VP9 frame payload. if (offset < 0 || static_cast(offset) >= payload_size) { WarnL << "VP9 RTP payload parse failed, seq:" << seq; + _gop_dropped = true; _frame_drop = true; _frame->_buffer.clear(); return false; diff --git a/tests/test_vp9_rtp.cpp b/tests/test_vp9_rtp.cpp index 2d2ecb63..3c5694b9 100644 --- a/tests/test_vp9_rtp.cpp +++ b/tests/test_vp9_rtp.cpp @@ -85,6 +85,32 @@ void testParseFailureDropsCurrentFrame(const char *name, const std::vector frames; + decoder.addDelegate([&](const Frame::Ptr &frame) { + frames.emplace_back(frame->data(), frame->size()); + return true; + }); + + RtpInfo rtp_info(0x12345678, 1400, 90000, 98, 0, 0); + auto input = [&](const std::vector &payload) { + auto rtp = rtp_info.makeRtp(TrackVideo, payload.data(), payload.size(), true, 100); + require(rtp != nullptr, "failed to create RTP packet for GOP recovery test"); + decoder.inputRtp(rtp, false); + }; + + input({ 0x50, 0x03 }); // Reject a truncated P_DIFF chain. + input({ 0x4C, 0x00, 0x44 }); // Suppress a dependent P-frame. + require(frames.empty(), "parse failure did not suppress the damaged GOP"); + + input({ 0x0C, 0x80, 0x55 }); // A keyframe starts a new GOP. + input({ 0x4C, 0x00, 0x66 }); // Its dependent P-frame is valid again. + require(frames.size() == 2, "decoder did not recover at the next VP9 keyframe"); + require(frames[0] == std::string("\x80\x55", 2), "recovery keyframe payload does not match"); + require(frames[1] == std::string("\x00\x66", 2), "recovered P-frame payload does not match"); +} + } // namespace int main() { @@ -122,5 +148,6 @@ int main() { runCase({ "reject layer-descriptor-only payload", { 0x30, 0x00 }, -1 }); testParseFailureDropsCurrentFrame("truncated P_DIFF", { 0x50, 0x03 }); testParseFailureDropsCurrentFrame("descriptor-only middle packet", { 0x00 }); + testParseFailureDropsGop(); return 0; }