| 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/base/decrypt_config.h" |
| 10 #include "media/filters/h264_parser.h" | 10 #include "media/filters/h264_parser.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 STLDeleteValues(&active_SPSes_); | 126 STLDeleteValues(&active_SPSes_); |
| 127 STLDeleteValues(&active_PPSes_); | 127 STLDeleteValues(&active_PPSes_); |
| 128 } | 128 } |
| 129 | 129 |
| 130 void H264Parser::Reset() { | 130 void H264Parser::Reset() { |
| 131 stream_ = NULL; | 131 stream_ = NULL; |
| 132 bytes_left_ = 0; | 132 bytes_left_ = 0; |
| 133 encrypted_ranges_.clear(); | 133 encrypted_ranges_.clear(); |
| 134 } | 134 } |
| 135 | 135 |
| 136 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { | 136 void H264Parser::SetStream(const uint8_t* stream, off_t stream_size) { |
| 137 std::vector<SubsampleEntry> subsamples; | 137 std::vector<SubsampleEntry> subsamples; |
| 138 SetEncryptedStream(stream, stream_size, subsamples); | 138 SetEncryptedStream(stream, stream_size, subsamples); |
| 139 } | 139 } |
| 140 | 140 |
| 141 void H264Parser::SetEncryptedStream( | 141 void H264Parser::SetEncryptedStream( |
| 142 const uint8* stream, off_t stream_size, | 142 const uint8_t* stream, |
| 143 off_t stream_size, |
| 143 const std::vector<SubsampleEntry>& subsamples) { | 144 const std::vector<SubsampleEntry>& subsamples) { |
| 144 DCHECK(stream); | 145 DCHECK(stream); |
| 145 DCHECK_GT(stream_size, 0); | 146 DCHECK_GT(stream_size, 0); |
| 146 | 147 |
| 147 stream_ = stream; | 148 stream_ = stream; |
| 148 bytes_left_ = stream_size; | 149 bytes_left_ = stream_size; |
| 149 | 150 |
| 150 encrypted_ranges_.clear(); | 151 encrypted_ranges_.clear(); |
| 151 const uint8* start = stream; | 152 const uint8_t* start = stream; |
| 152 const uint8* stream_end = stream_ + bytes_left_; | 153 const uint8_t* stream_end = stream_ + bytes_left_; |
| 153 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) { | 154 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) { |
| 154 start += subsamples[i].clear_bytes; | 155 start += subsamples[i].clear_bytes; |
| 155 | 156 |
| 156 const uint8* end = std::min(start + subsamples[i].cypher_bytes, stream_end); | 157 const uint8_t* end = |
| 158 std::min(start + subsamples[i].cypher_bytes, stream_end); |
| 157 encrypted_ranges_.Add(start, end); | 159 encrypted_ranges_.Add(start, end); |
| 158 start = end; | 160 start = end; |
| 159 } | 161 } |
| 160 } | 162 } |
| 161 | 163 |
| 162 const H264PPS* H264Parser::GetPPS(int pps_id) const { | 164 const H264PPS* H264Parser::GetPPS(int pps_id) const { |
| 163 auto it = active_PPSes_.find(pps_id); | 165 auto it = active_PPSes_.find(pps_id); |
| 164 if (it == active_PPSes_.end()) { | 166 if (it == active_PPSes_.end()) { |
| 165 DVLOG(1) << "Requested a nonexistent PPS id " << pps_id; | 167 DVLOG(1) << "Requested a nonexistent PPS id " << pps_id; |
| 166 return nullptr; | 168 return nullptr; |
| 167 } | 169 } |
| 168 | 170 |
| 169 return it->second; | 171 return it->second; |
| 170 } | 172 } |
| 171 | 173 |
| 172 const H264SPS* H264Parser::GetSPS(int sps_id) const { | 174 const H264SPS* H264Parser::GetSPS(int sps_id) const { |
| 173 auto it = active_SPSes_.find(sps_id); | 175 auto it = active_SPSes_.find(sps_id); |
| 174 if (it == active_SPSes_.end()) { | 176 if (it == active_SPSes_.end()) { |
| 175 DVLOG(1) << "Requested a nonexistent SPS id " << sps_id; | 177 DVLOG(1) << "Requested a nonexistent SPS id " << sps_id; |
| 176 return nullptr; | 178 return nullptr; |
| 177 } | 179 } |
| 178 | 180 |
| 179 return it->second; | 181 return it->second; |
| 180 } | 182 } |
| 181 | 183 |
| 182 static inline bool IsStartCode(const uint8* data) { | 184 static inline bool IsStartCode(const uint8_t* data) { |
| 183 return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01; | 185 return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01; |
| 184 } | 186 } |
| 185 | 187 |
| 186 // static | 188 // static |
| 187 bool H264Parser::FindStartCode(const uint8* data, off_t data_size, | 189 bool H264Parser::FindStartCode(const uint8_t* data, |
| 188 off_t* offset, off_t* start_code_size) { | 190 off_t data_size, |
| 191 off_t* offset, |
| 192 off_t* start_code_size) { |
| 189 DCHECK_GE(data_size, 0); | 193 DCHECK_GE(data_size, 0); |
| 190 off_t bytes_left = data_size; | 194 off_t bytes_left = data_size; |
| 191 | 195 |
| 192 while (bytes_left >= 3) { | 196 while (bytes_left >= 3) { |
| 193 if (IsStartCode(data)) { | 197 if (IsStartCode(data)) { |
| 194 // Found three-byte start code, set pointer at its beginning. | 198 // Found three-byte start code, set pointer at its beginning. |
| 195 *offset = data_size - bytes_left; | 199 *offset = data_size - bytes_left; |
| 196 *start_code_size = 3; | 200 *start_code_size = 3; |
| 197 | 201 |
| 198 // If there is a zero byte before this start code, | 202 // If there is a zero byte before this start code, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 228 encrypted_ranges_, | 232 encrypted_ranges_, |
| 229 &nalu_start_off, &annexb_start_code_size)) { | 233 &nalu_start_off, &annexb_start_code_size)) { |
| 230 DVLOG(4) << "Could not find start code, end of stream?"; | 234 DVLOG(4) << "Could not find start code, end of stream?"; |
| 231 return false; | 235 return false; |
| 232 } | 236 } |
| 233 | 237 |
| 234 // Move the stream to the beginning of the NALU (pointing at the start code). | 238 // Move the stream to the beginning of the NALU (pointing at the start code). |
| 235 stream_ += nalu_start_off; | 239 stream_ += nalu_start_off; |
| 236 bytes_left_ -= nalu_start_off; | 240 bytes_left_ -= nalu_start_off; |
| 237 | 241 |
| 238 const uint8* nalu_data = stream_ + annexb_start_code_size; | 242 const uint8_t* nalu_data = stream_ + annexb_start_code_size; |
| 239 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; | 243 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; |
| 240 if (max_nalu_data_size <= 0) { | 244 if (max_nalu_data_size <= 0) { |
| 241 DVLOG(3) << "End of stream"; | 245 DVLOG(3) << "End of stream"; |
| 242 return false; | 246 return false; |
| 243 } | 247 } |
| 244 | 248 |
| 245 // Find the start code of next NALU; | 249 // Find the start code of next NALU; |
| 246 // if successful, |nalu_size_without_start_code| is the number of bytes from | 250 // if successful, |nalu_size_without_start_code| is the number of bytes from |
| 247 // after previous start code to before this one; | 251 // after previous start code to before this one; |
| 248 // if next start code is not found, it is still a valid NALU since there | 252 // if next start code is not found, it is still a valid NALU since there |
| 249 // are some bytes left after the first start code: all the remaining bytes | 253 // are some bytes left after the first start code: all the remaining bytes |
| 250 // belong to the current NALU. | 254 // belong to the current NALU. |
| 251 off_t next_start_code_size = 0; | 255 off_t next_start_code_size = 0; |
| 252 off_t nalu_size_without_start_code = 0; | 256 off_t nalu_size_without_start_code = 0; |
| 253 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size, | 257 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size, |
| 254 encrypted_ranges_, | 258 encrypted_ranges_, |
| 255 &nalu_size_without_start_code, | 259 &nalu_size_without_start_code, |
| 256 &next_start_code_size)) { | 260 &next_start_code_size)) { |
| 257 nalu_size_without_start_code = max_nalu_data_size; | 261 nalu_size_without_start_code = max_nalu_data_size; |
| 258 } | 262 } |
| 259 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; | 263 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; |
| 260 *start_code_size = annexb_start_code_size; | 264 *start_code_size = annexb_start_code_size; |
| 261 return true; | 265 return true; |
| 262 } | 266 } |
| 263 | 267 |
| 264 bool H264Parser::FindStartCodeInClearRanges( | 268 bool H264Parser::FindStartCodeInClearRanges( |
| 265 const uint8* data, | 269 const uint8_t* data, |
| 266 off_t data_size, | 270 off_t data_size, |
| 267 const Ranges<const uint8*>& encrypted_ranges, | 271 const Ranges<const uint8_t*>& encrypted_ranges, |
| 268 off_t* offset, | 272 off_t* offset, |
| 269 off_t* start_code_size) { | 273 off_t* start_code_size) { |
| 270 if (encrypted_ranges.size() == 0) | 274 if (encrypted_ranges.size() == 0) |
| 271 return FindStartCode(data, data_size, offset, start_code_size); | 275 return FindStartCode(data, data_size, offset, start_code_size); |
| 272 | 276 |
| 273 DCHECK_GE(data_size, 0); | 277 DCHECK_GE(data_size, 0); |
| 274 const uint8* start = data; | 278 const uint8_t* start = data; |
| 275 do { | 279 do { |
| 276 off_t bytes_left = data_size - (start - data); | 280 off_t bytes_left = data_size - (start - data); |
| 277 | 281 |
| 278 if (!FindStartCode(start, bytes_left, offset, start_code_size)) | 282 if (!FindStartCode(start, bytes_left, offset, start_code_size)) |
| 279 return false; | 283 return false; |
| 280 | 284 |
| 281 // Construct a Ranges object that represents the region occupied | 285 // Construct a Ranges object that represents the region occupied |
| 282 // by the start code and the 1 byte needed to read the NAL unit type. | 286 // by the start code and the 1 byte needed to read the NAL unit type. |
| 283 const uint8* start_code = start + *offset; | 287 const uint8_t* start_code = start + *offset; |
| 284 const uint8* start_code_end = start_code + *start_code_size; | 288 const uint8_t* start_code_end = start_code + *start_code_size; |
| 285 Ranges<const uint8*> start_code_range; | 289 Ranges<const uint8_t*> start_code_range; |
| 286 start_code_range.Add(start_code, start_code_end + 1); | 290 start_code_range.Add(start_code, start_code_end + 1); |
| 287 | 291 |
| 288 if (encrypted_ranges.IntersectionWith(start_code_range).size() > 0) { | 292 if (encrypted_ranges.IntersectionWith(start_code_range).size() > 0) { |
| 289 // The start code is inside an encrypted section so we need to scan | 293 // The start code is inside an encrypted section so we need to scan |
| 290 // for another start code. | 294 // for another start code. |
| 291 *start_code_size = 0; | 295 *start_code_size = 0; |
| 292 start += std::min(*offset + 1, bytes_left); | 296 start += std::min(*offset + 1, bytes_left); |
| 293 } | 297 } |
| 294 } while (*start_code_size == 0); | 298 } while (*start_code_size == 0); |
| 295 | 299 |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 | 1337 |
| 1334 default: | 1338 default: |
| 1335 DVLOG(4) << "Unsupported SEI message"; | 1339 DVLOG(4) << "Unsupported SEI message"; |
| 1336 break; | 1340 break; |
| 1337 } | 1341 } |
| 1338 | 1342 |
| 1339 return kOk; | 1343 return kOk; |
| 1340 } | 1344 } |
| 1341 | 1345 |
| 1342 } // namespace media | 1346 } // namespace media |
| OLD | NEW |