decrypting_video_decoder.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/filters/decrypting_video_decoder.h"
  5. #include "base/bind.h"
  6. #include "base/callback_helpers.h"
  7. #include "base/location.h"
  8. #include "base/logging.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "base/task/sequenced_task_runner.h"
  11. #include "base/trace_event/trace_event.h"
  12. #include "media/base/bind_to_current_loop.h"
  13. #include "media/base/cdm_context.h"
  14. #include "media/base/decoder_buffer.h"
  15. #include "media/base/media_log.h"
  16. #include "media/base/video_frame.h"
  17. namespace media {
  18. const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder";
  19. DecryptingVideoDecoder::DecryptingVideoDecoder(
  20. const scoped_refptr<base::SequencedTaskRunner>& task_runner,
  21. MediaLog* media_log)
  22. : task_runner_(task_runner), media_log_(media_log) {
  23. DETACH_FROM_SEQUENCE(sequence_checker_);
  24. }
  25. VideoDecoderType DecryptingVideoDecoder::GetDecoderType() const {
  26. return VideoDecoderType::kDecrypting;
  27. }
  28. void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
  29. bool /* low_delay */,
  30. CdmContext* cdm_context,
  31. InitCB init_cb,
  32. const OutputCB& output_cb,
  33. const WaitingCB& waiting_cb) {
  34. DVLOG(2) << __func__ << ": " << config.AsHumanReadableString();
  35. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  36. DCHECK(state_ == kUninitialized || state_ == kIdle ||
  37. state_ == kDecodeFinished)
  38. << state_;
  39. DCHECK(!decode_cb_);
  40. DCHECK(!reset_cb_);
  41. DCHECK(config.IsValidConfig());
  42. init_cb_ = BindToCurrentLoop(std::move(init_cb));
  43. if (!cdm_context) {
  44. // Once we have a CDM context, one should always be present.
  45. DCHECK(!support_clear_content_);
  46. std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
  47. return;
  48. }
  49. if (!config.is_encrypted() && !support_clear_content_) {
  50. std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
  51. return;
  52. }
  53. // Once initialized with encryption support, the value is sticky, so we'll use
  54. // the decryptor for clear content as well.
  55. support_clear_content_ = true;
  56. output_cb_ = BindToCurrentLoop(output_cb);
  57. config_ = config;
  58. DCHECK(waiting_cb);
  59. waiting_cb_ = waiting_cb;
  60. if (state_ == kUninitialized) {
  61. if (!cdm_context->GetDecryptor()) {
  62. DVLOG(1) << __func__ << ": no decryptor";
  63. std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode);
  64. return;
  65. }
  66. decryptor_ = cdm_context->GetDecryptor();
  67. event_cb_registration_ = cdm_context->RegisterEventCB(
  68. base::BindRepeating(&DecryptingVideoDecoder::OnCdmContextEvent,
  69. weak_factory_.GetWeakPtr()));
  70. } else {
  71. // Reinitialization (i.e. upon a config change). The new config can be
  72. // encrypted or clear.
  73. decryptor_->DeinitializeDecoder(Decryptor::kVideo);
  74. }
  75. state_ = kPendingDecoderInit;
  76. decryptor_->InitializeVideoDecoder(
  77. config_, BindToCurrentLoop(
  78. base::BindOnce(&DecryptingVideoDecoder::FinishInitialization,
  79. weak_factory_.GetWeakPtr())));
  80. }
  81. bool DecryptingVideoDecoder::SupportsDecryption() const {
  82. return true;
  83. }
  84. void DecryptingVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
  85. DecodeCB decode_cb) {
  86. DVLOG(3) << "Decode()";
  87. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  88. DCHECK(state_ == kIdle || state_ == kDecodeFinished || state_ == kError)
  89. << state_;
  90. DCHECK(decode_cb);
  91. CHECK(!decode_cb_) << "Overlapping decodes are not supported.";
  92. decode_cb_ = BindToCurrentLoop(std::move(decode_cb));
  93. if (state_ == kError) {
  94. std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure);
  95. return;
  96. }
  97. // Return empty frames if decoding has finished.
  98. if (state_ == kDecodeFinished) {
  99. std::move(decode_cb_).Run(DecoderStatus::Codes::kOk);
  100. return;
  101. }
  102. pending_buffer_to_decode_ = std::move(buffer);
  103. state_ = kPendingDecode;
  104. DecodePendingBuffer();
  105. }
  106. void DecryptingVideoDecoder::Reset(base::OnceClosure closure) {
  107. DVLOG(2) << "Reset() - state: " << state_;
  108. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  109. DCHECK(state_ == kIdle || state_ == kPendingDecode ||
  110. state_ == kWaitingForKey || state_ == kDecodeFinished ||
  111. state_ == kError)
  112. << state_;
  113. DCHECK(!init_cb_); // No Reset() during pending initialization.
  114. DCHECK(!reset_cb_);
  115. reset_cb_ = BindToCurrentLoop(std::move(closure));
  116. decryptor_->ResetDecoder(Decryptor::kVideo);
  117. // Reset() cannot complete if the decode callback is still pending.
  118. // Defer the resetting process in this case. The |reset_cb_| will be fired
  119. // after the decode callback is fired - see DecryptAndDecodeBuffer() and
  120. // DeliverFrame().
  121. if (state_ == kPendingDecode) {
  122. DCHECK(decode_cb_);
  123. return;
  124. }
  125. if (state_ == kWaitingForKey) {
  126. CompleteWaitingForDecryptionKey();
  127. DCHECK(decode_cb_);
  128. pending_buffer_to_decode_.reset();
  129. std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted);
  130. }
  131. DCHECK(!decode_cb_);
  132. DoReset();
  133. }
  134. DecryptingVideoDecoder::~DecryptingVideoDecoder() {
  135. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  136. if (state_ == kUninitialized)
  137. return;
  138. if (state_ == kWaitingForKey)
  139. CompleteWaitingForDecryptionKey();
  140. if (state_ == kPendingDecode)
  141. CompletePendingDecode(Decryptor::kError);
  142. if (decryptor_) {
  143. decryptor_->DeinitializeDecoder(Decryptor::kVideo);
  144. decryptor_ = nullptr;
  145. }
  146. pending_buffer_to_decode_.reset();
  147. if (init_cb_)
  148. std::move(init_cb_).Run(DecoderStatus::Codes::kInterrupted);
  149. if (decode_cb_)
  150. std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted);
  151. if (reset_cb_)
  152. std::move(reset_cb_).Run();
  153. }
  154. void DecryptingVideoDecoder::FinishInitialization(bool success) {
  155. DVLOG(2) << "FinishInitialization()";
  156. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  157. DCHECK_EQ(state_, kPendingDecoderInit) << state_;
  158. DCHECK(init_cb_);
  159. DCHECK(!reset_cb_); // No Reset() before initialization finished.
  160. DCHECK(!decode_cb_); // No Decode() before initialization finished.
  161. if (!success) {
  162. DVLOG(1) << __func__ << ": failed to init video decoder on decryptor";
  163. // TODO(*) Is there a better reason? Should this method itself take a
  164. // status?
  165. std::move(init_cb_).Run(DecoderStatus::Codes::kFailed);
  166. decryptor_ = nullptr;
  167. event_cb_registration_.reset();
  168. state_ = kError;
  169. return;
  170. }
  171. // Success!
  172. state_ = kIdle;
  173. std::move(init_cb_).Run(DecoderStatus::Codes::kOk);
  174. }
  175. void DecryptingVideoDecoder::DecodePendingBuffer() {
  176. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  177. DCHECK_EQ(state_, kPendingDecode) << state_;
  178. // Note: Traces require a unique ID per decode, if we ever support multiple
  179. // in flight decodes, the trace begin+end macros need the same unique id.
  180. DCHECK_EQ(GetMaxDecodeRequests(), 1);
  181. TRACE_EVENT_ASYNC_BEGIN1(
  182. "media", "DecryptingVideoDecoder::DecodePendingBuffer", this,
  183. "timestamp_us",
  184. pending_buffer_to_decode_->end_of_stream()
  185. ? 0
  186. : pending_buffer_to_decode_->timestamp().InMicroseconds());
  187. decryptor_->DecryptAndDecodeVideo(
  188. pending_buffer_to_decode_,
  189. BindToCurrentLoop(base::BindRepeating(
  190. &DecryptingVideoDecoder::DeliverFrame, weak_factory_.GetWeakPtr())));
  191. }
  192. void DecryptingVideoDecoder::DeliverFrame(Decryptor::Status status,
  193. scoped_refptr<VideoFrame> frame) {
  194. DVLOG(3) << "DeliverFrame() - status: " << status;
  195. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  196. DCHECK_EQ(state_, kPendingDecode) << state_;
  197. DCHECK(decode_cb_);
  198. DCHECK(pending_buffer_to_decode_.get());
  199. CompletePendingDecode(status);
  200. bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_;
  201. key_added_while_decode_pending_ = false;
  202. scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode =
  203. std::move(pending_buffer_to_decode_);
  204. if (reset_cb_) {
  205. std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted);
  206. DoReset();
  207. return;
  208. }
  209. DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != nullptr);
  210. if (status == Decryptor::kError) {
  211. DVLOG(2) << "DeliverFrame() - kError";
  212. MEDIA_LOG(ERROR, media_log_) << GetDecoderType() << ": decode error";
  213. state_ = kError;
  214. std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure);
  215. return;
  216. }
  217. if (status == Decryptor::kNoKey) {
  218. std::string key_id =
  219. scoped_pending_buffer_to_decode->decrypt_config()->key_id();
  220. std::string log_message =
  221. "no key for key ID " + base::HexEncode(key_id.data(), key_id.size()) +
  222. "; will resume decoding after new usable key is available";
  223. DVLOG(1) << __func__ << ": " << log_message;
  224. MEDIA_LOG(INFO, media_log_) << GetDecoderType() << ": " << log_message;
  225. // Set |pending_buffer_to_decode_| back as we need to try decoding the
  226. // pending buffer again when new key is added to the decryptor.
  227. pending_buffer_to_decode_ = std::move(scoped_pending_buffer_to_decode);
  228. if (need_to_try_again_if_nokey_is_returned) {
  229. // The |state_| is still kPendingDecode.
  230. MEDIA_LOG(INFO, media_log_)
  231. << GetDecoderType() << ": key was added, resuming decode";
  232. DecodePendingBuffer();
  233. return;
  234. }
  235. TRACE_EVENT_ASYNC_BEGIN0(
  236. "media", "DecryptingVideoDecoder::WaitingForDecryptionKey", this);
  237. state_ = kWaitingForKey;
  238. waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
  239. return;
  240. }
  241. if (status == Decryptor::kNeedMoreData) {
  242. DVLOG(2) << "DeliverFrame() - kNeedMoreData";
  243. state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished
  244. : kIdle;
  245. std::move(decode_cb_).Run(DecoderStatus::Codes::kOk);
  246. return;
  247. }
  248. DCHECK_EQ(status, Decryptor::kSuccess);
  249. CHECK(frame);
  250. // Frame returned with kSuccess should not be an end-of-stream frame.
  251. DCHECK(!frame->metadata().end_of_stream);
  252. // If color space is not set, use the color space in the |config_|.
  253. if (!frame->ColorSpace().IsValid()) {
  254. DVLOG(3) << "Setting color space using information in the config.";
  255. if (config_.color_space_info().IsSpecified())
  256. frame->set_color_space(config_.color_space_info().ToGfxColorSpace());
  257. }
  258. output_cb_.Run(std::move(frame));
  259. if (scoped_pending_buffer_to_decode->end_of_stream()) {
  260. // Set |pending_buffer_to_decode_| back as we need to keep flushing the
  261. // decryptor.
  262. pending_buffer_to_decode_ = std::move(scoped_pending_buffer_to_decode);
  263. DecodePendingBuffer();
  264. return;
  265. }
  266. state_ = kIdle;
  267. std::move(decode_cb_).Run(DecoderStatus::Codes::kOk);
  268. }
  269. void DecryptingVideoDecoder::OnCdmContextEvent(CdmContext::Event event) {
  270. DVLOG(2) << __func__;
  271. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  272. if (event != CdmContext::Event::kHasAdditionalUsableKey)
  273. return;
  274. if (state_ == kPendingDecode) {
  275. key_added_while_decode_pending_ = true;
  276. return;
  277. }
  278. if (state_ == kWaitingForKey) {
  279. CompleteWaitingForDecryptionKey();
  280. MEDIA_LOG(INFO, media_log_)
  281. << GetDecoderType() << ": key added, resuming decode";
  282. state_ = kPendingDecode;
  283. DecodePendingBuffer();
  284. }
  285. }
  286. void DecryptingVideoDecoder::DoReset() {
  287. DCHECK(!init_cb_);
  288. DCHECK(!decode_cb_);
  289. state_ = kIdle;
  290. std::move(reset_cb_).Run();
  291. }
  292. void DecryptingVideoDecoder::CompletePendingDecode(Decryptor::Status status) {
  293. DCHECK_EQ(state_, kPendingDecode);
  294. TRACE_EVENT_ASYNC_END1("media", "DecryptingVideoDecoder::DecodePendingBuffer",
  295. this, "status", Decryptor::GetStatusName(status));
  296. }
  297. void DecryptingVideoDecoder::CompleteWaitingForDecryptionKey() {
  298. DCHECK_EQ(state_, kWaitingForKey);
  299. TRACE_EVENT_ASYNC_END0(
  300. "media", "DecryptingVideoDecoder::WaitingForDecryptionKey", this);
  301. }
  302. } // namespace media