Implement Surface input to MediaCodec.

Adds two new public methods to MediaCodec, and one new public
constant to MediaCodecInfo (currently @hidden).

Bug 7991062

Change-Id: I830a9794e92334ad05c870cc5fc90be4652147a5
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 86700b3..3a42db2 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -123,6 +123,11 @@
     return mCodec->configure(format, mSurfaceTextureClient, crypto, flags);
 }
 
+status_t JMediaCodec::createInputSurface(
+        sp<IGraphicBufferProducer>* bufferProducer) {
+    return mCodec->createInputSurface(bufferProducer);
+}
+
 status_t JMediaCodec::start() {
     return mCodec->start();
 }
@@ -190,6 +195,10 @@
         : mCodec->releaseOutputBuffer(index);
 }
 
+status_t JMediaCodec::signalEndOfInputStream() {
+    return mCodec->signalEndOfInputStream();
+}
+
 status_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const {
     sp<AMessage> msg;
     status_t err;
@@ -417,6 +426,29 @@
     throwExceptionAsNecessary(env, err);
 }
 
+static jobject android_media_MediaCodec_createInputSurface(JNIEnv* env,
+        jobject thiz) {
+    ALOGV("android_media_MediaCodec_createInputSurface");
+
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+    if (codec == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return NULL;
+    }
+
+    // Tell the MediaCodec that we want to use a Surface as input.
+    sp<IGraphicBufferProducer> bufferProducer;
+    status_t err = codec->createInputSurface(&bufferProducer);
+    if (err != NO_ERROR) {
+        throwExceptionAsNecessary(env, err);
+        return NULL;
+    }
+
+    // Wrap the IGBP in a Java-language Surface.
+    return android_view_Surface_createFromIGraphicBufferProducer(env,
+            bufferProducer);
+}
+
 static void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
     ALOGV("android_media_MediaCodec_start");
 
@@ -685,6 +717,21 @@
     throwExceptionAsNecessary(env, err);
 }
 
+static void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env,
+        jobject thiz) {
+    ALOGV("android_media_MediaCodec_signalEndOfInputStream");
+
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+    if (codec == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+
+    status_t err = codec->signalEndOfInputStream();
+
+    throwExceptionAsNecessary(env, err);
+}
+
 static jobject android_media_MediaCodec_getOutputFormatNative(
         JNIEnv *env, jobject thiz) {
     ALOGV("android_media_MediaCodec_getOutputFormatNative");
@@ -852,6 +899,9 @@
       "Landroid/media/MediaCrypto;I)V",
       (void *)android_media_MediaCodec_native_configure },
 
+    { "createInputSurface", "()Landroid/view/Surface;",
+      (void *)android_media_MediaCodec_createInputSurface },
+
     { "start", "()V", (void *)android_media_MediaCodec_start },
     { "stop", "()V", (void *)android_media_MediaCodec_stop },
     { "flush", "()V", (void *)android_media_MediaCodec_flush },
@@ -871,6 +921,9 @@
     { "releaseOutputBuffer", "(IZ)V",
       (void *)android_media_MediaCodec_releaseOutputBuffer },
 
+    { "signalEndOfInputStream", "()V",
+      (void *)android_media_MediaCodec_signalEndOfInputStream },
+
     { "getOutputFormatNative", "()Ljava/util/Map;",
       (void *)android_media_MediaCodec_getOutputFormatNative },
 
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index f478788..282d2c5 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -47,6 +47,8 @@
             const sp<ICrypto> &crypto,
             int flags);
 
+    status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
+
     status_t start();
     status_t stop();
 
@@ -76,6 +78,8 @@
 
     status_t releaseOutputBuffer(size_t index, bool render);
 
+    status_t signalEndOfInputStream();
+
     status_t getOutputFormat(JNIEnv *env, jobject *format) const;
 
     status_t getBuffers(