OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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 #include "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
12 #include "content/common/gpu/gpu_channel.h" | 12 #include "content/common/gpu/gpu_channel.h" |
| 13 #include "content/common/gpu/media/android_copying_backing_strategy.h" |
| 14 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h
" |
13 #include "content/common/gpu/media/avda_return_on_failure.h" | 15 #include "content/common/gpu/media/avda_return_on_failure.h" |
14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 16 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
15 #include "media/base/bitstream_buffer.h" | 17 #include "media/base/bitstream_buffer.h" |
16 #include "media/base/limits.h" | 18 #include "media/base/limits.h" |
17 #include "media/base/timestamp_constants.h" | 19 #include "media/base/timestamp_constants.h" |
18 #include "media/base/video_decoder_config.h" | 20 #include "media/base/video_decoder_config.h" |
19 #include "media/video/picture.h" | 21 #include "media/video/picture.h" |
20 #include "ui/gl/android/scoped_java_surface.h" | 22 #include "ui/gl/android/scoped_java_surface.h" |
21 #include "ui/gl/android/surface_texture.h" | 23 #include "ui/gl/android/surface_texture.h" |
22 #include "ui/gl/gl_bindings.h" | 24 #include "ui/gl/gl_bindings.h" |
23 | 25 |
24 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 26 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
25 #include "media/base/media_keys.h" | 27 #include "media/base/media_keys.h" |
26 #include "media/mojo/services/mojo_cdm_service.h" | 28 #include "media/mojo/services/mojo_cdm_service.h" |
27 #endif | 29 #endif |
28 | 30 |
29 namespace content { | 31 namespace content { |
30 | 32 |
| 33 // TODO(liberato): It is unclear if we have an issue with deadlock during |
| 34 // playback if we lower this. Previously (crbug.com/176036), a deadlock |
| 35 // could occur during preroll. More recent tests have shown some |
| 36 // instability with kNumPictureBuffers==2 with similar symptoms |
| 37 // during playback. crbug.com/:531588 . |
| 38 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; |
| 39 |
31 // Max number of bitstreams notified to the client with | 40 // Max number of bitstreams notified to the client with |
32 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. | 41 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. |
33 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; | 42 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; |
34 | 43 |
35 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | 44 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) |
36 // MediaCodec is only guaranteed to support baseline, but some devices may | 45 // MediaCodec is only guaranteed to support baseline, but some devices may |
37 // support others. Advertise support for all H264 profiles and let the | 46 // support others. Advertise support for all H264 profiles and let the |
38 // MediaCodec fail when decoding if it's not actually supported. It's assumed | 47 // MediaCodec fail when decoding if it's not actually supported. It's assumed |
39 // that consumers won't have software fallback for H264 on Android anyway. | 48 // that consumers won't have software fallback for H264 on Android anyway. |
40 static const media::VideoCodecProfile kSupportedH264Profiles[] = { | 49 static const media::VideoCodecProfile kSupportedH264Profiles[] = { |
41 media::H264PROFILE_BASELINE, | 50 media::H264PROFILE_BASELINE, |
42 media::H264PROFILE_MAIN, | 51 media::H264PROFILE_MAIN, |
43 media::H264PROFILE_EXTENDED, | 52 media::H264PROFILE_EXTENDED, |
44 media::H264PROFILE_HIGH, | 53 media::H264PROFILE_HIGH, |
45 media::H264PROFILE_HIGH10PROFILE, | 54 media::H264PROFILE_HIGH10PROFILE, |
46 media::H264PROFILE_HIGH422PROFILE, | 55 media::H264PROFILE_HIGH422PROFILE, |
47 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, | 56 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, |
48 media::H264PROFILE_SCALABLEBASELINE, | 57 media::H264PROFILE_SCALABLEBASELINE, |
49 media::H264PROFILE_SCALABLEHIGH, | 58 media::H264PROFILE_SCALABLEHIGH, |
50 media::H264PROFILE_STEREOHIGH, | 59 media::H264PROFILE_STEREOHIGH, |
51 media::H264PROFILE_MULTIVIEWHIGH | 60 media::H264PROFILE_MULTIVIEWHIGH |
52 }; | 61 }; |
| 62 |
| 63 #define BACKING_STRATEGY AndroidDeferredRenderingBackingStrategy |
| 64 #else |
| 65 #define BACKING_STRATEGY AndroidCopyingBackingStrategy |
53 #endif | 66 #endif |
54 | 67 |
55 // Because MediaCodec is thread-hostile (must be poked on a single thread) and | 68 // Because MediaCodec is thread-hostile (must be poked on a single thread) and |
56 // has no callback mechanism (b/11990118), we must drive it by polling for | 69 // has no callback mechanism (b/11990118), we must drive it by polling for |
57 // complete frames (and available input buffers, when the codec is fully | 70 // complete frames (and available input buffers, when the codec is fully |
58 // saturated). This function defines the polling delay. The value used is an | 71 // saturated). This function defines the polling delay. The value used is an |
59 // arbitrary choice that trades off CPU utilization (spinning) against latency. | 72 // arbitrary choice that trades off CPU utilization (spinning) against latency. |
60 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). | 73 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). |
61 static inline const base::TimeDelta DecodePollDelay() { | 74 static inline const base::TimeDelta DecodePollDelay() { |
62 // An alternative to this polling scheme could be to dedicate a new thread | 75 // An alternative to this polling scheme could be to dedicate a new thread |
63 // (instead of using the ChildThread) to run the MediaCodec, and make that | 76 // (instead of using the ChildThread) to run the MediaCodec, and make that |
64 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it | 77 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it |
65 // believes the codec should complete "soon" (e.g. waiting for an input | 78 // believes the codec should complete "soon" (e.g. waiting for an input |
66 // buffer, or waiting for a picture when it knows enough complete input | 79 // buffer, or waiting for a picture when it knows enough complete input |
67 // pictures have been fed to saturate any internal buffering). This is | 80 // pictures have been fed to saturate any internal buffering). This is |
68 // speculative and it's unclear that this would be a win (nor that there's a | 81 // speculative and it's unclear that this would be a win (nor that there's a |
69 // reasonably device-agnostic way to fill in the "believes" above). | 82 // reasonably device-agnostic way to fill in the "believes" above). |
70 return base::TimeDelta::FromMilliseconds(10); | 83 return base::TimeDelta::FromMilliseconds(10); |
71 } | 84 } |
72 | 85 |
73 static inline const base::TimeDelta NoWaitTimeOut() { | 86 static inline const base::TimeDelta NoWaitTimeOut() { |
74 return base::TimeDelta::FromMicroseconds(0); | 87 return base::TimeDelta::FromMicroseconds(0); |
75 } | 88 } |
76 | 89 |
77 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 90 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
78 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, | 91 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, |
79 const base::Callback<bool(void)>& make_context_current, | 92 const base::Callback<bool(void)>& make_context_current) |
80 scoped_ptr<BackingStrategy> strategy) | |
81 : client_(NULL), | 93 : client_(NULL), |
82 make_context_current_(make_context_current), | 94 make_context_current_(make_context_current), |
83 codec_(media::kCodecH264), | 95 codec_(media::kCodecH264), |
84 state_(NO_ERROR), | 96 state_(NO_ERROR), |
85 picturebuffers_requested_(false), | 97 picturebuffers_requested_(false), |
86 gl_decoder_(decoder), | 98 gl_decoder_(decoder), |
87 strategy_(strategy.Pass()), | 99 strategy_(new BACKING_STRATEGY()), |
88 weak_this_factory_(this) {} | 100 weak_this_factory_(this) {} |
89 | 101 |
90 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 102 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
91 DCHECK(thread_checker_.CalledOnValidThread()); | 103 DCHECK(thread_checker_.CalledOnValidThread()); |
92 } | 104 } |
93 | 105 |
94 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, | 106 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
95 Client* client) { | 107 Client* client) { |
96 DCHECK(!media_codec_); | 108 DCHECK(!media_codec_); |
97 DCHECK(thread_checker_.CalledOnValidThread()); | 109 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 | 434 |
423 pending_bitstream_buffers_.push( | 435 pending_bitstream_buffers_.push( |
424 std::make_pair(bitstream_buffer, base::Time::Now())); | 436 std::make_pair(bitstream_buffer, base::Time::Now())); |
425 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | 437 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", |
426 pending_bitstream_buffers_.size()); | 438 pending_bitstream_buffers_.size()); |
427 | 439 |
428 DoIOTask(); | 440 DoIOTask(); |
429 } | 441 } |
430 | 442 |
431 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { | 443 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { |
432 client_->ProvidePictureBuffers(strategy_->GetNumPictureBuffers(), size_, | 444 client_->ProvidePictureBuffers(kNumPictureBuffers, size_, |
433 strategy_->GetTextureTarget()); | 445 strategy_->GetTextureTarget()); |
434 } | 446 } |
435 | 447 |
436 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( | 448 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( |
437 const std::vector<media::PictureBuffer>& buffers) { | 449 const std::vector<media::PictureBuffer>& buffers) { |
438 DCHECK(thread_checker_.CalledOnValidThread()); | 450 DCHECK(thread_checker_.CalledOnValidThread()); |
439 DCHECK(output_picture_buffers_.empty()); | 451 DCHECK(output_picture_buffers_.empty()); |
440 DCHECK(free_picture_ids_.empty()); | 452 DCHECK(free_picture_ids_.empty()); |
441 | 453 |
442 for (size_t i = 0; i < buffers.size(); ++i) { | 454 for (size_t i = 0; i < buffers.size(); ++i) { |
443 RETURN_ON_FAILURE(this, buffers[i].size() == size_, | 455 RETURN_ON_FAILURE(this, buffers[i].size() == size_, |
444 "Invalid picture buffer size was passed.", | 456 "Invalid picture buffer size was passed.", |
445 INVALID_ARGUMENT); | 457 INVALID_ARGUMENT); |
446 int32 id = buffers[i].id(); | 458 int32 id = buffers[i].id(); |
447 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); | 459 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); |
448 free_picture_ids_.push(id); | 460 free_picture_ids_.push(id); |
449 // Since the client might be re-using |picture_buffer_id| values, forget | 461 // Since the client might be re-using |picture_buffer_id| values, forget |
450 // about previously-dismissed IDs now. See ReusePictureBuffer() comment | 462 // about previously-dismissed IDs now. See ReusePictureBuffer() comment |
451 // about "zombies" for why we maintain this set in the first place. | 463 // about "zombies" for why we maintain this set in the first place. |
452 dismissed_picture_ids_.erase(id); | 464 dismissed_picture_ids_.erase(id); |
453 | 465 |
454 strategy_->AssignOnePictureBuffer(buffers[i]); | 466 strategy_->AssignOnePictureBuffer(buffers[i]); |
455 } | 467 } |
456 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 468 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
457 | 469 |
458 RETURN_ON_FAILURE( | 470 RETURN_ON_FAILURE(this, output_picture_buffers_.size() >= kNumPictureBuffers, |
459 this, output_picture_buffers_.size() >= strategy_->GetNumPictureBuffers(), | 471 "Invalid picture buffers were passed.", INVALID_ARGUMENT); |
460 "Invalid picture buffers were passed.", INVALID_ARGUMENT); | |
461 | 472 |
462 DoIOTask(); | 473 DoIOTask(); |
463 } | 474 } |
464 | 475 |
465 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( | 476 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( |
466 int32 picture_buffer_id) { | 477 int32 picture_buffer_id) { |
467 DCHECK(thread_checker_.CalledOnValidThread()); | 478 DCHECK(thread_checker_.CalledOnValidThread()); |
468 | 479 |
469 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in | 480 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in |
470 // IPC, or in a PostTask either at the sender or receiver) when we sent a | 481 // IPC, or in a PostTask either at the sender or receiver) when we sent a |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 void AndroidVideoDecodeAccelerator::NotifyResetDone() { | 633 void AndroidVideoDecodeAccelerator::NotifyResetDone() { |
623 client_->NotifyResetDone(); | 634 client_->NotifyResetDone(); |
624 } | 635 } |
625 | 636 |
626 void AndroidVideoDecodeAccelerator::NotifyError( | 637 void AndroidVideoDecodeAccelerator::NotifyError( |
627 media::VideoDecodeAccelerator::Error error) { | 638 media::VideoDecodeAccelerator::Error error) { |
628 client_->NotifyError(error); | 639 client_->NotifyError(error); |
629 } | 640 } |
630 | 641 |
631 // static | 642 // static |
632 media::VideoDecodeAccelerator::SupportedProfiles | 643 media::VideoDecodeAccelerator::Capabilities |
633 AndroidVideoDecodeAccelerator::GetSupportedProfiles() { | 644 AndroidVideoDecodeAccelerator::GetCapabilities() { |
634 SupportedProfiles profiles; | 645 Capabilities capabilities; |
| 646 SupportedProfiles& profiles = capabilities.supported_profiles; |
635 | 647 |
636 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 648 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
637 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { | 649 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { |
638 SupportedProfile profile; | 650 SupportedProfile profile; |
639 profile.profile = media::VP8PROFILE_ANY; | 651 profile.profile = media::VP8PROFILE_ANY; |
640 profile.min_resolution.SetSize(0, 0); | 652 profile.min_resolution.SetSize(0, 0); |
641 profile.max_resolution.SetSize(1920, 1088); | 653 profile.max_resolution.SetSize(1920, 1088); |
642 profiles.push_back(profile); | 654 profiles.push_back(profile); |
643 } | 655 } |
644 | 656 |
(...skipping 12 matching lines...) Expand all Loading... |
657 profile.profile = supported_profile; | 669 profile.profile = supported_profile; |
658 profile.min_resolution.SetSize(0, 0); | 670 profile.min_resolution.SetSize(0, 0); |
659 // Advertise support for 4k and let the MediaCodec fail when decoding if it | 671 // Advertise support for 4k and let the MediaCodec fail when decoding if it |
660 // doesn't support the resolution. It's assumed that consumers won't have | 672 // doesn't support the resolution. It's assumed that consumers won't have |
661 // software fallback for H264 on Android anyway. | 673 // software fallback for H264 on Android anyway. |
662 profile.max_resolution.SetSize(3840, 2160); | 674 profile.max_resolution.SetSize(3840, 2160); |
663 profiles.push_back(profile); | 675 profiles.push_back(profile); |
664 } | 676 } |
665 #endif | 677 #endif |
666 | 678 |
667 return profiles; | 679 capabilities.flags = BACKING_STRATEGY::GetCapabilitiesFlags(); |
| 680 |
| 681 return capabilities; |
668 } | 682 } |
669 | 683 |
670 } // namespace content | 684 } // namespace content |
OLD | NEW |