From a4f1ad741316728184e68ccab9c06a8ba809d124 Mon Sep 17 00:00:00 2001 From: ouyang Date: Fri, 17 Jan 2025 16:07:02 +0800 Subject: [PATCH] =?UTF-8?q?HDRVivid=E5=BD=95=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/cpp/capbilities/VideoEncoder.cpp | 7 ++ .../src/main/ets/common/utils/CameraCheck.ets | 48 +++++++++++- entry/src/main/ets/pages/Index.ets | 4 +- entry/src/main/ets/pages/Recorder.ets | 76 ++++++++++++++++++- 4 files changed, 128 insertions(+), 7 deletions(-) diff --git a/entry/src/main/cpp/capbilities/VideoEncoder.cpp b/entry/src/main/cpp/capbilities/VideoEncoder.cpp index ac2c556..2030718 100644 --- a/entry/src/main/cpp/capbilities/VideoEncoder.cpp +++ b/entry/src/main/cpp/capbilities/VideoEncoder.cpp @@ -180,5 +180,12 @@ int32_t VideoEncoder::GetSurface(SampleInfo &sampleInfo) (void)OH_NativeWindow_NativeWindowHandleOpt(sampleInfo.window, SET_USAGE, 16425); // 16425: Window usage (void)OH_NativeWindow_NativeWindowHandleOpt(sampleInfo.window, SET_FORMAT, ToGraphicPixelFormat(sampleInfo.pixelFormat, sampleInfo.isHDRVivid)); + if(sampleInfo.isHDRVivid) { + uint8_t metadataType = OH_VIDEO_HDR_HLG; + (void)OH_NativeWindow_SetMetadataValue(sampleInfo.window, OH_HDR_METADATA_TYPE, sizeof(uint8_t), &metadataType); + (void)OH_NativeWindow_NativeWindowHandleOpt(sampleInfo.window, SET_COLOR_GAMUT, NATIVEBUFFER_COLOR_GAMUT_BT2020); + OH_NativeBuffer_ColorSpace colorSpace = OH_COLORSPACE_BT2020_HLG_LIMIT; + (void)OH_NativeWindow_SetColorSpace(sampleInfo.window, colorSpace); + } return AVCODEC_SAMPLE_ERR_OK; } \ No newline at end of file diff --git a/entry/src/main/ets/common/utils/CameraCheck.ets b/entry/src/main/ets/common/utils/CameraCheck.ets index 0f10251..2884907 100644 --- a/entry/src/main/ets/common/utils/CameraCheck.ets +++ b/entry/src/main/ets/common/utils/CameraCheck.ets @@ -20,7 +20,53 @@ import { CommonConstants as Const } from '../CommonConstants'; const TAG = 'CAMERA_CHECK'; -export function cameraCheck(cameraManager: camera.CameraManager, +function getPreviewProfile(previewProfiles: Array, size: camera.Size, isHDRVivid: number): undefined | camera.Profile { + let previewProfile: undefined | camera.Profile = previewProfiles.find((profile: camera.Profile) => { + if(isHDRVivid) { + return profile.format === camera.CameraFormat.CAMERA_FORMAT_YCRCB_P010 && + profile.size.width === size.width && profile.size.height == size.height + } else { + return profile.format === camera.CameraFormat.CAMERA_FORMAT_YUV_420_SP && + profile.size.width === size.width && profile.size.height == size.height + } + }); + return previewProfile; +} + +export function previewProfileCameraCheck(cameraManager: camera.CameraManager, + cameraData: CameraDataModel): undefined | camera.Profile { + let cameraDevices = cameraManager.getSupportedCameras(); + if (cameraDevices !== undefined && cameraDevices.length <= 0) { + Logger.error(TAG, 'cameraManager.getSupportedCameras error!'); + return; + } + + let profiles: camera.CameraOutputCapability = + cameraManager.getSupportedOutputCapability(cameraDevices[0], camera.SceneMode.NORMAL_VIDEO); + if (!profiles) { + Logger.error(TAG, 'cameraManager.getSupportedOutputCapability error!'); + return; + } + + let previewProfilesArray: Array = profiles.previewProfiles; + if (!previewProfilesArray) { + Logger.error("createOutput previewProfilesArray == null || undefined"); + return; + } + + let videoSize: camera.Size = { + width: 1920, + height: 1080 + } + let previewProfile: undefined | camera.Profile = getPreviewProfile(previewProfilesArray, videoSize, cameraData.isHDRVivid); + if (!previewProfile) { + Logger.error('previewProfile is not found'); + return; + } + return previewProfile; +} + +export function videoProfileCheck(cameraManager: camera.CameraManager, cameraData: CameraDataModel): undefined | camera.VideoProfile { let cameraDevices = cameraManager.getSupportedCameras(); if (cameraDevices !== undefined && cameraDevices.length <= 0) { diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 56f63f5..9adab6b 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -23,7 +23,7 @@ import Logger from '../common/utils/Logger'; import DateTimeUtil from '../common/utils/DateTimeUtils'; import { CommonConstants as Const } from '../common/CommonConstants'; import { CameraDataModel } from '../model/CameraDateModel'; -import { cameraCheck } from '../common/utils/CameraCheck'; +import { videoProfileCheck } from '../common/utils/CameraCheck'; const TAG: string = Const.INDEX_TAG; const DATETIME: DateTimeUtil = new DateTimeUtil(); @@ -82,7 +82,7 @@ struct Player { Logger.error(TAG, 'camera.getCameraManager error!'); } - let videoProfile: undefined | camera.VideoProfile = cameraCheck(cameraManager, this.cameraData); + let videoProfile: undefined | camera.VideoProfile = videoProfileCheck(cameraManager, this.cameraData); if (!videoProfile) { Logger.error(TAG, 'videoProfile is not found'); promptAction.showToast({ diff --git a/entry/src/main/ets/pages/Recorder.ets b/entry/src/main/ets/pages/Recorder.ets index 1d48c9a..0c049c0 100644 --- a/entry/src/main/ets/pages/Recorder.ets +++ b/entry/src/main/ets/pages/Recorder.ets @@ -22,7 +22,8 @@ import Logger from '../common/utils/Logger'; import { dateTime } from '../common/utils/DateTimeUtils'; import { CommonConstants as Const } from '../common/CommonConstants'; import { CameraDataModel } from '../model/CameraDateModel'; -import { cameraCheck } from '../common/utils/CameraCheck'; +import { previewProfileCameraCheck, videoProfileCheck } from '../common/utils/CameraCheck'; +import { colorSpaceManager } from '@kit.ArkGraphics2D'; const TAG: string = Const.RECORDER_TAG; @@ -59,6 +60,59 @@ async function releaseCamera(): Promise { videoSession.release(); } +function isVideoStabilizationModeSupported(session: camera.VideoSession, mode: camera.VideoStabilizationMode): boolean { + let isSupported: boolean = false; + try { + isSupported = session.isVideoStabilizationModeSupported(mode); + } catch (error) { + // 失败返回错误码error.code并处理 + let err = error as BusinessError; + console.error(`The isVideoStabilizationModeSupported call failed. error code: ${err.code}`); + } + return isSupported; +} + +function setVideoStabilizationMode(session: camera.VideoSession): boolean { + let mode: camera.VideoStabilizationMode = camera.VideoStabilizationMode.AUTO; + // 查询是否支持视频防抖 + let isSupported: boolean = isVideoStabilizationModeSupported(session, mode); + if (isSupported) { + console.info(`setVideoStabilizationMode: ${mode}`); + // 设置视频防抖 + session.setVideoStabilizationMode(mode); + let activeVideoStabilizationMode = session.getActiveVideoStabilizationMode(); + console.info(`activeVideoStabilizationMode: ${activeVideoStabilizationMode}`); + } else { + console.info(`videoStabilizationMode: ${mode} is not support`); + } + return isSupported; +} + +function getSupportedColorSpaces(session: camera.VideoSession): Array { + let colorSpaces: Array = []; + try { + colorSpaces = session.getSupportedColorSpaces(); + } catch (error) { + let err = error as BusinessError; + console.error(`The getSupportedColorSpaces call failed. error code: ${err.code}`); + } + return colorSpaces; +} + +function setColorSpaceBeforeCommitConfig(session: camera.VideoSession, isHdr: boolean): void { + let colorSpace: colorSpaceManager.ColorSpace = isHdr? colorSpaceManager.ColorSpace.BT2020_HLG_LIMIT : colorSpaceManager.ColorSpace.BT709_LIMIT; + let colorSpaces: Array = getSupportedColorSpaces(session); + let isSupportedColorSpaces = colorSpaces.indexOf(colorSpace) >= 0; + if (isSupportedColorSpaces) { + console.info(`setColorSpace: ${colorSpace}`); + session.setColorSpace(colorSpace); + let activeColorSpace:colorSpaceManager.ColorSpace = session.getActiveColorSpace(); + console.info(`activeColorSpace: ${activeColorSpace}`); + } else { + console.info(`colorSpace: ${colorSpace} is not support`); + } +} + @Entry @Component struct Recorder { @@ -130,14 +184,22 @@ struct Recorder { return; } - let videoProfile: undefined | camera.VideoProfile = cameraCheck(cameraManager, params); + // 获取支持的模式类型 + let sceneModes: Array = cameraManager.getSupportedSceneModes(cameraDevices[0]); + let isSupportVideoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_VIDEO) >= 0; + if (!isSupportVideoMode) { + Logger.error('video mode not support'); + return; + } + + let videoProfile: undefined | camera.VideoProfile = videoProfileCheck(cameraManager, params); if (!videoProfile) { Logger.error(TAG, 'videoProfile is not found!'); return; } - //The preview stream of XComponent. - let XComponentPreviewProfile: camera.Profile = params.previewProfile; + // The preview stream of XComponent. + let XComponentPreviewProfile: camera.Profile | undefined = previewProfileCameraCheck(cameraManager, params) if (XComponentPreviewProfile === undefined) { Logger.error(TAG, 'XComponentPreviewProfile is not found'); return; @@ -230,6 +292,12 @@ struct Recorder { Logger.error(TAG, `videoSession commitConfig error: ${JSON.stringify(err)}`); } + // 设置视频防抖 + if (setVideoStabilizationMode(videoSession)) { + // 设置色彩空间 + setColorSpaceBeforeCommitConfig(videoSession, true); + } + // Session start. try { await videoSession.start(); -- Gitee