OLD | NEW |
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 <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 bool BufferReader::Read4sInto8s(int64_t* v) { | 84 bool BufferReader::Read4sInto8s(int64_t* v) { |
85 // Beware of the need for sign extension. | 85 // Beware of the need for sign extension. |
86 int32_t tmp; | 86 int32_t tmp; |
87 RCHECK(Read4s(&tmp)); | 87 RCHECK(Read4s(&tmp)); |
88 *v = tmp; | 88 *v = tmp; |
89 return true; | 89 return true; |
90 } | 90 } |
91 | 91 |
92 BoxReader::BoxReader(const uint8_t* buf, | 92 BoxReader::BoxReader(const uint8_t* buf, |
93 const size_t buf_size, | 93 const size_t buf_size, |
94 const scoped_refptr<MediaLog>& media_log, | 94 MediaLog* media_log, |
95 bool is_EOS) | 95 bool is_EOS) |
96 : BufferReader(buf, buf_size), | 96 : BufferReader(buf, buf_size), |
97 media_log_(media_log), | 97 media_log_(media_log), |
98 box_size_(0), | 98 box_size_(0), |
99 box_size_known_(false), | 99 box_size_known_(false), |
100 type_(FOURCC_NULL), | 100 type_(FOURCC_NULL), |
101 version_(0), | 101 version_(0), |
102 flags_(0), | 102 flags_(0), |
103 scanned_(false), | 103 scanned_(false), |
104 is_EOS_(is_EOS) {} | 104 is_EOS_(is_EOS) {} |
105 | 105 |
106 BoxReader::BoxReader(const BoxReader& other) = default; | 106 BoxReader::BoxReader(const BoxReader& other) = default; |
107 | 107 |
108 BoxReader::~BoxReader() { | 108 BoxReader::~BoxReader() { |
109 if (scanned_ && !children_.empty()) { | 109 if (scanned_ && !children_.empty()) { |
110 for (ChildMap::iterator itr = children_.begin(); | 110 for (ChildMap::iterator itr = children_.begin(); |
111 itr != children_.end(); ++itr) { | 111 itr != children_.end(); ++itr) { |
112 DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first); | 112 DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first); |
113 } | 113 } |
114 } | 114 } |
115 } | 115 } |
116 | 116 |
117 // static | 117 // static |
118 BoxReader* BoxReader::ReadTopLevelBox(const uint8_t* buf, | 118 BoxReader* BoxReader::ReadTopLevelBox(const uint8_t* buf, |
119 const size_t buf_size, | 119 const size_t buf_size, |
120 const scoped_refptr<MediaLog>& media_log, | 120 MediaLog* media_log, |
121 bool* err) { | 121 bool* err) { |
122 std::unique_ptr<BoxReader> reader( | 122 std::unique_ptr<BoxReader> reader( |
123 new BoxReader(buf, buf_size, media_log, false)); | 123 new BoxReader(buf, buf_size, media_log, false)); |
124 if (!reader->ReadHeader(err)) | 124 if (!reader->ReadHeader(err)) |
125 return NULL; | 125 return NULL; |
126 | 126 |
127 // BoxReader::ReadHeader is expected to return false if box_size > buf_size. | 127 // BoxReader::ReadHeader is expected to return false if box_size > buf_size. |
128 // This may happen if a partial mp4 box is appended, or if the box header is | 128 // This may happen if a partial mp4 box is appended, or if the box header is |
129 // corrupt. | 129 // corrupt. |
130 CHECK(reader->box_size() <= static_cast<uint64_t>(buf_size)); | 130 CHECK(reader->box_size() <= static_cast<uint64_t>(buf_size)); |
131 | 131 |
132 if (!IsValidTopLevelBox(reader->type(), media_log)) { | 132 if (!IsValidTopLevelBox(reader->type(), media_log)) { |
133 *err = true; | 133 *err = true; |
134 return NULL; | 134 return NULL; |
135 } | 135 } |
136 | 136 |
137 return reader.release(); | 137 return reader.release(); |
138 } | 138 } |
139 | 139 |
140 // static | 140 // static |
141 bool BoxReader::StartTopLevelBox(const uint8_t* buf, | 141 bool BoxReader::StartTopLevelBox(const uint8_t* buf, |
142 const size_t buf_size, | 142 const size_t buf_size, |
143 const scoped_refptr<MediaLog>& media_log, | 143 MediaLog* media_log, |
144 FourCC* type, | 144 FourCC* type, |
145 size_t* box_size, | 145 size_t* box_size, |
146 bool* err) { | 146 bool* err) { |
147 BoxReader reader(buf, buf_size, media_log, false); | 147 BoxReader reader(buf, buf_size, media_log, false); |
148 if (!reader.ReadHeader(err)) return false; | 148 if (!reader.ReadHeader(err)) return false; |
149 if (!IsValidTopLevelBox(reader.type(), media_log)) { | 149 if (!IsValidTopLevelBox(reader.type(), media_log)) { |
150 *err = true; | 150 *err = true; |
151 return false; | 151 return false; |
152 } | 152 } |
153 *type = reader.type(); | 153 *type = reader.type(); |
154 *box_size = reader.box_size(); | 154 *box_size = reader.box_size(); |
155 return true; | 155 return true; |
156 } | 156 } |
157 | 157 |
158 // static | 158 // static |
159 BoxReader* BoxReader::ReadConcatentatedBoxes(const uint8_t* buf, | 159 BoxReader* BoxReader::ReadConcatentatedBoxes(const uint8_t* buf, |
160 const size_t buf_size) { | 160 const size_t buf_size) { |
161 BoxReader* reader = new BoxReader(buf, buf_size, new MediaLog(), true); | 161 // TODO(wolenetz): Questionable MediaLog usage, http://crbug.com/712310 |
| 162 MediaLog media_log; |
| 163 BoxReader* reader = new BoxReader(buf, buf_size, &media_log, true); |
162 | 164 |
163 // Concatenated boxes are passed in without a wrapping parent box. Set | 165 // Concatenated boxes are passed in without a wrapping parent box. Set |
164 // |box_size_| to the concatenated buffer length to mimic having already | 166 // |box_size_| to the concatenated buffer length to mimic having already |
165 // parsed the parent box. | 167 // parsed the parent box. |
166 reader->box_size_ = buf_size; | 168 reader->box_size_ = buf_size; |
167 reader->box_size_known_ = true; | 169 reader->box_size_known_ = true; |
168 | 170 |
169 return reader; | 171 return reader; |
170 } | 172 } |
171 | 173 |
172 // static | 174 // static |
173 bool BoxReader::IsValidTopLevelBox(const FourCC& type, | 175 bool BoxReader::IsValidTopLevelBox(const FourCC& type, MediaLog* media_log) { |
174 const scoped_refptr<MediaLog>& media_log) { | |
175 switch (type) { | 176 switch (type) { |
176 case FOURCC_FTYP: | 177 case FOURCC_FTYP: |
177 case FOURCC_PDIN: | 178 case FOURCC_PDIN: |
178 case FOURCC_BLOC: | 179 case FOURCC_BLOC: |
179 case FOURCC_MOOV: | 180 case FOURCC_MOOV: |
180 case FOURCC_MOOF: | 181 case FOURCC_MOOF: |
181 case FOURCC_MFRA: | 182 case FOURCC_MFRA: |
182 case FOURCC_MDAT: | 183 case FOURCC_MDAT: |
183 case FOURCC_FREE: | 184 case FOURCC_FREE: |
184 case FOURCC_SKIP: | 185 case FOURCC_SKIP: |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 | 298 |
298 // Note that the pos_ head has advanced to the byte immediately after the | 299 // Note that the pos_ head has advanced to the byte immediately after the |
299 // header, which is where we want it. | 300 // header, which is where we want it. |
300 box_size_ = base::checked_cast<size_t>(box_size); | 301 box_size_ = base::checked_cast<size_t>(box_size); |
301 box_size_known_ = true; | 302 box_size_known_ = true; |
302 return true; | 303 return true; |
303 } | 304 } |
304 | 305 |
305 } // namespace mp4 | 306 } // namespace mp4 |
306 } // namespace media | 307 } // namespace media |
OLD | NEW |