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, 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 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, 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 160 status_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 177 status_t LWOmxNode::freeBuffer( 178 OMX_U32 portIndex, buffer_id buffer) { 179 return toStatusT(mBase->freeBuffer(portIndex, buffer)); 180 } 181 182 status_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 199 status_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 } 220 status_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 233 status_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 246 TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) { 247 } 248 249 Return<Status> TWOmxNode::freeNode() { 250 return toStatus(mBase->freeNode()); 251 } 252 253 Return<Status> TWOmxNode::sendCommand(uint32_t cmd, int32_t param) { 254 return toStatus(mBase->sendCommand(toEnumCommandType(cmd), param)); 255 } 256 257 Return<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 269 Return<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 278 Return<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 290 Return<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 299 Return<Status> TWOmxNode::setPortMode(uint32_t portIndex, PortMode mode) { 300 return toStatus(mBase->setPortMode(portIndex, toIOMXPortMode(mode))); 301 } 302 303 Return<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 313 Return<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 326 Return<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 335 Return<Status> TWOmxNode::setInputSurface( 336 const sp<IOmxBufferSource>& bufferSource) { 337 return toStatus(mBase->setInputSurface(new LWOmxBufferSource( 338 bufferSource))); 339 } 340 341 Return<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 358 Return<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 373 Return<Status> TWOmxNode::freeBuffer(uint32_t portIndex, uint32_t buffer) { 374 return toStatus(mBase->freeBuffer(portIndex, buffer)); 375 } 376 377 Return<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 390 Return<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 405 Return<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 415 Return<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