mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-24 02:09:03 +03:00
ff_rtp_parse_packet() drains a depacketizer's internally buffered data on the follow-up buf==NULL call only while s->prev_ret > 0. The "while (rv < 0 && has_next_packet(s))" reordering loop delivered queued packets without updating s->prev_ret, so when a packet was returned from that loop, prev_ret kept its stale negative value and the next buf==NULL call was routed into the (now empty) reordering queue instead of back into the depacketizer. For MPEG-2 TS this drops data: when an RTP payload carries a payload unit start indicator (PUSI) on a TS packet other than the first, the depacketizer returns the finished PES, buffers the rest of the payload and returns 1, expecting a buf==NULL call to fetch the remainder. A plain continuation payload (no PUSI, the common case) completes no PES and returns < 0, which is enough to enter the loop above; if the next queued packet carries a mid-payload PUSI, its buffered tail (the TS packets from the PUSI onwards) is never drained and is lost. A single reordered pair of packets triggers this, so the loss occurs rather frequently, not only under heavy reordering. Update s->prev_ret inside the loop and add libavformat/tests/rtpdec.c, which drives the real MPEG-TS depacketizer with full 7x188-byte RTP packets and checks that an in-order and a reordered delivery of the same packets yield identical PES data. The test is registered as fate-rtpdec with a checked-in reference output; its two 64 KiB Output buffers are static to avoid a large stack allocation in main(). Signed-off-by: Torbjörn Einarsson <torbjorn@einarssons.se>