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

Side by Side Diff: media/gpu/android/media_codec_video_decoder.h

Issue 2549643002: media: Add MediaCodecVideoDecoder (as a copy of AVDA initially) (Closed)
Patch Set: update copyright 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 | « no previous file | media/gpu/android/media_codec_video_decoder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef MEDIA_GPU_ANDROID_MEDIA_CODEC_VIDEO_DECODER_H_
6 #define MEDIA_GPU_ANDROID_MEDIA_CODEC_VIDEO_DECODER_H_
7
8 #include <stdint.h>
9
10 #include <list>
11 #include <map>
12 #include <queue>
13 #include <vector>
14
15 #include "base/compiler_specific.h"
16 #include "base/optional.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/timer/timer.h"
19 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
20 #include "gpu/command_buffer/service/gpu_preferences.h"
21 #include "media/base/android/media_drm_bridge_cdm_context.h"
22 #include "media/base/android/sdk_media_codec_bridge.h"
23 #include "media/base/media_keys.h"
24 #include "media/gpu/avda_codec_allocator.h"
25 #include "media/gpu/avda_picture_buffer_manager.h"
26 #include "media/gpu/gpu_video_decode_accelerator_helpers.h"
27 #include "media/gpu/media_gpu_export.h"
28 #include "media/video/video_decode_accelerator.h"
29 #include "ui/gl/android/scoped_java_surface.h"
30
31 namespace media {
32 class SharedMemoryRegion;
33
34 // A VideoDecodeAccelerator implementation for Android. This class decodes the
35 // encded input stream using Android's MediaCodec. It handles the work of
36 // transferring data to and from MediaCodec, and delegates attaching MediaCodec
37 // output buffers to PictureBuffers to AVDAPictureBufferManager.
38 class MEDIA_GPU_EXPORT MediaCodecVideoDecoder
39 : public VideoDecodeAccelerator,
40 public AVDACodecAllocatorClient {
41 public:
42 static VideoDecodeAccelerator::Capabilities GetCapabilities(
43 const gpu::GpuPreferences& gpu_preferences);
44
45 MediaCodecVideoDecoder(
46 const MakeGLContextCurrentCallback& make_context_current_cb,
47 const GetGLES2DecoderCallback& get_gles2_decoder_cb);
48
49 ~MediaCodecVideoDecoder() override;
50
51 // VideoDecodeAccelerator implementation:
52 bool Initialize(const Config& config, Client* client) override;
53 void Decode(const BitstreamBuffer& bitstream_buffer) override;
54 void AssignPictureBuffers(const std::vector<PictureBuffer>& buffers) override;
55 void ReusePictureBuffer(int32_t picture_buffer_id) override;
56 void Flush() override;
57 void Reset() override;
58 void SetSurface(int32_t surface_id) override;
59 void Destroy() override;
60 bool TryToSetupDecodeOnSeparateThread(
61 const base::WeakPtr<Client>& decode_client,
62 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
63 override;
64
65 // AVDACodecAllocatorClient implementation:
66 void OnSurfaceAvailable(bool success) override;
67 void OnSurfaceDestroyed() override;
68 void OnCodecConfigured(
69 std::unique_ptr<VideoCodecBridge> media_codec) override;
70
71 private:
72 friend class MCVDManager;
73
74 // TODO(timav): evaluate the need for more states in the MCVD state machine.
75 enum State {
76 NO_ERROR,
77 ERROR,
78 // Set when we are asynchronously constructing the codec. Will transition
79 // to NO_ERROR or ERROR depending on success.
80 WAITING_FOR_CODEC,
81 // Set when we have a codec, but it doesn't yet have a key.
82 WAITING_FOR_KEY,
83 // The output surface was destroyed. We must not configure a new MediaCodec
84 // with the destroyed surface.
85 SURFACE_DESTROYED,
86 };
87
88 enum DrainType {
89 DRAIN_TYPE_NONE,
90 DRAIN_FOR_FLUSH,
91 DRAIN_FOR_RESET,
92 DRAIN_FOR_DESTROY,
93 };
94
95 // Initialize of the picture buffer manager. This is to be called when the
96 // SurfaceView in |surface_id_|, if any, is no longer busy. It will return
97 // false on failure, and true if initialization was successful. This includes
98 // synchronous and asynchronous init; the MCVD might not yet have a codec on
99 // success, but async init will at least be in progress.
100 bool InitializePictureBufferManager();
101
102 // A part of destruction process that is sometimes postponed after the drain.
103 void ActualDestroy();
104
105 // Configures |media_codec_| with the given codec parameters from the client.
106 // This configuration will (probably) not be complete before this call
107 // returns. Multiple calls before completion will be ignored. |state_|
108 // must be NO_ERROR or WAITING_FOR_CODEC. Note that, once you call this,
109 // you should be careful to avoid modifying members of |codec_config_| until
110 // |state_| is no longer WAITING_FOR_CODEC.
111 void ConfigureMediaCodecAsynchronously();
112
113 // Like ConfigureMediaCodecAsynchronously, but synchronous. Returns true if
114 // and only if |media_codec_| is non-null. Since all configuration is done
115 // synchronously, there is no concern with modifying |codec_config_| after
116 // this returns.
117 bool ConfigureMediaCodecSynchronously();
118
119 // Instantiate a media codec using |codec_config|.
120 // This may be called on any thread.
121 static std::unique_ptr<VideoCodecBridge> ConfigureMediaCodecOnAnyThread(
122 scoped_refptr<CodecConfig> codec_config);
123
124 // Sends the decoded frame specified by |codec_buffer_index| to the client.
125 void SendDecodedFrameToClient(int32_t codec_buffer_index,
126 int32_t bitstream_id);
127
128 // Does pending IO tasks if any. Once this is called, it polls |media_codec_|
129 // until it finishes pending tasks. For the polling, |kDecodePollDelay| is
130 // used.
131 void DoIOTask(bool start_timer);
132
133 // Feeds input data to |media_codec_|. This checks
134 // |pending_bitstream_buffers_| and queues a buffer to |media_codec_|.
135 // Returns true if any input was processed.
136 bool QueueInput();
137
138 // Dequeues output from |media_codec_| and feeds the decoded frame to the
139 // client. Returns a hint about whether calling again might produce
140 // more output.
141 bool DequeueOutput();
142
143 // Requests picture buffers from the client.
144 void RequestPictureBuffers();
145
146 // Decode the content in the |bitstream_buffer|. Note that a
147 // |bitstream_buffer| of id as -1 indicates a flush command.
148 void DecodeBuffer(const BitstreamBuffer& bitstream_buffer);
149
150 // Called during Initialize() for encrypted streams to set up the CDM.
151 void InitializeCdm();
152
153 // Called after the CDM obtains a MediaCrypto object.
154 void OnMediaCryptoReady(MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
155 bool needs_protected_surface);
156
157 // Called when a new key is added to the CDM.
158 void OnKeyAdded();
159
160 // Notifies the client of the result of deferred initialization.
161 void NotifyInitializationComplete(bool success);
162
163 // Notifies the client about the availability of a picture.
164 void NotifyPictureReady(const Picture& picture);
165
166 // Notifies the client that the input buffer identifed by input_buffer_id has
167 // been processed.
168 void NotifyEndOfBitstreamBuffer(int input_buffer_id);
169
170 // Notifies the client that the decoder was flushed.
171 void NotifyFlushDone();
172
173 // Notifies the client that the decoder was reset.
174 void NotifyResetDone();
175
176 // Notifies the client about the error and sets |state_| to |ERROR|.
177 void NotifyError(Error error);
178
179 // Start or stop our work-polling timer based on whether we did any work, and
180 // how long it has been since we've done work. Calling this with true will
181 // start the timer. Calling it with false may stop the timer.
182 void ManageTimer(bool did_work);
183
184 // Start the MediaCodec drain process by adding end_of_stream() buffer to the
185 // encoded buffers queue. When we receive EOS from the output buffer the drain
186 // process completes and we perform the action depending on the |drain_type|.
187 void StartCodecDrain(DrainType drain_type);
188
189 // Returns true if we are currently draining the codec and doing that as part
190 // of Reset() or Destroy() VP8 workaround. (http://crbug.com/598963). We won't
191 // display any frames and disable normal errors handling.
192 bool IsDrainingForResetOrDestroy() const;
193
194 // A helper method that performs the operation required after the drain
195 // completion (usually when we receive EOS in the output). The operation
196 // itself depends on the |drain_type_|.
197 void OnDrainCompleted();
198
199 // Resets MediaCodec and buffers/containers used for storing output. These
200 // components need to be reset upon EOS to decode a later stream. Input state
201 // (e.g. queued BitstreamBuffers) is not reset, as input following an EOS
202 // is still valid and should be processed.
203 void ResetCodecState();
204
205 // Indicates if MediaCodec should not be used for software decoding since we
206 // have safer versions elsewhere.
207 bool IsMediaCodecSoftwareDecodingForbidden() const;
208
209 // On platforms which support seamless surface changes, this will reinitialize
210 // the picture buffer manager with the new surface. This function reads and
211 // clears the surface id from |pending_surface_id_|. It will issue a decode
212 // error if the surface change fails. Returns false on failure.
213 bool UpdateSurface();
214
215 // Used to DCHECK that we are called on the correct thread.
216 base::ThreadChecker thread_checker_;
217
218 // To expose client callbacks from VideoDecodeAccelerator.
219 Client* client_;
220
221 // Callback to set the correct gl context.
222 MakeGLContextCurrentCallback make_context_current_cb_;
223
224 // Callback to get the GLES2Decoder instance.
225 GetGLES2DecoderCallback get_gles2_decoder_cb_;
226
227 // The current state of this class. For now, this is used only for setting
228 // error state.
229 State state_;
230
231 // The assigned picture buffers by picture buffer id.
232 AVDAPictureBufferManager::PictureBufferMap output_picture_buffers_;
233
234 // This keeps the free picture buffer ids which can be used for sending
235 // decoded frames to the client.
236 std::queue<int32_t> free_picture_ids_;
237
238 // The low-level decoder which Android SDK provides.
239 std::unique_ptr<VideoCodecBridge> media_codec_;
240
241 // Set to true after requesting picture buffers to the client.
242 bool picturebuffers_requested_;
243
244 // The resolution of the stream.
245 gfx::Size size_;
246
247 // Handy structure to remember a BitstreamBuffer and also its shared memory,
248 // if any. The goal is to prevent leaving a BitstreamBuffer's shared memory
249 // handle open.
250 struct BitstreamRecord {
251 BitstreamRecord(const BitstreamBuffer&);
252 BitstreamRecord(BitstreamRecord&& other);
253 ~BitstreamRecord();
254
255 BitstreamBuffer buffer;
256
257 // |memory| is not mapped, and may be null if buffer has no data.
258 std::unique_ptr<SharedMemoryRegion> memory;
259 };
260
261 // Encoded bitstream buffers to be passed to media codec, queued until an
262 // input buffer is available.
263 std::queue<BitstreamRecord> pending_bitstream_records_;
264
265 // A map of presentation timestamp to bitstream buffer id for the bitstream
266 // buffers that have been submitted to the decoder but haven't yet produced an
267 // output frame with the same timestamp. Note: there will only be one entry
268 // for multiple bitstream buffers that have the same presentation timestamp.
269 std::map<base::TimeDelta, int32_t> bitstream_buffers_in_decoder_;
270
271 // Keeps track of bitstream ids notified to the client with
272 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
273 std::list<int32_t> bitstreams_notified_in_advance_;
274
275 AVDAPictureBufferManager picture_buffer_manager_;
276
277 // Time at which we last did useful work on io_timer_.
278 base::TimeTicks most_recent_work_;
279
280 // Type of a drain request. We need to distinguish between DRAIN_FOR_FLUSH
281 // and other types, see IsDrainingForResetOrDestroy().
282 DrainType drain_type_;
283
284 // Holds a ref-count to the CDM to avoid using the CDM after it's destroyed.
285 scoped_refptr<MediaKeys> cdm_for_reference_holding_only_;
286
287 MediaDrmBridgeCdmContext* media_drm_bridge_cdm_context_;
288
289 // MediaDrmBridge requires registration/unregistration of the player, this
290 // registration id is used for this.
291 int cdm_registration_id_;
292
293 // Configuration that we use for MediaCodec.
294 // Do not update any of its members while |state_| is WAITING_FOR_CODEC.
295 scoped_refptr<CodecConfig> codec_config_;
296
297 // Index of the dequeued and filled buffer that we keep trying to enqueue.
298 // Such buffer appears in MEDIA_CODEC_NO_KEY processing.
299 int pending_input_buf_index_;
300
301 // Monotonically increasing value that is used to prevent old, delayed errors
302 // from being sent after a reset.
303 int error_sequence_token_;
304
305 // True if and only if VDA initialization is deferred, and we have not yet
306 // called NotifyInitializationComplete.
307 bool deferred_initialization_pending_;
308
309 // Indicates if ResetCodecState() should be called upon the next call to
310 // Decode(). Allows us to avoid trashing the last few frames of a playback
311 // when the EOS buffer is received.
312 bool codec_needs_reset_;
313
314 // True if surface creation and |picture_buffer_manager_| initialization has
315 // been defered until the first Decode() call.
316 bool defer_surface_creation_;
317
318 // Has a value if a SetSurface() call has occurred and a new surface should be
319 // switched to when possible. Cleared during OnSurfaceDestroyed() and if all
320 // pictures have been rendered in DequeueOutput().
321 base::Optional<int32_t> pending_surface_id_;
322
323 // Copy of the VDA::Config we were given.
324 Config config_;
325
326 // WeakPtrFactory for posting tasks back to |this|.
327 base::WeakPtrFactory<MediaCodecVideoDecoder> weak_this_factory_;
328
329 friend class MediaCodecVideoDecoderTest;
330 };
331
332 } // namespace media
333
334 #endif // MEDIA_GPU_ANDROID_MEDIA_CODEC_VIDEO_DECODER_H_
OLDNEW
« no previous file with comments | « no previous file | media/gpu/android/media_codec_video_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698