mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-28 13:04:07 +08:00
fix VP9 frame state after parse failure
This commit is contained in:
@@ -247,6 +247,8 @@ bool VP9RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
|
|||||||
int offset = info.parse(payload, payload_size);
|
int offset = info.parse(payload, payload_size);
|
||||||
if (offset < 0 || static_cast<size_t>(offset) >= payload_size) {
|
if (offset < 0 || static_cast<size_t>(offset) >= payload_size) {
|
||||||
WarnL << "VP9 RTP payload parse failed, seq:" << seq;
|
WarnL << "VP9 RTP payload parse failed, seq:" << seq;
|
||||||
|
_frame_drop = true;
|
||||||
|
_frame->_buffer.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// InfoL << rtp->dumpString() << "\n" << info.dump();
|
// InfoL << rtp->dumpString() << "\n" << info.dump();
|
||||||
|
|||||||
@@ -59,6 +59,31 @@ void runCase(const ParseCase &test) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testParseFailureDropsCurrentFrame() {
|
||||||
|
VP9RtpDecoder decoder;
|
||||||
|
std::vector<std::string> 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<unsigned char> &payload, bool mark) {
|
||||||
|
auto rtp = rtp_info.makeRtp(TrackVideo, payload.data(), payload.size(), mark, 100);
|
||||||
|
require(rtp != nullptr, "failed to create RTP packet for parse-failure recovery test");
|
||||||
|
decoder.inputRtp(rtp, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
input({ 0x08, 0x80, 0x11 }, false); // B: begin assembling a frame.
|
||||||
|
input({ 0x50, 0x03 }, false); // Truncated P_DIFF chain.
|
||||||
|
input({ 0x04, 0x22 }, true); // E: must not emit the incomplete frame.
|
||||||
|
require(frames.empty(), "parse failure emitted a partial VP9 frame");
|
||||||
|
|
||||||
|
input({ 0x0C, 0x80, 0x33 }, true); // A new complete frame must recover normally.
|
||||||
|
require(frames.size() == 1, "decoder did not recover after a VP9 parse failure");
|
||||||
|
require(frames[0] == std::string("\x80\x33", 2), "recovered VP9 frame payload does not match");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@@ -94,5 +119,6 @@ int main() {
|
|||||||
|
|
||||||
runCase({ "descriptor only", { 0x00 }, -1 });
|
runCase({ "descriptor only", { 0x00 }, -1 });
|
||||||
runCase({ "layer descriptor only", { 0x30, 0x00 }, -1 });
|
runCase({ "layer descriptor only", { 0x30, 0x00 }, -1 });
|
||||||
|
testParseFailureDropsCurrentFrame();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user