IOMX.cpp revision ac7d4125516299b8a3e6f2b25822a692bdd96311
143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar/* 243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Copyright (c) 2009 The Android Open Source Project 343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * 443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * you may not use this file except in compliance with the License. 643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * You may obtain a copy of the License at 743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * 843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * 1043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Unless required by applicable law or agreed to in writing, software 1143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * See the License for the specific language governing permissions and 14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount * limitations under the License. 1543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 1743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar//#define LOG_NDEBUG 0 18e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount#define LOG_TAG "IOMX" 19e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount#include <utils/Log.h> 204df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar 2196e1c821dd446d1ed78f8ae61131550588f60a24George Mount#include <sys/mman.h> 2296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <binder/IMemory.h> 246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <binder/Parcel.h> 2596e1c821dd446d1ed78f8ae61131550588f60a24George Mount#include <media/IOMX.h> 266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <media/stagefright/foundation/ADebug.h> 27ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount#include <media/openmax/OMX_IndexExt.h> 28ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount#include <media/OMXBuffer.h> 296047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <utils/NativeHandle.h> 306047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <gui/IGraphicBufferProducer.h> 31af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar 32af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar#include <omx/1.0/WOmxNode.h> 33af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar#include <android/IGraphicBufferSource.h> 3459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar#include <android/IOMXBufferSource.h> 35af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar 36af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarnamespace android { 3796e1c821dd446d1ed78f8ae61131550588f60a24George Mount 38af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarenum { 3996e1c821dd446d1ed78f8ae61131550588f60a24George Mount CONNECT = IBinder::FIRST_CALL_TRANSACTION, 4096e1c821dd446d1ed78f8ae61131550588f60a24George Mount LIST_NODES, 4196e1c821dd446d1ed78f8ae61131550588f60a24George Mount ALLOCATE_NODE, 426047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar CREATE_INPUT_SURFACE, 4396e1c821dd446d1ed78f8ae61131550588f60a24George Mount FREE_NODE, 4496e1c821dd446d1ed78f8ae61131550588f60a24George Mount SEND_COMMAND, 4596e1c821dd446d1ed78f8ae61131550588f60a24George Mount GET_PARAMETER, 466047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar SET_PARAMETER, 47af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar GET_CONFIG, 48af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar SET_CONFIG, 4996e1c821dd446d1ed78f8ae61131550588f60a24George Mount SET_PORT_MODE, 50af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar SET_INPUT_SURFACE, 515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar PREPARE_FOR_ADAPTIVE_PLAYBACK, 526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar ALLOC_SECURE_BUFFER, 535bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar USE_BUFFER, 54af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar FREE_BUFFER, 556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar FILL_BUFFER, 5643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar EMPTY_BUFFER, 5796e1c821dd446d1ed78f8ae61131550588f60a24George Mount GET_EXTENSION_INDEX, 5843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar OBSERVER_ON_MSG, 5943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar GET_GRAPHIC_BUFFER_USAGE, 6096e1c821dd446d1ed78f8ae61131550588f60a24George Mount CONFIGURE_VIDEO_TUNNEL_MODE, 616047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar DISPATCH_MESSAGE, 6296e1c821dd446d1ed78f8ae61131550588f60a24George Mount SET_QUIRKS, 636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar}; 646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 65af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarclass BpOMX : public BpInterface<IOMX> { 66af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarpublic: 676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar explicit BpOMX(const sp<IBinder> &impl) 6859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar : BpInterface<IOMX>(impl) { 69af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar } 7096e1c821dd446d1ed78f8ae61131550588f60a24George Mount 7196e1c821dd446d1ed78f8ae61131550588f60a24George Mount virtual status_t listNodes(List<ComponentInfo> *list) { 726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar list->clear(); 736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Parcel data, reply; 756047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar remote()->transact(LIST_NODES, data, &reply); 7796e1c821dd446d1ed78f8ae61131550588f60a24George Mount 786047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar int32_t n = reply.readInt32(); 7996e1c821dd446d1ed78f8ae61131550588f60a24George Mount for (int32_t i = 0; i < n; ++i) { 8096e1c821dd446d1ed78f8ae61131550588f60a24George Mount list->push_back(ComponentInfo()); 8196e1c821dd446d1ed78f8ae61131550588f60a24George Mount ComponentInfo &info = *--list->end(); 8243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar info.mName = reply.readString8(); 8496e1c821dd446d1ed78f8ae61131550588f60a24George Mount int32_t numRoles = reply.readInt32(); 8596e1c821dd446d1ed78f8ae61131550588f60a24George Mount for (int32_t j = 0; j < numRoles; ++j) { 866047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar info.mRoles.push_back(reply.readString8()); 876047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 886047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 894df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar 904df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar return OK; 916047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 926047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 93af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar virtual status_t allocateNode( 946047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar const char *name, const sp<IOMXObserver> &observer, 954df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar sp<IOMXNode> *omxNode) { 966047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Parcel data, reply; 976047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 984df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar data.writeCString(name); 994df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar data.writeStrongBinder(IInterface::asBinder(observer)); 1006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar remote()->transact(ALLOCATE_NODE, data, &reply); 1014df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar 1024df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar status_t err = reply.readInt32(); 1034df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar if (err == OK) { 104ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount *omxNode = IOMXNode::asInterface(reply.readStrongBinder()); 1056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } else { 106ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount omxNode->clear(); 1074df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar } 1086047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 1096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return err; 1106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 1116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 1126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar virtual status_t createInputSurface( 1136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar sp<IGraphicBufferProducer> *bufferProducer, 1144df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar sp<IGraphicBufferSource> *bufferSource) { 1156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Parcel data, reply; 1166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar status_t err; 1174df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 1184df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply); 1194df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar if (err != OK) { 1204df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar ALOGW("binder transaction failed: %d", err); 1214df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar return err; 1226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 12396e1c821dd446d1ed78f8ae61131550588f60a24George Mount 12496e1c821dd446d1ed78f8ae61131550588f60a24George Mount err = reply.readInt32(); 12543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar if (err != OK) { 126 return err; 127 } 128 129 *bufferProducer = IGraphicBufferProducer::asInterface( 130 reply.readStrongBinder()); 131 *bufferSource = IGraphicBufferSource::asInterface( 132 reply.readStrongBinder()); 133 134 return err; 135 } 136}; 137 138class BpOMXNode : public BpInterface<IOMXNode> { 139public: 140 explicit BpOMXNode(const sp<IBinder> &impl) 141 : BpInterface<IOMXNode>(impl) { 142 } 143 144 virtual status_t freeNode() { 145 Parcel data, reply; 146 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 147 remote()->transact(FREE_NODE, data, &reply); 148 149 return reply.readInt32(); 150 } 151 152 virtual status_t sendCommand( 153 OMX_COMMANDTYPE cmd, OMX_S32 param) { 154 Parcel data, reply; 155 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 156 data.writeInt32(cmd); 157 data.writeInt32(param); 158 remote()->transact(SEND_COMMAND, data, &reply); 159 160 return reply.readInt32(); 161 } 162 163 virtual status_t getParameter( 164 OMX_INDEXTYPE index, 165 void *params, size_t size) { 166 Parcel data, reply; 167 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 168 data.writeInt32(index); 169 data.writeInt64(size); 170 data.write(params, size); 171 remote()->transact(GET_PARAMETER, data, &reply); 172 173 status_t err = reply.readInt32(); 174 if (err != OK) { 175 return err; 176 } 177 178 reply.read(params, size); 179 180 return OK; 181 } 182 183 virtual status_t setParameter( 184 OMX_INDEXTYPE index, 185 const void *params, size_t size) { 186 Parcel data, reply; 187 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 188 data.writeInt32(index); 189 data.writeInt64(size); 190 data.write(params, size); 191 remote()->transact(SET_PARAMETER, data, &reply); 192 193 return reply.readInt32(); 194 } 195 196 virtual status_t getConfig( 197 OMX_INDEXTYPE index, 198 void *params, size_t size) { 199 Parcel data, reply; 200 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 201 data.writeInt32(index); 202 data.writeInt64(size); 203 data.write(params, size); 204 remote()->transact(GET_CONFIG, data, &reply); 205 206 status_t err = reply.readInt32(); 207 if (err != OK) { 208 return err; 209 } 210 211 reply.read(params, size); 212 213 return OK; 214 } 215 216 virtual status_t setConfig( 217 OMX_INDEXTYPE index, 218 const void *params, size_t size) { 219 Parcel data, reply; 220 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 221 data.writeInt32(index); 222 data.writeInt64(size); 223 data.write(params, size); 224 remote()->transact(SET_CONFIG, data, &reply); 225 226 return reply.readInt32(); 227 } 228 229 virtual status_t setPortMode( 230 OMX_U32 port_index, IOMX::PortMode mode) { 231 Parcel data, reply; 232 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 233 data.writeInt32(port_index); 234 data.writeInt32(mode); 235 remote()->transact(SET_PORT_MODE, data, &reply); 236 237 return reply.readInt32(); 238 } 239 240 virtual status_t getGraphicBufferUsage( 241 OMX_U32 port_index, OMX_U32* usage) { 242 Parcel data, reply; 243 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 244 data.writeInt32(port_index); 245 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); 246 247 status_t err = reply.readInt32(); 248 *usage = reply.readInt32(); 249 return err; 250 } 251 252 virtual status_t useBuffer( 253 OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) { 254 Parcel data, reply; 255 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 256 data.writeInt32(port_index); 257 258 status_t err = omxBuf.writeToParcel(&data); 259 if (err != OK) { 260 return err; 261 } 262 263 remote()->transact(USE_BUFFER, data, &reply); 264 265 err = reply.readInt32(); 266 if (err != OK) { 267 *buffer = 0; 268 269 return err; 270 } 271 272 *buffer = (buffer_id)reply.readInt32(); 273 274 return err; 275 } 276 277 virtual status_t setInputSurface( 278 const sp<IOMXBufferSource> &bufferSource) { 279 Parcel data, reply; 280 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 281 282 data.writeStrongBinder(IInterface::asBinder(bufferSource)); 283 284 status_t err = remote()->transact(SET_INPUT_SURFACE, data, &reply); 285 286 if (err != OK) { 287 ALOGW("binder transaction failed: %d", err); 288 return err; 289 } 290 291 err = reply.readInt32(); 292 293 return err; 294 } 295 296 virtual status_t prepareForAdaptivePlayback( 297 OMX_U32 port_index, OMX_BOOL enable, 298 OMX_U32 max_width, OMX_U32 max_height) { 299 Parcel data, reply; 300 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 301 data.writeInt32(port_index); 302 data.writeInt32((int32_t)enable); 303 data.writeInt32(max_width); 304 data.writeInt32(max_height); 305 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 306 307 status_t err = reply.readInt32(); 308 return err; 309 } 310 311 virtual status_t configureVideoTunnelMode( 312 OMX_U32 portIndex, OMX_BOOL tunneled, 313 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { 314 Parcel data, reply; 315 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 316 data.writeInt32(portIndex); 317 data.writeInt32((int32_t)tunneled); 318 data.writeInt32(audioHwSync); 319 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); 320 321 status_t err = reply.readInt32(); 322 if (err == OK && sidebandHandle) { 323 *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); 324 } 325 return err; 326 } 327 328 329 virtual status_t allocateSecureBuffer( 330 OMX_U32 port_index, size_t size, 331 buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) { 332 Parcel data, reply; 333 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 334 data.writeInt32(port_index); 335 data.writeInt64(size); 336 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply); 337 338 status_t err = reply.readInt32(); 339 if (err != OK) { 340 *buffer = 0; 341 *buffer_data = NULL; 342 *native_handle = NULL; 343 return err; 344 } 345 346 *buffer = (buffer_id)reply.readInt32(); 347 *buffer_data = (void *)reply.readInt64(); 348 if (*buffer_data == NULL) { 349 *native_handle = NativeHandle::create( 350 reply.readNativeHandle(), true /* ownsHandle */); 351 } else { 352 *native_handle = NULL; 353 } 354 return err; 355 } 356 357 virtual status_t freeBuffer( 358 OMX_U32 port_index, buffer_id buffer) { 359 Parcel data, reply; 360 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 361 data.writeInt32(port_index); 362 data.writeInt32((int32_t)buffer); 363 remote()->transact(FREE_BUFFER, data, &reply); 364 365 return reply.readInt32(); 366 } 367 368 virtual status_t fillBuffer( 369 buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) { 370 Parcel data, reply; 371 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 372 data.writeInt32((int32_t)buffer); 373 status_t err = omxBuf.writeToParcel(&data); 374 if (err != OK) { 375 return err; 376 } 377 data.writeInt32(fenceFd >= 0); 378 if (fenceFd >= 0) { 379 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 380 } 381 remote()->transact(FILL_BUFFER, data, &reply); 382 383 return reply.readInt32(); 384 } 385 386 virtual status_t emptyBuffer( 387 buffer_id buffer, const OMXBuffer &omxBuf, 388 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 389 Parcel data, reply; 390 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 391 data.writeInt32((int32_t)buffer); 392 status_t err = omxBuf.writeToParcel(&data); 393 if (err != OK) { 394 return err; 395 } 396 data.writeInt32(flags); 397 data.writeInt64(timestamp); 398 data.writeInt32(fenceFd >= 0); 399 if (fenceFd >= 0) { 400 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 401 } 402 remote()->transact(EMPTY_BUFFER, data, &reply); 403 404 return reply.readInt32(); 405 } 406 407 virtual status_t getExtensionIndex( 408 const char *parameter_name, 409 OMX_INDEXTYPE *index) { 410 Parcel data, reply; 411 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 412 data.writeCString(parameter_name); 413 414 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 415 416 status_t err = reply.readInt32(); 417 if (err == OK) { 418 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 419 } else { 420 *index = OMX_IndexComponentStartUnused; 421 } 422 423 return err; 424 } 425 426 virtual status_t dispatchMessage(const omx_message &msg) { 427 Parcel data, reply; 428 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 429 data.writeInt32(msg.fenceFd >= 0); 430 if (msg.fenceFd >= 0) { 431 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 432 } 433 data.writeInt32(msg.type); 434 data.write(&msg.u, sizeof(msg.u)); 435 436 remote()->transact(DISPATCH_MESSAGE, data, &reply); 437 438 return reply.readInt32(); 439 } 440 441 virtual status_t setQuirks(OMX_U32 quirks) { 442 Parcel data, reply; 443 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 444 data.writeInt32(quirks); 445 446 remote()->transact(SET_QUIRKS, data, &reply); 447 448 return reply.readInt32(); 449 } 450}; 451 452using ::android::hardware::media::omx::V1_0::utils::LWOmxNode; 453class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> { 454public: 455 HpOMXNode(const sp<IBinder>& base) : PBase(base) {} 456 457 virtual status_t freeNode() { 458 return mBase->freeNode(); 459 } 460 461 virtual status_t sendCommand( 462 OMX_COMMANDTYPE cmd, OMX_S32 param) { 463 return mBase->sendCommand(cmd, param); 464 } 465 466 virtual status_t getParameter( 467 OMX_INDEXTYPE index, void *params, size_t size) { 468 return mBase->getParameter(index, params, size); 469 } 470 471 virtual status_t setParameter( 472 OMX_INDEXTYPE index, const void *params, size_t size) { 473 return mBase->setParameter(index, params, size); 474 } 475 476 virtual status_t getConfig( 477 OMX_INDEXTYPE index, void *params, size_t size) { 478 return mBase->getConfig(index, params, size); 479 } 480 481 virtual status_t setConfig( 482 OMX_INDEXTYPE index, const void *params, size_t size) { 483 return mBase->setConfig(index, params, size); 484 } 485 486 virtual status_t setPortMode( 487 OMX_U32 port_index, IOMX::PortMode mode) { 488 return mBase->setPortMode(port_index, mode); 489 } 490 491 virtual status_t prepareForAdaptivePlayback( 492 OMX_U32 portIndex, OMX_BOOL enable, 493 OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { 494 return mBase->prepareForAdaptivePlayback( 495 portIndex, enable, maxFrameWidth, maxFrameHeight); 496 } 497 498 virtual status_t configureVideoTunnelMode( 499 OMX_U32 portIndex, OMX_BOOL tunneled, 500 OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { 501 return mBase->configureVideoTunnelMode( 502 portIndex, tunneled, audioHwSync, sidebandHandle); 503 } 504 505 virtual status_t getGraphicBufferUsage( 506 OMX_U32 port_index, OMX_U32* usage) { 507 return mBase->getGraphicBufferUsage(port_index, usage); 508 } 509 510 virtual status_t setInputSurface( 511 const sp<IOMXBufferSource> &bufferSource) { 512 return mBase->setInputSurface(bufferSource); 513 } 514 515 virtual status_t allocateSecureBuffer( 516 OMX_U32 port_index, size_t size, buffer_id *buffer, 517 void **buffer_data, sp<NativeHandle> *native_handle) { 518 return mBase->allocateSecureBuffer( 519 port_index, size, buffer, buffer_data, native_handle); 520 } 521 522 virtual status_t useBuffer( 523 OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) { 524 return mBase->useBuffer(port_index, omxBuf, buffer); 525 } 526 527 virtual status_t freeBuffer( 528 OMX_U32 port_index, buffer_id buffer) { 529 return mBase->freeBuffer(port_index, buffer); 530 } 531 532 virtual status_t fillBuffer( 533 buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) { 534 return mBase->fillBuffer(buffer, omxBuf, fenceFd); 535 } 536 537 virtual status_t emptyBuffer( 538 buffer_id buffer, const OMXBuffer &omxBuf, 539 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) { 540 return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd); 541 } 542 543 virtual status_t getExtensionIndex( 544 const char *parameter_name, 545 OMX_INDEXTYPE *index) { 546 return mBase->getExtensionIndex(parameter_name, index); 547 } 548 549 virtual status_t dispatchMessage(const omx_message &msg) { 550 return mBase->dispatchMessage(msg); 551 } 552 553 // TODO: this is temporary, will be removed when quirks move to OMX side 554 virtual status_t setQuirks(OMX_U32 quirks) { 555 return mBase->setQuirks(quirks); 556 } 557}; 558 559IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 560IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode"); 561 562//////////////////////////////////////////////////////////////////////////////// 563 564#define CHECK_OMX_INTERFACE(interface, data, reply) \ 565 do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \ 566 ALOGW("Call incorrectly routed to " #interface); \ 567 return PERMISSION_DENIED; \ 568 } } while (0) 569 570status_t BnOMX::onTransact( 571 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 572 switch (code) { 573 case LIST_NODES: 574 { 575 CHECK_OMX_INTERFACE(IOMX, data, reply); 576 577 List<ComponentInfo> list; 578 listNodes(&list); 579 580 reply->writeInt32(list.size()); 581 for (List<ComponentInfo>::iterator it = list.begin(); 582 it != list.end(); ++it) { 583 ComponentInfo &cur = *it; 584 585 reply->writeString8(cur.mName); 586 reply->writeInt32(cur.mRoles.size()); 587 for (List<String8>::iterator role_it = cur.mRoles.begin(); 588 role_it != cur.mRoles.end(); ++role_it) { 589 reply->writeString8(*role_it); 590 } 591 } 592 593 return NO_ERROR; 594 } 595 596 case ALLOCATE_NODE: 597 { 598 CHECK_OMX_INTERFACE(IOMX, data, reply); 599 600 const char *name = data.readCString(); 601 602 sp<IOMXObserver> observer = 603 interface_cast<IOMXObserver>(data.readStrongBinder()); 604 605 if (name == NULL || observer == NULL) { 606 ALOGE("b/26392700"); 607 reply->writeInt32(INVALID_OPERATION); 608 return NO_ERROR; 609 } 610 611 sp<IOMXNode> omxNode; 612 613 status_t err = allocateNode(name, observer, &omxNode); 614 615 reply->writeInt32(err); 616 if (err == OK) { 617 reply->writeStrongBinder(IInterface::asBinder(omxNode)); 618 } 619 620 return NO_ERROR; 621 } 622 623 case CREATE_INPUT_SURFACE: 624 { 625 CHECK_OMX_INTERFACE(IOMX, data, reply); 626 627 sp<IGraphicBufferProducer> bufferProducer; 628 sp<IGraphicBufferSource> bufferSource; 629 status_t err = createInputSurface(&bufferProducer, &bufferSource); 630 631 reply->writeInt32(err); 632 633 if (err == OK) { 634 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 635 reply->writeStrongBinder(IInterface::asBinder(bufferSource)); 636 } 637 638 return NO_ERROR; 639 } 640 641 default: 642 return BBinder::onTransact(code, data, reply, flags); 643 } 644} 645 646status_t BnOMXNode::onTransact( 647 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 648 switch (code) { 649 case FREE_NODE: 650 { 651 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 652 653 reply->writeInt32(freeNode()); 654 655 return NO_ERROR; 656 } 657 658 case SEND_COMMAND: 659 { 660 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 661 662 OMX_COMMANDTYPE cmd = 663 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 664 665 OMX_S32 param = data.readInt32(); 666 reply->writeInt32(sendCommand(cmd, param)); 667 668 return NO_ERROR; 669 } 670 671 case GET_PARAMETER: 672 case SET_PARAMETER: 673 case GET_CONFIG: 674 case SET_CONFIG: 675 { 676 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 677 678 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 679 680 size_t size = data.readInt64(); 681 682 status_t err = NOT_ENOUGH_DATA; 683 void *params = NULL; 684 size_t pageSize = 0; 685 size_t allocSize = 0; 686 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits); 687 if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) { 688 // we expect the structure to contain at least the size and 689 // version, 8 bytes total 690 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); 691 android_errorWriteLog(0x534e4554, "27207275"); 692 } else { 693 err = NO_MEMORY; 694 pageSize = (size_t) sysconf(_SC_PAGE_SIZE); 695 if (size > SIZE_MAX - (pageSize * 2)) { 696 ALOGE("requested param size too big"); 697 } else { 698 allocSize = (size + pageSize * 2) & ~(pageSize - 1); 699 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE, 700 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */); 701 } 702 if (params != MAP_FAILED && params != NULL) { 703 err = data.read(params, size); 704 if (err != OK) { 705 android_errorWriteLog(0x534e4554, "26914474"); 706 } else { 707 err = NOT_ENOUGH_DATA; 708 OMX_U32 declaredSize = *(OMX_U32*)params; 709 if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && 710 declaredSize > size) { 711 // the buffer says it's bigger than it actually is 712 ALOGE("b/27207275 (%u/%zu)", declaredSize, size); 713 android_errorWriteLog(0x534e4554, "27207275"); 714 } else { 715 // mark the last page as inaccessible, to avoid exploitation 716 // of codecs that access past the end of the allocation because 717 // they didn't check the size 718 if (mprotect((char*)params + allocSize - pageSize, pageSize, 719 PROT_NONE) != 0) { 720 ALOGE("mprotect failed: %s", strerror(errno)); 721 } else { 722 switch (code) { 723 case GET_PARAMETER: 724 err = getParameter(index, params, size); 725 break; 726 case SET_PARAMETER: 727 err = setParameter(index, params, size); 728 break; 729 case GET_CONFIG: 730 err = getConfig(index, params, size); 731 break; 732 case SET_CONFIG: 733 err = setConfig(index, params, size); 734 break; 735 default: 736 TRESPASS(); 737 } 738 } 739 } 740 } 741 } else { 742 ALOGE("couldn't map: %s", strerror(errno)); 743 } 744 } 745 746 reply->writeInt32(err); 747 748 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 749 reply->write(params, size); 750 } 751 752 if (params) { 753 munmap(params, allocSize); 754 } 755 params = NULL; 756 757 return NO_ERROR; 758 } 759 760 case SET_PORT_MODE: 761 { 762 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 763 OMX_U32 port_index = data.readInt32(); 764 IOMX::PortMode mode = (IOMX::PortMode) data.readInt32(); 765 reply->writeInt32(setPortMode(port_index, mode)); 766 767 return NO_ERROR; 768 } 769 770 case GET_GRAPHIC_BUFFER_USAGE: 771 { 772 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 773 774 OMX_U32 port_index = data.readInt32(); 775 776 OMX_U32 usage = 0; 777 status_t err = getGraphicBufferUsage(port_index, &usage); 778 reply->writeInt32(err); 779 reply->writeInt32(usage); 780 781 return NO_ERROR; 782 } 783 784 case USE_BUFFER: 785 { 786 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 787 788 OMX_U32 port_index = data.readInt32(); 789 790 OMXBuffer omxBuf; 791 status_t err = omxBuf.readFromParcel(&data); 792 if (err != OK) { 793 return err; 794 } 795 796 buffer_id buffer; 797 err = useBuffer(port_index, omxBuf, &buffer); 798 reply->writeInt32(err); 799 800 if (err == OK) { 801 reply->writeInt32((int32_t)buffer); 802 } 803 804 return NO_ERROR; 805 } 806 807 case SET_INPUT_SURFACE: 808 { 809 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 810 811 sp<IOMXBufferSource> bufferSource = 812 interface_cast<IOMXBufferSource>(data.readStrongBinder()); 813 814 status_t err = setInputSurface(bufferSource); 815 reply->writeInt32(err); 816 817 return NO_ERROR; 818 } 819 820 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 821 { 822 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 823 824 OMX_U32 port_index = data.readInt32(); 825 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 826 OMX_U32 max_width = data.readInt32(); 827 OMX_U32 max_height = data.readInt32(); 828 829 status_t err = prepareForAdaptivePlayback( 830 port_index, enable, max_width, max_height); 831 reply->writeInt32(err); 832 833 return NO_ERROR; 834 } 835 836 case CONFIGURE_VIDEO_TUNNEL_MODE: 837 { 838 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 839 840 OMX_U32 port_index = data.readInt32(); 841 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 842 OMX_U32 audio_hw_sync = data.readInt32(); 843 844 native_handle_t *sideband_handle = NULL; 845 status_t err = configureVideoTunnelMode( 846 port_index, tunneled, audio_hw_sync, &sideband_handle); 847 reply->writeInt32(err); 848 if(err == OK){ 849 reply->writeNativeHandle(sideband_handle); 850 } 851 852 return NO_ERROR; 853 } 854 855 case ALLOC_SECURE_BUFFER: 856 { 857 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 858 859 OMX_U32 port_index = data.readInt32(); 860 if (!isSecure() || port_index != 0 /* kPortIndexInput */) { 861 ALOGE("b/24310423"); 862 reply->writeInt32(INVALID_OPERATION); 863 return NO_ERROR; 864 } 865 866 size_t size = data.readInt64(); 867 868 buffer_id buffer; 869 void *buffer_data = NULL; 870 sp<NativeHandle> native_handle; 871 status_t err = allocateSecureBuffer( 872 port_index, size, &buffer, &buffer_data, &native_handle); 873 reply->writeInt32(err); 874 875 if (err == OK) { 876 reply->writeInt32((int32_t)buffer); 877 reply->writeInt64((uintptr_t)buffer_data); 878 if (buffer_data == NULL) { 879 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle()); 880 } 881 } 882 883 return NO_ERROR; 884 } 885 886 case FREE_BUFFER: 887 { 888 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 889 890 OMX_U32 port_index = data.readInt32(); 891 buffer_id buffer = (buffer_id)data.readInt32(); 892 reply->writeInt32(freeBuffer(port_index, buffer)); 893 894 return NO_ERROR; 895 } 896 897 case FILL_BUFFER: 898 { 899 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 900 901 buffer_id buffer = (buffer_id)data.readInt32(); 902 903 OMXBuffer omxBuf; 904 status_t err = omxBuf.readFromParcel(&data); 905 if (err != OK) { 906 return err; 907 } 908 909 bool haveFence = data.readInt32(); 910 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 911 912 reply->writeInt32(fillBuffer(buffer, omxBuf, fenceFd)); 913 914 return NO_ERROR; 915 } 916 917 case EMPTY_BUFFER: 918 { 919 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 920 921 buffer_id buffer = (buffer_id)data.readInt32(); 922 OMXBuffer omxBuf; 923 status_t err = omxBuf.readFromParcel(&data); 924 if (err != OK) { 925 return err; 926 } 927 OMX_U32 flags = data.readInt32(); 928 OMX_TICKS timestamp = data.readInt64(); 929 bool haveFence = data.readInt32(); 930 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 931 reply->writeInt32(emptyBuffer( 932 buffer, omxBuf, flags, timestamp, fenceFd)); 933 934 return NO_ERROR; 935 } 936 937 case GET_EXTENSION_INDEX: 938 { 939 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 940 941 const char *parameter_name = data.readCString(); 942 943 if (parameter_name == NULL) { 944 ALOGE("b/26392700"); 945 reply->writeInt32(INVALID_OPERATION); 946 return NO_ERROR; 947 } 948 949 OMX_INDEXTYPE index; 950 status_t err = getExtensionIndex(parameter_name, &index); 951 952 reply->writeInt32(err); 953 954 if (err == OK) { 955 reply->writeInt32(index); 956 } 957 958 return OK; 959 } 960 961 case DISPATCH_MESSAGE: 962 { 963 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 964 omx_message msg; 965 int haveFence = data.readInt32(); 966 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 967 msg.type = (typeof(msg.type))data.readInt32(); 968 status_t err = data.read(&msg.u, sizeof(msg.u)); 969 970 if (err == OK) { 971 err = dispatchMessage(msg); 972 } 973 reply->writeInt32(err); 974 975 return NO_ERROR; 976 } 977 978 case SET_QUIRKS: 979 { 980 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 981 982 OMX_U32 quirks = data.readInt32(); 983 984 reply->writeInt32(setQuirks(quirks)); 985 986 return NO_ERROR; 987 } 988 989 default: 990 return BBinder::onTransact(code, data, reply, flags); 991 } 992} 993 994//////////////////////////////////////////////////////////////////////////////// 995 996class BpOMXObserver : public BpInterface<IOMXObserver> { 997public: 998 explicit BpOMXObserver(const sp<IBinder> &impl) 999 : BpInterface<IOMXObserver>(impl) { 1000 } 1001 1002 virtual void onMessages(const std::list<omx_message> &messages) { 1003 Parcel data, reply; 1004 std::list<omx_message>::const_iterator it = messages.cbegin(); 1005 if (messages.empty()) { 1006 return; 1007 } 1008 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1009 while (it != messages.cend()) { 1010 const omx_message &msg = *it++; 1011 data.writeInt32(msg.fenceFd >= 0); 1012 if (msg.fenceFd >= 0) { 1013 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1014 } 1015 data.writeInt32(msg.type); 1016 data.write(&msg.u, sizeof(msg.u)); 1017 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1018 } 1019 data.writeInt32(-1); // mark end 1020 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1021 } 1022}; 1023 1024IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1025 1026status_t BnOMXObserver::onTransact( 1027 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1028 switch (code) { 1029 case OBSERVER_ON_MSG: 1030 { 1031 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1032 std::list<omx_message> messages; 1033 status_t err = FAILED_TRANSACTION; // must receive at least one message 1034 do { 1035 int haveFence = data.readInt32(); 1036 if (haveFence < 0) { // we use -1 to mark end of messages 1037 break; 1038 } 1039 omx_message msg; 1040 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1041 msg.type = (typeof(msg.type))data.readInt32(); 1042 err = data.read(&msg.u, sizeof(msg.u)); 1043 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1044 messages.push_back(msg); 1045 } while (err == OK); 1046 1047 if (err == OK) { 1048 onMessages(messages); 1049 } 1050 1051 return err; 1052 } 1053 1054 default: 1055 return BBinder::onTransact(code, data, reply, flags); 1056 } 1057} 1058 1059} // namespace android 1060