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

Commit d7eab895 authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "MediaRecorderTest: add tests for getSurface() and SURFACE source"

parents 94088e0c e996c419
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -137,6 +137,8 @@ public class MediaNames {
    public static final String INVALD_VIDEO_PATH =
            "/sdcard/media_api/filepathdoesnotexist" + "/filepathdoesnotexist/temp.3gp";

    public static final String RECORDED_SURFACE_3GP = "/sdcard/surface.3gp";

    public static final long RECORDED_TIME = 5000;
    public static final long VALID_VIDEO_DURATION = 2000;

+3 −1
Original line number Diff line number Diff line
@@ -88,7 +88,8 @@ public class MediaProfileReader
        if (audioEncoder != MediaRecorder.AudioEncoder.AMR_NB &&
            audioEncoder != MediaRecorder.AudioEncoder.AMR_WB &&
            audioEncoder != MediaRecorder.AudioEncoder.AAC &&
            audioEncoder != MediaRecorder.AudioEncoder.HE_AAC) {
            audioEncoder != MediaRecorder.AudioEncoder.HE_AAC &&
            audioEncoder != MediaRecorder.AudioEncoder.AAC_ELD) {
            throw new IllegalArgumentException("Unsupported audio encodeer " + audioEncoder);
        }
        return audioEncoderMap.get(audioEncoder);
@@ -128,5 +129,6 @@ public class MediaProfileReader
        audioEncoderMap.put(MediaRecorder.AudioEncoder.AMR_WB, "amrwb");
        audioEncoderMap.put(MediaRecorder.AudioEncoder.AAC, "aac");
        audioEncoderMap.put(MediaRecorder.AudioEncoder.HE_AAC, "heaac");
        audioEncoderMap.put(MediaRecorder.AudioEncoder.AAC_ELD, "aaceld");
    }
}
+245 −22
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ import com.android.mediaframeworktest.MediaNames;
import java.io.*;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.hardware.Camera;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
@@ -30,6 +34,7 @@ import android.media.EncoderCapabilities.VideoEncoderCap;
import android.media.EncoderCapabilities.AudioEncoderCap;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.android.mediaframeworktest.MediaProfileReader;
@@ -60,7 +65,7 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFra
    Camera mCamera;

    public MediaRecorderTest() {
        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
        super(MediaFrameworkTest.class);

    }

@@ -106,6 +111,179 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFra
        }
    }

    private boolean validateGetSurface(boolean useSurface) {
        Log.v(TAG,"validateGetSurface, useSurface=" + useSurface);
        MediaRecorder recorder = new MediaRecorder();
        Surface surface;
        boolean success = true;
        try {
            /* initialization */
            if (!useSurface) {
                mCamera = Camera.open(CAMERA_ID);
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setPreviewSize(352, 288);
                parameters.set("orientation", "portrait");
                mCamera.setParameters(parameters);
                mCamera.unlock();
                recorder.setCamera(mCamera);
                mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
                recorder.setPreviewDisplay(mSurfaceHolder.getSurface());
            }

            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            int videoSource = useSurface ?
                    MediaRecorder.VideoSource.SURFACE :
                    MediaRecorder.VideoSource.CAMERA;
            recorder.setVideoSource(videoSource);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            recorder.setOutputFile(MediaNames.RECORDED_SURFACE_3GP);
            recorder.setVideoFrameRate(30);
            recorder.setVideoSize(352, 288);
            recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

            /* Test: getSurface() before prepare()
             * should throw IllegalStateException
             */
            try {
                surface = recorder.getSurface();
                throw new Exception("getSurface failed to throw IllegalStateException");
            } catch (IllegalStateException e) {
                // OK
            }

            recorder.prepare();

            /* Test: getSurface() after prepare()
             * should succeed for surface source
             * should fail for camera source
             */
            try {
                surface = recorder.getSurface();
                if (!useSurface) {
                    throw new Exception("getSurface failed to throw IllegalStateException");
                }
            } catch (IllegalStateException e) {
                if (useSurface) {
                    throw new Exception("getSurface failed to throw IllegalStateException");
                }
            }

            recorder.start();

            /* Test: getSurface() after start()
             * should succeed for surface source
             * should fail for camera source
             */
            try {
                surface = recorder.getSurface();
                if (!useSurface) {
                    throw new Exception("getSurface failed to throw IllegalStateException");
                }
            } catch (IllegalStateException e) {
                if (useSurface) {
                    throw new Exception("getSurface failed to throw IllegalStateException");
                }
            }

            try {
                recorder.stop();
            } catch (Exception e) {
                // stop() could fail if the recording is empty, as we didn't render anything.
                // ignore any failure in stop, we just want it stopped.
            }

            /* Test: getSurface() after stop()
             * should throw IllegalStateException
             */
            try {
                surface = recorder.getSurface();
                throw new Exception("getSurface failed to throw IllegalStateException");
            } catch (IllegalStateException e) {
                // OK
            }
        } catch (Exception e) {
            // fail
            success = false;
        }

        try {
            if (mCamera != null) {
                mCamera.lock();
                mCamera.release();
                mCamera = null;
            }
            recorder.release();
        } catch (Exception e) {
            success = false;
        }

        return success;
    }

    private boolean recordVideoFromSurface(int frameRate, int width, int height,
            int videoFormat, int outFormat, String outFile, boolean videoOnly) {
        Log.v(TAG,"recordVideoFromSurface");
        MediaRecorder recorder = new MediaRecorder();
        try {
            if (!videoOnly) {
                recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            }
            recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            recorder.setOutputFormat(outFormat);
            recorder.setOutputFile(outFile);
            recorder.setVideoFrameRate(frameRate);
            recorder.setVideoSize(width, height);
            recorder.setVideoEncoder(videoFormat);
            if (!videoOnly) {
                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            }
            recorder.prepare();
            Surface surface = recorder.getSurface();

            Paint paint = new Paint();
            paint.setTextSize(16);
            paint.setColor(Color.RED);
            int i;

            /* Test: draw 10 frames at 30fps before start
             * these should be dropped and not causing malformed stream.
             */
            for(i = 0; i < 10; i++) {
                Canvas canvas = surface.lockCanvas(null);
                int background = (i * 255 / 99);
                canvas.drawARGB(255, background, background, background);
                String text = "Frame #" + i;
                canvas.drawText(text, 100, 100, paint);
                surface.unlockCanvasAndPost(canvas);
                Thread.sleep(33);
            }

            Log.v(TAG, "start");
            recorder.start();

            /* Test: draw another 90 frames at 30fps after start */
            for(i = 10; i < 100; i++) {
                Canvas canvas = surface.lockCanvas(null);
                int background = (i * 255 / 99);
                canvas.drawARGB(255, background, background, background);
                String text = "Frame #" + i;
                canvas.drawText(text, 100, 100, paint);
                surface.unlockCanvasAndPost(canvas);
                Thread.sleep(33);
            }

            Log.v(TAG, "stop");
            recorder.stop();
            recorder.release();
        } catch (Exception e) {
            Log.v("record video failed ", e.toString());
            recorder.release();
            return false;
        }
        return true;
    }

    private boolean recordVideoWithPara(VideoEncoderCap videoCap, AudioEncoderCap audioCap, boolean highQuality){
        boolean recordSuccess = false;
        int videoEncoder = videoCap.mCodec;
@@ -309,4 +487,49 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFra
            assertTrue("testDeviceSpecificCodec", false);
        }
    }

    // Test MediaRecorder.getSurface() api with surface or camera source
    public void testGetSurfaceApi() {
        boolean success = false;
        int noOfFailure = 0;
        try {
            for (int k = 0; k < 2; k++) {
                success = validateGetSurface(
                        k == 0 ? true : false /* useSurface */);
                if (!success) {
                    noOfFailure++;
                }
            }
        } catch (Exception e) {
            Log.v(TAG, e.toString());
        }
        assertTrue("testGetSurfaceApi", noOfFailure == 0);
    }

    // Test recording from surface source with/without audio
    public void testSurfaceRecording() {
        boolean success = false;
        int noOfFailure = 0;
        try {
            int codec = MediaRecorder.VideoEncoder.H264;
            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
            for (int k = 0; k < 2; k++) {
                String filename = "/sdcard/surface_" +
                            (k==0?"video_only":"with_audio") + ".3gp";

                success = recordVideoFromSurface(frameRate, 352, 288, codec,
                        MediaRecorder.OutputFormat.THREE_GPP, filename,
                        k == 0 ? true : false /* videoOnly */);
                if (success) {
                    success = validateVideo(filename, 352, 288);
                }
                if (!success) {
                    noOfFailure++;
                }
            }
        } catch (Exception e) {
            Log.v(TAG, e.toString());
        }
        assertTrue("testSurfaceRecording", noOfFailure == 0);
    }
}