Samsung Galaxy S5 няма да записва видео при ниска разделителна способност/честота на кадрите

Имам приложение, което използва MediaRecorder за запис на видео и имам проблем със запис с ниска разделителна способност на Samsung Galaxy S5 SM-G900F (само това устройство - записът на най-ниската поддържана разделителна способност на видео работи добре на всичко останало, с което съм тествал).

Първо разпитвам параметрите на камерата (с обект Camera Parameters, така че mParameters.getSupportedVideoSizes(); и mParameters.getSupportedPreviewSizes();), за да проверя за наличните разделителни способности за запис и визуализация и S5 връща съответно следните поддържани размери за видео и визуализация:

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

Обхватът на върнатите поддържани честоти на кадрите е 10 000-30 000, така че избирам 10 000 за най-ниската разделителна способност на запис (10 FPS).

Избирам най-ниската разделителна способност, предлагана от S5, която е 176(w) x 144(h) (за да запазя размера на видео файла малък) и след това правя следните настройки на MediaRecorder...

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);

... преди да извикате mMediaRecorder.prepare();, последвано от mMediaRecorder.start();.

Този код работи добре на "Sony XPeria", "HTC One", "HTC One V", "Samsung Galaxy S3" и "HTC Explorer" и редица други устройства, работещи с различни версии на Android от Gingerbread до KitKat (не мога да получа отделен списък с размери на видео в Gingerbread).

Само Samsung Galaxy S5 има проблем със записа при 176 x 144. При извикване на mMediaRecorder.start(); записът не започва с "java.lang.RuntimeException: стартирането е неуспешно." изключение.

Не мога да разбера какъв е проблемът. Всички други разделителни способности на запис (с повишени настройки на EncodingBitRate) работят добре - само 176 x 144 не работи на S5.

Някой друг виждал ли е този проблем? Някой знае ли дали има проблем с S5, който спира записа да работи правилно при най-ниската поддържана видео резолюция? Или има някакъв „трик“ на Samsung, който пропускам?

Всяка помощ или прозрения ще бъдат много оценени - направо си скубя косата заради това!


person DDSports    schedule 16.02.2015    source източник
comment
следните поддържани видео размери и размери за визуализация -- какво използвахте, за да определите поддържаните видео размери?   -  person CommonsWare    schedule 17.02.2015
comment
@CommonsWare, използвам параметри на камерата с getSupportedVideoSizes() и getSupportedPreviewSizes(). Актуализирах въпроса си.   -  person DDSports    schedule 17.02.2015
comment
Добре, изглежда, че никой друг не е имал същия проблем (или поне никога не е успявал да го реши). Току-що купих Galaxy S5 - когато (ако?) разбера какво прави този телефон, ще публикувам откритията си.   -  person DDSports    schedule 23.02.2015


Отговори (2)


Това, което открих е, че проблемът се дължи на честотата на кадрите, а не на разделителната способност. Изглежда, че S5 лъже за това какви честоти на кадрите за визуализация поддържа. Или, по-точно, списъкът със стойности, върнат от getSupportedPreviewFpsRange(), не е действителен диапазон от поддържани кадрови честоти.

S5 връща (10000, 30000) от getSupportedPreviewFpsRange(), което според документацията е диапазонът на кадровите честоти на видео, които се поддържат от устройството, което означава, че всяка кадрова честота в този диапазон се поддържа (или устройството ще се опита да се доближи възможно най-близо до скоростта, посочена в mMediaRecorder.setVideoFrameRate()).

S5 мисли различно! Задаването на кадрова честота от 10, както правя аз, спира MediaRecorder да започне видеозапис, с познатото изключение MediaRecorder(22664): start failed: -19.

При повикването mMediaRecorder.setVideoFrameRate(10) получавам изключение CameraSource(262): Requested frame rate (10) is not supported: 15,24,30, което означава, че 15, 24 и 30 са единствените поддържани честоти на кадрите. Получавам същото изключение, ако използвам mMediaRecorder.setVideoFrameRate(20), но ако използвам mMediaRecorder.setVideoFrameRate(30), работи добре.

Получавам и изключение OMX-VENC-720p(262): Invalid entry returned from get_supported_profile_level 2130706433, 65536, което изглежда свързано с настройките на MediaRecorder, но никой не може да предположи какво всъщност означава.

Нямам представа как трябва да знам, че 15fps, 24fps и 30fps са единствените поддържани честоти на кадрите.

Ако някой друг знае начин, по който мога да намеря това, без да се препъвам в изключението CameraSource(262): Requested frame rate (X) is not supported: 15,24,30, ще се радвам да знам какъв е той.

Методът, който използвам, се оказа ефективен при десетки типове устройства, включително Samsung S3, така че този проблем изглежда специфичен за S5. Следователно трябва да налагам специфична за S5 кадрова честота, като първо определям на какъв телефон работи приложението, което не е идеално – благодаря за това на Samsung!

И накрая, някой знае ли как/къде мога да докладвам тази грешка на Samsung?

person DDSports    schedule 27.02.2015
comment
Наистина съм удивен, че никой друг в цялата SO общност не е заседнал с този проблем. Мога ли наистина да бъда единственият разработчик, който се опитва да стартира запис с ниско качество на S5? - person DDSports; 17.03.2015

Тази публикация тук (Android не може да записва видео с предна камера, стартирането на MediaRecorder е неуспешно: -19) хвърля малко повече светлина върху този конкретен проблем и всичко изглежда сочи към това, че API на камерата е малко - ами - кофти! Откакто „реших“ този проблем със S5, оттогава открих точно същия проблем със Sony XPeria Z. Въпреки това, което Camera.getParameters().getSupportedPreviewFpsRange() връща, тези телефони всъщност поддържат само 15/24/30fps (S5) и 15/30fps (Xperia Z) за действителни видеозаписи на MediaRecorder чрез mMediaRecorder.setVideoFrameRate().

Може би уликата тук е думата "Преглед" в името на метода getSupportedPreviewFpsRange() и върнатите стойности се отнасят САМО за повърхност за предварителен преглед. Може би разработчиците на Samsung и Sony за тези телефони са приели това име на метода твърде буквално и връщат само стойности на Preview fps, оставяйки разработчика да отгатне кадровите честоти на видеото; Открих по трудния начин, че изглежда изобщо няма начин да разбера какви FPS стойности се поддържат за видеозапис с MediaRecorder.

Повечето телефони изглежда заместват стойността „OK“ за setVideoFrameRate(), ако предоставената стойност не се поддържа, като по този начин предпазва разработчика от необходимостта да гадае какви са поддържаните скорости. S5 и Z (и вероятно други) просто сляпо вземат каквато и да е стойност, зададена в setVideoFrameRate() и след това услужливо се сриват с грешка -19, ако стойността, която сте избрали, не се поддържа. Както @Madhava Jay посочва в публикацията си, „не виждам начин да определя [честотата на кадрите], без просто да гадая“.

Може да се окаже, че камерата може да поддържа диапазон от кадрови честоти, но изпълнението на MediaRecorder от Sony и Samsung е недостатъчно, тъй като не може да приеме тези честоти.

Топ неща Android!

person DDSports    schedule 23.03.2015