/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "dcamera_client_demo.h" using namespace OHOS; using namespace OHOS::Camera; using namespace OHOS::CameraStandard; using namespace OHOS::DistributedHardware; namespace OHOS { namespace DistributedHardware { constexpr double LOCATION_LATITUDE = 22.306; constexpr double LOCATION_LONGITUDE = 52.12; constexpr double LOCATION_ALTITUDE = 2.365; #ifdef DCAMERA_COMMON constexpr int32_t PHOTO_WIDTH = 1280; constexpr int32_t PHOTO_HEIGTH = 960; #else constexpr int32_t PHOTO_WIDTH = 1920; constexpr int32_t PHOTO_HEIGTH = 1080; #endif constexpr int32_t PREVIEW_WIDTH = 640; constexpr int32_t PREVIEW_HEIGTH = 480; constexpr int32_t VIDEO_WIDTH = 640; constexpr int32_t VIDEO_HEIGTH = 480; static sptr g_cameraInfo = nullptr; static sptr g_cameraManager = nullptr; static sptr g_cameraInput = nullptr; static sptr g_photoOutput = nullptr; static sptr g_previewOutput = nullptr; static sptr g_videoOutput = nullptr; static sptr g_captureSession = nullptr; static std::shared_ptr g_photoInfo = nullptr; static std::shared_ptr g_previewInfo = nullptr; static std::shared_ptr g_videoInfo = nullptr; #ifdef DCAMERA_COMMON constexpr int32_t PHOTO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_JPEG; constexpr int32_t PREVIEW_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888; constexpr int32_t VIDEO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888; #else constexpr int32_t PHOTO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_JPEG; constexpr int32_t PREVIEW_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP; constexpr int32_t VIDEO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP; #endif int32_t InitCameraStandard(CameraPosition position) { g_cameraManager = CameraManager::GetInstance(); g_cameraManager->SetCallback(std::make_shared()); int rv = g_cameraManager->CreateCaptureSession(&g_captureSession); if (rv != DCAMERA_OK) { DHLOGE("InitCameraStandard create captureSession failed, rv: %{public}d", rv); return rv; } std::shared_ptr sessionCallback = std::make_shared(); g_captureSession->SetCallback(sessionCallback); g_captureSession->SetFocusCallback(sessionCallback); std::vector> cameraObjList = g_cameraManager->GetSupportedCameras(); for (auto info : cameraObjList) { DHLOGI("Camera: %{public}s, position: %{public}d, camera type: %{public}d, connection type: %{public}d", GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType(), info->GetConnectionType()); // CAMERA_POSITION_BACK or CAMERA_POSITION_FRONT if ((info->GetPosition() == position) && (info->GetConnectionType() == ConnectionType::CAMERA_CONNECTION_REMOTE)) { g_cameraInfo = info; break; } } if (g_cameraInfo == nullptr) { DHLOGE("Distributed Camera Demo: have no remote camera"); return DCAMERA_BAD_VALUE; } rv = g_cameraManager->CreateCameraInput(g_cameraInfo, &((sptr &)g_cameraInput)); if (rv != DCAMERA_OK) { DHLOGE("InitCameraStandard create cameraInput failed, rv: %{public}d", rv); return rv; } int32_t ret = ((sptr &)g_cameraInput)->Open(); if (ret != DCAMERA_OK) { DHLOGE("InitCameraStandard g_cameraInput Open failed, ret: %{public}d", ret); return ret; } std::shared_ptr inputCallback = std::make_shared(); ((sptr &)g_cameraInput)->SetErrorCallback(inputCallback); return DCAMERA_OK; } void InitCaptureInfo(int32_t width, int32_t height) { g_photoInfo = std::make_shared(); g_photoInfo->width_ = PHOTO_WIDTH; g_photoInfo->height_ = PHOTO_HEIGTH; g_photoInfo->format_ = PHOTO_FORMAT; g_previewInfo = std::make_shared(); if (width == 0 && height == 0) { g_previewInfo->width_ = PREVIEW_WIDTH; g_previewInfo->height_ = PREVIEW_HEIGTH; } else { g_previewInfo->width_ = width; g_previewInfo->height_ = height; } g_previewInfo->format_ = PREVIEW_FORMAT; g_videoInfo = std::make_shared(); g_videoInfo->width_ = VIDEO_WIDTH; g_videoInfo->height_ = VIDEO_HEIGTH; g_videoInfo->format_ = VIDEO_FORMAT; } CameraFormat ConvertToCameraFormat(int32_t format) { CameraFormat ret = CameraFormat::CAMERA_FORMAT_INVALID; DCameraFormat df = static_cast(format); switch (df) { case DCameraFormat::OHOS_CAMERA_FORMAT_RGBA_8888: ret = CameraFormat::CAMERA_FORMAT_RGBA_8888; break; case DCameraFormat::OHOS_CAMERA_FORMAT_YCBCR_420_888: ret = CameraFormat::CAMERA_FORMAT_YCBCR_420_888; break; case DCameraFormat::OHOS_CAMERA_FORMAT_YCRCB_420_SP: ret = CameraFormat::CAMERA_FORMAT_YUV_420_SP; break; case DCameraFormat::OHOS_CAMERA_FORMAT_JPEG: ret = CameraFormat::CAMERA_FORMAT_JPEG; break; default: break; } return ret; } void InitPhotoOutput(void) { DHLOGI("Distributed Camera Demo: Create PhotoOutput, width = %{public}d, height = %{public}d, format = %{public}d", g_photoInfo->width_, g_photoInfo->height_, g_photoInfo->format_); sptr photoSurface = IConsumerSurface::Create(); sptr photoListener = new DemoDCameraPhotoSurfaceListener(photoSurface); photoSurface->RegisterConsumerListener(photoListener); CameraFormat photoFormat = ConvertToCameraFormat(g_photoInfo->format_); Size photoSize = {g_photoInfo->width_, g_photoInfo->height_}; Profile photoProfile(photoFormat, photoSize); sptr photoProducer = photoSurface->GetProducer(); int rv = g_cameraManager->CreatePhotoOutput(photoProfile, photoProducer, &((sptr &)g_photoOutput)); if (rv != DCAMERA_OK) { DHLOGE("InitPhotoOutput create photoOutput failed, rv: %{public}d", rv); return; } ((sptr &)g_photoOutput)->SetCallback(std::make_shared()); } void InitPreviewOutput(void) { DHLOGI("Distributed Camera Demo: Create PreviewOutput, width = %{public}d, height = %{public}d, format = " "%{public}d", g_previewInfo->width_, g_previewInfo->height_, g_previewInfo->format_); sptr previewSurface = IConsumerSurface::Create(); sptr previewListener = new DemoDCameraPreviewSurfaceListener(previewSurface); previewSurface->RegisterConsumerListener(previewListener); CameraFormat previewFormat = ConvertToCameraFormat(g_previewInfo->format_); Size previewSize = {g_previewInfo->width_, g_previewInfo->height_}; Profile previewProfile(previewFormat, previewSize); sptr previewProducer = previewSurface->GetProducer(); sptr previewProducerSurface = Surface::CreateSurfaceAsProducer(previewProducer); int rv = g_cameraManager->CreatePreviewOutput( previewProfile, previewProducerSurface, &((sptr &)g_previewOutput)); if (rv != DCAMERA_OK) { DHLOGE("InitPhotoOutput create previewOutput failed, rv: %{public}d", rv); return; } ((sptr &)g_previewOutput)->SetCallback(std::make_shared()); } void InitVideoOutput(void) { DHLOGI("Distributed Camera Demo: Create VideoOutput, width = %{public}d, height = %{public}d, format = %{public}d", g_videoInfo->width_, g_videoInfo->height_, g_videoInfo->format_); sptr videoSurface = IConsumerSurface::Create(); sptr videoListener = new DemoDCameraVideoSurfaceListener(videoSurface); videoSurface->RegisterConsumerListener(videoListener); CameraFormat videoFormat = ConvertToCameraFormat(g_videoInfo->format_); Size videoSize = {g_videoInfo->width_, g_videoInfo->height_}; std::vector framerates = {}; VideoProfile videoSettings(videoFormat, videoSize, framerates); sptr videoProducer = videoSurface->GetProducer(); sptr pSurface = Surface::CreateSurfaceAsProducer(videoProducer); int rv = g_cameraManager->CreateVideoOutput(videoSettings, pSurface, &((sptr &)g_videoOutput)); if (rv != DCAMERA_OK) { DHLOGE("InitPhotoOutput create videoOutput failed, rv: %{public}d", rv); return; } ((sptr &)g_videoOutput)->SetCallback(std::make_shared()); } void ConfigCaptureSession(void) { g_captureSession->BeginConfig(); g_captureSession->AddInput(g_cameraInput); g_captureSession->AddOutput(g_previewOutput); g_captureSession->AddOutput(g_videoOutput); g_captureSession->AddOutput(g_photoOutput); g_captureSession->CommitConfig(); std::vector stabilizationModes; int32_t rv = g_captureSession->GetSupportedStabilizationMode(stabilizationModes); if (rv != DCAMERA_OK) { DHLOGE("ConfigCaptureSession get supported stabilization mode failed, rv: %{public}d", rv); return; } if (!stabilizationModes.empty()) { for (auto mode : stabilizationModes) { DHLOGI("Distributed Camera Demo: video stabilization mode %{public}d", mode); } g_captureSession->SetVideoStabilizationMode(stabilizationModes.back()); } g_captureSession->Start(); } void ConfigFocusFlashAndExposure(bool isVideo) { g_captureSession->LockForControl(); FocusMode focusMode = FOCUS_MODE_CONTINUOUS_AUTO; ExposureMode exposureMode = EXPOSURE_MODE_AUTO; float exposureValue = 0; std::vector biasRange; int32_t rv = g_captureSession->GetExposureBiasRange(biasRange); if (rv != DCAMERA_OK) { DHLOGE("ConfigFocusAndExposure get exposure bias range failed, rv: %{public}d", rv); return; } if (!biasRange.empty()) { DHLOGI("Distributed Camera Demo: get %{public}d exposure compensation range", biasRange.size()); exposureValue = biasRange[0]; } FlashMode flash = FLASH_MODE_OPEN; if (isVideo) { flash = FLASH_MODE_ALWAYS_OPEN; } g_captureSession->SetFlashMode(flash); g_captureSession->SetFocusMode(focusMode); g_captureSession->SetExposureMode(exposureMode); g_captureSession->SetExposureBias(exposureValue); g_captureSession->UnlockForControl(); } std::shared_ptr ConfigPhotoCaptureSetting() { std::shared_ptr photoCaptureSettings = std::make_shared(); // Rotation PhotoCaptureSetting::RotationConfig rotation = PhotoCaptureSetting::RotationConfig::Rotation_0; photoCaptureSettings->SetRotation(rotation); // QualityLevel PhotoCaptureSetting::QualityLevel quality = PhotoCaptureSetting::QualityLevel::QUALITY_LEVEL_HIGH; photoCaptureSettings->SetQuality(quality); // Location std::unique_ptr location = std::make_unique(); location->latitude = LOCATION_LATITUDE; location->longitude = LOCATION_LONGITUDE; location->altitude = LOCATION_ALTITUDE; photoCaptureSettings->SetLocation(location); return photoCaptureSettings; } void ReleaseResource(void) { if (g_previewOutput != nullptr) { ((sptr &)g_previewOutput)->Stop(); g_previewOutput->Release(); g_previewOutput = nullptr; } if (g_photoOutput != nullptr) { g_photoOutput->Release(); g_photoOutput = nullptr; } if (g_videoOutput != nullptr) { g_videoOutput->Release(); g_videoOutput = nullptr; } if (g_cameraInput != nullptr) { g_cameraInput->Close(); g_cameraInput->Release(); g_cameraInput = nullptr; } if (g_captureSession != nullptr) { g_captureSession->Stop(); g_captureSession->Release(); g_captureSession = nullptr; } if (g_cameraManager != nullptr) { g_cameraManager->SetCallback(nullptr); } g_cameraInfo = nullptr; g_cameraManager = nullptr; } int32_t Capture() { int32_t ret = ((sptr &)g_photoOutput)->Capture(ConfigPhotoCaptureSetting()); if (ret != DCAMERA_OK) { DHLOGE("main g_photoOutput Capture failed, ret: %{public}d", ret); return ret; } return DCAMERA_OK; } int32_t Video() { int32_t ret = ((sptr &)g_videoOutput)->Start(); if (ret != DCAMERA_OK) { DHLOGE("main VideoOutput Start failed, ret: %{public}d", ret); return ret; } return DCAMERA_OK; } int32_t GetPreviewProfiles(std::vector &previewResolution) { sptr capability = g_cameraManager->GetSupportedOutputCapability(g_cameraInfo); if (capability == nullptr) { DHLOGI("get supported capability is null"); return DCAMERA_BAD_VALUE; } std::vector previewProfiles = capability->GetPreviewProfiles(); DHLOGI("size: %{public}d", previewProfiles.size()); for (auto& profile : previewProfiles) { CameraStandard::Size picSize = profile.GetSize(); DHLOGI("width: %{public}d, height: %{public}d", picSize.width, picSize.height); if (IsValid(picSize)) { previewResolution.push_back(picSize); } } return DCAMERA_OK; } bool IsValid(const CameraStandard::Size& size) { return (size.width >= RESOLUTION_MIN_WIDTH) && (size.height >= RESOLUTION_MIN_HEIGHT) && (size.width <= RESOLUTION_MAX_WIDTH_CONTINUOUS) && (size.height <= RESOLUTION_MAX_HEIGHT_CONTINUOUS); } } // namespace DistributedHardware } // namespace OHOS