1/* 2 * Copyright 2016, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <algorithm> 18 19#include <media/omx/1.0/WOmxNode.h> 20#include <media/omx/1.0/WOmxBufferSource.h> 21#include <media/omx/1.0/Conversion.h> 22 23namespace android { 24namespace hardware { 25namespace media { 26namespace omx { 27namespace V1_0 { 28namespace utils { 29 30using ::android::hardware::Void; 31 32// LWOmxNode 33status_t LWOmxNode::freeNode() { 34 return toStatusT(mBase->freeNode()); 35} 36 37status_t LWOmxNode::sendCommand( 38 OMX_COMMANDTYPE cmd, OMX_S32 param) { 39 return toStatusT(mBase->sendCommand( 40 toRawCommandType(cmd), param)); 41} 42 43status_t LWOmxNode::getParameter( 44 OMX_INDEXTYPE index, void *params, size_t size) { 45 hidl_vec<uint8_t> tParams = inHidlBytes(params, size); 46 status_t fnStatus; 47 status_t transStatus = toStatusT(mBase->getParameter( 48 toRawIndexType(index), 49 tParams, 50 [&fnStatus, params, size]( 51 Status status, hidl_vec<uint8_t> const& outParams) { 52 fnStatus = toStatusT(status); 53 std::copy( 54 outParams.data(), 55 outParams.data() + outParams.size(), 56 static_cast<uint8_t*>(params)); 57 })); 58 return transStatus == NO_ERROR ? fnStatus : transStatus; 59} 60 61status_t LWOmxNode::setParameter( 62 OMX_INDEXTYPE index, const void *params, size_t size) { 63 hidl_vec<uint8_t> tParams = inHidlBytes(params, size); 64 return toStatusT(mBase->setParameter( 65 toRawIndexType(index), tParams)); 66} 67 68status_t LWOmxNode::getConfig( 69 OMX_INDEXTYPE index, void *params, size_t size) { 70 hidl_vec<uint8_t> tParams = inHidlBytes(params, size); 71 status_t fnStatus; 72 status_t transStatus = toStatusT(mBase->getConfig( 73 toRawIndexType(index), 74 tParams, 75 [&fnStatus, params, size]( 76 Status status, hidl_vec<uint8_t> const& outParams) { 77 fnStatus = toStatusT(status); 78 std::copy( 79 outParams.data(), 80 outParams.data() + size, 81 static_cast<uint8_t*>(params)); 82 })); 83 return transStatus == NO_ERROR ? fnStatus : transStatus; 84} 85 86status_t LWOmxNode::setConfig( 87 OMX_INDEXTYPE index, const void *params, size_t size) { 88 hidl_vec<uint8_t> tParams = inHidlBytes(params, size); 89 return toStatusT(mBase->setConfig(toRawIndexType(index), tParams)); 90} 91 92status_t LWOmxNode::setPortMode( 93 OMX_U32 port_index, IOMX::PortMode mode) { 94 return toStatusT(mBase->setPortMode(port_index, toHardwarePortMode(mode))); 95} 96 97status_t LWOmxNode::prepareForAdaptivePlayback( 98 OMX_U32 portIndex, OMX_BOOL enable, 99 OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { 100 return toStatusT(mBase->prepareForAdaptivePlayback( 101 portIndex, toRawBool(enable), maxFrameWidth, maxFrameHeight)); 102} 103 104status_t LWOmxNode::configureVideoTunnelMode( 105 OMX_U32 portIndex, OMX_BOOL tunneled, 106 OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { 107 status_t fnStatus; 108 status_t transStatus = toStatusT(mBase->configureVideoTunnelMode( 109 portIndex, 110 toRawBool(tunneled), 111 audioHwSync, 112 [&fnStatus, sidebandHandle]( 113 Status status, hidl_handle const& outSidebandHandle) { 114 fnStatus = toStatusT(status); 115 *sidebandHandle = outSidebandHandle == nullptr ? 116 nullptr : native_handle_clone(outSidebandHandle); 117 })); 118 return transStatus == NO_ERROR ? fnStatus : transStatus; 119} 120 121status_t LWOmxNode::getGraphicBufferUsage( 122 OMX_U32 portIndex, OMX_U32* usage) { 123 status_t fnStatus; 124 status_t transStatus = toStatusT(mBase->getGraphicBufferUsage( 125 portIndex, 126 [&fnStatus, usage]( 127 Status status, uint32_t outUsage) { 128 fnStatus = toStatusT(status); 129 *usage = outUsage; 130 })); 131 return transStatus == NO_ERROR ? fnStatus : transStatus; 132} 133 134status_t LWOmxNode::setInputSurface( 135 const sp<IOMXBufferSource> &bufferSource) { 136 return toStatusT(mBase->setInputSurface( 137 new TWOmxBufferSource(bufferSource))); 138} 139 140status_t LWOmxNode::allocateSecureBuffer( 141 OMX_U32 portIndex, size_t size, buffer_id *buffer, 142 void **buffer_data, sp<NativeHandle> *native_handle) { 143 *buffer_data = nullptr; 144 status_t fnStatus; 145 status_t transStatus = toStatusT(mBase->allocateSecureBuffer( 146 portIndex, 147 static_cast<uint64_t>(size), 148 [&fnStatus, buffer, buffer_data, native_handle]( 149 Status status, 150 uint32_t outBuffer, 151 hidl_handle const& outNativeHandle) { 152 fnStatus = toStatusT(status); 153 *buffer = outBuffer; 154 *native_handle = NativeHandle::create( 155 native_handle_clone(outNativeHandle), true); 156 })); 157 return transStatus == NO_ERROR ? fnStatus : transStatus; 158} 159 160status_t LWOmxNode::useBuffer( 161 OMX_U32 portIndex, const OMXBuffer &omxBuffer, buffer_id *buffer) { 162 CodecBuffer codecBuffer; 163 if (!wrapAs(&codecBuffer, omxBuffer)) { 164 return BAD_VALUE; 165 } 166 status_t fnStatus; 167 status_t transStatus = toStatusT(mBase->useBuffer( 168 portIndex, 169 codecBuffer, 170 [&fnStatus, buffer](Status status, uint32_t outBuffer) { 171 fnStatus = toStatusT(status); 172 *buffer = outBuffer; 173 })); 174 return transStatus == NO_ERROR ? fnStatus : transStatus; 175} 176 177status_t LWOmxNode::freeBuffer( 178 OMX_U32 portIndex, buffer_id buffer) { 179 return toStatusT(mBase->freeBuffer(portIndex, buffer)); 180} 181 182status_t LWOmxNode::fillBuffer( 183 buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) { 184 CodecBuffer codecBuffer; 185 if (!wrapAs(&codecBuffer, omxBuffer)) { 186 return BAD_VALUE; 187 } 188 native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd); 189 if (!fenceNh) { 190 return NO_MEMORY; 191 } 192 status_t status = toStatusT(mBase->fillBuffer( 193 buffer, codecBuffer, fenceNh)); 194 native_handle_close(fenceNh); 195 native_handle_delete(fenceNh); 196 return status; 197} 198 199status_t LWOmxNode::emptyBuffer( 200 buffer_id buffer, const OMXBuffer &omxBuffer, 201 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 202 CodecBuffer codecBuffer; 203 if (!wrapAs(&codecBuffer, omxBuffer)) { 204 return BAD_VALUE; 205 } 206 native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd); 207 if (!fenceNh) { 208 return NO_MEMORY; 209 } 210 status_t status = toStatusT(mBase->emptyBuffer( 211 buffer, 212 codecBuffer, 213 flags, 214 toRawTicks(timestamp), 215 fenceNh)); 216 native_handle_close(fenceNh); 217 native_handle_delete(fenceNh); 218 return status; 219} 220status_t LWOmxNode::getExtensionIndex( 221 const char *parameter_name, 222 OMX_INDEXTYPE *index) { 223 status_t fnStatus; 224 status_t transStatus = toStatusT(mBase->getExtensionIndex( 225 hidl_string(parameter_name), 226 [&fnStatus, index](Status status, uint32_t outIndex) { 227 fnStatus = toStatusT(status); 228 *index = toEnumIndexType(outIndex); 229 })); 230 return transStatus == NO_ERROR ? fnStatus : transStatus; 231} 232 233status_t LWOmxNode::dispatchMessage(const omx_message &lMsg) { 234 Message tMsg; 235 native_handle_t* nh; 236 if (!wrapAs(&tMsg, &nh, lMsg)) { 237 return NO_MEMORY; 238 } 239 status_t status = toStatusT(mBase->dispatchMessage(tMsg)); 240 native_handle_close(nh); 241 native_handle_delete(nh); 242 return status; 243} 244 245// TWOmxNode 246TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) { 247} 248 249Return<Status> TWOmxNode::freeNode() { 250 return toStatus(mBase->freeNode()); 251} 252 253Return<Status> TWOmxNode::sendCommand(uint32_t cmd, int32_t param) { 254 return toStatus(mBase->sendCommand(toEnumCommandType(cmd), param)); 255} 256 257Return<void> TWOmxNode::getParameter( 258 uint32_t index, hidl_vec<uint8_t> const& inParams, 259 getParameter_cb _hidl_cb) { 260 hidl_vec<uint8_t> params(inParams); 261 Status status = toStatus(mBase->getParameter( 262 toEnumIndexType(index), 263 static_cast<void*>(params.data()), 264 params.size())); 265 _hidl_cb(status, params); 266 return Void(); 267} 268 269Return<Status> TWOmxNode::setParameter( 270 uint32_t index, hidl_vec<uint8_t> const& inParams) { 271 hidl_vec<uint8_t> params(inParams); 272 return toStatus(mBase->setParameter( 273 toEnumIndexType(index), 274 static_cast<void const*>(params.data()), 275 params.size())); 276} 277 278Return<void> TWOmxNode::getConfig( 279 uint32_t index, const hidl_vec<uint8_t>& inConfig, 280 getConfig_cb _hidl_cb) { 281 hidl_vec<uint8_t> config(inConfig); 282 Status status = toStatus(mBase->getConfig( 283 toEnumIndexType(index), 284 static_cast<void*>(config.data()), 285 config.size())); 286 _hidl_cb(status, config); 287 return Void(); 288} 289 290Return<Status> TWOmxNode::setConfig( 291 uint32_t index, const hidl_vec<uint8_t>& inConfig) { 292 hidl_vec<uint8_t> config(inConfig); 293 return toStatus(mBase->setConfig( 294 toEnumIndexType(index), 295 static_cast<void const*>(config.data()), 296 config.size())); 297} 298 299Return<Status> TWOmxNode::setPortMode(uint32_t portIndex, PortMode mode) { 300 return toStatus(mBase->setPortMode(portIndex, toIOMXPortMode(mode))); 301} 302 303Return<Status> TWOmxNode::prepareForAdaptivePlayback( 304 uint32_t portIndex, bool enable, 305 uint32_t maxFrameWidth, uint32_t maxFrameHeight) { 306 return toStatus(mBase->prepareForAdaptivePlayback( 307 portIndex, 308 toEnumBool(enable), 309 maxFrameWidth, 310 maxFrameHeight)); 311} 312 313Return<void> TWOmxNode::configureVideoTunnelMode( 314 uint32_t portIndex, bool tunneled, uint32_t audioHwSync, 315 configureVideoTunnelMode_cb _hidl_cb) { 316 native_handle_t* sidebandHandle = nullptr; 317 Status status = toStatus(mBase->configureVideoTunnelMode( 318 portIndex, 319 toEnumBool(tunneled), 320 audioHwSync, 321 &sidebandHandle)); 322 _hidl_cb(status, hidl_handle(sidebandHandle)); 323 return Void(); 324} 325 326Return<void> TWOmxNode::getGraphicBufferUsage( 327 uint32_t portIndex, getGraphicBufferUsage_cb _hidl_cb) { 328 OMX_U32 usage; 329 Status status = toStatus(mBase->getGraphicBufferUsage( 330 portIndex, &usage)); 331 _hidl_cb(status, usage); 332 return Void(); 333} 334 335Return<Status> TWOmxNode::setInputSurface( 336 const sp<IOmxBufferSource>& bufferSource) { 337 return toStatus(mBase->setInputSurface(new LWOmxBufferSource( 338 bufferSource))); 339} 340 341Return<void> TWOmxNode::allocateSecureBuffer( 342 uint32_t portIndex, uint64_t size, 343 allocateSecureBuffer_cb _hidl_cb) { 344 IOMX::buffer_id buffer; 345 void* bufferData; 346 sp<NativeHandle> nativeHandle; 347 Status status = toStatus(mBase->allocateSecureBuffer( 348 portIndex, 349 static_cast<size_t>(size), 350 &buffer, 351 &bufferData, 352 &nativeHandle)); 353 _hidl_cb(status, buffer, nativeHandle == nullptr ? 354 nullptr : nativeHandle->handle()); 355 return Void(); 356} 357 358Return<void> TWOmxNode::useBuffer( 359 uint32_t portIndex, const CodecBuffer& codecBuffer, 360 useBuffer_cb _hidl_cb) { 361 IOMX::buffer_id buffer; 362 OMXBuffer omxBuffer; 363 if (!convertTo(&omxBuffer, codecBuffer)) { 364 _hidl_cb(Status::BAD_VALUE, 0); 365 return Void(); 366 } 367 Status status = toStatus(mBase->useBuffer( 368 portIndex, omxBuffer, &buffer)); 369 _hidl_cb(status, buffer); 370 return Void(); 371} 372 373Return<Status> TWOmxNode::freeBuffer(uint32_t portIndex, uint32_t buffer) { 374 return toStatus(mBase->freeBuffer(portIndex, buffer)); 375} 376 377Return<Status> TWOmxNode::fillBuffer( 378 uint32_t buffer, const CodecBuffer& codecBuffer, 379 const hidl_handle& fence) { 380 OMXBuffer omxBuffer; 381 if (!convertTo(&omxBuffer, codecBuffer)) { 382 return Status::BAD_VALUE; 383 } 384 return toStatus(mBase->fillBuffer( 385 buffer, 386 omxBuffer, 387 dup(native_handle_read_fd(fence)))); 388} 389 390Return<Status> TWOmxNode::emptyBuffer( 391 uint32_t buffer, const CodecBuffer& codecBuffer, uint32_t flags, 392 uint64_t timestampUs, const hidl_handle& fence) { 393 OMXBuffer omxBuffer; 394 if (!convertTo(&omxBuffer, codecBuffer)) { 395 return Status::BAD_VALUE; 396 } 397 return toStatus(mBase->emptyBuffer( 398 buffer, 399 omxBuffer, 400 flags, 401 toOMXTicks(timestampUs), 402 dup(native_handle_read_fd(fence)))); 403} 404 405Return<void> TWOmxNode::getExtensionIndex( 406 const hidl_string& parameterName, 407 getExtensionIndex_cb _hidl_cb) { 408 OMX_INDEXTYPE index; 409 Status status = toStatus(mBase->getExtensionIndex( 410 parameterName.c_str(), &index)); 411 _hidl_cb(status, toRawIndexType(index)); 412 return Void(); 413} 414 415Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) { 416 omx_message lMsg; 417 if (!convertTo(&lMsg, tMsg)) { 418 return Status::BAD_VALUE; 419 } 420 return toStatus(mBase->dispatchMessage(lMsg)); 421} 422 423} // namespace utils 424} // namespace V1_0 425} // namespace omx 426} // namespace media 427} // namespace hardware 428} // namespace android 429