libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
mpegts.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <cstdint>
14#include <promeki/namespace.h>
15#include <promeki/buffer.h>
16#include <promeki/bufferview.h>
17#include <promeki/error.h>
18#include <promeki/list.h>
19
20PROMEKI_NAMESPACE_BEGIN
21
51class MpegTs {
52 public:
54 static constexpr int PacketSize = 188;
55
57 static constexpr uint8_t SyncByte = 0x47;
58
60 static constexpr uint16_t MaxPid = 0x1FFF;
61
63 static constexpr uint16_t PidPat = 0x0000;
64
66 static constexpr uint16_t PidCat = 0x0001;
67
69 static constexpr uint16_t PidTsdt = 0x0002;
70
72 static constexpr uint16_t PidIpmp = 0x0003;
73
75 static constexpr uint16_t PidNull = 0x1FFF;
76
78 static constexpr uint16_t DefaultPmtPid = 0x1000;
79
81 static constexpr uint16_t DefaultVideoPid = 0x0100;
82
84 static constexpr uint16_t DefaultAudioPid = 0x0101;
85
87 static constexpr uint16_t DefaultProgramNumber = 1;
88
90 static constexpr uint32_t PesStartCode = 0x000001;
91
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,
141 };
142
155 enum class StreamKind : uint8_t {
156 Auto = 0,
157 Video = 1,
158 Audio = 2,
159 Data = 3,
160 Metadata = 4
161 };
162
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;
177
179 static constexpr uint8_t DescriptorTagRegistration = 0x05;
180
192 enum PesStreamId : uint8_t {
193 PesStreamIdVideoFirst = 0xE0,
194 PesStreamIdAudioFirst = 0xC0,
195 PesStreamIdPrivate1 = 0xBD,
196 PesStreamIdPadding = 0xBE,
197 PesStreamIdPrivate2 = 0xBF,
198 PesStreamIdMetadata = 0xFC,
199 };
200
212 static uint32_t psiCrc32(const void *data, size_t len);
213
215 static uint32_t psiCrc32(const BufferView &v);
216
235 static void encodePesPts(uint64_t value90k, uint8_t prefix, uint8_t out[5]);
236
247 static uint64_t decodePesPts(const uint8_t in[5]);
248
265 static void encodePcr(uint64_t value27mhz, uint8_t out[6]);
266
276 static uint64_t decodePcr(const uint8_t in[6]);
277
297 static Error buildPat(uint16_t transportStreamId, uint16_t programNumber, uint16_t pmtPid,
298 uint8_t versionNumber, Buffer &outBuf);
299
310 struct PmtStream {
311 uint8_t streamType = 0;
312 uint16_t pid = 0;
313 Buffer descriptors;
314 };
315
332 static Error buildPmt(uint16_t programNumber, uint16_t pcrPid, uint8_t versionNumber,
333 const BufferView &programDescriptors, const List<PmtStream> &streams,
334 Buffer &outBuf);
335
350 struct PesHeader {
351 uint8_t streamId = 0;
352 uint16_t pesPacketLength = 0;
353 bool dataAlignmentIndicator = false;
354 bool hasPts = false;
355 bool hasDts = false;
356 uint64_t pts90k = 0;
357 uint64_t dts90k = 0;
358 };
359
373 static size_t pesHeaderSize(const PesHeader &h);
374
382 static void writePesHeader(const PesHeader &h, uint8_t *out);
383
409 static Error readPesHeader(const uint8_t *in, size_t len, PesHeader *out, size_t *headerSize);
410
421 static bool isPsiSectionValid(const uint8_t *section, size_t len);
422
430 struct PatEntry {
431 uint16_t programNumber = 0;
432 uint16_t pid = 0;
433 };
434
436 struct ParsedPat {
437 uint16_t transportStreamId = 0;
438 uint8_t versionNumber = 0;
439 bool currentNextIndicator = false;
440 List<PatEntry> entries;
441 };
442
461 static Error parsePat(const uint8_t *section, size_t len, ParsedPat *out);
462
464 struct ParsedPmt {
465 uint16_t programNumber = 0;
466 uint8_t versionNumber = 0;
467 bool currentNextIndicator = false;
468 uint16_t pcrPid = 0;
469 Buffer programDescriptors;
470 List<PmtStream> streams;
471 };
472
489 static Error parsePmt(const uint8_t *section, size_t len, ParsedPmt *out);
490
515 static Error buildRegistrationDescriptor(uint32_t formatIdentifier, Buffer &outBuf);
516
533 static Error findRegistrationDescriptor(const BufferView &descriptors,
534 uint32_t *outFormatIdentifier);
535
537 static constexpr uint8_t DescriptorTagExtension = 0x7F;
538
540 static constexpr uint8_t DescriptorTagAv1Video = 0x80;
541
543 static constexpr uint8_t DescriptorTagJxsVideo = 0x32;
544
549 static constexpr uint8_t ExtensionDescTagOpus = 0x80;
550
572 static Error buildOpusExtensionDescriptor(unsigned channels, Buffer &outBuf);
573
598 static Error buildAv1VideoDescriptor(Buffer &outBuf);
599
626 static Error buildJpegXsVideoDescriptor(uint16_t width, uint16_t height,
627 uint32_t frameRateNum, uint32_t frameRateDen,
628 Buffer &outBuf);
629};
630
631PROMEKI_NAMESPACE_END
632
633#endif // PROMEKI_ENABLE_PROAV