15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/gpu_video_decoder.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <algorithm> 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/cpu.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/task_runner_util.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox_holder.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/bind_to_current_loop.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decoder_buffer.h" 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/base/media_log.h" 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "media/base/media_switches.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/pipeline.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/pipeline_status.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_decoder_config.h" 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/filters/gpu_video_accelerator_factories.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum number of concurrent VDA::Decode() operations GVD will maintain. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Higher values allow better pipelining in the GPU, but also require more 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resources. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { kMaxInFlightDecodes = 4 }; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size of shared-memory segments we allocate. Since we reuse them we let them 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be on the beefy side. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kSharedMemorySegmentBytes = 100 << 10; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::SHMBuffer::SHMBuffer(base::SharedMemory* m, size_t s) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : shm(m), size(s) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GpuVideoDecoder::PendingDecoderBuffer::PendingDecoderBuffer( 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SHMBuffer* s, 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& b, 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DecodeCB& done_cb) 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : shm_buffer(s), buffer(b), done_cb(done_cb) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GpuVideoDecoder::PendingDecoderBuffer::~PendingDecoderBuffer() {} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::BufferData::BufferData( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) natural_size(ns) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::BufferData::~BufferData() {} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::GpuVideoDecoder( 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const scoped_refptr<GpuVideoAcceleratorFactories>& factories, 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const scoped_refptr<MediaLog>& media_log) 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : needs_bitstream_conversion_(false), 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factories_(factories), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(kNormal), 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media_log_(media_log), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_texture_target_(0), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_picture_buffer_id_(0), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_bitstream_buffer_id_(0), 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) available_pictures_(0), 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_factory_(this) { 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(factories_.get()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::Reset(const base::Closure& closure) { 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "Reset()"; 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (state_ == kDrainingDecoder) { 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind( 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &GpuVideoDecoder::Reset, weak_factory_.GetWeakPtr(), closure)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!vda_) { 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, closure); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(pending_reset_cb_.is_null()); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_reset_cb_ = BindToCurrentLoop(closure); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch vda_->Reset(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid GpuVideoDecoder::Stop() { 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (vda_) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DestroyVDA(); 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(bitstream_buffers_in_decoder_.empty()); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!pending_reset_cb_.is_null()) 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ResetAndReturn(&pending_reset_cb_).Run(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static bool IsCodedSizeSupported(const gfx::Size& coded_size) { 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Windows Media Foundation H.264 decoding does not support decoding videos 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // with any dimension smaller than 48 pixels: 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (coded_size.width() < 48 || coded_size.height() < 48) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We test against 1088 to account for 16x16 macroblocks. 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (coded_size.width() <= 1920 && coded_size.height() <= 1088) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // NOTE: additional autodetection logic may require updating input buffer size 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // selection in platform-specific implementations, such as 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // V4L2VideoDecodeAccelerator. 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::CPU cpu; 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool hw_large_video_support = 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch( 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode) || 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ((cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 55); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool os_large_video_support = true; 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) os_large_video_support = false; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return os_large_video_support && hw_large_video_support; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Report |status| to UMA and run |cb| with it. This is super-specific to the 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// callsite to always be called with the same stat name (can't parameterize it). 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PipelineStatusCB& cb, 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PipelineStatus status) { 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cb.Run(status); 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, 1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool /* low_delay */, 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const PipelineStatusCB& orig_status_cb, 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const OutputCB& output_cb) { 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "Initialize()"; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(config.IsValidConfig()); 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!config.is_encrypted()); 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PipelineStatusCB status_cb = 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BindToCurrentLoop(orig_status_cb)); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool previously_initialized = config_.IsValidConfig(); 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DVLOG(1) << "(Re)initializing GVD with config: " 165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << config.AsHumanReadableString(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // TODO(posciak): destroy and create a new VDA on codec/profile change 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // (http://crbug.com/260224). 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (previously_initialized && (config_.profile() != config.profile())) { 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DVLOG(1) << "Codec or profile changed, cannot reinitialize."; 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!IsCodedSizeSupported(config.coded_size())) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch config_ = config; 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) needs_bitstream_conversion_ = (config.codec() == kCodecH264); 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) output_cb_ = BindToCurrentLoop(output_cb); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (previously_initialized) { 185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Reinitialization with a different config (but same codec and profile). 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // VDA should handle it by detecting this in-stream by itself, 187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // no need to notify it. 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status_cb.Run(PIPELINE_OK); 189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!vda_ || !vda_->Initialize(config.profile(), this)) { 194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media_log_->SetStringProperty("video_decoder", "gpu"); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status_cb.Run(PIPELINE_OK); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++it) { 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) factories_->DeleteTexture(it->second.texture_id()); 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffers->clear(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::DestroyVDA() { 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) vda_.reset(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // their textures may still be in use by the user of this GpuVideoDecoder. 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (PictureBufferTextureMap::iterator it = 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) picture_buffers_at_display_.begin(); 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) it != picture_buffers_at_display_.end(); 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ++it) { 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) assigned_picture_buffers_.erase(it->first); 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 22623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DestroyPictureBuffers(&assigned_picture_buffers_); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const DecodeCB& decode_cb) { 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(pending_reset_cb_.is_null()); 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state_ == kError || !vda_) { 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bound_decode_cb.Run(kDecodeError); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kDecoderDrained: 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kNormal; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall-through. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kNormal: 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kDrainingDecoder: 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case kError: 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK_EQ(state_, kNormal); 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (buffer->end_of_stream()) { 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) state_ = kDrainingDecoder; 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) eos_decode_cb_ = bound_decode_cb; 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) vda_->Flush(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch size_t size = buffer->data_size(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHMBuffer* shm_buffer = GetSHM(size); 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!shm_buffer) { 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bound_decode_cb.Run(kDecodeError); 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch memcpy(shm_buffer->shm->memory(), buffer->data(), size); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitstreamBuffer bitstream_buffer( 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ContainsKey(bitstream_buffers_in_decoder_, bitstream_buffer.id())); 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bitstream_buffers_in_decoder_.insert( 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::make_pair(bitstream_buffer.id(), 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PendingDecoderBuffer(shm_buffer, buffer, decode_cb))); 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK_LE(static_cast<int>(bitstream_buffers_in_decoder_.size()), 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kMaxInFlightDecodes); 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordBufferData(bitstream_buffer, *buffer.get()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch vda_->Decode(bitstream_buffer); 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer, 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const DecoderBuffer& buffer) { 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch input_buffer_data_.push_front(BufferData(bitstream_buffer.id(), 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer.timestamp(), 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch config_.visible_rect(), 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch config_.natural_size())); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that's too small for some pathological B-frame test videos. The cost of 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // using too-high a value is low (192 bits per extra slot). 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kMaxInputBufferDataSize = 128; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pop from the back of the list, because that's the oldest and least likely 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be useful in the future data. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_buffer_data_.size() > kMaxInputBufferDataSize) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_data_.pop_back(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect* visible_rect, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size* natural_size) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::list<BufferData>::const_iterator it = 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_data_.begin(); it != input_buffer_data_.end(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->bitstream_buffer_id != id) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *timestamp = it->timestamp; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *visible_rect = it->visible_rect; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *natural_size = it->natural_size; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Missing bitstreambuffer id: " << id; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool GpuVideoDecoder::NeedsBitstreamConversion() const { 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return needs_bitstream_conversion_; 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool GpuVideoDecoder::CanReadWithoutStalling() const { 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) available_pictures_ > 0; 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int GpuVideoDecoder::GetMaxDecodeRequests() const { 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return kMaxInFlightDecodes; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 texture_target) { 3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "ProvidePictureBuffers(" << count << ", " 3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << size.width() << "x" << size.height() << ")"; 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint32> texture_ids; 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<gpu::Mailbox> texture_mailboxes; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_texture_target_ = texture_target; 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!factories_->CreateTextures(count, 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size, 345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &texture_ids, 346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &texture_mailboxes, 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch decoder_texture_target_)) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(count, texture_ids.size()); 352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(count, texture_mailboxes.size()); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!vda_) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PictureBuffer> picture_buffers; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < texture_ids.size(); ++i) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers.push_back(PictureBuffer( 360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool inserted = assigned_picture_buffers_.insert(std::make_pair( 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers.back().id(), picture_buffers.back())).second; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(inserted); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) available_pictures_ += count; 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 368bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch vda_->AssignPictureBuffers(picture_buffers); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "DismissPictureBuffer(" << id << ")"; 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it == assigned_picture_buffers_.end()) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Missing picture buffer: " << id; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PictureBuffer buffer_to_dismiss = it->second; 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) assigned_picture_buffers_.erase(it); 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 38423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!picture_buffers_at_display_.count(id)) { 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We can delete the texture immediately as it's not being displayed. 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) factories_->DeleteTexture(buffer_to_dismiss.texture_id()); 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK_GT(available_pictures_, 0); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) --available_pictures_; 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Not destroying a texture in display in |picture_buffers_at_display_|. 39123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Postpone deletion until after it's returned to us. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void ReadPixelsSyncInner( 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 texture_id, 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& visible_rect, 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SkBitmap& pixels, 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WaitableEvent* event) { 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories->ReadPixels(texture_id, visible_rect, pixels); 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event->Signal(); 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void ReadPixelsSync( 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 texture_id, 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& visible_rect, 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SkBitmap& pixels) { 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WaitableEvent event(true, false); 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!factories->GetTaskRunner()->PostTask(FROM_HERE, 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ReadPixelsSyncInner, 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories, 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) texture_id, 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visible_rect, 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixels, 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &event))) 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event.Wait(); 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::PictureReady(const media::Picture& picture) { 4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "PictureReady()"; 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PictureBufferMap::iterator it = 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) assigned_picture_buffers_.find(picture.picture_buffer_id()); 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it == assigned_picture_buffers_.end()) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PictureBuffer& pb = it->second; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update frame's timestamp. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect visible_rect; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size natural_size; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &natural_size); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(decoder_texture_target_); 441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 442a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) make_scoped_ptr(new gpu::MailboxHolder( 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pb.texture_mailbox(), decoder_texture_target_, 0 /* sync_point */)), 44523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) BindToCurrentLoop(base::Bind(&GpuVideoDecoder::ReleaseMailbox, 44623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_factory_.GetWeakPtr(), 44723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) factories_, 44823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) picture.picture_buffer_id(), 44923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pb.texture_id())), 450a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch pb.size(), 451a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch visible_rect, 452a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch natural_size, 453a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch timestamp, 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect))); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GT(available_pictures_, 0); 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) --available_pictures_; 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool inserted = 45823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) picture_buffers_at_display_.insert(std::make_pair( 45923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) picture.picture_buffer_id(), 46023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pb.texture_id())).second; 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(inserted); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DeliverFrame(frame); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GpuVideoDecoder::DeliverFrame( 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<VideoFrame>& frame) { 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // floor and return. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_reset_cb_.is_null()) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) output_cb_.Run(frame); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// static 47923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void GpuVideoDecoder::ReleaseMailbox( 48023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::WeakPtr<GpuVideoDecoder> decoder, 48123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 picture_buffer_id, 48323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) uint32 texture_id, 4845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::vector<uint32>& release_sync_points) { 48523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); 4865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (size_t i = 0; i < release_sync_points.size(); i++) 4885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu factories->WaitSyncPoint(release_sync_points[i]); 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 49023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (decoder) { 49123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) decoder->ReusePictureBuffer(picture_buffer_id); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 49323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 49423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // It's the last chance to delete the texture after display, 49523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // because GpuVideoDecoder was destructed. 49623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) factories->DeleteTexture(texture_id); 49723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 49923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 50023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; 50123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 50323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!picture_buffers_at_display_.empty()); 50423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PictureBufferTextureMap::iterator display_iterator = 50523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) picture_buffers_at_display_.find(picture_buffer_id); 50623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) uint32 texture_id = display_iterator->second; 50723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(display_iterator != picture_buffers_at_display_.end()); 50823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) picture_buffers_at_display_.erase(display_iterator); 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 51023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!assigned_picture_buffers_.count(picture_buffer_id)) { 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This picture was dismissed while in display, so we postponed deletion. 51223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) factories_->DeleteTexture(texture_id); 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++available_pictures_; 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 51823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // DestroyVDA() might already have been called. 51923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (vda_) 52023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) vda_->ReusePictureBuffer(picture_buffer_id); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (available_shm_segments_.empty() || 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) available_shm_segments_.back()->size < min_size) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CreateSharedMemory() can return NULL during Shutdown. 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!shm) 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SHMBuffer(shm, size_to_allocate); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHMBuffer* ret = available_shm_segments_.back(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) available_shm_segments_.pop_back(); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) { 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) available_shm_segments_.push_back(shm_buffer); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")"; 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 548f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::map<int32, PendingDecoderBuffer>::iterator it = 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_in_decoder_.find(id); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == bitstream_buffers_in_decoder_.end()) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Missing bitstream buffer: " << id; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PutSHM(it->second.shm_buffer); 557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it->second.done_cb.Run(state_ == kError ? kDecodeError : kOk); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_in_decoder_.erase(it); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecoder::~GpuVideoDecoder() { 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 56323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Stop should have been already called. 56423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!vda_.get() && assigned_picture_buffers_.empty()); 565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(bitstream_buffers_in_decoder_.empty()); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) available_shm_segments_[i]->shm->Close(); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete available_shm_segments_[i]; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) available_shm_segments_.clear(); 571f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (std::map<int32, PendingDecoderBuffer>::iterator it = 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_in_decoder_.begin(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != bitstream_buffers_in_decoder_.end(); ++it) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second.shm_buffer->shm->Close(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitstream_buffers_in_decoder_.clear(); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::NotifyFlushDone() { 5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "NotifyFlushDone()"; 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, kDrainingDecoder); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kDecoderDrained; 584f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::ResetAndReturn(&eos_decode_cb_).Run(kOk); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::NotifyResetDone() { 5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DVLOG(3) << "NotifyResetDone()"; 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 590f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(bitstream_buffers_in_decoder_.empty()); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This needs to happen after the Reset() on vda_ is done to ensure pictures 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delivered during the reset can find their time data. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_data_.clear(); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_reset_cb_.is_null()) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ResetAndReturn(&pending_reset_cb_).Run(); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!vda_) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_ = kError; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DLOG(ERROR) << "VDA Error: " << error; 608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DestroyVDA(); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const { 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 617