| Index: media/filters/h264_parser.cc
|
| diff --git a/media/filters/h264_parser.cc b/media/filters/h264_parser.cc
|
| index ee21ab82a1fca5381d91e9abe5908a23d831ca76..fd5646d49ecb3830315b0a8600c3665e5455b561 100644
|
| --- a/media/filters/h264_parser.cc
|
| +++ b/media/filters/h264_parser.cc
|
| @@ -6,6 +6,7 @@
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/stl_util.h"
|
|
|
| +#include "media/base/decrypt_config.h"
|
| #include "media/filters/h264_parser.h"
|
|
|
| namespace media {
|
| @@ -129,14 +130,33 @@ H264Parser::~H264Parser() {
|
| void H264Parser::Reset() {
|
| stream_ = NULL;
|
| bytes_left_ = 0;
|
| + encrypted_ranges_.clear();
|
| }
|
|
|
| void H264Parser::SetStream(const uint8* stream, off_t stream_size) {
|
| + std::vector<SubsampleEntry> subsamples;
|
| + SetEncryptedStream(stream, stream_size, subsamples);
|
| +}
|
| +
|
| +void H264Parser::SetEncryptedStream(
|
| + const uint8* stream, off_t stream_size,
|
| + const std::vector<SubsampleEntry>& subsamples) {
|
| DCHECK(stream);
|
| DCHECK_GT(stream_size, 0);
|
|
|
| stream_ = stream;
|
| bytes_left_ = stream_size;
|
| +
|
| + encrypted_ranges_.clear();
|
| + const uint8* start = stream;
|
| + const uint8* stream_end = stream_ + bytes_left_;
|
| + for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) {
|
| + start += subsamples[i].clear_bytes;
|
| +
|
| + const uint8* end = std::min(start + subsamples[i].cypher_bytes, stream_end);
|
| + encrypted_ranges_.Add(start, end);
|
| + start = end;
|
| + }
|
| }
|
|
|
| const H264PPS* H264Parser::GetPPS(int pps_id) {
|
| @@ -191,8 +211,9 @@ bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
|
| // Find the start code of next NALU.
|
| off_t nalu_start_off = 0;
|
| off_t annexb_start_code_size = 0;
|
| - if (!FindStartCode(stream_, bytes_left_,
|
| - &nalu_start_off, &annexb_start_code_size)) {
|
| +
|
| + if (!FindStartCodeInClearRanges(stream_, bytes_left_,
|
| + &nalu_start_off, &annexb_start_code_size)) {
|
| DVLOG(4) << "Could not find start code, end of stream?";
|
| return false;
|
| }
|
| @@ -216,8 +237,9 @@ bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
|
| // belong to the current NALU.
|
| off_t next_start_code_size = 0;
|
| off_t nalu_size_without_start_code = 0;
|
| - if (!FindStartCode(nalu_data, max_nalu_data_size,
|
| - &nalu_size_without_start_code, &next_start_code_size)) {
|
| + if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size,
|
| + &nalu_size_without_start_code,
|
| + &next_start_code_size)) {
|
| nalu_size_without_start_code = max_nalu_data_size;
|
| }
|
| *nalu_size = nalu_size_without_start_code + annexb_start_code_size;
|
| @@ -225,6 +247,42 @@ bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
|
| return true;
|
| }
|
|
|
| +bool H264Parser::FindStartCodeInClearRanges(
|
| + const uint8* data,
|
| + off_t data_size,
|
| + off_t* offset,
|
| + off_t* start_code_size) {
|
| + if (encrypted_ranges_.size() == 0)
|
| + return FindStartCode(data, data_size, offset, start_code_size);
|
| +
|
| + DCHECK_GE(data_size, 0);
|
| + const uint8* start = data;
|
| + do {
|
| + off_t bytes_left = data_size - (start - data);
|
| +
|
| + if (!FindStartCode(start, bytes_left, offset, start_code_size))
|
| + return false;
|
| +
|
| + // Construct a Ranges object that represents the region occupied
|
| + // by the start code and the 1 byte needed to read the NAL unit type.
|
| + const uint8* start_code = start + *offset;
|
| + const uint8* start_code_end = start_code + *start_code_size;
|
| + Ranges<const uint8*> start_code_range;
|
| + start_code_range.Add(start_code, start_code_end + 1);
|
| +
|
| + if (encrypted_ranges_.IntersectionWith(start_code_range).size() > 0) {
|
| + // The start code is inside an encrypted section so we need to scan
|
| + // for another start code.
|
| + *start_code_size = 0;
|
| + start += std::min(*offset + 1, bytes_left);
|
| + }
|
| + } while (*start_code_size == 0);
|
| +
|
| + // Update |*offset| to include the data we skipped over.
|
| + *offset += start - data;
|
| + return true;
|
| +}
|
| +
|
| H264Parser::Result H264Parser::ReadUE(int* val) {
|
| int num_bits = -1;
|
| int bit;
|
|
|