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

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.h

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix several more bot-identified build issues Created 4 years, 8 months 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_DECODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_DECODE_ACCELERATOR_H_
7
8 #include <stdint.h>
9
10 #include <list>
11 #include <map>
12 #include <queue>
13 #include <string>
14 #include <vector>
15
16 #include "base/compiler_specific.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/timer/timer.h"
19 #include "content/common/content_export.h"
20 #include "content/common/gpu/media/avda_state_provider.h"
21 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
22 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
23 #include "gpu/command_buffer/service/gpu_preferences.h"
24 #include "media/base/android/media_drm_bridge_cdm_context.h"
25 #include "media/base/android/sdk_media_codec_bridge.h"
26 #include "media/base/media_keys.h"
27 #include "media/video/video_decode_accelerator.h"
28 #include "ui/gl/android/scoped_java_surface.h"
29
30 namespace gfx {
31 class SurfaceTexture;
32 }
33
34 namespace content {
35
36 // A VideoDecodeAccelerator implementation for Android.
37 // This class decodes the input encoded stream by using Android's MediaCodec
38 // class. http://developer.android.com/reference/android/media/MediaCodec.html
39 // It delegates attaching pictures to PictureBuffers to a BackingStrategy, but
40 // otherwise handles the work of transferring data to / from MediaCodec.
41 class CONTENT_EXPORT AndroidVideoDecodeAccelerator
42 : public media::VideoDecodeAccelerator,
43 public AVDAStateProvider {
44 public:
45 using OutputBufferMap = std::map<int32_t, media::PictureBuffer>;
46
47 // A BackingStrategy is responsible for making a PictureBuffer's texture
48 // contain the image that a MediaCodec decoder buffer tells it to.
49 class BackingStrategy {
50 public:
51 virtual ~BackingStrategy() {}
52
53 // Must be called before anything else. If surface_view_id is not equal to
54 // |kNoSurfaceID| it refers to a SurfaceView that the strategy must render
55 // to.
56 // Returns the Java surface to configure MediaCodec with.
57 virtual gfx::ScopedJavaSurface Initialize(int surface_view_id) = 0;
58
59 // Called before the AVDA does any Destroy() work. This will be
60 // the last call that the BackingStrategy receives.
61 virtual void Cleanup(bool have_context,
62 const OutputBufferMap& buffer_map) = 0;
63
64 // This returns the SurfaceTexture created by Initialize, or nullptr if
65 // the strategy was initialized with a SurfaceView.
66 virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture() const = 0;
67
68 // Return the GL texture target that the PictureBuffer textures use.
69 virtual uint32_t GetTextureTarget() const = 0;
70
71 // Return the size to use when requesting picture buffers.
72 virtual gfx::Size GetPictureBufferSize() const = 0;
73
74 // Make the provided PictureBuffer draw the image that is represented by
75 // the decoded output buffer at codec_buffer_index.
76 virtual void UseCodecBufferForPictureBuffer(
77 int32_t codec_buffer_index,
78 const media::PictureBuffer& picture_buffer) = 0;
79
80 // Notify strategy that a picture buffer has been assigned.
81 virtual void AssignOnePictureBuffer(
82 const media::PictureBuffer& picture_buffer,
83 bool have_context) {}
84
85 // Notify strategy that a picture buffer has been reused.
86 virtual void ReuseOnePictureBuffer(
87 const media::PictureBuffer& picture_buffer) {}
88
89 // Notify strategy that we have a new android MediaCodec instance. This
90 // happens when we're starting up or re-configuring mid-stream. Any
91 // previously provided codec should no longer be referenced.
92 // For convenience, a container of PictureBuffers is provided in case
93 // per-image cleanup is needed.
94 virtual void CodecChanged(media::VideoCodecBridge* codec,
95 const OutputBufferMap& buffer_map) = 0;
96
97 // Notify the strategy that a frame is available. This callback can happen
98 // on any thread at any time.
99 virtual void OnFrameAvailable() = 0;
100
101 // Whether the pictures produced by this backing strategy are overlayable.
102 virtual bool ArePicturesOverlayable() = 0;
103
104 // Size may have changed due to resolution change since the last time this
105 // PictureBuffer was used. Update the size of the picture buffer to
106 // |new_size| and also update any size-dependent state (e.g. size of
107 // associated texture). Callers should set the correct GL context prior to
108 // calling.
109 virtual void UpdatePictureBufferSize(media::PictureBuffer* picture_buffer,
110 const gfx::Size& new_size) = 0;
111 };
112
113 AndroidVideoDecodeAccelerator(
114 const MakeGLContextCurrentCallback& make_context_current_cb,
115 const GetGLES2DecoderCallback& get_gles2_decoder_cb);
116
117 ~AndroidVideoDecodeAccelerator() override;
118
119 // media::VideoDecodeAccelerator implementation:
120 bool Initialize(const Config& config, Client* client) override;
121 void SetCdm(int cdm_id) override;
122 void Decode(const media::BitstreamBuffer& bitstream_buffer) override;
123 void AssignPictureBuffers(
124 const std::vector<media::PictureBuffer>& buffers) override;
125 void ReusePictureBuffer(int32_t picture_buffer_id) override;
126 void Flush() override;
127 void Reset() override;
128 void Destroy() override;
129 bool TryToSetupDecodeOnSeparateThread(
130 const base::WeakPtr<Client>& decode_client,
131 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
132 override;
133
134 // AVDAStateProvider implementation:
135 const gfx::Size& GetSize() const override;
136 const base::ThreadChecker& ThreadChecker() const override;
137 base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const override;
138 gpu::gles2::TextureRef* GetTextureForPicture(
139 const media::PictureBuffer& picture_buffer) override;
140 void PostError(const ::tracked_objects::Location& from_here,
141 media::VideoDecodeAccelerator::Error error) override;
142
143 static media::VideoDecodeAccelerator::Capabilities GetCapabilities(
144 const gpu::GpuPreferences& gpu_preferences);
145
146 // Notifies about SurfaceTexture::OnFrameAvailable. This can happen on any
147 // thread at any time!
148 void OnFrameAvailable();
149
150 private:
151 friend class AVDATimerManager;
152
153 // TODO(timav): evaluate the need for more states in the AVDA state machine.
154 enum State {
155 NO_ERROR,
156 ERROR,
157 // Set when we are asynchronously constructing the codec. Will transition
158 // to NO_ERROR or ERROR depending on success.
159 WAITING_FOR_CODEC,
160 // Set when we have a codec, but it doesn't yet have a key.
161 WAITING_FOR_KEY,
162 WAITING_FOR_EOS,
163 };
164
165 // Configuration info for MediaCodec.
166 // This is used to shuttle configuration info between threads without needing
167 // to worry about the lifetime of the AVDA instance. All of these should not
168 // be modified while |state_| is WAITING_FOR_CODEC.
169 class CodecConfig : public base::RefCountedThreadSafe<CodecConfig> {
170 public:
171 CodecConfig();
172
173 // Codec type. Used when we configure media codec.
174 media::VideoCodec codec_ = media::kUnknownVideoCodec;
175
176 // Whether encryption scheme requires to use protected surface.
177 bool needs_protected_surface_ = false;
178
179 // The surface that MediaCodec is configured to output to. It's created by
180 // the backing strategy.
181 gfx::ScopedJavaSurface surface_;
182
183 // The MediaCrypto object is used in the MediaCodec.configure() in case of
184 // an encrypted stream.
185 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto_;
186
187 // Initial coded size. The actual size might change at any time, so this
188 // is only a hint.
189 gfx::Size initial_expected_coded_size_;
190
191 protected:
192 friend class base::RefCountedThreadSafe<CodecConfig>;
193 virtual ~CodecConfig();
194
195 private:
196 DISALLOW_COPY_AND_ASSIGN(CodecConfig);
197 };
198
199 // Configures |media_codec_| with the given codec parameters from the client.
200 // This configuration will (probably) not be complete before this call
201 // returns. Multiple calls before completion will be ignored. |state_|
202 // must be NO_ERROR or WAITING_FOR_CODEC. Note that, once you call this,
203 // you should be careful to avoid modifying members of |codec_config_| until
204 // |state_| is no longer WAITING_FOR_CODEC.
205 void ConfigureMediaCodecAsynchronously();
206
207 // Like ConfigureMediaCodecAsynchronously, but synchronous. Returns true if
208 // and only if |media_codec_| is non-null. Since all configuration is done
209 // synchronously, there is no concern with modifying |codec_config_| after
210 // this returns.
211 bool ConfigureMediaCodecSynchronously();
212
213 // Instantiate a media codec using |codec_config|.
214 // This may be called on any thread.
215 static std::unique_ptr<media::VideoCodecBridge>
216 ConfigureMediaCodecOnAnyThread(scoped_refptr<CodecConfig> codec_config);
217
218 // Called on the main thread to update |media_codec_| and complete codec
219 // configuration. |media_codec| will be null if configuration failed.
220 void OnCodecConfigured(std::unique_ptr<media::VideoCodecBridge> media_codec);
221
222 // Sends the decoded frame specified by |codec_buffer_index| to the client.
223 void SendDecodedFrameToClient(int32_t codec_buffer_index,
224 int32_t bitstream_id);
225
226 // Does pending IO tasks if any. Once this is called, it polls |media_codec_|
227 // until it finishes pending tasks. For the polling, |kDecodePollDelay| is
228 // used.
229 void DoIOTask(bool start_timer);
230
231 // Feeds input data to |media_codec_|. This checks
232 // |pending_bitstream_buffers_| and queues a buffer to |media_codec_|.
233 // Returns true if any input was processed.
234 bool QueueInput();
235
236 // Dequeues output from |media_codec_| and feeds the decoded frame to the
237 // client. Returns a hint about whether calling again might produce
238 // more output.
239 bool DequeueOutput();
240
241 // Requests picture buffers from the client.
242 void RequestPictureBuffers();
243
244 // Decode the content in the |bitstream_buffer|. Note that a
245 // |bitstream_buffer| of id as -1 indicates a flush command.
246 void DecodeBuffer(const media::BitstreamBuffer& bitstream_buffer);
247
248 // This callback is called after CDM obtained a MediaCrypto object.
249 void OnMediaCryptoReady(
250 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
251 bool needs_protected_surface);
252
253 // This callback is called when a new key is added to CDM.
254 void OnKeyAdded();
255
256 // Notifies the client of the result of deferred initialization.
257 void NotifyInitializationComplete(bool success);
258
259 // Notifies the client about the availability of a picture.
260 void NotifyPictureReady(const media::Picture& picture);
261
262 // Notifies the client that the input buffer identifed by input_buffer_id has
263 // been processed.
264 void NotifyEndOfBitstreamBuffer(int input_buffer_id);
265
266 // Notifies the client that the decoder was flushed.
267 void NotifyFlushDone();
268
269 // Notifies the client that the decoder was reset.
270 void NotifyResetDone();
271
272 // Notifies about decoding errors.
273 // Note: you probably don't want to call this directly. Use PostError or
274 // RETURN_ON_FAILURE, since we can defer error reporting to keep the pipeline
275 // from breaking. NotifyError will do so immediately, PostError may wait.
276 // |token| has to match |error_sequence_token_|, or else it's assumed to be
277 // from a post that's prior to a previous reset, and ignored.
278 void NotifyError(media::VideoDecodeAccelerator::Error error, int token);
279
280 // Start or stop our work-polling timer based on whether we did any work, and
281 // how long it has been since we've done work. Calling this with true will
282 // start the timer. Calling it with false may stop the timer.
283 void ManageTimer(bool did_work);
284
285 // Resets MediaCodec and buffers/containers used for storing output. These
286 // components need to be reset upon EOS to decode a later stream. Input state
287 // (e.g. queued BitstreamBuffers) is not reset, as input following an EOS
288 // is still valid and should be processed.
289 void ResetCodecState();
290
291 // Return true if and only if we should use deferred rendering.
292 static bool UseDeferredRenderingStrategy(
293 const gpu::GpuPreferences& gpu_preferences);
294
295 // Used to DCHECK that we are called on the correct thread.
296 base::ThreadChecker thread_checker_;
297
298 // To expose client callbacks from VideoDecodeAccelerator.
299 Client* client_;
300
301 // Callback to set the correct gl context.
302 MakeGLContextCurrentCallback make_context_current_cb_;
303
304 // Callback to get the GLES2Decoder instance.
305 GetGLES2DecoderCallback get_gles2_decoder_cb_;
306
307 // Whether the stream is encrypted.
308 bool is_encrypted_;
309
310 // The current state of this class. For now, this is used only for setting
311 // error state.
312 State state_;
313
314 // This map maintains the picture buffers passed to the client for decoding.
315 // The key is the picture buffer id.
316 OutputBufferMap output_picture_buffers_;
317
318 // This keeps the free picture buffer ids which can be used for sending
319 // decoded frames to the client.
320 std::queue<int32_t> free_picture_ids_;
321
322 // The low-level decoder which Android SDK provides.
323 std::unique_ptr<media::VideoCodecBridge> media_codec_;
324
325 // Set to true after requesting picture buffers to the client.
326 bool picturebuffers_requested_;
327
328 // The resolution of the stream.
329 gfx::Size size_;
330
331 // Encoded bitstream buffers to be passed to media codec, queued until an
332 // input buffer is available.
333 std::queue<media::BitstreamBuffer> pending_bitstream_buffers_;
334
335 // A map of presentation timestamp to bitstream buffer id for the bitstream
336 // buffers that have been submitted to the decoder but haven't yet produced an
337 // output frame with the same timestamp. Note: there will only be one entry
338 // for multiple bitstream buffers that have the same presentation timestamp.
339 std::map<base::TimeDelta, int32_t> bitstream_buffers_in_decoder_;
340
341 // Keeps track of bitstream ids notified to the client with
342 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
343 std::list<int32_t> bitstreams_notified_in_advance_;
344
345 // Backing strategy that we'll use to connect PictureBuffers to frames.
346 std::unique_ptr<BackingStrategy> strategy_;
347
348 // Helper class that manages asynchronous OnFrameAvailable callbacks.
349 class OnFrameAvailableHandler;
350 scoped_refptr<OnFrameAvailableHandler> on_frame_available_handler_;
351
352 // Time at which we last did useful work on io_timer_.
353 base::TimeTicks most_recent_work_;
354
355 // CDM related stuff.
356
357 // Holds a ref-count to the CDM to avoid using the CDM after it's destroyed.
358 scoped_refptr<media::MediaKeys> cdm_for_reference_holding_only_;
359
360 media::MediaDrmBridgeCdmContext* media_drm_bridge_cdm_context_;
361
362 // MediaDrmBridge requires registration/unregistration of the player, this
363 // registration id is used for this.
364 int cdm_registration_id_;
365
366 // Configuration that we use for MediaCodec.
367 // Do not update any of its members while |state_| is WAITING_FOR_CODEC.
368 scoped_refptr<CodecConfig> codec_config_;
369
370 // Index of the dequeued and filled buffer that we keep trying to enqueue.
371 // Such buffer appears in MEDIA_CODEC_NO_KEY processing.
372 int pending_input_buf_index_;
373
374 // Monotonically increasing value that is used to prevent old, delayed errors
375 // from being sent after a reset.
376 int error_sequence_token_;
377
378 // PostError will defer sending an error if and only if this is true.
379 bool defer_errors_;
380
381 // True if and only if VDA initialization is deferred, and we have not yet
382 // called NotifyInitializationComplete.
383 bool deferred_initialization_pending_;
384
385 // WeakPtrFactory for posting tasks back to |this|.
386 base::WeakPtrFactory<AndroidVideoDecodeAccelerator> weak_this_factory_;
387
388 friend class AndroidVideoDecodeAcceleratorTest;
389 };
390
391 } // namespace content
392
393 #endif // CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_DECODE_ACCELERATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698