[go: nahoru, domu]

Encode InitializationVectors into VP9 video frames

Using a vector of subsamples and a starting initialization vector,
start incrementing the IV based on how large each video frame is. These
values are used by accelerators to support encrypted playback.

Since subsamples and frames can overlap, we have to cover multiple
scenarios:
frames & subsamples line up:
┌───────────────────┬────────────────────┐
│ frame 1           │ frame 2            │
┝━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━┥
│ clear1 | cipher 1 │ clear 2 | cipher 2 │
└───────────────────┴────────────────────┘

subsample clear covers all first frame and partial second frame:
┌───────────────────┬────────────────────┐
│ frame 1           │ frame 2            │
┝━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━┥
│ clear1                  | cipher 1     │
└────────────────────────────────────────┘

one frame has more than one subsample, and subsamples might not align:
┌─────────────────────────┬────────────────────┐
│ frame 1                 │ frame 2            │
┝━━━━━━━━━━━━━━━━━━━┯━━━━━┷━━━━━━━━━━━━━━━━━━━━┥
│ clear1 | cipher 1 │ clear 2       | cipher 2 │
└───────────────────┴──────────────────────────┘
or:
┌────────────────────────────────────────┬────────────────────┐
│ frame 1                                │ frame 2            │
┝━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━┥
│ clear1 | cipher 1 │ clear 2 | cipher 2 │ clear 3 | cipher 3 │
└───────────────────┴────────────────────┴────────────────────┘
or:
┌─────────────────────────────────────────────┬───────────────┐
│ frame 1                                     │ frame 2       │
┝━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━┯━━━━┷━━━━━━━━━━━━━━━┥
│ clear1 | cipher 1 │ clear 2 | cipher 2 │ clear 3 | cipher 3 │
└───────────────────┴────────────────────┴────────────────────┘

a cipher section crosses a frame boundary: (this is an error and is caught)
┌───────────────────┬────────────────────┐
│ frame 1           │ frame 2            │
┝━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━┥
│ clear1      | cipher 1                 │
└────────────────────────────────────────┘

Bug: 881922
Bug: 836557
Change-Id: I7e69be34221702f77ec67daa8647c1767661bb51
Reviewed-on: https://chromium-review.googlesource.com/c/1307059
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
Reviewed-by: Rintaro Kuroiwa <rkuroiwa@chromium.org>
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611378}
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
index 3b40f0ef..5b8e183 100644
--- a/media/gpu/vp9_decoder.cc
+++ b/media/gpu/vp9_decoder.cc
@@ -34,15 +34,14 @@
                            const DecryptConfig* decrypt_config) {
   DCHECK(ptr);
   DCHECK(size);
-  if (decrypt_config) {
-    NOTIMPLEMENTED();
-    state_ = kError;
-    return;
-  }
   DVLOG(4) << "New input stream id: " << id << " at: " << (void*)ptr
            << " size: " << size;
   stream_id_ = id;
-  parser_.SetStream(ptr, size);
+  if (decrypt_config) {
+    parser_.SetStream(ptr, size, decrypt_config->Clone());
+  } else {
+    parser_.SetStream(ptr, size, nullptr);
+  }
 }
 
 bool VP9Decoder::Flush() {
@@ -65,9 +64,11 @@
 VP9Decoder::DecodeResult VP9Decoder::Decode() {
   while (1) {
     // Read a new frame header if one is not awaiting decoding already.
+    std::unique_ptr<DecryptConfig> decrypt_config;
     if (!curr_frame_hdr_) {
       std::unique_ptr<Vp9FrameHeader> hdr(new Vp9FrameHeader());
-      Vp9Parser::Result res = parser_.ParseNextFrame(hdr.get());
+      Vp9Parser::Result res =
+          parser_.ParseNextFrame(hdr.get(), &decrypt_config);
       switch (res) {
         case Vp9Parser::kOk:
           curr_frame_hdr_ = std::move(hdr);
@@ -179,6 +180,8 @@
     pic->set_visible_rect(new_render_rect);
     pic->set_bitstream_id(stream_id_);
 
+    pic->set_decrypt_config(std::move(decrypt_config));
+
     // For VP9, container color spaces override video stream color spaces.
     if (container_color_space_.IsSpecified()) {
       pic->set_colorspace(container_color_space_);