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

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: Address CR comment 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
« no previous file with comments | « media/filters/h264_parser.h ('k') | media/formats/mp4/avc.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « media/filters/h264_parser.h ('k') | media/formats/mp4/avc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698