Index: media/gpu/vp9_decoder.cc |
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc |
index 993a8a149ae23bc036906e9c6623be15eb436544..a6f40d9e1401271a413de20d5f8ba804d5083a90 100644 |
--- a/media/gpu/vp9_decoder.cc |
+++ b/media/gpu/vp9_decoder.cc |
@@ -6,6 +6,7 @@ |
#include <memory> |
+#include "base/bind.h" |
#include "base/logging.h" |
#include "media/base/limits.h" |
#include "media/gpu/vp9_decoder.h" |
@@ -17,8 +18,9 @@ VP9Decoder::VP9Accelerator::VP9Accelerator() {} |
VP9Decoder::VP9Accelerator::~VP9Accelerator() {} |
VP9Decoder::VP9Decoder(VP9Accelerator* accelerator) |
- : state_(kNeedStreamMetadata), parser_(false), accelerator_(accelerator) { |
- DCHECK(accelerator_); |
+ : state_(kNeedStreamMetadata), |
+ accelerator_(accelerator), |
+ parser_(accelerator->IsFrameContextRequired()) { |
ref_frames_.resize(kVp9NumRefFrames); |
} |
@@ -54,7 +56,7 @@ VP9Decoder::DecodeResult VP9Decoder::Decode() { |
// Read a new frame header if one is not awaiting decoding already. |
if (!curr_frame_hdr_) { |
std::unique_ptr<Vp9FrameHeader> hdr(new Vp9FrameHeader()); |
- Vp9Parser::Result res = parser_.ParseNextFrame(hdr.get(), nullptr); |
+ Vp9Parser::Result res = parser_.ParseNextFrame(hdr.get()); |
switch (res) { |
case Vp9Parser::kOk: |
curr_frame_hdr_.reset(hdr.release()); |
@@ -69,7 +71,8 @@ VP9Decoder::DecodeResult VP9Decoder::Decode() { |
return kDecodeError; |
case Vp9Parser::kAwaitingRefresh: |
- NOTREACHED(); |
+ DVLOG(4) << "Awaiting context update"; |
+ return kNeedContextUpdate; |
} |
} |
@@ -152,12 +155,35 @@ void VP9Decoder::RefreshReferenceFrames(const scoped_refptr<VP9Picture>& pic) { |
} |
} |
+void VP9Decoder::UpdateFrameContext( |
+ const scoped_refptr<VP9Picture>& pic, |
+ const base::Callback<void(const Vp9FrameContext&)>& context_refresh_cb) { |
+ DCHECK(!context_refresh_cb.is_null()); |
+ Vp9FrameContext frame_ctx; |
+ memset(&frame_ctx, 0, sizeof(frame_ctx)); |
+ |
+ if (!accelerator_->GetFrameContext(pic, &frame_ctx)) { |
+ SetError(); |
+ return; |
+ } |
+ |
+ context_refresh_cb.Run(frame_ctx); |
+} |
+ |
bool VP9Decoder::DecodeAndOutputPicture(scoped_refptr<VP9Picture> pic) { |
DCHECK(!pic_size_.IsEmpty()); |
DCHECK(pic->frame_hdr); |
- if (!accelerator_->SubmitDecode(pic, parser_.GetSegmentation(), |
- parser_.GetLoopFilter(), ref_frames_)) |
+ base::Closure done_cb; |
+ const auto& context_refresh_cb = |
+ parser_.GetContextRefreshCb(pic->frame_hdr->frame_context_idx); |
+ if (!context_refresh_cb.is_null()) |
+ done_cb = base::Bind(&VP9Decoder::UpdateFrameContext, |
+ base::Unretained(this), pic, context_refresh_cb); |
+ |
+ const Vp9Parser::Context& context = parser_.context(); |
+ if (!accelerator_->SubmitDecode(pic, context.segmentation(), |
+ context.loop_filter(), ref_frames_, done_cb)) |
return false; |
if (pic->frame_hdr->show_frame) { |