5 #include "packager/media/formats/mp2t/ts_section_pmt.h"
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/formats/mp2t/mp2t_common.h"
12 #include "packager/media/formats/mp2t/ts_stream_type.h"
18 TsSectionPmt::TsSectionPmt(
const RegisterPesCb& register_pes_cb)
19 : register_pes_cb_(register_pes_cb) {
22 TsSectionPmt::~TsSectionPmt() {
25 bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
28 int section_syntax_indicator;
34 int current_next_indicator;
36 int last_section_number;
37 RCHECK(bit_reader->ReadBits(8, &table_id));
38 RCHECK(bit_reader->ReadBits(1, §ion_syntax_indicator));
39 RCHECK(bit_reader->ReadBits(1, &dummy_zero));
40 RCHECK(bit_reader->ReadBits(2, &reserved));
41 RCHECK(bit_reader->ReadBits(12, §ion_length));
42 int section_start_marker =
static_cast<int>(bit_reader->bits_available()) / 8;
44 RCHECK(bit_reader->ReadBits(16, &program_number));
45 RCHECK(bit_reader->ReadBits(2, &reserved));
46 RCHECK(bit_reader->ReadBits(5, &version_number));
47 RCHECK(bit_reader->ReadBits(1, ¤t_next_indicator));
48 RCHECK(bit_reader->ReadBits(8, §ion_number));
49 RCHECK(bit_reader->ReadBits(8, &last_section_number));
55 RCHECK(table_id == 0x2);
56 RCHECK(section_syntax_indicator);
58 RCHECK(section_length <= 1021);
59 RCHECK(section_number == 0);
60 RCHECK(last_section_number == 0);
64 int program_info_length;
65 RCHECK(bit_reader->ReadBits(3, &reserved));
66 RCHECK(bit_reader->ReadBits(13, &pcr_pid));
67 RCHECK(bit_reader->ReadBits(4, &reserved));
68 RCHECK(bit_reader->ReadBits(12, &program_info_length));
69 RCHECK(program_info_length < 1024);
73 RCHECK(bit_reader->SkipBits(8 * program_info_length));
78 int pid_map_end_marker = section_start_marker - section_length + 4;
81 TsStreamType stream_type;
82 const uint8_t* descriptor;
83 size_t descriptor_length;
85 std::vector<Info> pid_info;
86 while (
static_cast<int>(bit_reader->bits_available()) >
87 8 * pid_map_end_marker) {
88 TsStreamType stream_type;
90 size_t es_info_length;
91 RCHECK(bit_reader->ReadBits(8, &stream_type));
92 RCHECK(bit_reader->SkipBits(3));
93 RCHECK(bit_reader->ReadBits(13, &pid_es));
94 RCHECK(bit_reader->ReadBits(4, &reserved));
95 RCHECK(bit_reader->ReadBits(12, &es_info_length));
96 const uint8_t* descriptor = bit_reader->current_byte_ptr();
101 pid_info.push_back({pid_es, stream_type, descriptor, es_info_length});
105 if (es_info_length > 0) {
106 uint8_t descriptor_tag;
107 RCHECK(bit_reader->ReadBits(8, &descriptor_tag));
111 if (stream_type == TsStreamType::kPesPrivateData &&
112 descriptor_tag == 0x59) {
113 pid_info.back().stream_type = TsStreamType::kDvbSubtitles;
116 RCHECK(bit_reader->SkipBits(8 * es_info_length));
121 RCHECK(bit_reader->ReadBits(32, &crc32));
124 for (
auto& info : pid_info) {
125 register_pes_cb_.Run(info.pid_es, info.stream_type, info.descriptor,
126 info.descriptor_length);
132 void TsSectionPmt::ResetPsiSection() {
All the methods that are virtual are virtual for mocking.