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 23 namespace android { 24 namespace hardware { 25 namespace media { 26 namespace omx { 27 namespace V1_0 { 28 namespace utils { 29 30 using ::android::hardware::Void; 31 32 // LWOmxNode 33 status_t LWOmxNode::freeNode() { 34 return toStatusT(mBase->freeNode()); 35 } 36 37 status_t LWOmxNode::sendCommand( 38 OMX_COMMANDTYPE cmd, OMX_S32 param) { 39 return toStatusT(mBase->sendCommand( 40 toRawCommandType(cmd), param)); 41 } 42 43 status_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]( 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 61 status_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 68 status_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 86 status_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 92 status_t LWOmxNode::setPortMode( 93 OMX_U32 port_index, IOMX::PortMode mode) { 94 return toStatusT(mBase->setPortMode(port_index, toHardwarePortMode(mode))); 95 } 96 97 status_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 104 status_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 121 status_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 134 status_t LWOmxNode::setInputSurface( 135 const sp<IOMXBufferSource> &bufferSource) { 136 return toStatusT(mBase->setInputSurface( 137 new TWOmxBufferSource(bufferSource))); 138 } 139 140 status_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, native_handle]( 149 Status status, 150 uint32_t outBuffer, 151 hidl_handle const& outNativeHandle) { 152 fnStatus = toStatusT(status); 153 *buffer = outBuffer; 154 *native_handle = outNativeHandle.getNativeHandle() == nullptr ? 155 nullptr : NativeHandle::create( 156 native_handle_clone(outNativeHandle), true); 157 })); 158 return transStatus == NO_ERROR ? fnStatus : transStatus; 159 } 160 161 status_t LWOmxNode::useBuffer( 162 OMX_U32 portIndex, const OMXBuffer &omxBuffer, buffer_id *buffer) { 163 CodecBuffer codecBuffer; 164 if (!wrapAs(&codecBuffer, omxBuffer)) { 165 return BAD_VALUE; 166 } 167 status_t fnStatus; 168 status_t transStatus = toStatusT(mBase->useBuffer( 169 portIndex, 170 codecBuffer, 171 [&fnStatus, buffer](Status status, uint32_t outBuffer) { 172 fnStatus = toStatusT(status); 173 *buffer = outBuffer; 174 })); 175 return transStatus == NO_ERROR ? fnStatus : transStatus; 176 } 177 178 status_t LWOmxNode::freeBuffer( 179 OMX_U32 portIndex, buffer_id buffer) { 180 return toStatusT(mBase->freeBuffer(portIndex, buffer)); 181 } 182 183 status_t LWOmxNode::fillBuffer( 184 buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) { 185 CodecBuffer codecBuffer; 186 if (!wrapAs(&codecBuffer, omxBuffer)) { 187 return BAD_VALUE; 188 } 189 native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd); 190 if (!fenceNh) { 191 return NO_MEMORY; 192 } 193 status_t status = toStatusT(mBase->fillBuffer( 194 buffer, codecBuffer, fenceNh)); 195 native_handle_close(fenceNh); 196 native_handle_delete(fenceNh); 197 return status; 198 } 199 200 status_t LWOmxNode::emptyBuffer( 201 buffer_id buffer, const OMXBuffer &omxBuffer, 202 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 203 CodecBuffer codecBuffer; 204 if (!wrapAs(&codecBuffer, omxBuffer)) { 205 return BAD_VALUE; 206 } 207 native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd); 208 if (!fenceNh) { 209 return NO_MEMORY; 210 } 211 status_t status = toStatusT(mBase->emptyBuffer( 212 buffer, 213 codecBuffer, 214 flags, 215 toRawTicks(timestamp), 216 fenceNh)); 217 native_handle_close(fenceNh); 218 native_handle_delete(fenceNh); 219 return status; 220 } 221 status_t LWOmxNode::getExtensionIndex( 222 const char *parameter_name, 223 OMX_INDEXTYPE *index) { 224 status_t fnStatus; 225 status_t transStatus = toStatusT(mBase->getExtensionIndex( 226 hidl_string(parameter_name), 227 [&fnStatus, index](Status status, uint32_t outIndex) { 228 fnStatus = toStatusT(status); 229 *index = toEnumIndexType(outIndex); 230 })); 231 return transStatus == NO_ERROR ? fnStatus : transStatus; 232 } 233 234 status_t LWOmxNode::dispatchMessage(const omx_message &lMsg) { 235 Message tMsg; 236 native_handle_t* nh; 237 if (!wrapAs(&tMsg, &nh, lMsg)) { 238 return NO_MEMORY; 239 } 240 status_t status = toStatusT(mBase->dispatchMessage(tMsg)); 241 native_handle_close(nh); 242 native_handle_delete(nh); 243 return status; 244 } 245 246 // TWOmxNode 247 TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) { 248 } 249 250 Return<Status> TWOmxNode::freeNode() { 251 return toStatus(mBase->freeNode()); 252 } 253 254 Return<Status> TWOmxNode::sendCommand(uint32_t cmd, int32_t param) { 255 return toStatus(mBase->sendCommand(toEnumCommandType(cmd), param)); 256 } 257 258 Return<void> TWOmxNode::getParameter( 259 uint32_t index, hidl_vec<uint8_t> const& inParams, 260 getParameter_cb _hidl_cb) { 261 hidl_vec<uint8_t> params(inParams); 262 Status status = toStatus(mBase->getParameter( 263 toEnumIndexType(index), 264 static_cast<void*>(params.data()), 265 params.size())); 266 _hidl_cb(status, params); 267 return Void(); 268 } 269 270 Return<Status> TWOmxNode::setParameter( 271 uint32_t index, hidl_vec<uint8_t> const& inParams) { 272 hidl_vec<uint8_t> params(inParams); 273 return toStatus(mBase->setParameter( 274 toEnumIndexType(index), 275 static_cast<void const*>(params.data()), 276 params.size())); 277 } 278 279 Return<void> TWOmxNode::getConfig( 280 uint32_t index, const hidl_vec<uint8_t>& inConfig, 281 getConfig_cb _hidl_cb) { 282 hidl_vec<uint8_t> config(inConfig); 283 Status status = toStatus(mBase->getConfig( 284 toEnumIndexType(index), 285 static_cast<void*>(config.data()), 286 config.size())); 287 _hidl_cb(status, config); 288 return Void(); 289 } 290 291 Return<Status> TWOmxNode::setConfig( 292 uint32_t index, const hidl_vec<uint8_t>& inConfig) { 293 hidl_vec<uint8_t> config(inConfig); 294 return toStatus(mBase->setConfig( 295 toEnumIndexType(index), 296 static_cast<void const*>(config.data()), 297 config.size())); 298 } 299 300 Return<Status> TWOmxNode::setPortMode(uint32_t portIndex, PortMode mode) { 301 return toStatus(mBase->setPortMode(portIndex, toIOMXPortMode(mode))); 302 } 303 304 Return<Status> TWOmxNode::prepareForAdaptivePlayback( 305 uint32_t portIndex, bool enable, 306 uint32_t maxFrameWidth, uint32_t maxFrameHeight) { 307 return toStatus(mBase->prepareForAdaptivePlayback( 308 portIndex, 309 toEnumBool(enable), 310 maxFrameWidth, 311 maxFrameHeight)); 312 } 313 314 Return<void> TWOmxNode::configureVideoTunnelMode( 315 uint32_t portIndex, bool tunneled, uint32_t audioHwSync, 316 configureVideoTunnelMode_cb _hidl_cb) { 317 native_handle_t* sidebandHandle = nullptr; 318 Status status = toStatus(mBase->configureVideoTunnelMode( 319 portIndex, 320 toEnumBool(tunneled), 321 audioHwSync, 322 &sidebandHandle)); 323 _hidl_cb(status, hidl_handle(sidebandHandle)); 324 return Void(); 325 } 326 327 Return<void> TWOmxNode::getGraphicBufferUsage( 328 uint32_t portIndex, getGraphicBufferUsage_cb _hidl_cb) { 329 OMX_U32 usage; 330 Status status = toStatus(mBase->getGraphicBufferUsage( 331 portIndex, &usage)); 332 _hidl_cb(status, usage); 333 return Void(); 334 } 335 336 Return<Status> TWOmxNode::setInputSurface( 337 const sp<IOmxBufferSource>& bufferSource) { 338 return toStatus(mBase->setInputSurface(new LWOmxBufferSource( 339 bufferSource))); 340 } 341 342 Return<void> TWOmxNode::allocateSecureBuffer( 343 uint32_t portIndex, uint64_t size, 344 allocateSecureBuffer_cb _hidl_cb) { 345 IOMX::buffer_id buffer; 346 void* bufferData; 347 sp<NativeHandle> nativeHandle; 348 Status status = toStatus(mBase->allocateSecureBuffer( 349 portIndex, 350 static_cast<size_t>(size), 351 &buffer, 352 &bufferData, 353 &nativeHandle)); 354 _hidl_cb(status, buffer, nativeHandle == nullptr ? 355 nullptr : nativeHandle->handle()); 356 return Void(); 357 } 358 359 Return<void> TWOmxNode::useBuffer( 360 uint32_t portIndex, const CodecBuffer& codecBuffer, 361 useBuffer_cb _hidl_cb) { 362 IOMX::buffer_id buffer; 363 OMXBuffer omxBuffer; 364 if (!convertTo(&omxBuffer, codecBuffer)) { 365 _hidl_cb(Status::BAD_VALUE, 0); 366 return Void(); 367 } 368 Status status = toStatus(mBase->useBuffer( 369 portIndex, omxBuffer, &buffer)); 370 _hidl_cb(status, buffer); 371 return Void(); 372 } 373 374 Return<Status> TWOmxNode::freeBuffer(uint32_t portIndex, uint32_t buffer) { 375 return toStatus(mBase->freeBuffer(portIndex, buffer)); 376 } 377 378 Return<Status> TWOmxNode::fillBuffer( 379 uint32_t buffer, const CodecBuffer& codecBuffer, 380 const hidl_handle& fence) { 381 OMXBuffer omxBuffer; 382 if (!convertTo(&omxBuffer, codecBuffer)) { 383 return Status::BAD_VALUE; 384 } 385 return toStatus(mBase->fillBuffer( 386 buffer, 387 omxBuffer, 388 dup(native_handle_read_fd(fence)))); 389 } 390 391 Return<Status> TWOmxNode::emptyBuffer( 392 uint32_t buffer, const CodecBuffer& codecBuffer, uint32_t flags, 393 uint64_t timestampUs, const hidl_handle& fence) { 394 OMXBuffer omxBuffer; 395 if (!convertTo(&omxBuffer, codecBuffer)) { 396 return Status::BAD_VALUE; 397 } 398 return toStatus(mBase->emptyBuffer( 399 buffer, 400 omxBuffer, 401 flags, 402 toOMXTicks(timestampUs), 403 dup(native_handle_read_fd(fence)))); 404 } 405 406 Return<void> TWOmxNode::getExtensionIndex( 407 const hidl_string& parameterName, 408 getExtensionIndex_cb _hidl_cb) { 409 OMX_INDEXTYPE index; 410 Status status = toStatus(mBase->getExtensionIndex( 411 parameterName.c_str(), &index)); 412 _hidl_cb(status, toRawIndexType(index)); 413 return Void(); 414 } 415 416 Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) { 417 omx_message lMsg; 418 if (!convertTo(&lMsg, tMsg)) { 419 return Status::BAD_VALUE; 420 } 421 return toStatus(mBase->dispatchMessage(lMsg)); 422 } 423 424 } // namespace utils 425 } // namespace V1_0 426 } // namespace omx 427 } // namespace media 428 } // namespace hardware 429 } // namespace android 430