| Index: media/base/android/media_codec_video_decoder.cc
|
| diff --git a/media/base/android/media_codec_video_decoder.cc b/media/base/android/media_codec_video_decoder.cc
|
| index 48b278ad137ca961fdcb415cdf948ee5e7dda29b..7636465294a1f59437e5ad4ca6ef659a4ddbcd67 100644
|
| --- a/media/base/android/media_codec_video_decoder.cc
|
| +++ b/media/base/android/media_codec_video_decoder.cc
|
| @@ -7,6 +7,7 @@
|
| #include "base/bind.h"
|
| #include "base/logging.h"
|
| #include "media/base/android/media_codec_bridge.h"
|
| +#include "media/base/android/media_drm_bridge.h"
|
| #include "media/base/demuxer_stream.h"
|
| #include "media/base/timestamp_constants.h"
|
|
|
| @@ -22,6 +23,7 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
|
| const base::Closure& starvation_cb,
|
| const base::Closure& decoder_drained_cb,
|
| const base::Closure& stop_done_cb,
|
| + const base::Closure& key_required_cb,
|
| const base::Closure& error_cb,
|
| const SetTimeCallback& update_current_time_cb,
|
| const VideoSizeChangedCallback& video_size_changed_cb,
|
| @@ -31,6 +33,7 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
|
| starvation_cb,
|
| decoder_drained_cb,
|
| stop_done_cb,
|
| + key_required_cb,
|
| error_cb,
|
| "VideoDecoder"),
|
| update_current_time_cb_(update_current_time_cb),
|
| @@ -66,6 +69,10 @@ void MediaCodecVideoDecoder::SetDemuxerConfigs(const DemuxerConfigs& configs) {
|
| }
|
| }
|
|
|
| +bool MediaCodecVideoDecoder::IsContentEncrypted() const {
|
| + return configs_.is_video_encrypted;
|
| +}
|
| +
|
| void MediaCodecVideoDecoder::ReleaseDecoderResources() {
|
| DCHECK(media_task_runner_->BelongsToCurrentThread());
|
| DVLOG(1) << class_name() << "::" << __FUNCTION__;
|
| @@ -90,6 +97,15 @@ void MediaCodecVideoDecoder::SetVideoSurface(gfx::ScopedJavaSurface surface) {
|
| DVLOG(1) << class_name() << "::" << __FUNCTION__
|
| << (surface.IsEmpty() ? " empty" : " non-empty");
|
|
|
| + // Do not set unprotected surface if we know that we need a protected one.
|
| + // Empty surface means the surface removal and we always allow for it.
|
| + if (!surface.IsEmpty() && drm_bridge_ &&
|
| + drm_bridge_->IsProtectedSurfaceRequired() && !surface.is_protected()) {
|
| + DVLOG(0) << class_name() << "::" << __FUNCTION__
|
| + << ": surface is not protected, ignoring";
|
| + return;
|
| + }
|
| +
|
| surface_ = surface.Pass();
|
|
|
| needs_reconfigure_ = true;
|
| @@ -123,7 +139,8 @@ bool MediaCodecVideoDecoder::IsCodecReconfigureNeeded(
|
| next.video_size.height());
|
| }
|
|
|
| -MediaCodecDecoder::ConfigStatus MediaCodecVideoDecoder::ConfigureInternal() {
|
| +MediaCodecDecoder::ConfigStatus MediaCodecVideoDecoder::ConfigureInternal(
|
| + jobject media_crypto) {
|
| DCHECK(media_task_runner_->BelongsToCurrentThread());
|
|
|
| DVLOG(1) << class_name() << "::" << __FUNCTION__;
|
| @@ -136,27 +153,24 @@ MediaCodecDecoder::ConfigStatus MediaCodecVideoDecoder::ConfigureInternal() {
|
|
|
| if (configs_.video_codec == kUnknownVideoCodec) {
|
| DVLOG(0) << class_name() << "::" << __FUNCTION__
|
| - << " configuration parameters are required";
|
| + << ": configuration parameters are required";
|
| return kConfigFailure;
|
| }
|
|
|
| - // TODO(timav): implement DRM.
|
| - // bool is_secure = is_content_encrypted() && drm_bridge() &&
|
| - // drm_bridge()->IsProtectedSurfaceRequired();
|
| -
|
| - bool is_secure = false; // DRM is not implemented
|
| -
|
| if (surface_.IsEmpty()) {
|
| - DVLOG(0) << class_name() << "::" << __FUNCTION__ << " surface required";
|
| + DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": surface is required";
|
| return kConfigFailure;
|
| }
|
|
|
| + bool is_secure = IsContentEncrypted() && drm_bridge_ &&
|
| + drm_bridge_->IsProtectedSurfaceRequired();
|
| +
|
| media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder(
|
| configs_.video_codec,
|
| is_secure,
|
| configs_.video_size,
|
| surface_.j_surface().obj(),
|
| - GetMediaCrypto().obj()));
|
| + media_crypto));
|
|
|
| if (!media_codec_bridge_) {
|
| DVLOG(0) << class_name() << "::" << __FUNCTION__
|
|
|