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)// This file contains an implementation of VideoDecoderAccelerator 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that utilizes hardware video decoder present on Intel CPUs. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <map> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <queue> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/linked_ptr.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/vaapi_h264_decoder.h" 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/gpu/media/vaapi_wrapper.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/bitstream_buffer.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/picture.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/video_decode_accelerator.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_bindings.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class to provide video decode acceleration for Intel systems with hardware 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// support for it, and on which libva is available. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decoding tasks are performed in a separate decoding thread. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Threading/life-cycle: this object is created & destroyed on the GPU 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ChildThread. A few methods on it are called on the decoder thread which is 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stopped during |this->Destroy()|, so any tasks posted to the decoder thread 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can assume |*this| is still alive. See |weak_this_| below for more details. 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class CONTENT_EXPORT VaapiVideoDecodeAccelerator 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : public media::VideoDecodeAccelerator { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VaapiVideoDecodeAccelerator( 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Display* x_display, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<bool(void)>& make_context_current); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VaapiVideoDecodeAccelerator(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // media::VideoDecodeAccelerator implementation. 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool Initialize(media::VideoCodecProfile profile, 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Client* client) OVERRIDE; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AssignPictureBuffers( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<media::PictureBuffer>& buffers) OVERRIDE; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Flush() OVERRIDE; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Reset() OVERRIDE; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Destroy() OVERRIDE; 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual bool CanDecodeOnIOThread() OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify the client that an error has occurred and decoding cannot continue. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyError(Error error); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map the received input buffer into this process' address space and 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // queue it for decode. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MapAndQueueNewInputBuffer( 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const media::BitstreamBuffer& bitstream_buffer); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get a new input buffer from the queue and set it up in decoder. This will 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sleep if no input buffers are available. Return true if a new buffer has 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // been set up, false if an early exit has been requested (due to initiated 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reset/flush/destroy). 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetInputBuffer_Locked(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Signal the client that the current buffer has been read and can be 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returned. Will also release the mapping. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReturnCurrInputBuffer_Locked(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Pass one or more output buffers to the decoder. This will sleep 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if no buffers are available. Return true if buffers have been set up or 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false if an early exit has been requested (due to initiated 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reset/flush/destroy). 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool FeedDecoderWithOutputSurfaces_Locked(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Continue decoding given input buffers and sleep waiting for input/output 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // as needed. Will exit if a new set of surfaces or reset/flush/destroy 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is requested. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecodeTask(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scheduled after receiving a flush request and executed after the current 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decoding task finishes decoding pending inputs. Makes the decoder return 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all remaining output pictures and puts it in an idle state, ready 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to resume if needed and schedules a FinishFlush. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FlushTask(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scheduled by the FlushTask after decoder is flushed to put VAVDA into idle 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // state and notify the client that flushing has been finished. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FinishFlush(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scheduled after receiving a reset request and executed after the current 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decoding task finishes decoding the current frame. Puts the decoder into 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an idle state, ready to resume if needed, discarding decoded but not yet 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // outputted pictures (decoder keeps ownership of their associated picture 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffers). Schedules a FinishReset afterwards. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetTask(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scheduled by ResetTask after it's done putting VAVDA into an idle state. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drops remaining input buffers and notifies the client that reset has been 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // finished. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FinishReset(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper for Destroy(), doing all the actual work except for deleting self. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Cleanup(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Get a usable framebuffer configuration for use in binding textures 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // or return false on failure. 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool InitializeFBConfig(); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback for the decoder to execute when it wants us to output given 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |va_surface|. 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SurfaceReady(int32 input_id, const scoped_refptr<VASurface>& va_surface); 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Represents a texture bound to an X Pixmap for output purposes. 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) class TFPPicture; 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback to be executed once we have a |va_surface| to be output and 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // an available |tfp_picture| to use for output. 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Puts contents of |va_surface| into given |tfp_picture|, releases the 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // surface and passes the resulting picture to client for output. 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void OutputPicture(const scoped_refptr<VASurface>& va_surface, 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int32 input_id, 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TFPPicture* tfp_picture); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Try to OutputPicture() if we have both a ready surface and picture. 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void TryOutputSurface(); 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Called when a VASurface is no longer in use by the decoder or is not being 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // synced/waiting to be synced to a picture. Returns it to available surfaces 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // pool. 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void RecycleVASurfaceID(VASurfaceID va_surface_id); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Initiate wait cycle for surfaces to be released before we release them 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // and allocate new ones, as requested by the decoder. 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Check if the surfaces have been released or post ourselves for later. 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void TryFinishSurfaceSetChange(); 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Client-provided X/GLX state. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Display* x_display_; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Callback<bool(void)> make_context_current_; 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GLXFBConfig fb_config_; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // VAVDA state. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize() not called yet or failed. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kUninitialized, 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // DecodeTask running. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDecoding, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resetting, waiting for decoder to finish current task and cleanup. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kResetting, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flushing, waiting for decoder to finish current task and cleanup. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFlushing, 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Idle, decoder in state ready to start/resume decoding. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIdle, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroying, waiting for the decoder to finish current task. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDestroying, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Protects input buffer and surface queues and state_. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock lock_; 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) State state_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An input buffer awaiting consumption, provided by the client. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct InputBuffer { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputBuffer(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~InputBuffer(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 id; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::SharedMemory> shm; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Queue for incoming input buffers. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::queue<linked_ptr<InputBuffer> > InputBuffers; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputBuffers input_buffers_; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Signalled when input buffers are queued onto the input_buffers_ queue. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ConditionVariable input_ready_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Current input buffer at decoder. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) linked_ptr<InputBuffer> curr_input_buffer_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Queue for incoming output buffers (texture ids). 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::queue<int32> OutputBuffers; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputBuffers output_buffers_; 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) typedef std::map<int32, linked_ptr<TFPPicture> > TFPPictures; 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // All allocated TFPPictures, regardless of their current state. TFPPictures 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // are allocated once and destroyed at the end of decode. 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TFPPictures tfp_pictures_; 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Return a TFPPicture associated with given client-provided id. 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TFPPicture* TFPPictureById(int32 picture_buffer_id); 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // VA Surfaces no longer in use that can be passed back to the decoder for 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // reuse, once it requests them. 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::list<VASurfaceID> available_va_surfaces_; 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Signalled when output surfaces are queued onto the available_va_surfaces_ 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // queue. 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::ConditionVariable surfaces_available_; 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Pending output requests from the decoder. When it indicates that we should 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // output a surface and we have an available TFPPicture (i.e. texture) ready 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // to use, we'll execute the callback passing the TFPPicture. The callback 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // will put the contents of the surface into the picture and return it to 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the client, releasing the surface as well. 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If we don't have any available TFPPictures at the time when the decoder 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // requests output, we'll store the request on pending_output_cbs_ queue for 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // later and run it once the client gives us more textures 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // via ReusePictureBuffer(). 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) typedef base::Callback<void(TFPPicture*)> OutputCB; 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::queue<OutputCB> pending_output_cbs_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChildThread's message loop 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop* message_loop_; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WeakPtr<> pointing to |this| for use in posting tasks from the decoder 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread back to the ChildThread. Because the decoder thread is a member of 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this class, any task running on the decoder thread is guaranteed that this 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object is still alive. As a result, tasks posted from ChildThread to 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decoder thread should use base::Unretained(this), and tasks posted from the 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decoder thread to the ChildThread should use |weak_this_|. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<VaapiVideoDecodeAccelerator> weak_this_; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Callback used when creating VASurface objects. 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VASurface::ReleaseCB va_surface_release_cb_; 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To expose client callbacks from VideoDecodeAccelerator. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: all calls to these objects *MUST* be executed on message_loop_. 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<Client> client_; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<VaapiWrapper> vaapi_wrapper_; 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Comes after vaapi_wrapper_ to ensure its destructor is executed before 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // vaapi_wrapper_ is destroyed. 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<VaapiH264Decoder> decoder_; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread decoder_thread_; 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use this to post tasks to |decoder_thread_| instead of 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |decoder_thread_.message_loop()| because the latter will be NULL once 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |decoder_thread_.Stop()| returns. 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_frames_at_client_; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_stream_bufs_at_decoder_; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Whether we are waiting for any pending_output_cbs_ to be run before 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // NotifyingFlushDone. 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool finish_flush_pending_; 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Decoder requested a new surface set and we are waiting for all the surfaces 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to be returned before we can free them. 2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool awaiting_va_surfaces_recycle_; 2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Last requested number/resolution of output picture buffers. 2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t requested_num_pics_; 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Size requested_pic_size_; 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The WeakPtrFactory for |weak_this_|. 272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; 273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ 280