#include "media/filters/decrypting_video_decoder.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/trace_event/trace_event.h"
-#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_context.h"
#include "media/base/decoder_buffer.h"
#include "media/base/media_log.h"
DCHECK(!reset_cb_);
DCHECK(config.IsValidConfig());
- init_cb_ = BindToCurrentLoop(std::move(init_cb));
+ init_cb_ = base::BindPostTaskToCurrentDefault(std::move(init_cb));
if (!cdm_context) {
// Once we have a CDM context, one should always be present.
// the decryptor for clear content as well.
support_clear_content_ = true;
- output_cb_ = BindToCurrentLoop(output_cb);
+ output_cb_ = base::BindPostTaskToCurrentDefault(output_cb);
config_ = config;
DCHECK(waiting_cb);
state_ = kPendingDecoderInit;
decryptor_->InitializeVideoDecoder(
- config_, BindToCurrentLoop(
+ config_, base::BindPostTaskToCurrentDefault(
base::BindOnce(&DecryptingVideoDecoder::FinishInitialization,
weak_factory_.GetWeakPtr())));
}
DCHECK(decode_cb);
CHECK(!decode_cb_) << "Overlapping decodes are not supported.";
- decode_cb_ = BindToCurrentLoop(std::move(decode_cb));
+ decode_cb_ = base::BindPostTaskToCurrentDefault(std::move(decode_cb));
if (state_ == kError) {
std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure);
return;
}
+ // One time set of `has_clear_lead_`.
+ if (!has_clear_lead_.has_value()) {
+ has_clear_lead_ = !buffer->end_of_stream() && !buffer->decrypt_config();
+ }
+
+ // Although the stream may switch from clear to encrypted to clear multiple
+ // times (e.g ad-insertions), we only log to the Media log the first switch
+ // from clear to encrypted.
+ if (HasClearLead() && !switched_clear_to_encrypted_ &&
+ !buffer->end_of_stream() && buffer->is_encrypted()) {
+ MEDIA_LOG(INFO, media_log_)
+ << "First switch from clear to encrypted buffers.";
+ switched_clear_to_encrypted_ = true;
+ }
+
pending_buffer_to_decode_ = std::move(buffer);
state_ = kPendingDecode;
DecodePendingBuffer();
DCHECK(!init_cb_); // No Reset() during pending initialization.
DCHECK(!reset_cb_);
- reset_cb_ = BindToCurrentLoop(std::move(closure));
+ reset_cb_ = base::BindPostTaskToCurrentDefault(std::move(closure));
decryptor_->ResetDecoder(Decryptor::kVideo);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(state_, kPendingDecode) << state_;
+ auto& buffer = pending_buffer_to_decode_;
+
// Note: Traces require a unique ID per decode, if we ever support multiple
// in flight decodes, the trace begin+end macros need the same unique id.
DCHECK_EQ(GetMaxDecodeRequests(), 1);
- TRACE_EVENT_ASYNC_BEGIN1(
+ const bool is_end_of_stream = buffer->end_of_stream();
+ const bool is_encrypted = !is_end_of_stream && buffer->decrypt_config();
+ const auto timestamp_us =
+ is_end_of_stream ? 0 : buffer->timestamp().InMicroseconds();
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
"media", "DecryptingVideoDecoder::DecodePendingBuffer", this,
- "timestamp_us",
- pending_buffer_to_decode_->end_of_stream()
- ? 0
- : pending_buffer_to_decode_->timestamp().InMicroseconds());
+ "is_encrypted", is_encrypted, "timestamp_us", timestamp_us);
+
+ if (!DecoderBuffer::DoSubsamplesMatch(*buffer)) {
+ MEDIA_LOG(ERROR, media_log_)
+ << "DecryptingVideoDecoder: Subsamples for Buffer do not match";
+ state_ = kError;
+ std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure);
+ return;
+ }
decryptor_->DecryptAndDecodeVideo(
- pending_buffer_to_decode_,
- BindToCurrentLoop(base::BindRepeating(
+ buffer,
+ base::BindPostTaskToCurrentDefault(base::BindRepeating(
&DecryptingVideoDecoder::DeliverFrame, weak_factory_.GetWeakPtr())));
}
return;
}
- TRACE_EVENT_ASYNC_BEGIN0(
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
"media", "DecryptingVideoDecoder::WaitingForDecryptionKey", this);
state_ = kWaitingForKey;
waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
void DecryptingVideoDecoder::CompletePendingDecode(Decryptor::Status status) {
DCHECK_EQ(state_, kPendingDecode);
- TRACE_EVENT_ASYNC_END1("media", "DecryptingVideoDecoder::DecodePendingBuffer",
- this, "status", Decryptor::GetStatusName(status));
+ TRACE_EVENT_NESTABLE_ASYNC_END1(
+ "media", "DecryptingVideoDecoder::DecodePendingBuffer", this, "status",
+ Decryptor::GetStatusName(status));
}
void DecryptingVideoDecoder::CompleteWaitingForDecryptionKey() {
DCHECK_EQ(state_, kWaitingForKey);
- TRACE_EVENT_ASYNC_END0(
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
"media", "DecryptingVideoDecoder::WaitingForDecryptionKey", this);
}