summaryrefslogtreecommitdiffstats
path: root/media/omx
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-22 02:12:34 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-22 02:12:34 +0000
commite41dd82ca759c41fe121da6200278e9d174a1461 (patch)
tree4e49bd4b48a3b968ae2864897952632bb17a3286 /media/omx
parentf060a159b265353593d0b1604af2ef12afe05dfe (diff)
downloadchromium_src-e41dd82ca759c41fe121da6200278e9d174a1461.zip
chromium_src-e41dd82ca759c41fe121da6200278e9d174a1461.tar.gz
chromium_src-e41dd82ca759c41fe121da6200278e9d174a1461.tar.bz2
Unit tests for testing OpenMAX support
Added the following test cases: 1. GetComponentsByRole() now works with valid roles 2. GetHandle() / FreeHandle() pair on video decoder component 3. General configuration of video decoder component TEST=omx_unittests Review URL: http://codereview.chromium.org/550051 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36834 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/omx')
-rw-r--r--media/omx/omx_unittest.cc355
1 files changed, 331 insertions, 24 deletions
diff --git a/media/omx/omx_unittest.cc b/media/omx/omx_unittest.cc
index 76d8f14..c2f7143 100644
--- a/media/omx/omx_unittest.cc
+++ b/media/omx/omx_unittest.cc
@@ -2,45 +2,352 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/command_line.h"
+#include "base/condition_variable.h"
#include "base/logging.h"
+#include "base/waitable_event.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/openmax/il/OMX_Component.h"
#include "third_party/openmax/il/OMX_Core.h"
-namespace media {
+namespace {
+
+// Defines the maximum number of buffers created for I/O ports.
+const int kMaxBufferNum = 256;
-TEST(OmxTest, SimpleInit) {
- EXPECT_EQ(OMX_ErrorNone, OMX_Init());
- EXPECT_EQ(OMX_ErrorNone, OMX_Deinit());
+template <typename T>
+static void ResetHeader(T* param) {
+ memset(param, 0, sizeof(T));
+ // TODO(hclam): Make this version number configurable.
+ param->nVersion.nVersion = 0x00000101;
+ param->nSize = sizeof(T);
}
-TEST(OmxTest, GetComponentsOfRole) {
- OMX_U32 roles = 0;
- OMX_U8** component_names = NULL;
- char role[] = "video_decoder";
- const int kSize = 256;
+} // namespace
+
+namespace media {
+
+class OmxTest : public testing::Test {
+ public:
+ OmxTest()
+ : handle_(NULL),
+ event_(&lock_),
+ empty_buffer_(&lock_),
+ fill_buffer_(&lock_) {
+ memset(input_buffers_, 0, sizeof(input_buffers_));
+ memset(output_buffers_, 0, sizeof(output_buffers_));
+ }
+
+ protected:
+ virtual void SetUp() {
+ // Initialize OpenMAX.
+ EXPECT_EQ(OMX_ErrorNone, OMX_Init());
+ }
+
+ virtual void TearDown() {
+ EXPECT_EQ(OMX_ErrorNone, OMX_Deinit());
+ }
+
+ void InitComponent(std::string component_name) {
+ OMX_CALLBACKTYPE callback = { &EventHandler,
+ &EmptyBufferCallback,
+ &FillBufferCallback };
+
+ OMX_ERRORTYPE omxresult = OMX_GetHandle(
+ (void**)&handle_,
+ const_cast<OMX_STRING>(component_name.c_str()),
+ this, &callback);
+ EXPECT_EQ(OMX_ErrorNone, omxresult);
+ CHECK(handle_);
+ }
+
+ void DeinitComponent() {
+ if (handle_)
+ OMX_FreeHandle(handle_);
+ }
+
+ void AllocateBuffers(int port) {
+ int count = 0;
+ int size = 0;
+ OMX_BUFFERHEADERTYPE** buffers = NULL;
+ if (port == input_port_) {
+ count = input_buffer_count_;
+ size = input_buffer_size_;
+ buffers = input_buffers_;
+ } else if (port == output_port_) {
+ count = output_buffer_count_;
+ size = output_buffer_size_;
+ buffers = output_buffers_;
+ } else {
+ NOTREACHED() << "Not a valid port";
+ }
+ for (int i = 0; i < count; ++i) {
+ CHECK(!buffers[i]);
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_AllocateBuffer(handle_, buffers + i,
+ port, NULL, size));
+ }
+ }
+
+ void ReleaseBuffers(int port) {
+ int count = 0;
+ OMX_BUFFERHEADERTYPE** buffers = NULL;
+ if (port == input_port_) {
+ count = input_buffer_count_;
+ buffers = input_buffers_;
+ } else if (port == output_port_) {
+ count = output_buffer_count_;
+ buffers = output_buffers_;
+ } else {
+ NOTREACHED() << "Not a valid port";
+ }
+ for (int i = 0; i < count; ++i) {
+ CHECK(buffers[i]);
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_FreeBuffer(handle_, port, buffers[i]));
+ buffers[i] = NULL;
+ }
+ }
+
+ void TransitionToIdle() {
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_SendCommand(handle_, OMX_CommandStateSet,
+ OMX_StateIdle, 0));
+ AllocateBuffers(input_port_);
+ AllocateBuffers(output_port_);
+ AutoLock auto_lock(lock_);
+ event_.Wait();
+ }
+
+ void TransitionToLoaded() {
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_SendCommand(handle_, OMX_CommandStateSet,
+ OMX_StateLoaded, 0));
+ ReleaseBuffers(input_port_);
+ ReleaseBuffers(output_port_);
+ AutoLock auto_lock(lock_);
+ event_.Wait();
+ }
+
+ void GetComponentsOfRole(std::string role) {
+ OMX_U32 roles = 0;
+ OMX_U8** component_names = NULL;
+ const int kSize = 256;
+
+ LOG(INFO) << "GetComponentsOfRole: " << role;
+ EXPECT_EQ(OMX_ErrorNone, OMX_GetComponentsOfRole(
+ const_cast<OMX_STRING>(role.c_str()), &roles, 0));
+
+ // TODO(hclam): Should assert the component number.
+ LOG(INFO) << "Components: " << roles;
+
+ if (roles) {
+ component_names = new OMX_U8*[roles];
+ for (size_t i = 0; i < roles; ++i)
+ component_names[i] = new OMX_U8[kSize];
+
+ OMX_U32 roles_backup = roles;
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_GetComponentsOfRole(
+ const_cast<OMX_STRING>(role.c_str()),
+ &roles, component_names));
+ ASSERT_EQ(roles_backup, roles);
+
+ for (size_t i = 0; i < roles; ++i) {
+ LOG(INFO) << "Component name: " << component_names[i];
+ delete [] component_names[i];
+ }
+ delete [] component_names;
+ }
+ }
+
+ OMX_ERRORTYPE EventHandlerInternal(
+ OMX_HANDLETYPE component, OMX_EVENTTYPE event,
+ OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data) {
+ AutoLock auto_lock(lock_);
+ // TODO(hclam): Save the parameters.
+ event_.Signal();
+ return OMX_ErrorNone;
+ }
+
+ OMX_ERRORTYPE EmptyBufferCallbackInternal(
+ OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE* buffer) {
+ // TODO(hclam): Add code here.
+ AutoLock auto_lock(lock_);
+ empty_buffer_.Signal();
+ return OMX_ErrorNone;
+ }
- EXPECT_EQ(OMX_ErrorNone, OMX_Init());
- EXPECT_EQ(OMX_ErrorNone, OMX_GetComponentsOfRole(role, &roles, 0));
+ OMX_ERRORTYPE FillBufferCallbackInternal(
+ OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE* buffer) {
+ // TODO(hclam): Add code here.
+ AutoLock auto_lock(lock_);
+ fill_buffer_.Signal();
+ return OMX_ErrorNone;
+ }
+
+ // Static callback methods.
+ static OMX_ERRORTYPE EventHandler(
+ OMX_HANDLETYPE component, OMX_PTR priv_data,
+ OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2,
+ OMX_PTR event_data) {
+ return static_cast<OmxTest*>(priv_data)
+ ->EventHandlerInternal(component,
+ event, data1, data2, event_data);
+ }
+
+ static OMX_ERRORTYPE EmptyBufferCallback(
+ OMX_HANDLETYPE component, OMX_PTR priv_data,
+ OMX_BUFFERHEADERTYPE* buffer) {
+ return static_cast<OmxTest*>(priv_data)
+ ->EmptyBufferCallbackInternal(component, buffer);
+ }
+
+ static OMX_ERRORTYPE FillBufferCallback(
+ OMX_HANDLETYPE component, OMX_PTR priv_data,
+ OMX_BUFFERHEADERTYPE* buffer) {
+ return static_cast<OmxTest*>(priv_data)
+ ->FillBufferCallbackInternal(component, buffer);
+ }
+
+ OMX_COMPONENTTYPE* handle_;
+ int input_port_;
+ int output_port_;
+ int input_buffer_count_;
+ int input_buffer_size_;
+ int output_buffer_count_;
+ int output_buffer_size_;
+ OMX_BUFFERHEADERTYPE* input_buffers_[kMaxBufferNum];
+ OMX_BUFFERHEADERTYPE* output_buffers_[kMaxBufferNum];
+
+ Lock lock_;
+ ConditionVariable event_;
+ ConditionVariable empty_buffer_;
+ ConditionVariable fill_buffer_;
+};
+
+class OmxVideoDecoderTest : public OmxTest {
+ protected:
+ void Configure(OMX_VIDEO_CODINGTYPE codec,
+ int width, int height) {
+ // Obtain port IDs.
+ OMX_PORT_PARAM_TYPE port_param;
+ ResetHeader(&port_param);
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_GetParameter(handle_,
+ OMX_IndexParamVideoInit,
+ &port_param));
+
+ input_port_ = port_param.nStartPortNumber;
+ output_port_ = port_param.nStartPortNumber + 1;
+ LOG(INFO) << "Input port number: " << input_port_;
+ LOG(INFO) << "Output port number: " << output_port_;
+
+ // Get and set parameters for input port.
+ LOG(INFO) << "Input port width: " << width;
+ LOG(INFO) << "Input port height: " << height;
+ LOG(INFO) << "Input port codec: " << codec;
+ OMX_PARAM_PORTDEFINITIONTYPE port_format;
+ ResetHeader(&port_format);
+ port_format.nPortIndex = input_port_;
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_GetParameter(handle_,
+ OMX_IndexParamPortDefinition,
+ &port_format));
+ EXPECT_EQ(OMX_DirInput, port_format.eDir);
+ port_format.format.video.eCompressionFormat = codec;
+ port_format.format.video.nFrameWidth = width;
+ port_format.format.video.nFrameHeight = height;
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_SetParameter(handle_,
+ OMX_IndexParamPortDefinition,
+ &port_format));
- // TODO(hclam): Should assert the component number.
- LOG(INFO) << "Video decoder components: " << roles;
+ // TODO(hclam): Add configurations to output port.
- if (roles) {
- component_names = new OMX_U8*[roles];
- for (size_t i = 0; i < roles; ++i)
- component_names[i] = new OMX_U8[kSize];
+ // Get Parameters for input port.
+ ResetHeader(&port_format);
+ port_format.nPortIndex = input_port_;
+ EXPECT_EQ(OMX_ErrorNone,
+ OMX_GetParameter(handle_,
+ OMX_IndexParamPortDefinition,
+ &port_format));
+ EXPECT_EQ(OMX_DirInput, port_format.eDir);
+ input_buffer_count_ = port_format.nBufferCountMin;
+ input_buffer_size_ = port_format.nBufferSize;
+ CHECK(input_buffer_count_ < kMaxBufferNum);
- OMX_U32 roles_backup = roles;
+ // Get parameters for output port.
+ ResetHeader(&port_format);
+ port_format.nPortIndex = output_port_;
EXPECT_EQ(OMX_ErrorNone,
- OMX_GetComponentsOfRole(role, &roles, component_names));
- ASSERT_EQ(roles_backup, roles);
+ OMX_GetParameter(handle_,
+ OMX_IndexParamPortDefinition,
+ &port_format));
+ EXPECT_EQ(OMX_DirOutput, port_format.eDir);
+ output_buffer_count_ = port_format.nBufferCountMin;
+ output_buffer_size_ = port_format.nBufferSize;
+ CHECK(output_buffer_count_ < kMaxBufferNum);
+
+ LOG(INFO) << "Input buffer count: " << input_buffer_count_;
+ LOG(INFO) << "Input buffer size: " << input_buffer_size_;
+ LOG(INFO) << "Output buffer count: " << output_buffer_count_;
+ LOG(INFO) << "Output buffer size: " << output_buffer_size_;
+ }
+
+ std::string component() {
+ return CommandLine::ForCurrentProcess()
+ ->GetSwitchValueASCII("video-decoder-component");
+ }
- for (size_t i = 0; i < roles; ++i)
- delete [] component_names[i];
- delete [] component_names;
+ OMX_VIDEO_CODINGTYPE codec() {
+ std::string codec = CommandLine::ForCurrentProcess()
+ ->GetSwitchValueASCII("video-decoder-codec");
+ if (codec == "h264")
+ return OMX_VIDEO_CodingAVC;
+ return OMX_VIDEO_CodingAutoDetect;
}
- EXPECT_EQ(OMX_ErrorNone, OMX_Deinit());
+};
+
+TEST_F(OmxTest, SimpleInit) {
+ // A empty test case will test basic init/deinit of OpenMAX library.
+}
+
+TEST_F(OmxTest, GetComponentsOfRole) {
+ // Roles video decoders.
+ GetComponentsOfRole("video_decoder.avc");
+ GetComponentsOfRole("video_decoder.mpeg4");
+ GetComponentsOfRole("video_decoder.vc1");
+
+ // TODO(hclam): Add roles of encoders.
+}
+
+TEST_F(OmxVideoDecoderTest, GetHandle) {
+ // TODO(hclam): Should use GetComponentsOfRole instead.
+ InitComponent(component());
+ DeinitComponent();
+}
+
+TEST_F(OmxVideoDecoderTest, Configuration) {
+ InitComponent(component());
+ // TODO(hclam): Make resolution configurable.
+ Configure(codec(), 1024, 768);
+ DeinitComponent();
+}
+
+TEST_F(OmxVideoDecoderTest, TransitionToIdle) {
+ InitComponent(component());
+ Configure(codec(), 1024, 768);
+ TransitionToIdle();
+ TransitionToLoaded();
+ DeinitComponent();
+}
+
+TEST_F(OmxVideoDecoderTest, FreeHandleWhenIdle) {
+ InitComponent(component());
+ Configure(codec(), 1024, 768);
+ TransitionToIdle();
+ DeinitComponent();
}
} // namespace media