fake_video_decoder.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright 2013 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/fake_video_decoder.h"
  5. #include "base/location.h"
  6. #include "media/base/bind_to_current_loop.h"
  7. #include "media/base/test_helpers.h"
  8. namespace media {
  9. FakeVideoDecoder::FakeVideoDecoder(int decoder_id,
  10. int decoding_delay,
  11. int max_parallel_decoding_requests,
  12. const BytesDecodedCB& bytes_decoded_cb)
  13. : decoder_id_(decoder_id),
  14. decoding_delay_(decoding_delay),
  15. max_parallel_decoding_requests_(max_parallel_decoding_requests),
  16. bytes_decoded_cb_(bytes_decoded_cb),
  17. state_(STATE_UNINITIALIZED),
  18. hold_decode_(false),
  19. total_bytes_decoded_(0),
  20. fail_to_initialize_(false) {
  21. DETACH_FROM_SEQUENCE(sequence_checker_);
  22. DVLOG(1) << decoder_id_ << ": " << __func__;
  23. DCHECK_GE(decoding_delay, 0);
  24. }
  25. FakeVideoDecoder::~FakeVideoDecoder() {
  26. DVLOG(1) << decoder_id_ << ": " << __func__;
  27. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  28. if (state_ == STATE_UNINITIALIZED)
  29. return;
  30. if (!init_cb_.IsNull())
  31. SatisfyInit();
  32. if (!held_decode_callbacks_.empty())
  33. SatisfyDecode();
  34. if (!reset_cb_.IsNull())
  35. SatisfyReset();
  36. decoded_frames_.clear();
  37. }
  38. void FakeVideoDecoder::EnableEncryptedConfigSupport() {
  39. supports_encrypted_config_ = true;
  40. }
  41. void FakeVideoDecoder::SetIsPlatformDecoder(bool value) {
  42. is_platform_decoder_ = value;
  43. }
  44. base::WeakPtr<FakeVideoDecoder> FakeVideoDecoder::GetWeakPtr() {
  45. return weak_factory_.GetWeakPtr();
  46. }
  47. bool FakeVideoDecoder::SupportsDecryption() const {
  48. return supports_encrypted_config_;
  49. }
  50. bool FakeVideoDecoder::IsPlatformDecoder() const {
  51. return is_platform_decoder_;
  52. }
  53. VideoDecoderType FakeVideoDecoder::GetDecoderType() const {
  54. return VideoDecoderType::kTesting;
  55. }
  56. void FakeVideoDecoder::Initialize(const VideoDecoderConfig& config,
  57. bool low_delay,
  58. CdmContext* cdm_context,
  59. InitCB init_cb,
  60. const OutputCB& output_cb,
  61. const WaitingCB& waiting_cb) {
  62. DVLOG(1) << decoder_id_ << ": " << __func__;
  63. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  64. DCHECK(config.IsValidConfig());
  65. DCHECK(held_decode_callbacks_.empty())
  66. << "No reinitialization during pending decode.";
  67. DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset.";
  68. current_config_ = config;
  69. init_cb_.SetCallback(BindToCurrentLoop(std::move(init_cb)));
  70. // Don't need BindToCurrentLoop() because |output_cb_| is only called from
  71. // RunDecodeCallback() which is posted from Decode().
  72. output_cb_ = output_cb;
  73. if (!decoded_frames_.empty()) {
  74. DVLOG(1) << "Decoded frames dropped during reinitialization.";
  75. decoded_frames_.clear();
  76. }
  77. if (config.is_encrypted() && (!supports_encrypted_config_ || !cdm_context)) {
  78. DVLOG(1) << "Encrypted config not supported.";
  79. state_ = STATE_NORMAL;
  80. init_cb_.RunOrHold(DecoderStatus::Codes::kUnsupportedEncryptionMode);
  81. return;
  82. }
  83. if (fail_to_initialize_) {
  84. DVLOG(1) << decoder_id_ << ": Initialization failed.";
  85. state_ = STATE_ERROR;
  86. init_cb_.RunOrHold(DecoderStatus::Codes::kFailed);
  87. } else {
  88. DVLOG(1) << decoder_id_ << ": Initialization succeeded.";
  89. state_ = STATE_NORMAL;
  90. init_cb_.RunOrHold(DecoderStatus::Codes::kOk);
  91. }
  92. }
  93. void FakeVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
  94. DecodeCB decode_cb) {
  95. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  96. DCHECK(reset_cb_.IsNull());
  97. DCHECK_LE(decoded_frames_.size(),
  98. decoding_delay_ + held_decode_callbacks_.size());
  99. DCHECK_LT(static_cast<int>(held_decode_callbacks_.size()),
  100. max_parallel_decoding_requests_);
  101. DCHECK_NE(state_, STATE_END_OF_STREAM);
  102. int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
  103. DecodeCB wrapped_decode_cb = base::BindOnce(
  104. &FakeVideoDecoder::OnFrameDecoded, weak_factory_.GetWeakPtr(),
  105. buffer_size, BindToCurrentLoop(std::move(decode_cb)));
  106. if (state_ == STATE_ERROR) {
  107. std::move(wrapped_decode_cb).Run(DecoderStatus::Codes::kFailed);
  108. return;
  109. }
  110. if (buffer->end_of_stream()) {
  111. state_ = STATE_END_OF_STREAM;
  112. } else {
  113. DCHECK(VerifyFakeVideoBufferForTest(*buffer, current_config_));
  114. decoded_frames_.push_back(MakeVideoFrame(*buffer));
  115. }
  116. RunOrHoldDecode(std::move(wrapped_decode_cb));
  117. }
  118. scoped_refptr<VideoFrame> FakeVideoDecoder::MakeVideoFrame(
  119. const DecoderBuffer& buffer) {
  120. return VideoFrame::CreateColorFrame(current_config_.coded_size(), 0, 0, 0,
  121. buffer.timestamp());
  122. }
  123. void FakeVideoDecoder::Reset(base::OnceClosure closure) {
  124. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  125. DCHECK(reset_cb_.IsNull());
  126. reset_cb_.SetCallback(BindToCurrentLoop(std::move(closure)));
  127. decoded_frames_.clear();
  128. // Defer the reset if a decode is pending.
  129. if (!held_decode_callbacks_.empty())
  130. return;
  131. DoReset();
  132. }
  133. void FakeVideoDecoder::HoldNextInit() {
  134. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  135. init_cb_.HoldCallback();
  136. }
  137. void FakeVideoDecoder::HoldDecode() {
  138. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  139. hold_decode_ = true;
  140. }
  141. void FakeVideoDecoder::HoldNextReset() {
  142. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  143. reset_cb_.HoldCallback();
  144. }
  145. void FakeVideoDecoder::SatisfyInit() {
  146. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  147. DCHECK(held_decode_callbacks_.empty());
  148. DCHECK(reset_cb_.IsNull());
  149. init_cb_.RunHeldCallback();
  150. }
  151. void FakeVideoDecoder::SatisfyDecode() {
  152. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  153. DCHECK(hold_decode_);
  154. hold_decode_ = false;
  155. while (!held_decode_callbacks_.empty()) {
  156. SatisfySingleDecode();
  157. }
  158. }
  159. void FakeVideoDecoder::SatisfySingleDecode() {
  160. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  161. DCHECK(!held_decode_callbacks_.empty());
  162. DecodeCB decode_cb = std::move(held_decode_callbacks_.front());
  163. held_decode_callbacks_.pop_front();
  164. RunDecodeCallback(std::move(decode_cb));
  165. if (!reset_cb_.IsNull() && held_decode_callbacks_.empty())
  166. DoReset();
  167. }
  168. void FakeVideoDecoder::SatisfyReset() {
  169. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  170. DCHECK(held_decode_callbacks_.empty());
  171. reset_cb_.RunHeldCallback();
  172. }
  173. void FakeVideoDecoder::SimulateError() {
  174. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  175. state_ = STATE_ERROR;
  176. while (!held_decode_callbacks_.empty()) {
  177. std::move(held_decode_callbacks_.front())
  178. .Run(DecoderStatus::Codes::kFailed);
  179. held_decode_callbacks_.pop_front();
  180. }
  181. decoded_frames_.clear();
  182. }
  183. void FakeVideoDecoder::SimulateFailureToInit() {
  184. fail_to_initialize_ = true;
  185. }
  186. int FakeVideoDecoder::GetMaxDecodeRequests() const {
  187. return max_parallel_decoding_requests_;
  188. }
  189. void FakeVideoDecoder::OnFrameDecoded(int buffer_size,
  190. DecodeCB decode_cb,
  191. DecoderStatus status) {
  192. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  193. if (status.is_ok()) {
  194. total_bytes_decoded_ += buffer_size;
  195. if (bytes_decoded_cb_)
  196. bytes_decoded_cb_.Run(buffer_size);
  197. }
  198. std::move(decode_cb).Run(std::move(status));
  199. }
  200. void FakeVideoDecoder::RunOrHoldDecode(DecodeCB decode_cb) {
  201. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  202. if (hold_decode_) {
  203. held_decode_callbacks_.push_back(std::move(decode_cb));
  204. } else {
  205. DCHECK(held_decode_callbacks_.empty());
  206. RunDecodeCallback(std::move(decode_cb));
  207. }
  208. }
  209. void FakeVideoDecoder::RunDecodeCallback(DecodeCB decode_cb) {
  210. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  211. if (!reset_cb_.IsNull()) {
  212. DCHECK(decoded_frames_.empty());
  213. std::move(decode_cb).Run(DecoderStatus::Codes::kAborted);
  214. return;
  215. }
  216. // Make sure we leave decoding_delay_ frames in the queue and also frames for
  217. // all pending decode callbacks, except the current one.
  218. if (decoded_frames_.size() >
  219. decoding_delay_ + held_decode_callbacks_.size()) {
  220. output_cb_.Run(decoded_frames_.front());
  221. decoded_frames_.pop_front();
  222. } else if (state_ == STATE_END_OF_STREAM) {
  223. // Drain the queue if this was the last request in the stream, otherwise
  224. // just pop the last frame from the queue.
  225. if (held_decode_callbacks_.empty()) {
  226. while (!decoded_frames_.empty()) {
  227. output_cb_.Run(decoded_frames_.front());
  228. decoded_frames_.pop_front();
  229. }
  230. state_ = STATE_NORMAL;
  231. } else if (!decoded_frames_.empty()) {
  232. output_cb_.Run(decoded_frames_.front());
  233. decoded_frames_.pop_front();
  234. }
  235. }
  236. std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
  237. }
  238. void FakeVideoDecoder::DoReset() {
  239. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  240. DCHECK(held_decode_callbacks_.empty());
  241. DCHECK(!reset_cb_.IsNull());
  242. reset_cb_.RunOrHold();
  243. }
  244. } // namespace media