// Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this // source code is governed by a BSD-style license that can be found in the // LICENSE file. #include "media/omx/omx_configurator.h" #include "base/logging.h" namespace { std::string GetCodecName(media::OmxConfigurator::Codec codec) { switch (codec) { case media::OmxConfigurator::kCodecH264: return "avc"; case media::OmxConfigurator::kCodecH263: return "h263"; case media::OmxConfigurator::kCodecMpeg4: return "mpeg4"; case media::OmxConfigurator::kCodecVc1: return "vc1"; default: break; } NOTREACHED(); return ""; } } // namespace namespace media { std::string OmxDecoderConfigurator::GetRoleName() const { return "video_decoder." + GetCodecName(input_format().codec); } bool OmxDecoderConfigurator::ConfigureIOPorts( OMX_COMPONENTTYPE* component, OMX_PARAM_PORTDEFINITIONTYPE* input_port_def, OMX_PARAM_PORTDEFINITIONTYPE* output_port_def) const { // Configure the input port. if (input_format().codec == kCodecNone) { LOG(ERROR) << "Unsupported codec " << input_format().codec; return false; } if (input_format().codec == kCodecH264) input_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; else if (input_format().codec == kCodecMpeg4) input_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; else if (input_format().codec == kCodecH263) input_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingH263; else if (input_format().codec == kCodecVc1) input_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; // Assumes 480P. input_port_def->format.video.nFrameWidth = 720; input_port_def->format.video.nFrameHeight = 480; OMX_ERRORTYPE omxresult = OMX_ErrorNone; omxresult = OMX_SetParameter(component, OMX_IndexParamPortDefinition, input_port_def); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "SetParameter(OMX_IndexParamPortDefinition) " "for input port failed"; return false; } return true; } std::string OmxEncoderConfigurator::GetRoleName() const { return "video_encoder." + GetCodecName(output_format().codec); } bool OmxEncoderConfigurator::ConfigureIOPorts( OMX_COMPONENTTYPE* component, OMX_PARAM_PORTDEFINITIONTYPE* input_port_def, OMX_PARAM_PORTDEFINITIONTYPE* output_port_def) const { // TODO(jiesun): Add support for other format than MPEG4. DCHECK_EQ(kCodecMpeg4, output_format().codec); // Configure the input port. input_port_def->format.video.nFrameWidth = input_format().video_header.width; input_port_def->format.video.nFrameHeight = input_format().video_header.height; OMX_ERRORTYPE omxresult = OMX_ErrorNone; omxresult = OMX_SetParameter(component, OMX_IndexParamPortDefinition, input_port_def); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "SetParameter(OMX_IndexParamPortDefinition) " "for input port failed"; return false; } // Configure the output port. output_port_def->format.video.nFrameWidth = input_format().video_header.width; output_port_def->format.video.nFrameHeight = input_format().video_header.height; omxresult = OMX_SetParameter(component, OMX_IndexParamPortDefinition, output_port_def); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "SetParameter(OMX_IndexParamPortDefinition) " "for output port failed"; return false; } if (output_format().codec == kCodecMpeg4) { OMX_VIDEO_PARAM_MPEG4TYPE mp4_type; omxresult = OMX_GetParameter(component, OMX_IndexParamVideoMpeg4, &mp4_type); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "GetParameter(OMX_IndexParamVideoMpeg4) failed"; return false; } // TODO(jiesun): verify if other vendors had the same definition. // Specify the frame rate. mp4_type.nTimeIncRes = output_format().video_header.frame_rate * 2; // Specify how many P frames between adjacent intra frames. mp4_type.nPFrames = output_format().video_header.i_dist - 1; omxresult = OMX_SetParameter(component, OMX_IndexParamVideoMpeg4, &mp4_type); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "SetParameter(OMX_IndexParamVideoMpeg4) failed"; return false; } } OMX_VIDEO_PARAM_BITRATETYPE bitrate; omxresult = OMX_GetParameter(component, OMX_IndexParamVideoBitrate, &bitrate); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "GetParameter(OMX_IndexParamVideoBitrate) failed"; return false; } // TODO(jiesun): expose other rate control method that matters. bitrate.eControlRate = OMX_Video_ControlRateConstant; bitrate.nTargetBitrate = output_format().video_header.bit_rate; omxresult = OMX_SetParameter(component, OMX_IndexParamVideoBitrate, &bitrate); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "SetParameter(OMX_IndexParamVideoBitrate) failed"; return false; } OMX_CONFIG_FRAMERATETYPE framerate; omxresult = OMX_GetConfig(component, OMX_IndexConfigVideoFramerate, &framerate); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "GetParameter(OMX_IndexConfigVideoFramerate) failed"; return false; } framerate.xEncodeFramerate = output_format().video_header.frame_rate << 16; // Q16 format. omxresult = OMX_SetConfig(component, OMX_IndexConfigVideoFramerate, &framerate); if (omxresult != OMX_ErrorNone) { LOG(ERROR) << "SetParameter(OMX_IndexConfigVideoFramerate) failed"; return false; } return true; } } // namespace media