| 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 |