diff options
| -rw-r--r-- | media/java/android/media/MediaCodec.java | 6 | ||||
| -rw-r--r-- | media/jni/android_media_MediaCodec.cpp | 50 | ||||
| -rw-r--r-- | media/jni/android_media_MediaCodec.h | 3 |
3 files changed, 56 insertions, 3 deletions
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index f4a5bc3..8220a74 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -664,11 +664,11 @@ final public class MediaCodec { if (!mHasSurface) { throw new IllegalStateException("codec was not configured for an output surface"); } - - // TODO implement this - throw new IllegalArgumentException("codec does not support this surface"); + native_setSurface(surface); } + private native void native_setSurface(@NonNull Surface surface); + /** * Create a persistent input surface that can be used with codecs that normally have an input * surface, such as video encoders. A persistent input can be reused by subsequent diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index a09c5c0..f808c0d 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -254,6 +254,19 @@ status_t JMediaCodec::configure( return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); } +status_t JMediaCodec::setSurface( + const sp<IGraphicBufferProducer> &bufferProducer) { + sp<Surface> client; + if (bufferProducer != NULL) { + client = new Surface(bufferProducer, true /* controlledByApp */); + } + status_t err = mCodec->setSurface(client); + if (err == OK) { + mSurfaceTextureClient = client; + } + return err; +} + status_t JMediaCodec::createInputSurface( sp<IGraphicBufferProducer>* bufferProducer) { return mCodec->createInputSurface(bufferProducer); @@ -811,6 +824,10 @@ static jint throwExceptionAsNecessary( jniThrowException(env, "java/lang/IllegalStateException", msg); return 0; + case BAD_VALUE: + jniThrowException(env, "java/lang/IllegalArgumentException", msg); + return 0; + default: if (isCryptoError(err)) { throwCryptoException(env, err, msg); @@ -883,6 +900,35 @@ static void android_media_MediaCodec_native_configure( throwExceptionAsNecessary(env, err); } +static void android_media_MediaCodec_native_setSurface( + JNIEnv *env, + jobject thiz, + jobject jsurface) { + sp<JMediaCodec> codec = getMediaCodec(env, thiz); + + if (codec == NULL) { + throwExceptionAsNecessary(env, INVALID_OPERATION); + return; + } + + sp<IGraphicBufferProducer> bufferProducer; + if (jsurface != NULL) { + sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); + if (surface != NULL) { + bufferProducer = surface->getIGraphicBufferProducer(); + } else { + jniThrowException( + env, + "java/lang/IllegalArgumentException", + "The surface has been released"); + return; + } + } + + status_t err = codec->setSurface(bufferProducer); + throwExceptionAsNecessary(env, err); +} + sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface( JNIEnv* env, jobject object) { sp<PersistentSurface> persistentSurface; @@ -1692,6 +1738,10 @@ static JNINativeMethod gMethods[] = { "Landroid/media/MediaCrypto;I)V", (void *)android_media_MediaCodec_native_configure }, + { "native_setSurface", + "(Landroid/view/Surface;)V", + (void *)android_media_MediaCodec_native_setSurface }, + { "createInputSurface", "()Landroid/view/Surface;", (void *)android_media_MediaCodec_createInputSurface }, diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index 4721d2d..bf61f42 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -54,6 +54,9 @@ struct JMediaCodec : public AHandler { const sp<ICrypto> &crypto, int flags); + status_t setSurface( + const sp<IGraphicBufferProducer> &surface); + status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); status_t usePersistentInputSurface(const sp<PersistentSurface> &surface); |
