Chromium Code Reviews| 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 "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 | 8 |
| 9 #include "media/base/decrypt_config.h" | |
| 9 #include "media/filters/h264_parser.h" | 10 #include "media/filters/h264_parser.h" |
| 10 | 11 |
| 11 namespace media { | 12 namespace media { |
| 12 | 13 |
| 13 bool H264SliceHeader::IsPSlice() const { | 14 bool H264SliceHeader::IsPSlice() const { |
| 14 return (slice_type % 5 == kPSlice); | 15 return (slice_type % 5 == kPSlice); |
| 15 } | 16 } |
| 16 | 17 |
| 17 bool H264SliceHeader::IsBSlice() const { | 18 bool H264SliceHeader::IsBSlice() const { |
| 18 return (slice_type % 5 == kBSlice); | 19 return (slice_type % 5 == kBSlice); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 } | 123 } |
| 123 | 124 |
| 124 H264Parser::~H264Parser() { | 125 H264Parser::~H264Parser() { |
| 125 STLDeleteValues(&active_SPSes_); | 126 STLDeleteValues(&active_SPSes_); |
| 126 STLDeleteValues(&active_PPSes_); | 127 STLDeleteValues(&active_PPSes_); |
| 127 } | 128 } |
| 128 | 129 |
| 129 void H264Parser::Reset() { | 130 void H264Parser::Reset() { |
| 130 stream_ = NULL; | 131 stream_ = NULL; |
| 131 bytes_left_ = 0; | 132 bytes_left_ = 0; |
| 133 encrypted_ranges_.clear(); | |
| 132 } | 134 } |
| 133 | 135 |
| 134 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { | 136 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { |
| 137 std::vector<SubsampleEntry> subsamples; | |
| 138 SetStream(stream, stream_size, subsamples); | |
| 139 } | |
| 140 | |
| 141 void H264Parser::SetStream(const uint8* stream, off_t stream_size, | |
| 142 const std::vector<SubsampleEntry>& subsamples) { | |
| 135 DCHECK(stream); | 143 DCHECK(stream); |
| 136 DCHECK_GT(stream_size, 0); | 144 DCHECK_GT(stream_size, 0); |
| 137 | 145 |
| 138 stream_ = stream; | 146 stream_ = stream; |
| 139 bytes_left_ = stream_size; | 147 bytes_left_ = stream_size; |
| 148 | |
| 149 encrypted_ranges_.clear(); | |
| 150 const uint8* offset = stream; | |
| 151 for (size_t i = 0; i < subsamples.size(); ++i) { | |
| 152 offset += subsamples[i].clear_bytes; | |
| 153 | |
| 154 encrypted_ranges_.Add(offset, offset + subsamples[i].cypher_bytes); | |
| 155 | |
| 156 offset += subsamples[i].cypher_bytes; | |
| 157 } | |
| 140 } | 158 } |
| 141 | 159 |
| 142 const H264PPS* H264Parser::GetPPS(int pps_id) { | 160 const H264PPS* H264Parser::GetPPS(int pps_id) { |
| 143 return active_PPSes_[pps_id]; | 161 return active_PPSes_[pps_id]; |
| 144 } | 162 } |
| 145 | 163 |
| 146 const H264SPS* H264Parser::GetSPS(int sps_id) { | 164 const H264SPS* H264Parser::GetSPS(int sps_id) { |
| 147 return active_SPSes_[sps_id]; | 165 return active_SPSes_[sps_id]; |
| 148 } | 166 } |
| 149 | 167 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 // |*offset| is equal to 0 (valid offset). | 202 // |*offset| is equal to 0 (valid offset). |
| 185 *offset = data_size - bytes_left; | 203 *offset = data_size - bytes_left; |
| 186 *start_code_size = 0; | 204 *start_code_size = 0; |
| 187 return false; | 205 return false; |
| 188 } | 206 } |
| 189 | 207 |
| 190 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) { | 208 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) { |
| 191 // Find the start code of next NALU. | 209 // Find the start code of next NALU. |
| 192 off_t nalu_start_off = 0; | 210 off_t nalu_start_off = 0; |
| 193 off_t annexb_start_code_size = 0; | 211 off_t annexb_start_code_size = 0; |
| 194 if (!FindStartCode(stream_, bytes_left_, | 212 |
| 195 &nalu_start_off, &annexb_start_code_size)) { | 213 if (!FindNextStartCode(stream_, bytes_left_, |
| 214 &nalu_start_off, &annexb_start_code_size)) { | |
| 196 DVLOG(4) << "Could not find start code, end of stream?"; | 215 DVLOG(4) << "Could not find start code, end of stream?"; |
| 197 return false; | 216 return false; |
| 198 } | 217 } |
| 199 | 218 |
| 200 // Move the stream to the beginning of the NALU (pointing at the start code). | 219 // Move the stream to the beginning of the NALU (pointing at the start code). |
| 201 stream_ += nalu_start_off; | 220 stream_ += nalu_start_off; |
| 202 bytes_left_ -= nalu_start_off; | 221 bytes_left_ -= nalu_start_off; |
| 203 | 222 |
| 204 const uint8* nalu_data = stream_ + annexb_start_code_size; | 223 const uint8* nalu_data = stream_ + annexb_start_code_size; |
| 205 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; | 224 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; |
| 206 if (max_nalu_data_size <= 0) { | 225 if (max_nalu_data_size <= 0) { |
| 207 DVLOG(3) << "End of stream"; | 226 DVLOG(3) << "End of stream"; |
| 208 return false; | 227 return false; |
| 209 } | 228 } |
| 210 | 229 |
| 211 // Find the start code of next NALU; | 230 // Find the start code of next NALU; |
| 212 // if successful, |nalu_size_without_start_code| is the number of bytes from | 231 // if successful, |nalu_size_without_start_code| is the number of bytes from |
| 213 // after previous start code to before this one; | 232 // after previous start code to before this one; |
| 214 // if next start code is not found, it is still a valid NALU since there | 233 // if next start code is not found, it is still a valid NALU since there |
| 215 // are some bytes left after the first start code: all the remaining bytes | 234 // are some bytes left after the first start code: all the remaining bytes |
| 216 // belong to the current NALU. | 235 // belong to the current NALU. |
| 217 off_t next_start_code_size = 0; | 236 off_t next_start_code_size = 0; |
| 218 off_t nalu_size_without_start_code = 0; | 237 off_t nalu_size_without_start_code = 0; |
| 219 if (!FindStartCode(nalu_data, max_nalu_data_size, | 238 if (!FindNextStartCode(nalu_data, max_nalu_data_size, |
| 220 &nalu_size_without_start_code, &next_start_code_size)) { | 239 &nalu_size_without_start_code, |
| 240 &next_start_code_size)) { | |
| 221 nalu_size_without_start_code = max_nalu_data_size; | 241 nalu_size_without_start_code = max_nalu_data_size; |
| 222 } | 242 } |
| 223 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; | 243 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; |
| 224 *start_code_size = annexb_start_code_size; | 244 *start_code_size = annexb_start_code_size; |
| 225 return true; | 245 return true; |
| 226 } | 246 } |
| 227 | 247 |
| 248 bool H264Parser::FindNextStartCode(const uint8* data, off_t data_size, | |
| 249 off_t* offset, off_t* start_code_size) { | |
| 250 if (encrypted_ranges_.size() == 0) | |
| 251 return FindStartCode(data, data_size, offset, start_code_size); | |
| 252 | |
| 253 DCHECK_GE(data_size, 0); | |
| 254 const uint8* start = data; | |
| 255 do { | |
| 256 off_t bytes_left = data_size - (start - data); | |
| 257 | |
| 258 if (!FindStartCode(start, bytes_left, offset, start_code_size)) | |
| 259 return false; | |
| 260 | |
| 261 const uint8* start_code = start + *offset; | |
| 262 const uint8* start_code_end = start_code + *start_code_size; | |
| 263 Ranges<const uint8*> start_code_range; | |
| 264 start_code_range.Add(start_code, start_code_end); | |
| 265 | |
| 266 if (encrypted_ranges_.IntersectionWith(start_code_range).size() > 0) { | |
| 267 // The start code is inside an encrypted section so we need to scan | |
| 268 // for another start code. | |
| 269 *start_code_size = 0; | |
| 270 start += std::min(*offset + 1, bytes_left); | |
| 271 } | |
| 272 } while (*start_code_size == 0); | |
|
xhwang
2014/07/10 06:23:01
Will it be simpler and more efficient if you just
acolwell GONE FROM CHROMIUM
2014/07/15 22:10:44
I've changed the code around to search clear range
| |
| 273 | |
| 274 // Update |*offset| to include the data we skipped over. | |
| 275 *offset += start - data; | |
| 276 return true; | |
| 277 } | |
| 278 | |
| 228 H264Parser::Result H264Parser::ReadUE(int* val) { | 279 H264Parser::Result H264Parser::ReadUE(int* val) { |
| 229 int num_bits = -1; | 280 int num_bits = -1; |
| 230 int bit; | 281 int bit; |
| 231 int rest; | 282 int rest; |
| 232 | 283 |
| 233 // Count the number of contiguous zero bits. | 284 // Count the number of contiguous zero bits. |
| 234 do { | 285 do { |
| 235 READ_BITS_OR_RETURN(1, &bit); | 286 READ_BITS_OR_RETURN(1, &bit); |
| 236 num_bits++; | 287 num_bits++; |
| 237 } while (bit == 0); | 288 } while (bit == 0); |
| (...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1251 | 1302 |
| 1252 default: | 1303 default: |
| 1253 DVLOG(4) << "Unsupported SEI message"; | 1304 DVLOG(4) << "Unsupported SEI message"; |
| 1254 break; | 1305 break; |
| 1255 } | 1306 } |
| 1256 | 1307 |
| 1257 return kOk; | 1308 return kOk; |
| 1258 } | 1309 } |
| 1259 | 1310 |
| 1260 } // namespace media | 1311 } // namespace media |
| OLD | NEW |