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

Side by Side Diff: media/formats/mp4/box_reader.cc

Issue 1149023002: Combine 'pssh' parsing routines. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: size_t Created 5 years, 6 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
« no previous file with comments | « media/formats/mp4/box_reader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/formats/mp4/box_reader.h" 5 #include "media/formats/mp4/box_reader.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <set> 9 #include <set>
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 } 68 }
69 69
70 bool BufferReader::Read4sInto8s(int64* v) { 70 bool BufferReader::Read4sInto8s(int64* v) {
71 // Beware of the need for sign extension. 71 // Beware of the need for sign extension.
72 int32 tmp; 72 int32 tmp;
73 RCHECK(Read4s(&tmp)); 73 RCHECK(Read4s(&tmp));
74 *v = tmp; 74 *v = tmp;
75 return true; 75 return true;
76 } 76 }
77 77
78 78 BoxReader::BoxReader(const uint8* buf,
79 BoxReader::BoxReader(const uint8* buf, const int size, 79 const int size,
80 const LogCB& log_cb) 80 const LogCB& log_cb,
81 bool is_EOS)
81 : BufferReader(buf, size), 82 : BufferReader(buf, size),
82 log_cb_(log_cb), 83 log_cb_(log_cb),
83 type_(FOURCC_NULL), 84 type_(FOURCC_NULL),
84 version_(0), 85 version_(0),
85 flags_(0), 86 flags_(0),
86 scanned_(false) { 87 scanned_(false),
88 is_EOS_(is_EOS) {
87 } 89 }
88 90
89 BoxReader::~BoxReader() { 91 BoxReader::~BoxReader() {
90 if (scanned_ && !children_.empty()) { 92 if (scanned_ && !children_.empty()) {
91 for (ChildMap::iterator itr = children_.begin(); 93 for (ChildMap::iterator itr = children_.begin();
92 itr != children_.end(); ++itr) { 94 itr != children_.end(); ++itr) {
93 DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first); 95 DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first);
94 } 96 }
95 } 97 }
96 } 98 }
97 99
98 // static 100 // static
99 BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf, 101 BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf,
100 const int buf_size, 102 const int buf_size,
101 const LogCB& log_cb, 103 const LogCB& log_cb,
102 bool* err) { 104 bool* err) {
103 scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size, log_cb)); 105 scoped_ptr<BoxReader> reader(
106 new BoxReader(buf, buf_size, log_cb, false));
104 if (!reader->ReadHeader(err)) 107 if (!reader->ReadHeader(err))
105 return NULL; 108 return NULL;
106 109
107 if (!IsValidTopLevelBox(reader->type(), log_cb)) { 110 if (!IsValidTopLevelBox(reader->type(), log_cb)) {
108 *err = true; 111 *err = true;
109 return NULL; 112 return NULL;
110 } 113 }
111 114
112 if (reader->size() <= buf_size) 115 if (reader->size() <= buf_size)
113 return reader.release(); 116 return reader.release();
114 117
115 return NULL; 118 return NULL;
116 } 119 }
117 120
118 // static 121 // static
119 bool BoxReader::StartTopLevelBox(const uint8* buf, 122 bool BoxReader::StartTopLevelBox(const uint8* buf,
120 const int buf_size, 123 const int buf_size,
121 const LogCB& log_cb, 124 const LogCB& log_cb,
122 FourCC* type, 125 FourCC* type,
123 int* box_size, 126 int* box_size,
124 bool* err) { 127 bool* err) {
125 BoxReader reader(buf, buf_size, log_cb); 128 BoxReader reader(buf, buf_size, log_cb, false);
126 if (!reader.ReadHeader(err)) return false; 129 if (!reader.ReadHeader(err)) return false;
127 if (!IsValidTopLevelBox(reader.type(), log_cb)) { 130 if (!IsValidTopLevelBox(reader.type(), log_cb)) {
128 *err = true; 131 *err = true;
129 return false; 132 return false;
130 } 133 }
131 *type = reader.type(); 134 *type = reader.type();
132 *box_size = reader.size(); 135 *box_size = reader.size();
133 return true; 136 return true;
134 } 137 }
135 138
136 // static 139 // static
140 BoxReader* BoxReader::ReadConcatentatedBoxes(const uint8* buf,
141 const int buf_size) {
142 return new BoxReader(buf, buf_size, LogCB(), true);
143 }
144
145 // static
137 bool BoxReader::IsValidTopLevelBox(const FourCC& type, 146 bool BoxReader::IsValidTopLevelBox(const FourCC& type,
138 const LogCB& log_cb) { 147 const LogCB& log_cb) {
139 switch (type) { 148 switch (type) {
140 case FOURCC_FTYP: 149 case FOURCC_FTYP:
141 case FOURCC_PDIN: 150 case FOURCC_PDIN:
142 case FOURCC_BLOC: 151 case FOURCC_BLOC:
143 case FOURCC_MOOV: 152 case FOURCC_MOOV:
144 case FOURCC_MOOF: 153 case FOURCC_MOOF:
145 case FOURCC_MFRA: 154 case FOURCC_MFRA:
146 case FOURCC_MDAT: 155 case FOURCC_MDAT:
(...skipping 15 matching lines...) Expand all
162 return false; 171 return false;
163 } 172 }
164 } 173 }
165 174
166 bool BoxReader::ScanChildren() { 175 bool BoxReader::ScanChildren() {
167 DCHECK(!scanned_); 176 DCHECK(!scanned_);
168 scanned_ = true; 177 scanned_ = true;
169 178
170 bool err = false; 179 bool err = false;
171 while (pos() < size()) { 180 while (pos() < size()) {
172 BoxReader child(&buf_[pos_], size_ - pos_, log_cb_); 181 BoxReader child(&buf_[pos_], size_ - pos_, log_cb_, is_EOS_);
173 if (!child.ReadHeader(&err)) break; 182 if (!child.ReadHeader(&err)) break;
174 183
175 children_.insert(std::pair<FourCC, BoxReader>(child.type(), child)); 184 children_.insert(std::pair<FourCC, BoxReader>(child.type(), child));
176 pos_ += child.size(); 185 pos_ += child.size();
177 } 186 }
178 187
179 DCHECK(!err); 188 DCHECK(!err);
180 return !err && pos() == size(); 189 return !err && pos() == size();
181 } 190 }
182 191
(...skipping 25 matching lines...) Expand all
208 RCHECK(Read4(&vflags)); 217 RCHECK(Read4(&vflags));
209 version_ = vflags >> 24; 218 version_ = vflags >> 24;
210 flags_ = vflags & 0xffffff; 219 flags_ = vflags & 0xffffff;
211 return true; 220 return true;
212 } 221 }
213 222
214 bool BoxReader::ReadHeader(bool* err) { 223 bool BoxReader::ReadHeader(bool* err) {
215 uint64 size = 0; 224 uint64 size = 0;
216 *err = false; 225 *err = false;
217 226
218 if (!HasBytes(8)) return false; 227 if (!HasBytes(8)) {
228 // If EOS is known, then this is an error. If not, additional data may be
229 // appended later, so this is a soft error.
230 *err = is_EOS_;
231 return false;
232 }
219 CHECK(Read4Into8(&size) && ReadFourCC(&type_)); 233 CHECK(Read4Into8(&size) && ReadFourCC(&type_));
220 234
221 if (size == 0) { 235 if (size == 0) {
222 MEDIA_LOG(DEBUG, log_cb_) << "Media Source Extensions do not support ISO " 236 if (is_EOS_) {
223 "BMFF boxes that run to EOS"; 237 // All the data bytes are expected to be provided.
224 *err = true; 238 size = size_;
225 return false; 239 } else {
240 MEDIA_LOG(DEBUG, log_cb_)
241 << "ISO BMFF boxes that run to EOS are not supported";
242 *err = true;
243 return false;
244 }
226 } else if (size == 1) { 245 } else if (size == 1) {
227 if (!HasBytes(8)) return false; 246 if (!HasBytes(8)) {
247 // If EOS is known, then this is an error. If not, it's a soft error.
248 *err = is_EOS_;
249 return false;
250 }
228 CHECK(Read8(&size)); 251 CHECK(Read8(&size));
229 } 252 }
230 253
231 // Implementation-specific: support for boxes larger than 2^31 has been 254 // Implementation-specific: support for boxes larger than 2^31 has been
232 // removed. 255 // removed.
233 if (size < static_cast<uint64>(pos_) || 256 if (size < static_cast<uint64>(pos_) ||
234 size > static_cast<uint64>(kint32max)) { 257 size > static_cast<uint64>(kint32max)) {
235 *err = true; 258 *err = true;
236 return false; 259 return false;
237 } 260 }
238 261
262 // Make sure the buffer contains at least the expected number of bytes.
263 // Since the data may be appended in pieces, this can only be checked if EOS.
264 if (is_EOS_ && size > static_cast<uint64>(size_)) {
265 *err = true;
266 return false;
267 }
268
239 // Note that the pos_ head has advanced to the byte immediately after the 269 // Note that the pos_ head has advanced to the byte immediately after the
240 // header, which is where we want it. 270 // header, which is where we want it.
241 size_ = size; 271 size_ = size;
242 return true; 272 return true;
243 } 273 }
244 274
245 } // namespace mp4 275 } // namespace mp4
246 } // namespace media 276 } // namespace media
OLDNEW
« no previous file with comments | « media/formats/mp4/box_reader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698