Commit 7d25c694 authored by Xiaohan Wang's avatar Xiaohan Wang Committed by Commit Bot

media: Disallow CDM reset in mojo media services

In general, after playback starts, we do NOT support removing or
resetting the CDM if one is already set. There's no use case for this
at least for now and foreseeable future, and this change would help
simplify some logic.

Bug: 1066893
Change-Id: I53ad2445fab79d78b34e76d252c9c069c3e8950d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2133173Reviewed-by: default avatarJohn Rummell <jrummell@chromium.org>
Reviewed-by: default avatarŁukasz Anforowicz <lukasza@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756091}
parent 6a98570f
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/logging.h" #include "base/logging.h"
#include "media/base/cdm_context.h"
#include "media/base/content_decryption_module.h" #include "media/base/content_decryption_module.h"
#include "media/mojo/common/media_type_converters.h" #include "media/mojo/common/media_type_converters.h"
#include "media/mojo/common/mojo_decoder_buffer_converter.h" #include "media/mojo/common/mojo_decoder_buffer_converter.h"
...@@ -39,19 +38,27 @@ void MojoAudioDecoderService::Initialize(const AudioDecoderConfig& config, ...@@ -39,19 +38,27 @@ void MojoAudioDecoderService::Initialize(const AudioDecoderConfig& config,
InitializeCallback callback) { InitializeCallback callback) {
DVLOG(1) << __func__ << " " << config.AsHumanReadableString(); DVLOG(1) << __func__ << " " << config.AsHumanReadableString();
// Get CdmContext from |cdm_id|, which could be null. // |cdm_context_ref_| must be kept as long as |cdm_context| is used by the
CdmContext* cdm_context = nullptr; // |decoder_|. We do NOT support resetting |cdm_context_ref_| because in
// general we don't support resetting CDM in the media pipeline.
if (cdm_id != CdmContext::kInvalidCdmId) { if (cdm_id != CdmContext::kInvalidCdmId) {
auto cdm_context_ref = mojo_cdm_service_context_->GetCdmContextRef(cdm_id); if (cdm_id_ == CdmContext::kInvalidCdmId) {
if (cdm_context_ref) { DCHECK(!cdm_context_ref_);
// |cdm_context_ref_| must be kept as long as |cdm_context| is used by the cdm_id_ = cdm_id;
// |decoder_|. cdm_context_ref_ = mojo_cdm_service_context_->GetCdmContextRef(cdm_id);
cdm_context_ref_ = std::move(cdm_context_ref); } else if (cdm_id != cdm_id_) {
cdm_context = cdm_context_ref_->GetCdmContext(); // TODO(xhwang): Replace with mojo::ReportBadMessage().
DCHECK(cdm_context); NOTREACHED() << "The caller should not switch CDM";
OnInitialized(std::move(callback),
StatusCode::kDecoderMissingCdmForEncryptedContent);
return;
} }
} }
// Get CdmContext, which could be null.
CdmContext* cdm_context =
cdm_context_ref_ ? cdm_context_ref_->GetCdmContext() : nullptr;
if (config.is_encrypted() && !cdm_context) { if (config.is_encrypted() && !cdm_context) {
DVLOG(1) << "CdmContext for " << cdm_id << " not found for encrypted audio"; DVLOG(1) << "CdmContext for " << cdm_id << " not found for encrypted audio";
OnInitialized(std::move(callback), OnInitialized(std::move(callback),
...@@ -97,7 +104,6 @@ void MojoAudioDecoderService::OnInitialized(InitializeCallback callback, ...@@ -97,7 +104,6 @@ void MojoAudioDecoderService::OnInitialized(InitializeCallback callback,
DVLOG(1) << __func__ << " success:" << status.is_ok(); DVLOG(1) << __func__ << " success:" << status.is_ok();
if (!status.is_ok()) { if (!status.is_ok()) {
cdm_context_ref_.reset();
// Do not call decoder_->NeedsBitstreamConversion() if init failed. // Do not call decoder_->NeedsBitstreamConversion() if init failed.
std::move(callback).Run(std::move(status), false); std::move(callback).Run(std::move(status), false);
return; return;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "media/base/audio_decoder.h" #include "media/base/audio_decoder.h"
#include "media/base/cdm_context.h"
#include "media/mojo/mojom/audio_decoder.mojom.h" #include "media/mojo/mojom/audio_decoder.mojom.h"
#include "media/mojo/services/media_mojo_export.h" #include "media/mojo/services/media_mojo_export.h"
#include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/associated_remote.h"
...@@ -74,8 +75,9 @@ class MEDIA_MOJO_EXPORT MojoAudioDecoderService : public mojom::AudioDecoder { ...@@ -74,8 +75,9 @@ class MEDIA_MOJO_EXPORT MojoAudioDecoderService : public mojom::AudioDecoder {
// The destination for the decoded buffers. // The destination for the decoded buffers.
mojo::AssociatedRemote<mojom::AudioDecoderClient> client_; mojo::AssociatedRemote<mojom::AudioDecoderClient> client_;
// Holds the CdmContextRef to keep the CdmContext alive for the lifetime of // The CDM ID and the corresponding CdmContextRef, which must be held to keep
// the |decoder_|. // the CdmContext alive for the lifetime of the |decoder_|.
int cdm_id_ = CdmContext::kInvalidCdmId;
std::unique_ptr<CdmContextRef> cdm_context_ref_; std::unique_ptr<CdmContextRef> cdm_context_ref_;
// The AudioDecoder that does actual decoding work. // The AudioDecoder that does actual decoding work.
......
...@@ -124,6 +124,12 @@ void MojoRendererService::SetVolume(float volume) { ...@@ -124,6 +124,12 @@ void MojoRendererService::SetVolume(float volume) {
} }
void MojoRendererService::SetCdm(int32_t cdm_id, SetCdmCallback callback) { void MojoRendererService::SetCdm(int32_t cdm_id, SetCdmCallback callback) {
if (cdm_context_ref_) {
DVLOG(1) << "Switching CDM not supported";
std::move(callback).Run(false);
return;
}
if (!mojo_cdm_service_context_) { if (!mojo_cdm_service_context_) {
DVLOG(1) << "CDM service context not available."; DVLOG(1) << "CDM service context not available.";
std::move(callback).Run(false); std::move(callback).Run(false);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "media/base/cdm_context.h"
#include "media/base/decoder_buffer.h" #include "media/base/decoder_buffer.h"
#include "media/base/simple_sync_token_client.h" #include "media/base/simple_sync_token_client.h"
#include "media/base/video_decoder.h" #include "media/base/video_decoder.h"
...@@ -182,19 +181,26 @@ void MojoVideoDecoderService::Initialize(const VideoDecoderConfig& config, ...@@ -182,19 +181,26 @@ void MojoVideoDecoderService::Initialize(const VideoDecoderConfig& config,
return; return;
} }
// Get CdmContext from |cdm_id|, which could be null. // |cdm_context_ref_| must be kept as long as |cdm_context| is used by the
CdmContext* cdm_context = nullptr; // |decoder_|. We do NOT support resetting |cdm_context_ref_| because in
// general we don't support resetting CDM in the media pipeline.
if (cdm_id != CdmContext::kInvalidCdmId) { if (cdm_id != CdmContext::kInvalidCdmId) {
auto cdm_context_ref = mojo_cdm_service_context_->GetCdmContextRef(cdm_id); if (cdm_id_ == CdmContext::kInvalidCdmId) {
if (cdm_context_ref) { DCHECK(!cdm_context_ref_);
// |cdm_context_ref_| must be kept as long as |cdm_context| is used by the cdm_id_ = cdm_id;
// |decoder_|. cdm_context_ref_ = mojo_cdm_service_context_->GetCdmContextRef(cdm_id);
cdm_context_ref_ = std::move(cdm_context_ref); } else if (cdm_id != cdm_id_) {
cdm_context = cdm_context_ref_->GetCdmContext(); // TODO(xhwang): Replace with mojo::ReportBadMessage().
DCHECK(cdm_context); NOTREACHED() << "The caller should not switch CDM";
OnDecoderInitialized(StatusCode::kDecoderMissingCdmForEncryptedContent);
return;
} }
} }
// Get CdmContext, which could be null.
CdmContext* cdm_context =
cdm_context_ref_ ? cdm_context_ref_->GetCdmContext() : nullptr;
if (config.is_encrypted() && !cdm_context) { if (config.is_encrypted() && !cdm_context) {
DVLOG(1) << "CdmContext for " << cdm_id << " not found for encrypted video"; DVLOG(1) << "CdmContext for " << cdm_id << " not found for encrypted video";
OnDecoderInitialized(StatusCode::kDecoderMissingCdmForEncryptedContent); OnDecoderInitialized(StatusCode::kDecoderMissingCdmForEncryptedContent);
...@@ -267,9 +273,6 @@ void MojoVideoDecoderService::OnDecoderInitialized(Status status) { ...@@ -267,9 +273,6 @@ void MojoVideoDecoderService::OnDecoderInitialized(Status status) {
TRACE_EVENT_ASYNC_END1("media", kInitializeTraceName, this, "success", TRACE_EVENT_ASYNC_END1("media", kInitializeTraceName, this, "success",
status.code()); status.code());
if (!status.is_ok())
cdm_context_ref_.reset();
std::move(init_cb_).Run( std::move(init_cb_).Run(
status, status.is_ok() ? decoder_->NeedsBitstreamConversion() : false, status, status.is_ok() ? decoder_->NeedsBitstreamConversion() : false,
status.is_ok() ? decoder_->GetMaxDecodeRequests() : 1); status.is_ok() ? decoder_->GetMaxDecodeRequests() : 1);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "media/base/cdm_context.h"
#include "media/base/decode_status.h" #include "media/base/decode_status.h"
#include "media/base/overlay_info.h" #include "media/base/overlay_info.h"
#include "media/base/video_decoder.h" #include "media/base/video_decoder.h"
...@@ -110,8 +111,9 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final ...@@ -110,8 +111,9 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final
// Helper for reading DecoderBuffer data from the DataPipe. // Helper for reading DecoderBuffer data from the DataPipe.
std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_; std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_;
// Holds the CdmContextRef to keep the CdmContext alive for the lifetime of // The CDM ID and the corresponding CdmContextRef, which must be held to keep
// the |decoder_|. // the CdmContext alive for the lifetime of the |decoder_|.
int cdm_id_ = CdmContext::kInvalidCdmId;
std::unique_ptr<CdmContextRef> cdm_context_ref_; std::unique_ptr<CdmContextRef> cdm_context_ref_;
std::unique_ptr<media::VideoDecoder> decoder_; std::unique_ptr<media::VideoDecoder> decoder_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment