DDSports
DDSports

Reputation: 400

Samsung Galaxy S5 won't record video at low res/frame rate

I have an application that uses MediaRecorder for recording video and I have a problem with low resolution recording on the Samsung Galaxy S5 SM-G900F (only this device - recording at the lowest supported video resolution works fine on everything else I have tested with).

I firstly interrogate the camera parameters (with a Camera Parameters object, so mParameters.getSupportedVideoSizes(); and mParameters.getSupportedPreviewSizes();) to check for the available recording and preview resolutions and the S5 returns the following supported video and preview sizes, respectively:

Video Size List:        Preview Size List:
                        W = 1920,   H = 1080
W = 1920,   H = 1080    W = 1440,   H = 1080
W = 1440,   H = 1080    W = 1280,   H = 720
W = 1280,   H = 720     W = 1056,   H = 864
W = 800,    H = 450     W = 960,    H = 720
W = 800,    H = 480     W = 800,    H = 480
W = 720,    H = 480     W = 720,    H = 480
W = 640,    H = 480     W = 640,    H = 480
W = 352,    H = 288     W = 352,    H = 288
W = 320,    H = 240     W = 320,    H = 240
W = 176,    H = 144     W = 176,    H = 144

The range of supported frame rates returned is 10,000-30,000, so I select 10,000 for the lowest recording resolution (10FPS).

I select the lowest resolution offered by the S5, which is 176(w) x 144(h) (to keep the video file size low) and then make the following MediaRecorder settings...

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoFrameRate(10);
mMediaRecorder.setVideoSize(176, 144);
mMediaRecorder.setVideoEncodingBitRate(256000);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());   // Preview size is also set to 176 x 144
mMediaRecorder.setOutputFile(mVideoFilename);

...before then calling mMediaRecorder.prepare();, followed by mMediaRecorder.start();.

This code works fine on the "Sony XPeria", the "HTC One", the "HTC One V", the "Samsung Galaxy S3" an "HTC Explorer" and a number of other devices, running various Android versions from Gingerbread up to KitKat (I can't get a separate Video Size list on Gingerbread).

Only the Samsung Galaxy S5 has a problem recording at 176 x 144. When calling mMediaRecorder.start();, the recording fails to start with a "java.lang.RuntimeException: start failed." exception.

I cannot work out what the problem is. All other recording resolutions (with increased EncodingBitRate settings) work just fine - it is only 176 x 144 that doesn't work on the S5.

Has anybody else seen this problem? Does anybody know if there's a problem with the S5 that stops recording from working properly at the lowest supported video resolution? Or is there some Samsung 'trick' that I'm missing?

Any help or insights would be much appreciated - I'm tearing my hair out over this one!

Upvotes: 3

Views: 1774

Answers (2)

DDSports
DDSports

Reputation: 400

This post here (Android can't record video with Front Facing Camera, MediaRecorder start failed: -19) sheds some more light on this particular issue and it all seems to point to the camera API being a bit - well - naff! Since 'solving' this problem with the S5, I've since found exactly the same issue with the Sony XPeria Z. In spite of what Camera.getParameters().getSupportedPreviewFpsRange() returns, these phones actually only support 15/24/30fps(S5) and 15/30fps (Xperia Z) for actual MediaRecorder video recordings via mMediaRecorder.setVideoFrameRate().

Maybe the clue here is the word "Preview" in the method name getSupportedPreviewFpsRange() and the returned values ONLY apply to a preview surface. Maybe the Samsung and Sony developers for these phones took that method name too literally, and only return Preview fps values, leaving the developer to guess the video frame rates; I found out the hard way that there doesn't seem to be any way at all to find out what FPS values are supported for MediaRecorder video recording.

Most phones seem to substitute an 'OK' value for setVideoFrameRate() if the supplied value isn't supported, thus protecting the developer from having to guess what the supported rates are. The S5 and the Z (and probably others) just blindly take whatever value is set in setVideoFrameRate() and then helpfully crash with the -19 error if the value you happen to choose isn't supported. As @Madhava Jay points out in his post "I don't see any way I could determine the [frame rate] without just guessing".

It may be the case that the camera can support a range of frame rates, but that the Sony and Samsung implementation of MediaRecorder is deficient in not being able to accept these rates.

Top stuff Android!

Upvotes: 0

DDSports
DDSports

Reputation: 400

What I've found is that the problem was due to the frame rate, not the resolution. The S5 seems to be telling lies about what preview frame rates it supports. Or, more accurately, the list of values returned by getSupportedPreviewFpsRange() is not an actual range of supported frame rates.

The S5 returns (10000, 30000) from getSupportedPreviewFpsRange() which, according to the documentation, is the range of video frame rates that is supported by the device, the implication being that any frame rate within that range is supported (or the device will try to get as close as possible to the rate specified in mMediaRecorder.setVideoFrameRate()).

The S5 thinks differently! Setting a frame rate of 10, as I am doing, stops MediaRecorder from starting a video recording, with the familiar MediaRecorder(22664): start failed: -19 exception.

On the mMediaRecorder.setVideoFrameRate(10) call, I get a CameraSource(262): Requested frame rate (10) is not supported: 15,24,30 exception, the implication being that 15, 24 and 30 are the only frame rates supported. I get the same exception if I use mMediaRecorder.setVideoFrameRate(20), but if I use mMediaRecorder.setVideoFrameRate(30) it works fine.

I also get a OMX-VENC-720p(262): Invalid entry returned from get_supported_profile_level 2130706433, 65536 exception, which seems related to the MediaRecorder settings, but it's anybody's guess as to what it really means.

I have no idea how I am supposed to know that 15fps, 24fps and 30fps are the only supported frame rates.

If anybody else knows of a way that I can find this out without tripping over the CameraSource(262): Requested frame rate (X) is not supported: 15,24,30 exception, I'd love to know what it is.

The method I use has proven effective on dozens of device types, including a Samsung S3, so this problem seems to be S5 specific. I'm reduced therefore to having to force an S5-specific frame rate by firstly working out what phone the app is running on, which is not ideal - thanks for that Samsung!

Finally, does anybody know how/where I can report this bug to Samsung?

Upvotes: 2

Related Questions