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
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 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 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 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.