summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/filters/decoder_base.h10
-rw-r--r--media/filters/decoder_base_unittest.cc7
-rw-r--r--media/filters/ffmpeg_video_decode_engine.cc11
-rw-r--r--media/filters/ffmpeg_video_decode_engine.h3
-rw-r--r--media/filters/ffmpeg_video_decoder.cc10
-rw-r--r--media/filters/ffmpeg_video_decoder.h2
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc4
-rw-r--r--media/filters/omx_video_decode_engine.cc134
-rw-r--r--media/filters/omx_video_decode_engine.h26
-rw-r--r--media/filters/omx_video_decoder.cc30
-rw-r--r--media/filters/omx_video_decoder.h7
-rw-r--r--media/filters/video_decode_engine.h7
-rw-r--r--media/omx/omx_codec_unittest.cc11
-rw-r--r--media/tools/omx_test/omx_test.cc4
14 files changed, 231 insertions, 35 deletions
diff --git a/media/filters/decoder_base.h b/media/filters/decoder_base.h
index 82f767e..8796464 100644
--- a/media/filters/decoder_base.h
+++ b/media/filters/decoder_base.h
@@ -99,9 +99,9 @@ class DecoderBase : public Decoder {
// Method that may be implemented by the derived class if desired. It will
// be called from within the MediaFilter::Stop() method prior to stopping the
// base class.
- //
- // TODO(ajwong): Make this asynchronous.
- virtual void DoStop() {}
+ virtual void DoStop(Task* done_cb) {
+ AutoTaskRunner done_runner(done_cb);
+ }
// Derived class can implement this method and perform seeking logic prior
// to the base class.
@@ -150,8 +150,10 @@ class DecoderBase : public Decoder {
DCHECK_EQ(MessageLoop::current(), this->message_loop());
// Delegate to the subclass first.
- DoStop();
+ DoStop(NewRunnableMethod(this, &DecoderBase::OnStopComplete, callback));
+ }
+ void OnStopComplete(FilterCallback* callback) {
// Throw away all buffers in all queues.
result_queue_.clear();
state_ = kStopped;
diff --git a/media/filters/decoder_base_unittest.cc b/media/filters/decoder_base_unittest.cc
index 4bc0531..19ba820 100644
--- a/media/filters/decoder_base_unittest.cc
+++ b/media/filters/decoder_base_unittest.cc
@@ -5,6 +5,7 @@
#include <vector>
#include "media/base/mock_filters.h"
+#include "media/base/mock_task.h"
#include "media/filters/decoder_base.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -12,6 +13,7 @@
using ::testing::_;
using ::testing::NotNull;
using ::testing::StrictMock;
+using ::testing::WithArg;
namespace media {
@@ -69,7 +71,7 @@ class MockDecoderImpl : public media::DecoderBase<
void(media::DemuxerStream* demuxer_stream,
bool* success,
Task* done_cb));
- MOCK_METHOD0(DoStop, void());
+ MOCK_METHOD1(DoStop, void(Task* done_cb));
MOCK_METHOD2(DoSeek, void(base::TimeDelta time, Task* done_cb));
MOCK_METHOD1(DoDecode, void(media::Buffer* input));
@@ -152,7 +154,8 @@ TEST(DecoderBaseTest, FlowControl) {
message_loop.RunAllPending();
// Stop.
- EXPECT_CALL(*decoder, DoStop());
+ EXPECT_CALL(*decoder, DoStop(_))
+ .WillOnce(WithArg<0>(InvokeRunnable()));
EXPECT_CALL(callback, OnFilterCallback());
EXPECT_CALL(callback, OnCallbackDestroyed());
decoder->Stop(callback.NewCallback());
diff --git a/media/filters/ffmpeg_video_decode_engine.cc b/media/filters/ffmpeg_video_decode_engine.cc
index d84d56c..46e2de0 100644
--- a/media/filters/ffmpeg_video_decode_engine.cc
+++ b/media/filters/ffmpeg_video_decode_engine.cc
@@ -212,6 +212,17 @@ void FFmpegVideoDecodeEngine::DecodeFrame(scoped_refptr<Buffer> buffer) {
fill_this_buffer_callback_->Run(video_frame);
}
+void FFmpegVideoDecodeEngine::Stop(Task* done_cb) {
+ // TODO(jiesun): Release buffers when we support buffer recycling.
+ AutoTaskRunner done_runner(done_cb);
+}
+
+void FFmpegVideoDecodeEngine::Pause(Task* done_cb) {
+ // TODO(jiesun): Stop out-going buffer exchange when we support
+ // buffer recycling.
+ AutoTaskRunner done_runner(done_cb);
+}
+
void FFmpegVideoDecodeEngine::Flush(Task* done_cb) {
AutoTaskRunner done_runner(done_cb);
diff --git a/media/filters/ffmpeg_video_decode_engine.h b/media/filters/ffmpeg_video_decode_engine.h
index 9b0c186..3941c52 100644
--- a/media/filters/ffmpeg_video_decode_engine.h
+++ b/media/filters/ffmpeg_video_decode_engine.h
@@ -31,6 +31,9 @@ class FFmpegVideoDecodeEngine : public VideoDecodeEngine {
FillThisBufferCallback* fill_buffer_callback,
Task* done_cb);
virtual void EmptyThisBuffer(scoped_refptr<Buffer> buffer);
+ virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame) {}
+ virtual void Stop(Task* done_cb);
+ virtual void Pause(Task* done_cb);
virtual void Flush(Task* done_cb);
virtual VideoFrame::Format GetSurfaceFormat() const;
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index 361e5f2..716c60d 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -85,6 +85,10 @@ void FFmpegVideoDecoder::OnInitializeComplete(bool* success, Task* done_cb) {
}
}
+void FFmpegVideoDecoder::DoStop(Task* done_cb) {
+ decode_engine_->Stop(done_cb);
+}
+
void FFmpegVideoDecoder::DoSeek(base::TimeDelta time, Task* done_cb) {
// Everything in the presentation time queue is invalid, clear the queue.
while (!pts_heap_.IsEmpty())
@@ -184,6 +188,12 @@ void FFmpegVideoDecoder::OnEmptyBufferDone(scoped_refptr<Buffer> buffer) {
DecoderBase<VideoDecoder, VideoFrame>::OnDecodeComplete();
}
+void FFmpegVideoDecoder::FillThisBuffer(scoped_refptr<VideoFrame> frame) {
+ DecoderBase<VideoDecoder, VideoFrame>::FillThisBuffer(frame);
+ // Notify decode engine the available of new frame.
+ decode_engine_->FillThisBuffer(frame);
+}
+
void FFmpegVideoDecoder::EnqueueVideoFrame(
const scoped_refptr<VideoFrame>& video_frame) {
EnqueueResult(video_frame);
diff --git a/media/filters/ffmpeg_video_decoder.h b/media/filters/ffmpeg_video_decoder.h
index 8350492..a66f5e5 100644
--- a/media/filters/ffmpeg_video_decoder.h
+++ b/media/filters/ffmpeg_video_decoder.h
@@ -29,11 +29,13 @@ class FFmpegVideoDecoder : public DecoderBase<VideoDecoder, VideoFrame> {
protected:
virtual void DoInitialize(DemuxerStream* demuxer_stream, bool* success,
Task* done_cb);
+ virtual void DoStop(Task* done_cb);
virtual void DoSeek(base::TimeDelta time, Task* done_cb);
virtual void DoDecode(Buffer* input);
protected:
virtual void OnEmptyBufferDone(scoped_refptr<Buffer> buffer);
+ virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame);
private:
friend class FilterFactoryImpl1<FFmpegVideoDecoder, VideoDecodeEngine*>;
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index d564a73..33b7f5a 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -56,6 +56,8 @@ class MockVideoDecodeEngine : public VideoDecodeEngine {
Task* done_cb));
MOCK_METHOD1(EmptyThisBuffer, void(scoped_refptr<Buffer> buffer));
MOCK_METHOD1(FillThisBuffer, void(scoped_refptr<VideoFrame> buffer));
+ MOCK_METHOD1(Stop, void(Task* done_cb));
+ MOCK_METHOD1(Pause, void(Task* done_cb));
MOCK_METHOD1(Flush, void(Task* done_cb));
MOCK_CONST_METHOD0(state, State());
MOCK_CONST_METHOD0(GetSurfaceFormat, VideoFrame::Format());
@@ -139,6 +141,8 @@ class FFmpegVideoDecoderTest : public testing::Test {
// Call Stop() to shut down internal threads.
EXPECT_CALL(callback_, OnFilterCallback());
EXPECT_CALL(callback_, OnCallbackDestroyed());
+ EXPECT_CALL(*engine_, Stop(_))
+ .WillOnce(WithArg<0>(InvokeRunnable()));
decoder_->Stop(callback_.NewCallback());
// Finish up any remaining tasks.
diff --git a/media/filters/omx_video_decode_engine.cc b/media/filters/omx_video_decode_engine.cc
index cb42138..8110cd8 100644
--- a/media/filters/omx_video_decode_engine.cc
+++ b/media/filters/omx_video_decode_engine.cc
@@ -38,6 +38,7 @@ OmxVideoDecodeEngine::OmxVideoDecodeEngine()
input_buffer_size_(0),
input_port_(0),
input_buffers_at_component_(0),
+ input_pending_request_(0),
input_queue_has_eos_(false),
input_has_fed_eos_(false),
output_buffer_count_(0),
@@ -116,6 +117,8 @@ void OmxVideoDecodeEngine::EmptyThisBuffer(scoped_refptr<Buffer> buffer) {
DCHECK_EQ(message_loop_, MessageLoop::current());
DCHECK(!free_input_buffers_.empty());
+ --input_pending_request_;
+
if (!CanAcceptInput()) {
FinishEmptyBuffer(buffer);
return;
@@ -141,14 +144,115 @@ void OmxVideoDecodeEngine::EmptyThisBuffer(scoped_refptr<Buffer> buffer) {
// Try to feed buffers into the decoder.
EmptyBufferTask();
+
+ if (il_state_ == kIlPause && input_pending_request_ == 0) {
+ if (pause_callback_.get()) {
+ pause_callback_->Run();
+ pause_callback_.reset();
+ }
+ }
+}
+
+void OmxVideoDecodeEngine::Pause(Task* done_cb) {
+ message_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &OmxVideoDecodeEngine::PauseTask, done_cb));
+}
+
+void OmxVideoDecodeEngine::PauseTask(Task* done_cb) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(il_state_, kIlExecuting);
+
+ pause_callback_.reset(done_cb);
+
+ client_state_ = kClientFlushing;
+
+ expected_il_state_ = kIlPause;
+ OnStateSetEventFunc = &OmxVideoDecodeEngine::PauseFromExecuting;
+ TransitionToState(OMX_StatePause);
+}
+
+void OmxVideoDecodeEngine::PauseFromExecuting(OMX_STATETYPE state) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ OnStateSetEventFunc = NULL;
+ il_state_ = kIlPause;
+
+ if (input_pending_request_ == 0 ) {
+ if (pause_callback_.get()) {
+ pause_callback_->Run();
+ pause_callback_.reset(NULL);
+ }
+ }
}
void OmxVideoDecodeEngine::Flush(Task* done_cb) {
+ message_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &OmxVideoDecodeEngine::FlushTask, done_cb));
+}
+
+void OmxVideoDecodeEngine::FlushTask(Task* done_cb) {
DCHECK_EQ(message_loop_, MessageLoop::current());
- AutoTaskRunner done_cb_runner(done_cb);
+ if (client_state_ != kClientFlushing) {
+ // TODO(jiesun): how to prevent initial seek.
+ AutoTaskRunner done_runner(done_cb);
+ return;
+ }
+
+ flush_callback_.reset(done_cb);
+
+ // TODO(jiesun): return buffers to filter who allocate them.
+ while (!output_frames_ready_.empty())
+ output_frames_ready_.pop();
+
+ while (!available_input_buffers_.empty())
+ available_input_buffers_.pop();
+
+ input_port_flushed_ = false;
+ output_port_flushed_ = false;
+ OnFlushEventFunc = &OmxVideoDecodeEngine::PortFlushDone;
+ OMX_ERRORTYPE omxresult;
+ omxresult = OMX_SendCommand(component_handle_,
+ OMX_CommandFlush,
+ OMX_ALL, 0);
+}
+
+bool OmxVideoDecodeEngine::InputPortFlushed() {
+ DCHECK_EQ(client_state_, kClientFlushing);
+ // Port flushed is defined by OpenMAX component had signal flush done and
+ // We had all buffers returned from demuxer and OpenMAX component.
+ int free_input_size = static_cast<int>(free_input_buffers_.size());
+ return input_port_flushed_ && free_input_size == input_buffer_count_;
+}
- // TODO(wjia): to flush component
+bool OmxVideoDecodeEngine::OutputPortFlushed() {
+ DCHECK_EQ(client_state_, kClientFlushing);
+ // Port flushed is defined by OpenMAX component had signal flush done and
+ // We had all buffers returned from renderer and OpenMAX component.
+ // TODO(jiesun): egl image path may use different value.
+ return output_port_flushed_ /*&&
+ available_output_frames_.size() == output_buffer_count_*/;
+}
+
+void OmxVideoDecodeEngine::ComponentFlushDone() {
+ if (flush_callback_.get()) {
+ flush_callback_->Run();
+ flush_callback_.reset(NULL);
+
+ InitialReadBuffer();
+ OnStateSetEventFunc = &OmxVideoDecodeEngine::DoneSetStateExecuting;
+ TransitionToState(OMX_StateExecuting);
+ }
+}
+
+void OmxVideoDecodeEngine::PortFlushDone(int port) {
+ if (port == input_port_ || port == static_cast<int>(OMX_ALL))
+ input_port_flushed_ = true;
+ if (port == output_port_ || port == static_cast<int>(OMX_ALL))
+ output_port_flushed_ = true;
+
+ if (InputPortFlushed() && OutputPortFlushed())
+ ComponentFlushDone();
}
VideoFrame::Format OmxVideoDecodeEngine::GetSurfaceFormat() const {
@@ -181,7 +285,7 @@ VideoDecodeEngine::State OmxVideoDecodeEngine::state() const {
return kError;
}
-void OmxVideoDecodeEngine::Stop(Callback0::Type* done_cb) {
+void OmxVideoDecodeEngine::Stop(Task* done_cb) {
// TODO(wjia): make this call in the thread.
// DCHECK_EQ(message_loop_, MessageLoop::current());
@@ -203,8 +307,10 @@ void OmxVideoDecodeEngine::OnFormatChange(
void OmxVideoDecodeEngine::FinishEmptyBuffer(scoped_refptr<Buffer> buffer) {
DCHECK_EQ(message_loop_, MessageLoop::current());
- if (!input_queue_has_eos_)
+ if (!input_queue_has_eos_) {
empty_this_buffer_callback_->Run(buffer);
+ ++input_pending_request_;
+ }
}
void OmxVideoDecodeEngine::FinishFillBuffer(OMX_BUFFERHEADERTYPE* buffer) {
@@ -687,10 +793,10 @@ void OmxVideoDecodeEngine::OnPortEnableEventRun(int port) {
}
// Functions for stopping
-void OmxVideoDecodeEngine::StopTask(Callback* callback) {
+void OmxVideoDecodeEngine::StopTask(Task* task) {
DCHECK_EQ(message_loop_, MessageLoop::current());
- stop_callback_.reset(callback);
+ stop_callback_.reset(task);
if (client_state_ == kClientError) {
OnStopDone();
@@ -1115,7 +1221,8 @@ void OmxVideoDecodeEngine::EmptyBufferDoneTask(OMX_BUFFERHEADERTYPE* buffer) {
Buffer* stored_buffer = static_cast<Buffer*>(buffer->pAppPrivate);
buffer->pAppPrivate = NULL;
- FinishEmptyBuffer(stored_buffer);
+ if (client_state_ != kClientFlushing)
+ FinishEmptyBuffer(stored_buffer);
stored_buffer->Release();
// Enqueue the available buffer because the decoder has consumed it.
@@ -1127,6 +1234,10 @@ void OmxVideoDecodeEngine::EmptyBufferDoneTask(OMX_BUFFERHEADERTYPE* buffer) {
// Try to feed more data into the decoder.
EmptyBufferTask();
+
+ if (client_state_ == kClientFlushing &&
+ InputPortFlushed() && OutputPortFlushed())
+ ComponentFlushDone();
}
void OmxVideoDecodeEngine::FillBufferDoneTask(OMX_BUFFERHEADERTYPE* buffer) {
@@ -1142,10 +1253,17 @@ void OmxVideoDecodeEngine::FillBufferDoneTask(OMX_BUFFERHEADERTYPE* buffer) {
output_eos_ = true;
DLOG(INFO) << "Output has EOS";
}
- output_frames_ready_.push(buffer);
+
+ // TODO(jiesun): return this buffer to allocator?
+ if (client_state_ != kClientFlushing)
+ output_frames_ready_.push(buffer);
// Try to fulfill one read request.
FulfillOneRead();
+
+ if (client_state_ == kClientFlushing &&
+ InputPortFlushed() && OutputPortFlushed())
+ ComponentFlushDone();
}
void OmxVideoDecodeEngine::EventHandlerCompleteTask(OMX_EVENTTYPE event,
diff --git a/media/filters/omx_video_decode_engine.h b/media/filters/omx_video_decode_engine.h
index 83480d0..24ee407 100644
--- a/media/filters/omx_video_decode_engine.h
+++ b/media/filters/omx_video_decode_engine.h
@@ -44,18 +44,13 @@ class OmxVideoDecodeEngine :
Task* done_cb);
virtual void EmptyThisBuffer(scoped_refptr<Buffer> buffer);
virtual void FillThisBuffer(scoped_refptr<VideoFrame> video_frame);
+ virtual void Stop(Task* done_cb);
+ virtual void Pause(Task* done_cb);
virtual void Flush(Task* done_cb);
virtual VideoFrame::Format GetSurfaceFormat() const;
virtual State state() const;
- // Stops the engine.
- //
- // TODO(ajwong): Normalize this interface with Task like the others, and
- // promote to the abstract interface.
- // TODO(boliu): Should the callback type be FilterCallback*?
- virtual void Stop(Callback0::Type* done_cb);
-
// Subclass can provide a different value.
virtual int current_omx_spec_version() const { return 0x00000101; }
@@ -102,7 +97,9 @@ class OmxVideoDecodeEngine :
// Methods to be executed in |message_loop_|, they correspond to the
// public methods.
void InitializeTask();
- void StopTask(Callback* callback);
+ void StopTask(Task* task);
+ void PauseTask(Task* task);
+ void FlushTask(Task* task);
// Transition method sequence for initialization
bool CreateComponent();
@@ -117,6 +114,9 @@ class OmxVideoDecodeEngine :
void DeinitFromExecuting(OMX_STATETYPE state);
void DeinitFromIdle(OMX_STATETYPE state);
void DeinitFromLoaded(OMX_STATETYPE state);
+ void PauseFromExecuting(OMX_STATETYPE state);
+ void PortFlushDone(int port);
+ void ComponentFlushDone();
void StopOnError();
@@ -140,6 +140,9 @@ class OmxVideoDecodeEngine :
bool CanAcceptInput();
bool CanAcceptOutput();
+ bool InputPortFlushed();
+ bool OutputPortFlushed();
+
// Method to send input buffers to component
void EmptyBufferTask();
@@ -203,14 +206,17 @@ class OmxVideoDecodeEngine :
int input_buffer_size_;
int input_port_;
int input_buffers_at_component_;
+ int input_pending_request_;
bool input_queue_has_eos_;
bool input_has_fed_eos_;
+ bool input_port_flushed_;
std::vector<OMX_BUFFERHEADERTYPE*> output_buffers_;
int output_buffer_count_;
int output_buffer_size_;
int output_port_;
bool output_eos_;
+ bool output_port_flushed_;
bool uses_egl_image_;
base::TimeDelta last_pts_;
@@ -228,7 +234,9 @@ class OmxVideoDecodeEngine :
scoped_ptr<EmptyThisBufferCallback> empty_this_buffer_callback_;
scoped_ptr<FillThisBufferCallback> fill_this_buffer_callback_;
- scoped_ptr<Callback> stop_callback_;
+ scoped_ptr<Task> stop_callback_;
+ scoped_ptr<Task> flush_callback_;
+ scoped_ptr<Task> pause_callback_;
// Free input OpenMAX buffers that can be used to take input bitstream from
// demuxer.
diff --git a/media/filters/omx_video_decoder.cc b/media/filters/omx_video_decoder.cc
index eb9d598..ceabccc 100644
--- a/media/filters/omx_video_decoder.cc
+++ b/media/filters/omx_video_decoder.cc
@@ -6,6 +6,7 @@
#include "base/callback.h"
#include "base/waitable_event.h"
+#include "media/base/callback.h"
#include "media/base/factory.h"
#include "media/base/filter_host.h"
#include "media/base/limits.h"
@@ -73,7 +74,34 @@ void OmxVideoDecoder::FillThisBuffer(scoped_refptr<VideoFrame> frame) {
}
void OmxVideoDecoder::Stop(FilterCallback* callback) {
- omx_engine_->Stop(callback);
+ omx_engine_->Stop(
+ NewRunnableMethod(this,
+ &OmxVideoDecoder::StopCompleteTask, callback));
+}
+
+void OmxVideoDecoder::StopCompleteTask(FilterCallback* callback) {
+ AutoCallbackRunner done_runner(callback);
+}
+
+void OmxVideoDecoder::Pause(FilterCallback* callback) {
+ omx_engine_->Pause(
+ NewRunnableMethod(this,
+ &OmxVideoDecoder::PauseCompleteTask, callback));
+}
+
+void OmxVideoDecoder::PauseCompleteTask(FilterCallback* callback) {
+ AutoCallbackRunner done_runner(callback);
+}
+
+void OmxVideoDecoder::Seek(base::TimeDelta time,
+ FilterCallback* callback) {
+ omx_engine_->Flush(
+ NewRunnableMethod(this,
+ &OmxVideoDecoder::SeekCompleteTask, callback));
+}
+
+void OmxVideoDecoder::SeekCompleteTask(FilterCallback* callback) {
+ AutoCallbackRunner done_runner(callback);
}
void OmxVideoDecoder::DoInitialize(DemuxerStream* demuxer_stream,
diff --git a/media/filters/omx_video_decoder.h b/media/filters/omx_video_decoder.h
index 236130b..5f747ad 100644
--- a/media/filters/omx_video_decoder.h
+++ b/media/filters/omx_video_decoder.h
@@ -29,6 +29,8 @@ class OmxVideoDecoder : public VideoDecoder {
virtual void Initialize(DemuxerStream* stream, FilterCallback* callback);
virtual void Stop(FilterCallback* callback);
+ virtual void Pause(FilterCallback* callback);
+ virtual void Seek(base::TimeDelta time, FilterCallback* callback);
virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame);
virtual const MediaFormat& media_format() { return media_format_; }
@@ -42,6 +44,11 @@ class OmxVideoDecoder : public VideoDecoder {
void EmptyBufferCallback(scoped_refptr<Buffer> buffer);
void InitCompleteTask(FilterCallback* callback);
+
+ void StopCompleteTask(FilterCallback* callback);
+ void PauseCompleteTask(FilterCallback* callback);
+ void SeekCompleteTask(FilterCallback* callback);
+
// TODO(hclam): This is very ugly that we keep reference instead of
// scoped_refptr.
void DemuxCompleteTask(Buffer* buffer);
diff --git a/media/filters/video_decode_engine.h b/media/filters/video_decode_engine.h
index f0ff923..8dc9d25 100644
--- a/media/filters/video_decode_engine.h
+++ b/media/filters/video_decode_engine.h
@@ -61,9 +61,10 @@ class VideoDecodeEngine {
// engine through |FillThisBuffer|. Output buffers are returned to outside
// by |FillThisBufferCallback|.
virtual void EmptyThisBuffer(scoped_refptr<Buffer> buffer) = 0;
- virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame) {
- NOTREACHED();
- };
+ virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame) = 0;
+
+ virtual void Stop(Task* done_cb) = 0;
+ virtual void Pause(Task* done_cb) = 0;
// Flushes the decode engine of any buffered input packets.
virtual void Flush(Task* done_cb) = 0;
diff --git a/media/omx/omx_codec_unittest.cc b/media/omx/omx_codec_unittest.cc
index 71a9ca7..b1960b9 100644
--- a/media/omx/omx_codec_unittest.cc
+++ b/media/omx/omx_codec_unittest.cc
@@ -295,8 +295,7 @@ class OmxCodecTest : public testing::Test {
}
void ExpectStop() {
- EXPECT_CALL(stop_callback_, OnFilterCallback());
- EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
+ EXPECT_CALL(stop_task_, Run());
ExpectToIdle();
ExpectIdleToLoaded();
ExpectToEmpty();
@@ -355,7 +354,7 @@ class OmxCodecTest : public testing::Test {
VideoDecodeEngine::FillThisBufferCallback* decode_done_cb_;
TaskMocker init_done_cb_task_;
- MockFilterCallback stop_callback_;
+ TaskMocker stop_task_;
private:
DISALLOW_COPY_AND_ASSIGN(OmxCodecTest);
@@ -375,7 +374,7 @@ TEST_F(OmxCodecTest, SimpleStartAndStop) {
EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
ExpectStop();
- omx_engine_->Stop(stop_callback_.NewCallback());
+ omx_engine_->Stop(stop_task_.CreateTask());
message_loop_.RunAllPending();
}
@@ -422,7 +421,7 @@ TEST_F(OmxCodecTest, NormalFlow) {
// Shutdown.
ExpectStop();
- omx_engine_->Stop(stop_callback_.NewCallback());
+ omx_engine_->Stop(stop_task_.CreateTask());
message_loop_.RunAllPending();
}
@@ -474,7 +473,7 @@ TEST_F(OmxCodecTest, RecycleInputBuffers) {
// Shutdown.
ExpectStop();
- omx_engine_->Stop(stop_callback_.NewCallback());
+ omx_engine_->Stop(stop_task_.CreateTask());
message_loop_.RunAllPending();
}
diff --git a/media/tools/omx_test/omx_test.cc b/media/tools/omx_test/omx_test.cc
index 2b39fee..9a185e6 100644
--- a/media/tools/omx_test/omx_test.cc
+++ b/media/tools/omx_test/omx_test.cc
@@ -126,9 +126,9 @@ class TestApp : public base::RefCountedThreadSafe<TestApp> {
if (!frame_count_)
first_sample_delivered_time_ = base::TimeTicks::HighResNow();
- // If we are readding to the end, then stop.
+ // If we are reading to the end, then stop.
if (frame->IsEndOfStream()) {
- engine_->Stop(NewCallback(this, &TestApp::StopCallback));
+ engine_->Stop(NewRunnableMethod(this, &TestApp::StopCallback));
return;
}