OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |