| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #ifndef MEDIA_GPU_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ | 5 #ifndef MEDIA_GPU_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ |
| 6 #define MEDIA_GPU_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ | 6 #define MEDIA_GPU_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <list> | 10 #include <list> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <queue> | 12 #include <queue> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/optional.h" | 16 #include "base/optional.h" |
| 17 #include "base/threading/thread_checker.h" | 17 #include "base/threading/thread_checker.h" |
| 18 #include "base/timer/timer.h" | 18 #include "base/timer/timer.h" |
| 19 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 19 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 20 #include "gpu/command_buffer/service/gpu_preferences.h" | 20 #include "gpu/command_buffer/service/gpu_preferences.h" |
| 21 #include "media/base/android/media_drm_bridge_cdm_context.h" | 21 #include "media/base/android/media_drm_bridge_cdm_context.h" |
| 22 #include "media/base/android/sdk_media_codec_bridge.h" | 22 #include "media/base/android/sdk_media_codec_bridge.h" |
| 23 #include "media/base/media_keys.h" | 23 #include "media/base/media_keys.h" |
| 24 #include "media/gpu/avda_codec_allocator.h" | 24 #include "media/gpu/avda_codec_allocator.h" |
| 25 #include "media/gpu/avda_picture_buffer_manager.h" | 25 #include "media/gpu/avda_picture_buffer_manager.h" |
| 26 #include "media/gpu/avda_state_provider.h" | 26 #include "media/gpu/avda_state_provider.h" |
| 27 #include "media/gpu/avda_surface_tracker.h" | |
| 28 #include "media/gpu/gpu_video_decode_accelerator_helpers.h" | 27 #include "media/gpu/gpu_video_decode_accelerator_helpers.h" |
| 29 #include "media/gpu/media_gpu_export.h" | 28 #include "media/gpu/media_gpu_export.h" |
| 30 #include "media/video/video_decode_accelerator.h" | 29 #include "media/video/video_decode_accelerator.h" |
| 31 #include "ui/gl/android/scoped_java_surface.h" | 30 #include "ui/gl/android/scoped_java_surface.h" |
| 32 | 31 |
| 33 namespace gl { | |
| 34 class SurfaceTexture; | |
| 35 } | |
| 36 | |
| 37 namespace media { | 32 namespace media { |
| 38 class SharedMemoryRegion; | 33 class SharedMemoryRegion; |
| 39 | 34 |
| 40 // A VideoDecodeAccelerator implementation for Android. This class decodes the | 35 // A VideoDecodeAccelerator implementation for Android. This class decodes the |
| 41 // encded input stream using Android's MediaCodec. It handles the work of | 36 // encded input stream using Android's MediaCodec. It handles the work of |
| 42 // transferring data to and from MediaCodec, and delegates attaching MediaCodec | 37 // transferring data to and from MediaCodec, and delegates attaching MediaCodec |
| 43 // output buffers to PictureBuffers to AVDAPictureBufferManager. | 38 // output buffers to PictureBuffers to AVDAPictureBufferManager. |
| 44 class MEDIA_GPU_EXPORT AndroidVideoDecodeAccelerator | 39 class MEDIA_GPU_EXPORT AndroidVideoDecodeAccelerator |
| 45 : public VideoDecodeAccelerator, | 40 : public VideoDecodeAccelerator, |
| 46 public AVDAStateProvider { | 41 public AVDAStateProvider, |
| 42 public AVDACodecAllocatorClient { |
| 47 public: | 43 public: |
| 48 static VideoDecodeAccelerator::Capabilities GetCapabilities( | 44 static VideoDecodeAccelerator::Capabilities GetCapabilities( |
| 49 const gpu::GpuPreferences& gpu_preferences); | 45 const gpu::GpuPreferences& gpu_preferences); |
| 50 | 46 |
| 51 AndroidVideoDecodeAccelerator( | 47 AndroidVideoDecodeAccelerator( |
| 52 const MakeGLContextCurrentCallback& make_context_current_cb, | 48 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 53 const GetGLES2DecoderCallback& get_gles2_decoder_cb); | 49 const GetGLES2DecoderCallback& get_gles2_decoder_cb); |
| 54 | 50 |
| 55 ~AndroidVideoDecodeAccelerator() override; | 51 ~AndroidVideoDecodeAccelerator() override; |
| 56 | 52 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 67 const base::WeakPtr<Client>& decode_client, | 63 const base::WeakPtr<Client>& decode_client, |
| 68 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) | 64 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) |
| 69 override; | 65 override; |
| 70 | 66 |
| 71 // AVDAStateProvider implementation: | 67 // AVDAStateProvider implementation: |
| 72 const gfx::Size& GetSize() const override; | 68 const gfx::Size& GetSize() const override; |
| 73 base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const override; | 69 base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const override; |
| 74 // Notifies the client about the error and sets |state_| to |ERROR|. | 70 // Notifies the client about the error and sets |state_| to |ERROR|. |
| 75 void NotifyError(Error error) override; | 71 void NotifyError(Error error) override; |
| 76 | 72 |
| 73 // AVDACodecAllocatorClient implementation: |
| 74 void OnSurfaceAvailable(bool success) override; |
| 75 void OnSurfaceDestroyed() override; |
| 76 void OnCodecConfigured( |
| 77 std::unique_ptr<VideoCodecBridge> media_codec) override; |
| 78 |
| 77 private: | 79 private: |
| 78 friend class AVDAManager; | 80 friend class AVDAManager; |
| 79 | 81 |
| 80 // TODO(timav): evaluate the need for more states in the AVDA state machine. | 82 // TODO(timav): evaluate the need for more states in the AVDA state machine. |
| 81 enum State { | 83 enum State { |
| 82 NO_ERROR, | 84 NO_ERROR, |
| 83 ERROR, | 85 ERROR, |
| 84 // Set when we are asynchronously constructing the codec. Will transition | 86 // Set when we are asynchronously constructing the codec. Will transition |
| 85 // to NO_ERROR or ERROR depending on success. | 87 // to NO_ERROR or ERROR depending on success. |
| 86 WAITING_FOR_CODEC, | 88 WAITING_FOR_CODEC, |
| 87 // Set when we have a codec, but it doesn't yet have a key. | 89 // Set when we have a codec, but it doesn't yet have a key. |
| 88 WAITING_FOR_KEY, | 90 WAITING_FOR_KEY, |
| 89 // The output surface was destroyed. We must not configure a new MediaCodec | 91 // The output surface was destroyed. We must not configure a new MediaCodec |
| 90 // with the destroyed surface. | 92 // with the destroyed surface. |
| 91 SURFACE_DESTROYED, | 93 SURFACE_DESTROYED, |
| 92 }; | 94 }; |
| 93 | 95 |
| 94 enum DrainType { | 96 enum DrainType { |
| 95 DRAIN_TYPE_NONE, | 97 DRAIN_TYPE_NONE, |
| 96 DRAIN_FOR_FLUSH, | 98 DRAIN_FOR_FLUSH, |
| 97 DRAIN_FOR_RESET, | 99 DRAIN_FOR_RESET, |
| 98 DRAIN_FOR_DESTROY, | 100 DRAIN_FOR_DESTROY, |
| 99 }; | 101 }; |
| 100 | 102 |
| 101 // Configuration info for MediaCodec. | |
| 102 // This is used to shuttle configuration info between threads without needing | |
| 103 // to worry about the lifetime of the AVDA instance. All of these should not | |
| 104 // be modified while |state_| is WAITING_FOR_CODEC. | |
| 105 class CodecConfig : public base::RefCountedThreadSafe<CodecConfig> { | |
| 106 public: | |
| 107 CodecConfig(); | |
| 108 | |
| 109 // Codec type. Used when we configure media codec. | |
| 110 VideoCodec codec_ = kUnknownVideoCodec; | |
| 111 | |
| 112 // Whether encryption scheme requires to use protected surface. | |
| 113 bool needs_protected_surface_ = false; | |
| 114 | |
| 115 // The surface that MediaCodec is configured to output to. | |
| 116 gl::ScopedJavaSurface surface_; | |
| 117 | |
| 118 // The MediaCrypto object is used in the MediaCodec.configure() in case of | |
| 119 // an encrypted stream. | |
| 120 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto_; | |
| 121 | |
| 122 // Initial coded size. The actual size might change at any time, so this | |
| 123 // is only a hint. | |
| 124 gfx::Size initial_expected_coded_size_; | |
| 125 | |
| 126 // The type of allocation to use for this. We use this to select the right | |
| 127 // thread for construction / destruction, and to decide if we should | |
| 128 // restrict the codec to be software only. | |
| 129 AVDACodecAllocator::TaskType task_type_; | |
| 130 | |
| 131 // Codec specific data (SPS and PPS for H264). | |
| 132 std::vector<uint8_t> csd0_; | |
| 133 std::vector<uint8_t> csd1_; | |
| 134 | |
| 135 protected: | |
| 136 friend class base::RefCountedThreadSafe<CodecConfig>; | |
| 137 virtual ~CodecConfig(); | |
| 138 | |
| 139 private: | |
| 140 DISALLOW_COPY_AND_ASSIGN(CodecConfig); | |
| 141 }; | |
| 142 | |
| 143 // Callback that is called when the SurfaceView becomes available, if it's | |
| 144 // not during Initialize. |success| is true if it is now available, false | |
| 145 // if initialization should stop. | |
| 146 void OnSurfaceAvailable(bool success); | |
| 147 | |
| 148 // Initialize of the picture buffer manager. This is to be called when the | 103 // Initialize of the picture buffer manager. This is to be called when the |
| 149 // SurfaceView in |surface_id_|, if any, is no longer busy. It will return | 104 // SurfaceView in |surface_id_|, if any, is no longer busy. It will return |
| 150 // false on failure, and true if initialization was successful. This includes | 105 // false on failure, and true if initialization was successful. This includes |
| 151 // synchronous and asynchronous init; the AVDA might not yet have a codec on | 106 // synchronous and asynchronous init; the AVDA might not yet have a codec on |
| 152 // success, but async init will at least be in progress. | 107 // success, but async init will at least be in progress. |
| 153 bool InitializePictureBufferManager(); | 108 bool InitializePictureBufferManager(); |
| 154 | 109 |
| 155 // A part of destruction process that is sometimes postponed after the drain. | 110 // A part of destruction process that is sometimes postponed after the drain. |
| 156 void ActualDestroy(); | 111 void ActualDestroy(); |
| 157 | 112 |
| 158 // Configures |media_codec_| with the given codec parameters from the client. | 113 // Configures |media_codec_| with the given codec parameters from the client. |
| 159 // This configuration will (probably) not be complete before this call | 114 // This configuration will (probably) not be complete before this call |
| 160 // returns. Multiple calls before completion will be ignored. |state_| | 115 // returns. Multiple calls before completion will be ignored. |state_| |
| 161 // must be NO_ERROR or WAITING_FOR_CODEC. Note that, once you call this, | 116 // must be NO_ERROR or WAITING_FOR_CODEC. Note that, once you call this, |
| 162 // you should be careful to avoid modifying members of |codec_config_| until | 117 // you should be careful to avoid modifying members of |codec_config_| until |
| 163 // |state_| is no longer WAITING_FOR_CODEC. | 118 // |state_| is no longer WAITING_FOR_CODEC. |
| 164 void ConfigureMediaCodecAsynchronously(); | 119 void ConfigureMediaCodecAsynchronously(); |
| 165 | 120 |
| 166 // Like ConfigureMediaCodecAsynchronously, but synchronous. Returns true if | 121 // Like ConfigureMediaCodecAsynchronously, but synchronous. Returns true if |
| 167 // and only if |media_codec_| is non-null. Since all configuration is done | 122 // and only if |media_codec_| is non-null. Since all configuration is done |
| 168 // synchronously, there is no concern with modifying |codec_config_| after | 123 // synchronously, there is no concern with modifying |codec_config_| after |
| 169 // this returns. | 124 // this returns. |
| 170 bool ConfigureMediaCodecSynchronously(); | 125 bool ConfigureMediaCodecSynchronously(); |
| 171 | 126 |
| 172 // Instantiate a media codec using |codec_config|. | 127 // Instantiate a media codec using |codec_config|. |
| 173 // This may be called on any thread. | 128 // This may be called on any thread. |
| 174 static std::unique_ptr<VideoCodecBridge> ConfigureMediaCodecOnAnyThread( | 129 static std::unique_ptr<VideoCodecBridge> ConfigureMediaCodecOnAnyThread( |
| 175 scoped_refptr<CodecConfig> codec_config); | 130 scoped_refptr<CodecConfig> codec_config); |
| 176 | 131 |
| 177 // Called on the main thread to update |media_codec_| and complete codec | |
| 178 // configuration. |media_codec| will be null if configuration failed. | |
| 179 void OnCodecConfigured(std::unique_ptr<VideoCodecBridge> media_codec); | |
| 180 | |
| 181 // Sends the decoded frame specified by |codec_buffer_index| to the client. | 132 // Sends the decoded frame specified by |codec_buffer_index| to the client. |
| 182 void SendDecodedFrameToClient(int32_t codec_buffer_index, | 133 void SendDecodedFrameToClient(int32_t codec_buffer_index, |
| 183 int32_t bitstream_id); | 134 int32_t bitstream_id); |
| 184 | 135 |
| 185 // Does pending IO tasks if any. Once this is called, it polls |media_codec_| | 136 // Does pending IO tasks if any. Once this is called, it polls |media_codec_| |
| 186 // until it finishes pending tasks. For the polling, |kDecodePollDelay| is | 137 // until it finishes pending tasks. For the polling, |kDecodePollDelay| is |
| 187 // used. | 138 // used. |
| 188 void DoIOTask(bool start_timer); | 139 void DoIOTask(bool start_timer); |
| 189 | 140 |
| 190 // Feeds input data to |media_codec_|. This checks | 141 // Feeds input data to |media_codec_|. This checks |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 void NotifyFlushDone(); | 179 void NotifyFlushDone(); |
| 229 | 180 |
| 230 // Notifies the client that the decoder was reset. | 181 // Notifies the client that the decoder was reset. |
| 231 void NotifyResetDone(); | 182 void NotifyResetDone(); |
| 232 | 183 |
| 233 // Start or stop our work-polling timer based on whether we did any work, and | 184 // Start or stop our work-polling timer based on whether we did any work, and |
| 234 // how long it has been since we've done work. Calling this with true will | 185 // how long it has been since we've done work. Calling this with true will |
| 235 // start the timer. Calling it with false may stop the timer. | 186 // start the timer. Calling it with false may stop the timer. |
| 236 void ManageTimer(bool did_work); | 187 void ManageTimer(bool did_work); |
| 237 | 188 |
| 238 // Safely clear |media_codec_|. Do this instead of calling reset() / assign. | |
| 239 // Otherwise, the destructor can hang if mediaserver is in a bad state. This | |
| 240 // will release immediately if safe, else post to a separate thread. Either | |
| 241 // way, |media_codec_| will be null upon return. | |
| 242 void ReleaseMediaCodec(); | |
| 243 | |
| 244 // Start the MediaCodec drain process by adding end_of_stream() buffer to the | 189 // Start the MediaCodec drain process by adding end_of_stream() buffer to the |
| 245 // encoded buffers queue. When we receive EOS from the output buffer the drain | 190 // encoded buffers queue. When we receive EOS from the output buffer the drain |
| 246 // process completes and we perform the action depending on the |drain_type|. | 191 // process completes and we perform the action depending on the |drain_type|. |
| 247 void StartCodecDrain(DrainType drain_type); | 192 void StartCodecDrain(DrainType drain_type); |
| 248 | 193 |
| 249 // Returns true if we are currently draining the codec and doing that as part | 194 // Returns true if we are currently draining the codec and doing that as part |
| 250 // of Reset() or Destroy() VP8 workaround. (http://crbug.com/598963). We won't | 195 // of Reset() or Destroy() VP8 workaround. (http://crbug.com/598963). We won't |
| 251 // display any frames and disable normal errors handling. | 196 // display any frames and disable normal errors handling. |
| 252 bool IsDrainingForResetOrDestroy() const; | 197 bool IsDrainingForResetOrDestroy() const; |
| 253 | 198 |
| 254 // A helper method that performs the operation required after the drain | 199 // A helper method that performs the operation required after the drain |
| 255 // completion (usually when we receive EOS in the output). The operation | 200 // completion (usually when we receive EOS in the output). The operation |
| 256 // itself depends on the |drain_type_|. | 201 // itself depends on the |drain_type_|. |
| 257 void OnDrainCompleted(); | 202 void OnDrainCompleted(); |
| 258 | 203 |
| 259 // Resets MediaCodec and buffers/containers used for storing output. These | 204 // Resets MediaCodec and buffers/containers used for storing output. These |
| 260 // components need to be reset upon EOS to decode a later stream. Input state | 205 // components need to be reset upon EOS to decode a later stream. Input state |
| 261 // (e.g. queued BitstreamBuffers) is not reset, as input following an EOS | 206 // (e.g. queued BitstreamBuffers) is not reset, as input following an EOS |
| 262 // is still valid and should be processed. | 207 // is still valid and should be processed. |
| 263 void ResetCodecState(); | 208 void ResetCodecState(); |
| 264 | 209 |
| 265 // Registered to be called when surfaces are being destroyed. If |surface_id| | |
| 266 // is our surface, we should release the MediaCodec before returning from | |
| 267 // this. | |
| 268 void OnDestroyingSurface(int surface_id); | |
| 269 | |
| 270 // Indicates if MediaCodec should not be used for software decoding since we | 210 // Indicates if MediaCodec should not be used for software decoding since we |
| 271 // have safer versions elsewhere. | 211 // have safer versions elsewhere. |
| 272 bool IsMediaCodecSoftwareDecodingForbidden() const; | 212 bool IsMediaCodecSoftwareDecodingForbidden() const; |
| 273 | 213 |
| 274 // On platforms which support seamless surface changes, this will reinitialize | 214 // On platforms which support seamless surface changes, this will reinitialize |
| 275 // the picture buffer manager with the new surface. This function reads and | 215 // the picture buffer manager with the new surface. This function reads and |
| 276 // clears the surface id from |pending_surface_id_|. It will issue a decode | 216 // clears the surface id from |pending_surface_id_|. It will issue a decode |
| 277 // error if the surface change fails. Returns false on failure. | 217 // error if the surface change fails. Returns false on failure. |
| 278 bool UpdateSurface(); | 218 bool UpdateSurface(); |
| 279 | 219 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 // Indicates if ResetCodecState() should be called upon the next call to | 314 // Indicates if ResetCodecState() should be called upon the next call to |
| 375 // Decode(). Allows us to avoid trashing the last few frames of a playback | 315 // Decode(). Allows us to avoid trashing the last few frames of a playback |
| 376 // when the EOS buffer is received. | 316 // when the EOS buffer is received. |
| 377 bool codec_needs_reset_; | 317 bool codec_needs_reset_; |
| 378 | 318 |
| 379 // True if surface creation and |picture_buffer_manager_| initialization has | 319 // True if surface creation and |picture_buffer_manager_| initialization has |
| 380 // been defered until the first Decode() call. | 320 // been defered until the first Decode() call. |
| 381 bool defer_surface_creation_; | 321 bool defer_surface_creation_; |
| 382 | 322 |
| 383 // Has a value if a SetSurface() call has occurred and a new surface should be | 323 // Has a value if a SetSurface() call has occurred and a new surface should be |
| 384 // switched to when possible. Cleared during OnDestroyingSurface() and if all | 324 // switched to when possible. Cleared during OnSurfaceDestroyed() and if all |
| 385 // pictures have been rendered in DequeueOutput(). | 325 // pictures have been rendered in DequeueOutput(). |
| 386 base::Optional<int32_t> pending_surface_id_; | 326 base::Optional<int32_t> pending_surface_id_; |
| 387 | 327 |
| 388 // Copy of the VDA::Config we were given. | 328 // Copy of the VDA::Config we were given. |
| 389 Config config_; | 329 Config config_; |
| 390 | 330 |
| 391 OnDestroyingSurfaceCallback on_destroying_surface_cb_; | |
| 392 | |
| 393 // WeakPtrFactory for posting tasks back to |this|. | 331 // WeakPtrFactory for posting tasks back to |this|. |
| 394 base::WeakPtrFactory<AndroidVideoDecodeAccelerator> weak_this_factory_; | 332 base::WeakPtrFactory<AndroidVideoDecodeAccelerator> weak_this_factory_; |
| 395 | 333 |
| 396 friend class AndroidVideoDecodeAcceleratorTest; | 334 friend class AndroidVideoDecodeAcceleratorTest; |
| 397 }; | 335 }; |
| 398 | 336 |
| 399 } // namespace media | 337 } // namespace media |
| 400 | 338 |
| 401 #endif // MEDIA_GPU_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ | 339 #endif // MEDIA_GPU_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ |
| OLD | NEW |