diff --git a/entry/src/main/cpp/capbilities/AudioDecoder.cpp b/entry/src/main/cpp/capbilities/AudioDecoder.cpp index 4d429e7d912ce9ad5f1b38ea4d590e006d9b70f8..1e61e17c7b6bc325c0f34b14b174ecccd7886728 100644 --- a/entry/src/main/cpp/capbilities/AudioDecoder.cpp +++ b/entry/src/main/cpp/capbilities/AudioDecoder.cpp @@ -14,6 +14,7 @@ */ #include "AudioDecoder.h" +#include "dfx/error/AVCodecSampleError.h" #undef LOG_TAG #define LOG_TAG "AudioDecoder" @@ -49,10 +50,9 @@ int32_t AudioDecoder::Configure(const SampleInfo &sampleInfo) { int ret = OH_AudioCodec_Configure(decoder_, format); AVCODEC_SAMPLE_LOGI("====== AudioDecoder config ======"); - CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); OH_AVFormat_Destroy(format); format = nullptr; - + CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); return AVCODEC_SAMPLE_ERR_OK; } diff --git a/entry/src/main/cpp/capbilities/Muxer.cpp b/entry/src/main/cpp/capbilities/Muxer.cpp index 59eb4abb4a65167339907c0edec07c8967443333..fec20da8fda31170c9b9b1d102b1e9749caf51a9 100644 --- a/entry/src/main/cpp/capbilities/Muxer.cpp +++ b/entry/src/main/cpp/capbilities/Muxer.cpp @@ -14,6 +14,7 @@ */ #include "Muxer.h" +#include "dfx/error/AVCodecSampleError.h" #undef LOG_TAG #define LOG_TAG "Muxer" @@ -55,10 +56,11 @@ int32_t Muxer::Config(SampleInfo &sampleInfo) OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_MATRIX_COEFFICIENTS, sampleInfo.matrix); } - int32_t ret = OH_AVMuxer_AddTrack(muxer_, &videoTrackId_, formatVideo); - CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "AddTrack failed"); + int32_t ret = OH_AVMuxer_AddTrack(muxer_, &videoTrackId_, formatVideo); OH_AVFormat_Destroy(formatVideo); + formatVideo = nullptr; OH_AVMuxer_SetRotation(muxer_, sampleInfo.videoHeight > sampleInfo.videoWidth ? VERTICAL_ANGLE : HORIZONTAL_ANGLE); + CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "AddTrack failed"); return AVCODEC_SAMPLE_ERR_OK; } diff --git a/entry/src/main/cpp/capbilities/VideoDecoder.cpp b/entry/src/main/cpp/capbilities/VideoDecoder.cpp index 879b372758043ae58e378919110b3286857f8234..5ae314b2b83885d4f99394cf4c314beb768c02fe 100644 --- a/entry/src/main/cpp/capbilities/VideoDecoder.cpp +++ b/entry/src/main/cpp/capbilities/VideoDecoder.cpp @@ -65,10 +65,9 @@ int32_t VideoDecoder::Configure(const SampleInfo &sampleInfo) AVCODEC_SAMPLE_LOGI("====== VideoDecoder config ======"); int ret = OH_VideoDecoder_Configure(decoder_, format); - CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); OH_AVFormat_Destroy(format); format = nullptr; - + CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); return AVCODEC_SAMPLE_ERR_OK; } diff --git a/entry/src/main/cpp/capbilities/VideoEncoder.cpp b/entry/src/main/cpp/capbilities/VideoEncoder.cpp index ac2c5560443859811fa7b34a74d93c435399c3b8..734270237f417964e69cc77d13085d71649c3e86 100644 --- a/entry/src/main/cpp/capbilities/VideoEncoder.cpp +++ b/entry/src/main/cpp/capbilities/VideoEncoder.cpp @@ -164,9 +164,9 @@ int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) AVCODEC_SAMPLE_LOGI("====== VideoEncoder config ======"); int ret = OH_VideoEncoder_Configure(encoder_, format); - CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); OH_AVFormat_Destroy(format); format = nullptr; + CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); return AVCODEC_SAMPLE_ERR_OK; } @@ -180,5 +180,13 @@ 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/cpp/capbilities/include/AudioDecoder.h b/entry/src/main/cpp/capbilities/include/AudioDecoder.h index 6d89f32655b1b9b0b1644dd0c83a611d685daf82..8534042798b77aa2fe78687c1d6a0a82bcf0a504 100644 --- a/entry/src/main/cpp/capbilities/include/AudioDecoder.h +++ b/entry/src/main/cpp/capbilities/include/AudioDecoder.h @@ -19,7 +19,6 @@ #include "multimedia/player_framework/native_avcodec_audiocodec.h" #include "multimedia/player_framework/native_avbuffer_info.h" #include "SampleCallback.h" -#include "dfx/error/AVCodecSampleError.h" #include "AVCodecSampleLog.h" class AudioDecoder { diff --git a/entry/src/main/cpp/capbilities/include/Muxer.h b/entry/src/main/cpp/capbilities/include/Muxer.h index 8354a9cdbfcd730cabcb03a96c18a9e12f12949a..93b5b4c208ec0c3040f53f0963d9b8b1591e7d97 100644 --- a/entry/src/main/cpp/capbilities/include/Muxer.h +++ b/entry/src/main/cpp/capbilities/include/Muxer.h @@ -19,7 +19,6 @@ #include #include "multimedia/player_framework/native_avmuxer.h" #include "SampleInfo.h" -#include "dfx/error/AVCodecSampleError.h" #include "AVCodecSampleLog.h" class Muxer { diff --git a/entry/src/main/cpp/sample/player/Player.cpp b/entry/src/main/cpp/sample/player/Player.cpp index 7f89adc503c715ca3c92e2bb94f04dfdec7dcc9b..535c661eec2795ef6ee18a9d4a29e2cfdc15733f 100644 --- a/entry/src/main/cpp/sample/player/Player.cpp +++ b/entry/src/main/cpp/sample/player/Player.cpp @@ -53,11 +53,7 @@ int32_t Player::CreateAudioDecoder() { sampleInfo_.audioChannelCount); OH_AudioRenderer_Callbacks callbacks; // Configure the callback function -#ifndef DEBUG_DECODE callbacks.OH_AudioRenderer_OnWriteData = SampleCallback::OnRenderWriteData; -#else - callbacks.OH_AudioRenderer_OnWriteData = nullptr; -#endif callbacks.OH_AudioRenderer_OnStreamEvent = SampleCallback::OnRenderStreamEvent; callbacks.OH_AudioRenderer_OnInterruptEvent = SampleCallback::OnRenderInterruptEvent; callbacks.OH_AudioRenderer_OnError = SampleCallback::OnRenderError; @@ -83,7 +79,7 @@ int32_t Player::CreateVideoDecoder() { } int32_t Player::Init(SampleInfo &sampleInfo) { - std::lock_guard lock(mutex_); + std::unique_lock lock(mutex_); CHECK_AND_RETURN_RET_LOG(!isStarted_, AVCODEC_SAMPLE_ERR_ERROR, "Already started."); CHECK_AND_RETURN_RET_LOG(demuxer_ == nullptr && videoDecoder_ == nullptr && audioDecoder_ == nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Already started."); @@ -93,53 +89,69 @@ int32_t Player::Init(SampleInfo &sampleInfo) { videoDecoder_ = std::make_unique(); audioDecoder_ = std::make_unique(); demuxer_ = std::make_unique(); - - int32_t ret = demuxer_->Create(sampleInfo_); - CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, ret, "Create demuxer failed"); - - ret = CreateAudioDecoder(); - CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, ret, "Create audio decoder failed"); - - ret = CreateVideoDecoder(); - CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, ret, "Create video decoder failed"); - isReleased_ = false; + int32_t ret = demuxer_->Create(sampleInfo_); + if ( ret == AVCODEC_SAMPLE_ERR_OK) { + ret = CreateAudioDecoder(); + } else { + AVCODEC_SAMPLE_LOGE("Create demuxer failed"); + } + + if ( ret == AVCODEC_SAMPLE_ERR_OK) { + ret = CreateVideoDecoder(); + } else { + AVCODEC_SAMPLE_LOGE("Create audio decoder failed"); + } + + if (ret != AVCODEC_SAMPLE_ERR_OK) { + AVCODEC_SAMPLE_LOGE("Create video decoder failed"); + doneCond_.notify_all(); + lock.unlock(); + StartRelease(); + return AVCODEC_SAMPLE_ERR_ERROR; + } AVCODEC_SAMPLE_LOGI("Succeed"); return AVCODEC_SAMPLE_ERR_OK; } int32_t Player::Start() { - std::lock_guard lock(mutex_); + std::unique_lock lock(mutex_); int32_t ret; CHECK_AND_RETURN_RET_LOG(!isStarted_, AVCODEC_SAMPLE_ERR_ERROR, "Already started."); CHECK_AND_RETURN_RET_LOG(demuxer_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Already started."); if (videoDecContext_) { ret = videoDecoder_->Start(); - CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, ret, "Video Decoder start failed"); + if (ret != AVCODEC_SAMPLE_ERR_OK) { + AVCODEC_SAMPLE_LOGE("Video Decoder start failed"); + lock.unlock(); + StartRelease(); + return AVCODEC_SAMPLE_ERR_ERROR; + } isStarted_ = true; videoDecInputThread_ = std::make_unique(&Player::VideoDecInputThread, this); videoDecOutputThread_ = std::make_unique(&Player::VideoDecOutputThread, this); if (videoDecInputThread_ == nullptr || videoDecOutputThread_ == nullptr) { AVCODEC_SAMPLE_LOGE("Create thread failed"); + lock.unlock(); StartRelease(); return AVCODEC_SAMPLE_ERR_ERROR; } } if (audioDecContext_) { ret = audioDecoder_->Start(); - CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, ret, "Audio Decoder start failed"); + if (ret != AVCODEC_SAMPLE_ERR_OK) { + AVCODEC_SAMPLE_LOGE("Audio Decoder start failed"); + lock.unlock(); + StartRelease(); + return AVCODEC_SAMPLE_ERR_ERROR; + } isStarted_ = true; audioDecInputThread_ = std::make_unique(&Player::AudioDecInputThread, this); audioDecOutputThread_ = std::make_unique(&Player::AudioDecOutputThread, this); -#ifdef DEBUG_DECODE - // for debug The decoded data is written to the sandbox address, and the physical address is - // /data/app/el2/100/base/com.example.avcodecsample/haps/entry/files/ - audioOutputFile_.open("/data/storage/el2/base/haps/entry/files/audio_decode_out.pcm", - std::ios::out | std::ios::binary); -#endif if (audioDecInputThread_ == nullptr || audioDecOutputThread_ == nullptr) { AVCODEC_SAMPLE_LOGE("Create thread failed"); + lock.unlock(); StartRelease(); return AVCODEC_SAMPLE_ERR_ERROR; } @@ -157,6 +169,7 @@ int32_t Player::Start() { } void Player::StartRelease() { + AVCODEC_SAMPLE_LOGI("start release"); if (audioRenderer_) { OH_AudioRenderer_Stop(audioRenderer_); } @@ -197,11 +210,6 @@ void Player::Release() { OH_AudioRenderer_Release(audioRenderer_); audioRenderer_ = nullptr; } -#ifdef DEBUG_DECODE - if (audioOutputFile_.is_open()) { - audioOutputFile_.close(); - } -#endif ReleaseThread(); if (demuxer_ != nullptr) { @@ -334,13 +342,6 @@ void Player::AudioDecOutputThread() { for (int i = 0; i < bufferInfo.attr.size; i++) { audioDecContext_->renderQueue.push(*(source + i)); } -#ifdef DEBUG_DECODE - if (audioOutputFile_.is_open()) { - audioOutputFile_.write( - (const char *)OH_AVBuffer_GetAddr(reinterpret_cast(bufferInfo.buffer)), - bufferInfo.attr.size); - } -#endif lock.unlock(); int32_t ret = audioDecoder_->FreeOutputBuffer(bufferInfo.bufferIndex, true); diff --git a/entry/src/main/cpp/sample/player/Player.h b/entry/src/main/cpp/sample/player/Player.h index a45ee8d128d7e7875c0124232d4a29c8b3aac9ea..1359093bd2c840bf5f12867dbe731635fd3d038d 100644 --- a/entry/src/main/cpp/sample/player/Player.h +++ b/entry/src/main/cpp/sample/player/Player.h @@ -73,9 +73,6 @@ private: CodecUserData *audioDecContext_ = nullptr; OH_AudioStreamBuilder *builder_ = nullptr; OH_AudioRenderer *audioRenderer_ = nullptr; -#ifdef DEBUG_DECODE - std::ofstream audioOutputFile_; // for debug -#endif static constexpr int64_t MICROSECOND = 1000000; }; diff --git a/entry/src/main/cpp/sample/player/PlayerNative.cpp b/entry/src/main/cpp/sample/player/PlayerNative.cpp index c5e598c7b2f96fe1c939a34e0f315ac0edb3960c..ef2262c519cfd1b7eba2231a1602deac46d9a5d3 100644 --- a/entry/src/main/cpp/sample/player/PlayerNative.cpp +++ b/entry/src/main/cpp/sample/player/PlayerNative.cpp @@ -36,11 +36,11 @@ void Callback(void *asyncContext) { [](uv_work_t *work, int status) { CallbackContext *context = (CallbackContext *)work->data; napi_handle_scope scope = nullptr; - // 管理 napi_value 的生命周期,防止内存泄露 + // Manage the lifecycle of napi_value to prevent memory leaks. napi_open_handle_scope(context->env, &scope); napi_value callback = nullptr; napi_get_reference_value(context->env, context->callbackRef, &callback); - // 回调至UI侧 + // Callback to UI side. napi_call_function(context->env, nullptr, callback, 0, nullptr, nullptr); napi_close_handle_scope(context->env, scope); delete context; @@ -66,8 +66,10 @@ napi_value PlayerNative::Play(napi_env env, napi_callback_info info) { sampleInfo.playDoneCallback = &Callback; sampleInfo.playDoneCallbackData = asyncContext; - Player::GetInstance().Init(sampleInfo); - Player::GetInstance().Start(); + int32_t ret = Player::GetInstance().Init(sampleInfo); + if (ret == AVCODEC_SAMPLE_ERR_OK) { + Player::GetInstance().Start(); + } return nullptr; } diff --git a/entry/src/main/ets/common/utils/CameraCheck.ets b/entry/src/main/ets/common/utils/CameraCheck.ets index 0f102517a616caa2b4924281bb922db492a3ba3d..8b1384a0009b6ded4d6fc5ba977d9e31312cf96e 100644 --- a/entry/src/main/ets/common/utils/CameraCheck.ets +++ b/entry/src/main/ets/common/utils/CameraCheck.ets @@ -20,7 +20,57 @@ 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 + } + }); + Logger.error(TAG, `profile.format: ${previewProfile!.size.width}`); + 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(TAG, "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(TAG, '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 56f63f50c300d72ac14b94117fc8bb68222d3a4d..9adab6b39117ac8ae8cc7979f978bb7d47ea59e3 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 1d48c9a57162d98f2bb44cf74616a167e518f58d..15b550187662c913ba5d584692265d7b8aeb6cf1 100644 --- a/entry/src/main/ets/pages/Recorder.ets +++ b/entry/src/main/ets/pages/Recorder.ets @@ -17,12 +17,13 @@ import { camera } from '@kit.CameraKit'; import { fileIo } from '@kit.CoreFileKit'; import { display, router } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; +import { colorSpaceManager } from '@kit.ArkGraphics2D'; import recorder from 'librecorder.so'; 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'; const TAG: string = Const.RECORDER_TAG; @@ -59,6 +60,58 @@ 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) { + // Failed to return error code error. code and handle it. + let err = error as BusinessError; + Logger.error(TAG, `The isVideoStabilizationModeSupported call failed. error code: ${err.code}`); + } + return isSupported; +} + +function setVideoStabilizationMode(session: camera.VideoSession): boolean { + let mode: camera.VideoStabilizationMode = camera.VideoStabilizationMode.AUTO; + // Check if video stabilization is supported. + let isSupported: boolean = isVideoStabilizationModeSupported(session, mode); + if (isSupported) { + Logger.info(TAG, `setVideoStabilizationMode: ${mode}`); + session.setVideoStabilizationMode(mode); + let activeVideoStabilizationMode = session.getActiveVideoStabilizationMode(); + Logger.info(TAG, `activeVideoStabilizationMode: ${activeVideoStabilizationMode}`); + } else { + Logger.info(TAG, `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; + Logger.error(TAG, `The getSupportedColorSpaces call failed. error code: ${err.code}`); + } + return colorSpaces; +} + +function setColorSpaceBeforeCommitConfig(session: camera.VideoSession, isHdr: number): 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) { + Logger.info(TAG, `setColorSpace: ${colorSpace}`); + session.setColorSpace(colorSpace); + let activeColorSpace:colorSpaceManager.ColorSpace = session.getActiveColorSpace(); + Logger.info(TAG, `activeColorSpace: ${activeColorSpace}`); + } else { + Logger.info(TAG, `colorSpace: ${colorSpace} is not support`); + } +} + @Entry @Component struct Recorder { @@ -130,20 +183,28 @@ struct Recorder { return; } - let videoProfile: undefined | camera.VideoProfile = cameraCheck(cameraManager, params); + // Get supported modes. + 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; } - //Create the encoder output object + // Create the encoder output object encoderVideoOutput = cameraManager.createVideoOutput(videoProfile, params.surfaceId); if (encoderVideoOutput === undefined) { Logger.error(TAG, 'encoderVideoOutput is undefined'); @@ -230,6 +291,12 @@ struct Recorder { Logger.error(TAG, `videoSession commitConfig error: ${JSON.stringify(err)}`); } + // Set video stabilization. + if (setVideoStabilizationMode(videoSession)) { + // Set color space. + setColorSpaceBeforeCommitConfig(videoSession, params.isHDRVivid); + } + // Session start. try { await videoSession.start();