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

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

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 | « media/gpu/android/media_codec_video_decoder.h ('k') | no next file » | 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 (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 #include "media/gpu/android/media_codec_video_decoder.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10
11 #include "base/android/build_info.h"
12 #include "base/auto_reset.h"
13 #include "base/bind.h"
14 #include "base/bind_helpers.h"
15 #include "base/callback_helpers.h"
16 #include "base/command_line.h"
17 #include "base/lazy_instance.h"
18 #include "base/logging.h"
19 #include "base/message_loop/message_loop.h"
20 #include "base/metrics/histogram.h"
21 #include "base/sys_info.h"
22 #include "base/task_runner_util.h"
23 #include "base/threading/thread.h"
24 #include "base/threading/thread_checker.h"
25 #include "base/threading/thread_task_runner_handle.h"
26 #include "base/trace_event/trace_event.h"
27 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
28 #include "gpu/command_buffer/service/mailbox_manager.h"
29 #include "gpu/ipc/service/gpu_channel.h"
30 #include "media/base/android/media_codec_bridge.h"
31 #include "media/base/android/media_codec_util.h"
32 #include "media/base/bind_to_current_loop.h"
33 #include "media/base/bitstream_buffer.h"
34 #include "media/base/limits.h"
35 #include "media/base/media.h"
36 #include "media/base/timestamp_constants.h"
37 #include "media/base/video_decoder_config.h"
38 #include "media/gpu/avda_picture_buffer_manager.h"
39 #include "media/gpu/shared_memory_region.h"
40 #include "media/video/picture.h"
41 #include "ui/gl/android/scoped_java_surface.h"
42 #include "ui/gl/android/surface_texture.h"
43 #include "ui/gl/gl_bindings.h"
44
45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
46 #include "media/mojo/services/mojo_cdm_service.h"
47 #endif
48
49 #define NOTIFY_ERROR(error_code, error_message) \
50 do { \
51 DLOG(ERROR) << error_message; \
52 NotifyError(VideoDecodeAccelerator::error_code); \
53 } while (0)
54
55 namespace media {
56
57 namespace {
58
59 enum { kNumPictureBuffers = limits::kMaxVideoFrames + 1 };
60
61 // Max number of bitstreams notified to the client with
62 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
63 enum { kMaxBitstreamsNotifiedInAdvance = 32 };
64
65 // MediaCodec is only guaranteed to support baseline, but some devices may
66 // support others. Advertise support for all H264 profiles and let the
67 // MediaCodec fail when decoding if it's not actually supported. It's assumed
68 // that consumers won't have software fallback for H264 on Android anyway.
69 constexpr VideoCodecProfile kSupportedH264Profiles[] = {
70 H264PROFILE_BASELINE,
71 H264PROFILE_MAIN,
72 H264PROFILE_EXTENDED,
73 H264PROFILE_HIGH,
74 H264PROFILE_HIGH10PROFILE,
75 H264PROFILE_HIGH422PROFILE,
76 H264PROFILE_HIGH444PREDICTIVEPROFILE,
77 H264PROFILE_SCALABLEBASELINE,
78 H264PROFILE_SCALABLEHIGH,
79 H264PROFILE_STEREOHIGH,
80 H264PROFILE_MULTIVIEWHIGH};
81
82 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
83 constexpr VideoCodecProfile kSupportedHevcProfiles[] = {HEVCPROFILE_MAIN,
84 HEVCPROFILE_MAIN10};
85 #endif
86
87 // Because MediaCodec is thread-hostile (must be poked on a single thread) and
88 // has no callback mechanism (b/11990118), we must drive it by polling for
89 // complete frames (and available input buffers, when the codec is fully
90 // saturated). This function defines the polling delay. The value used is an
91 // arbitrary choice that trades off CPU utilization (spinning) against latency.
92 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay().
93 //
94 // An alternative to this polling scheme could be to dedicate a new thread
95 // (instead of using the ChildThread) to run the MediaCodec, and make that
96 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it
97 // believes the codec should complete "soon" (e.g. waiting for an input
98 // buffer, or waiting for a picture when it knows enough complete input
99 // pictures have been fed to saturate any internal buffering). This is
100 // speculative and it's unclear that this would be a win (nor that there's a
101 // reasonably device-agnostic way to fill in the "believes" above).
102 constexpr base::TimeDelta DecodePollDelay =
103 base::TimeDelta::FromMilliseconds(10);
104
105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0);
106
107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1);
108
109 // On low end devices (< KitKat is always low-end due to buggy MediaCodec),
110 // defer the surface creation until the codec is actually used if we know no
111 // software fallback exists.
112 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) {
113 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 &&
114 AVDACodecAllocator::Instance()->IsAnyRegisteredAVDA() &&
115 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 ||
116 base::SysInfo::IsLowEndDevice());
117 }
118
119 } // namespace
120
121 // MCVDManager manages shared resources for a number of MCVD instances.
122 // Its responsibilities include:
123 // - Starting and stopping a shared "construction" thread for instantiating and
124 // releasing MediaCodecs.
125 // - Detecting when a task has hung on the construction thread so MCVDs can
126 // stop using it.
127 // - Running a RepeatingTimer so that MCVDs can get a regular callback to
128 // DoIOTask().
129 // - Tracking the allocation of surfaces to MCVDs and delivering callbacks when
130 // surfaces are released.
131 class MCVDManager {
132 public:
133 // Request periodic callback of |mcvd|->DoIOTask(). Does nothing if the
134 // instance is already registered and the timer started. The first request
135 // will start the repeating timer on an interval of DecodePollDelay.
136 void StartTimer(MediaCodecVideoDecoder* mcvd) {
137 DCHECK(thread_checker_.CalledOnValidThread());
138
139 timer_mcvd_instances_.insert(mcvd);
140
141 // If the timer is running, StopTimer() might have been called earlier, if
142 // so remove the instance from the pending erasures.
143 if (timer_running_)
144 pending_erase_.erase(mcvd);
145
146 if (io_timer_.IsRunning())
147 return;
148 io_timer_.Start(FROM_HERE, DecodePollDelay, this, &MCVDManager::RunTimer);
149 }
150
151 // Stop callbacks to |mcvd|->DoIOTask(). Does nothing if the instance is not
152 // registered. If there are no instances left, the repeating timer will be
153 // stopped.
154 void StopTimer(MediaCodecVideoDecoder* mcvd) {
155 DCHECK(thread_checker_.CalledOnValidThread());
156
157 // If the timer is running, defer erasures to avoid iterator invalidation.
158 if (timer_running_) {
159 pending_erase_.insert(mcvd);
160 return;
161 }
162
163 timer_mcvd_instances_.erase(mcvd);
164 if (timer_mcvd_instances_.empty())
165 io_timer_.Stop();
166 }
167
168 private:
169 friend struct base::DefaultLazyInstanceTraits<MCVDManager>;
170
171 MCVDManager() {}
172 ~MCVDManager() { NOTREACHED(); }
173
174 void RunTimer() {
175 {
176 // Call out to all MCVD instances, some of which may attempt to remove
177 // themselves from the list during this operation; those removals will be
178 // deferred until after all iterations are complete.
179 base::AutoReset<bool> scoper(&timer_running_, true);
180 for (auto* mcvd : timer_mcvd_instances_)
181 mcvd->DoIOTask(false);
182 }
183
184 // Take care of any deferred erasures.
185 for (auto* mcvd : pending_erase_)
186 StopTimer(mcvd);
187 pending_erase_.clear();
188
189 // TODO(dalecurtis): We may want to consider chunking this if task execution
190 // takes too long for the combined timer.
191 }
192
193 // All MCVD instances that would like us to poll DoIOTask.
194 std::set<MediaCodecVideoDecoder*> timer_mcvd_instances_;
195
196 // Since we can't delete while iterating when using a set, defer erasure until
197 // after iteration complete.
198 bool timer_running_ = false;
199 std::set<MediaCodecVideoDecoder*> pending_erase_;
200
201 // Repeating timer responsible for draining pending IO to the codecs.
202 base::RepeatingTimer io_timer_;
203
204 base::ThreadChecker thread_checker_;
205
206 DISALLOW_COPY_AND_ASSIGN(MCVDManager);
207 };
208
209 static base::LazyInstance<MCVDManager>::Leaky g_mcvd_manager =
210 LAZY_INSTANCE_INITIALIZER;
211
212 MediaCodecVideoDecoder::BitstreamRecord::BitstreamRecord(
213 const BitstreamBuffer& bitstream_buffer)
214 : buffer(bitstream_buffer) {
215 if (buffer.id() != -1)
216 memory.reset(new SharedMemoryRegion(buffer, true));
217 }
218
219 MediaCodecVideoDecoder::BitstreamRecord::BitstreamRecord(
220 BitstreamRecord&& other)
221 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {}
222
223 MediaCodecVideoDecoder::BitstreamRecord::~BitstreamRecord() {}
224
225 MediaCodecVideoDecoder::MediaCodecVideoDecoder(
226 const MakeGLContextCurrentCallback& make_context_current_cb,
227 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
228 : client_(NULL),
229 make_context_current_cb_(make_context_current_cb),
230 get_gles2_decoder_cb_(get_gles2_decoder_cb),
231 state_(NO_ERROR),
232 picturebuffers_requested_(false),
233 picture_buffer_manager_(get_gles2_decoder_cb),
234 drain_type_(DRAIN_TYPE_NONE),
235 media_drm_bridge_cdm_context_(nullptr),
236 cdm_registration_id_(0),
237 pending_input_buf_index_(-1),
238 deferred_initialization_pending_(false),
239 codec_needs_reset_(false),
240 defer_surface_creation_(false),
241 weak_this_factory_(this) {}
242
243 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() {
244 DCHECK(thread_checker_.CalledOnValidThread());
245 g_mcvd_manager.Get().StopTimer(this);
246 AVDACodecAllocator::Instance()->StopThread(this);
247
248 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
249 if (!media_drm_bridge_cdm_context_)
250 return;
251
252 DCHECK(cdm_registration_id_);
253
254 // Cancel previously registered callback (if any).
255 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(
256 MediaDrmBridgeCdmContext::MediaCryptoReadyCB());
257
258 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_);
259 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
260 }
261
262 bool MediaCodecVideoDecoder::Initialize(const Config& config, Client* client) {
263 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString();
264 TRACE_EVENT0("media", "MCVD::Initialize");
265 DCHECK(!media_codec_);
266 DCHECK(thread_checker_.CalledOnValidThread());
267
268 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) {
269 DLOG(ERROR) << "GL callbacks are required for this VDA";
270 return false;
271 }
272
273 if (config.output_mode != Config::OutputMode::ALLOCATE) {
274 DLOG(ERROR) << "Only ALLOCATE OutputMode is supported by this VDA";
275 return false;
276 }
277
278 DCHECK(client);
279 client_ = client;
280 config_ = config;
281 codec_config_ = new CodecConfig();
282 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile);
283 codec_config_->initial_expected_coded_size_ =
284 config.initial_expected_coded_size;
285
286 if (codec_config_->codec_ != kCodecVP8 &&
287 codec_config_->codec_ != kCodecVP9 &&
288 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
289 codec_config_->codec_ != kCodecHEVC &&
290 #endif
291 codec_config_->codec_ != kCodecH264) {
292 DLOG(ERROR) << "Unsupported profile: " << config.profile;
293 return false;
294 }
295
296 if (codec_config_->codec_ == kCodecH264) {
297 codec_config_->csd0_ = config.sps;
298 codec_config_->csd1_ = config.pps;
299 }
300
301 // Only use MediaCodec for VP8/9 if it's likely backed by hardware
302 // or if the stream is encrypted.
303 if (IsMediaCodecSoftwareDecodingForbidden() &&
304 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_,
305 MEDIA_CODEC_DECODER)) {
306 DVLOG(1) << "Initialization failed: "
307 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9")
308 << " is not hardware accelerated";
309 return false;
310 }
311
312 auto gles_decoder = get_gles2_decoder_cb_.Run();
313 if (!gles_decoder) {
314 DLOG(ERROR) << "Failed to get gles2 decoder instance.";
315 return false;
316 }
317
318 // SetSurface() can't be called before Initialize(), so we pick up our first
319 // surface ID from the codec configuration.
320 DCHECK(!pending_surface_id_);
321
322 // If we're low on resources, we may decide to defer creation of the surface
323 // until the codec is actually used.
324 if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec_)) {
325 DCHECK(!deferred_initialization_pending_);
326 // We should never be here if a SurfaceView is required.
327 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID);
328 defer_surface_creation_ = true;
329 NotifyInitializationComplete(true);
330 return true;
331 }
332
333 // We signaled that we support deferred initialization, so see if the client
334 // does also.
335 deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
336 if (config_.is_encrypted && !deferred_initialization_pending_) {
337 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams";
338 return false;
339 }
340
341 if (AVDACodecAllocator::Instance()->AllocateSurface(this,
342 config_.surface_id)) {
343 // We now own the surface, so finish initialization.
344 return InitializePictureBufferManager();
345 }
346
347 // We have to wait for some other MCVD instance to free up the surface.
348 // OnSurfaceAvailable will be called when it's available.
349 return true;
350 }
351
352 void MediaCodecVideoDecoder::OnSurfaceAvailable(bool success) {
353 DCHECK(deferred_initialization_pending_);
354 DCHECK(!defer_surface_creation_);
355
356 if (!success || !InitializePictureBufferManager()) {
357 NotifyInitializationComplete(false);
358 deferred_initialization_pending_ = false;
359 }
360 }
361
362 bool MediaCodecVideoDecoder::InitializePictureBufferManager() {
363 if (!make_context_current_cb_.Run()) {
364 LOG(ERROR) << "Failed to make this decoder's GL context current.";
365 return false;
366 }
367
368 codec_config_->surface_ =
369 picture_buffer_manager_.Initialize(config_.surface_id);
370 if (codec_config_->surface_.IsEmpty())
371 return false;
372
373 if (!AVDACodecAllocator::Instance()->StartThread(this))
374 return false;
375
376 // If we are encrypted, then we aren't able to create the codec yet.
377 if (config_.is_encrypted) {
378 InitializeCdm();
379 return true;
380 }
381
382 if (deferred_initialization_pending_ || defer_surface_creation_) {
383 defer_surface_creation_ = false;
384 ConfigureMediaCodecAsynchronously();
385 return true;
386 }
387
388 // If the client doesn't support deferred initialization (WebRTC), then we
389 // should complete it now and return a meaningful result. Note that it would
390 // be nice if we didn't have to worry about starting codec configuration at
391 // all (::Initialize or the wrapper can do it), but then they have to remember
392 // not to start codec config if we have to wait for the cdm. It's somewhat
393 // clearer for us to handle both cases.
394 return ConfigureMediaCodecSynchronously();
395 }
396
397 void MediaCodecVideoDecoder::DoIOTask(bool start_timer) {
398 DCHECK(thread_checker_.CalledOnValidThread());
399 TRACE_EVENT0("media", "MCVD::DoIOTask");
400 if (state_ == ERROR || state_ == WAITING_FOR_CODEC ||
401 state_ == SURFACE_DESTROYED) {
402 return;
403 }
404
405 picture_buffer_manager_.MaybeRenderEarly();
406 bool did_work = false, did_input = false, did_output = false;
407 do {
408 did_input = QueueInput();
409 did_output = DequeueOutput();
410 if (did_input || did_output)
411 did_work = true;
412 } while (did_input || did_output);
413
414 ManageTimer(did_work || start_timer);
415 }
416
417 bool MediaCodecVideoDecoder::QueueInput() {
418 DCHECK(thread_checker_.CalledOnValidThread());
419 TRACE_EVENT0("media", "MCVD::QueueInput");
420 if (state_ == ERROR || state_ == WAITING_FOR_CODEC ||
421 state_ == WAITING_FOR_KEY) {
422 return false;
423 }
424 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
425 return false;
426 if (pending_bitstream_records_.empty())
427 return false;
428
429 int input_buf_index = pending_input_buf_index_;
430
431 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY.
432 // That status does not return this buffer back to the pool of
433 // available input buffers. We have to reuse it in QueueSecureInputBuffer().
434 if (input_buf_index == -1) {
435 MediaCodecStatus status =
436 media_codec_->DequeueInputBuffer(NoWaitTimeOut, &input_buf_index);
437 switch (status) {
438 case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER:
439 return false;
440 case MEDIA_CODEC_ERROR:
441 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueInputBuffer failed");
442 return false;
443 case MEDIA_CODEC_OK:
444 break;
445 default:
446 NOTREACHED();
447 return false;
448 }
449 }
450
451 DCHECK_NE(input_buf_index, -1);
452
453 BitstreamBuffer bitstream_buffer = pending_bitstream_records_.front().buffer;
454
455 if (bitstream_buffer.id() == -1) {
456 pending_bitstream_records_.pop();
457 TRACE_COUNTER1("media", "MCVD::PendingBitstreamBufferCount",
458 pending_bitstream_records_.size());
459
460 media_codec_->QueueEOS(input_buf_index);
461 return true;
462 }
463
464 std::unique_ptr<SharedMemoryRegion> shm;
465
466 if (pending_input_buf_index_ == -1) {
467 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
468 // from MediaCodec, filled with data and bitstream_buffer.handle() is
469 // closed.
470 shm = std::move(pending_bitstream_records_.front().memory);
471
472 if (!shm->Map()) {
473 NOTIFY_ERROR(UNREADABLE_INPUT, "SharedMemoryRegion::Map() failed");
474 return false;
475 }
476 }
477
478 const base::TimeDelta presentation_timestamp =
479 bitstream_buffer.presentation_timestamp();
480 DCHECK(presentation_timestamp != kNoTimestamp)
481 << "Bitstream buffers must have valid presentation timestamps";
482
483 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt
484 // ref frames, but it's OK to overwrite it because we only expect a single
485 // output frame to have that timestamp. MCVD clients only use the bitstream
486 // buffer id in the returned Pictures to map a bitstream buffer back to a
487 // timestamp on their side, so either one of the bitstream buffer ids will
488 // result in them finding the right timestamp.
489 bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id();
490
491 // Notice that |memory| will be null if we repeatedly enqueue the same buffer,
492 // this happens after MEDIA_CODEC_NO_KEY.
493 const uint8_t* memory =
494 shm ? static_cast<const uint8_t*>(shm->memory()) : nullptr;
495 const std::string& key_id = bitstream_buffer.key_id();
496 const std::string& iv = bitstream_buffer.iv();
497 const std::vector<SubsampleEntry>& subsamples = bitstream_buffer.subsamples();
498
499 MediaCodecStatus status;
500 if (key_id.empty() || iv.empty()) {
501 status = media_codec_->QueueInputBuffer(input_buf_index, memory,
502 bitstream_buffer.size(),
503 presentation_timestamp);
504 } else {
505 status = media_codec_->QueueSecureInputBuffer(
506 input_buf_index, memory, bitstream_buffer.size(), key_id, iv,
507 subsamples, presentation_timestamp);
508 }
509
510 DVLOG(2) << __FUNCTION__
511 << ": Queue(Secure)InputBuffer: pts:" << presentation_timestamp
512 << " status:" << status;
513
514 if (status == MEDIA_CODEC_NO_KEY) {
515 // Keep trying to enqueue the same input buffer.
516 // The buffer is owned by us (not the MediaCodec) and is filled with data.
517 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY";
518 pending_input_buf_index_ = input_buf_index;
519 state_ = WAITING_FOR_KEY;
520 return false;
521 }
522
523 pending_input_buf_index_ = -1;
524 pending_bitstream_records_.pop();
525 TRACE_COUNTER1("media", "MCVD::PendingBitstreamBufferCount",
526 pending_bitstream_records_.size());
527 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
528 // will be returned from the bitstream buffer. However, MediaCodec API is
529 // not enough to guarantee it.
530 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
531 // keep getting more bitstreams from the client, and throttle them by using
532 // |bitstreams_notified_in_advance_|.
533 // TODO(dwkang): check if there is a way to remove this workaround.
534 base::ThreadTaskRunnerHandle::Get()->PostTask(
535 FROM_HERE,
536 base::Bind(&MediaCodecVideoDecoder::NotifyEndOfBitstreamBuffer,
537 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
538 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
539
540 if (status != MEDIA_CODEC_OK) {
541 NOTIFY_ERROR(PLATFORM_FAILURE, "QueueInputBuffer failed:" << status);
542 return false;
543 }
544
545 return true;
546 }
547
548 bool MediaCodecVideoDecoder::DequeueOutput() {
549 DCHECK(thread_checker_.CalledOnValidThread());
550 TRACE_EVENT0("media", "MCVD::DequeueOutput");
551 if (state_ == ERROR || state_ == WAITING_FOR_CODEC)
552 return false;
553 // If we're draining for reset or destroy, then we don't need picture buffers
554 // since we won't send any decoded frames anyway. There might not be any,
555 // since the pipeline might not be sending them back and / or they don't
556 // exist anymore. From the pipeline's point of view, for Destroy at least,
557 // the VDA is already gone.
558 if (picturebuffers_requested_ && output_picture_buffers_.empty() &&
559 !IsDrainingForResetOrDestroy()) {
560 return false;
561 }
562 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() &&
563 !IsDrainingForResetOrDestroy()) {
564 // Don't have any picture buffer to send. Need to wait.
565 return false;
566 }
567
568 // If we're waiting to switch surfaces pause output release until we have all
569 // picture buffers returned. This is so we can ensure the right flags are set
570 // on the picture buffers returned to the client.
571 if (pending_surface_id_) {
572 if (picture_buffer_manager_.HasUnrenderedPictures())
573 return false;
574 if (!UpdateSurface())
575 return false;
576 }
577
578 bool eos = false;
579 base::TimeDelta presentation_timestamp;
580 int32_t buf_index = 0;
581 do {
582 size_t offset = 0;
583 size_t size = 0;
584
585 TRACE_EVENT_BEGIN0("media", "MCVD::DequeueOutput");
586 MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
587 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp,
588 &eos, NULL);
589 TRACE_EVENT_END2("media", "MCVD::DequeueOutput", "status", status,
590 "presentation_timestamp (ms)",
591 presentation_timestamp.InMilliseconds());
592
593 switch (status) {
594 case MEDIA_CODEC_ERROR:
595 // Do not post an error if we are draining for reset and destroy.
596 // Instead, run the drain completion task.
597 if (IsDrainingForResetOrDestroy()) {
598 DVLOG(1) << __FUNCTION__ << ": error while codec draining";
599 state_ = ERROR;
600 OnDrainCompleted();
601 } else {
602 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
603 }
604 return false;
605
606 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
607 return false;
608
609 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
610 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame
611 // size does not change. Therefore we have to keep track on the format
612 // even if draining, unless we are draining for destroy.
613 if (drain_type_ == DRAIN_FOR_DESTROY)
614 return true; // ignore
615
616 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) {
617 NOTIFY_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
618 return false;
619 }
620
621 DVLOG(3) << __FUNCTION__
622 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
623
624 // Don't request picture buffers if we already have some. This avoids
625 // having to dismiss the existing buffers which may actively reference
626 // decoded images. Breaking their connection to the decoded image will
627 // cause rendering of black frames. Instead, we let the existing
628 // PictureBuffers live on and we simply update their size the next time
629 // they're attached to an image of the new resolution. See the
630 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
631 if (output_picture_buffers_.empty() && !picturebuffers_requested_) {
632 picturebuffers_requested_ = true;
633 base::ThreadTaskRunnerHandle::Get()->PostTask(
634 FROM_HERE,
635 base::Bind(&MediaCodecVideoDecoder::RequestPictureBuffers,
636 weak_this_factory_.GetWeakPtr()));
637 return false;
638 }
639
640 return true;
641 }
642
643 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
644 break;
645
646 case MEDIA_CODEC_OK:
647 DCHECK_GE(buf_index, 0);
648 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
649 << " buf_index:" << buf_index << " offset:" << offset
650 << " size:" << size << " eos:" << eos;
651 break;
652
653 default:
654 NOTREACHED();
655 break;
656 }
657 } while (buf_index < 0);
658
659 if (eos) {
660 OnDrainCompleted();
661 return false;
662 }
663
664 if (IsDrainingForResetOrDestroy()) {
665 media_codec_->ReleaseOutputBuffer(buf_index, false);
666 return true;
667 }
668
669 if (!picturebuffers_requested_) {
670 // In 0.01% of playbacks MediaCodec returns a frame before FORMAT_CHANGED.
671 // Occurs on JB and M. (See the Media.MCVD.MissingFormatChanged histogram.)
672 media_codec_->ReleaseOutputBuffer(buf_index, false);
673 NOTIFY_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
674 return false;
675 }
676
677 // Get the bitstream buffer id from the timestamp.
678 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp);
679
680 if (it != bitstream_buffers_in_decoder_.end()) {
681 const int32_t bitstream_buffer_id = it->second;
682 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(),
683 ++it);
684 SendDecodedFrameToClient(buf_index, bitstream_buffer_id);
685
686 // Removes ids former or equal than the id from decoder. Note that
687 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder
688 // because of frame reordering issue. We just maintain this roughly and use
689 // it for throttling.
690 for (auto bitstream_it = bitstreams_notified_in_advance_.begin();
691 bitstream_it != bitstreams_notified_in_advance_.end();
692 ++bitstream_it) {
693 if (*bitstream_it == bitstream_buffer_id) {
694 bitstreams_notified_in_advance_.erase(
695 bitstreams_notified_in_advance_.begin(), ++bitstream_it);
696 break;
697 }
698 }
699 } else {
700 // Normally we assume that the decoder makes at most one output frame for
701 // each distinct input timestamp. However MediaCodecBridge uses timestamp
702 // correction and provides a non-decreasing timestamp sequence, which might
703 // result in timestamp duplicates. Discard the frame if we cannot get the
704 // corresponding buffer id.
705 DVLOG(3) << __FUNCTION__ << ": Releasing buffer with unexpected PTS: "
706 << presentation_timestamp;
707 media_codec_->ReleaseOutputBuffer(buf_index, false);
708 }
709
710 // We got a decoded frame, so try for another.
711 return true;
712 }
713
714 void MediaCodecVideoDecoder::SendDecodedFrameToClient(
715 int32_t codec_buffer_index,
716 int32_t bitstream_id) {
717 DCHECK(thread_checker_.CalledOnValidThread());
718 DCHECK_NE(bitstream_id, -1);
719 DCHECK(!free_picture_ids_.empty());
720 TRACE_EVENT0("media", "MCVD::SendDecodedFrameToClient");
721
722 if (!make_context_current_cb_.Run()) {
723 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
724 return;
725 }
726
727 int32_t picture_buffer_id = free_picture_ids_.front();
728 free_picture_ids_.pop();
729 TRACE_COUNTER1("media", "MCVD::FreePictureIds", free_picture_ids_.size());
730
731 const auto it = output_picture_buffers_.find(picture_buffer_id);
732 if (it == output_picture_buffers_.end()) {
733 NOTIFY_ERROR(PLATFORM_FAILURE,
734 "Can't find PictureBuffer id: " << picture_buffer_id);
735 return;
736 }
737
738 PictureBuffer& picture_buffer = it->second;
739 const bool size_changed = picture_buffer.size() != size_;
740 if (size_changed)
741 picture_buffer.set_size(size_);
742
743 const bool allow_overlay = picture_buffer_manager_.ArePicturesOverlayable();
744 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay);
745 // TODO(hubbe): Insert the correct color space. http://crbug.com/647725
746 Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_),
747 gfx::ColorSpace(), allow_overlay);
748 picture.set_size_changed(size_changed);
749
750 // Notify picture ready before calling UseCodecBufferForPictureBuffer() since
751 // that process may be slow and shouldn't delay delivery of the frame to the
752 // renderer. The picture is only used on the same thread as this method is
753 // called, so it is safe to do this.
754 NotifyPictureReady(picture);
755
756 // Connect the PictureBuffer to the decoded frame.
757 if (!picture_buffer_manager_.UseCodecBufferForPictureBuffer(
758 codec_buffer_index, picture_buffer, size_)) {
759 NOTIFY_ERROR(PLATFORM_FAILURE,
760 "Failed to attach the codec buffer to a picture buffer.");
761 }
762 }
763
764 void MediaCodecVideoDecoder::Decode(const BitstreamBuffer& bitstream_buffer) {
765 DCHECK(thread_checker_.CalledOnValidThread());
766
767 if (defer_surface_creation_ && !InitializePictureBufferManager()) {
768 NOTIFY_ERROR(PLATFORM_FAILURE,
769 "Failed deferred surface and MediaCodec initialization.");
770 return;
771 }
772
773 // If we previously deferred a codec restart, take care of it now. This can
774 // happen on older devices where configuration changes require a codec reset.
775 if (codec_needs_reset_) {
776 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE);
777 ResetCodecState();
778 }
779
780 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) {
781 DecodeBuffer(bitstream_buffer);
782 return;
783 }
784
785 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
786 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
787
788 if (bitstream_buffer.id() < 0) {
789 NOTIFY_ERROR(INVALID_ARGUMENT,
790 "Invalid bistream_buffer, id: " << bitstream_buffer.id());
791 } else {
792 base::ThreadTaskRunnerHandle::Get()->PostTask(
793 FROM_HERE,
794 base::Bind(&MediaCodecVideoDecoder::NotifyEndOfBitstreamBuffer,
795 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
796 }
797 }
798
799 void MediaCodecVideoDecoder::DecodeBuffer(
800 const BitstreamBuffer& bitstream_buffer) {
801 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer));
802 TRACE_COUNTER1("media", "MCVD::PendingBitstreamBufferCount",
803 pending_bitstream_records_.size());
804
805 DoIOTask(true);
806 }
807
808 void MediaCodecVideoDecoder::RequestPictureBuffers() {
809 if (client_) {
810 // Allocate a picture buffer that is the actual frame size. Note that it
811 // will be an external texture anyway, so it doesn't allocate an image of
812 // that size. It's important to get the coded size right, so that
813 // VideoLayerImpl doesn't try to scale the texture when building the quad
814 // for it.
815 client_->ProvidePictureBuffers(kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1,
816 size_,
817 AVDAPictureBufferManager::kTextureTarget);
818 }
819 }
820
821 void MediaCodecVideoDecoder::AssignPictureBuffers(
822 const std::vector<PictureBuffer>& buffers) {
823 DCHECK(thread_checker_.CalledOnValidThread());
824 DCHECK(output_picture_buffers_.empty());
825 DCHECK(free_picture_ids_.empty());
826
827 if (buffers.size() < kNumPictureBuffers) {
828 NOTIFY_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
829 return;
830 }
831
832 const bool have_context = make_context_current_cb_.Run();
833 LOG_IF(WARNING, !have_context)
834 << "Failed to make GL context current for Assign, continuing.";
835
836 for (size_t i = 0; i < buffers.size(); ++i) {
837 DCHECK(buffers[i].size() == size_);
838 int32_t id = buffers[i].id();
839 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
840 free_picture_ids_.push(id);
841
842 picture_buffer_manager_.AssignPictureBuffer(buffers[i], size_,
843 have_context);
844 }
845 TRACE_COUNTER1("media", "MCVD::FreePictureIds", free_picture_ids_.size());
846 DoIOTask(true);
847 }
848
849 void MediaCodecVideoDecoder::ReusePictureBuffer(int32_t picture_buffer_id) {
850 DCHECK(thread_checker_.CalledOnValidThread());
851
852 free_picture_ids_.push(picture_buffer_id);
853 TRACE_COUNTER1("media", "MCVD::FreePictureIds", free_picture_ids_.size());
854
855 auto it = output_picture_buffers_.find(picture_buffer_id);
856 if (it == output_picture_buffers_.end()) {
857 NOTIFY_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
858 << picture_buffer_id);
859 return;
860 }
861
862 picture_buffer_manager_.ReusePictureBuffer(it->second);
863 DoIOTask(true);
864 }
865
866 void MediaCodecVideoDecoder::Flush() {
867 DVLOG(1) << __FUNCTION__;
868 DCHECK(thread_checker_.CalledOnValidThread());
869
870 if (state_ == SURFACE_DESTROYED || defer_surface_creation_)
871 NotifyFlushDone();
872 else
873 StartCodecDrain(DRAIN_FOR_FLUSH);
874 }
875
876 void MediaCodecVideoDecoder::ConfigureMediaCodecAsynchronously() {
877 DCHECK(thread_checker_.CalledOnValidThread());
878
879 DCHECK_NE(state_, WAITING_FOR_CODEC);
880 state_ = WAITING_FOR_CODEC;
881
882 if (media_codec_) {
883 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
884 std::move(media_codec_), codec_config_->task_type_, config_.surface_id);
885 picture_buffer_manager_.CodecChanged(nullptr);
886 }
887
888 codec_config_->task_type_ =
889 AVDACodecAllocator::Instance()->TaskTypeForAllocation();
890 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) {
891 // If there is no free thread, then just fail.
892 OnCodecConfigured(nullptr);
893 return;
894 }
895
896 // If autodetection is disallowed, fall back to Chrome's software decoders
897 // instead of using the software decoders provided by MediaCodec.
898 if (codec_config_->task_type_ == TaskType::SW_CODEC &&
899 IsMediaCodecSoftwareDecodingForbidden()) {
900 OnCodecConfigured(nullptr);
901 return;
902 }
903
904 AVDACodecAllocator::Instance()->CreateMediaCodecAsync(
905 weak_this_factory_.GetWeakPtr(), codec_config_);
906 }
907
908 bool MediaCodecVideoDecoder::ConfigureMediaCodecSynchronously() {
909 DCHECK(thread_checker_.CalledOnValidThread());
910 DCHECK(!media_codec_);
911 DCHECK_NE(state_, WAITING_FOR_CODEC);
912 state_ = WAITING_FOR_CODEC;
913
914 codec_config_->task_type_ =
915 AVDACodecAllocator::Instance()->TaskTypeForAllocation();
916 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) {
917 OnCodecConfigured(nullptr);
918 return false;
919 }
920
921 std::unique_ptr<VideoCodecBridge> media_codec =
922 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_);
923 OnCodecConfigured(std::move(media_codec));
924 return !!media_codec_;
925 }
926
927 void MediaCodecVideoDecoder::OnCodecConfigured(
928 std::unique_ptr<VideoCodecBridge> media_codec) {
929 DCHECK(thread_checker_.CalledOnValidThread());
930 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED);
931
932 // If we are supposed to notify that initialization is complete, then do so
933 // now. Otherwise, this is a reconfiguration.
934 if (deferred_initialization_pending_) {
935 // Losing the output surface is not considered an error state, so notify
936 // success. The client will destroy this soon.
937 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true
938 : !!media_codec);
939 deferred_initialization_pending_ = false;
940 }
941
942 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec,
943 // then the codec is already invalid so we return early and drop it.
944 if (state_ == SURFACE_DESTROYED)
945 return;
946
947 DCHECK(!media_codec_);
948 media_codec_ = std::move(media_codec);
949 picture_buffer_manager_.CodecChanged(media_codec_.get());
950 if (!media_codec_) {
951 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec");
952 return;
953 }
954
955 state_ = NO_ERROR;
956
957 ManageTimer(true);
958 }
959
960 void MediaCodecVideoDecoder::StartCodecDrain(DrainType drain_type) {
961 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
962 DCHECK(thread_checker_.CalledOnValidThread());
963
964 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while
965 // another drain request is present, but DRAIN_FOR_DESTROY can.
966 DCHECK_NE(drain_type, DRAIN_TYPE_NONE);
967 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY)
968 << "Unexpected StartCodecDrain() with drain type " << drain_type
969 << " while already draining with drain type " << drain_type_;
970
971 const bool enqueue_eos = drain_type_ == DRAIN_TYPE_NONE;
972 drain_type_ = drain_type;
973
974 if (enqueue_eos)
975 DecodeBuffer(BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
976 }
977
978 bool MediaCodecVideoDecoder::IsDrainingForResetOrDestroy() const {
979 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY;
980 }
981
982 void MediaCodecVideoDecoder::OnDrainCompleted() {
983 DVLOG(2) << __FUNCTION__;
984 DCHECK(thread_checker_.CalledOnValidThread());
985
986 // If we were waiting for an EOS, clear the state and reset the MediaCodec
987 // as normal.
988 //
989 // Some Android platforms seem to send an EOS buffer even when we're not
990 // expecting it. In this case, destroy and reset the codec but don't notify
991 // flush done since it violates the state machine. http://crbug.com/585959.
992
993 switch (drain_type_) {
994 case DRAIN_TYPE_NONE:
995 // Unexpected EOS.
996 state_ = ERROR;
997 ResetCodecState();
998 break;
999 case DRAIN_FOR_FLUSH:
1000 ResetCodecState();
1001 base::ThreadTaskRunnerHandle::Get()->PostTask(
1002 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::NotifyFlushDone,
1003 weak_this_factory_.GetWeakPtr()));
1004 break;
1005 case DRAIN_FOR_RESET:
1006 ResetCodecState();
1007 base::ThreadTaskRunnerHandle::Get()->PostTask(
1008 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::NotifyResetDone,
1009 weak_this_factory_.GetWeakPtr()));
1010 break;
1011 case DRAIN_FOR_DESTROY:
1012 ResetCodecState();
1013 base::ThreadTaskRunnerHandle::Get()->PostTask(
1014 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::ActualDestroy,
1015 weak_this_factory_.GetWeakPtr()));
1016 break;
1017 }
1018 drain_type_ = DRAIN_TYPE_NONE;
1019 }
1020
1021 void MediaCodecVideoDecoder::ResetCodecState() {
1022 DCHECK(thread_checker_.CalledOnValidThread());
1023
1024 // If there is already a reset in flight, then that counts. This can really
1025 // only happen if somebody calls Reset.
1026 // If the surface is destroyed there's nothing to do.
1027 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED)
1028 return;
1029
1030 bitstream_buffers_in_decoder_.clear();
1031
1032 if (pending_input_buf_index_ != -1) {
1033 // The data for that index exists in the input buffer, but corresponding
1034 // shm block been deleted. Check that it is safe to flush the codec, i.e.
1035 // |pending_bitstream_records_| is empty.
1036 // TODO(timav): keep shm block for that buffer and remove this restriction.
1037 DCHECK(pending_bitstream_records_.empty());
1038 pending_input_buf_index_ = -1;
1039 }
1040
1041 const bool did_codec_error_happen = state_ == ERROR;
1042 state_ = NO_ERROR;
1043
1044 // Don't reset the codec here if there's no error and we're only flushing;
1045 // instead defer until the next decode call; this prevents us from unbacking
1046 // frames that might be out for display at end of stream.
1047 codec_needs_reset_ = false;
1048 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) {
1049 codec_needs_reset_ = true;
1050 return;
1051 }
1052
1053 // Flush the codec if possible, or create a new one if not.
1054 if (!did_codec_error_happen &&
1055 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) {
1056 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec.";
1057 media_codec_->Flush();
1058 // Since we just flushed all the output buffers, make sure that nothing is
1059 // using them.
1060 picture_buffer_manager_.CodecChanged(media_codec_.get());
1061 } else {
1062 DVLOG(3) << __FUNCTION__
1063 << " Deleting the MediaCodec and creating a new one.";
1064 g_mcvd_manager.Get().StopTimer(this);
1065 ConfigureMediaCodecAsynchronously();
1066 }
1067 }
1068
1069 void MediaCodecVideoDecoder::Reset() {
1070 DVLOG(1) << __FUNCTION__;
1071 DCHECK(thread_checker_.CalledOnValidThread());
1072 TRACE_EVENT0("media", "MCVD::Reset");
1073
1074 if (defer_surface_creation_) {
1075 DCHECK(!media_codec_);
1076 DCHECK(pending_bitstream_records_.empty());
1077 DCHECK_EQ(state_, NO_ERROR);
1078 base::ThreadTaskRunnerHandle::Get()->PostTask(
1079 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::NotifyResetDone,
1080 weak_this_factory_.GetWeakPtr()));
1081 return;
1082 }
1083
1084 while (!pending_bitstream_records_.empty()) {
1085 int32_t bitstream_buffer_id =
1086 pending_bitstream_records_.front().buffer.id();
1087 pending_bitstream_records_.pop();
1088
1089 if (bitstream_buffer_id != -1) {
1090 base::ThreadTaskRunnerHandle::Get()->PostTask(
1091 FROM_HERE,
1092 base::Bind(&MediaCodecVideoDecoder::NotifyEndOfBitstreamBuffer,
1093 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1094 }
1095 }
1096 TRACE_COUNTER1("media", "MCVD::PendingBitstreamBufferCount", 0);
1097 bitstreams_notified_in_advance_.clear();
1098
1099 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1100
1101 // Some VP8 files require complete MediaCodec drain before we can call
1102 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1103 if (media_codec_ && codec_config_->codec_ == kCodecVP8 &&
1104 !bitstream_buffers_in_decoder_.empty()) {
1105 // Postpone ResetCodecState() after the drain.
1106 StartCodecDrain(DRAIN_FOR_RESET);
1107 } else {
1108 ResetCodecState();
1109 base::ThreadTaskRunnerHandle::Get()->PostTask(
1110 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::NotifyResetDone,
1111 weak_this_factory_.GetWeakPtr()));
1112 }
1113 }
1114
1115 void MediaCodecVideoDecoder::SetSurface(int32_t surface_id) {
1116 DVLOG(1) << __func__;
1117 DCHECK(thread_checker_.CalledOnValidThread());
1118
1119 if (surface_id == config_.surface_id) {
1120 pending_surface_id_.reset();
1121 return;
1122 }
1123
1124 // Surface changes never take effect immediately, they will be handled during
1125 // DequeOutput() once we get to a good switch point or immediately during an
1126 // OnSurfaceDestroyed() call.
1127 pending_surface_id_ = surface_id;
1128 }
1129
1130 void MediaCodecVideoDecoder::Destroy() {
1131 DVLOG(1) << __FUNCTION__;
1132 DCHECK(thread_checker_.CalledOnValidThread());
1133
1134 picture_buffer_manager_.Destroy(output_picture_buffers_);
1135
1136 client_ = nullptr;
1137
1138 // Some VP8 files require a complete MediaCodec drain before we can call
1139 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In
1140 // that case, postpone ActualDestroy() until after the drain.
1141 if (media_codec_ && codec_config_->codec_ == kCodecVP8) {
1142 // Clear |pending_bitstream_records_|.
1143 while (!pending_bitstream_records_.empty())
1144 pending_bitstream_records_.pop();
1145
1146 StartCodecDrain(DRAIN_FOR_DESTROY);
1147 } else {
1148 ActualDestroy();
1149 }
1150 }
1151
1152 void MediaCodecVideoDecoder::ActualDestroy() {
1153 DVLOG(1) << __FUNCTION__;
1154 DCHECK(thread_checker_.CalledOnValidThread());
1155
1156 // Note that async codec construction might still be in progress. In that
1157 // case, the codec will be deleted when it completes once we invalidate all
1158 // our weak refs.
1159 weak_this_factory_.InvalidateWeakPtrs();
1160 g_mcvd_manager.Get().StopTimer(this);
1161 if (media_codec_) {
1162 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
1163 std::move(media_codec_), codec_config_->task_type_, config_.surface_id);
1164 }
1165
1166 // We no longer care about |surface_id|, in case we did before. It's okay
1167 // if we have no surface and/or weren't the owner or a waiter.
1168 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id);
1169
1170 delete this;
1171 }
1172
1173 bool MediaCodecVideoDecoder::TryToSetupDecodeOnSeparateThread(
1174 const base::WeakPtr<Client>& decode_client,
1175 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1176 return false;
1177 }
1178
1179 void MediaCodecVideoDecoder::OnSurfaceDestroyed() {
1180 DVLOG(1) << __func__;
1181 TRACE_EVENT0("media", "MCVD::OnSurfaceDestroyed");
1182 DCHECK(thread_checker_.CalledOnValidThread());
1183
1184 // If the API is available avoid having to restart the decoder in order to
1185 // leave fullscreen. If we don't clear the surface immediately during this
1186 // callback, the MediaCodec will throw an error as the surface is destroyed.
1187 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) {
1188 // Since we can't wait for a transition, we must invalidate all outstanding
1189 // picture buffers to avoid putting the GL system in a broken state.
1190 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1191
1192 // Switch away from the surface being destroyed to a surface texture.
1193 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID);
1194
1195 // The leaving fullscreen notification may come in before this point.
1196 if (pending_surface_id_)
1197 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID);
1198
1199 pending_surface_id_ = SurfaceManager::kNoSurfaceID;
1200 UpdateSurface();
1201 return;
1202 }
1203
1204 // If we're currently asynchronously configuring a codec, it will be destroyed
1205 // when configuration completes and it notices that |state_| has changed to
1206 // SURFACE_DESTROYED.
1207 state_ = SURFACE_DESTROYED;
1208 if (media_codec_) {
1209 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
1210 std::move(media_codec_), codec_config_->task_type_, config_.surface_id);
1211 picture_buffer_manager_.CodecChanged(nullptr);
1212 }
1213
1214 // If we're draining, signal completion now because the drain can no longer
1215 // proceed.
1216 if (drain_type_ != DRAIN_TYPE_NONE)
1217 OnDrainCompleted();
1218 }
1219
1220 void MediaCodecVideoDecoder::InitializeCdm() {
1221 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id;
1222
1223 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1224 NOTIMPLEMENTED();
1225 NotifyInitializationComplete(false);
1226 #else
1227 // Store the CDM to hold a reference to it.
1228 cdm_for_reference_holding_only_ =
1229 MojoCdmService::LegacyGetCdm(config_.cdm_id);
1230 DCHECK(cdm_for_reference_holding_only_);
1231
1232 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext.
1233 media_drm_bridge_cdm_context_ = static_cast<MediaDrmBridgeCdmContext*>(
1234 cdm_for_reference_holding_only_->GetCdmContext());
1235 DCHECK(media_drm_bridge_cdm_context_);
1236
1237 // Register CDM callbacks. The callbacks registered will be posted back to
1238 // this thread via BindToCurrentLoop.
1239
1240 // Since |this| holds a reference to the |cdm_|, by the time the CDM is
1241 // destructed, UnregisterPlayer() must have been called and |this| has been
1242 // destructed as well. So the |cdm_unset_cb| will never have a chance to be
1243 // called.
1244 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms.
1245 cdm_registration_id_ = media_drm_bridge_cdm_context_->RegisterPlayer(
1246 BindToCurrentLoop(base::Bind(&MediaCodecVideoDecoder::OnKeyAdded,
1247 weak_this_factory_.GetWeakPtr())),
1248 base::Bind(&base::DoNothing));
1249
1250 // Deferred initialization will continue in OnMediaCryptoReady().
1251 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(
1252 BindToCurrentLoop(base::Bind(&MediaCodecVideoDecoder::OnMediaCryptoReady,
1253 weak_this_factory_.GetWeakPtr())));
1254 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1255 }
1256
1257 void MediaCodecVideoDecoder::OnMediaCryptoReady(
1258 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
1259 bool needs_protected_surface) {
1260 DVLOG(1) << __FUNCTION__;
1261
1262 if (!media_crypto) {
1263 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream.";
1264 cdm_for_reference_holding_only_ = nullptr;
1265 media_drm_bridge_cdm_context_ = nullptr;
1266 NotifyInitializationComplete(false);
1267 return;
1268 }
1269
1270 DCHECK(!media_crypto->is_null());
1271
1272 // We assume this is a part of the initialization process, thus MediaCodec
1273 // is not created yet.
1274 DCHECK(!media_codec_);
1275
1276 codec_config_->media_crypto_ = std::move(media_crypto);
1277 codec_config_->needs_protected_surface_ = needs_protected_surface;
1278
1279 // After receiving |media_crypto_| we can configure MediaCodec.
1280 ConfigureMediaCodecAsynchronously();
1281 }
1282
1283 void MediaCodecVideoDecoder::OnKeyAdded() {
1284 DVLOG(1) << __FUNCTION__;
1285
1286 if (state_ == WAITING_FOR_KEY)
1287 state_ = NO_ERROR;
1288
1289 DoIOTask(true);
1290 }
1291
1292 void MediaCodecVideoDecoder::NotifyInitializationComplete(bool success) {
1293 if (client_)
1294 client_->NotifyInitializationComplete(success);
1295 }
1296
1297 void MediaCodecVideoDecoder::NotifyPictureReady(const Picture& picture) {
1298 if (client_)
1299 client_->PictureReady(picture);
1300 }
1301
1302 void MediaCodecVideoDecoder::NotifyEndOfBitstreamBuffer(int input_buffer_id) {
1303 if (client_)
1304 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
1305 }
1306
1307 void MediaCodecVideoDecoder::NotifyFlushDone() {
1308 if (client_)
1309 client_->NotifyFlushDone();
1310 }
1311
1312 void MediaCodecVideoDecoder::NotifyResetDone() {
1313 if (client_)
1314 client_->NotifyResetDone();
1315 }
1316
1317 void MediaCodecVideoDecoder::NotifyError(Error error) {
1318 state_ = ERROR;
1319 if (client_)
1320 client_->NotifyError(error);
1321 }
1322
1323 void MediaCodecVideoDecoder::ManageTimer(bool did_work) {
1324 bool should_be_running = true;
1325
1326 base::TimeTicks now = base::TimeTicks::Now();
1327 if (!did_work && !most_recent_work_.is_null()) {
1328 // Make sure that we have done work recently enough, else stop the timer.
1329 if (now - most_recent_work_ > IdleTimerTimeOut) {
1330 most_recent_work_ = base::TimeTicks();
1331 should_be_running = false;
1332 }
1333 } else {
1334 most_recent_work_ = now;
1335 }
1336
1337 if (should_be_running)
1338 g_mcvd_manager.Get().StartTimer(this);
1339 else
1340 g_mcvd_manager.Get().StopTimer(this);
1341 }
1342
1343 // static
1344 VideoDecodeAccelerator::Capabilities MediaCodecVideoDecoder::GetCapabilities(
1345 const gpu::GpuPreferences& gpu_preferences) {
1346 Capabilities capabilities;
1347 SupportedProfiles& profiles = capabilities.supported_profiles;
1348
1349 if (MediaCodecUtil::IsVp8DecoderAvailable()) {
1350 SupportedProfile profile;
1351 profile.profile = VP8PROFILE_ANY;
1352 // Since there is little to no power benefit below 360p, don't advertise
1353 // support for it. Let libvpx decode it, and save a MediaCodec instance.
1354 // Note that we allow it anyway for encrypted content, since we push a
1355 // separate profile for that.
1356 profile.min_resolution.SetSize(480, 360);
1357 profile.max_resolution.SetSize(3840, 2160);
1358 // If we know MediaCodec will just create a software codec, prefer our
1359 // internal software decoder instead. It's more up to date and secured
1360 // within the renderer sandbox. However if the content is encrypted, we
1361 // must use MediaCodec anyways since MediaDrm offers no way to decrypt
1362 // the buffers and let us use our internal software decoders.
1363 profile.encrypted_only =
1364 VideoCodecBridge::IsKnownUnaccelerated(kCodecVP8, MEDIA_CODEC_DECODER);
1365 profiles.push_back(profile);
1366
1367 // Always allow encrypted content, even at low resolutions.
1368 profile.min_resolution.SetSize(0, 0);
1369 profile.encrypted_only = true;
1370 profiles.push_back(profile);
1371 }
1372
1373 if (MediaCodecUtil::IsVp9DecoderAvailable()) {
1374 const VideoCodecProfile profile_types[] = {
1375 VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE1, VP9PROFILE_PROFILE2,
1376 VP9PROFILE_PROFILE3, VIDEO_CODEC_PROFILE_UNKNOWN};
1377 const bool is_known_unaccelerated =
1378 VideoCodecBridge::IsKnownUnaccelerated(kCodecVP9, MEDIA_CODEC_DECODER);
1379 for (int i = 0; profile_types[i] != VIDEO_CODEC_PROFILE_UNKNOWN; i++) {
1380 SupportedProfile profile;
1381 // Limit to 360p, like we do for vp8. See above.
1382 profile.min_resolution.SetSize(480, 360);
1383 profile.max_resolution.SetSize(3840, 2160);
1384 // If we know MediaCodec will just create a software codec, prefer our
1385 // internal software decoder instead. It's more up to date and secured
1386 // within the renderer sandbox. However if the content is encrypted, we
1387 // must use MediaCodec anyways since MediaDrm offers no way to decrypt
1388 // the buffers and let us use our internal software decoders.
1389 profile.encrypted_only = is_known_unaccelerated;
1390 profile.profile = profile_types[i];
1391 profiles.push_back(profile);
1392
1393 // Always allow encrypted content.
1394 profile.min_resolution.SetSize(0, 0);
1395 profile.encrypted_only = true;
1396 profiles.push_back(profile);
1397 }
1398 }
1399
1400 for (const auto& supported_profile : kSupportedH264Profiles) {
1401 SupportedProfile profile;
1402 profile.profile = supported_profile;
1403 profile.min_resolution.SetSize(0, 0);
1404 // Advertise support for 4k and let the MediaCodec fail when decoding if it
1405 // doesn't support the resolution. It's assumed that consumers won't have
1406 // software fallback for H264 on Android anyway.
1407 profile.max_resolution.SetSize(3840, 2160);
1408 profiles.push_back(profile);
1409 }
1410
1411 capabilities.flags =
1412 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION;
1413 capabilities.flags |=
1414 VideoDecodeAccelerator::Capabilities::NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE;
1415
1416 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be
1417 // set on the video frames (http://crbug.com/582170), and SurfaceView output
1418 // is disabled (http://crbug.com/582170).
1419 if (gpu_preferences.enable_threaded_texture_mailboxes) {
1420 capabilities.flags |=
1421 VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY;
1422 } else if (MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1423 capabilities.flags |=
1424 VideoDecodeAccelerator::Capabilities::SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1425 }
1426
1427 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
1428 for (const auto& supported_profile : kSupportedHevcProfiles) {
1429 SupportedProfile profile;
1430 profile.profile = supported_profile;
1431 profile.min_resolution.SetSize(0, 0);
1432 profile.max_resolution.SetSize(3840, 2160);
1433 profiles.push_back(profile);
1434 }
1435 #endif
1436
1437 return capabilities;
1438 }
1439
1440 bool MediaCodecVideoDecoder::IsMediaCodecSoftwareDecodingForbidden() const {
1441 // Prevent MediaCodec from using its internal software decoders when we have
1442 // more secure and up to date versions in the renderer process.
1443 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 ||
1444 codec_config_->codec_ == kCodecVP9);
1445 }
1446
1447 bool MediaCodecVideoDecoder::UpdateSurface() {
1448 DCHECK(pending_surface_id_);
1449 DCHECK_NE(config_.surface_id, pending_surface_id_.value());
1450 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID ||
1451 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID);
1452
1453 const int previous_surface_id = config_.surface_id;
1454 const int new_surface_id = pending_surface_id_.value();
1455 pending_surface_id_.reset();
1456 bool success = true;
1457
1458 // TODO(watk): Fix this so we can wait for the new surface to be allocated.
1459 if (!AVDACodecAllocator::Instance()->AllocateSurface(this, new_surface_id)) {
1460 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface");
1461 success = false;
1462 }
1463
1464 // Ensure the current context is active when switching surfaces; we may need
1465 // to create a new texture.
1466 if (success && !make_context_current_cb_.Run()) {
1467 NOTIFY_ERROR(PLATFORM_FAILURE,
1468 "Failed to make this decoder's GL context current when "
1469 "switching surfaces.");
1470 success = false;
1471 }
1472
1473 if (success) {
1474 codec_config_->surface_ =
1475 picture_buffer_manager_.Initialize(new_surface_id);
1476 if (codec_config_->surface_.IsEmpty()) {
1477 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces.");
1478 success = false;
1479 }
1480 }
1481
1482 if (success && media_codec_ &&
1483 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) {
1484 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
1485 success = false;
1486 }
1487
1488 if (success) {
1489 config_.surface_id = new_surface_id;
1490 } else {
1491 // This might be called from OnSurfaceDestroyed(), so we have to release the
1492 // MediaCodec if we failed to switch the surface.
1493 if (media_codec_) {
1494 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
1495 std::move(media_codec_), codec_config_->task_type_,
1496 previous_surface_id);
1497 picture_buffer_manager_.CodecChanged(nullptr);
1498 }
1499 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id);
1500 }
1501
1502 // Regardless of whether we succeeded, we no longer own the previous surface.
1503 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id);
1504
1505 return success;
1506 }
1507
1508 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android/media_codec_video_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698