/* * Copyright 2016, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <algorithm> #include <media/omx/1.0/WOmxNode.h> #include <media/omx/1.0/WOmxBufferSource.h> #include <media/omx/1.0/Conversion.h> namespace android { namespace hardware { namespace media { namespace omx { namespace V1_0 { namespace utils { using ::android::hardware::Void; // LWOmxNode status_t LWOmxNode::freeNode() { return toStatusT(mBase->freeNode()); } status_t LWOmxNode::sendCommand( OMX_COMMANDTYPE cmd, OMX_S32 param) { return toStatusT(mBase->sendCommand( toRawCommandType(cmd), param)); } status_t LWOmxNode::getParameter( OMX_INDEXTYPE index, void *params, size_t size) { hidl_vec<uint8_t> tParams = inHidlBytes(params, size); status_t fnStatus; status_t transStatus = toStatusT(mBase->getParameter( toRawIndexType(index), tParams, [&fnStatus, params]( Status status, hidl_vec<uint8_t> const& outParams) { fnStatus = toStatusT(status); std::copy( outParams.data(), outParams.data() + outParams.size(), static_cast<uint8_t*>(params)); })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::setParameter( OMX_INDEXTYPE index, const void *params, size_t size) { hidl_vec<uint8_t> tParams = inHidlBytes(params, size); return toStatusT(mBase->setParameter( toRawIndexType(index), tParams)); } status_t LWOmxNode::getConfig( OMX_INDEXTYPE index, void *params, size_t size) { hidl_vec<uint8_t> tParams = inHidlBytes(params, size); status_t fnStatus; status_t transStatus = toStatusT(mBase->getConfig( toRawIndexType(index), tParams, [&fnStatus, params, size]( Status status, hidl_vec<uint8_t> const& outParams) { fnStatus = toStatusT(status); std::copy( outParams.data(), outParams.data() + size, static_cast<uint8_t*>(params)); })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::setConfig( OMX_INDEXTYPE index, const void *params, size_t size) { hidl_vec<uint8_t> tParams = inHidlBytes(params, size); return toStatusT(mBase->setConfig(toRawIndexType(index), tParams)); } status_t LWOmxNode::setPortMode( OMX_U32 port_index, IOMX::PortMode mode) { return toStatusT(mBase->setPortMode(port_index, toHardwarePortMode(mode))); } status_t LWOmxNode::prepareForAdaptivePlayback( OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { return toStatusT(mBase->prepareForAdaptivePlayback( portIndex, toRawBool(enable), maxFrameWidth, maxFrameHeight)); } status_t LWOmxNode::configureVideoTunnelMode( OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { status_t fnStatus; status_t transStatus = toStatusT(mBase->configureVideoTunnelMode( portIndex, toRawBool(tunneled), audioHwSync, [&fnStatus, sidebandHandle]( Status status, hidl_handle const& outSidebandHandle) { fnStatus = toStatusT(status); *sidebandHandle = outSidebandHandle == nullptr ? nullptr : native_handle_clone(outSidebandHandle); })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::getGraphicBufferUsage( OMX_U32 portIndex, OMX_U32* usage) { status_t fnStatus; status_t transStatus = toStatusT(mBase->getGraphicBufferUsage( portIndex, [&fnStatus, usage]( Status status, uint32_t outUsage) { fnStatus = toStatusT(status); *usage = outUsage; })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::setInputSurface( const sp<IOMXBufferSource> &bufferSource) { return toStatusT(mBase->setInputSurface( new TWOmxBufferSource(bufferSource))); } status_t LWOmxNode::allocateSecureBuffer( OMX_U32 portIndex, size_t size, buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) { *buffer_data = nullptr; status_t fnStatus; status_t transStatus = toStatusT(mBase->allocateSecureBuffer( portIndex, static_cast<uint64_t>(size), [&fnStatus, buffer, native_handle]( Status status, uint32_t outBuffer, hidl_handle const& outNativeHandle) { fnStatus = toStatusT(status); *buffer = outBuffer; *native_handle = outNativeHandle.getNativeHandle() == nullptr ? nullptr : NativeHandle::create( native_handle_clone(outNativeHandle), true); })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::useBuffer( OMX_U32 portIndex, const OMXBuffer &omxBuffer, buffer_id *buffer) { CodecBuffer codecBuffer; if (!wrapAs(&codecBuffer, omxBuffer)) { return BAD_VALUE; } status_t fnStatus; status_t transStatus = toStatusT(mBase->useBuffer( portIndex, codecBuffer, [&fnStatus, buffer](Status status, uint32_t outBuffer) { fnStatus = toStatusT(status); *buffer = outBuffer; })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::freeBuffer( OMX_U32 portIndex, buffer_id buffer) { return toStatusT(mBase->freeBuffer(portIndex, buffer)); } status_t LWOmxNode::fillBuffer( buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) { CodecBuffer codecBuffer; if (!wrapAs(&codecBuffer, omxBuffer)) { return BAD_VALUE; } native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd); if (!fenceNh) { return NO_MEMORY; } status_t status = toStatusT(mBase->fillBuffer( buffer, codecBuffer, fenceNh)); native_handle_close(fenceNh); native_handle_delete(fenceNh); return status; } status_t LWOmxNode::emptyBuffer( buffer_id buffer, const OMXBuffer &omxBuffer, OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { CodecBuffer codecBuffer; if (!wrapAs(&codecBuffer, omxBuffer)) { return BAD_VALUE; } native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd); if (!fenceNh) { return NO_MEMORY; } status_t status = toStatusT(mBase->emptyBuffer( buffer, codecBuffer, flags, toRawTicks(timestamp), fenceNh)); native_handle_close(fenceNh); native_handle_delete(fenceNh); return status; } status_t LWOmxNode::getExtensionIndex( const char *parameter_name, OMX_INDEXTYPE *index) { status_t fnStatus; status_t transStatus = toStatusT(mBase->getExtensionIndex( hidl_string(parameter_name), [&fnStatus, index](Status status, uint32_t outIndex) { fnStatus = toStatusT(status); *index = toEnumIndexType(outIndex); })); return transStatus == NO_ERROR ? fnStatus : transStatus; } status_t LWOmxNode::dispatchMessage(const omx_message &lMsg) { Message tMsg; native_handle_t* nh; if (!wrapAs(&tMsg, &nh, lMsg)) { return NO_MEMORY; } status_t status = toStatusT(mBase->dispatchMessage(tMsg)); native_handle_close(nh); native_handle_delete(nh); return status; } // TWOmxNode TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) { } Return<Status> TWOmxNode::freeNode() { return toStatus(mBase->freeNode()); } Return<Status> TWOmxNode::sendCommand(uint32_t cmd, int32_t param) { return toStatus(mBase->sendCommand(toEnumCommandType(cmd), param)); } Return<void> TWOmxNode::getParameter( uint32_t index, hidl_vec<uint8_t> const& inParams, getParameter_cb _hidl_cb) { hidl_vec<uint8_t> params(inParams); Status status = toStatus(mBase->getParameter( toEnumIndexType(index), static_cast<void*>(params.data()), params.size())); _hidl_cb(status, params); return Void(); } Return<Status> TWOmxNode::setParameter( uint32_t index, hidl_vec<uint8_t> const& inParams) { hidl_vec<uint8_t> params(inParams); return toStatus(mBase->setParameter( toEnumIndexType(index), static_cast<void const*>(params.data()), params.size())); } Return<void> TWOmxNode::getConfig( uint32_t index, const hidl_vec<uint8_t>& inConfig, getConfig_cb _hidl_cb) { hidl_vec<uint8_t> config(inConfig); Status status = toStatus(mBase->getConfig( toEnumIndexType(index), static_cast<void*>(config.data()), config.size())); _hidl_cb(status, config); return Void(); } Return<Status> TWOmxNode::setConfig( uint32_t index, const hidl_vec<uint8_t>& inConfig) { hidl_vec<uint8_t> config(inConfig); return toStatus(mBase->setConfig( toEnumIndexType(index), static_cast<void const*>(config.data()), config.size())); } Return<Status> TWOmxNode::setPortMode(uint32_t portIndex, PortMode mode) { return toStatus(mBase->setPortMode(portIndex, toIOMXPortMode(mode))); } Return<Status> TWOmxNode::prepareForAdaptivePlayback( uint32_t portIndex, bool enable, uint32_t maxFrameWidth, uint32_t maxFrameHeight) { return toStatus(mBase->prepareForAdaptivePlayback( portIndex, toEnumBool(enable), maxFrameWidth, maxFrameHeight)); } Return<void> TWOmxNode::configureVideoTunnelMode( uint32_t portIndex, bool tunneled, uint32_t audioHwSync, configureVideoTunnelMode_cb _hidl_cb) { native_handle_t* sidebandHandle = nullptr; Status status = toStatus(mBase->configureVideoTunnelMode( portIndex, toEnumBool(tunneled), audioHwSync, &sidebandHandle)); _hidl_cb(status, hidl_handle(sidebandHandle)); return Void(); } Return<void> TWOmxNode::getGraphicBufferUsage( uint32_t portIndex, getGraphicBufferUsage_cb _hidl_cb) { OMX_U32 usage; Status status = toStatus(mBase->getGraphicBufferUsage( portIndex, &usage)); _hidl_cb(status, usage); return Void(); } Return<Status> TWOmxNode::setInputSurface( const sp<IOmxBufferSource>& bufferSource) { return toStatus(mBase->setInputSurface(new LWOmxBufferSource( bufferSource))); } Return<void> TWOmxNode::allocateSecureBuffer( uint32_t portIndex, uint64_t size, allocateSecureBuffer_cb _hidl_cb) { IOMX::buffer_id buffer; void* bufferData; sp<NativeHandle> nativeHandle; Status status = toStatus(mBase->allocateSecureBuffer( portIndex, static_cast<size_t>(size), &buffer, &bufferData, &nativeHandle)); _hidl_cb(status, buffer, nativeHandle == nullptr ? nullptr : nativeHandle->handle()); return Void(); } Return<void> TWOmxNode::useBuffer( uint32_t portIndex, const CodecBuffer& codecBuffer, useBuffer_cb _hidl_cb) { IOMX::buffer_id buffer; OMXBuffer omxBuffer; if (!convertTo(&omxBuffer, codecBuffer)) { _hidl_cb(Status::BAD_VALUE, 0); return Void(); } Status status = toStatus(mBase->useBuffer( portIndex, omxBuffer, &buffer)); _hidl_cb(status, buffer); return Void(); } Return<Status> TWOmxNode::freeBuffer(uint32_t portIndex, uint32_t buffer) { return toStatus(mBase->freeBuffer(portIndex, buffer)); } Return<Status> TWOmxNode::fillBuffer( uint32_t buffer, const CodecBuffer& codecBuffer, const hidl_handle& fence) { OMXBuffer omxBuffer; if (!convertTo(&omxBuffer, codecBuffer)) { return Status::BAD_VALUE; } return toStatus(mBase->fillBuffer( buffer, omxBuffer, dup(native_handle_read_fd(fence)))); } Return<Status> TWOmxNode::emptyBuffer( uint32_t buffer, const CodecBuffer& codecBuffer, uint32_t flags, uint64_t timestampUs, const hidl_handle& fence) { OMXBuffer omxBuffer; if (!convertTo(&omxBuffer, codecBuffer)) { return Status::BAD_VALUE; } return toStatus(mBase->emptyBuffer( buffer, omxBuffer, flags, toOMXTicks(timestampUs), dup(native_handle_read_fd(fence)))); } Return<void> TWOmxNode::getExtensionIndex( const hidl_string& parameterName, getExtensionIndex_cb _hidl_cb) { OMX_INDEXTYPE index; Status status = toStatus(mBase->getExtensionIndex( parameterName.c_str(), &index)); _hidl_cb(status, toRawIndexType(index)); return Void(); } Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) { omx_message lMsg; if (!convertTo(&lMsg, tMsg)) { return Status::BAD_VALUE; } return toStatus(mBase->dispatchMessage(lMsg)); } } // namespace utils } // namespace V1_0 } // namespace omx } // namespace media } // namespace hardware } // namespace android