diff options
-rw-r--r-- | include/media/IOMX.h | 4 | ||||
-rw-r--r-- | include/media/stagefright/ACodec.h | 3 | ||||
-rw-r--r-- | media/libmedia/IOMX.cpp | 38 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 157 | ||||
-rw-r--r-- | media/libstagefright/OMXClient.cpp | 11 | ||||
-rw-r--r-- | media/libstagefright/include/OMX.h | 4 | ||||
-rw-r--r-- | media/libstagefright/include/OMXNodeInstance.h | 4 | ||||
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 7 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 43 |
9 files changed, 214 insertions, 57 deletions
diff --git a/include/media/IOMX.h b/include/media/IOMX.h index dd13fea..627f23b 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -87,6 +87,10 @@ public: node_id node, OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0; + virtual status_t configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0; + virtual status_t enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 3a6bb9e..eb31c77 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -234,6 +234,9 @@ private: status_t setComponentRole(bool isEncoder, const char *mime); status_t configureCodec(const char *mime, const sp<AMessage> &msg); + status_t configureTunneledVideoPlayback(int64_t audioHwSync, + const sp<ANativeWindow> &nativeWindow); + status_t setVideoPortFormatType( OMX_U32 portIndex, OMX_VIDEO_CODINGTYPE compressionFormat, diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 5df232f..c583d32 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -54,6 +54,7 @@ enum { GET_GRAPHIC_BUFFER_USAGE, SET_INTERNAL_OPTION, UPDATE_GRAPHIC_BUFFER_IN_META, + CONFIGURE_VIDEO_TUNNEL_MODE, }; class BpOMX : public BpInterface<IOMX> { @@ -368,6 +369,25 @@ public: return err; } + virtual status_t configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { + Parcel data, reply; + data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); + data.writeInt32((int32_t)node); + data.writeInt32(portIndex); + data.writeInt32((int32_t)tunneled); + data.writeInt32(audioHwSync); + remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); + + status_t err = reply.readInt32(); + if (sidebandHandle) { + *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); + } + return err; + } + + virtual status_t allocateBuffer( node_id node, OMX_U32 port_index, size_t size, buffer_id *buffer, void **buffer_data) { @@ -804,6 +824,24 @@ status_t BnOMX::onTransact( return NO_ERROR; } + case CONFIGURE_VIDEO_TUNNEL_MODE: + { + CHECK_OMX_INTERFACE(IOMX, data, reply); + + node_id node = (node_id)data.readInt32(); + OMX_U32 port_index = data.readInt32(); + OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); + OMX_U32 audio_hw_sync = data.readInt32(); + + native_handle_t *sideband_handle; + status_t err = configureVideoTunnelMode( + node, port_index, tunneled, audio_hw_sync, &sideband_handle); + reply->writeInt32(err); + reply->writeNativeHandle(sideband_handle); + + return NO_ERROR; + } + case ALLOC_BUFFER: { CHECK_OMX_INTERFACE(IOMX, data, reply); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 503ce81..ac80da2 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1224,77 +1224,99 @@ status_t ACodec::configureCodec( } } - // Always try to enable dynamic output buffers on native surface sp<RefBase> obj; int32_t haveNativeWindow = msg->findObject("native-window", &obj) && - obj != NULL; + obj != NULL; mStoreMetaDataInOutputBuffers = false; if (video && !encoder) { inputFormat->setInt32("adaptive-playback", false); } if (!encoder && video && haveNativeWindow) { - err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE); - if (err != OK) { - ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d", - mComponentName.c_str(), err); - - // if adaptive playback has been requested, try JB fallback - // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS - // LARGE MEMORY REQUIREMENT - - // we will not do adaptive playback on software accessed - // surfaces as they never had to respond to changes in the - // crop window, and we don't trust that they will be able to. - int usageBits = 0; - bool canDoAdaptivePlayback; - - sp<NativeWindowWrapper> windowWrapper( - static_cast<NativeWindowWrapper *>(obj.get())); - sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow(); - - if (nativeWindow->query( - nativeWindow.get(), - NATIVE_WINDOW_CONSUMER_USAGE_BITS, - &usageBits) != OK) { - canDoAdaptivePlayback = false; - } else { - canDoAdaptivePlayback = - (usageBits & - (GRALLOC_USAGE_SW_READ_MASK | - GRALLOC_USAGE_SW_WRITE_MASK)) == 0; + sp<NativeWindowWrapper> windowWrapper( + static_cast<NativeWindowWrapper *>(obj.get())); + sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow(); + + int32_t tunneled; + if (msg->findInt32("feature-tunneled-playback", &tunneled) && + tunneled != 0) { + ALOGI("Configuring TUNNELED video playback."); + + int64_t audioHwSync = 0; + if (!msg->findInt64("audio-hw-sync", &audioHwSync)) { + ALOGW("No Audio HW Sync provided for video tunnel"); + } + err = configureTunneledVideoPlayback(audioHwSync, nativeWindow); + if (err != OK) { + ALOGE("configureTunneledVideoPlayback(%" PRId64 ",%p) failed!", + audioHwSync, nativeWindow.get()); + return err; } - int32_t maxWidth = 0, maxHeight = 0; - if (canDoAdaptivePlayback && - msg->findInt32("max-width", &maxWidth) && - msg->findInt32("max-height", &maxHeight)) { - ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", - mComponentName.c_str(), maxWidth, maxHeight); - - err = mOMX->prepareForAdaptivePlayback( - mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); - ALOGW_IF(err != OK, - "[%s] prepareForAdaptivePlayback failed w/ err %d", + inputFormat->setInt32("adaptive-playback", true); + } else { + // Always try to enable dynamic output buffers on native surface + err = mOMX->storeMetaDataInBuffers( + mNode, kPortIndexOutput, OMX_TRUE); + if (err != OK) { + ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d", mComponentName.c_str(), err); - if (err == OK) { - inputFormat->setInt32("max-width", maxWidth); - inputFormat->setInt32("max-height", maxHeight); - inputFormat->setInt32("adaptive-playback", true); + // if adaptive playback has been requested, try JB fallback + // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS + // LARGE MEMORY REQUIREMENT + + // we will not do adaptive playback on software accessed + // surfaces as they never had to respond to changes in the + // crop window, and we don't trust that they will be able to. + int usageBits = 0; + bool canDoAdaptivePlayback; + + if (nativeWindow->query( + nativeWindow.get(), + NATIVE_WINDOW_CONSUMER_USAGE_BITS, + &usageBits) != OK) { + canDoAdaptivePlayback = false; + } else { + canDoAdaptivePlayback = + (usageBits & + (GRALLOC_USAGE_SW_READ_MASK | + GRALLOC_USAGE_SW_WRITE_MASK)) == 0; + } + + int32_t maxWidth = 0, maxHeight = 0; + if (canDoAdaptivePlayback && + msg->findInt32("max-width", &maxWidth) && + msg->findInt32("max-height", &maxHeight)) { + ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", + mComponentName.c_str(), maxWidth, maxHeight); + + err = mOMX->prepareForAdaptivePlayback( + mNode, kPortIndexOutput, OMX_TRUE, maxWidth, + maxHeight); + ALOGW_IF(err != OK, + "[%s] prepareForAdaptivePlayback failed w/ err %d", + mComponentName.c_str(), err); + + if (err == OK) { + inputFormat->setInt32("max-width", maxWidth); + inputFormat->setInt32("max-height", maxHeight); + inputFormat->setInt32("adaptive-playback", true); + } } + // allow failure + err = OK; + } else { + ALOGV("[%s] storeMetaDataInBuffers succeeded", + mComponentName.c_str()); + mStoreMetaDataInOutputBuffers = true; + inputFormat->setInt32("adaptive-playback", true); } - // allow failure - err = OK; - } else { - ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str()); - mStoreMetaDataInOutputBuffers = true; - inputFormat->setInt32("adaptive-playback", true); - } - int32_t push; - if (msg->findInt32("push-blank-buffers-on-shutdown", &push) - && push != 0) { - mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; + int32_t push; + if (msg->findInt32("push-blank-buffers-on-shutdown", &push) + && push != 0) { + mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; + } } int32_t rotationDegrees; @@ -1869,6 +1891,27 @@ status_t ACodec::setupRawAudioFormat( mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); } +status_t ACodec::configureTunneledVideoPlayback( + int64_t audioHwSync, const sp<ANativeWindow> &nativeWindow) { + native_handle_t* sidebandHandle; + + status_t err = mOMX->configureVideoTunnelMode( + mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle); + if (err != OK) { + ALOGE("configureVideoTunnelMode failed! (err %d).", err); + return err; + } + + err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle); + if (err != OK) { + ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", + sidebandHandle, err); + return err; + } + + return OK; +} + status_t ACodec::setVideoPortFormatType( OMX_U32 portIndex, OMX_VIDEO_CODINGTYPE compressionFormat, diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp index aca21cf..ca031aa 100644 --- a/media/libstagefright/OMXClient.cpp +++ b/media/libstagefright/OMXClient.cpp @@ -78,6 +78,10 @@ struct MuxOMX : public IOMX { node_id node, OMX_U32 port_index, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight); + virtual status_t configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle); + virtual status_t enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable); @@ -291,6 +295,13 @@ status_t MuxOMX::prepareForAdaptivePlayback( node, port_index, enable, maxFrameWidth, maxFrameHeight); } +status_t MuxOMX::configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL enable, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { + return getOMX(node)->configureVideoTunnelMode( + node, portIndex, enable, audioHwSync, sidebandHandle); +} + status_t MuxOMX::enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable) { return getOMX(node)->enableGraphicBuffers(node, port_index, enable); diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index cd51bbf..e8c4970 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -75,6 +75,10 @@ public: node_id node, OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 max_frame_width, OMX_U32 max_frame_height); + virtual status_t configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle); + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer); diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index 3967dc6..dc6d410 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -62,6 +62,10 @@ struct OMXNodeInstance { OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight); + status_t configureVideoTunnelMode( + OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle); + status_t useBuffer( OMX_U32 portIndex, const sp<IMemory> ¶ms, OMX::buffer_id *buffer); diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index cc4770a..41407e4 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -342,6 +342,13 @@ status_t OMX::prepareForAdaptivePlayback( portIndex, enable, maxFrameWidth, maxFrameHeight); } +status_t OMX::configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { + return findInstance(node)->configureVideoTunnelMode( + portIndex, tunneled, audioHwSync, sidebandHandle); +} + status_t OMX::useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) { diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index d6ab109..efb27f5 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -460,6 +460,49 @@ status_t OMXNodeInstance::prepareForAdaptivePlayback( return err; } +status_t OMXNodeInstance::configureVideoTunnelMode( + OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync, + native_handle_t **sidebandHandle) { + Mutex::Autolock autolock(mLock); + + OMX_INDEXTYPE index; + OMX_STRING name = const_cast<OMX_STRING>( + "OMX.google.android.index.configureVideoTunnelMode"); + + OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); + if (err != OMX_ErrorNone) { + ALOGE("configureVideoTunnelMode extension is missing!"); + return StatusFromOMXError(err); + } + + ConfigureVideoTunnelModeParams tunnelParams; + tunnelParams.nSize = sizeof(tunnelParams); + tunnelParams.nVersion.s.nVersionMajor = 1; + tunnelParams.nVersion.s.nVersionMinor = 0; + tunnelParams.nVersion.s.nRevision = 0; + tunnelParams.nVersion.s.nStep = 0; + + tunnelParams.nPortIndex = portIndex; + tunnelParams.bTunneled = tunneled; + tunnelParams.nAudioHwSync = audioHwSync; + err = OMX_SetParameter(mHandle, index, &tunnelParams); + if (err != OMX_ErrorNone) { + ALOGE("configureVideoTunnelMode failed! (err %d).", err); + return UNKNOWN_ERROR; + } + + err = OMX_GetParameter(mHandle, index, &tunnelParams); + if (err != OMX_ErrorNone) { + ALOGE("GetVideoTunnelWindow failed! (err %d).", err); + return UNKNOWN_ERROR; + } + if (sidebandHandle) { + *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow; + } + + return err; +} + status_t OMXNodeInstance::useBuffer( OMX_U32 portIndex, const sp<IMemory> ¶ms, OMX::buffer_id *buffer) { |