summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorwjia@google.com <wjia@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-02 18:34:18 +0000
committerwjia@google.com <wjia@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-02 18:34:18 +0000
commit006febfee42193e999c25c5ce4dcd510f630013b (patch)
tree9b2a4bcd2c23b7165f50353b09bb4c3c1c31dde2 /media
parent2f939cbdf5c1907c6da835ec1369bc1ec0b88890 (diff)
downloadchromium_src-006febfee42193e999c25c5ce4dcd510f630013b.zip
chromium_src-006febfee42193e999c25c5ce4dcd510f630013b.tar.gz
chromium_src-006febfee42193e999c25c5ce4dcd510f630013b.tar.bz2
enable omx_codec_unittest based on new omx engine
BUG=none TEST=try bot Review URL: http://codereview.chromium.org/2397001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48741 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/omx/omx_codec_unittest.cc350
1 files changed, 192 insertions, 158 deletions
diff --git a/media/omx/omx_codec_unittest.cc b/media/omx/omx_codec_unittest.cc
index 97aaff8..ebec9c9 100644
--- a/media/omx/omx_codec_unittest.cc
+++ b/media/omx/omx_codec_unittest.cc
@@ -8,7 +8,13 @@
#include "base/callback.h"
#include "base/message_loop.h"
+#include "base/task.h"
+#include "media/base/buffers.h"
#include "media/base/mock_filters.h"
+#include "media/base/mock_task.h"
+#include "media/ffmpeg/ffmpeg_common.h"
+#include "media/filters/omx_video_decode_engine.h"
+#include "media/filters/video_decode_engine.h"
#include "media/omx/mock_omx.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,19 +29,15 @@ using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
-// Temporarily disable omx_codec_unittests during heavy refactoring.
-#if 0
namespace {
const int kBufferCount = 3;
const int kBufferSize = 4096;
-const char* kRoleName = "awsome";
-const char* kComponentName = "OMX.google.mock.awsome";
+const char* kComponentName = "OMX.google.video_decoder.avc";
} // namespace
namespace media {
-
ACTION(ReturnComponentName) {
strcpy(((char**)arg2)[0], kComponentName);
}
@@ -59,40 +61,57 @@ ACTION(GetParameterPortDefinition) {
else
port_format->eDir = OMX_DirOutput;
port_format->nBufferCountMin = kBufferCount;
+ port_format->nBufferCountActual = kBufferCount;
port_format->nBufferSize = kBufferSize;
}
ACTION(AllocateBuffer) {
*arg0 = new OMX_BUFFERHEADERTYPE();
memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE));
- (*arg0)->pBuffer = new uint8[kBufferSize];
+ (*arg0)->nAllocLen = arg3;
+ (*arg0)->pBuffer = new uint8[arg3];
+ (*arg0)->nOutputPortIndex = 1;
+ (*arg0)->nInputPortIndex = OMX_ALL;
}
ACTION(UseBuffer) {
*arg0 = new OMX_BUFFERHEADERTYPE();
memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE));
+ (*arg0)->nOutputPortIndex = OMX_ALL;
+ (*arg0)->nInputPortIndex = 0;
}
ACTION(FreeBuffer) {
- delete [] arg1->pBuffer;
+ if (1 == arg1->nOutputPortIndex)
+ delete [] arg1->pBuffer;
delete arg1;
}
-ACTION_P2(SendEvent, event, data1) {
- // TODO(hclam): pass data2 and event data.
+ACTION_P3(SendEvent, event, data1, data2) {
(*MockOmx::get()->callbacks()->EventHandler)(
MockOmx::get()->component(),
MockOmx::get()->component()->pApplicationPrivate,
- event, static_cast<OMX_U32>(data1), 0, NULL);
+ event, static_cast<OMX_U32>(data1), static_cast<OMX_U32>(data2), NULL);
}
-ACTION(FillBuffer) {
- arg0->nFlags = 0;
- arg0->nFilledLen = kBufferSize;
- (*MockOmx::get()->callbacks()->FillBufferDone)(
+ACTION_P(EmptyBufferDone, output_pool_ptr) {
+ (*MockOmx::get()->callbacks()->EmptyBufferDone)(
MockOmx::get()->component(),
MockOmx::get()->component()->pApplicationPrivate,
arg0);
+ OMX_BUFFERHEADERTYPE* out_buffer = output_pool_ptr->front();
+ output_pool_ptr->pop_front();
+ if (arg0->nFlags & OMX_BUFFERFLAG_EOS)
+ out_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
+ out_buffer->nFilledLen = kBufferSize;
+ (*MockOmx::get()->callbacks()->FillBufferDone)(
+ MockOmx::get()->component(),
+ MockOmx::get()->component()->pApplicationPrivate,
+ out_buffer);
+}
+
+ACTION_P(EnqueueOutputBuffer, output_pool_ptr) {
+ output_pool_ptr->push_back(arg0);
}
ACTION(FillEosBuffer) {
@@ -104,27 +123,44 @@ ACTION(FillEosBuffer) {
arg0);
}
-class MockOmxConfigurator : public OmxConfigurator {
+class TestBuffer : public media::Buffer {
public:
- MockOmxConfigurator()
- : OmxConfigurator(MediaFormat(), MediaFormat()) {}
-
- MOCK_CONST_METHOD0(GetRoleName, std::string());
- MOCK_CONST_METHOD3(ConfigureIOPorts,
- bool(OMX_COMPONENTTYPE* component,
- OMX_PARAM_PORTDEFINITIONTYPE* input_fef,
- OMX_PARAM_PORTDEFINITIONTYPE* output_def));
+ TestBuffer() : size_(0), data_(NULL) { }
+ explicit TestBuffer(int size) : size_(size) {
+ if (size)
+ data_.reset(new uint8[size]);
+ else
+ data_.reset(NULL);
+ }
+ virtual const uint8* GetData() const {
+ return data_.get();
+ }
+ virtual size_t GetDataSize() const {
+ return size_;
+ }
+ private:
+ virtual ~TestBuffer() { }
+
+ int size_;
+ scoped_array<uint8> data_;
+ DISALLOW_COPY_AND_ASSIGN(TestBuffer);
};
class OmxCodecTest : public testing::Test {
public:
OmxCodecTest ()
- : omx_codec_(new OmxCodec(&message_loop_)) {
- omx_codec_->Setup(&mock_configurator_);
+ : got_eos_(false),
+ omx_engine_(new OmxVideoDecodeEngine()) {
+ av_stream_.codec = &av_codec_context_;
+ av_codec_context_.width = 16;
+ av_codec_context_.height = 16;
+ feed_done_cb_ =
+ NewCallback(this, &OmxCodecTest::EmptyBufferDoneCallback);
+ decode_done_cb_ =
+ NewCallback(this, &OmxCodecTest::FillBufferDoneCallback);
}
~OmxCodecTest() {
- CHECK(output_units_.size() == 0);
}
protected:
@@ -150,14 +186,6 @@ class OmxCodecTest : public testing::Test {
// Ignore all set parameter calls.
EXPECT_CALL(*MockOmx::get(), SetParameter(_, _))
.WillRepeatedly(Return(OMX_ErrorNone));
-
- // Expect calling to configurator once.
- EXPECT_CALL(mock_configurator_,
- ConfigureIOPorts(MockOmx::get()->component(), _, _))
- .WillOnce(Return(true));
-
- EXPECT_CALL(mock_configurator_, GetRoleName())
- .WillRepeatedly(Return(kRoleName));
}
void ExpectToLoaded() {
@@ -183,12 +211,13 @@ class OmxCodecTest : public testing::Test {
SendCommand(OMX_CommandStateSet, OMX_StateIdle, _))
.WillOnce(
DoAll(
- SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet),
+ SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
+ OMX_StateIdle),
Return(OMX_ErrorNone)));
// Expect allocation of buffers.
EXPECT_CALL(*MockOmx::get(),
- UseBuffer(NotNull(), 0, IsNull(), kBufferSize, _))
+ UseBuffer(NotNull(), 0, NotNull(), kBufferSize, _))
.Times(kBufferCount)
.WillRepeatedly(DoAll(UseBuffer(), Return(OMX_ErrorNone)));
@@ -206,13 +235,15 @@ class OmxCodecTest : public testing::Test {
EXPECT_CALL(*MockOmx::get(),
SendCommand(OMX_CommandStateSet, OMX_StateExecuting, _))
.WillOnce(DoAll(
- SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet),
+ SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
+ OMX_StateExecuting),
Return(OMX_ErrorNone)));
// Expect initial FillThisBuffer() calls.
EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
.Times(kBufferCount)
- .WillRepeatedly(DoAll(FillBuffer(), Return(OMX_ErrorNone)));
+ .WillRepeatedly(DoAll(EnqueueOutputBuffer(&output_pool_),
+ Return(OMX_ErrorNone)));
}
void ExpectToIdle() {
@@ -220,7 +251,7 @@ class OmxCodecTest : public testing::Test {
EXPECT_CALL(*MockOmx::get(),
SendCommand(OMX_CommandStateSet, OMX_StateIdle, _))
.WillOnce(DoAll(
- SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet),
+ SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet, OMX_StateIdle),
Return(OMX_ErrorNone)));
}
@@ -231,7 +262,8 @@ class OmxCodecTest : public testing::Test {
EXPECT_CALL(*MockOmx::get(),
SendCommand(OMX_CommandStateSet, OMX_StateLoaded, _))
.WillOnce(DoAll(
- SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet),
+ SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
+ OMX_StateLoaded),
Return(OMX_ErrorNone)));
// Expect free buffer for input port.
@@ -258,41 +290,68 @@ class OmxCodecTest : public testing::Test {
ExpectToLoaded();
ExpectLoadedToIdle();
ExpectToExecuting();
+ EXPECT_CALL(init_done_cb_task_, Run());
}
void ExpectStop() {
+ EXPECT_CALL(stop_callback_, OnFilterCallback());
+ EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
ExpectToIdle();
ExpectIdleToLoaded();
ExpectToEmpty();
}
- void ReadCallback(OMX_BUFFERHEADERTYPE* buffer) {
- output_units_.push_back(buffer);
+ void EmptyBufferDoneCallback(scoped_refptr<Buffer> buffer) {
+ input_units_.push_back(buffer);
}
- void MakeReadRequest() {
- omx_codec_->Read(NewCallback(this, &OmxCodecTest::ReadCallback));
+ void FillBufferDoneCallback(scoped_refptr<VideoFrame> frame) {
+ output_units_.push_back(frame);
+ if (frame.get() == NULL)
+ got_eos_ = true;
}
- void SaveFillThisBuffer(OMX_BUFFERHEADERTYPE* buffer) {
- fill_this_buffer_received_.push_back(buffer);
+ void InitializeInputBuffers(int count) {
+ for (int i = 0; i < count; ++i) {
+ scoped_refptr<Buffer> buffer_ref = new TestBuffer(i + 1);
+ input_units_.push_back(buffer_ref);
+ }
}
- void ExpectAndSaveFillThisBuffer() {
- EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
- .WillOnce(DoAll(Invoke(this, &OmxCodecTest::SaveFillThisBuffer),
- Return(OMX_ErrorNone)))
+ void MakeEmptyBufferRequest() {
+ scoped_refptr<Buffer> buffer = input_units_.front();
+ input_units_.pop_front();
+ omx_engine_->EmptyThisBuffer(buffer);
+ }
+
+ void SendEOSInputBuffer() {
+ input_units_.pop_front();
+ scoped_refptr<Buffer> buffer_ref = new TestBuffer();
+ input_units_.push_front(buffer_ref);
+ EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
+ .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
.RetiresOnSaturation();
+ MakeEmptyBufferRequest();
+ message_loop_.RunAllPending();
}
- std::deque<OMX_BUFFERHEADERTYPE*> output_units_;
+ std::deque<scoped_refptr<Buffer> > input_units_;
+ std::deque<scoped_refptr<VideoFrame> > output_units_;
std::deque<OMX_BUFFERHEADERTYPE*> fill_this_buffer_received_;
+ std::deque<OMX_BUFFERHEADERTYPE*> output_pool_;
MockOmx mock_omx_;
- MockOmxConfigurator mock_configurator_;
+ bool got_eos_;
MessageLoop message_loop_;
- scoped_refptr<OmxCodec> omx_codec_;
+ scoped_refptr<OmxVideoDecodeEngine> omx_engine_;
+
+ AVStream av_stream_;
+ AVCodecContext av_codec_context_;
+
+ VideoDecodeEngine::EmptyThisBufferCallback* feed_done_cb_;
+ VideoDecodeEngine::FillThisBufferCallback* decode_done_cb_;
+ TaskMocker init_done_cb_task_;
MockFilterCallback stop_callback_;
@@ -303,150 +362,125 @@ class OmxCodecTest : public testing::Test {
TEST_F(OmxCodecTest, SimpleStartAndStop) {
ExpectSettings();
ExpectStart();
- omx_codec_->Start();
+ omx_engine_->Initialize(&message_loop_,
+ &av_stream_,
+ feed_done_cb_,
+ decode_done_cb_,
+ init_done_cb_task_.CreateTask());
message_loop_.RunAllPending();
- EXPECT_CALL(stop_callback_, OnFilterCallback());
- EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
+ EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
+
ExpectStop();
- omx_codec_->Stop(stop_callback_.NewCallback());
+ omx_engine_->Stop(stop_callback_.NewCallback());
message_loop_.RunAllPending();
}
-TEST_F(OmxCodecTest, EndOfStream) {
+TEST_F(OmxCodecTest, NormalFlow) {
ExpectSettings();
ExpectStart();
- omx_codec_->Start();
+ omx_engine_->Initialize(&message_loop_,
+ &av_stream_,
+ feed_done_cb_,
+ decode_done_cb_,
+ init_done_cb_task_.CreateTask());
message_loop_.RunAllPending();
- // Make read requests, OmxCodec should have gotten kBufferCount
- // buffers already.
+ EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
+
+ // Allocate bitstream buffers.
+ InitializeInputBuffers(kBufferCount);
+
+ // Make emptybuffer requests.
EXPECT_EQ(0u, output_units_.size());
+ int count = output_pool_.size();
for (int i = 0; i < kBufferCount; ++i) {
- // Give buffers back to OmxCodec. OmxCodec will make a new
- // FillThisBuffer() call for each read.
+ // Give input buffers to OmxVideoDecodeEngine. OmxVideoDecodeEngine will
+ // make a new FillThisBuffer() call for each read.
+ EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
+ .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
+ .RetiresOnSaturation();
EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
- .WillOnce(DoAll(FillEosBuffer(), Return(OMX_ErrorNone)))
+ .WillOnce(DoAll(EnqueueOutputBuffer(&output_pool_),
+ Return(OMX_ErrorNone)))
.RetiresOnSaturation();
- MakeReadRequest();
+ MakeEmptyBufferRequest();
}
message_loop_.RunAllPending();
- CHECK(kBufferCount == static_cast<int>(output_units_.size()));
-
- // Make sure buffers received are in order.
- for (int i = 0; i < kBufferCount; ++i) {
- // TODO(jiesun): How to verify this now?
- // EXPECT_EQ(i, output_units_[i].first);
- EXPECT_TRUE(output_units_[i] != NULL);
- }
-
+ EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
+ EXPECT_EQ(kBufferCount, static_cast<int>(output_units_.size()));
+ EXPECT_EQ(count, static_cast<int>(output_pool_.size()));
output_units_.clear();
- // Make some read requests and make sure end-of-stream buffer id
- // are received.
- EXPECT_EQ(0u, output_units_.size());
- for (int i = 0; i < 2 * kBufferCount; ++i) {
- MakeReadRequest();
- }
- message_loop_.RunAllPending();
- EXPECT_EQ(2 * kBufferCount, static_cast<int>(output_units_.size()));
-
- for (size_t i = 0; i <output_units_.size(); ++i) {
- EXPECT_EQ(NULL, output_units_[i]);
- }
- output_units_.clear();
+ // Send EndOfStream, expect eos flag.
+ SendEOSInputBuffer();
+ EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
+ EXPECT_EQ(1, static_cast<int>(output_units_.size()));
+ EXPECT_EQ(count-1, static_cast<int>(output_pool_.size()));
+ EXPECT_EQ(true, got_eos_);
- // Stop OmxCodec.
- EXPECT_CALL(stop_callback_, OnFilterCallback());
- EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
+ // Shutdown.
ExpectStop();
- omx_codec_->Stop(stop_callback_.NewCallback());
+ omx_engine_->Stop(stop_callback_.NewCallback());
message_loop_.RunAllPending();
}
-TEST_F(OmxCodecTest, OutputFlowControl) {
+TEST_F(OmxCodecTest, RecycleInputBuffers) {
ExpectSettings();
ExpectStart();
- omx_codec_->Start();
- message_loop_.RunAllPending();
-
- // Since initial FillThisBuffer() calls are made and fulfilled during
- // start. Reads issued to OmxCodec will be fulfilled now.
- EXPECT_EQ(0u, output_units_.size());
- for (int i = 0; i < kBufferCount; ++i) {
- ExpectAndSaveFillThisBuffer();
- MakeReadRequest();
- }
+ omx_engine_->Initialize(&message_loop_,
+ &av_stream_,
+ feed_done_cb_,
+ decode_done_cb_,
+ init_done_cb_task_.CreateTask());
message_loop_.RunAllPending();
- CHECK(kBufferCount == static_cast<int>(output_units_.size()));
- // Make sure buffers received are in order.
- for (int i = 0; i < kBufferCount; ++i) {
- EXPECT_TRUE(output_units_[i] != NULL);
- }
+ EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
- output_units_.clear();
+ // Allocate bitstream buffers.
+ InitializeInputBuffers(kBufferCount);
- // In each loop, perform the following actions:
- // 1. Make a read request to OmxCodec.
- // 2. Fake a response for FillBufferDone().
- // 3. Expect read response received.
- // 4. NULL buffer is returned in first time
- for (int i = 0; i < kBufferCount + 1; ++i) {
- // 1. First make a read request.
- // Since a buffer is given back to OmxCodec component after first time,
- // a FillThisBuffer() is called to OmxCodec component.
- if (i > 0) {
- EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
- .WillOnce(Return(OMX_ErrorNone))
- .RetiresOnSaturation();
- }
- MakeReadRequest();
-
- // 2. Then fake a response from OpenMAX, only |kBufferCount| times
- if (i < kBufferCount) {
- OMX_BUFFERHEADERTYPE* buffer = fill_this_buffer_received_.front();
- fill_this_buffer_received_.pop_front();
- buffer->nFlags = 0;
- buffer->nFilledLen = kBufferSize;
- (*MockOmx::get()->callbacks()->FillBufferDone)(
- MockOmx::get()->component(),
- MockOmx::get()->component()->pApplicationPrivate,
- buffer);
- }
-
- // Make sure actions are completed.
- message_loop_.RunAllPending();
-
- // 3. Expect read response received.
- // The above action will cause a read callback be called and we should
- // receive one buffer now. Also expect the buffer id be received in
- // reverse order.
- EXPECT_EQ(1u, output_units_.size());
- //EXPECT_EQ(kBufferCount - i - 1, output_units_.front().first);
-
- output_units_.pop_front();
-
- // Make sure actions are completed.
+ // Make emptybuffer requests, also recycle input buffers
+ EXPECT_EQ(0u, output_units_.size());
+ int count = output_pool_.size();
+ int repeat_count = kBufferCount * 2;
+ for (int i = 0; i < repeat_count; ++i) {
+ // Give input buffers to OmxVideoDecodeEngine. OmxVideoDecodeEngine will
+ // make a new FillThisBuffer() call for each read.
+ EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
+ .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
+ .WillOnce(DoAll(EnqueueOutputBuffer(&output_pool_),
+ Return(OMX_ErrorNone)))
+ .RetiresOnSaturation();
+ MakeEmptyBufferRequest();
message_loop_.RunAllPending();
+ CHECK(kBufferCount == static_cast<int>(input_units_.size()));
+ CHECK(((i % kBufferCount) + 1) ==
+ static_cast<int>(input_units_.back()->GetDataSize()));
}
+ message_loop_.RunAllPending();
+ EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
+ EXPECT_EQ(repeat_count, static_cast<int>(output_units_.size()));
+ EXPECT_EQ(count, static_cast<int>(output_pool_.size()));
+ output_units_.clear();
- // Now issue kBufferCount reads to OmxCodec.
- EXPECT_EQ(0u, output_units_.size());
+ // Send EndOfStream, expect eos flag.
+ SendEOSInputBuffer();
+ EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
+ EXPECT_EQ(1, static_cast<int>(output_units_.size()));
+ EXPECT_EQ(count-1, static_cast<int>(output_pool_.size()));
+ EXPECT_EQ(true, got_eos_);
- // Stop OmxCodec.
- EXPECT_CALL(stop_callback_, OnFilterCallback());
- EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
+ // Shutdown.
ExpectStop();
- omx_codec_->Stop(stop_callback_.NewCallback());
+ omx_engine_->Stop(stop_callback_.NewCallback());
message_loop_.RunAllPending();
}
// TODO(hclam): Add test case for dynamic port config.
// TODO(hclam): Create a more complicated test case so that read
// requests and reply from FillThisBuffer() arrives out of order.
-// TODO(hclam): Add test case for Feed().
} // namespace media
-
-#endif