Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: media/mpeg2/mpeg2ts_pmt.cc

Issue 23566013: Mpeg2 TS stream parser for media source. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "media/mpeg2/mpeg2ts_pmt.h"
6
7 #include <map>
8
9 #include "base/logging.h"
10 #include "media/base/bit_reader.h"
11
12 namespace media {
13 namespace mpeg2ts {
14
15 Mpeg2TsPmtParser::Mpeg2TsPmtParser(RegisterPesCb register_pes_cb)
16 : register_pes_cb_(register_pes_cb) {
17 }
18
19 Mpeg2TsPmtParser::~Mpeg2TsPmtParser() {
20 }
21
22 bool Mpeg2TsPmtParser::ParsePsiSection(BitReader* bit_reader) {
23 // Read up to the section length.
24 DCHECK_GE(bit_reader->bits_available(), 3*8);
25 int table_id;
26 DCHECK(bit_reader->ReadBits(8, &table_id));
27 if (table_id != 0x2) {
28 // Table ID should be 2 for a PMT.
29 LOG(WARNING) << "Unexpected table id: " << table_id;
30 return false;
31 }
32 bool section_syntax_indicator;
33 DCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
34 if (!section_syntax_indicator) {
35 LOG(WARNING) << "Unexpected section_syntax_indicator";
36 return false;
37 }
38 bool dummy_zero;
39 DCHECK(bit_reader->ReadBits(1, &dummy_zero));
40 if (dummy_zero) {
41 LOG(WARNING) << "Unexpected bit";
42 return false;
43 }
44 int reserved;
45 DCHECK(bit_reader->ReadBits(2, &reserved));
46 int section_length;
47 DCHECK(bit_reader->ReadBits(12, &section_length));
48 if (section_length >= 1021) {
49 return false;
50 }
51
52 // Read the rest of the fixed size section.
53 if (section_length < 5) {
54 LOG(WARNING) << "Section length too small";
55 return false;
56 }
57 int program_number;
58 DCHECK(bit_reader->ReadBits(16, &program_number));
59 DCHECK(bit_reader->ReadBits(2, &reserved));
60 int version_number;
61 DCHECK(bit_reader->ReadBits(5, &version_number));
62 bool current_next_indicator;
63 DCHECK(bit_reader->ReadBits(1, &current_next_indicator));
64 int section_number;
65 DCHECK(bit_reader->ReadBits(8, &section_number));
66 int last_section_number;
67 DCHECK(bit_reader->ReadBits(8, &last_section_number));
68 section_length -= 5;
69
70 if (section_number != 0) {
71 // Should be 0 for a PMT.
72 return false;
73 }
74 if (last_section_number != 0) {
75 // Should be 0 for a PMT.
76 return false;
77 }
78 // TODO(damienv):
79 // - Verify that there is no mismatch between the program number
80 // and the program number that was provided in a PAT for the current PMT.
81 // - What if the program number is not registered yet ?
82 // Do we want to add an implicitly defined program number ?
83
84 // Read the end of the fixed length section.
85 if (section_length < 4) {
86 LOG(WARNING) << "Section length too small";
87 return false;
88 }
89 DCHECK(bit_reader->ReadBits(3, &reserved));
90 int pcr_pid;
91 DCHECK(bit_reader->ReadBits(13, &pcr_pid));
92 DCHECK(bit_reader->ReadBits(4, &reserved));
93 int program_info_length;
94 DCHECK(bit_reader->ReadBits(12, &program_info_length));
95 if (program_info_length >= 1024) {
96 return false;
97 }
98 section_length -= 4;
99
100 // Read the program info descriptor.
101 // TODO(damienv): check wether any of the descriptors
102 // could be useful.
103 // Defined in section 2.6 of ISO-13818.
104 if (section_length < program_info_length) {
105 LOG(WARNING) << "Section length too small";
106 return false;
107 }
108 for (int k = 0; k < program_info_length; k++) {
109 int dummy;
110 DCHECK(bit_reader->ReadBits(8, &dummy));
111 }
112 section_length -= program_info_length;
113
114 // Read the ES description table.
115 // 5 bytes: minimum size of an ES descriptor.
116 std::map<int, int> pid_map;
117 while (section_length >= 5) {
118 int stream_type;
119 DCHECK(bit_reader->ReadBits(8, &stream_type));
120 int reserved;
121 DCHECK(bit_reader->ReadBits(3, &reserved));
122 int pid_es;
123 DCHECK(bit_reader->ReadBits(13, &pid_es));
124 DCHECK(bit_reader->ReadBits(4, &reserved));
125 int es_info_length;
126 DCHECK(bit_reader->ReadBits(12, &es_info_length));
127 section_length -= 5;
128
129 // Do not register the PID right away.
130 // Wait for the end of the section to be fully parsed
131 // to make sure there is no error.
132 pid_map.insert(std::pair<int,int>(pid_es, stream_type));
133
134 // Read the ES info descriptors.
135 // TODO(damienv): check wether any of the descriptors
136 // could be useful.
137 // Defined in section 2.6 of ISO-13818.
138 if (section_length < es_info_length) {
139 // This should not happen if the PMT size
140 // was correctly encoded into the stream.
141 LOG(WARNING) << "section_length=" << section_length
142 << " es_info_length=" << es_info_length;
143 return false;
144 }
145 for (int k = 0; k < es_info_length; k++) {
146 int dummy;
147 DCHECK(bit_reader->ReadBits(8, &dummy));
148 }
149 section_length -= es_info_length;
150 }
151
152 // Read the CRC.
153 if (section_length < 4) {
154 LOG(WARNING) << "Section length too small: " << section_length;
155 return false;
156 }
157 int crc32;
158 DCHECK(bit_reader->ReadBits(32, &crc32));
159 section_length -= 4;
160
161 // This should not happen if the PMT size
162 // was correctly encoded into the stream.
163 LOG_IF(WARNING, section_length != 0)
164 << "section_length=" << section_length;
165
166 // Once the PMT has been proved to be correct, register the PIDs.
167 for (std::map<int, int>::iterator it = pid_map.begin();
168 it != pid_map.end(); ++it) {
169 register_pes_cb_.Run(it->first, it->second);
170 }
171
172 return true;
173 }
174
175 } // namespace mpeg2ts
176 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698