| Index: media/gpu/vp9_decoder.cc
 | 
| diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
 | 
| index 993a8a149ae23bc036906e9c6623be15eb436544..8031ca3a1a86a0a3b18e859e84c61c57f9725070 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->RequiresFrameContext()) {
 | 
|    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,34 @@ 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);
 | 
|  
 | 
| +  base::Closure done_cb;
 | 
| +  const auto& context_refresh_cb = parser_.GetContextRefreshCb(pic->frame_hdr);
 | 
| +  if (!context_refresh_cb.is_null())
 | 
| +    done_cb = base::Bind(&VP9Decoder::UpdateFrameContext,
 | 
| +                         base::Unretained(this), pic, context_refresh_cb);
 | 
| +
 | 
|    if (!accelerator_->SubmitDecode(pic, parser_.GetSegmentation(),
 | 
| -                                  parser_.GetLoopFilter(), ref_frames_))
 | 
| +                                  parser_.GetLoopFilter(), ref_frames_,
 | 
| +                                  done_cb))
 | 
|      return false;
 | 
|  
 | 
|    if (pic->frame_hdr->show_frame) {
 | 
| 
 |