Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: media/base/android/media_codec_loop.cc

Issue 2132653002: MediaCodecLoop unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added some tests Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/android/media_codec_loop.h" 5 #include "media/base/android/media_codec_loop.h"
6 6
7 #include "base/android/build_info.h" 7 // TODO(liberato): do something
8 //#include "base/android/build_info.h"
8 #include "base/bind.h" 9 #include "base/bind.h"
9 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/threading/thread_task_runner_handle.h"
12 #include "media/base/android/sdk_media_codec_bridge.h"
13 #include "media/base/audio_buffer.h" 12 #include "media/base/audio_buffer.h"
14 #include "media/base/audio_timestamp_helper.h" 13 #include "media/base/audio_timestamp_helper.h"
15 #include "media/base/bind_to_current_loop.h" 14 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/timestamp_constants.h" 15 #include "media/base/timestamp_constants.h"
17 16
18 namespace media { 17 namespace media {
19 18
20 constexpr base::TimeDelta kDecodePollDelay = 19 constexpr base::TimeDelta kDecodePollDelay =
21 base::TimeDelta::FromMilliseconds(10); 20 base::TimeDelta::FromMilliseconds(10);
22 constexpr base::TimeDelta kNoWaitTimeout = base::TimeDelta::FromMicroseconds(0); 21 constexpr base::TimeDelta kNoWaitTimeout = base::TimeDelta::FromMicroseconds(0);
23 constexpr base::TimeDelta kIdleTimerTimeout = base::TimeDelta::FromSeconds(1); 22 constexpr base::TimeDelta kIdleTimerTimeout = base::TimeDelta::FromSeconds(1);
24 23
25 static inline bool codec_flush_requires_destruction() { 24 static inline bool codec_flush_requires_destruction() {
26 // Return true if and only if Flush() isn't supported / doesn't work. 25 // Return true if and only if Flush() isn't supported / doesn't work.
27 // Prior to JellyBean-MR2, flush() had several bugs (b/8125974, b/8347958) so 26 // Prior to JellyBean-MR2, flush() had several bugs (b/8125974, b/8347958) so
28 // we have to completely destroy and recreate the codec there. 27 // we have to completely destroy and recreate the codec there.
29 return base::android::BuildInfo::GetInstance()->sdk_int() < 18; 28 // return base::android::BuildInfo::GetInstance()->sdk_int() < 18;
29 // TODO(liberato): testing
30 return false;
30 } 31 }
31 32
32 MediaCodecLoop::InputData::InputData() {} 33 MediaCodecLoop::InputData::InputData() {}
33 34
34 MediaCodecLoop::InputData::InputData(const InputData& other) 35 MediaCodecLoop::InputData::InputData(const InputData& other)
35 : memory(other.memory), 36 : memory(other.memory),
36 length(other.length), 37 length(other.length),
37 key_id(other.key_id), 38 key_id(other.key_id),
38 iv(other.iv), 39 iv(other.iv),
39 subsamples(other.subsamples), 40 subsamples(other.subsamples),
40 presentation_time(other.presentation_time), 41 presentation_time(other.presentation_time),
41 completion_cb(other.completion_cb), 42 completion_cb(other.completion_cb),
42 is_eos(other.is_eos), 43 is_eos(other.is_eos),
43 is_encrypted(other.is_encrypted) {} 44 is_encrypted(other.is_encrypted) {}
44 45
45 MediaCodecLoop::InputData::~InputData() {} 46 MediaCodecLoop::InputData::~InputData() {}
46 47
47 MediaCodecLoop::MediaCodecLoop(Client* client, 48 MediaCodecLoop::MediaCodecLoop(
48 std::unique_ptr<MediaCodecBridge> media_codec) 49 Client* client,
50 std::unique_ptr<MediaCodecBridge> media_codec,
51 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
49 : state_(STATE_READY), 52 : state_(STATE_READY),
50 client_(client), 53 client_(client),
51 media_codec_(std::move(media_codec)), 54 media_codec_(std::move(media_codec)),
52 pending_input_buf_index_(kInvalidBufferIndex), 55 pending_input_buf_index_(kInvalidBufferIndex),
53 weak_factory_(this) { 56 weak_factory_(this) {
57 if (task_runner)
58 io_timer_.SetTaskRunner(task_runner);
54 // TODO(liberato): should this DCHECK? 59 // TODO(liberato): should this DCHECK?
55 if (media_codec_ == nullptr) 60 if (media_codec_ == nullptr)
56 SetState(STATE_ERROR); 61 SetState(STATE_ERROR);
57 } 62 }
58 63
59 MediaCodecLoop::~MediaCodecLoop() {} 64 MediaCodecLoop::~MediaCodecLoop() {}
60 65
66 void MediaCodecLoop::SetTestTickClock(base::TickClock* test_tick_clock) {
67 test_tick_clock_ = test_tick_clock;
68 }
69
61 void MediaCodecLoop::OnKeyAdded() { 70 void MediaCodecLoop::OnKeyAdded() {
62 if (state_ == STATE_WAITING_FOR_KEY) 71 if (state_ == STATE_WAITING_FOR_KEY)
63 SetState(STATE_READY); 72 SetState(STATE_READY);
64 73
65 DoPendingWork(); 74 DoPendingWork();
66 } 75 }
67 76
68 bool MediaCodecLoop::TryFlush() { 77 bool MediaCodecLoop::TryFlush() {
69 // We do not clear the input queue here. It depends on the caller. 78 // We do not clear the input queue here. It depends on the caller.
70 // For decoder reset, then it is appropriate. Otherwise, the requests might 79 // For decoder reset, then it is appropriate. Otherwise, the requests might
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 // should not be asked to decode again. 280 // should not be asked to decode again.
272 DCHECK_EQ(state_, STATE_DRAINING); 281 DCHECK_EQ(state_, STATE_DRAINING);
273 SetState(STATE_DRAINED); 282 SetState(STATE_DRAINED);
274 283
275 DCHECK_NE(out.index, kInvalidBufferIndex); 284 DCHECK_NE(out.index, kInvalidBufferIndex);
276 DCHECK(media_codec_); 285 DCHECK(media_codec_);
277 286
278 media_codec_->ReleaseOutputBuffer(out.index, false); 287 media_codec_->ReleaseOutputBuffer(out.index, false);
279 288
280 // Run the EOS completion callback now, since we deferred it until 289 // Run the EOS completion callback now, since we deferred it until
281 // the EOS was completely processed. 290 // the EOS was completely processed. If there is no EOS callback, then
282 pending_eos_completion_cb_.Run(DecodeStatus::OK); 291 // this is an unsolicited EOS. Skip the callback since it will crash,
292 // but still notify the client.
293 if (!pending_eos_completion_cb_.is_null())
294 pending_eos_completion_cb_.Run(DecodeStatus::OK);
283 pending_eos_completion_cb_ = DecodeCB(); 295 pending_eos_completion_cb_ = DecodeCB();
284 296
285 client_->OnDecodedEos(out); 297 client_->OnDecodedEos(out);
286 } else { 298 } else {
287 if (!client_->OnDecodedFrame(out)) 299 if (!client_->OnDecodedFrame(out))
288 SetState(STATE_ERROR); 300 SetState(STATE_ERROR);
289 } 301 }
290 302
291 did_work = true; 303 did_work = true;
292 break; 304 break;
(...skipping 13 matching lines...) Expand all
306 SetState(STATE_ERROR); 318 SetState(STATE_ERROR);
307 break; 319 break;
308 } 320 }
309 321
310 return did_work; 322 return did_work;
311 } 323 }
312 324
313 void MediaCodecLoop::ManageTimer(bool did_work) { 325 void MediaCodecLoop::ManageTimer(bool did_work) {
314 bool should_be_running = true; 326 bool should_be_running = true;
315 327
316 base::TimeTicks now = base::TimeTicks::Now(); 328 // One might also use DefaultTickClock, but then ownership becomes harder.
329 base::TimeTicks now = (test_tick_clock_ ? test_tick_clock_->NowTicks()
330 : base::TimeTicks::Now());
317 if (did_work || idle_time_begin_ == base::TimeTicks()) { 331 if (did_work || idle_time_begin_ == base::TimeTicks()) {
318 idle_time_begin_ = now; 332 idle_time_begin_ = now;
319 } else { 333 } else {
320 // Make sure that we have done work recently enough, else stop the timer. 334 // Make sure that we have done work recently enough, else stop the timer.
321 if (now - idle_time_begin_ > kIdleTimerTimeout) 335 if (now - idle_time_begin_ > kIdleTimerTimeout)
322 should_be_running = false; 336 should_be_running = false;
323 } 337 }
324 338
325 if (should_be_running && !io_timer_.IsRunning()) { 339 if (should_be_running && !io_timer_.IsRunning()) {
326 io_timer_.Start(FROM_HERE, kDecodePollDelay, this, 340 io_timer_.Start(FROM_HERE, kDecodePollDelay, this,
(...skipping 27 matching lines...) Expand all
354 RETURN_STRING(STATE_DRAINED); 368 RETURN_STRING(STATE_DRAINED);
355 RETURN_STRING(STATE_ERROR); 369 RETURN_STRING(STATE_ERROR);
356 } 370 }
357 #undef RETURN_STRING 371 #undef RETURN_STRING
358 372
359 NOTREACHED() << "Unknown state " << state; 373 NOTREACHED() << "Unknown state " << state;
360 return nullptr; 374 return nullptr;
361 } 375 }
362 376
363 } // namespace media 377 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698