Skip to content

Commit 4b39d2b

Browse files
committed
Test with unknown stream
1 parent f8dddb9 commit 4b39d2b

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

tests/test_streams.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import io
12
import os
3+
import struct
24

35
import pytest
46

@@ -8,6 +10,63 @@
810
from .common import fate_suite
911

1012

13+
def _crc32_mpeg(data: bytes) -> int:
14+
crc = 0xFFFFFFFF
15+
for byte in data:
16+
crc ^= byte << 24
17+
for _ in range(8):
18+
if crc & 0x80000000:
19+
crc = (crc << 1) ^ 0x04C11DB7
20+
else:
21+
crc <<= 1
22+
crc &= 0xFFFFFFFF
23+
return crc
24+
25+
26+
def _make_ts_packet(pid: int, payload: bytes, pusi: bool = False, cc: int = 0) -> bytes:
27+
pid_hi = (pid >> 8) & 0x1F
28+
pid_lo = pid & 0xFF
29+
if pusi:
30+
pid_hi |= 0x40
31+
header = bytes([0x47, pid_hi, pid_lo, 0x10 | (cc & 0x0F)])
32+
pkt = header + payload
33+
return (pkt + b"\xff" * (188 - len(pkt)))[:188]
34+
35+
36+
def _make_unknown_stream_ts() -> bytes:
37+
"""Build a minimal MPEG-TS byte string whose only stream has AVMEDIA_TYPE_UNKNOWN.
38+
39+
Uses stream_type=0x82 in the PMT, which FFmpeg does not map to any known
40+
media type, resulting in ``stream.type == "unknown"``.
41+
"""
42+
pat_data = bytes(
43+
[0x00, 0xB0, 0x0D, 0x00, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x01, 0xE1, 0x00]
44+
)
45+
pat_data += struct.pack(">I", _crc32_mpeg(pat_data))
46+
pat_payload = bytes([0x00]) + pat_data
47+
48+
# fmt: off
49+
pmt_data = bytes([0x02, 0xB0, 0x12, 0x00, 0x01, 0xC1, 0x00, 0x00,
50+
0xE1, 0x02, 0xF0, 0x00, 0x82, 0xE1, 0x02, 0xF0, 0x00,
51+
])
52+
# fmt: on
53+
pmt_data += struct.pack(">I", _crc32_mpeg(pmt_data))
54+
pmt_payload = bytes([0x00]) + pmt_data
55+
56+
pes_header = bytes([0x00, 0x00, 0x01, 0xBD, 0x00, 0x0A, 0x80, 0x00, 0x00])
57+
pes_data = pes_header + b"\xaa" * (184 - len(pes_header))
58+
59+
packets: list[bytes] = []
60+
for i in range(2):
61+
packets.append(_make_ts_packet(0x0000, pat_payload, pusi=True, cc=i))
62+
for i in range(2):
63+
packets.append(_make_ts_packet(0x0100, pmt_payload, pusi=True, cc=i))
64+
for i in range(200):
65+
packets.append(_make_ts_packet(0x0102, pes_data, pusi=(i % 10 == 0), cc=i % 16))
66+
67+
return b"".join(packets)
68+
69+
1170
class TestStreams:
1271
@pytest.fixture(autouse=True)
1372
def cleanup(self):
@@ -300,3 +359,12 @@ def test_attachment_stream(self) -> None:
300359
assert att.name == "attachment.txt"
301360
assert att.mimetype == "text/plain"
302361
assert att.data == b"hello\n"
362+
363+
def test_unknown_stream_type(self) -> None:
364+
ts_data = _make_unknown_stream_ts()
365+
366+
with av.open(io.BytesIO(ts_data), format="mpegts") as container:
367+
assert len(container.streams) == 1
368+
stream = container.streams[0]
369+
assert stream.type == "unknown"
370+
assert type(stream) is av.stream.Stream

0 commit comments

Comments
 (0)