Loading media/java/android/media/MediaCodec.java +22 −3 Original line number Diff line number Diff line Loading @@ -2364,12 +2364,16 @@ final public class MediaCodec { } // at the moment no codecs support detachable surface boolean canDetach = GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport()); if (GetFlag(() -> android.media.codec.Flags.nullOutputSurface())) { // Detached surface flag is only meaningful if surface is null. Otherwise, it is // ignored. if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) { if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0 && !canDetach) { throw new IllegalArgumentException("Codec does not support detached surface"); } } else { // don't allow detaching if API is disabled canDetach = false; } String[] keys = null; Loading Loading @@ -2411,6 +2415,14 @@ final public class MediaCodec { } native_configure(keys, values, surface, crypto, descramblerBinder, flags); if (canDetach) { // If we were able to configure native codec with a detached surface // we now know that we have a surface. if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) { mHasSurface = true; } } } /** Loading Loading @@ -2455,11 +2467,18 @@ final public class MediaCodec { if (!mHasSurface) { throw new IllegalStateException("codec was not configured for an output surface"); } // note: we still have a surface in detached mode, so keep mHasSurface // we also technically allow calling detachOutputSurface multiple times in a row if (GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport())) { native_detachOutputSurface(); } else { throw new IllegalStateException("codec does not support detaching output surface"); // native_detachSurface(); } } private native void native_detachOutputSurface(); /** * Create a persistent input surface that can be used with codecs that normally have an input Loading media/jni/android_media_MediaCodec.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,14 @@ status_t JMediaCodec::setSurface( return err; } status_t JMediaCodec::detachOutputSurface() { status_t err = mCodec->detachOutputSurface(); if (err == OK) { mSurfaceTextureClient.clear(); } return err; } status_t JMediaCodec::createInputSurface( sp<IGraphicBufferProducer>* bufferProducer) { return mCodec->createInputSurface(bufferProducer); Loading Loading @@ -1798,6 +1806,20 @@ static void android_media_MediaCodec_native_setSurface( throwExceptionAsNecessary(env, err, codec); } static void android_media_MediaCodec_native_detachOutputSurface( JNIEnv *env, jobject thiz) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION, codec); return; } status_t err = codec->detachOutputSurface(); throwExceptionAsNecessary(env, err, codec); } sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface( JNIEnv* env, jobject object) { sp<PersistentSurface> persistentSurface; Loading Loading @@ -4107,6 +4129,10 @@ static const JNINativeMethod gMethods[] = { "(Landroid/view/Surface;)V", (void *)android_media_MediaCodec_native_setSurface }, { "native_detachOutputSurface", "()V", (void *)android_media_MediaCodec_native_detachOutputSurface }, { "createInputSurface", "()Landroid/view/Surface;", (void *)android_media_MediaCodec_createInputSurface }, Loading media/jni/android_media_MediaCodec.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ struct JMediaCodec : public AHandler { status_t setSurface( const sp<IGraphicBufferProducer> &surface); status_t detachOutputSurface(); status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); status_t setInputSurface(const sp<PersistentSurface> &surface); Loading Loading
media/java/android/media/MediaCodec.java +22 −3 Original line number Diff line number Diff line Loading @@ -2364,12 +2364,16 @@ final public class MediaCodec { } // at the moment no codecs support detachable surface boolean canDetach = GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport()); if (GetFlag(() -> android.media.codec.Flags.nullOutputSurface())) { // Detached surface flag is only meaningful if surface is null. Otherwise, it is // ignored. if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) { if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0 && !canDetach) { throw new IllegalArgumentException("Codec does not support detached surface"); } } else { // don't allow detaching if API is disabled canDetach = false; } String[] keys = null; Loading Loading @@ -2411,6 +2415,14 @@ final public class MediaCodec { } native_configure(keys, values, surface, crypto, descramblerBinder, flags); if (canDetach) { // If we were able to configure native codec with a detached surface // we now know that we have a surface. if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) { mHasSurface = true; } } } /** Loading Loading @@ -2455,11 +2467,18 @@ final public class MediaCodec { if (!mHasSurface) { throw new IllegalStateException("codec was not configured for an output surface"); } // note: we still have a surface in detached mode, so keep mHasSurface // we also technically allow calling detachOutputSurface multiple times in a row if (GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport())) { native_detachOutputSurface(); } else { throw new IllegalStateException("codec does not support detaching output surface"); // native_detachSurface(); } } private native void native_detachOutputSurface(); /** * Create a persistent input surface that can be used with codecs that normally have an input Loading
media/jni/android_media_MediaCodec.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,14 @@ status_t JMediaCodec::setSurface( return err; } status_t JMediaCodec::detachOutputSurface() { status_t err = mCodec->detachOutputSurface(); if (err == OK) { mSurfaceTextureClient.clear(); } return err; } status_t JMediaCodec::createInputSurface( sp<IGraphicBufferProducer>* bufferProducer) { return mCodec->createInputSurface(bufferProducer); Loading Loading @@ -1798,6 +1806,20 @@ static void android_media_MediaCodec_native_setSurface( throwExceptionAsNecessary(env, err, codec); } static void android_media_MediaCodec_native_detachOutputSurface( JNIEnv *env, jobject thiz) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION, codec); return; } status_t err = codec->detachOutputSurface(); throwExceptionAsNecessary(env, err, codec); } sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface( JNIEnv* env, jobject object) { sp<PersistentSurface> persistentSurface; Loading Loading @@ -4107,6 +4129,10 @@ static const JNINativeMethod gMethods[] = { "(Landroid/view/Surface;)V", (void *)android_media_MediaCodec_native_setSurface }, { "native_detachOutputSurface", "()V", (void *)android_media_MediaCodec_native_detachOutputSurface }, { "createInputSurface", "()Landroid/view/Surface;", (void *)android_media_MediaCodec_createInputSurface }, Loading
media/jni/android_media_MediaCodec.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ struct JMediaCodec : public AHandler { status_t setSurface( const sp<IGraphicBufferProducer> &surface); status_t detachOutputSurface(); status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); status_t setInputSurface(const sp<PersistentSurface> &surface); Loading