11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
20PROMEKI_NAMESPACE_BEGIN
54 static constexpr int PacketSize = 188;
57 static constexpr uint8_t SyncByte = 0x47;
60 static constexpr uint16_t MaxPid = 0x1FFF;
63 static constexpr uint16_t PidPat = 0x0000;
66 static constexpr uint16_t PidCat = 0x0001;
69 static constexpr uint16_t PidTsdt = 0x0002;
72 static constexpr uint16_t PidIpmp = 0x0003;
75 static constexpr uint16_t PidNull = 0x1FFF;
78 static constexpr uint16_t DefaultPmtPid = 0x1000;
81 static constexpr uint16_t DefaultVideoPid = 0x0100;
84 static constexpr uint16_t DefaultAudioPid = 0x0101;
87 static constexpr uint16_t DefaultProgramNumber = 1;
90 static constexpr uint32_t PesStartCode = 0x000001;
104 enum StreamType : uint8_t {
105 StreamTypeReserved = 0x00,
106 StreamTypeMpeg1Video = 0x01,
107 StreamTypeMpeg2Video = 0x02,
108 StreamTypeMpeg1Audio = 0x03,
109 StreamTypeMpeg2Audio = 0x04,
124 StreamTypePrivatePes = 0x06,
125 StreamTypeAacAdts = 0x0F,
126 StreamTypeAacLatm = 0x11,
127 StreamTypeMetadata = 0x15,
128 StreamTypeH264 = 0x1B,
129 StreamTypeHevc = 0x24,
138 StreamTypeJpegXs = 0x32,
139 StreamTypeAc3 = 0x81,
140 StreamTypeScte35 = 0x86,
155 enum class StreamKind : uint8_t {
173 static constexpr uint32_t RegFormatSmpte302M = 0x42535344;
174 static constexpr uint32_t RegFormatOpus = 0x4F707573;
175 static constexpr uint32_t RegFormatAv1 = 0x41563031;
176 static constexpr uint32_t RegFormatJpegXs = 0x4A585356;
179 static constexpr uint8_t DescriptorTagRegistration = 0x05;
192 enum PesStreamId : uint8_t {
193 PesStreamIdVideoFirst = 0xE0,
194 PesStreamIdAudioFirst = 0xC0,
195 PesStreamIdPrivate1 = 0xBD,
196 PesStreamIdPadding = 0xBE,
197 PesStreamIdPrivate2 = 0xBF,
198 PesStreamIdMetadata = 0xFC,
212 static uint32_t psiCrc32(
const void *data,
size_t len);
215 static uint32_t psiCrc32(
const BufferView &v);
235 static void encodePesPts(uint64_t value90k, uint8_t prefix, uint8_t out[5]);
247 static uint64_t decodePesPts(
const uint8_t in[5]);
265 static void encodePcr(uint64_t value27mhz, uint8_t out[6]);
276 static uint64_t decodePcr(
const uint8_t in[6]);
297 static Error buildPat(uint16_t transportStreamId, uint16_t programNumber, uint16_t pmtPid,
298 uint8_t versionNumber, Buffer &outBuf);
311 uint8_t streamType = 0;
332 static Error buildPmt(uint16_t programNumber, uint16_t pcrPid, uint8_t versionNumber,
333 const BufferView &programDescriptors,
const List<PmtStream> &streams,
351 uint8_t streamId = 0;
352 uint16_t pesPacketLength = 0;
353 bool dataAlignmentIndicator =
false;
373 static size_t pesHeaderSize(
const PesHeader &h);
382 static void writePesHeader(
const PesHeader &h, uint8_t *out);
409 static Error readPesHeader(
const uint8_t *in,
size_t len, PesHeader *out,
size_t *headerSize);
421 static bool isPsiSectionValid(
const uint8_t *section,
size_t len);
431 uint16_t programNumber = 0;
437 uint16_t transportStreamId = 0;
438 uint8_t versionNumber = 0;
439 bool currentNextIndicator =
false;
440 List<PatEntry> entries;
461 static Error parsePat(
const uint8_t *section,
size_t len, ParsedPat *out);
465 uint16_t programNumber = 0;
466 uint8_t versionNumber = 0;
467 bool currentNextIndicator =
false;
469 Buffer programDescriptors;
470 List<PmtStream> streams;
489 static Error parsePmt(
const uint8_t *section,
size_t len, ParsedPmt *out);
515 static Error buildRegistrationDescriptor(uint32_t formatIdentifier, Buffer &outBuf);
533 static Error findRegistrationDescriptor(
const BufferView &descriptors,
534 uint32_t *outFormatIdentifier);
537 static constexpr uint8_t DescriptorTagExtension = 0x7F;
540 static constexpr uint8_t DescriptorTagAv1Video = 0x80;
543 static constexpr uint8_t DescriptorTagJxsVideo = 0x32;
549 static constexpr uint8_t ExtensionDescTagOpus = 0x80;
572 static Error buildOpusExtensionDescriptor(
unsigned channels, Buffer &outBuf);
598 static Error buildAv1VideoDescriptor(Buffer &outBuf);
626 static Error buildJpegXsVideoDescriptor(uint16_t width, uint16_t height,
627 uint32_t frameRateNum, uint32_t frameRateDen,