Index: media/base/android/media_codec_loop.cc |
diff --git a/media/base/android/media_codec_loop.cc b/media/base/android/media_codec_loop.cc |
index 96c525118dc57e48248769d310bf8907312db5be..1c6ce5e59278fc84a8b6a1056c7c00f40ed83049 100644 |
--- a/media/base/android/media_codec_loop.cc |
+++ b/media/base/android/media_codec_loop.cc |
@@ -4,29 +4,29 @@ |
#include "media/base/android/media_codec_loop.h" |
-#include "base/android/build_info.h" |
#include "base/bind.h" |
#include "base/callback_helpers.h" |
#include "base/logging.h" |
-#include "base/threading/thread_task_runner_handle.h" |
-#include "media/base/android/sdk_media_codec_bridge.h" |
-#include "media/base/audio_buffer.h" |
-#include "media/base/audio_timestamp_helper.h" |
#include "media/base/bind_to_current_loop.h" |
#include "media/base/timestamp_constants.h" |
namespace media { |
-constexpr base::TimeDelta kDecodePollDelay = |
- base::TimeDelta::FromMilliseconds(10); |
-constexpr base::TimeDelta kNoWaitTimeout = base::TimeDelta::FromMicroseconds(0); |
-constexpr base::TimeDelta kIdleTimerTimeout = base::TimeDelta::FromSeconds(1); |
+// Declaring these as constexpr variables doesn't work in windows -- they |
+// always are 0. The exception is FromMicroseconds, which doesn't do any |
+// conversion. However, declaring these as constexpr functions seesm to work |
+// fine everywhere. We care that this works in windows because our unit tests |
+// run on non-android platforms. |
+constexpr base::TimeDelta DecodePollDelay() { |
+ return base::TimeDelta::FromMilliseconds(10); |
+} |
-static inline bool codec_flush_requires_destruction() { |
- // Return true if and only if Flush() isn't supported / doesn't work. |
- // Prior to JellyBean-MR2, flush() had several bugs (b/8125974, b/8347958) so |
- // we have to completely destroy and recreate the codec there. |
- return base::android::BuildInfo::GetInstance()->sdk_int() < 18; |
+constexpr base::TimeDelta NoWaitTimeout() { |
+ return base::TimeDelta::FromMicroseconds(0); |
+} |
+ |
+constexpr base::TimeDelta IdleTimerTimeout() { |
+ return base::TimeDelta::FromSeconds(1); |
} |
MediaCodecLoop::InputData::InputData() {} |
@@ -43,13 +43,19 @@ MediaCodecLoop::InputData::InputData(const InputData& other) |
MediaCodecLoop::InputData::~InputData() {} |
-MediaCodecLoop::MediaCodecLoop(Client* client, |
- std::unique_ptr<MediaCodecBridge> media_codec) |
+MediaCodecLoop::MediaCodecLoop( |
+ int sdk_int, |
+ Client* client, |
+ std::unique_ptr<MediaCodecBridge> media_codec, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
: state_(STATE_READY), |
client_(client), |
media_codec_(std::move(media_codec)), |
pending_input_buf_index_(kInvalidBufferIndex), |
+ sdk_int_(sdk_int), |
weak_factory_(this) { |
+ if (task_runner) |
+ io_timer_.SetTaskRunner(task_runner); |
// TODO(liberato): should this DCHECK? |
if (media_codec_ == nullptr) |
SetState(STATE_ERROR); |
@@ -59,6 +65,10 @@ MediaCodecLoop::~MediaCodecLoop() { |
io_timer_.Stop(); |
} |
+void MediaCodecLoop::SetTestTickClock(base::TickClock* test_tick_clock) { |
+ test_tick_clock_ = test_tick_clock; |
+} |
+ |
void MediaCodecLoop::OnKeyAdded() { |
if (state_ == STATE_WAITING_FOR_KEY) |
SetState(STATE_READY); |
@@ -76,7 +86,7 @@ bool MediaCodecLoop::TryFlush() { |
if (state_ == STATE_ERROR || state_ == STATE_DRAINED) |
return false; |
- if (codec_flush_requires_destruction()) |
+ if (CodecNeedsFlushWorkaround()) |
return false; |
// Actually try to flush! |
@@ -147,7 +157,7 @@ MediaCodecLoop::InputBuffer MediaCodecLoop::DequeueInputBuffer() { |
int input_buf_index = kInvalidBufferIndex; |
media::MediaCodecStatus status = |
- media_codec_->DequeueInputBuffer(kNoWaitTimeout, &input_buf_index); |
+ media_codec_->DequeueInputBuffer(NoWaitTimeout(), &input_buf_index); |
switch (status) { |
case media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: |
break; |
@@ -249,8 +259,8 @@ bool MediaCodecLoop::ProcessOneOutputBuffer() { |
OutputBuffer out; |
MediaCodecStatus status = media_codec_->DequeueOutputBuffer( |
- kNoWaitTimeout, &out.index, &out.offset, &out.size, &out.pts, &out.is_eos, |
- &out.is_key_frame); |
+ NoWaitTimeout(), &out.index, &out.offset, &out.size, &out.pts, |
+ &out.is_eos, &out.is_key_frame); |
bool did_work = false; |
switch (status) { |
@@ -310,17 +320,19 @@ bool MediaCodecLoop::ProcessOneOutputBuffer() { |
void MediaCodecLoop::ManageTimer(bool did_work) { |
bool should_be_running = true; |
- base::TimeTicks now = base::TimeTicks::Now(); |
+ // One might also use DefaultTickClock, but then ownership becomes harder. |
+ base::TimeTicks now = (test_tick_clock_ ? test_tick_clock_->NowTicks() |
+ : base::TimeTicks::Now()); |
if (did_work || idle_time_begin_ == base::TimeTicks()) { |
idle_time_begin_ = now; |
} else { |
// Make sure that we have done work recently enough, else stop the timer. |
- if (now - idle_time_begin_ > kIdleTimerTimeout) |
+ if (now - idle_time_begin_ > IdleTimerTimeout()) |
should_be_running = false; |
} |
if (should_be_running && !io_timer_.IsRunning()) { |
- io_timer_.Start(FROM_HERE, kDecodePollDelay, this, |
+ io_timer_.Start(FROM_HERE, DecodePollDelay(), this, |
&MediaCodecLoop::DoPendingWork); |
} else if (!should_be_running && io_timer_.IsRunning()) { |
io_timer_.Stop(); |
@@ -338,6 +350,15 @@ MediaCodecBridge* MediaCodecLoop::GetCodec() const { |
return media_codec_.get(); |
} |
+bool MediaCodecLoop::CodecNeedsFlushWorkaround() const { |
+ // Return true if and only if Flush() isn't supported / doesn't work. |
+ // Prior to JellyBean-MR2, flush() had several bugs (b/8125974, b/8347958) so |
+ // we have to completely destroy and recreate the codec there. |
+ // TODO(liberato): MediaCodecUtil implements the same function. We should |
+ // call that one, except that it doesn't compile outside of android right now. |
+ return sdk_int_ < 18; |
+} |
+ |
// static |
const char* MediaCodecLoop::AsString(State state) { |
#define RETURN_STRING(x) \ |