Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / decrypting_demuxer_stream.cc
1 // Copyright 2012 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.
4
5 #include "media/filters/decrypting_demuxer_stream.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/task/sequenced_task_runner.h"
13 #include "base/task/single_thread_task_runner.h"
14 #include "base/trace_event/trace_event.h"
15 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/cdm_context.h"
17 #include "media/base/decoder_buffer.h"
18 #include "media/base/media_log.h"
19 #include "media/base/media_util.h"
20
21 namespace media {
22
23 static bool IsStreamValid(DemuxerStream* stream) {
24   return ((stream->type() == DemuxerStream::AUDIO &&
25            stream->audio_decoder_config().IsValidConfig()) ||
26           (stream->type() == DemuxerStream::VIDEO &&
27            stream->video_decoder_config().IsValidConfig()));
28 }
29
30 DecryptingDemuxerStream::DecryptingDemuxerStream(
31     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
32     MediaLog* media_log,
33     const WaitingCB& waiting_cb)
34     : task_runner_(task_runner),
35       media_log_(media_log),
36       waiting_cb_(waiting_cb) {
37   DETACH_FROM_SEQUENCE(sequence_checker_);
38 }
39
40 std::string DecryptingDemuxerStream::GetDisplayName() const {
41   return "DecryptingDemuxerStream";
42 }
43
44 void DecryptingDemuxerStream::Initialize(DemuxerStream* stream,
45                                          CdmContext* cdm_context,
46                                          PipelineStatusCallback status_cb) {
47   DVLOG(2) << __func__;
48   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
49   DCHECK_EQ(state_, kUninitialized) << state_;
50   DCHECK(stream);
51   DCHECK(cdm_context);
52   DCHECK(!demuxer_stream_);
53
54   demuxer_stream_ = stream;
55   init_cb_ = BindToCurrentLoop(std::move(status_cb));
56
57   InitializeDecoderConfig();
58
59   if (!cdm_context->GetDecryptor()) {
60     DVLOG(1) << __func__ << ": no decryptor";
61     state_ = kUninitialized;
62     std::move(init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
63     return;
64   }
65
66   decryptor_ = cdm_context->GetDecryptor();
67
68   event_cb_registration_ = cdm_context->RegisterEventCB(base::BindRepeating(
69       &DecryptingDemuxerStream::OnCdmContextEvent, weak_factory_.GetWeakPtr()));
70
71   state_ = kIdle;
72   std::move(init_cb_).Run(PIPELINE_OK);
73 }
74
75 void DecryptingDemuxerStream::Read(ReadCB read_cb) {
76   DVLOG(3) << __func__;
77   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
78   DCHECK_EQ(state_, kIdle) << state_;
79   DCHECK(read_cb);
80   CHECK(!read_cb_) << "Overlapping reads are not supported.";
81
82   read_cb_ = BindToCurrentLoop(std::move(read_cb));
83   state_ = kPendingDemuxerRead;
84   demuxer_stream_->Read(
85       base::BindOnce(&DecryptingDemuxerStream::OnBufferReadFromDemuxerStream,
86                      weak_factory_.GetWeakPtr()));
87 }
88
89 void DecryptingDemuxerStream::Reset(base::OnceClosure closure) {
90   DVLOG(2) << __func__ << " - state: " << state_;
91   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
92   DCHECK(state_ != kUninitialized) << state_;
93   DCHECK(!reset_cb_);
94
95   reset_cb_ = BindToCurrentLoop(std::move(closure));
96
97   decryptor_->CancelDecrypt(GetDecryptorStreamType());
98
99   // Reset() cannot complete if the read callback is still pending.
100   // Defer the resetting process in this case. The |reset_cb_| will be fired
101   // after the read callback is fired - see OnBufferReadFromDemuxerStream() and
102   // OnBufferDecrypted().
103   if (state_ == kPendingDemuxerRead || state_ == kPendingDecrypt) {
104     DCHECK(read_cb_);
105     return;
106   }
107
108   if (state_ == kWaitingForKey) {
109     CompleteWaitingForDecryptionKey();
110     DCHECK(read_cb_);
111     pending_buffer_to_decrypt_ = nullptr;
112     std::move(read_cb_).Run(kAborted, nullptr);
113   }
114
115   DCHECK(!read_cb_);
116   DoReset();
117 }
118
119 AudioDecoderConfig DecryptingDemuxerStream::audio_decoder_config() {
120   DCHECK(state_ != kUninitialized) << state_;
121   CHECK_EQ(demuxer_stream_->type(), AUDIO);
122   return audio_config_;
123 }
124
125 VideoDecoderConfig DecryptingDemuxerStream::video_decoder_config() {
126   DCHECK(state_ != kUninitialized) << state_;
127   CHECK_EQ(demuxer_stream_->type(), VIDEO);
128   return video_config_;
129 }
130
131 DemuxerStream::Type DecryptingDemuxerStream::type() const {
132   DCHECK(state_ != kUninitialized) << state_;
133   return demuxer_stream_->type();
134 }
135
136 StreamLiveness DecryptingDemuxerStream::liveness() const {
137   DCHECK(state_ != kUninitialized) << state_;
138   return demuxer_stream_->liveness();
139 }
140
141 void DecryptingDemuxerStream::EnableBitstreamConverter() {
142   demuxer_stream_->EnableBitstreamConverter();
143 }
144
145 bool DecryptingDemuxerStream::SupportsConfigChanges() {
146   return demuxer_stream_->SupportsConfigChanges();
147 }
148
149 bool DecryptingDemuxerStream::HasClearLead() const {
150   return has_clear_lead_.value_or(false);
151 }
152
153 DecryptingDemuxerStream::~DecryptingDemuxerStream() {
154   DVLOG(2) << __func__ << " : state_ = " << state_;
155   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
156
157   if (state_ == kUninitialized)
158     return;
159
160   if (state_ == kWaitingForKey)
161     CompleteWaitingForDecryptionKey();
162   if (state_ == kPendingDecrypt)
163     CompletePendingDecrypt(Decryptor::kError);
164
165   if (decryptor_) {
166     decryptor_->CancelDecrypt(GetDecryptorStreamType());
167     decryptor_ = nullptr;
168   }
169   if (init_cb_)
170     std::move(init_cb_).Run(PIPELINE_ERROR_ABORT);
171   if (read_cb_)
172     std::move(read_cb_).Run(kAborted, nullptr);
173   if (reset_cb_)
174     std::move(reset_cb_).Run();
175   pending_buffer_to_decrypt_ = nullptr;
176 }
177
178 void DecryptingDemuxerStream::OnBufferReadFromDemuxerStream(
179     DemuxerStream::Status status,
180     scoped_refptr<DecoderBuffer> buffer) {
181   DVLOG(3) << __func__ << ": status = " << status;
182   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
183   DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
184   DCHECK(read_cb_);
185   DCHECK_EQ(buffer.get() != nullptr, status == kOk) << status;
186
187   // Even when |reset_cb_|, we need to pass |kConfigChanged| back to
188   // the caller so that the downstream decoder can be properly reinitialized.
189   if (status == kConfigChanged) {
190     DVLOG(2) << __func__ << ": config change";
191     DCHECK_EQ(demuxer_stream_->type() == AUDIO, audio_config_.IsValidConfig());
192     DCHECK_EQ(demuxer_stream_->type() == VIDEO, video_config_.IsValidConfig());
193
194     // Update the decoder config, which the decoder will use when it is notified
195     // of kConfigChanged.
196     InitializeDecoderConfig();
197
198     state_ = kIdle;
199     std::move(read_cb_).Run(kConfigChanged, nullptr);
200     if (reset_cb_)
201       DoReset();
202     return;
203   }
204
205   if (reset_cb_) {
206     std::move(read_cb_).Run(kAborted, nullptr);
207     DoReset();
208     return;
209   }
210
211   if (status == kAborted || status == kError) {
212     if (status == kError) {
213       MEDIA_LOG(ERROR, media_log_)
214           << GetDisplayName() << ": demuxer stream read error.";
215     }
216     state_ = kIdle;
217     std::move(read_cb_).Run(status, nullptr);
218     return;
219   }
220
221   DCHECK_EQ(kOk, status);
222
223   if (buffer->end_of_stream()) {
224     DVLOG(2) << __func__ << ": EOS buffer";
225     state_ = kIdle;
226     std::move(read_cb_).Run(kOk, std::move(buffer));
227     return;
228   }
229
230   // One time set of `has_clear_lead_`.
231   if (!has_clear_lead_.has_value()) {
232     has_clear_lead_ = !buffer->decrypt_config();
233   }
234
235   if (!buffer->decrypt_config()) {
236     DVLOG(2) << __func__ << ": clear buffer";
237     state_ = kIdle;
238     std::move(read_cb_).Run(kOk, std::move(buffer));
239     return;
240   }
241
242   pending_buffer_to_decrypt_ = std::move(buffer);
243   state_ = kPendingDecrypt;
244   DecryptPendingBuffer();
245 }
246
247 void DecryptingDemuxerStream::DecryptPendingBuffer() {
248   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
249   DCHECK_EQ(state_, kPendingDecrypt) << state_;
250   DCHECK(!pending_buffer_to_decrypt_->end_of_stream());
251   TRACE_EVENT_ASYNC_BEGIN2(
252       "media", "DecryptingDemuxerStream::DecryptPendingBuffer", this, "type",
253       DemuxerStream::GetTypeName(demuxer_stream_->type()), "timestamp_us",
254       pending_buffer_to_decrypt_->timestamp().InMicroseconds());
255   decryptor_->Decrypt(GetDecryptorStreamType(), pending_buffer_to_decrypt_,
256                       BindToCurrentLoop(base::BindOnce(
257                           &DecryptingDemuxerStream::OnBufferDecrypted,
258                           weak_factory_.GetWeakPtr())));
259 }
260
261 void DecryptingDemuxerStream::OnBufferDecrypted(
262     Decryptor::Status status,
263     scoped_refptr<DecoderBuffer> decrypted_buffer) {
264   DVLOG(3) << __func__ << " - status: " << status;
265   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
266   DCHECK_EQ(state_, kPendingDecrypt) << state_;
267   DCHECK(read_cb_);
268   DCHECK(pending_buffer_to_decrypt_);
269   CompletePendingDecrypt(status);
270
271   bool need_to_try_again_if_nokey = key_added_while_decrypt_pending_;
272   key_added_while_decrypt_pending_ = false;
273
274   if (reset_cb_) {
275     pending_buffer_to_decrypt_ = nullptr;
276     std::move(read_cb_).Run(kAborted, nullptr);
277     DoReset();
278     return;
279   }
280
281   DCHECK_EQ(status == Decryptor::kSuccess, decrypted_buffer.get() != nullptr);
282
283   if (status == Decryptor::kError || status == Decryptor::kNeedMoreData) {
284     DVLOG(2) << __func__ << ": Error with status " << status;
285     MEDIA_LOG(ERROR, media_log_)
286         << GetDisplayName() << ": decrypt error " << status;
287     pending_buffer_to_decrypt_ = nullptr;
288     state_ = kIdle;
289     std::move(read_cb_).Run(kError, nullptr);
290     return;
291   }
292
293   if (status == Decryptor::kNoKey) {
294     std::string key_id = pending_buffer_to_decrypt_->decrypt_config()->key_id();
295
296     std::string log_message =
297         "no key for key ID " + base::HexEncode(key_id.data(), key_id.size()) +
298         "; will resume decrypting after new usable key is available";
299     DVLOG(1) << __func__ << ": " << log_message;
300     MEDIA_LOG(INFO, media_log_) << GetDisplayName() << ": " << log_message;
301
302     if (need_to_try_again_if_nokey) {
303       // The |state_| is still kPendingDecrypt.
304       MEDIA_LOG(INFO, media_log_)
305           << GetDisplayName() << ": key was added, resuming decrypt";
306       DecryptPendingBuffer();
307       return;
308     }
309
310     state_ = kWaitingForKey;
311
312     TRACE_EVENT_ASYNC_BEGIN0(
313         "media", "DecryptingDemuxerStream::WaitingForDecryptionKey", this);
314     waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
315     return;
316   }
317
318   DCHECK_EQ(status, Decryptor::kSuccess);
319
320   // Copy the key frame flag and duration from the encrypted to decrypted
321   // buffer.
322   // TODO(crbug.com/1116263): Ensure all fields are copied by Decryptor.
323   decrypted_buffer->set_is_key_frame(
324       pending_buffer_to_decrypt_->is_key_frame());
325   decrypted_buffer->set_duration(pending_buffer_to_decrypt_->duration());
326
327   pending_buffer_to_decrypt_ = nullptr;
328   state_ = kIdle;
329   std::move(read_cb_).Run(kOk, std::move(decrypted_buffer));
330 }
331
332 void DecryptingDemuxerStream::OnCdmContextEvent(CdmContext::Event event) {
333   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
334
335   if (event != CdmContext::Event::kHasAdditionalUsableKey)
336     return;
337
338   if (state_ == kPendingDecrypt) {
339     key_added_while_decrypt_pending_ = true;
340     return;
341   }
342
343   // Nothing to do.
344   if (state_ != kWaitingForKey)
345     return;
346
347   CompleteWaitingForDecryptionKey();
348   MEDIA_LOG(INFO, media_log_)
349       << GetDisplayName() << ": key was added, resuming decrypt";
350   state_ = kPendingDecrypt;
351   DecryptPendingBuffer();
352 }
353
354 void DecryptingDemuxerStream::DoReset() {
355   DCHECK(state_ != kUninitialized);
356   DCHECK(!init_cb_);
357   DCHECK(!read_cb_);
358
359   state_ = kIdle;
360   std::move(reset_cb_).Run();
361 }
362
363 Decryptor::StreamType DecryptingDemuxerStream::GetDecryptorStreamType() const {
364   if (demuxer_stream_->type() == AUDIO)
365     return Decryptor::kAudio;
366
367   DCHECK_EQ(demuxer_stream_->type(), VIDEO);
368   return Decryptor::kVideo;
369 }
370
371 void DecryptingDemuxerStream::InitializeDecoderConfig() {
372   // The decoder selector or upstream demuxer make sure the stream is valid.
373   DCHECK(IsStreamValid(demuxer_stream_));
374
375   // Since |this| is a decrypted version of |demuxer_stream_|, the decoder
376   // config of |this| should always be a decrypted version of |demuxer_stream_|
377   // configs.
378   switch (demuxer_stream_->type()) {
379     case AUDIO: {
380       audio_config_ = demuxer_stream_->audio_decoder_config();
381       if (audio_config_.is_encrypted())
382         audio_config_.SetIsEncrypted(false);
383       break;
384     }
385
386     case VIDEO: {
387       video_config_ = demuxer_stream_->video_decoder_config();
388       if (video_config_.is_encrypted())
389         video_config_.SetIsEncrypted(false);
390       break;
391     }
392
393     default:
394       NOTREACHED();
395       return;
396   }
397   LogMetadata();
398 }
399
400 void DecryptingDemuxerStream::LogMetadata() {
401   std::vector<AudioDecoderConfig> audio_metadata{audio_config_};
402   std::vector<VideoDecoderConfig> video_metadata{video_config_};
403   media_log_->SetProperty<MediaLogProperty::kAudioTracks>(audio_metadata);
404   media_log_->SetProperty<MediaLogProperty::kVideoTracks>(video_metadata);
405   // FFmpegDemuxer also provides a max diration, start time, and bitrate.
406 }
407
408 void DecryptingDemuxerStream::CompletePendingDecrypt(Decryptor::Status status) {
409   DCHECK_EQ(state_, kPendingDecrypt);
410   TRACE_EVENT_ASYNC_END1("media",
411                          "DecryptingDemuxerStream::DecryptPendingBuffer", this,
412                          "status", Decryptor::GetStatusName(status));
413 }
414
415 void DecryptingDemuxerStream::CompleteWaitingForDecryptionKey() {
416   DCHECK_EQ(state_, kWaitingForKey);
417   TRACE_EVENT_ASYNC_END0(
418       "media", "DecryptingDemuxerStream::WaitingForDecryptionKey", this);
419 }
420
421 }  // namespace media