PR #24697 opened by superuser404
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24697
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24697.patch
`mpegts_set_stream_info()` asks for a content probe on stream type 0x04 (MPEG-2
audio) and 0x0f (AAC), but takes 0x03 (MPEG-1 audio) at its word. A PID
labelled 0x03 that carries something else is opened as mp3 without its bytes
being looked at, and every packet fails with `Header missing`. Reported against
an IPTV restream whose DTS-HD audio PID is labelled that way. The same payload
labelled 0x04, 0x06 or with an unknown type is identified correctly.
The patch gives 0x03 the same `request_probe = 50` as 0x04.
### Reproducer
```sh
ffmpeg -f lavfi -i testsrc2=size=1280x720:rate=24000/1001 \
-f lavfi -i "sine=f=440:r=48000,pan=5.1|c0=c0|c1=c0|c2=c0|c3=c0|c4=c0|c5=c0" \
-t 20 -c:v libx264 -c:a dca -strict -2 -b:a 1509k -f mpegts dts.ts
python3 relabel.py dts.ts dts03.ts 03
ffprobe -v error -show_entries stream=codec_name,sample_rate,channels
-select_streams a -of compact dts03.ts
```
`relabel.py` rewrites the stream type of the audio PID (0x101) in the PMT (PID
0x1000) and recomputes the section CRC:
```python
import sys
def crc32(data):
c = 0xffffffff
for b in data:
c ^= b << 24
for _ in range(8):
c = ((c << 1) ^ 0x04c11db7) & 0xffffffff if c & 0x80000000 else (c
<< 1) & 0xffffffff
return c
src, dst, st = sys.argv[1], sys.argv[2], int(sys.argv[3], 16)
d = bytearray(open(src, 'rb').read())
for i in range(0, len(d), 188):
if ((d[i+1] & 0x1f) << 8 | d[i+2]) != 0x1000:
continue
s = i + 5
end = s + 3 + (((d[s+1] & 0x0f) << 8) | d[s+2]) - 4
j = s + 12 + (((d[s+10] & 0x0f) << 8) | d[s+11])
while j < end:
if ((d[j+1] & 0x1f) << 8 | d[j+2]) == 0x101:
d[j] = st
j += 5 + (((d[j+3] & 0x0f) << 8) | d[j+4])
d[end:end+4] = crc32(d[s:end]).to_bytes(4, 'big')
open(dst, 'wb').write(d)
```
| audio PID labelled | master | this patch |
|---|---|---|
| 0x03 | `mp3`, 0 Hz, 0 channels | `dts`, 48000 Hz, 6 channels |
| 0x04 | `dts`, 48000 Hz, 6 channels | unchanged |
| 0x06 / 0x0f / 0x99 | `dts`, 48000 Hz, 6 channels | unchanged |
### Genuine MPEG audio
A probe that finds nothing better keeps the codec from the PMT (the
`request_probe > score && codec_id != id` guard in
`set_codec_from_probe_data()`), and real MP1/MP2/MP3 settles within the first
one or two PES packets, which are buffered rather than dropped. Measured with
`-loglevel debug`: `xdcam8mp2-1s_small.ts` settles at `packets=2`,
`h264_intra_first-small.ts` and ffmpeg's own MP2 and MP3 muxed into MPEG-TS
(written as 0x03) at `packets=1`, all with the same codec, sample rate and
channel count as master.
### FATE
The 69 FATE tests whose command reads or writes MPEG-TS were run on master and
on this patch with the MPEG-TS samples of the suite: identical results,
including `copy-trac4914`, `copy-trac4914-avi`, `h264-skip-nokey`,
`h264-skip-nointra`, `spdif-mp2-remux`, `matroska-h264-remux` and `lavf-ts`,
whose inputs carry 0x03 PIDs. (Seven of the 69 need samples I did not fetch and
fail identically on both.)
>From 990d6ac75837d6e08c4a69b214d73aebea30a401 Mon Sep 17 00:00:00 2001
From: Vincent Herbst <[email protected]>
Date: Fri, 25 Sep 2026 22:44:43 +0200
Subject: [PATCH] avformat/mpegts: probe the payload of streams labelled MPEG-1
audio
mpegts_set_stream_info() asks for a content probe on stream type 0x04
(MPEG-2 audio) and 0x0f (AAC), because those labels are known to be put
on payloads they do not describe, but takes 0x03 (MPEG-1 audio) at its
word. A PID labelled 0x03 that carries something else is therefore
opened as mp3 without its bytes ever being looked at, and every packet
fails in the decoder:
[mp3float] Header missing
Could not find codec parameters for stream 1 (Audio: mp3 (mp3float)
([3][0][0][0] / 0x0003), 0 channels, fltp): unspecified frame size
This was reported against an IPTV restream whose DTS-HD audio PID is
labelled that way. The same DTS payload labelled 0x04, 0x06 or with an
unknown stream type is identified correctly, only 0x03 is not.
Give 0x03 the same request_probe as 0x04. A probe that finds nothing
better keeps the codec from the PMT, and genuine MPEG audio settles
within the first one or two PES packets, which are buffered rather than
dropped. The FATE tests that read or write MPEG-TS, including the ones
whose samples carry 0x03 PIDs (copy-trac4914, h264-skip-nokey,
spdif-mp2-remux, matroska-h264-remux, lavf-ts), are unchanged.
---
libavformat/mpegts.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index a1b6065320..2e1640c769 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -969,7 +969,9 @@ static int mpegts_set_stream_info(AVStream *st, PESContext
*pes,
st->codecpar->codec_tag = pes->stream_type;
mpegts_find_stream_type(st, pes->stream_type, ISO_types);
- if (pes->stream_type == STREAM_TYPE_AUDIO_MPEG2 || pes->stream_type ==
STREAM_TYPE_AUDIO_AAC)
+ if (pes->stream_type == STREAM_TYPE_AUDIO_MPEG1 ||
+ pes->stream_type == STREAM_TYPE_AUDIO_MPEG2 ||
+ pes->stream_type == STREAM_TYPE_AUDIO_AAC)
sti->request_probe = 50;
if (pes->stream_type == STREAM_TYPE_PRIVATE_DATA)
sti->request_probe = AVPROBE_SCORE_STREAM_RETRY;
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]