Loading include/media/IOMX.h +1 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ public: virtual status_t allocateNode( const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node) = 0; virtual status_t freeNode(node_id node) = 0; Loading include/media/stagefright/ACodec.h +1 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ private: uint32_t mFlags; uint32_t mQuirks; sp<IOMX> mOMX; sp<IBinder> mNodeBinder; IOMX::node_id mNode; sp<MemoryDealer> mDealer[2]; Loading media/libmedia/IOMX.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ public: } virtual status_t allocateNode( const char *name, const sp<IOMXObserver> &observer, node_id *node) { const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node) { Parcel data, reply; data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeCString(name); Loading @@ -108,6 +110,9 @@ public: status_t err = reply.readInt32(); if (err == OK) { *node = (node_id)reply.readInt32(); if (nodeBinder != NULL) { *nodeBinder = remote(); } } else { *node = 0; } Loading Loading @@ -656,7 +661,8 @@ status_t BnOMX::onTransact( node_id node; status_t err = allocateNode(name, observer, &node); status_t err = allocateNode(name, observer, NULL /* nodeBinder */, &node); reply->writeInt32(err); if (err == OK) { reply->writeInt32((int32_t)node); Loading media/libstagefright/ACodec.cpp +11 −10 Original line number Diff line number Diff line Loading @@ -5541,7 +5541,7 @@ void ACodec::UninitializedState::stateEntered() { ALOGV("Now uninitialized"); if (mDeathNotifier != NULL) { IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier); mDeathNotifier.clear(); } Loading Loading @@ -5638,13 +5638,6 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); mDeathNotifier = new DeathNotifier(notify); if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { // This was a local binder, if it dies so do we, we won't care // about any notifications in the afterlife. mDeathNotifier.clear(); } Vector<AString> matchingCodecs; AString mime; Loading Loading @@ -5683,7 +5676,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { pid_t tid = gettid(); int prevPriority = androidGetThreadPriority(tid); androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); err = omx->allocateNode(componentName.c_str(), observer, &node); err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node); androidSetThreadPriority(tid, prevPriority); if (err == OK) { Loading @@ -5707,6 +5700,14 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { return false; } mDeathNotifier = new DeathNotifier(notify); if (mCodec->mNodeBinder == NULL || mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) { // This was a local binder, if it dies so do we, we won't care // about any notifications in the afterlife. mDeathNotifier.clear(); } notify = new AMessage(kWhatOMXMessageList, mCodec); observer->setNotificationMessage(notify); Loading Loading @@ -7078,7 +7079,7 @@ status_t ACodec::queryCapabilities( sp<CodecObserver> observer = new CodecObserver; IOMX::node_id node = 0; err = omx->allocateNode(name.c_str(), observer, &node); err = omx->allocateNode(name.c_str(), observer, NULL, &node); if (err != OK) { client.disconnect(); return err; Loading media/libstagefright/OMXClient.cpp +105 −34 Original line number Diff line number Diff line Loading @@ -25,19 +25,29 @@ #include <binder/IServiceManager.h> #include <media/IMediaPlayerService.h> #include <media/IMediaCodecService.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/OMXClient.h> #include <cutils/properties.h> #include <utils/KeyedVector.h> #include "include/OMX.h" namespace android { static bool sCodecProcessEnabled = true; struct MuxOMX : public IOMX { MuxOMX(const sp<IOMX> &remoteOMX); MuxOMX(const sp<IOMX> &mediaServerOMX, const sp<IOMX> &mediaCodecOMX); virtual ~MuxOMX(); virtual IBinder *onAsBinder() { return IInterface::asBinder(mRemoteOMX).get(); } // Nobody should be calling this. In case someone does anyway, just // return the media server IOMX. // TODO: return NULL virtual IBinder *onAsBinder() { ALOGE("MuxOMX::onAsBinder should not be called"); return IInterface::asBinder(mMediaServerOMX).get(); } virtual bool livesLocally(node_id node, pid_t pid); Loading @@ -45,6 +55,7 @@ struct MuxOMX : public IOMX { virtual status_t allocateNode( const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node); virtual status_t freeNode(node_id node); Loading Loading @@ -148,23 +159,32 @@ struct MuxOMX : public IOMX { private: mutable Mutex mLock; sp<IOMX> mRemoteOMX; sp<IOMX> mMediaServerOMX; sp<IOMX> mMediaCodecOMX; sp<IOMX> mLocalOMX; KeyedVector<node_id, bool> mIsLocalNode; typedef enum { LOCAL, MEDIAPROCESS, CODECPROCESS } node_location; KeyedVector<node_id, node_location> mNodeLocation; bool isLocalNode(node_id node) const; bool isLocalNode_l(node_id node) const; const sp<IOMX> &getOMX(node_id node) const; const sp<IOMX> &getOMX_l(node_id node) const; static bool CanLiveLocally(const char *name); static node_location getPreferredCodecLocation(const char *name); DISALLOW_EVIL_CONSTRUCTORS(MuxOMX); }; MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX) : mRemoteOMX(remoteOMX) { MuxOMX::MuxOMX(const sp<IOMX> &mediaServerOMX, const sp<IOMX> &mediaCodecOMX) : mMediaServerOMX(mediaServerOMX), mMediaCodecOMX(mediaCodecOMX) { ALOGI("MuxOMX ctor"); } MuxOMX::~MuxOMX() { Loading @@ -177,27 +197,49 @@ bool MuxOMX::isLocalNode(node_id node) const { } bool MuxOMX::isLocalNode_l(node_id node) const { return mIsLocalNode.indexOfKey(node) >= 0; return mNodeLocation.valueFor(node) == LOCAL; } // static bool MuxOMX::CanLiveLocally(const char *name) { MuxOMX::node_location MuxOMX::getPreferredCodecLocation(const char *name) { if (sCodecProcessEnabled) { // all non-secure decoders plus OMX.google.* encoders can go in the codec process if ((strcasestr(name, "decoder") && !strcasestr(name, "secure")) || !strncasecmp(name, "OMX.google.", 11)) { return CODECPROCESS; } // everything else runs in the media server return MEDIAPROCESS; } else { #ifdef __LP64__ (void)name; // disable unused parameter warning // 64 bit processes always run OMX remote on MediaServer return false; return MEDIAPROCESS; #else // 32 bit processes run only OMX.google.* components locally return !strncasecmp(name, "OMX.google.", 11); if (!strncasecmp(name, "OMX.google.", 11)) { return LOCAL; } return MEDIAPROCESS; #endif } } const sp<IOMX> &MuxOMX::getOMX(node_id node) const { return isLocalNode(node) ? mLocalOMX : mRemoteOMX; Mutex::Autolock autoLock(mLock); return getOMX_l(node); } const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const { return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX; node_location loc = mNodeLocation.valueFor(node); if (loc == LOCAL) { return mLocalOMX; } else if (loc == MEDIAPROCESS) { return mMediaServerOMX; } else if (loc == CODECPROCESS) { return mMediaCodecOMX; } ALOGE("Couldn't determine node location for node %d: %d, using local", node, loc); return mLocalOMX; } bool MuxOMX::livesLocally(node_id node, pid_t pid) { Loading @@ -216,29 +258,34 @@ status_t MuxOMX::listNodes(List<ComponentInfo> *list) { status_t MuxOMX::allocateNode( const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node) { Mutex::Autolock autoLock(mLock); sp<IOMX> omx; if (CanLiveLocally(name)) { node_location loc = getPreferredCodecLocation(name); if (loc == CODECPROCESS) { omx = mMediaCodecOMX; } else if (loc == MEDIAPROCESS) { omx = mMediaServerOMX; } else { if (mLocalOMX == NULL) { mLocalOMX = new OMX; } omx = mLocalOMX; } else { omx = mRemoteOMX; } status_t err = omx->allocateNode(name, observer, node); status_t err = omx->allocateNode(name, observer, nodeBinder, node); ALOGV("allocated node_id %x on %s OMX", *node, omx == mMediaCodecOMX ? "codecprocess" : omx == mMediaServerOMX ? "mediaserver" : "local"); if (err != OK) { return err; } if (omx == mLocalOMX) { mIsLocalNode.add(*node, true); } mNodeLocation.add(*node, loc); return OK; } Loading @@ -252,7 +299,7 @@ status_t MuxOMX::freeNode(node_id node) { return err; } mIsLocalNode.removeItem(node); mNodeLocation.removeItem(node); return OK; } Loading Loading @@ -352,7 +399,7 @@ status_t MuxOMX::createPersistentInputSurface( sp<IGraphicBufferProducer> *bufferProducer, sp<IGraphicBufferConsumer> *bufferConsumer) { // TODO: local or remote? Always use remote for now return mRemoteOMX->createPersistentInputSurface( return mMediaServerOMX->createPersistentInputSurface( bufferProducer, bufferConsumer); } Loading Loading @@ -415,29 +462,53 @@ status_t MuxOMX::setInternalOption( } OMXClient::OMXClient() { char value[PROPERTY_VALUE_MAX]; if (property_get("media.stagefright.codecremote", value, NULL) && (!strcmp("0", value) || !strcasecmp("false", value))) { sCodecProcessEnabled = false; } } status_t OMXClient::connect() { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("media.player")); sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); sp<IBinder> playerbinder = sm->getService(String16("media.player")); sp<IMediaPlayerService> mediaservice = interface_cast<IMediaPlayerService>(playerbinder); if (service.get() == NULL) { if (mediaservice.get() == NULL) { ALOGE("Cannot obtain IMediaPlayerService"); return NO_INIT; } mOMX = service->getOMX(); if (mOMX.get() == NULL) { ALOGE("Cannot obtain IOMX"); sp<IOMX> mediaServerOMX = mediaservice->getOMX(); if (mediaServerOMX.get() == NULL) { ALOGE("Cannot obtain mediaserver IOMX"); return NO_INIT; } if (!mOMX->livesLocally(0 /* node */, getpid())) { ALOGI("Using client-side OMX mux."); mOMX = new MuxOMX(mOMX); // If we don't want to use the codec process, and the media server OMX // is local, use it directly instead of going through MuxOMX if (!sCodecProcessEnabled && mediaServerOMX->livesLocally(0 /* node */, getpid())) { mOMX = mediaServerOMX; return OK; } sp<IBinder> codecbinder = sm->getService(String16("media.codec")); sp<IMediaCodecService> codecservice = interface_cast<IMediaCodecService>(codecbinder); if (codecservice.get() == NULL) { ALOGE("Cannot obtain IMediaCodecService"); return NO_INIT; } sp<IOMX> mediaCodecOMX = codecservice->getOMX(); if (mediaCodecOMX.get() == NULL) { ALOGE("Cannot obtain mediacodec IOMX"); return NO_INIT; } mOMX = new MuxOMX(mediaServerOMX, mediaCodecOMX); return OK; } Loading Loading
include/media/IOMX.h +1 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ public: virtual status_t allocateNode( const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node) = 0; virtual status_t freeNode(node_id node) = 0; Loading
include/media/stagefright/ACodec.h +1 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ private: uint32_t mFlags; uint32_t mQuirks; sp<IOMX> mOMX; sp<IBinder> mNodeBinder; IOMX::node_id mNode; sp<MemoryDealer> mDealer[2]; Loading
media/libmedia/IOMX.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ public: } virtual status_t allocateNode( const char *name, const sp<IOMXObserver> &observer, node_id *node) { const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node) { Parcel data, reply; data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeCString(name); Loading @@ -108,6 +110,9 @@ public: status_t err = reply.readInt32(); if (err == OK) { *node = (node_id)reply.readInt32(); if (nodeBinder != NULL) { *nodeBinder = remote(); } } else { *node = 0; } Loading Loading @@ -656,7 +661,8 @@ status_t BnOMX::onTransact( node_id node; status_t err = allocateNode(name, observer, &node); status_t err = allocateNode(name, observer, NULL /* nodeBinder */, &node); reply->writeInt32(err); if (err == OK) { reply->writeInt32((int32_t)node); Loading
media/libstagefright/ACodec.cpp +11 −10 Original line number Diff line number Diff line Loading @@ -5541,7 +5541,7 @@ void ACodec::UninitializedState::stateEntered() { ALOGV("Now uninitialized"); if (mDeathNotifier != NULL) { IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier); mDeathNotifier.clear(); } Loading Loading @@ -5638,13 +5638,6 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); mDeathNotifier = new DeathNotifier(notify); if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { // This was a local binder, if it dies so do we, we won't care // about any notifications in the afterlife. mDeathNotifier.clear(); } Vector<AString> matchingCodecs; AString mime; Loading Loading @@ -5683,7 +5676,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { pid_t tid = gettid(); int prevPriority = androidGetThreadPriority(tid); androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); err = omx->allocateNode(componentName.c_str(), observer, &node); err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node); androidSetThreadPriority(tid, prevPriority); if (err == OK) { Loading @@ -5707,6 +5700,14 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { return false; } mDeathNotifier = new DeathNotifier(notify); if (mCodec->mNodeBinder == NULL || mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) { // This was a local binder, if it dies so do we, we won't care // about any notifications in the afterlife. mDeathNotifier.clear(); } notify = new AMessage(kWhatOMXMessageList, mCodec); observer->setNotificationMessage(notify); Loading Loading @@ -7078,7 +7079,7 @@ status_t ACodec::queryCapabilities( sp<CodecObserver> observer = new CodecObserver; IOMX::node_id node = 0; err = omx->allocateNode(name.c_str(), observer, &node); err = omx->allocateNode(name.c_str(), observer, NULL, &node); if (err != OK) { client.disconnect(); return err; Loading
media/libstagefright/OMXClient.cpp +105 −34 Original line number Diff line number Diff line Loading @@ -25,19 +25,29 @@ #include <binder/IServiceManager.h> #include <media/IMediaPlayerService.h> #include <media/IMediaCodecService.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/OMXClient.h> #include <cutils/properties.h> #include <utils/KeyedVector.h> #include "include/OMX.h" namespace android { static bool sCodecProcessEnabled = true; struct MuxOMX : public IOMX { MuxOMX(const sp<IOMX> &remoteOMX); MuxOMX(const sp<IOMX> &mediaServerOMX, const sp<IOMX> &mediaCodecOMX); virtual ~MuxOMX(); virtual IBinder *onAsBinder() { return IInterface::asBinder(mRemoteOMX).get(); } // Nobody should be calling this. In case someone does anyway, just // return the media server IOMX. // TODO: return NULL virtual IBinder *onAsBinder() { ALOGE("MuxOMX::onAsBinder should not be called"); return IInterface::asBinder(mMediaServerOMX).get(); } virtual bool livesLocally(node_id node, pid_t pid); Loading @@ -45,6 +55,7 @@ struct MuxOMX : public IOMX { virtual status_t allocateNode( const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node); virtual status_t freeNode(node_id node); Loading Loading @@ -148,23 +159,32 @@ struct MuxOMX : public IOMX { private: mutable Mutex mLock; sp<IOMX> mRemoteOMX; sp<IOMX> mMediaServerOMX; sp<IOMX> mMediaCodecOMX; sp<IOMX> mLocalOMX; KeyedVector<node_id, bool> mIsLocalNode; typedef enum { LOCAL, MEDIAPROCESS, CODECPROCESS } node_location; KeyedVector<node_id, node_location> mNodeLocation; bool isLocalNode(node_id node) const; bool isLocalNode_l(node_id node) const; const sp<IOMX> &getOMX(node_id node) const; const sp<IOMX> &getOMX_l(node_id node) const; static bool CanLiveLocally(const char *name); static node_location getPreferredCodecLocation(const char *name); DISALLOW_EVIL_CONSTRUCTORS(MuxOMX); }; MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX) : mRemoteOMX(remoteOMX) { MuxOMX::MuxOMX(const sp<IOMX> &mediaServerOMX, const sp<IOMX> &mediaCodecOMX) : mMediaServerOMX(mediaServerOMX), mMediaCodecOMX(mediaCodecOMX) { ALOGI("MuxOMX ctor"); } MuxOMX::~MuxOMX() { Loading @@ -177,27 +197,49 @@ bool MuxOMX::isLocalNode(node_id node) const { } bool MuxOMX::isLocalNode_l(node_id node) const { return mIsLocalNode.indexOfKey(node) >= 0; return mNodeLocation.valueFor(node) == LOCAL; } // static bool MuxOMX::CanLiveLocally(const char *name) { MuxOMX::node_location MuxOMX::getPreferredCodecLocation(const char *name) { if (sCodecProcessEnabled) { // all non-secure decoders plus OMX.google.* encoders can go in the codec process if ((strcasestr(name, "decoder") && !strcasestr(name, "secure")) || !strncasecmp(name, "OMX.google.", 11)) { return CODECPROCESS; } // everything else runs in the media server return MEDIAPROCESS; } else { #ifdef __LP64__ (void)name; // disable unused parameter warning // 64 bit processes always run OMX remote on MediaServer return false; return MEDIAPROCESS; #else // 32 bit processes run only OMX.google.* components locally return !strncasecmp(name, "OMX.google.", 11); if (!strncasecmp(name, "OMX.google.", 11)) { return LOCAL; } return MEDIAPROCESS; #endif } } const sp<IOMX> &MuxOMX::getOMX(node_id node) const { return isLocalNode(node) ? mLocalOMX : mRemoteOMX; Mutex::Autolock autoLock(mLock); return getOMX_l(node); } const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const { return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX; node_location loc = mNodeLocation.valueFor(node); if (loc == LOCAL) { return mLocalOMX; } else if (loc == MEDIAPROCESS) { return mMediaServerOMX; } else if (loc == CODECPROCESS) { return mMediaCodecOMX; } ALOGE("Couldn't determine node location for node %d: %d, using local", node, loc); return mLocalOMX; } bool MuxOMX::livesLocally(node_id node, pid_t pid) { Loading @@ -216,29 +258,34 @@ status_t MuxOMX::listNodes(List<ComponentInfo> *list) { status_t MuxOMX::allocateNode( const char *name, const sp<IOMXObserver> &observer, sp<IBinder> *nodeBinder, node_id *node) { Mutex::Autolock autoLock(mLock); sp<IOMX> omx; if (CanLiveLocally(name)) { node_location loc = getPreferredCodecLocation(name); if (loc == CODECPROCESS) { omx = mMediaCodecOMX; } else if (loc == MEDIAPROCESS) { omx = mMediaServerOMX; } else { if (mLocalOMX == NULL) { mLocalOMX = new OMX; } omx = mLocalOMX; } else { omx = mRemoteOMX; } status_t err = omx->allocateNode(name, observer, node); status_t err = omx->allocateNode(name, observer, nodeBinder, node); ALOGV("allocated node_id %x on %s OMX", *node, omx == mMediaCodecOMX ? "codecprocess" : omx == mMediaServerOMX ? "mediaserver" : "local"); if (err != OK) { return err; } if (omx == mLocalOMX) { mIsLocalNode.add(*node, true); } mNodeLocation.add(*node, loc); return OK; } Loading @@ -252,7 +299,7 @@ status_t MuxOMX::freeNode(node_id node) { return err; } mIsLocalNode.removeItem(node); mNodeLocation.removeItem(node); return OK; } Loading Loading @@ -352,7 +399,7 @@ status_t MuxOMX::createPersistentInputSurface( sp<IGraphicBufferProducer> *bufferProducer, sp<IGraphicBufferConsumer> *bufferConsumer) { // TODO: local or remote? Always use remote for now return mRemoteOMX->createPersistentInputSurface( return mMediaServerOMX->createPersistentInputSurface( bufferProducer, bufferConsumer); } Loading Loading @@ -415,29 +462,53 @@ status_t MuxOMX::setInternalOption( } OMXClient::OMXClient() { char value[PROPERTY_VALUE_MAX]; if (property_get("media.stagefright.codecremote", value, NULL) && (!strcmp("0", value) || !strcasecmp("false", value))) { sCodecProcessEnabled = false; } } status_t OMXClient::connect() { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("media.player")); sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); sp<IBinder> playerbinder = sm->getService(String16("media.player")); sp<IMediaPlayerService> mediaservice = interface_cast<IMediaPlayerService>(playerbinder); if (service.get() == NULL) { if (mediaservice.get() == NULL) { ALOGE("Cannot obtain IMediaPlayerService"); return NO_INIT; } mOMX = service->getOMX(); if (mOMX.get() == NULL) { ALOGE("Cannot obtain IOMX"); sp<IOMX> mediaServerOMX = mediaservice->getOMX(); if (mediaServerOMX.get() == NULL) { ALOGE("Cannot obtain mediaserver IOMX"); return NO_INIT; } if (!mOMX->livesLocally(0 /* node */, getpid())) { ALOGI("Using client-side OMX mux."); mOMX = new MuxOMX(mOMX); // If we don't want to use the codec process, and the media server OMX // is local, use it directly instead of going through MuxOMX if (!sCodecProcessEnabled && mediaServerOMX->livesLocally(0 /* node */, getpid())) { mOMX = mediaServerOMX; return OK; } sp<IBinder> codecbinder = sm->getService(String16("media.codec")); sp<IMediaCodecService> codecservice = interface_cast<IMediaCodecService>(codecbinder); if (codecservice.get() == NULL) { ALOGE("Cannot obtain IMediaCodecService"); return NO_INIT; } sp<IOMX> mediaCodecOMX = codecservice->getOMX(); if (mediaCodecOMX.get() == NULL) { ALOGE("Cannot obtain mediacodec IOMX"); return NO_INIT; } mOMX = new MuxOMX(mediaServerOMX, mediaCodecOMX); return OK; } Loading