[M120 Migration][hbbtv] Audio tracks count notification
[platform/framework/web/chromium-efl.git] / media / filters / decrypting_video_decoder.cc
index b84bd55..1da8104 100644 (file)
@@ -1,17 +1,17 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2012 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #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/sequenced_task_runner.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"
@@ -48,17 +48,17 @@ void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
   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.
     DCHECK(!support_clear_content_);
-    std::move(init_cb_).Run(StatusCode::kDecoderMissingCdmForEncryptedContent);
+    std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
     return;
   }
 
   if (!config.is_encrypted() && !support_clear_content_) {
-    std::move(init_cb_).Run(StatusCode::kClearContentUnsupported);
+    std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
     return;
   }
 
@@ -66,7 +66,7 @@ void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
   // 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);
@@ -75,7 +75,7 @@ void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
   if (state_ == kUninitialized) {
     if (!cdm_context->GetDecryptor()) {
       DVLOG(1) << __func__ << ": no decryptor";
-      std::move(init_cb_).Run(StatusCode::kDecoderFailedInitialization);
+      std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
       return;
     }
 
@@ -91,7 +91,7 @@ void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
 
   state_ = kPendingDecoderInit;
   decryptor_->InitializeVideoDecoder(
-      config_, BindToCurrentLoop(
+      config_, base::BindPostTaskToCurrentDefault(
                    base::BindOnce(&DecryptingVideoDecoder::FinishInitialization,
                                   weak_factory_.GetWeakPtr())));
 }
@@ -109,19 +109,34 @@ void DecryptingVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
   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(DecodeStatus::DECODE_ERROR);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure);
     return;
   }
 
   // Return empty frames if decoding has finished.
   if (state_ == kDecodeFinished) {
-    std::move(decode_cb_).Run(DecodeStatus::OK);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kOk);
     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();
@@ -137,7 +152,7 @@ void DecryptingVideoDecoder::Reset(base::OnceClosure closure) {
   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);
 
@@ -154,7 +169,7 @@ void DecryptingVideoDecoder::Reset(base::OnceClosure closure) {
     CompleteWaitingForDecryptionKey();
     DCHECK(decode_cb_);
     pending_buffer_to_decode_.reset();
-    std::move(decode_cb_).Run(DecodeStatus::ABORTED);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted);
   }
 
   DCHECK(!decode_cb_);
@@ -178,9 +193,9 @@ DecryptingVideoDecoder::~DecryptingVideoDecoder() {
   }
   pending_buffer_to_decode_.reset();
   if (init_cb_)
-    std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted);
+    std::move(init_cb_).Run(DecoderStatus::Codes::kInterrupted);
   if (decode_cb_)
-    std::move(decode_cb_).Run(DecodeStatus::ABORTED);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted);
   if (reset_cb_)
     std::move(reset_cb_).Run();
 }
@@ -195,7 +210,9 @@ void DecryptingVideoDecoder::FinishInitialization(bool success) {
 
   if (!success) {
     DVLOG(1) << __func__ << ": failed to init video decoder on decryptor";
-    std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted);
+    // TODO(*) Is there a better reason? Should this method itself take a
+    // status?
+    std::move(init_cb_).Run(DecoderStatus::Codes::kFailed);
     decryptor_ = nullptr;
     event_cb_registration_.reset();
     state_ = kError;
@@ -204,26 +221,37 @@ void DecryptingVideoDecoder::FinishInitialization(bool success) {
 
   // Success!
   state_ = kIdle;
-  std::move(init_cb_).Run(OkStatus());
+  std::move(init_cb_).Run(DecoderStatus::Codes::kOk);
 }
 
 void DecryptingVideoDecoder::DecodePendingBuffer() {
   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())));
 }
 
@@ -243,7 +271,7 @@ void DecryptingVideoDecoder::DeliverFrame(Decryptor::Status status,
       std::move(pending_buffer_to_decode_);
 
   if (reset_cb_) {
-    std::move(decode_cb_).Run(DecodeStatus::ABORTED);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted);
     DoReset();
     return;
   }
@@ -254,7 +282,7 @@ void DecryptingVideoDecoder::DeliverFrame(Decryptor::Status status,
     DVLOG(2) << "DeliverFrame() - kError";
     MEDIA_LOG(ERROR, media_log_) << GetDecoderType() << ": decode error";
     state_ = kError;
-    std::move(decode_cb_).Run(DecodeStatus::DECODE_ERROR);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure);
     return;
   }
 
@@ -279,7 +307,7 @@ void DecryptingVideoDecoder::DeliverFrame(Decryptor::Status status,
       return;
     }
 
-    TRACE_EVENT_ASYNC_BEGIN0(
+    TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
         "media", "DecryptingVideoDecoder::WaitingForDecryptionKey", this);
     state_ = kWaitingForKey;
     waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
@@ -290,7 +318,7 @@ void DecryptingVideoDecoder::DeliverFrame(Decryptor::Status status,
     DVLOG(2) << "DeliverFrame() - kNeedMoreData";
     state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished
                                                               : kIdle;
-    std::move(decode_cb_).Run(DecodeStatus::OK);
+    std::move(decode_cb_).Run(DecoderStatus::Codes::kOk);
     return;
   }
 
@@ -318,7 +346,7 @@ void DecryptingVideoDecoder::DeliverFrame(Decryptor::Status status,
   }
 
   state_ = kIdle;
-  std::move(decode_cb_).Run(DecodeStatus::OK);
+  std::move(decode_cb_).Run(DecoderStatus::Codes::kOk);
 }
 
 void DecryptingVideoDecoder::OnCdmContextEvent(CdmContext::Event event) {
@@ -351,13 +379,14 @@ void DecryptingVideoDecoder::DoReset() {
 
 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);
 }