Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2621e40d authored by Andy McFadden's avatar Andy McFadden
Browse files

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
parent cdac4972
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -262,6 +262,16 @@ final public class MediaCodec {
            String[] keys, Object[] values,
            Surface surface, MediaCrypto crypto, int flags);

    /**
     * Requests a Surface to use instead of input buffers.  This may only be called after
     * {@link #configure} and before {@link #start}.
     * <p>
     * The application is responsible for calling release() on the Surface when
     * done.
     * @hide -- TODO(fadden): make this public before release
     */
    public native final Surface createInputSurface();

    /**
     * After successfully configuring the component, call start. On return
     * you can query the component for its input/output buffers.
@@ -457,6 +467,14 @@ final public class MediaCodec {
     */
    public native final void releaseOutputBuffer(int index, boolean render);

    /**
     * Signals end-of-stream on input.  Equivalent to submitting an empty buffer with
     * {@link #BUFFER_FLAG_END_OF_STREAM} set.  This may only be used with
     * encoders receiving input from a Surface created by {@link #createInputSurface}.
     * @hide -- TODO(fadden): make this public before release
     */
    public native final void signalEndOfInputStream();

    /**
     * Call this after dequeueOutputBuffer signals a format change by returning
     * {@link #INFO_OUTPUT_FORMAT_CHANGED}
+2 −0
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ public final class MediaCodecInfo {
        public final static int COLOR_Format24BitABGR6666           = 43;

        public final static int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
        /** @hide -- TODO(fadden): make this public before release */
        public final static int COLOR_FormatAndroidOpaque             = 0x7F000789;
        public final static int COLOR_QCOM_FormatYUV420SemiPlanar     = 0x7fa30c00;

        /**
+53 −0
Original line number Diff line number Diff line
@@ -123,6 +123,11 @@ status_t JMediaCodec::configure(
    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 @@ status_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) {
        : 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 @@ static void android_media_MediaCodec_native_configure(
    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 @@ static void android_media_MediaCodec_releaseOutputBuffer(
    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 @@ static JNINativeMethod gMethods[] = {
      "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 @@ static JNINativeMethod gMethods[] = {
    { "releaseOutputBuffer", "(IZ)V",
      (void *)android_media_MediaCodec_releaseOutputBuffer },

    { "signalEndOfInputStream", "()V",
      (void *)android_media_MediaCodec_signalEndOfInputStream },

    { "getOutputFormatNative", "()Ljava/util/Map;",
      (void *)android_media_MediaCodec_getOutputFormatNative },

+4 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ struct JMediaCodec : public RefBase {
            const sp<ICrypto> &crypto,
            int flags);

    status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);

    status_t start();
    status_t stop();

@@ -76,6 +78,8 @@ struct JMediaCodec : public RefBase {

    status_t releaseOutputBuffer(size_t index, bool render);

    status_t signalEndOfInputStream();

    status_t getOutputFormat(JNIEnv *env, jobject *format) const;

    status_t getBuffers(