Shaka Packager SDK
ts_section_pmt.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp2t/ts_section_pmt.h"
6 
7 #include <vector>
8 
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"
13 
14 namespace shaka {
15 namespace media {
16 namespace mp2t {
17 
18 TsSectionPmt::TsSectionPmt(const RegisterPesCb& register_pes_cb)
19  : register_pes_cb_(register_pes_cb) {
20 }
21 
22 TsSectionPmt::~TsSectionPmt() {
23 }
24 
25 bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
26  // Read up to |last_section_number|.
27  int table_id;
28  int section_syntax_indicator;
29  int dummy_zero;
30  int reserved;
31  int section_length;
32  int program_number;
33  int version_number;
34  int current_next_indicator;
35  int section_number;
36  int last_section_number;
37  RCHECK(bit_reader->ReadBits(8, &table_id));
38  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
39  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
40  RCHECK(bit_reader->ReadBits(2, &reserved));
41  RCHECK(bit_reader->ReadBits(12, &section_length));
42  int section_start_marker = static_cast<int>(bit_reader->bits_available()) / 8;
43 
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, &current_next_indicator));
48  RCHECK(bit_reader->ReadBits(8, &section_number));
49  RCHECK(bit_reader->ReadBits(8, &last_section_number));
50 
51  // Perform a few verifications:
52  // - table ID should be 2 for a PMT.
53  // - section_syntax_indicator should be one.
54  // - section length should not exceed 1021.
55  RCHECK(table_id == 0x2);
56  RCHECK(section_syntax_indicator);
57  RCHECK(!dummy_zero);
58  RCHECK(section_length <= 1021);
59  RCHECK(section_number == 0);
60  RCHECK(last_section_number == 0);
61 
62  // Read the end of the fixed length section.
63  int pcr_pid;
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);
70 
71  // Read the program info descriptor.
72  // Defined in section 2.6 of ISO-13818.
73  RCHECK(bit_reader->SkipBits(8 * program_info_length));
74 
75  // Read the ES description table.
76  // The end of the PID map if 4 bytes away from the end of the section
77  // (4 bytes = size of the CRC).
78  int pid_map_end_marker = section_start_marker - section_length + 4;
79  struct Info {
80  int pid_es;
81  TsStreamType stream_type;
82  const uint8_t* descriptor;
83  size_t descriptor_length;
84  };
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;
89  int pid_es;
90  size_t es_info_length;
91  RCHECK(bit_reader->ReadBits(8, &stream_type));
92  RCHECK(bit_reader->SkipBits(3)); // reserved
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();
97 
98  // Do not register the PID right away.
99  // Wait for the end of the section to be fully parsed
100  // to make sure there is no error.
101  pid_info.push_back({pid_es, stream_type, descriptor, es_info_length});
102 
103  // Read the ES info descriptors.
104  // Defined in section 2.6 of ISO-13818.
105  if (es_info_length > 0) {
106  uint8_t descriptor_tag;
107  RCHECK(bit_reader->ReadBits(8, &descriptor_tag));
108  es_info_length--;
109 
110  // See ETSI EN 300 468 Section 6.1
111  if (stream_type == TsStreamType::kPesPrivateData &&
112  descriptor_tag == 0x59) { // subtitling_descriptor
113  pid_info.back().stream_type = TsStreamType::kDvbSubtitles;
114  }
115  }
116  RCHECK(bit_reader->SkipBits(8 * es_info_length));
117  }
118 
119  // Read the CRC.
120  int crc32;
121  RCHECK(bit_reader->ReadBits(32, &crc32));
122 
123  // Once the PMT has been proved to be correct, register the PIDs.
124  for (auto& info : pid_info) {
125  register_pes_cb_.Run(info.pid_es, info.stream_type, info.descriptor,
126  info.descriptor_length);
127  }
128 
129  return true;
130 }
131 
132 void TsSectionPmt::ResetPsiSection() {
133 }
134 
135 } // namespace mp2t
136 } // namespace media
137 } // namespace shaka
All the methods that are virtual are virtual for mocking.