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