diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-21 02:05:37 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-21 02:05:37 +0000 |
commit | 2f465753368c58befe94e801179f8d7a31640901 (patch) | |
tree | 0d3dc9c37afe838c64bf892f76078c5b40b61cf9 /media/omx | |
parent | 8c0af3834e11d643562c13788c06c695f2666f51 (diff) | |
download | chromium_src-2f465753368c58befe94e801179f8d7a31640901.zip chromium_src-2f465753368c58befe94e801179f8d7a31640901.tar.gz chromium_src-2f465753368c58befe94e801179f8d7a31640901.tar.bz2 |
Video and OpenMAX: add role name to replace vendor specific component name.
Add role name to replace vendor specific component name.
Remove vendor specific Open MAX component name. use role
name to find the appropriate component name in current OMX core
library. We only pick the first component name returned and ignore all
the other components with the same role.
BUG=none
TEST=none
Reviewed: http://codereview.chromium.org/551084/show
Submitted for: jiesun@chromium.org
Review URL: http://codereview.chromium.org/546098
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36716 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/omx')
-rw-r--r-- | media/omx/omx_codec.cc | 114 | ||||
-rw-r--r-- | media/omx/omx_codec.h | 9 | ||||
-rw-r--r-- | media/omx/omx_test.cc | 15 |
3 files changed, 103 insertions, 35 deletions
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, |