OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/mp4/box_reader.h" | 5 #include "media/mp4/box_reader.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
11 | 11 |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/scoped_ptr.h" | |
13 #include "media/mp4/box_definitions.h" | 14 #include "media/mp4/box_definitions.h" |
14 #include "media/mp4/rcheck.h" | 15 #include "media/mp4/rcheck.h" |
15 | 16 |
16 namespace media { | 17 namespace media { |
17 namespace mp4 { | 18 namespace mp4 { |
18 | 19 |
19 Box::~Box() {} | 20 Box::~Box() {} |
20 | 21 |
21 bool BufferReader::Read1(uint8* v) { | 22 bool BufferReader::Read1(uint8* v) { |
22 RCHECK(HasBytes(1)); | 23 RCHECK(HasBytes(1)); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 | 89 |
89 BoxReader::~BoxReader() { | 90 BoxReader::~BoxReader() { |
90 if (scanned_ && !children_.empty()) { | 91 if (scanned_ && !children_.empty()) { |
91 for (ChildMap::iterator itr = children_.begin(); | 92 for (ChildMap::iterator itr = children_.begin(); |
92 itr != children_.end(); ++itr) { | 93 itr != children_.end(); ++itr) { |
93 DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first); | 94 DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first); |
94 } | 95 } |
95 } | 96 } |
96 } | 97 } |
97 | 98 |
99 // static | |
98 BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf, | 100 BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf, |
99 const int buf_size, | 101 const int buf_size, |
100 bool* err) { | 102 bool* err) { |
101 BoxReader* reader = new BoxReader(buf, buf_size); | 103 scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size)); |
102 if (reader->ReadHeader(err) && reader->size() <= buf_size) { | 104 if (!reader->ReadHeader(err)) |
103 return reader; | 105 return NULL; |
106 | |
107 if (!IsValidTopLevelBox(reader->type())) { | |
108 LOG(WARNING) << "Unrecognized top-level box type 0x" | |
109 << std::hex << reader->type(); | |
acolwell GONE FROM CHROMIUM
2012/08/02 20:38:18
Any reason not to use FourCCToString() here like y
strobe_
2012/08/02 21:27:50
In the expected case of misregistration, the box t
acolwell GONE FROM CHROMIUM
2012/08/02 21:40:25
Ok. Makes sense.
| |
110 *err = true; | |
111 return NULL; | |
104 } | 112 } |
105 delete reader; | 113 |
114 if (reader->size() <= buf_size) | |
115 return reader.release(); | |
116 | |
106 return NULL; | 117 return NULL; |
107 } | 118 } |
108 | 119 |
109 // static | 120 // static |
110 bool BoxReader::StartTopLevelBox(const uint8* buf, | 121 bool BoxReader::StartTopLevelBox(const uint8* buf, |
111 const int buf_size, | 122 const int buf_size, |
112 FourCC* type, | 123 FourCC* type, |
113 int* box_size, | 124 int* box_size, |
114 bool* err) { | 125 bool* err) { |
115 BoxReader reader(buf, buf_size); | 126 BoxReader reader(buf, buf_size); |
116 if (!reader.ReadHeader(err)) return false; | 127 if (!reader.ReadHeader(err)) return false; |
128 if (!IsValidTopLevelBox(reader.type())) { | |
129 *err = true; | |
130 return false; | |
131 } | |
117 *type = reader.type(); | 132 *type = reader.type(); |
118 *box_size = reader.size(); | 133 *box_size = reader.size(); |
119 return true; | 134 return true; |
120 } | 135 } |
121 | 136 |
137 // static | |
138 bool BoxReader::IsValidTopLevelBox(const FourCC& type) { | |
139 return (type == FOURCC_FTYP || | |
acolwell GONE FROM CHROMIUM
2012/08/02 20:38:18
nit: WDYT about using a switch() here w/ a return
strobe_
2012/08/02 21:27:50
Done.
| |
140 type == FOURCC_PDIN || | |
141 type == FOURCC_MOOV || | |
142 type == FOURCC_MOOF || | |
143 type == FOURCC_MFRA || | |
144 type == FOURCC_MDAT || | |
145 type == FOURCC_FREE || | |
146 type == FOURCC_SKIP || | |
147 type == FOURCC_META || | |
148 type == FOURCC_MECO || | |
149 type == FOURCC_STYP || | |
150 type == FOURCC_SIDX || | |
151 type == FOURCC_SSIX || | |
152 type == FOURCC_PRFT); | |
153 } | |
154 | |
122 bool BoxReader::ScanChildren() { | 155 bool BoxReader::ScanChildren() { |
123 DCHECK(!scanned_); | 156 DCHECK(!scanned_); |
124 scanned_ = true; | 157 scanned_ = true; |
125 | 158 |
126 bool err = false; | 159 bool err = false; |
127 // TODO(strobe): Check or correct for multimap not inserting elements in | 160 // TODO(strobe): Check or correct for multimap not inserting elements in |
128 // consistent order. | 161 // consistent order. |
129 while (pos() < size()) { | 162 while (pos() < size()) { |
130 BoxReader child(&buf_[pos_], size_ - pos_); | 163 BoxReader child(&buf_[pos_], size_ - pos_); |
131 if (!child.ReadHeader(&err)) break; | 164 if (!child.ReadHeader(&err)) break; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 } | 221 } |
189 | 222 |
190 // Note that the pos_ head has advanced to the byte immediately after the | 223 // Note that the pos_ head has advanced to the byte immediately after the |
191 // header, which is where we want it. | 224 // header, which is where we want it. |
192 size_ = size; | 225 size_ = size; |
193 return true; | 226 return true; |
194 } | 227 } |
195 | 228 |
196 } // namespace mp4 | 229 } // namespace mp4 |
197 } // namespace media | 230 } // namespace media |
OLD | NEW |