CamcorderProfile.QUALITY_HIGH resolution produces green flickering video

前端 未结 5 1860
无人及你
无人及你 2020-12-01 09:12

I haven\'t found any explanation for this so far. Basically I have a video recording class which works splendidly when setVideoSize() is set to 720 x 480 on my Samsung Galax

相关标签:
5条回答
  • 2020-12-01 09:38

    Here is how I managed to make this work on Samsung Galaxy S2. The critical point here is to set the same resolution both in camera parameters and recorder video size. Also, already mentioned 'cam_mode' hack is required. So, I allowed a user to select from three quality modes: low (800x480), medium(1280x720), and high(1920x1080):

    enum InternalCameraQuality {
        LOW, MEDIUM, HIGH
    }
    

    and when creating/populating camera and recorder I did

    // signature types are irrelevant here
    File start(DeviceHandler handler, FileHelper fh) throws IOException {
        file = fh.createTempFile(".mp4");
    
        camera = Camera.open();
        setCameraParameters(camera);
        camera.setPreviewDisplay(getHolder());
        camera.unlock();
    
        recorder = new MediaRecorder();
        recorder.setCamera(camera);
        setRecorderParameters(recorder);
    
        recorder.prepare();
        recorder.start();
    
        return file;
    }
    
    void setCameraParameters(Camera camera) {
        Camera.Parameters param = camera.getParameters();
    
        // getParams() simply returns some field holding configuration parameters
        // only the 'quality' parameter is relevant here
        if (getParams().quality != InternalCameraQuality.LOW) {
            // Samsung Galaxy hack for HD video
            param.set("cam_mode", 1);
        }
    
        Pair<Integer, Integer> resolution = getResolution(getParams().quality);
        param.setPreviewSize(resolution.first, resolution.second);
        param.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
    
        camera.setParameters(param);
    }
    
    void setRecorderParameters(MediaRecorder recorder) {
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    
        Pair<Integer, Integer> resolution = getResolution(getParams().quality);
    
        CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
        profile.videoFrameWidth = resolution.first;
        profile.videoFrameHeight = resolution.second;
        recorder.setProfile(profile);
    
        recorder.setOutputFile(file.getAbsolutePath());
        recorder.setPreviewDisplay(getHolder().getSurface());
    }
    
    Pair<Integer, Integer> getResolution(InternalCameraQuality quality) {
        final int width, height;
        switch (quality) {
            case LOW:
                width = 800;
                height = 480;
                break;
            case MEDIUM:
                width = 1280;
                height = 720;
                break;
            case HIGH:
                width = 1920;
                height = 1080;
                break;
            default:
                throw new IllegalArgumentException("Unknown quality: " + quality.name());
        }
        return Pair.create(width, height);
    }
    

    Note that you must use the 'cam_mode' hack only for medium and high quality, otherwise green flickering will appear in low quality mode. Also you may wish to customize some other profile settings if you need.

    Hope, that helped.

    0 讨论(0)
  • 2020-12-01 09:39

    I've experienced similar problems like this in the past. What you're doing seems to be fine but here are a few suggestions that might help to debug the problem:

    Ensure you are selecting a supported resolution

    int cameraId = 0; // using back facing camera
    Camera camera = Camera.open(cameraId);
    Camera.Parameters cameraParams = camera.getParameters();
    List<Camera.Size> supportedPreviewSizes = cameraParams.getSupportedPreviewSizez();
    
    // find suitable Camera preview size from list and set your CamcorderProfile to use that new size
    

    After you've located a suitable preview size be sure to reset your SurfaceView -- you will need to resize it to accommodate the change in aspect ratio

    MediaRecorder API uses the SurfaceView so if your surface view isn't configured correctly it will result in the green flicker you're seeing

    Ensure you are using a video bit rate that can support the new resolution -- try bumping the video bit rate to double what it was originally set to (*note this drastically effects your output filesize)

    CamcorderProfile.QUALITY_HIGH returns the highest possible supported camera resolution. Ensure you are using the correct camera id (front vs. back) -- maybe the back facing camera supports 1080p but the front facing camera does not?

    Hope the tips help!

    0 讨论(0)
  • 2020-12-01 09:43

    Ok, I tested many variants and the only Version wich works well on real Devices is:

    CamcorderProfile camcorderProfile    = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    
    // THREE_GPP works well but only on Phones            
    //  camcorderProfile.fileFormat = MediaRecorder.OutputFormat.THREE_GPP;
    
    // so better you use MPEG_4 for most Devices and PC
    camcorderProfile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
    camcorderProfile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;
    
    mrec.setProfile(camcorderProfile);
    
    0 讨论(0)
  • 2020-12-01 09:53
            List<Size> ls = parameters.getSupportedPreviewSizes();
            Size size = ls.get(1);
            sizes 1 ----------960 720
            sizes 2 ----------800 480
            sizes 3 ----------720 480
            sizes 5 -----------640 384
            sizes 6 ----------576 432
            sizes 7 ----------480 320
    

    this are the list of sizes and more in android.

    0 讨论(0)
  • 2020-12-01 10:00

    I came across this question trying to solve the same problem.

    A solution is given over on xda developer http://forum.xda-developers.com/showthread.php?t=1104970&page=8. It seems that you need to set an obscure parameter "cam_mode" for high definition recording to work:

    camera = Camera.open();
    Camera.Parameters param = camera.getParameters();
    param.set( "cam_mode", 1 );     
    camera.setParameters( param );
    

    In mediarecorder, you can then use

    mediarecorder.setVideoSize(1920, 1080);
    

    although this will now also work:

    mediarecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
    

    (The latter seems to have a video bitrate of 20Mb/s, so you might want to take that down a bit!) I found that I didn't have to set the preview size to 1920x1080.

    (edit) You also need to set

    parame.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
    

    or

    param.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
    

    otherwise you get a delay of a few seconds before the camera starts!

    As to why Samsung has implemented the Camera in this way, I have no idea. It's certainly not developer friendly!

    0 讨论(0)
提交回复
热议问题