1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/filters/decrypting_media_resource.h"
10 #include "base/functional/bind.h"
11 #include "base/functional/callback_helpers.h"
12 #include "base/logging.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "media/base/cdm_context.h"
15 #include "media/base/demuxer_stream.h"
16 #include "media/base/media_log.h"
17 #include "media/base/pipeline_status.h"
18 #include "media/filters/decrypting_demuxer_stream.h"
22 DecryptingMediaResource::DecryptingMediaResource(
23 MediaResource* media_resource,
24 CdmContext* cdm_context,
26 scoped_refptr<base::SequencedTaskRunner> task_runner)
27 : media_resource_(media_resource),
28 cdm_context_(cdm_context),
29 media_log_(media_log),
30 task_runner_(task_runner) {
31 DCHECK(media_resource);
32 DCHECK_EQ(MediaResource::Type::kStream, media_resource->GetType());
34 DCHECK(cdm_context_->GetDecryptor());
35 DCHECK(cdm_context_->GetDecryptor()->CanAlwaysDecrypt());
37 DCHECK(task_runner->RunsTasksInCurrentSequence());
40 DecryptingMediaResource::~DecryptingMediaResource() = default;
42 MediaResource::Type DecryptingMediaResource::GetType() const {
43 DCHECK_EQ(MediaResource::Type::kStream, media_resource_->GetType());
44 return MediaResource::Type::kStream;
47 std::vector<DemuxerStream*> DecryptingMediaResource::GetAllStreams() {
51 return media_resource_->GetAllStreams();
54 void DecryptingMediaResource::Initialize(InitCB init_cb, WaitingCB waiting_cb) {
57 auto streams = media_resource_->GetAllStreams();
59 // Save the callback so that we can invoke it when the
60 // DecryptingDemuxerStreams have finished initialization.
61 init_cb_ = std::move(init_cb);
62 num_dds_pending_init_ = streams.size();
64 for (auto* stream : streams) {
65 auto decrypting_demuxer_stream = std::make_unique<DecryptingDemuxerStream>(
66 task_runner_, media_log_, waiting_cb);
68 // DecryptingDemuxerStream always invokes the callback asynchronously so
69 // that we have no reentrancy issues. "All public APIs and callbacks are
70 // trampolined to the |task_runner_|."
71 decrypting_demuxer_stream->Initialize(
73 base::BindOnce(&DecryptingMediaResource::OnDecryptingDemuxerInitialized,
74 weak_factory_.GetWeakPtr()));
76 streams_.push_back(decrypting_demuxer_stream.get());
77 owned_streams_.push_back(std::move(decrypting_demuxer_stream));
81 int DecryptingMediaResource::DecryptingDemuxerStreamCountForTesting() const {
82 return owned_streams_.size();
85 void DecryptingMediaResource::OnDecryptingDemuxerInitialized(
86 PipelineStatus status) {
87 DVLOG(2) << __func__ << ": DecryptingDemuxerStream initialization ended "
88 << "with the status: " << status;
90 // Decrement the count of DecryptingDemuxerStreams that need to be
92 --num_dds_pending_init_;
97 if (status != PIPELINE_OK)
98 std::move(init_cb_).Run(false);
99 else if (num_dds_pending_init_ == 0)
100 std::move(init_cb_).Run(true);