summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/filters/omx_video_decode_engine.cc4
-rw-r--r--media/omx/omx_codec.cc114
-rw-r--r--media/omx/omx_codec.h9
-rw-r--r--media/omx/omx_test.cc15
4 files changed, 106 insertions, 36 deletions
diff --git a/media/filters/omx_video_decode_engine.cc b/media/filters/omx_video_decode_engine.cc
index a263509..89e687f 100644
--- a/media/filters/omx_video_decode_engine.cc
+++ b/media/filters/omx_video_decode_engine.cc
@@ -32,10 +32,12 @@ void OmxVideoDecodeEngine::Initialize(AVStream* stream, Task* done_cb) {
// TODO(ajwong): Find the right way to determine the Omx component name.
OmxCodec::OmxMediaFormat input_format;
+ memset(&input_format, 0, sizeof(input_format));
input_format.codec = OmxCodec::kCodecH264;
OmxCodec::OmxMediaFormat output_format;
+ memset(&output_format, 0, sizeof(output_format));
output_format.codec = OmxCodec::kCodecRaw;
- omx_codec_->Setup("OMX.st.video_decoder.avc", input_format, output_format);
+ omx_codec_->Setup(input_format, output_format);
omx_codec_->SetErrorCallback(
NewCallback(this, &OmxVideoDecodeEngine::OnHardwareError));
omx_codec_->SetFormatCallback(
diff --git a/media/omx/omx_codec.cc b/media/omx/omx_codec.cc
index 55d02f5..b757a88 100644
--- a/media/omx/omx_codec.cc
+++ b/media/omx/omx_codec.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/stl_util-inl.h"
+#include "base/string_util.h"
#include "media/omx/input_buffer.h"
#include "media/omx/omx_codec.h"
@@ -45,14 +46,14 @@ OmxCodec::~OmxCodec() {
}
void OmxCodec::Setup(
- const std::string& component_name,
const OmxCodec::OmxMediaFormat& input_format,
const OmxCodec::OmxMediaFormat& output_format) {
DCHECK_EQ(kEmpty, state_);
DCHECK_NE(input_format.codec, kCodecNone);
- component_name_ = component_name;
input_format_ = input_format;
output_format_ = output_format;
+ Codec codec = encoder() ? output_format_.codec : input_format_.codec;
+ role_name_ = SelectRole(codec, encoder());
}
void OmxCodec::SetErrorCallback(Callback* callback) {
@@ -273,21 +274,23 @@ void OmxCodec::FreeOutputQueue() {
// Sequence of actions in this transition:
//
// 1. Initialize OMX (To be removed.)
-// 2. Get handle of the OMX component
-// 3. Get parameters about I/O ports.
-// 4. Device specific configurations.
-// 5. General configuration of input port.
-// 6. General configuration of output port.
-// 7. Get Parameters about input port.
-// 8. Get Parameters about output port.
-// 9. Codec specific configurations.
+// 2. Map role name to component name.
+// 3. Get handle of the OMX component
+// 4. Get the port information.
+// 5. Set role for the component.
+// 6. Device specific configurations.
+// 7. Input/output ports media format configuration.
+// 8. Obtain the information about the input port.
+// 9. Obtain the information about the output port.
void OmxCodec::Transition_EmptyToLoaded() {
DCHECK_EQ(message_loop_, MessageLoop::current());
DCHECK_EQ(kEmpty, GetState());
- OMX_CALLBACKTYPE callback = { &EventHandler,
- &EmptyBufferCallback,
- &FillBufferCallback };
+ static OMX_CALLBACKTYPE callback = {
+ &EventHandler,
+ &EmptyBufferCallback,
+ &FillBufferCallback
+ };
// 1. Initialize the OpenMAX Core.
// TODO(hclam): move this out.
@@ -298,9 +301,45 @@ void OmxCodec::Transition_EmptyToLoaded() {
return;
}
- // 2. Get the handle to the component. After OMX_GetHandle(),
+ // 2. Map role name to component name.
+ OMX_U32 roles = 0;
+ omxresult = OMX_GetComponentsOfRole(
+ const_cast<OMX_STRING>(role_name_.c_str()),
+ &roles, 0);
+ if (omxresult != OMX_ErrorNone || roles == 0) {
+ LOG(ERROR) << "Unsupported Role: " << role_name_.c_str();
+ StateTransitionTask(kError);
+ return;
+ }
+ const OMX_U32 kMaxRolePerComponent = 20;
+ CHECK(roles < kMaxRolePerComponent);
+
+ OMX_U8** component_names = new OMX_U8*[roles];
+ const int kMaxComponentNameLength = 256;
+ for (size_t i = 0; i < roles; ++i)
+ component_names[i] = new OMX_U8[kMaxComponentNameLength];
+
+ omxresult = OMX_GetComponentsOfRole(
+ const_cast<OMX_STRING>(role_name_.c_str()),
+ &roles, component_names);
+
+ // Use first component only. Copy the name of the first component
+ // so that we could free the memory.
+ if (omxresult == OMX_ErrorNone)
+ component_name_ = reinterpret_cast<char*>(component_names[0]);
+
+ for (size_t i = 0; i < roles; ++i)
+ delete [] component_names[i];
+ delete [] component_names;
+
+ if (omxresult != OMX_ErrorNone || roles == 0) {
+ LOG(ERROR) << "Unsupported Role: " << role_name_.c_str();
+ StateTransitionTask(kError);
+ return;
+ }
+
+ // 3. Get the handle to the component. After OMX_GetHandle(),
// the component is in loaded state.
- // TODO(hclam): We should have a list of componant names instead.
OMX_STRING component = const_cast<OMX_STRING>(component_name_.c_str());
OMX_HANDLETYPE handle = reinterpret_cast<OMX_HANDLETYPE>(component_handle_);
omxresult = OMX_GetHandle(&handle, component, this, &callback);
@@ -311,7 +350,7 @@ void OmxCodec::Transition_EmptyToLoaded() {
return;
}
- // 3. Get the port information. This will obtain information about the
+ // 4. Get the port information. This will obtain information about the
// number of ports and index of the first port.
OMX_PORT_PARAM_TYPE port_param;
ResetPortHeader(*this, &port_param);
@@ -325,21 +364,38 @@ void OmxCodec::Transition_EmptyToLoaded() {
input_port_ = port_param.nStartPortNumber;
output_port_ = input_port_ + 1;
- // 4. Device specific configurations.
+ // 5. Set role for the component because our component could
+ // have multiple roles.
+ OMX_PARAM_COMPONENTROLETYPE role_type;
+ ResetPortHeader(*this, &role_type);
+ base::strlcpy(reinterpret_cast<char*>(role_type.cRole),
+ role_name_.c_str(),
+ OMX_MAX_STRINGNAME_SIZE);
+ role_type.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
+ omxresult = OMX_SetParameter(component_handle_,
+ OMX_IndexParamStandardComponentRole,
+ &role_type);
+ if (omxresult != OMX_ErrorNone) {
+ LOG(ERROR) << "Failed to Set Role";
+ StateTransitionTask(kError);
+ return;
+ }
+
+ // 6. Device specific configurations.
if (!DeviceSpecificConfig()) {
LOG(ERROR) << "Device specific configurations failed";
StateTransitionTask(kError);
return;
}
- // 5. Input/output ports media format configuration.
+ // 7. Input/output ports media format configuration.
if (!ConfigureIOPorts()) {
LOG(ERROR) << "Media format configurations failed";
StateTransitionTask(kError);
return;
}
- // 6. Obtain the information about the input port.
+ // 8. Obtain the information about the input port.
// This will have the new mini buffer count in |port_format.nBufferCountMin|.
// Save this value to input_buf_count.
OMX_PARAM_PORTDEFINITIONTYPE port_format;
@@ -361,7 +417,7 @@ void OmxCodec::Transition_EmptyToLoaded() {
input_buffer_count_ = port_format.nBufferCountMin;
input_buffer_size_ = port_format.nBufferSize;
- // 7. Obtain the information about the output port.
+ // 9. Obtain the information about the output port.
ResetPortHeader(*this, &port_format);
port_format.nPortIndex = output_port_;
omxresult = OMX_GetParameter(component_handle_,
@@ -826,6 +882,24 @@ void OmxCodec::ReportFormatChange() {
format_callback_->Run(&input_format_, &output_format_);
}
+std::string OmxCodec::SelectRole(Codec codec, bool encoder) {
+ std::string role_name = encoder ? "video_encoder." : "video_decoder.";
+ switch (codec) {
+ case kCodecH264:
+ return role_name + "avc";
+ case kCodecH263:
+ return role_name + "h263";
+ case kCodecMpeg4:
+ return role_name + "mpeg4";
+ case kCodecVc1:
+ return role_name + "vc1";
+ default:
+ break;
+ }
+ NOTREACHED();
+ return "";
+}
+
bool OmxCodec::ConfigureIOPorts() {
OMX_PARAM_PORTDEFINITIONTYPE input_port_def, output_port_def;
OMX_ERRORTYPE omxresult = OMX_ErrorNone;
diff --git a/media/omx/omx_codec.h b/media/omx/omx_codec.h
index c198766..bb98a3d 100644
--- a/media/omx/omx_codec.h
+++ b/media/omx/omx_codec.h
@@ -18,7 +18,7 @@
// OmxCodec::OmxMediaFormat input_format, output_format;
// input_format.codec = OmxCodec::kCodecH264;
// output_format.codec = OmxCodec::kCodecRaw;
-// decoder->Setup(component_name, input_format, output_format);
+// decoder->Setup(input_format, output_format);
// decoder->SetErrorCallback(NewCallback(this, &Client::ErrorCallback));
// decoder->SetFormatCallback(NewCallback(this, &Client::FormatCallback));
//
@@ -174,8 +174,7 @@ class OmxCodec : public base::RefCountedThreadSafe<OmxCodec> {
// Set the component name and input/output media format.
// TODO(hclam): Remove |component|.
- void Setup(const std::string& component_name,
- const OmxMediaFormat& input_format,
+ void Setup(const OmxMediaFormat& input_format,
const OmxMediaFormat& output_format);
// Set the error callback. In case of error the callback will be called.
@@ -264,6 +263,9 @@ class OmxCodec : public base::RefCountedThreadSafe<OmxCodec> {
bool ConfigureAsEncoder(OMX_PARAM_PORTDEFINITIONTYPE* input_port_def,
OMX_PARAM_PORTDEFINITIONTYPE* output_port_def);
+ // Helper to return predefined OpenMAX role name for specific codec type.
+ static std::string SelectRole(Codec codec, bool encoder);
+
// Methods and free input and output buffers.
bool AllocateInputBuffers();
bool AllocateOutputBuffers();
@@ -375,6 +377,7 @@ class OmxCodec : public base::RefCountedThreadSafe<OmxCodec> {
State next_state_;
// TODO(hclam): We should keep a list of component names.
+ std::string role_name_;
std::string component_name_;
OMX_COMPONENTTYPE* component_handle_;
bool encoder_;
diff --git a/media/omx/omx_test.cc b/media/omx/omx_test.cc
index 34b98c3..a86f6a6 100644
--- a/media/omx/omx_test.cc
+++ b/media/omx/omx_test.cc
@@ -26,7 +26,6 @@ class TestApp {
public:
TestApp(const char* input_filename,
const char* output_filename,
- const std::string& component_name,
media::OmxCodec::OmxMediaFormat& input_format,
media::OmxCodec::OmxMediaFormat& output_format,
bool simulate_copy,
@@ -35,7 +34,6 @@ class TestApp {
int loop_count)
: input_filename_(input_filename),
output_filename_(output_filename),
- component_name_(component_name),
input_format_(input_format),
output_format_(output_format),
simulate_copy_(simulate_copy),
@@ -282,7 +280,7 @@ class TestApp {
// Setup the |codec_| with the message loop of the current thread. Also
// setup component name, codec format and callbacks.
codec_ = new media::OmxCodec(&message_loop_);
- codec_->Setup(component_name_, input_format_, output_format_);
+ codec_->Setup(input_format_, output_format_);
codec_->SetErrorCallback(NewCallback(this, &TestApp::ErrorCallback));
codec_->SetFormatCallback(NewCallback(this, &TestApp::FormatCallback));
@@ -403,7 +401,6 @@ class TestApp {
MessageLoop message_loop_;
const char* input_filename_;
const char* output_filename_;
- std::string component_name_;
media::OmxCodec::OmxMediaFormat input_format_;
media::OmxCodec::OmxMediaFormat output_format_;
bool simulate_copy_;
@@ -434,11 +431,9 @@ int main(int argc, char** argv) {
bool encoder = cmd_line->HasSwitch("encoder");
if (!encoder) {
if (argc < 3) {
- printf("Usage: omx_test --input-file=FILE"
- " --component=COMPONENT --codec=CODEC"
+ printf("Usage: omx_test --input-file=FILE --codec=CODEC"
" [--output-file=FILE] [--enable-csc]"
" [--copy] [--measure-fps]\n");
- printf(" COMPONENT: OpenMAX component name\n");
printf(" CODEC: h264/mpeg4/h263/vc1\n");
printf("\n");
printf("Optional Arguments\n");
@@ -451,13 +446,11 @@ int main(int argc, char** argv) {
}
} else {
if (argc < 7) {
- printf("Usage: omx_test --input-file=FILE"
- " --component=COMPONENT --codec=CODEC"
+ printf("Usage: omx_test --input-file=FILE --codec=CODEC"
" --width=PIXEL_WIDTH --height=PIXEL_HEIGHT"
" --bitrate=BIT_PER_SECOND --framerate=FRAME_PER_SECOND"
" [--output-file=FILE] [--enable-csc]"
" [--copy] [--measure-fps]\n");
- printf(" COMPONENT: OpenMAX component name\n");
printf(" CODEC: h264/mpeg4/h263/vc1\n");
printf("\n");
printf("Optional Arguments\n");
@@ -472,7 +465,6 @@ int main(int argc, char** argv) {
std::string input_filename = cmd_line->GetSwitchValueASCII("input-file");
std::string output_filename = cmd_line->GetSwitchValueASCII("output-file");
- std::string component_name = cmd_line->GetSwitchValueASCII("component");
std::string codec = cmd_line->GetSwitchValueASCII("codec");
bool copy = cmd_line->HasSwitch("copy");
bool measure_fps = cmd_line->HasSwitch("measure-fps");
@@ -522,7 +514,6 @@ int main(int argc, char** argv) {
// Create a TestApp object and run the decoder.
TestApp test(input_filename.c_str(),
output_filename.c_str(),
- component_name,
input,
output,
copy,