| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_AVDA_CODEC_ALLOCATOR_H_ | 5 #ifndef MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_ |
| 6 #define MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_ | 6 #define MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/android/build_info.h" | 12 #include "base/android/build_info.h" |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/optional.h" | 15 #include "base/optional.h" |
| 16 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
| 17 #include "base/sys_info.h" | 17 #include "base/sys_info.h" |
| 18 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
| 19 #include "base/threading/thread_checker.h" | 19 #include "base/threading/thread_checker.h" |
| 20 #include "base/time/tick_clock.h" | 20 #include "base/time/tick_clock.h" |
| 21 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 22 #include "media/base/android/media_codec_bridge_impl.h" | 22 #include "media/base/android/media_codec_bridge_impl.h" |
| 23 #include "media/base/android/media_drm_bridge_cdm_context.h" | 23 #include "media/base/android/media_drm_bridge_cdm_context.h" |
| 24 #include "media/base/media.h" | 24 #include "media/base/media.h" |
| 25 #include "media/base/surface_manager.h" | 25 #include "media/base/surface_manager.h" |
| 26 #include "media/base/video_codecs.h" | 26 #include "media/base/video_codecs.h" |
| 27 #include "media/gpu/avda_surface_bundle.h" |
| 27 #include "media/gpu/media_gpu_export.h" | 28 #include "media/gpu/media_gpu_export.h" |
| 28 #include "ui/gfx/geometry/size.h" | 29 #include "ui/gfx/geometry/size.h" |
| 29 #include "ui/gl/android/scoped_java_surface.h" | 30 #include "ui/gl/android/scoped_java_surface.h" |
| 30 | 31 |
| 31 namespace media { | 32 namespace media { |
| 32 | 33 |
| 33 // For TaskRunnerFor. These are used as vector indices, so please update | 34 // For TaskRunnerFor. These are used as vector indices, so please update |
| 34 // AVDACodecAllocator's constructor if you add / change them. | 35 // AVDACodecAllocator's constructor if you add / change them. |
| 35 enum TaskType { | 36 enum TaskType { |
| 36 // Task for an autodetected MediaCodec instance. | 37 // Task for an autodetected MediaCodec instance. |
| 37 AUTO_CODEC = 0, | 38 AUTO_CODEC = 0, |
| 38 | 39 |
| 39 // Task for a software-codec-required MediaCodec. | 40 // Task for a software-codec-required MediaCodec. |
| 40 SW_CODEC = 1, | 41 SW_CODEC = 1, |
| 41 }; | 42 }; |
| 42 | 43 |
| 43 // Configuration info for MediaCodec. | 44 // Configuration info for MediaCodec. |
| 44 // This is used to shuttle configuration info between threads without needing | 45 // This is used to shuttle configuration info between threads without needing |
| 45 // to worry about the lifetime of the AVDA instance. | 46 // to worry about the lifetime of the AVDA instance. |
| 46 class CodecConfig : public base::RefCountedThreadSafe<CodecConfig> { | 47 class CodecConfig : public base::RefCountedThreadSafe<CodecConfig> { |
| 47 public: | 48 public: |
| 48 CodecConfig(); | 49 CodecConfig(); |
| 49 | 50 |
| 50 VideoCodec codec = kUnknownVideoCodec; | 51 VideoCodec codec = kUnknownVideoCodec; |
| 51 | 52 |
| 52 // The surface that MediaCodec is configured to output to. | 53 // The surface that MediaCodec is configured to output to. |
| 53 gl::ScopedJavaSurface surface; | 54 scoped_refptr<AVDASurfaceBundle> surface_bundle; |
| 54 int surface_id = SurfaceManager::kNoSurfaceID; | |
| 55 | |
| 56 // The SurfaceTexture attached to |surface|, or nullptr if |surface| is | |
| 57 // SurfaceView backed. | |
| 58 scoped_refptr<gl::SurfaceTexture> surface_texture; | |
| 59 | 55 |
| 60 // The MediaCrypto that MediaCodec is configured with for an encrypted stream. | 56 // The MediaCrypto that MediaCodec is configured with for an encrypted stream. |
| 61 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto; | 57 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto; |
| 62 | 58 |
| 63 // Whether the encryption scheme requires us to use a protected surface. | 59 // Whether the encryption scheme requires us to use a protected surface. |
| 64 bool needs_protected_surface = false; | 60 bool needs_protected_surface = false; |
| 65 | 61 |
| 66 // The initial coded size. The actual size might change at any time, so this | 62 // The initial coded size. The actual size might change at any time, so this |
| 67 // is only a hint. | 63 // is only a hint. |
| 68 gfx::Size initial_expected_coded_size; | 64 gfx::Size initial_expected_coded_size; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 // Create and configure a MediaCodec synchronously. | 133 // Create and configure a MediaCodec synchronously. |
| 138 std::unique_ptr<MediaCodecBridge> CreateMediaCodecSync( | 134 std::unique_ptr<MediaCodecBridge> CreateMediaCodecSync( |
| 139 scoped_refptr<CodecConfig> codec_config); | 135 scoped_refptr<CodecConfig> codec_config); |
| 140 | 136 |
| 141 // Create and configure a MediaCodec asynchronously. The result is delivered | 137 // Create and configure a MediaCodec asynchronously. The result is delivered |
| 142 // via OnCodecConfigured(). | 138 // via OnCodecConfigured(). |
| 143 virtual void CreateMediaCodecAsync( | 139 virtual void CreateMediaCodecAsync( |
| 144 base::WeakPtr<AVDACodecAllocatorClient> client, | 140 base::WeakPtr<AVDACodecAllocatorClient> client, |
| 145 scoped_refptr<CodecConfig> codec_config); | 141 scoped_refptr<CodecConfig> codec_config); |
| 146 | 142 |
| 147 // Asynchronously release |media_codec| with the attached surface. | 143 // Asynchronously release |media_codec| with the attached surface. We will |
| 144 // drop our reference to |surface_bundle| on the main thread after the codec |
| 145 // is deallocated, since the codec isn't using it anymore. We will not take |
| 146 // other action on it (e.g., calling ReleaseSurfaceTexture if it has one), |
| 147 // since some other codec might be going to use it. We just want to be sure |
| 148 // that it outlives |media_codec|. |
| 148 // TODO(watk): Bundle the MediaCodec and surface together so you can't get | 149 // TODO(watk): Bundle the MediaCodec and surface together so you can't get |
| 149 // this pairing wrong. | 150 // this pairing wrong. |
| 150 void ReleaseMediaCodec(std::unique_ptr<MediaCodecBridge> media_codec, | 151 void ReleaseMediaCodec( |
| 151 TaskType task_type, | 152 std::unique_ptr<MediaCodecBridge> media_codec, |
| 152 int surface_id); | 153 TaskType task_type, |
| 154 const scoped_refptr<AVDASurfaceBundle>& surface_bundle); |
| 153 | 155 |
| 154 // Returns a hint about whether the construction thread has hung for | 156 // Returns a hint about whether the construction thread has hung for |
| 155 // |task_type|. Note that if a thread isn't started, then we'll just return | 157 // |task_type|. Note that if a thread isn't started, then we'll just return |
| 156 // "not hung", since it'll run on the current thread anyway. The hang | 158 // "not hung", since it'll run on the current thread anyway. The hang |
| 157 // detector will see no pending jobs in that case, so it's automatic. | 159 // detector will see no pending jobs in that case, so it's automatic. |
| 158 bool IsThreadLikelyHung(TaskType task_type); | 160 bool IsThreadLikelyHung(TaskType task_type); |
| 159 | 161 |
| 160 // Return true if and only if there is any AVDA registered. | 162 // Return true if and only if there is any AVDA registered. |
| 161 bool IsAnyRegisteredAVDA(); | 163 bool IsAnyRegisteredAVDA(); |
| 162 | 164 |
| 163 // Return the task type to use for a new codec allocation, or nullopt if | 165 // Return the task type to use for a new codec allocation, or nullopt if |
| 164 // both threads are hung. | 166 // both threads are hung. |
| 165 base::Optional<TaskType> TaskTypeForAllocation(); | 167 base::Optional<TaskType> TaskTypeForAllocation(); |
| 166 | 168 |
| 167 // Return the task runner for tasks of type |type|. | 169 // Return the task runner for tasks of type |type|. |
| 168 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerFor(TaskType task_type); | 170 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerFor(TaskType task_type); |
| 169 | 171 |
| 170 // Return a reference to the thread for unit tests. | 172 // Return a reference to the thread for unit tests. |
| 171 base::Thread& GetThreadForTesting(TaskType task_type); | 173 base::Thread& GetThreadForTesting(TaskType task_type); |
| 172 | 174 |
| 173 protected: | 175 protected: |
| 174 // |tick_clock| and |stop_event| are for tests only. | 176 // |tick_clock| and |stop_event| are for tests only. |
| 175 AVDACodecAllocator(base::TickClock* tick_clock = nullptr, | 177 AVDACodecAllocator(base::TickClock* tick_clock = nullptr, |
| 176 base::WaitableEvent* stop_event = nullptr); | 178 base::WaitableEvent* stop_event = nullptr); |
| 177 virtual ~AVDACodecAllocator(); | 179 virtual ~AVDACodecAllocator(); |
| 178 | 180 |
| 181 // Forward |media_codec|, which is configured to output to |surface_bundle|, |
| 182 // to |client| if |client| is still around. Otherwise, release the codec and |
| 183 // then drop our ref to |surface_bundle|. |
| 184 void ForwardOrDropCodec(base::WeakPtr<AVDACodecAllocatorClient> client, |
| 185 TaskType task_type, |
| 186 scoped_refptr<AVDASurfaceBundle> surface_bundle, |
| 187 std::unique_ptr<MediaCodecBridge> media_codec); |
| 188 |
| 179 private: | 189 private: |
| 180 friend class AVDACodecAllocatorTest; | 190 friend class AVDACodecAllocatorTest; |
| 181 | 191 |
| 182 struct OwnerRecord { | 192 struct OwnerRecord { |
| 183 AVDACodecAllocatorClient* owner = nullptr; | 193 AVDACodecAllocatorClient* owner = nullptr; |
| 184 AVDACodecAllocatorClient* waiter = nullptr; | 194 AVDACodecAllocatorClient* waiter = nullptr; |
| 185 }; | 195 }; |
| 186 | 196 |
| 187 class HangDetector : public base::MessageLoop::TaskObserver { | 197 class HangDetector : public base::MessageLoop::TaskObserver { |
| 188 public: | 198 public: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 203 }; | 213 }; |
| 204 | 214 |
| 205 // Handy combination of a thread and hang detector for it. | 215 // Handy combination of a thread and hang detector for it. |
| 206 struct ThreadAndHangDetector { | 216 struct ThreadAndHangDetector { |
| 207 ThreadAndHangDetector(const std::string& name, base::TickClock* tick_clock) | 217 ThreadAndHangDetector(const std::string& name, base::TickClock* tick_clock) |
| 208 : thread(name), hang_detector(tick_clock) {} | 218 : thread(name), hang_detector(tick_clock) {} |
| 209 base::Thread thread; | 219 base::Thread thread; |
| 210 HangDetector hang_detector; | 220 HangDetector hang_detector; |
| 211 }; | 221 }; |
| 212 | 222 |
| 213 void OnMediaCodecAndSurfaceReleased(int surface_id); | 223 // Called on the gpu main thread when a codec is freed on a codec thread. |
| 224 // |surface_bundle| is the surface bundle that the codec was using. |
| 225 void OnMediaCodecReleased(scoped_refptr<AVDASurfaceBundle> surface_bundle); |
| 214 | 226 |
| 215 // Stop the thread indicated by |index|. This signals stop_event_for_testing_ | 227 // Stop the thread indicated by |index|. This signals stop_event_for_testing_ |
| 216 // after both threads are stopped. | 228 // after both threads are stopped. |
| 217 void StopThreadTask(size_t index); | 229 void StopThreadTask(size_t index); |
| 218 | 230 |
| 219 // All registered AVDAs. | 231 // All registered AVDAs. |
| 220 std::set<AVDACodecAllocatorClient*> clients_; | 232 std::set<AVDACodecAllocatorClient*> clients_; |
| 221 | 233 |
| 222 // Indexed by surface id. | 234 // Indexed by surface id. |
| 223 std::map<int32_t, OwnerRecord> surface_owners_; | 235 std::map<int32_t, OwnerRecord> surface_owners_; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 236 | 248 |
| 237 // For canceling pending StopThreadTask()s. | 249 // For canceling pending StopThreadTask()s. |
| 238 base::WeakPtrFactory<AVDACodecAllocator> weak_this_factory_; | 250 base::WeakPtrFactory<AVDACodecAllocator> weak_this_factory_; |
| 239 | 251 |
| 240 DISALLOW_COPY_AND_ASSIGN(AVDACodecAllocator); | 252 DISALLOW_COPY_AND_ASSIGN(AVDACodecAllocator); |
| 241 }; | 253 }; |
| 242 | 254 |
| 243 } // namespace media | 255 } // namespace media |
| 244 | 256 |
| 245 #endif // MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_ | 257 #endif // MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_ |
| OLD | NEW |