DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
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 <map>
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 
13 namespace edash_packager {
14 namespace media {
15 namespace mp2t {
16 
17 TsSectionPmt::TsSectionPmt(const RegisterPesCb& register_pes_cb)
18  : register_pes_cb_(register_pes_cb) {
19 }
20 
21 TsSectionPmt::~TsSectionPmt() {
22 }
23 
24 bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
25  // Read up to |last_section_number|.
26  int table_id;
27  int section_syntax_indicator;
28  int dummy_zero;
29  int reserved;
30  int section_length;
31  int program_number;
32  int version_number;
33  int current_next_indicator;
34  int section_number;
35  int last_section_number;
36  RCHECK(bit_reader->ReadBits(8, &table_id));
37  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
38  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
39  RCHECK(bit_reader->ReadBits(2, &reserved));
40  RCHECK(bit_reader->ReadBits(12, &section_length));
41  int section_start_marker = bit_reader->bits_available() / 8;
42 
43  RCHECK(bit_reader->ReadBits(16, &program_number));
44  RCHECK(bit_reader->ReadBits(2, &reserved));
45  RCHECK(bit_reader->ReadBits(5, &version_number));
46  RCHECK(bit_reader->ReadBits(1, &current_next_indicator));
47  RCHECK(bit_reader->ReadBits(8, &section_number));
48  RCHECK(bit_reader->ReadBits(8, &last_section_number));
49 
50  // Perform a few verifications:
51  // - table ID should be 2 for a PMT.
52  // - section_syntax_indicator should be one.
53  // - section length should not exceed 1021.
54  RCHECK(table_id == 0x2);
55  RCHECK(section_syntax_indicator);
56  RCHECK(!dummy_zero);
57  RCHECK(section_length <= 1021);
58  RCHECK(section_number == 0);
59  RCHECK(last_section_number == 0);
60 
61  // Read the end of the fixed length section.
62  int pcr_pid;
63  int program_info_length;
64  RCHECK(bit_reader->ReadBits(3, &reserved));
65  RCHECK(bit_reader->ReadBits(13, &pcr_pid));
66  RCHECK(bit_reader->ReadBits(4, &reserved));
67  RCHECK(bit_reader->ReadBits(12, &program_info_length));
68  RCHECK(program_info_length < 1024);
69 
70  // Read the program info descriptor.
71  // Defined in section 2.6 of ISO-13818.
72  RCHECK(bit_reader->SkipBits(8 * program_info_length));
73 
74  // Read the ES description table.
75  // The end of the PID map if 4 bytes away from the end of the section
76  // (4 bytes = size of the CRC).
77  int pid_map_end_marker = section_start_marker - section_length + 4;
78  std::map<int, int> pid_map;
79  while (bit_reader->bits_available() > 8 * pid_map_end_marker) {
80  int stream_type;
81  int reserved;
82  int pid_es;
83  int es_info_length;
84  RCHECK(bit_reader->ReadBits(8, &stream_type));
85  RCHECK(bit_reader->ReadBits(3, &reserved));
86  RCHECK(bit_reader->ReadBits(13, &pid_es));
87  RCHECK(bit_reader->ReadBits(4, &reserved));
88  RCHECK(bit_reader->ReadBits(12, &es_info_length));
89 
90  // Do not register the PID right away.
91  // Wait for the end of the section to be fully parsed
92  // to make sure there is no error.
93  pid_map.insert(std::pair<int, int>(pid_es, stream_type));
94 
95  // Read the ES info descriptors.
96  // Defined in section 2.6 of ISO-13818.
97  RCHECK(bit_reader->SkipBits(8 * es_info_length));
98  }
99 
100  // Read the CRC.
101  int crc32;
102  RCHECK(bit_reader->ReadBits(32, &crc32));
103 
104  // Once the PMT has been proved to be correct, register the PIDs.
105  for (std::map<int, int>::iterator it = pid_map.begin();
106  it != pid_map.end(); ++it)
107  register_pes_cb_.Run(it->first, it->second);
108 
109  return true;
110 }
111 
112 void TsSectionPmt::ResetPsiSection() {
113 }
114 
115 } // namespace mp2t
116 } // namespace media
117 } // namespace edash_packager