Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This file contains an implementation of VideoDecoderAccelerator | 5 // This file contains an implementation of VideoDecoderAccelerator |
| 6 // that utilizes hardware video decoder present on Intel CPUs. | 6 // that utilizes hardware video decoder present on Intel CPUs. |
| 7 | 7 |
| 8 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ | 8 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ |
| 9 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ | 9 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ |
| 10 | 10 |
| 11 #include <list> | |
| 11 #include <map> | 12 #include <map> |
| 12 #include <queue> | 13 #include <queue> |
| 13 #include <utility> | 14 #include <utility> |
| 14 #include <vector> | 15 #include <vector> |
| 15 | 16 |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/memory/linked_ptr.h" | 18 #include "base/memory/linked_ptr.h" |
| 18 #include "base/memory/shared_memory.h" | 19 #include "base/memory/shared_memory.h" |
| 19 #include "base/memory/weak_ptr.h" | 20 #include "base/memory/weak_ptr.h" |
| 20 #include "base/message_loop/message_loop.h" | 21 #include "base/message_loop/message_loop.h" |
| 21 #include "base/synchronization/condition_variable.h" | 22 #include "base/synchronization/condition_variable.h" |
| 22 #include "base/synchronization/lock.h" | 23 #include "base/synchronization/lock.h" |
| 23 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
| 24 #include "content/common/content_export.h" | 25 #include "content/common/content_export.h" |
| 25 #include "content/common/gpu/media/vaapi_h264_decoder.h" | |
| 26 #include "content/common/gpu/media/vaapi_wrapper.h" | 26 #include "content/common/gpu/media/vaapi_wrapper.h" |
| 27 #include "media/base/bitstream_buffer.h" | 27 #include "media/base/bitstream_buffer.h" |
| 28 #include "media/video/picture.h" | 28 #include "media/video/picture.h" |
| 29 #include "media/video/video_decode_accelerator.h" | 29 #include "media/video/video_decode_accelerator.h" |
| 30 | 30 |
| 31 namespace gfx { | 31 namespace gfx { |
| 32 class GLImage; | 32 class GLImage; |
| 33 } | 33 } |
| 34 | 34 |
| 35 namespace content { | 35 namespace content { |
| 36 | 36 |
| 37 class AcceleratedVideoDecoder; | |
| 37 class VaapiPicture; | 38 class VaapiPicture; |
| 38 | 39 |
| 39 // Class to provide video decode acceleration for Intel systems with hardware | 40 // Class to provide video decode acceleration for Intel systems with hardware |
| 40 // support for it, and on which libva is available. | 41 // support for it, and on which libva is available. |
| 41 // Decoding tasks are performed in a separate decoding thread. | 42 // Decoding tasks are performed in a separate decoding thread. |
| 42 // | 43 // |
| 43 // Threading/life-cycle: this object is created & destroyed on the GPU | 44 // Threading/life-cycle: this object is created & destroyed on the GPU |
| 44 // ChildThread. A few methods on it are called on the decoder thread which is | 45 // ChildThread. A few methods on it are called on the decoder thread which is |
| 45 // stopped during |this->Destroy()|, so any tasks posted to the decoder thread | 46 // stopped during |this->Destroy()|, so any tasks posted to the decoder thread |
| 46 // can assume |*this| is still alive. See |weak_this_| below for more details. | 47 // can assume |*this| is still alive. See |weak_this_| below for more details. |
| 47 class CONTENT_EXPORT VaapiVideoDecodeAccelerator | 48 class CONTENT_EXPORT VaapiVideoDecodeAccelerator |
| 48 : public media::VideoDecodeAccelerator { | 49 : public media::VideoDecodeAccelerator { |
| 49 public: | 50 public: |
| 51 class VaapiDecodeSurface; | |
| 52 | |
| 50 VaapiVideoDecodeAccelerator( | 53 VaapiVideoDecodeAccelerator( |
| 51 const base::Callback<bool(void)>& make_context_current, | 54 const base::Callback<bool(void)>& make_context_current, |
| 52 const base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)>& | 55 const base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)>& |
| 53 bind_image); | 56 bind_image); |
| 54 ~VaapiVideoDecodeAccelerator() override; | 57 ~VaapiVideoDecodeAccelerator() override; |
| 55 | 58 |
| 56 // media::VideoDecodeAccelerator implementation. | 59 // media::VideoDecodeAccelerator implementation. |
| 57 bool Initialize(media::VideoCodecProfile profile, | 60 bool Initialize(media::VideoCodecProfile profile, Client* client) override; |
| 58 Client* client) override; | |
| 59 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; | 61 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; |
| 60 void AssignPictureBuffers( | 62 void AssignPictureBuffers( |
| 61 const std::vector<media::PictureBuffer>& buffers) override; | 63 const std::vector<media::PictureBuffer>& buffers) override; |
| 62 void ReusePictureBuffer(int32 picture_buffer_id) override; | 64 void ReusePictureBuffer(int32 picture_buffer_id) override; |
| 63 void Flush() override; | 65 void Flush() override; |
| 64 void Reset() override; | 66 void Reset() override; |
| 65 void Destroy() override; | 67 void Destroy() override; |
| 66 bool CanDecodeOnIOThread() override; | 68 bool CanDecodeOnIOThread() override; |
| 67 | 69 |
| 68 private: | 70 private: |
| 71 class VaapiH264Accelerator; | |
| 72 | |
| 69 // Notify the client that an error has occurred and decoding cannot continue. | 73 // Notify the client that an error has occurred and decoding cannot continue. |
| 70 void NotifyError(Error error); | 74 void NotifyError(Error error); |
| 71 | 75 |
| 72 // Map the received input buffer into this process' address space and | 76 // Map the received input buffer into this process' address space and |
| 73 // queue it for decode. | 77 // queue it for decode. |
| 74 void MapAndQueueNewInputBuffer( | 78 void MapAndQueueNewInputBuffer( |
| 75 const media::BitstreamBuffer& bitstream_buffer); | 79 const media::BitstreamBuffer& bitstream_buffer); |
| 76 | 80 |
| 77 // Get a new input buffer from the queue and set it up in decoder. This will | 81 // Get a new input buffer from the queue and set it up in decoder. This will |
| 78 // sleep if no input buffers are available. Return true if a new buffer has | 82 // sleep if no input buffers are available. Return true if a new buffer has |
| 79 // been set up, false if an early exit has been requested (due to initiated | 83 // been set up, false if an early exit has been requested (due to initiated |
| 80 // reset/flush/destroy). | 84 // reset/flush/destroy). |
| 81 bool GetInputBuffer_Locked(); | 85 bool GetInputBuffer_Locked(); |
| 82 | 86 |
| 83 // Signal the client that the current buffer has been read and can be | 87 // Signal the client that the current buffer has been read and can be |
| 84 // returned. Will also release the mapping. | 88 // returned. Will also release the mapping. |
| 85 void ReturnCurrInputBuffer_Locked(); | 89 void ReturnCurrInputBuffer_Locked(); |
| 86 | 90 |
| 87 // Pass one or more output buffers to the decoder. This will sleep | 91 // Wait for more surfaces to become available. Return true once they do or |
| 88 // if no buffers are available. Return true if buffers have been set up or | 92 // false if an early exit has been requested (due to an initiated |
| 89 // false if an early exit has been requested (due to initiated | |
| 90 // reset/flush/destroy). | 93 // reset/flush/destroy). |
| 91 bool FeedDecoderWithOutputSurfaces_Locked(); | 94 // TODO(posciak): refactor the whole class to remove sleeping in wait for |
| 95 // surfaces, and reschedule DecodeTask instead. | |
| 96 bool WaitForSurfaces_Locked(); | |
| 92 | 97 |
| 93 // Continue decoding given input buffers and sleep waiting for input/output | 98 // Continue decoding given input buffers and sleep waiting for input/output |
| 94 // as needed. Will exit if a new set of surfaces or reset/flush/destroy | 99 // as needed. Will exit if a new set of surfaces or reset/flush/destroy |
| 95 // is requested. | 100 // is requested. |
| 96 void DecodeTask(); | 101 void DecodeTask(); |
| 97 | 102 |
| 98 // Scheduled after receiving a flush request and executed after the current | 103 // Scheduled after receiving a flush request and executed after the current |
| 99 // decoding task finishes decoding pending inputs. Makes the decoder return | 104 // decoding task finishes decoding pending inputs. Makes the decoder return |
| 100 // all remaining output pictures and puts it in an idle state, ready | 105 // all remaining output pictures and puts it in an idle state, ready |
| 101 // to resume if needed and schedules a FinishFlush. | 106 // to resume if needed and schedules a FinishFlush. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 117 // finished. | 122 // finished. |
| 118 void FinishReset(); | 123 void FinishReset(); |
| 119 | 124 |
| 120 // Helper for Destroy(), doing all the actual work except for deleting self. | 125 // Helper for Destroy(), doing all the actual work except for deleting self. |
| 121 void Cleanup(); | 126 void Cleanup(); |
| 122 | 127 |
| 123 // Get a usable framebuffer configuration for use in binding textures | 128 // Get a usable framebuffer configuration for use in binding textures |
| 124 // or return false on failure. | 129 // or return false on failure. |
| 125 bool InitializeFBConfig(); | 130 bool InitializeFBConfig(); |
| 126 | 131 |
| 127 // Callback for the decoder to execute when it wants us to output given | |
| 128 // |va_surface|. | |
| 129 void SurfaceReady(int32 input_id, const scoped_refptr<VASurface>& va_surface); | |
| 130 | |
| 131 // Callback to be executed once we have a |va_surface| to be output and | 132 // Callback to be executed once we have a |va_surface| to be output and |
| 132 // an available |picture| to use for output. | 133 // an available |picture| to use for output. |
| 133 // Puts contents of |va_surface| into given |picture|, releases the | 134 // Puts contents of |va_surface| into given |picture|, releases the |
| 134 // surface and passes the resulting picture to client for output. | 135 // surface and passes the resulting picture to client for output. |
| 135 void OutputPicture(const scoped_refptr<VASurface>& va_surface, | 136 void OutputPicture(const scoped_refptr<VASurface>& va_surface, |
| 136 int32 input_id, | 137 int32 input_id, |
| 137 VaapiPicture* picture); | 138 VaapiPicture* picture); |
| 138 | 139 |
| 139 // Try to OutputPicture() if we have both a ready surface and picture. | 140 // Try to OutputPicture() if we have both a ready surface and picture. |
| 140 void TryOutputSurface(); | 141 void TryOutputSurface(); |
| 141 | 142 |
| 142 // Called when a VASurface is no longer in use by the decoder or is not being | 143 // Called when a VASurface is no longer in use by the decoder or is not being |
| 143 // synced/waiting to be synced to a picture. Returns it to available surfaces | 144 // synced/waiting to be synced to a picture. Returns it to available surfaces |
| 144 // pool. | 145 // pool. |
| 145 void RecycleVASurfaceID(VASurfaceID va_surface_id); | 146 void RecycleVASurfaceID(VASurfaceID va_surface_id); |
| 146 | 147 |
| 147 // Initiate wait cycle for surfaces to be released before we release them | 148 // Initiate wait cycle for surfaces to be released before we release them |
| 148 // and allocate new ones, as requested by the decoder. | 149 // and allocate new ones, as requested by the decoder. |
| 149 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); | 150 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); |
| 151 | |
| 150 // Check if the surfaces have been released or post ourselves for later. | 152 // Check if the surfaces have been released or post ourselves for later. |
| 151 void TryFinishSurfaceSetChange(); | 153 void TryFinishSurfaceSetChange(); |
| 152 | 154 |
| 155 // | |
| 156 // Below methods are used by accelerator implementations. | |
| 157 // | |
| 158 // Decode of |dec_surface| is ready to be submitted and all codec-specific | |
| 159 // settings are set in hardware. | |
| 160 bool DecodeSurface(const scoped_refptr<VaapiDecodeSurface>& dec_surface); | |
| 161 | |
| 162 // |dec_surface| is ready to be outputted once decode is finished. | |
| 163 // This can be called before decode is actually done in hardware, and this | |
| 164 // method is responsible for maintaining the ordering, i.e. the surfaces have | |
| 165 // to be outputted in the same order as SurfaceReady is called. | |
| 166 // On Intel, we don't have to explicitly maintain the ordering however, as the | |
| 167 // driver will maintain ordering, as well as dependencies, and will process | |
| 168 // each submitted command in order, and run each command only if its | |
| 169 // dependencies are ready. | |
| 170 void SurfaceReady(const scoped_refptr<VaapiDecodeSurface>& dec_surface); | |
| 171 | |
| 172 // Return a new VaapiDecodeSurface for decoding into, or nullptr if not | |
| 173 // available. | |
| 174 scoped_refptr<VaapiDecodeSurface> CreateSurface(); | |
| 175 | |
| 176 | |
|
kcwu
2015/03/31 15:20:09
two blank line
Pawel Osciak
2015/04/03 07:06:00
This was intentional to make a clear delineation b
| |
| 153 // Client-provided GL state. | 177 // Client-provided GL state. |
| 154 base::Callback<bool(void)> make_context_current_; | 178 base::Callback<bool(void)> make_context_current_; |
| 155 | 179 |
| 156 // VAVDA state. | 180 // VAVDA state. |
| 157 enum State { | 181 enum State { |
| 158 // Initialize() not called yet or failed. | 182 // Initialize() not called yet or failed. |
| 159 kUninitialized, | 183 kUninitialized, |
| 160 // DecodeTask running. | 184 // DecodeTask running. |
| 161 kDecoding, | 185 kDecoding, |
| 162 // Resetting, waiting for decoder to finish current task and cleanup. | 186 // Resetting, waiting for decoder to finish current task and cleanup. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 // Callback used when creating VASurface objects. | 265 // Callback used when creating VASurface objects. |
| 242 VASurface::ReleaseCB va_surface_release_cb_; | 266 VASurface::ReleaseCB va_surface_release_cb_; |
| 243 | 267 |
| 244 // To expose client callbacks from VideoDecodeAccelerator. | 268 // To expose client callbacks from VideoDecodeAccelerator. |
| 245 // NOTE: all calls to these objects *MUST* be executed on message_loop_. | 269 // NOTE: all calls to these objects *MUST* be executed on message_loop_. |
| 246 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; | 270 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; |
| 247 base::WeakPtr<Client> client_; | 271 base::WeakPtr<Client> client_; |
| 248 | 272 |
| 249 // Comes after vaapi_wrapper_ to ensure its destructor is executed before | 273 // Comes after vaapi_wrapper_ to ensure its destructor is executed before |
| 250 // vaapi_wrapper_ is destroyed. | 274 // vaapi_wrapper_ is destroyed. |
| 251 scoped_ptr<VaapiH264Decoder> decoder_; | 275 scoped_ptr<VaapiH264Accelerator> h264_accelerator_; |
| 276 // After h264_accelerator_ to ensure correct destruction order. | |
| 277 scoped_ptr<AcceleratedVideoDecoder> decoder_; | |
| 278 | |
| 252 base::Thread decoder_thread_; | 279 base::Thread decoder_thread_; |
| 253 // Use this to post tasks to |decoder_thread_| instead of | 280 // Use this to post tasks to |decoder_thread_| instead of |
| 254 // |decoder_thread_.message_loop()| because the latter will be NULL once | 281 // |decoder_thread_.message_loop()| because the latter will be NULL once |
| 255 // |decoder_thread_.Stop()| returns. | 282 // |decoder_thread_.Stop()| returns. |
| 256 scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_; | 283 scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_; |
| 257 | 284 |
| 258 int num_frames_at_client_; | 285 int num_frames_at_client_; |
| 259 int num_stream_bufs_at_decoder_; | 286 int num_stream_bufs_at_decoder_; |
| 260 | 287 |
| 261 // Whether we are waiting for any pending_output_cbs_ to be run before | 288 // Whether we are waiting for any pending_output_cbs_ to be run before |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 276 | 303 |
| 277 // The WeakPtrFactory for |weak_this_|. | 304 // The WeakPtrFactory for |weak_this_|. |
| 278 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; | 305 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; |
| 279 | 306 |
| 280 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator); | 307 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator); |
| 281 }; | 308 }; |
| 282 | 309 |
| 283 } // namespace content | 310 } // namespace content |
| 284 | 311 |
| 285 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ | 312 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ |
| OLD | NEW |