Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1046)

Unified Diff: media/filters/h264_parser.cc

Issue 379983002: Fix AnnexB validation logic to work with encrypted content. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Change method name and fix crash Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/h264_parser.cc
diff --git a/media/filters/h264_parser.cc b/media/filters/h264_parser.cc
index ee21ab82a1fca5381d91e9abe5908a23d831ca76..7d6334b71a58a040fef802d7b759e29a899204ab 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;
+ clear_ranges_.clear();
+ clear_range_index_ = 0;
}
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;
+
+ clear_ranges_.clear();
+ clear_range_index_ = 0;
+ const uint8* start = stream;
+ const uint8* stream_end = stream_ + bytes_left_;
+ for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) {
+ const uint8* end = std::min(start + subsamples[i].clear_bytes, stream_end);
xhwang 2014/07/16 05:06:13 It seems possible that start + subsamples[i].clear
acolwell GONE FROM CHROMIUM 2014/07/28 19:43:12 This is to protect this code from invalid subsampl
+ clear_ranges_.Add(start, end);
+ start += subsamples[i].clear_bytes + subsamples[i].cypher_bytes;
+ }
}
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,50 @@ bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
return true;
}
+bool H264Parser::FindStartCodeInClearRanges(
damienv1 2014/07/16 14:33:17 The likelihood of a start code emulation (although
acolwell GONE FROM CHROMIUM 2014/07/28 19:43:12 I've restored the code to what I had in Patch Set
+ const uint8* data,
+ off_t data_size,
+ off_t* offset,
+ off_t* start_code_size) {
+ if (clear_ranges_.size() == 0)
+ return FindStartCode(data, data_size, offset, start_code_size);
xhwang 2014/07/16 05:06:13 If there's no clear ranges, we don't need to searc
acolwell GONE FROM CHROMIUM 2014/07/28 19:43:12 Yes. A lack of clear ranges, or now encrypted rang
+
+ if (clear_range_index_ >= clear_ranges_.size())
+ return false;
+
+ DCHECK_GE(data_size, 0);
+ const uint8* start = data;
+ const uint8* end = data + data_size;
+ while (start < end) {
+ while (start >= clear_ranges_.end(clear_range_index_)) {
+ clear_range_index_++;
+ if (clear_range_index_ >= clear_ranges_.size())
+ return false;
+ if (start < clear_ranges_.start(clear_range_index_))
+ start = clear_ranges_.start(clear_range_index_);
+ }
xhwang 2014/07/16 05:06:13 This seems complicated. Can you add some comments
acolwell GONE FROM CHROMIUM 2014/07/28 19:43:12 Code is no longer here anymore.
+
+ DCHECK_LT(start, end);
+ DCHECK_GE(start, clear_ranges_.start(clear_range_index_));
+ DCHECK_LT(start, clear_ranges_.end(clear_range_index_));
+ off_t clear_bytes_left =
+ clear_ranges_.end(clear_range_index_) - start;
+ off_t bytes_left = std::min(end - start, clear_bytes_left);
+
+ if (FindStartCode(start, bytes_left, offset, start_code_size))
+ break;
+
+ start += bytes_left;
+ }
+
+ if (start >= end)
+ return false;
+
+ // 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;

Powered by Google App Engine
This is Rietveld 408576698