| 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 |