1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.mediaframeworktest.functional.mediarecorder;
18
19import com.android.mediaframeworktest.MediaFrameworkTest;
20import com.android.mediaframeworktest.MediaNames;
21
22import java.io.*;
23
24import android.content.Context;
25import android.graphics.Canvas;
26import android.graphics.Color;
27import android.graphics.Paint;
28import android.graphics.Typeface;
29import android.hardware.Camera;
30import android.media.MediaCodec;
31import android.media.MediaMetadataRetriever;
32import android.media.MediaPlayer;
33import android.media.MediaRecorder;
34import android.media.EncoderCapabilities;
35import android.media.EncoderCapabilities.VideoEncoderCap;
36import android.media.EncoderCapabilities.AudioEncoderCap;
37import android.test.ActivityInstrumentationTestCase2;
38import android.util.Log;
39import android.view.Surface;
40import android.view.SurfaceHolder;
41import android.view.SurfaceView;
42import com.android.mediaframeworktest.MediaProfileReader;
43import com.android.mediaframeworktest.MediaFrameworkTestRunner;
44
45import android.test.suitebuilder.annotation.LargeTest;
46import android.test.suitebuilder.annotation.Suppress;
47import java.util.List;
48
49
50/**
51 * Junit / Instrumentation test case for the media recorder api
52 */
53public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
54    private String TAG = "MediaRecorderTest";
55    private int mOutputDuration =0;
56    private int mOutputVideoWidth = 0;
57    private int mOutputVideoHeight= 0 ;
58
59    private SurfaceHolder mSurfaceHolder = null;
60    private MediaRecorder mRecorder;
61
62    private int MIN_VIDEO_FPS = 5;
63    private int HIGH_SPEED_FPS = 120;
64
65    private static final int CAMERA_ID = 0;
66
67    Context mContext;
68    Camera mCamera;
69
70    public MediaRecorderTest() {
71        super(MediaFrameworkTest.class);
72
73    }
74
75    protected void setUp() throws Exception {
76        getActivity();
77        mRecorder = new MediaRecorder();
78        super.setUp();
79    }
80
81    private void recordVideo(int frameRate, int width, int height,
82            int videoFormat, int outFormat, String outFile, boolean videoOnly) {
83        Log.v(TAG,"startPreviewAndPrepareRecording");
84        try {
85            if (!videoOnly) {
86                Log.v(TAG, "setAudioSource");
87                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
88            }
89            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
90            mRecorder.setOutputFormat(outFormat);
91            Log.v(TAG, "output format " + outFormat);
92            mRecorder.setOutputFile(outFile);
93            mRecorder.setVideoFrameRate(frameRate);
94            mRecorder.setVideoSize(width, height);
95            Log.v(TAG, "setEncoder");
96            mRecorder.setVideoEncoder(videoFormat);
97            if (!videoOnly) {
98                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
99            }
100            mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
101            Log.v(TAG, "setPreview");
102            mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
103            Log.v(TAG, "prepare");
104            mRecorder.prepare();
105            Log.v(TAG, "start");
106            mRecorder.start();
107            Thread.sleep(MediaNames.RECORDED_TIME);
108            Log.v(TAG, "stop");
109            mRecorder.stop();
110            mRecorder.release();
111        } catch (Exception e) {
112            Log.v("record video failed ", e.toString());
113            mRecorder.release();
114        }
115    }
116
117    private boolean validateGetSurface(boolean useSurface) {
118        Log.v(TAG,"validateGetSurface, useSurface=" + useSurface);
119        MediaRecorder recorder = new MediaRecorder();
120        Surface surface;
121        boolean success = true;
122        try {
123            /* initialization */
124            if (!useSurface) {
125                mCamera = Camera.open(CAMERA_ID);
126                Camera.Parameters parameters = mCamera.getParameters();
127                parameters.setPreviewSize(352, 288);
128                parameters.set("orientation", "portrait");
129                mCamera.setParameters(parameters);
130                mCamera.unlock();
131                recorder.setCamera(mCamera);
132                mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
133                recorder.setPreviewDisplay(mSurfaceHolder.getSurface());
134            }
135
136            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
137            int videoSource = useSurface ?
138                    MediaRecorder.VideoSource.SURFACE :
139                    MediaRecorder.VideoSource.CAMERA;
140            recorder.setVideoSource(videoSource);
141            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
142            recorder.setOutputFile(MediaNames.RECORDED_SURFACE_3GP);
143            recorder.setVideoFrameRate(30);
144            recorder.setVideoSize(352, 288);
145            recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
146            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
147
148            /* Test: getSurface() before prepare()
149             * should throw IllegalStateException
150             */
151            try {
152                surface = recorder.getSurface();
153                throw new Exception("getSurface failed to throw IllegalStateException");
154            } catch (IllegalStateException e) {
155                // OK
156            }
157
158            recorder.prepare();
159
160            /* Test: getSurface() after prepare()
161             * should succeed for surface source
162             * should fail for camera source
163             */
164            try {
165                surface = recorder.getSurface();
166                if (!useSurface) {
167                    throw new Exception("getSurface failed to throw IllegalStateException");
168                }
169            } catch (IllegalStateException e) {
170                if (useSurface) {
171                    throw new Exception("getSurface failed to throw IllegalStateException");
172                }
173            }
174
175            recorder.start();
176
177            /* Test: getSurface() after start()
178             * should succeed for surface source
179             * should fail for camera source
180             */
181            try {
182                surface = recorder.getSurface();
183                if (!useSurface) {
184                    throw new Exception("getSurface failed to throw IllegalStateException");
185                }
186            } catch (IllegalStateException e) {
187                if (useSurface) {
188                    throw new Exception("getSurface failed to throw IllegalStateException");
189                }
190            }
191
192            try {
193                recorder.stop();
194            } catch (Exception e) {
195                // stop() could fail if the recording is empty, as we didn't render anything.
196                // ignore any failure in stop, we just want it stopped.
197            }
198
199            /* Test: getSurface() after stop()
200             * should throw IllegalStateException
201             */
202            try {
203                surface = recorder.getSurface();
204                throw new Exception("getSurface failed to throw IllegalStateException");
205            } catch (IllegalStateException e) {
206                // OK
207            }
208        } catch (Exception e) {
209            // fail
210            success = false;
211        }
212
213        try {
214            if (mCamera != null) {
215                mCamera.lock();
216                mCamera.release();
217                mCamera = null;
218            }
219            recorder.release();
220        } catch (Exception e) {
221            success = false;
222        }
223
224        return success;
225    }
226
227    private boolean recordVideoFromSurface(
228            int frameRate, int captureRate, int width, int height,
229            int videoFormat, int outFormat, String outFile, boolean videoOnly,
230            Surface persistentSurface) {
231        Log.v(TAG,"recordVideoFromSurface");
232        MediaRecorder recorder = new MediaRecorder();
233        int sleepTime = 33; // normal capture at 33ms / frame
234        Surface surface = null;
235        try {
236            if (!videoOnly) {
237                recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
238            }
239            recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
240            recorder.setOutputFormat(outFormat);
241            recorder.setOutputFile(outFile);
242            recorder.setVideoFrameRate(frameRate);
243            if (captureRate > 0) {
244                recorder.setCaptureRate(captureRate);
245                sleepTime = 1000 / captureRate;
246            }
247            recorder.setVideoSize(width, height);
248            recorder.setVideoEncoder(videoFormat);
249            if (!videoOnly) {
250                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
251            }
252            if (persistentSurface != null) {
253                Log.v(TAG, "using persistent surface");
254                surface = persistentSurface;
255                recorder.setInputSurface(surface);
256            }
257            recorder.prepare();
258            if (persistentSurface == null) {
259                surface = recorder.getSurface();
260            }
261
262            Paint paint = new Paint();
263            paint.setTextSize(16);
264            paint.setColor(Color.RED);
265            int i;
266
267            /* Test: draw 10 frames at 30fps before start
268             * these should be dropped and not causing malformed stream.
269             */
270            for(i = 0; i < 10; i++) {
271                Canvas canvas = surface.lockCanvas(null);
272                int background = (i * 255 / 99);
273                canvas.drawARGB(255, background, background, background);
274                String text = "Frame #" + i;
275                canvas.drawText(text, 100, 100, paint);
276                surface.unlockCanvasAndPost(canvas);
277                Thread.sleep(sleepTime);
278            }
279
280            Log.v(TAG, "start");
281            recorder.start();
282
283            /* Test: draw another 90 frames at 30fps after start */
284            for(i = 10; i < 100; i++) {
285                Canvas canvas = surface.lockCanvas(null);
286                int background = (i * 255 / 99);
287                canvas.drawARGB(255, background, background, background);
288                String text = "Frame #" + i;
289                canvas.drawText(text, 100, 100, paint);
290                surface.unlockCanvasAndPost(canvas);
291                Thread.sleep(sleepTime);
292            }
293
294            Log.v(TAG, "stop");
295            recorder.stop();
296        } catch (Exception e) {
297            Log.v(TAG, "record video failed: " + e.toString());
298            return false;
299        } finally {
300            recorder.release();
301            // release surface if not using persistent surface
302            if (persistentSurface == null && surface != null) {
303                surface.release();
304            }
305        }
306        return true;
307    }
308
309    private boolean recordVideoWithPara(VideoEncoderCap videoCap, AudioEncoderCap audioCap, boolean highQuality){
310        boolean recordSuccess = false;
311        int videoEncoder = videoCap.mCodec;
312        int audioEncoder = audioCap.mCodec;
313        int videoWidth = highQuality? videoCap.mMaxFrameWidth: videoCap.mMinFrameWidth;
314        int videoHeight = highQuality? videoCap.mMaxFrameHeight: videoCap.mMinFrameHeight;
315        int videoFps = highQuality? videoCap.mMaxFrameRate: videoCap.mMinFrameRate;
316        int videoBitrate = highQuality? videoCap.mMaxBitRate: videoCap.mMinBitRate;
317        int audioBitrate = highQuality? audioCap.mMaxBitRate: audioCap.mMinBitRate;
318        int audioChannels = highQuality? audioCap.mMaxChannels: audioCap.mMinChannels ;
319        int audioSamplingRate = highQuality? audioCap.mMaxSampleRate: audioCap.mMinSampleRate;
320
321        //Overide the fps if the min_camera_fps is set
322        if (MediaFrameworkTestRunner.mMinCameraFps != 0 &&
323            MediaFrameworkTestRunner.mMinCameraFps > videoFps){
324            videoFps = MediaFrameworkTestRunner.mMinCameraFps;
325        }
326
327        if (videoFps < MIN_VIDEO_FPS) {
328            videoFps = MIN_VIDEO_FPS;
329        }
330
331        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
332        String filename = ("/sdcard/" + videoEncoder + "_" + audioEncoder + "_" + highQuality + ".3gp");
333        try {
334            Log.v(TAG, "video encoder : " + videoEncoder);
335            Log.v(TAG, "audio encoder : " + audioEncoder);
336            Log.v(TAG, "quality : " + (highQuality?"high": "low"));
337            Log.v(TAG, "encoder : " + MediaProfileReader.getVideoCodecName(videoEncoder));
338            Log.v(TAG, "audio : " + MediaProfileReader.getAudioCodecName(audioEncoder));
339            Log.v(TAG, "videoWidth : " + videoWidth);
340            Log.v(TAG, "videoHeight : " + videoHeight);
341            Log.v(TAG, "videoFPS : " + videoFps);
342            Log.v(TAG, "videobitrate : " + videoBitrate);
343            Log.v(TAG, "audioBitrate : " + audioBitrate);
344            Log.v(TAG, "audioChannel : " + audioChannels);
345            Log.v(TAG, "AudioSampleRate : " + audioSamplingRate);
346
347            MediaRecorder mMediaRecorder = new MediaRecorder();
348            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
349            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
350            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
351            mMediaRecorder.setOutputFile(filename);
352            mMediaRecorder.setVideoFrameRate(videoFps);
353            mMediaRecorder.setVideoSize(videoWidth, videoHeight);
354            mMediaRecorder.setVideoEncodingBitRate(videoBitrate);
355            mMediaRecorder.setAudioEncodingBitRate(audioBitrate);
356            mMediaRecorder.setAudioChannels(audioChannels);
357            mMediaRecorder.setAudioSamplingRate(audioSamplingRate);
358            mMediaRecorder.setVideoEncoder(videoEncoder);
359            mMediaRecorder.setAudioEncoder(audioEncoder);
360            mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
361            mMediaRecorder.prepare();
362            mMediaRecorder.start();
363            Thread.sleep(MediaNames.RECORDED_TIME);
364            mMediaRecorder.stop();
365            mMediaRecorder.release();
366            recordSuccess = validateVideo(filename, videoWidth, videoHeight);
367        } catch (Exception e) {
368            Log.v(TAG, e.toString());
369            return false;
370        }
371        return recordSuccess;
372    }
373
374    private boolean invalidRecordSetting(int frameRate, int width, int height,
375            int videoFormat, int outFormat, String outFile, boolean videoOnly) {
376        try {
377            if (!videoOnly) {
378                Log.v(TAG, "setAudioSource");
379                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
380            }
381            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
382            mRecorder.setOutputFormat(outFormat);
383            Log.v(TAG, "output format " + outFormat);
384            mRecorder.setOutputFile(outFile);
385            mRecorder.setVideoFrameRate(frameRate);
386            mRecorder.setVideoSize(width, height);
387            Log.v(TAG, "setEncoder");
388            mRecorder.setVideoEncoder(videoFormat);
389            if (!videoOnly) {
390                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
391            }
392            mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
393            Log.v(TAG, "setPreview");
394            mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
395            Log.v(TAG, "prepare");
396            mRecorder.prepare();
397            Log.v(TAG, "start");
398            mRecorder.start();
399            Thread.sleep(MediaNames.RECORDED_TIME);
400            Log.v(TAG, "stop");
401            mRecorder.stop();
402            mRecorder.release();
403        } catch (Exception e) {
404            Log.v("record video failed ", e.toString());
405            mRecorder.release();
406            Log.v(TAG, "reset and release");
407            return true;
408        }
409        return false;
410    }
411
412    private void getOutputVideoProperty(String outputFilePath) {
413        MediaPlayer mediaPlayer = new MediaPlayer();
414        try {
415            mediaPlayer.setDataSource(outputFilePath);
416            Log.v(TAG, "file Path = " + outputFilePath);
417            mediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
418            Log.v(TAG, "before player prepare");
419            mediaPlayer.prepare();
420            Log.v(TAG, "before getduration");
421            mOutputDuration = mediaPlayer.getDuration();
422            Log.v(TAG, "get video dimension");
423            Thread.sleep(1000);
424            mOutputVideoHeight = mediaPlayer.getVideoHeight();
425            mOutputVideoWidth = mediaPlayer.getVideoWidth();
426            mediaPlayer.release();
427        } catch (Exception e) {
428            Log.v(TAG, e.toString());
429            mediaPlayer.release();
430        }
431    }
432
433    private boolean validateVideo(String filePath, int width, int height) {
434        boolean validVideo = false;
435        getOutputVideoProperty(filePath);
436        if (mOutputVideoWidth == width && mOutputVideoHeight == height &&
437                mOutputDuration > MediaNames.VALID_VIDEO_DURATION ) {
438            validVideo = true;
439        }
440        Log.v(TAG, "width = " + mOutputVideoWidth + " height = " + mOutputVideoHeight + " Duration = " + mOutputDuration);
441        return validVideo;
442    }
443
444    private boolean validateMetadata(String filePath, int captureRate) {
445        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
446
447        retriever.setDataSource(filePath);
448
449        // verify capture rate meta key is present and correct
450        String captureFps = retriever.extractMetadata(
451                MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE);
452
453        if (captureFps == null) {
454            Log.d(TAG, "METADATA_KEY_CAPTURE_FRAMERATE is missing");
455            return false;
456        }
457
458        if (Math.abs(Float.parseFloat(captureFps) - captureRate) > 0.001) {
459            Log.d(TAG, "METADATA_KEY_CAPTURE_FRAMERATE is incorrect: "
460                    + captureFps + "vs. " + captureRate);
461            return false;
462        }
463
464        // verify other meta keys here if necessary
465        return true;
466    }
467    @LargeTest
468    /*
469     * This test case set the camera in portrait mode.
470     * Verification: validate the video dimension and the duration.
471     */
472    public void testPortraitH263() throws Exception {
473        boolean videoRecordedResult = false;
474        try {
475            mCamera = Camera.open(CAMERA_ID);
476            Camera.Parameters parameters = mCamera.getParameters();
477            parameters.setPreviewSize(352, 288);
478            parameters.set("orientation", "portrait");
479            mCamera.setParameters(parameters);
480            mCamera.unlock();
481            mRecorder.setCamera(mCamera);
482            Thread.sleep(1000);
483            int codec = MediaRecorder.VideoEncoder.H263;
484            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
485            recordVideo(frameRate, 352, 288, codec,
486                    MediaRecorder.OutputFormat.THREE_GPP,
487                    MediaNames.RECORDED_PORTRAIT_H263, true);
488            mCamera.lock();
489            mCamera.release();
490            videoRecordedResult =
491                validateVideo(MediaNames.RECORDED_PORTRAIT_H263, 352, 288);
492        } catch (Exception e) {
493            Log.v(TAG, e.toString());
494        }
495        assertTrue("PortraitH263", videoRecordedResult);
496    }
497
498    @LargeTest
499    public void testInvalidVideoPath() throws Exception {
500        boolean isTestInvalidVideoPathSuccessful = false;
501        isTestInvalidVideoPathSuccessful = invalidRecordSetting(15, 176, 144, MediaRecorder.VideoEncoder.H263,
502               MediaRecorder.OutputFormat.THREE_GPP, MediaNames.INVALD_VIDEO_PATH, false);
503        assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful);
504    }
505
506    @LargeTest
507    //test cases for the new codec
508    public void testDeviceSpecificCodec() throws Exception {
509        int noOfFailure = 0;
510        boolean recordSuccess = false;
511        String deviceType = MediaProfileReader.getDeviceType();
512        Log.v(TAG, "deviceType = " + deviceType);
513        List<VideoEncoderCap> videoEncoders = MediaProfileReader.getVideoEncoders();
514        List<AudioEncoderCap> audioEncoders = MediaProfileReader.getAudioEncoders();
515        for (int k = 0; k < 2; k++) {
516            for (VideoEncoderCap videoEncoder: videoEncoders) {
517                for (AudioEncoderCap audioEncoder: audioEncoders) {
518                    if (k == 0) {
519                        recordSuccess = recordVideoWithPara(videoEncoder, audioEncoder, true);
520                    } else {
521                        recordSuccess = recordVideoWithPara(videoEncoder, audioEncoder, false);
522                    }
523                    if (!recordSuccess) {
524                        Log.v(TAG, "testDeviceSpecificCodec failed");
525                        Log.v(TAG, "Encoder = " + videoEncoder.mCodec + "Audio Encoder = " + audioEncoder.mCodec);
526                        noOfFailure++;
527                    }
528                }
529            }
530        }
531        if (noOfFailure != 0) {
532            assertTrue("testDeviceSpecificCodec", false);
533        }
534    }
535
536    // Test MediaRecorder.getSurface() api with surface or camera source
537    public void testGetSurfaceApi() {
538        boolean success = false;
539        int noOfFailure = 0;
540        try {
541            for (int k = 0; k < 2; k++) {
542                success = validateGetSurface(
543                        k == 0 ? true : false /* useSurface */);
544                if (!success) {
545                    noOfFailure++;
546                }
547            }
548        } catch (Exception e) {
549            Log.v(TAG, e.toString());
550        }
551        assertTrue("testGetSurfaceApi", noOfFailure == 0);
552    }
553
554    // Test recording from surface source with/without audio
555    public void testSurfaceRecording() {
556        boolean success = false;
557        int noOfFailure = 0;
558        try {
559            int codec = MediaRecorder.VideoEncoder.H264;
560            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
561            for (int k = 0; k < 2; k++) {
562                String filename = "/sdcard/surface_" +
563                            (k==0?"video_only":"with_audio") + ".3gp";
564
565                success = recordVideoFromSurface(frameRate, 0, 352, 288, codec,
566                        MediaRecorder.OutputFormat.THREE_GPP, filename,
567                        k == 0 ? true : false /* videoOnly */, null);
568                if (success) {
569                    success = validateVideo(filename, 352, 288);
570                }
571                if (!success) {
572                    noOfFailure++;
573                }
574            }
575        } catch (Exception e) {
576            Log.v(TAG, e.toString());
577        }
578        assertTrue("testSurfaceRecording", noOfFailure == 0);
579    }
580
581    public void testPersistentSurfaceRecording() {
582        boolean success = false;
583        int noOfFailure = 0;
584        Surface surface = null;
585        try {
586            int codec = MediaRecorder.VideoEncoder.H264;
587            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
588            surface = MediaCodec.createPersistentInputSurface();
589            for (int k = 0; k < 2; k++) {
590                String filename = "/sdcard/surface_persistent" + k + ".3gp";
591
592                Log.v(TAG, "test persistent surface - round " + k);
593                success = recordVideoFromSurface(frameRate, 0, 352, 288, codec,
594                        MediaRecorder.OutputFormat.THREE_GPP, filename,
595                        true /* videoOnly */, surface);
596                if (success) {
597                    success = validateVideo(filename, 352, 288);
598                }
599                if (!success) {
600                    noOfFailure++;
601                }
602            }
603        } catch (Exception e) {
604            Log.v(TAG, e.toString());
605        } finally {
606            if (surface != null) {
607                Log.v(TAG, "releasing persistent surface");
608                surface.release();
609                surface = null;
610            }
611        }
612        assertTrue("testPersistentSurfaceRecording", noOfFailure == 0);
613    }
614
615    // Test recording from surface source with/without audio
616    public void testSurfaceRecordingTimeLapse() {
617        boolean success = false;
618        int noOfFailure = 0;
619        try {
620            int codec = MediaRecorder.VideoEncoder.H264;
621            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
622            for (int k = 0; k < 2; k++) {
623                // k==0: time lapse test, set capture rate to MIN_VIDEO_FPS
624                // k==1: slow motion test, set capture rate to HIGH_SPEED_FPS
625                String filename = "/sdcard/surface_" +
626                            (k==0 ? "time_lapse" : "slow_motion") + ".3gp";
627
628                // always set videoOnly=false, MediaRecorder should disable
629                // audio automatically with time lapse/slow motion
630                int captureRate = k==0 ? MIN_VIDEO_FPS : HIGH_SPEED_FPS;
631                success = recordVideoFromSurface(
632                        frameRate, captureRate, 352, 288, codec,
633                        MediaRecorder.OutputFormat.THREE_GPP,
634                        filename, false /* videoOnly */, null);
635                if (success) {
636                    success = validateVideo(filename, 352, 288);
637                    if (success) {
638                        success = validateMetadata(filename, captureRate);
639                    }
640                }
641                if (!success) {
642                    noOfFailure++;
643                }
644            }
645        } catch (Exception e) {
646            Log.v(TAG, e.toString());
647            noOfFailure++;
648        }
649        assertTrue("testSurfaceRecordingTimeLapse", noOfFailure == 0);
650    }
651
652}
653