Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1636)

Side by Side Diff: media/gpu/avda_codec_allocator.h

Issue 2508053002: media: Do a TimedWait() for video surface teardown in AVDA (Closed)
Patch Set: change timeout to 2 Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/gpu/android_video_decode_accelerator.cc ('k') | media/gpu/avda_codec_allocator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_
6 #define MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_
7
5 #include <stddef.h> 8 #include <stddef.h>
6 9
7 #include <memory> 10 #include <memory>
8 11
9 #include "base/android/build_info.h" 12 #include "base/android/build_info.h"
10 #include "base/bind.h" 13 #include "base/bind.h"
11 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
12 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/synchronization/waitable_event.h"
13 #include "base/sys_info.h" 17 #include "base/sys_info.h"
14 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
15 #include "base/threading/thread_checker.h" 19 #include "base/threading/thread_checker.h"
16 #include "base/time/tick_clock.h" 20 #include "base/time/tick_clock.h"
17 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "media/base/android/media_drm_bridge_cdm_context.h"
23 #include "media/base/android/sdk_media_codec_bridge.h"
18 #include "media/base/media.h" 24 #include "media/base/media.h"
25 #include "media/base/surface_manager.h"
26 #include "media/base/video_codecs.h"
19 #include "media/gpu/media_gpu_export.h" 27 #include "media/gpu/media_gpu_export.h"
28 #include "ui/gfx/geometry/size.h"
29 #include "ui/gl/android/scoped_java_surface.h"
20 30
21 namespace media { 31 namespace media {
22 32
23 class AndroidVideoDecodeAccelerator; 33 // For TaskRunnerFor. These are used as vector indices, so please update
34 // AVDACodecAllocator's constructor if you add / change them.
35 // TODO(watk): Hide this from AVDA now that we manage codec creation.
36 enum TaskType {
37 // Task for an autodetected MediaCodec instance.
38 AUTO_CODEC = 0,
39
40 // Task for a software-codec-required MediaCodec.
41 SW_CODEC = 1,
42
43 // Special value to indicate "none". This is not used as an array index. It
44 // must, however, be positive to keep the enum unsigned.
45 FAILED_CODEC = 99,
46 };
47
48 // Configuration info for MediaCodec.
49 // This is used to shuttle configuration info between threads without needing
50 // to worry about the lifetime of the AVDA instance.
51 class CodecConfig : public base::RefCountedThreadSafe<CodecConfig> {
52 public:
53 CodecConfig();
54
55 // Codec type. Used when we configure media codec.
56 VideoCodec codec_ = kUnknownVideoCodec;
57
58 // Whether encryption scheme requires to use protected surface.
59 bool needs_protected_surface_ = false;
60
61 // The surface that MediaCodec is configured to output to.
62 gl::ScopedJavaSurface surface_;
63
64 int surface_id_ = SurfaceManager::kNoSurfaceID;
65
66 // The MediaCrypto object is used in the MediaCodec.configure() in case of
67 // an encrypted stream.
68 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto_;
69
70 // Initial coded size. The actual size might change at any time, so this
71 // is only a hint.
72 gfx::Size initial_expected_coded_size_;
73
74 // The type of allocation to use for this. We use this to select the right
75 // thread for construction / destruction, and to decide if we should
76 // restrict the codec to be software only.
77 TaskType task_type_;
78
79 // Codec specific data (SPS and PPS for H264).
80 std::vector<uint8_t> csd0_;
81 std::vector<uint8_t> csd1_;
82
83 protected:
84 friend class base::RefCountedThreadSafe<CodecConfig>;
85 virtual ~CodecConfig();
86
87 private:
88 DISALLOW_COPY_AND_ASSIGN(CodecConfig);
89 };
90
91 class AVDACodecAllocatorClient {
92 public:
93 // Called when the requested SurfaceView becomes available after a call to
94 // AllocateSurface()
95 virtual void OnSurfaceAvailable(bool success) = 0;
96
97 // Called when the allocated surface is being destroyed. This must either
98 // replace the surface with MediaCodec#setSurface, or release the MediaCodec
99 // it's attached to. The client no longer owns the surface and doesn't
100 // need to call DeallocateSurface();
101 virtual void OnSurfaceDestroyed() = 0;
102
103 // Called on the main thread when a new MediaCodec is configured.
104 // |media_codec| will be null if configuration failed.
105 virtual void OnCodecConfigured(
106 std::unique_ptr<VideoCodecBridge> media_codec) = 0;
107
108 protected:
109 ~AVDACodecAllocatorClient() {}
110 };
24 111
25 // AVDACodecAllocator manages threads for allocating and releasing MediaCodec 112 // AVDACodecAllocator manages threads for allocating and releasing MediaCodec
26 // instances. These activities can hang, depending on android version, due 113 // instances. These activities can hang, depending on android version, due
27 // to mediaserver bugs. AVDACodecAllocator detects these cases, and reports 114 // to mediaserver bugs. AVDACodecAllocator detects these cases, and reports
28 // on them to allow software fallback if the HW path is hung up. 115 // on them to allow software fallback if the HW path is hung up.
29 class MEDIA_GPU_EXPORT AVDACodecAllocator { 116 class MEDIA_GPU_EXPORT AVDACodecAllocator {
30 public: 117 public:
31 // For AVDAManager::TaskRunnerFor. These are used as vector indices, so 118 static AVDACodecAllocator* Instance();
32 // please update AVDACodecAllocator's constructor if you add / change them.
33 enum TaskType {
34 // Task for an autodetected MediaCodec instance.
35 AUTO_CODEC = 0,
36 119
37 // Task for a software-codec-required MediaCodec. 120 // Called synchronously when the given surface is being destroyed on the
38 SW_CODEC = 1, 121 // browser UI thread.
122 void OnSurfaceDestroyed(int surface_id);
39 123
40 // Special value to indicate "none". This is not used as an array index. It 124 // Make sure the construction thread is started for |client|.
41 // must, however, be positive to keep the enum unsigned. 125 bool StartThread(AVDACodecAllocatorClient* client);
42 FAILED_CODEC = 99,
43 };
44 126
45 // Make sure the construction thread is started for |avda|. 127 void StopThread(AVDACodecAllocatorClient* client);
46 bool StartThread(AndroidVideoDecodeAccelerator* avda);
47
48 void StopThread(AndroidVideoDecodeAccelerator* avda);
49 128
50 // Return the task runner for tasks of type |type|. If that thread failed 129 // Return the task runner for tasks of type |type|. If that thread failed
51 // to start, then fall back to the GPU main thread. 130 // to start, then fall back to the GPU main thread.
52 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerFor(TaskType task_type); 131 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerFor(TaskType task_type);
53 132
133 // Returns true if the caller now owns the surface, or false if someone else
134 // owns the surface. |client| will be notified when the surface is available
135 // via OnSurfaceAvailable().
136 bool AllocateSurface(AVDACodecAllocatorClient* client, int surface_id);
137
138 // Relinquish ownership of the surface or stop waiting for it to be available.
139 // The caller must guarantee that when calling this the surface is either no
140 // longer attached to a MediaCodec, or the MediaCodec it was attached to is
141 // was released with ReleaseMediaCodec().
142 void DeallocateSurface(AVDACodecAllocatorClient* client, int surface_id);
143
144 // Create and configure a MediaCodec synchronously.
145 std::unique_ptr<VideoCodecBridge> CreateMediaCodecSync(
146 scoped_refptr<CodecConfig> codec_config);
147
148 // Create and configure a MediaCodec asynchronously. The result is delivered
149 // via OnCodecConfigured().
150 void CreateMediaCodecAsync(base::WeakPtr<AVDACodecAllocatorClient> client,
151 scoped_refptr<CodecConfig> codec_config);
152
153 // Asynchronously release |media_codec| with the attached surface.
154 // TODO(watk): Bundle the MediaCodec and surface together so you can't get
155 // this pairing wrong.
156 void ReleaseMediaCodec(std::unique_ptr<VideoCodecBridge> media_codec,
157 TaskType task_type,
158 int surface_id);
159
54 // Returns a hint about whether the construction thread has hung for 160 // Returns a hint about whether the construction thread has hung for
55 // |task_type|. Note that if a thread isn't started, then we'll just return 161 // |task_type|. Note that if a thread isn't started, then we'll just return
56 // "not hung", since it'll run on the current thread anyway. The hang 162 // "not hung", since it'll run on the current thread anyway. The hang
57 // detector will see no pending jobs in that case, so it's automatic. 163 // detector will see no pending jobs in that case, so it's automatic.
58 bool IsThreadLikelyHung(TaskType task_type); 164 bool IsThreadLikelyHung(TaskType task_type);
59 165
60 // Return true if and only if there is any AVDA registered. 166 // Return true if and only if there is any AVDA registered.
61 bool IsAnyRegisteredAVDA(); 167 bool IsAnyRegisteredAVDA();
62 168
63 // Return the task type to use for a new codec allocation, or FAILED_CODEC if 169 // Return the task type to use for a new codec allocation, or FAILED_CODEC if
(...skipping 12 matching lines...) Expand all
76 struct TestInformation { 182 struct TestInformation {
77 TestInformation(); 183 TestInformation();
78 ~TestInformation(); 184 ~TestInformation();
79 // Optional clock source. 185 // Optional clock source.
80 std::unique_ptr<base::TickClock> tick_clock_; 186 std::unique_ptr<base::TickClock> tick_clock_;
81 187
82 // Optional event that we'll signal when stopping the AUTO_CODEC thread. 188 // Optional event that we'll signal when stopping the AUTO_CODEC thread.
83 std::unique_ptr<base::WaitableEvent> stop_event_; 189 std::unique_ptr<base::WaitableEvent> stop_event_;
84 }; 190 };
85 191
86 // |test_info| is owned by the unit test. 192 struct OwnerRecord {
87 AVDACodecAllocator(TestInformation* test_info = nullptr); 193 AVDACodecAllocatorClient* owner = nullptr;
88 ~AVDACodecAllocator(); 194 AVDACodecAllocatorClient* waiter = nullptr;
89 195 };
90 // Stop the thread indicated by |index|, then signal |event| if provided.
91 void StopThreadTask(size_t index, base::WaitableEvent* event = nullptr);
92
93 // All registered AVDA instances.
94 std::set<AndroidVideoDecodeAccelerator*> thread_avda_instances_;
95 196
96 class HangDetector : public base::MessageLoop::TaskObserver { 197 class HangDetector : public base::MessageLoop::TaskObserver {
97 public: 198 public:
98 HangDetector(base::TickClock* tick_clock); 199 HangDetector(base::TickClock* tick_clock);
99
100 void WillProcessTask(const base::PendingTask& pending_task) override; 200 void WillProcessTask(const base::PendingTask& pending_task) override;
101 void DidProcessTask(const base::PendingTask& pending_task) override; 201 void DidProcessTask(const base::PendingTask& pending_task) override;
102
103 bool IsThreadLikelyHung(); 202 bool IsThreadLikelyHung();
104 203
105 private: 204 private:
106 base::Lock lock_; 205 base::Lock lock_;
206
107 // Non-null when a task is currently running. 207 // Non-null when a task is currently running.
108 base::TimeTicks task_start_time_; 208 base::TimeTicks task_start_time_;
109 209
110 base::TickClock* tick_clock_; 210 base::TickClock* tick_clock_;
111 211
112 DISALLOW_COPY_AND_ASSIGN(HangDetector); 212 DISALLOW_COPY_AND_ASSIGN(HangDetector);
113 }; 213 };
114 214
115 // Handy combination of a thread and hang detector for it. 215 // Handy combination of a thread and hang detector for it.
116 struct ThreadAndHangDetector { 216 struct ThreadAndHangDetector {
117 ThreadAndHangDetector(const std::string& name, base::TickClock* tick_clock) 217 ThreadAndHangDetector(const std::string& name, base::TickClock* tick_clock)
118 : thread(name), hang_detector(tick_clock) {} 218 : thread(name), hang_detector(tick_clock) {}
119 base::Thread thread; 219 base::Thread thread;
120 HangDetector hang_detector; 220 HangDetector hang_detector;
121 }; 221 };
122 222
223 // |test_info| is owned by the unit test.
224 AVDACodecAllocator(TestInformation* test_info = nullptr);
225 ~AVDACodecAllocator();
226
227 void OnMediaCodecAndSurfaceReleased(int surface_id);
228
229 // Stop the thread indicated by |index|, then signal |event| if provided.
230 void StopThreadTask(size_t index, base::WaitableEvent* event = nullptr);
231
232 // All registered AVDAs.
233 std::set<AVDACodecAllocatorClient*> clients_;
234
235 // Indexed by surface id.
236 std::map<int32_t, OwnerRecord> surface_owners_;
237
238 // Waitable events for ongoing release tasks indexed by surface id so we can
239 // wait on the codec release if the surface attached to it is being destroyed.
240 std::map<int32_t, base::WaitableEvent> pending_codec_releases_;
241
123 // Threads for each of TaskType. They are started / stopped as avda instances 242 // Threads for each of TaskType. They are started / stopped as avda instances
124 // show and and request them. The vector indicies must match TaskType. 243 // show and and request them. The vector indicies must match TaskType.
125 std::vector<ThreadAndHangDetector*> threads_; 244 std::vector<ThreadAndHangDetector*> threads_;
126 245
127 base::ThreadChecker thread_checker_; 246 base::ThreadChecker thread_checker_;
128 247
129 // Optional, used for unit testing. We do not own this. 248 // Optional, used for unit testing. We do not own this.
130 TestInformation* test_info_; 249 TestInformation* test_info_;
131 250
132 // For canceling pending StopThreadTask()s. 251 // For canceling pending StopThreadTask()s.
133 base::WeakPtrFactory<AVDACodecAllocator> weak_this_factory_; 252 base::WeakPtrFactory<AVDACodecAllocator> weak_this_factory_;
134 253
135 DISALLOW_COPY_AND_ASSIGN(AVDACodecAllocator); 254 DISALLOW_COPY_AND_ASSIGN(AVDACodecAllocator);
136 }; 255 };
137 256
138 } // namespace media 257 } // namespace media
258
259 #endif // MEDIA_GPU_AVDA_CODEC_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.cc ('k') | media/gpu/avda_codec_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698