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 *err = true; |
| 109 return NULL; |
104 } | 110 } |
105 delete reader; | 111 |
| 112 if (reader->size() <= buf_size) |
| 113 return reader.release(); |
| 114 |
106 return NULL; | 115 return NULL; |
107 } | 116 } |
108 | 117 |
109 // static | 118 // static |
110 bool BoxReader::StartTopLevelBox(const uint8* buf, | 119 bool BoxReader::StartTopLevelBox(const uint8* buf, |
111 const int buf_size, | 120 const int buf_size, |
112 FourCC* type, | 121 FourCC* type, |
113 int* box_size, | 122 int* box_size, |
114 bool* err) { | 123 bool* err) { |
115 BoxReader reader(buf, buf_size); | 124 BoxReader reader(buf, buf_size); |
116 if (!reader.ReadHeader(err)) return false; | 125 if (!reader.ReadHeader(err)) return false; |
| 126 if (!IsValidTopLevelBox(reader.type())) { |
| 127 *err = true; |
| 128 return false; |
| 129 } |
117 *type = reader.type(); | 130 *type = reader.type(); |
118 *box_size = reader.size(); | 131 *box_size = reader.size(); |
119 return true; | 132 return true; |
120 } | 133 } |
121 | 134 |
| 135 // static |
| 136 bool BoxReader::IsValidTopLevelBox(const FourCC& type) { |
| 137 switch (type) { |
| 138 case FOURCC_FTYP: |
| 139 case FOURCC_PDIN: |
| 140 case FOURCC_MOOV: |
| 141 case FOURCC_MOOF: |
| 142 case FOURCC_MFRA: |
| 143 case FOURCC_MDAT: |
| 144 case FOURCC_FREE: |
| 145 case FOURCC_SKIP: |
| 146 case FOURCC_META: |
| 147 case FOURCC_MECO: |
| 148 case FOURCC_STYP: |
| 149 case FOURCC_SIDX: |
| 150 case FOURCC_SSIX: |
| 151 case FOURCC_PRFT: |
| 152 return true; |
| 153 default: |
| 154 // Hex is used to show nonprintable characters and aid in debugging |
| 155 LOG(WARNING) << "Unrecognized top-level box type 0x" |
| 156 << std::hex << type; |
| 157 return false; |
| 158 } |
| 159 } |
| 160 |
122 bool BoxReader::ScanChildren() { | 161 bool BoxReader::ScanChildren() { |
123 DCHECK(!scanned_); | 162 DCHECK(!scanned_); |
124 scanned_ = true; | 163 scanned_ = true; |
125 | 164 |
126 bool err = false; | 165 bool err = false; |
127 // TODO(strobe): Check or correct for multimap not inserting elements in | 166 // TODO(strobe): Check or correct for multimap not inserting elements in |
128 // consistent order. | 167 // consistent order. |
129 while (pos() < size()) { | 168 while (pos() < size()) { |
130 BoxReader child(&buf_[pos_], size_ - pos_); | 169 BoxReader child(&buf_[pos_], size_ - pos_); |
131 if (!child.ReadHeader(&err)) break; | 170 if (!child.ReadHeader(&err)) break; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 } | 227 } |
189 | 228 |
190 // Note that the pos_ head has advanced to the byte immediately after the | 229 // Note that the pos_ head has advanced to the byte immediately after the |
191 // header, which is where we want it. | 230 // header, which is where we want it. |
192 size_ = size; | 231 size_ = size; |
193 return true; | 232 return true; |
194 } | 233 } |
195 | 234 |
196 } // namespace mp4 | 235 } // namespace mp4 |
197 } // namespace media | 236 } // namespace media |
OLD | NEW |