记录一下遇到的RK camera2应用 开发过程中遇到支持1080P后部分不支持1080P的摄像头录像却使用1080P分辨率的BUG问题
本篇流程部分参考(43条消息) RK3588 camera2 支持4K录像_camera2 设置分辨率_开开心心everyday的博客-CSDN博客
packages/apps/Camera2/src/com/android/camera/VideoModule.java
private void initializeRecorder(){
...
//add by szw 2023.5.5 start
Camera camera = mCameraDevice.getCamera();
Camera.Parameters params = camera.getParameters();
List<Camera.Size> pictureSizes = params.getSupportedPictureSizes();
int length = pictureSizes.size(); //获取全部支持分辨率
for (int i = 0; i < length; i++) {
Log.e(TAG,"SupportedPictureSizes : " + pictureSizes.get(i).width + "x" + pictureSizes.get(i).height);
}
List<Camera.Size> previewSizes = params.getSupportedPreviewSizes();
length = previewSizes.size(); //获取全部支持分辨率
for (int i = 0; i < length; i++) {
Log.e(TAG,"SupportedPreviewSizes : " + previewSizes.get(i).width + "x" + previewSizes.get(i).height);
}
if (mCameraDevice == null) {
return;
}
mCameraSettings = mCameraDevice.getSettings();
Point desiredPreviewSize = getDesiredPreviewSize(mCameraCapabilities, mProfile, mUI.getPreviewScreenSize(), mActivity);
mDesiredPreviewWidth = desiredPreviewSize.x;
mDesiredPreviewHeight = desiredPreviewSize.y;
//读取设置分辨率,获取x与y的值
boolean released = camera.isReleased();
Log.d(TAG, "camera isReleased:" + released);
if (released) {
releaseMediaRecorder(); //必须在其之前去获取xy,否则会出现占用的情况导致无法打开camera
return;
}
mCameraDevice.unlock();
mMediaRecorder.setCamera(camera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
Log.d(TAG, "setProfile"+mProfile);
mMediaRecorder.setProfile(mProfile);
Log.d(TAG, "setVideoSize="+mDesiredPreviewWidth+"x"+mDesiredPreviewHeight);
mMediaRecorder.setVideoSize(mDesiredPreviewWidth,mDesiredPreviewHeight);
//此处更改了VideoSize的属性值,之前加载的为mProfile.videoFrameWidth/videoFrameHight
//摄像头预览正常但录像的分辨率在支持1080P后读到的为1080P,此处更改为与预览一致
Log.d(TAG, "setMaxDuration"+mMaxVideoDurationInMs);
mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
setRecordLocation();
}
以上为最核心的部分,实际上大部分相关代码都在VideoModule.java之中,其他有关预览的非录像相关的不在过多赘述,只提一下个人认为比较核心的部分;
packages/apps/Camera2/src/com/android/camera/settings/SettingsUtil.java
SelectedVideoQualities getSelectedVideoQualities(int cameraId) {
if (sCachedSelectedVideoQualities.get(cameraId) != null) {
return sCachedSelectedVideoQualities.get(cameraId);
}
// Go through the sizes in descending order, see if they are supported,
// and set large/medium/small accordingly.
// If no quality is supported at all, the first call to
// getNextSupportedQuality will throw an exception.
// If only one quality is supported, then all three selected qualities
// will be the same.
int largeIndex = getNextSupportedVideoQualityIndex(cameraId, -1);
int mediumIndex = getNextSupportedVideoQualityIndex(cameraId, largeIndex);
int smallIndex = getNextSupportedVideoQualityIndex(cameraId, mediumIndex);
Log.d(TAG,"largeIndex="+largeIndex+" sVideoQualities[largeIndex]"+sVideoQualities[largeIndex]);
SelectedVideoQualities selectedQualities = new SelectedVideoQualities();
selectedQualities.large = sVideoQualities[largeIndex];
selectedQualities.medium = sVideoQualities[mediumIndex];
selectedQualities.small = sVideoQualities[smallIndex];
sCachedSelectedVideoQualities.put(cameraId, selectedQualities);
return selectedQualities;
}
此处有获取大中小三个设置分辨率的对应分辨率
private static boolean isVideoQualitySupported(int videoQuality) {
// 4k is only supported on L or higher but some devices falsely report
// to have support for it on K, see b/18172081.
if (!ApiHelper.isLOrHigher() && videoQuality == CamcorderProfile.QUALITY_2160P) {
return false;
}
if (!ApiHelper.isLOrHigher() && videoQuality == CamcorderProfile.QUALITY_1080P) {
return false;
}
return true;
}
此处针对分辨率支持有做限制
packages/apps/Camera2/src/com/android/camera/settings/CameraSettingsActivity.java
private void setEntries(Preference preference) {
if (!(preference instanceof ListPreference)) {
return;
} ListPreference listPreference = (ListPreference) preference;
if (listPreference.getKey().equals(Keys.KEY_PICTURE_SIZE_BACK)) {
setEntriesForSelection(mPictureSizes.backCameraSizes, listPreference);
} else if (listPreference.getKey().equals(Keys.KEY_PICTURE_SIZE_FRONT)) {
setEntriesForSelection(mPictureSizes.frontCameraSizes, listPreference);
}else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_BACK)) {
String str = mPictureSizes.videoQualitiesBack.orNull().toString();
Log.d(TAG,"mPictureSizes.videoQualitiesBack.orNull()"+str);
setEntriesForSelection(mPictureSizes.videoQualitiesBack.orNull(), listPreference);
} else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_FRONT)) {
setEntriesForSelection(mPictureSizes.videoQualitiesFront.orNull(), listPreference);
} else if (listPreference.getKey().equals(Keys.KEY_ANTIBANDING)) {
listPreference.setEntries(mAntiBandingNames);
}
}
private void setEntriesForSelection(SelectedVideoQualities selectedQualities,
ListPreference preference) {
if (selectedQualities == null) {
return;
}
entries.add(mCamcorderProfileNames[selectedQualities.large]);
if (selectedQualities.medium != selectedQualities.large) {
entries.add(mCamcorderProfileNames[selectedQualities.medium]);
}
if (selectedQualities.small != selectedQualities.medium) {
entries.add(mCamcorderProfileNames[selectedQualities.small]);
}
preference.setEntries(entries.toArray(new String[0]));
}
setEntriesForSelection;