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

Commit 17d79047 authored by Lajos Molnar's avatar Lajos Molnar
Browse files

media: surface parity for MediaCodec & Recorder

allow setting output surface dynamically on MediaCodec
allow creating persistent input surface for MediaCodec and MediaRecorder

Bug: 19127604
Bug: 19489395
Change-Id: I68d95ce012574f1cc161556fd7d016be104e5076
parent aba29b77
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -15274,6 +15274,7 @@ package android.media {
    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
    method public final android.view.Surface createInputSurface();
    method public static android.view.Surface createPersistentInputSurface();
    method public final int dequeueInputBuffer(long);
    method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
    method public final void flush();
@@ -15296,10 +15297,12 @@ package android.media {
    method public final void reset();
    method public void setCallback(android.media.MediaCodec.Callback);
    method public final void setParameters(android.os.Bundle);
    method public void setSurface(android.view.Surface);
    method public final void setVideoScalingMode(int);
    method public final void signalEndOfInputStream();
    method public final void start();
    method public final void stop();
    method public void usePersistentInputSurface(android.view.Surface);
    field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
    field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
    field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
@@ -16144,6 +16147,7 @@ package android.media {
    method public void setVideoSource(int) throws java.lang.IllegalStateException;
    method public void start() throws java.lang.IllegalStateException;
    method public void stop() throws java.lang.IllegalStateException;
    method public void usePersistentSurface(android.view.Surface);
    field public static final int MEDIA_ERROR_SERVER_DIED = 100; // 0x64
    field public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1; // 0x1
    field public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800; // 0x320
+4 −0
Original line number Diff line number Diff line
@@ -16486,6 +16486,7 @@ package android.media {
    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
    method public final android.view.Surface createInputSurface();
    method public static android.view.Surface createPersistentInputSurface();
    method public final int dequeueInputBuffer(long);
    method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
    method public final void flush();
@@ -16508,10 +16509,12 @@ package android.media {
    method public final void reset();
    method public void setCallback(android.media.MediaCodec.Callback);
    method public final void setParameters(android.os.Bundle);
    method public void setSurface(android.view.Surface);
    method public final void setVideoScalingMode(int);
    method public final void signalEndOfInputStream();
    method public final void start();
    method public final void stop();
    method public void usePersistentInputSurface(android.view.Surface);
    field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
    field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
    field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
@@ -17357,6 +17360,7 @@ package android.media {
    method public void setVideoSource(int) throws java.lang.IllegalStateException;
    method public void start() throws java.lang.IllegalStateException;
    method public void stop() throws java.lang.IllegalStateException;
    method public void usePersistentSurface(android.view.Surface);
    field public static final int MEDIA_ERROR_SERVER_DIED = 100; // 0x64
    field public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1; // 0x1
    field public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800; // 0x320
+55 −0
Original line number Diff line number Diff line
@@ -610,6 +610,61 @@ final public class MediaCodec {
        native_configure(keys, values, surface, crypto, flags);
    }

    /**
     *  Dynamically sets the output surface of a codec.
     *  <p>
     *  This can only be used if the codec was configured with an output surface.  The
     *  new output surface should have a compatible usage type to the original output surface.
     *  E.g. codecs may not support switching from a SurfaceTexture (GPU readable) output
     *  to ImageReader (software readable) output.
     *  @param surface the output surface to use. It must not be {@code null}.
     *  @throws IllegalStateException if the codec does not support setting the output
     *            surface in the current state.
     *  @throws IllegalArgumentException if the new surface is not of a suitable type for the codec.
     */
    public void setSurface(@NonNull Surface surface) {
        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");
    }

    /**
     * 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
     * {@link MediaCodec} or {@link MediaRecorder} instances, but can only be used by at
     * most one codec or recorder instance concurrently.
     * <p>
     * The application is responsible for calling release() on the Surface when done.
     *
     * @return an input surface that can be used with {@link #usePersistentInputSurface}.
     */
    @NonNull
    public static Surface createPersistentInputSurface() {
        // TODO implement this
        return new PersistentSurface();
    }

    static class PersistentSurface extends Surface {
        PersistentSurface() {}
    };

    /**
     * Configures the codec (e.g. encoder) to use a persistent input surface in place of input
     * buffers.  This may only be called after {@link #configure} and before {@link #start}, in
     * lieu of {@link #createInputSurface}.
     * @param surface a persistent input surface created by {@link #createPersistentInputSurface}
     * @throws IllegalStateException if not in the Configured state or does not require an input
     *           surface.
     * @throws IllegalArgumentException if the surface was not created by
     *           {@link #createPersistentInputSurface}.
     */
    public void usePersistentInputSurface(@NonNull Surface surface) {
        throw new IllegalArgumentException("not implemented");
    }

    private native final void native_setCallback(@Nullable Callback cb);

    private native final void native_configure(
+18 −0
Original line number Diff line number Diff line
@@ -139,6 +139,24 @@ public class MediaRecorder
     */
    public native Surface getSurface();

    /**
     * Configures the recorder to use a persistent surface when using SURFACE video source.
     * <p> May only be called after {@link #prepare} in lieu of {@link #getSurface}.
     * Frames rendered to the Surface before {@link #start} will be discarded.</p>

     * @param surface a persistent input surface created by
     *           {@link MediaCodec#createPersistentInputSurface}
     * @throws IllegalStateException if it is called before {@link #prepare}, after
     * {@link #stop}, or is called when VideoSource is not set to SURFACE.
     * @throws IllegalArgumentException if the surface was not created by
     *           {@link MediaCodec#createPersistentInputSurface}.
     * @see MediaCodec#createPersistentInputSurface
     * @see MediaRecorder.VideoSource
     */
    public void usePersistentSurface(Surface surface) {
        throw new IllegalArgumentException("not implemented");
    }

    /**
     * Sets a Surface to show a preview of recorded media (video). Calls this
     * before prepare() to make sure that the desirable preview display is