1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import deviceInfo from '@ohos.deviceInfo'; 17import type camera from '@ohos.multimedia.camera'; 18import { Log } from '../utils/Log'; 19 20const TAG = '[CameraPlatformCapability]:'; 21 22export class CameraPlatformCapability { 23 public mZoomRatioRangeMap = new Map(); 24 public mPhotoPreviewSizeMap = new Map(); 25 public mVideoPreviewSizeMap = new Map(); 26 public mImageSizeMap = new Map(); 27 public mVideoFrameSizeMap = new Map(); 28 public mCameraCount = 0; 29 // TODO 需要针对不同设备固定不同的值 30 public mPhotoPreviewSize = [ 31 { width: 640, height: 480 }, //Photo 4:3 32 { width: 720, height: 720 }, //Photo 1:1 33 { width: 1920, height: 1080 },//Photo 16:9 34 ] 35 public mVideoPreviewSize = [ 36 { width: 1280, height: 720 }, //Video 16:9 720p 37 { width: 1920, height: 1080 }, //Video 16:9 1080p 38 { width: 1920, height: 1080 }//Video 16:9 4k 39 ] 40 public mImageSize = [ 41 { width: 1280, height: 960 }, //4:3 42 { width: 3120, height: 3120 }, //1:1 43 { width: 1920, height: 1080 }//16:9 44 ] 45 public mVideoFrameSize = [ 46 { width: 1280, height: 720 }, //16:9 720p 47 { width: 1920, height: 1080 }, //16:9 1080p 48 { width: 3840, height: 2160 }//16:9 4k 49 ] 50 51 constructor() { 52 } 53 54 public static getInstance(): CameraPlatformCapability { 55 if (!globalThis?.sInstanceCapability) { 56 globalThis.sInstanceCapability = new CameraPlatformCapability(); 57 } 58 return globalThis.sInstanceCapability; 59 } 60 61 public async init(cameraCount: number) { 62 Log.info(`${TAG} init E.`); 63 this.mCameraCount = cameraCount; 64 Log.info(`${TAG} init X.`); 65 } 66 67 public async calcSupportedSizes(cameraInput, outputCapability: camera.CameraOutputCapability): Promise<void> { 68 Log.info(`${TAG} calcSupportedSizes start.`); 69 if (deviceInfo.deviceType == 'default') { 70 return; 71 } 72 const photoSize = outputCapability.photoProfiles; //CAMERA_FORMAT_JPEG 73 const previewCurSize = outputCapability.previewProfiles; //CAMERA_FORMAT_YCRCb_420_SP 74 75 this.mImageSize[0] = this.getMaxSize(photoSize, 4, 3); 76 this.mImageSize[1] = this.getMaxSize(photoSize, 1, 1); 77 this.mImageSize[2] = this.getMaxSize(photoSize, 16, 9); 78 this.mPhotoPreviewSize[0] = this.getMaxSize(previewCurSize, 4, 3); 79 this.mPhotoPreviewSize[1] = this.getMaxSize(previewCurSize, 1, 1); 80 this.mPhotoPreviewSize[2] = this.getMaxSize(previewCurSize, 16, 9); 81 82 this.mVideoFrameSize[0] = this.getSpecifiedSize(previewCurSize, 1280, 720); 83 this.mVideoFrameSize[1] = this.getSpecifiedSize(previewCurSize, 1920, 1080); 84 this.mVideoFrameSize[2] = this.getSpecifiedSize(previewCurSize, 3840, 2160); 85 this.mVideoPreviewSize[0] = this.mVideoFrameSize[0]; 86 this.mVideoPreviewSize[1] = this.mVideoFrameSize[1]; 87 this.mVideoPreviewSize[2] = this.mVideoFrameSize[2]; 88 Log.info(`${TAG} calcSupportedSizes end.`); 89 } 90 91 public async getZoomRatioRange(captureSession) { 92 Log.info(`${TAG} getZoomRatioRange called`); 93 const zoomRatioRange = await captureSession.getZoomRatioRange(); 94 Log.info(`${TAG} zoomRatioRange= ${zoomRatioRange}`); 95 return zoomRatioRange; 96 } 97 98 private getMaxSize(sizeList, width: number, height: number) { 99 const maxSize = { width: 0, height: 0 }; 100 const fitList = []; 101 for (let i = 0; i < sizeList.length; i++) { 102 const errorValue = sizeList[i].size.width * height - sizeList[i].size.height * width; 103 if (errorValue <= 4 && errorValue >= -4) { 104 fitList.push(sizeList[i]); 105 } 106 } 107 if (fitList.length == 0) { 108 Log.error(`${TAG} calc failed based on the supportedSizesList, try default value.`); 109 maxSize.width = 640; 110 maxSize.height = 480; 111 Log.info(`${TAG} -----------SupportedSizes List Start-----------`); 112 for (let i = 0; i < sizeList.length; i++) { 113 Log.info(`${TAG} supportedSize width: ${sizeList[i].size.width} height: ${sizeList[i].size.height}`); 114 } 115 Log.info(`${TAG} -----------SupportedSizes List End-----------`); 116 return maxSize; 117 } else { 118 const index = Math.floor(fitList.length / 2); 119 maxSize.width = fitList[index].size.width; 120 maxSize.height = fitList[index].size.height; 121 } 122 return maxSize; 123 } 124 125 private getSpecifiedSize(sizeList, width: number, height: number) { 126 const specifiedSize = { width: 0, height: 0 }; 127 for (let i = 0; i < sizeList.length; i++) { 128 const widthError = sizeList[i].size.width - width; 129 const heightError = sizeList[i].size.height - height; 130 if (widthError <= 4 && widthError >= -4 && heightError <= 4 && heightError >= -4) { 131 if (sizeList[i].size.width > specifiedSize.width) { 132 specifiedSize.width = sizeList[i].size.width; 133 specifiedSize.height = sizeList[i].size.height; 134 } 135 } 136 } 137 if (specifiedSize.width == 0) { 138 Log.error(`${TAG} calc failed based on the supportedSizesList, try default value.`); 139 specifiedSize.width = 1920; 140 specifiedSize.height = 1080; 141 } 142 return specifiedSize; 143 } 144}