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