146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file. 468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "media/cast/receiver/video_decoder.h" 668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/bind.h" 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/bind_helpers.h" 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/json/json_reader.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/location.h" 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/logging.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/values.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "media/base/video_util.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "media/cast/cast_defines.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "media/cast/cast_environment.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// VPX_CODEC_DISABLE_COMPAT excludes parts of the libvpx API that provide 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// backwards compatibility for legacy applications using the library. 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#define VPX_CODEC_DISABLE_COMPAT 1 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/gfx/size.h" 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace media { 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace cast { 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Base class that handles the common problem of detecting dropped frames, and 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// then invoking the Decode() method implemented by the subclasses to convert 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// the encoded payload data into a usable video frame. 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass VideoDecoder::ImplBase 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : public base::RefCountedThreadSafe<VideoDecoder::ImplBase> { 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ImplBase(const scoped_refptr<CastEnvironment>& cast_environment, 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Codec codec) 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : cast_environment_(cast_environment), 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch codec_(codec), 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED), 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch seen_first_frame_(false) {} 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CastInitializationStatus InitializationResult() const { 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return cast_initialization_status_; 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void DecodeFrame(scoped_ptr<EncodedFrame> encoded_frame, 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DecodeFrameCallback& callback) { 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK_EQ(cast_initialization_status_, STATUS_VIDEO_INITIALIZED); 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch COMPILE_ASSERT(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_), 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch size_of_frame_id_types_do_not_match); 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool is_continuous = true; 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (seen_first_frame_) { 51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const uint32 frames_ahead = encoded_frame->frame_id - last_frame_id_; 52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (frames_ahead > 1) { 53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch RecoverBecauseFramesWereDropped(); 54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch is_continuous = false; 55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch seen_first_frame_ = true; 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch last_frame_id_ = encoded_frame->frame_id; 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<VideoFrame> decoded_frame = Decode( 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) encoded_frame->mutable_bytes(), 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static_cast<int>(encoded_frame->data.size())); 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cast_environment_->PostTask( 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CastEnvironment::MAIN, 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FROM_HERE, 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(callback, decoded_frame, is_continuous)); 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch protected: 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch friend class base::RefCountedThreadSafe<ImplBase>; 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual ~ImplBase() {} 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual void RecoverBecauseFramesWereDropped() {} 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Note: Implementation of Decode() is allowed to mutate |data|. 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual scoped_refptr<VideoFrame> Decode(uint8* data, int len) = 0; 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<CastEnvironment> cast_environment_; 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Codec codec_; 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Subclass' ctor is expected to set this to STATUS_VIDEO_INITIALIZED. 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CastInitializationStatus cast_initialization_status_; 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private: 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool seen_first_frame_; 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uint32 last_frame_id_; 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(ImplBase); 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass VideoDecoder::Vp8Impl : public VideoDecoder::ImplBase { 93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch explicit Vp8Impl(const scoped_refptr<CastEnvironment>& cast_environment) 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : ImplBase(cast_environment, CODEC_VIDEO_VP8) { 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (ImplBase::cast_initialization_status_ != STATUS_VIDEO_UNINITIALIZED) 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vpx_codec_dec_cfg_t cfg = {0}; 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(miu): Revisit this for typical multi-core desktop use case. This 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // feels like it should be 4 or 8. 102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cfg.threads = 1; 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(vpx_codec_get_caps(vpx_codec_vp8_dx()) & VPX_CODEC_CAP_POSTPROC); 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (vpx_codec_dec_init(&context_, 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vpx_codec_vp8_dx(), 107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &cfg, 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VPX_CODEC_USE_POSTPROC) != VPX_CODEC_OK) { 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ImplBase::cast_initialization_status_ = 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch STATUS_INVALID_VIDEO_CONFIGURATION; 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ImplBase::cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private: 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual ~Vp8Impl() { 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (ImplBase::cast_initialization_status_ == STATUS_VIDEO_INITIALIZED) 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CHECK_EQ(VPX_CODEC_OK, vpx_codec_destroy(&context_)); 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual scoped_refptr<VideoFrame> Decode(uint8* data, int len) OVERRIDE { 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (len <= 0 || vpx_codec_decode(&context_, 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch data, 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static_cast<unsigned int>(len), 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NULL, 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 0) != VPX_CODEC_OK) { 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vpx_codec_iter_t iter = NULL; 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vpx_image_t* const image = vpx_codec_get_frame(&context_, &iter); 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!image) 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (image->fmt != VPX_IMG_FMT_I420 && image->fmt != VPX_IMG_FMT_YV12) { 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(vpx_codec_get_frame(&context_, &iter) == NULL) 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << "Should have only decoded exactly one frame."; 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const gfx::Size frame_size(image->d_w, image->d_h); 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Note: Timestamp for the VideoFrame will be set in VideoReceiver. 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<VideoFrame> decoded_frame = 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VideoFrame::CreateFrame(VideoFrame::YV12, 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame_size, 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect(frame_size), 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame_size, 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta()); 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CopyYPlane(image->planes[VPX_PLANE_Y], 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch image->stride[VPX_PLANE_Y], 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch image->d_h, 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci decoded_frame.get()); 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CopyUPlane(image->planes[VPX_PLANE_U], 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch image->stride[VPX_PLANE_U], 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (image->d_h + 1) / 2, 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci decoded_frame.get()); 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CopyVPlane(image->planes[VPX_PLANE_V], 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch image->stride[VPX_PLANE_V], 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (image->d_h + 1) / 2, 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci decoded_frame.get()); 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return decoded_frame; 163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // VPX decoder context (i.e., an instantiation). 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vpx_codec_ctx_t context_; 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(Vp8Impl); 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#ifndef OFFICIAL_BUILD 1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// A fake video decoder that always output 2x2 black frames. 1730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass VideoDecoder::FakeImpl : public VideoDecoder::ImplBase { 1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public: 1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch explicit FakeImpl(const scoped_refptr<CastEnvironment>& cast_environment) 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : ImplBase(cast_environment, CODEC_VIDEO_FAKE), 1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch last_decoded_id_(-1) { 1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (ImplBase::cast_initialization_status_ != STATUS_VIDEO_UNINITIALIZED) 1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ImplBase::cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; 1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual ~FakeImpl() {} 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual scoped_refptr<VideoFrame> Decode(uint8* data, int len) OVERRIDE { 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Make sure this is a JSON string. 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!len || data[0] != '{') 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::JSONReader reader; 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<base::Value> values( 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reader.Read(base::StringPiece(reinterpret_cast<char*>(data), len))); 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!values) 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::DictionaryValue* dict = NULL; 1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch values->GetAsDictionary(&dict); 1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool key = false; 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int id = 0; 2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int ref = 0; 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dict->GetBoolean("key", &key); 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dict->GetInteger("id", &id); 2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dict->GetInteger("ref", &ref); 2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(id == last_decoded_id_ + 1); 2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch last_decoded_id_ = id; 2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2)); 2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int last_decoded_id_; 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(FakeImpl); 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochVideoDecoder::VideoDecoder( 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<CastEnvironment>& cast_environment, 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Codec codec) 218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : cast_environment_(cast_environment) { 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (codec) { 2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#ifndef OFFICIAL_BUILD 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case CODEC_VIDEO_FAKE: 2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch impl_ = new FakeImpl(cast_environment); 2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case CODEC_VIDEO_VP8: 226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch impl_ = new Vp8Impl(cast_environment); 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case CODEC_VIDEO_H264: 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(miu): Need implementation. 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NOTIMPLEMENTED(); 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch default: 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED() << "Unknown or unspecified codec."; 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)VideoDecoder::~VideoDecoder() {} 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochCastInitializationStatus VideoDecoder::InitializationResult() const { 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (impl_.get()) 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return impl_->InitializationResult(); 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return STATUS_UNSUPPORTED_VIDEO_CODEC; 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid VideoDecoder::DecodeFrame( 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<EncodedFrame> encoded_frame, 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DecodeFrameCallback& callback) { 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(encoded_frame.get()); 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(!callback.is_null()); 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!impl_.get() || 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci impl_->InitializationResult() != STATUS_VIDEO_INITIALIZED) { 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch callback.Run(make_scoped_refptr<VideoFrame>(NULL), false); 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cast_environment_->PostTask(CastEnvironment::VIDEO, 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FROM_HERE, 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&VideoDecoder::ImplBase::DecodeFrame, 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch impl_, 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Passed(&encoded_frame), 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch callback)); 26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace cast 26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace media 266