diff --git a/frameworks/js/camera_napi/src/input/camera_manager_napi.cpp b/frameworks/js/camera_napi/src/input/camera_manager_napi.cpp index b823c324e3d21b01de21e7655e8ba469f956b825..605c4f9767471803dd7505f2dbbb774c3b1cff0e 100644 --- a/frameworks/js/camera_napi/src/input/camera_manager_napi.cpp +++ b/frameworks/js/camera_napi/src/input/camera_manager_napi.cpp @@ -13,8 +13,9 @@ * limitations under the License. */ -#include "input/camera_napi.h" #include "input/camera_manager_napi.h" +#include "input/camera_napi.h" +#include "input/camera_pre_launch_config_napi.h" namespace OHOS { namespace CameraStandard { @@ -98,6 +99,9 @@ napi_value CameraManagerNapi::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("isCameraMuted", IsCameraMuted), DECLARE_NAPI_FUNCTION("isCameraMuteSupported", IsCameraMuteSupported), DECLARE_NAPI_FUNCTION("muteCamera", MuteCamera), + DECLARE_NAPI_FUNCTION("preLaunch", PrelaunchCamera), + DECLARE_NAPI_FUNCTION("isPreLaunchSupported", IsPreLaunchSupported), + DECLARE_NAPI_FUNCTION("setPreLaunchConfig", SetPreLaunchConfig), DECLARE_NAPI_FUNCTION("createCameraInput", CreateCameraInputInstance), DECLARE_NAPI_FUNCTION("createCaptureSession", CreateCameraSessionInstance), DECLARE_NAPI_FUNCTION("createPreviewOutput", CreatePreviewOutputInstance), @@ -180,8 +184,8 @@ void CameraManagerCommonCompleteCallback(napi_env env, napi_status status, void* MEDIA_INFO_LOG("modeForAsync = %{public}d", context->modeForAsync); napi_get_undefined(env, &jsContext->error); if (context->modeForAsync == CREATE_DEFERRED_PREVIEW_OUTPUT_ASYNC_CALLBACK) { - jsContext->data = PhotoOutputNapi::CreatePhotoOutput(env, context->profile, context->surfaceId); - MEDIA_INFO_LOG("CreatePhotoOutput context->photoSurfaceId : %{public}s", context->surfaceId.c_str()); + MEDIA_INFO_LOG("createDeferredPreviewOutput"); + jsContext->data = PreviewOutputNapi::CreateDeferredPreviewOutput(env, context->profile); } if (jsContext->data == nullptr) { @@ -309,9 +313,7 @@ static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_va napi_value result; size_t length = 0; auto context = &asyncContext; - NAPI_ASSERT(env, argv != nullptr, "Argument list is empty"); - for (size_t i = PARAM0; i < argc; i++) { napi_valuetype valueType = napi_undefined; napi_typeof(env, argv[i], &valueType); @@ -334,9 +336,11 @@ static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_va context->videoProfile.framerates_[0], context->videoProfile.framerates_[1]); } + } else if (i == PARAM1 && valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &context->callbackRef); + break; } else if (i == PARAM1 && valueType == napi_string) { if (napi_get_value_string_utf8(env, argv[i], buffer, PATH_MAX, &length) == napi_ok) { - MEDIA_INFO_LOG("surfaceId buffer --1 : %{public}s", buffer); context->surfaceId = std::string(buffer); MEDIA_INFO_LOG("context->surfaceId after convert : %{public}s", context->surfaceId.c_str()); } else { @@ -349,7 +353,6 @@ static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_va NAPI_ASSERT(env, false, "type mismatch"); } } - // Return true napi_value if params are successfully obtained napi_get_boolean(env, true, &result); return result; @@ -809,5 +812,75 @@ napi_value CameraManagerNapi::On(napi_env env, napi_callback_info info) } return undefinedResult; } + +napi_value CameraManagerNapi::IsPreLaunchSupported(napi_env env, napi_callback_info info) +{ + MEDIA_INFO_LOG("IsPreLaunchSupported is called"); + napi_status status; + + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value argv[ARGS_ONE] = {0}; + napi_value thisVar = nullptr; + CameraDeviceNapi* cameraDeviceNapi = nullptr; + CameraManagerNapi* cameraManagerNapi = nullptr; + + CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); + + napi_get_undefined(env, &result); + status = napi_unwrap(env, thisVar, reinterpret_cast(&cameraManagerNapi)); + if (status != napi_ok || cameraManagerNapi == nullptr) { + MEDIA_ERR_LOG("napi_unwrap( ) failure!"); + return result; + } + status = napi_unwrap(env, argv[PARAM0], reinterpret_cast(&cameraDeviceNapi)); + if (status != napi_ok || cameraDeviceNapi == nullptr) { + MEDIA_ERR_LOG("Could not able to read cameraDevice argument!"); + return result; + } + sptr cameraInfo = cameraDeviceNapi->cameraDevice_; + bool isPreLaunchSupported = CameraManager::GetInstance()->IsPreLaunchSupported(cameraInfo); + MEDIA_DEBUG_LOG("isPreLaunchSupported: %{public}d", isPreLaunchSupported); + napi_get_boolean(env, isPreLaunchSupported, &result); + return result; +} + +napi_value CameraManagerNapi::PrelaunchCamera(napi_env env, napi_callback_info info) +{ + MEDIA_INFO_LOG("PrelaunchCamera is called"); + napi_value result = nullptr; + CameraManager::GetInstance()->PrelaunchCamera(); + MEDIA_INFO_LOG("PrelaunchCamera"); + napi_get_undefined(env, &result); + return result; +} + +napi_value CameraManagerNapi::SetPreLaunchConfig(napi_env env, napi_callback_info info) +{ + MEDIA_INFO_LOG("SetPrelaunchConfig is called"); + napi_status status; + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value argv[ARGS_ONE] = {0}; + napi_value thisVar = nullptr; + CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); + NAPI_ASSERT(env, argc < ARGS_TWO, "requires 1 parameters maximum"); + napi_value res = nullptr; + PreLaunchConfig prelaunchConfig; + CameraDeviceNapi* cameraDeviceNapi = nullptr; + if (napi_get_named_property(env, argv[PARAM0], "cameraDevice", &res) == napi_ok) { + status = napi_unwrap(env, res, reinterpret_cast(&cameraDeviceNapi)); + prelaunchConfig.cameraDevice_ = cameraDeviceNapi->cameraDevice_; + if (status != napi_ok || prelaunchConfig.cameraDevice_ == nullptr) { + MEDIA_ERR_LOG("napi_unwrap( ) failure!"); + return result; + } + } + std::string cameraId = prelaunchConfig.GetCameraDevice()->GetID(); + MEDIA_INFO_LOG("SetPreLaunchConfig cameraId = %{public}s", cameraId.c_str()); + CameraManager::GetInstance()->SetPreLaunchConfig(cameraId); + napi_get_undefined(env, &result); + return result; +} } // namespace CameraStandard } // namespace OHOS diff --git a/frameworks/js/camera_napi/src/input/camera_pre_launch_config_napi.cpp b/frameworks/js/camera_napi/src/input/camera_pre_launch_config_napi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31bad4df99dc6a1de09641e5250803be365b04dc --- /dev/null +++ b/frameworks/js/camera_napi/src/input/camera_pre_launch_config_napi.cpp @@ -0,0 +1,136 @@ +/* + * 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 "input/camera_pre_launch_config_napi.h" +#include "input/camera_info_napi.h" + +namespace OHOS { +namespace CameraStandard { +thread_local napi_ref CameraPreLaunchConfigNapi::sConstructor_ = nullptr; +thread_local PreLaunchConfig* CameraPreLaunchConfigNapi::sPreLaunchConfig_ = nullptr; + +CameraPreLaunchConfigNapi::CameraPreLaunchConfigNapi() : env_(nullptr), wrapper_(nullptr) +{ +} + +CameraPreLaunchConfigNapi::~CameraPreLaunchConfigNapi() +{ + MEDIA_DEBUG_LOG("~CameraPreLaunchConfigNapi is called"); + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } + if (sPreLaunchConfig_) { + sPreLaunchConfig_ = nullptr; + } +} + +void CameraPreLaunchConfigNapi::CameraPreLaunchConfigNapiDestructor( + napi_env env, void* nativeObject, void* finalize_hint) +{ + MEDIA_DEBUG_LOG("CameraPreLaunchConfigNapiDestructor is called"); + CameraPreLaunchConfigNapi* cameraPreLaunchConfigNapi = reinterpret_cast(nativeObject); + if (cameraPreLaunchConfigNapi != nullptr) { + MEDIA_INFO_LOG("CameraPreLaunchConfigNapiDestructor ~"); + cameraPreLaunchConfigNapi->~CameraPreLaunchConfigNapi(); + } +} + +napi_value CameraPreLaunchConfigNapi::Init(napi_env env, napi_value exports) +{ + MEDIA_INFO_LOG("Init is called"); + napi_status status; + napi_value ctorObj; + napi_property_descriptor prelaunch_config_props[] = { + DECLARE_NAPI_GETTER("cameraDevice", GetPreLaunchCameraDevice) + }; + status = napi_define_class(env, CAMERA_PRELAUNCH_CONFIG_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, + CameraPreLaunchConfigNapiConstructor, nullptr, + sizeof(prelaunch_config_props) / sizeof(prelaunch_config_props[PARAM0]), + prelaunch_config_props, &ctorObj); + if (status == napi_ok) { + int32_t refCount = 1; + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, CAMERA_PRELAUNCH_CONFIG_NAPI_CLASS_NAME, ctorObj); + if (status == napi_ok) { + return exports; + } + } + } + MEDIA_ERR_LOG("Init call Failed!"); + return nullptr; +} + +// Constructor callback +napi_value CameraPreLaunchConfigNapi::CameraPreLaunchConfigNapiConstructor(napi_env env, napi_callback_info info) +{ + MEDIA_DEBUG_LOG("CameraProfileNapiConstructor is called"); + napi_status status; + napi_value result = nullptr; + napi_value thisVar = nullptr; + + napi_get_undefined(env, &result); + CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar); + + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + obj->env_ = env; + obj->preLaunchConfig_ = sPreLaunchConfig_; + MEDIA_INFO_LOG("CameraPreLaunchConfigNapiConstructor cameraId = %{public}s", + obj->preLaunchConfig_->GetCameraDevice()->GetID().c_str()); + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + CameraPreLaunchConfigNapi::CameraPreLaunchConfigNapiDestructor, nullptr, nullptr); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + MEDIA_ERR_LOG("Failure wrapping js to native napi"); + } + } + MEDIA_ERR_LOG("CameraPreLaunchConfigNapiConstructor call Failed!"); + return result; +} + +napi_value CameraPreLaunchConfigNapi::GetPreLaunchCameraDevice(napi_env env, napi_callback_info info) +{ + MEDIA_DEBUG_LOG("GetCameraProfileSize is called"); + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + CameraPreLaunchConfigNapi* obj = nullptr; + sptr cameraDevice; + napi_value thisVar = nullptr; + + napi_get_undefined(env, &undefinedResult); + CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar); + + if (status != napi_ok || thisVar == nullptr) { + MEDIA_ERR_LOG("Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if ((status == napi_ok) && (obj != nullptr)) { + cameraDevice = obj->preLaunchConfig_->GetCameraDevice(); + MEDIA_INFO_LOG("GetPreLaunchCameraDevice cameraId = %{public}s", + obj->preLaunchConfig_->GetCameraDevice()->GetID().c_str()); + jsResult = CameraDeviceNapi::CreateCameraObj(env, cameraDevice); + return jsResult; + } + MEDIA_ERR_LOG("GetCameraProfileSize call Failed!"); + return undefinedResult; +} +} // namespace CameraStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/camera_napi/src/native_module_ohos_camera.cpp b/frameworks/js/camera_napi/src/native_module_ohos_camera.cpp index e912446250dff8085dd0fd825690379c3e3c7cef..351f99d3bce546e2a445551d350536a129b91146 100644 --- a/frameworks/js/camera_napi/src/native_module_ohos_camera.cpp +++ b/frameworks/js/camera_napi/src/native_module_ohos_camera.cpp @@ -34,6 +34,7 @@ static napi_value Export(napi_env env, napi_value exports) CameraOutputCapabilityNapi::Init(env, exports); CameraSizeNapi::Init(env, exports); CameraVideoProfileNapi::Init(env, exports); + CameraPreLaunchConfigNapi::Init(env, exports); MetadataOutputNapi::Init(env, exports); MetadataObjectNapi::Init(env, exports); PortraitSessionNapi::Init(env, exports); diff --git a/frameworks/js/camera_napi/src/output/photo_output_napi.cpp b/frameworks/js/camera_napi/src/output/photo_output_napi.cpp index 6fefa587e01f416c70bb793fa1254df26e857ffc..04fba0d8b3e575939cad2f4a26de184aecd8a936 100644 --- a/frameworks/js/camera_napi/src/output/photo_output_napi.cpp +++ b/frameworks/js/camera_napi/src/output/photo_output_napi.cpp @@ -15,6 +15,8 @@ #include "output/photo_output_napi.h" #include +#include "image_napi.h" +#include "pixel_map_napi.h" namespace OHOS { namespace CameraStandard { @@ -172,6 +174,104 @@ void PhotoOutputCallback::UpdateJSCallback(std::string propName, const CallbackI napi_call_function(env_, nullptr, callback, ARGS_TWO, result, &retVal); } +ThumbnailListener::ThumbnailListener(napi_env env, const napi_ref &callbackRef, const sptr photoOutput) + : env_(env), thumbnailCallbackRef_(callbackRef), photoOutput_(photoOutput) {} + +void ThumbnailListener::OnBufferAvailable() +{ + CAMERA_SYNC_TRACE; + MEDIA_INFO_LOG("ThumbnailListener:OnBufferAvailable() called"); + if (!photoOutput_) { + MEDIA_ERR_LOG("photoOutput napi sPhotoOutput_ is null"); + return; + } + UpdateJSCallbackAsync(photoOutput_); +} + +void ThumbnailListener::UpdateJSCallback(sptr photoOutput) const +{ + CAMERA_NAPI_CHECK_NULL_PTR_RETURN_VOID(thumbnailCallbackRef_, + "OnThunbnail callback is not registered by JS"); + + napi_value valueParam = nullptr; + napi_value result[ARGS_TWO] = {0}; + napi_get_undefined(env_, &result[0]); + napi_get_undefined(env_, &result[1]); + napi_value callback = nullptr; + napi_value retVal; + MEDIA_ERR_LOG("enter ImageNapi::Create start"); + int32_t fence = -1; + int64_t timestamp; + OHOS::Rect damage; + sptr thumbnailBuffer = nullptr; + SurfaceError surfaceRet = photoOutput_->thumbnailSurface_->AcquireBuffer(thumbnailBuffer, fence, timestamp, damage); + if (surfaceRet != SURFACE_ERROR_OK) { + MEDIA_ERR_LOG("ThumbnailListener Failed to acquire surface buffer"); + return; + } + MEDIA_INFO_LOG("ThumbnailListener start decode surface buffer"); + int32_t thumbnailWidth; + int32_t thumbnailHeight; + thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth); + thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight); + Media::InitializationOptions opts; + opts.pixelFormat = Media::PixelFormat::RGBA_8888; + opts.size = { + .width = thumbnailWidth, + .height = thumbnailHeight + }; + MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailheight: %{public}d, bufSize: %{public}d", + thumbnailWidth, thumbnailHeight, thumbnailBuffer->GetSize()); + auto pixelMap = Media::PixelMap::Create(opts); + pixelMap->SetPixelsAddr(thumbnailBuffer->GetVirAddr(), nullptr, thumbnailBuffer->GetSize(), + Media::AllocatorType::HEAP_ALLOC, nullptr); + valueParam = Media::PixelMapNapi::CreatePixelMap(env_, std::move(pixelMap)); + if (valueParam == nullptr) { + MEDIA_ERR_LOG("ImageNapi Create failed"); + napi_get_undefined(env_, &valueParam); + } + MEDIA_INFO_LOG("enter ImageNapi::Create end"); + napi_get_reference_value(env_, thumbnailCallbackRef_, &callback); + result[1] = valueParam; + napi_call_function(env_, nullptr, callback, ARGS_TWO, result, &retVal); + photoOutput_->thumbnailSurface_->ReleaseBuffer(thumbnailBuffer, -1); +} + +void ThumbnailListener::UpdateJSCallbackAsync(sptr photoOutput) const +{ + uv_loop_s* loop = nullptr; + napi_get_uv_event_loop(env_, &loop); + if (!loop) { + MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to get event loop"); + return; + } + uv_work_t* work = new(std::nothrow) uv_work_t; + if (!work) { + MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to allocate work"); + return; + } + std::unique_ptr callbackInfo = + std::make_unique(photoOutput, this); + work->data = callbackInfo.get(); + int ret = uv_queue_work(loop, work, [] (uv_work_t* work) {}, [] (uv_work_t* work, int status) { + ThumbnailListenerInfo* callbackInfo = reinterpret_cast(work->data); + if (callbackInfo) { + callbackInfo->listener_->UpdateJSCallback(callbackInfo->photoOutput_); + MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() complete"); + callbackInfo->photoOutput_ = nullptr; + callbackInfo->listener_ = nullptr; + delete callbackInfo; + } + delete work; + }); + if (ret) { + MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to execute work"); + delete work; + } else { + callbackInfo.release(); + } +} + PhotoOutputNapi::PhotoOutputNapi() : env_(nullptr), wrapper_(nullptr) { } @@ -212,6 +312,8 @@ napi_value PhotoOutputNapi::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("release", Release), DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported), DECLARE_NAPI_FUNCTION("setMirror", SetMirror), + DECLARE_NAPI_FUNCTION("enableQuickThumbnail", EnableQuickThumbnail), + DECLARE_NAPI_FUNCTION("isQuickThumbnailSupported", IsQuickThumbnailSupported), DECLARE_NAPI_FUNCTION("on", On) }; @@ -710,6 +812,27 @@ napi_value PhotoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info i return result; } +napi_value PhotoOutputNapi::IsQuickThumbnailSupported(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + size_t argc = ARGS_ZERO; + napi_value argv[ARGS_ZERO]; + napi_value thisVar = nullptr; + + CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); + + napi_get_undefined(env, &result); + PhotoOutputNapi* photoOutputNapi = nullptr; + status = napi_unwrap(env, thisVar, reinterpret_cast(&photoOutputNapi)); + if (status == napi_ok && photoOutputNapi != nullptr) { + bool isSupported = photoOutputNapi->photoOutput_->IsQuickThumbnailSupported(); + napi_get_boolean(env, isSupported, &result); + } + + return result; +} + napi_value PhotoOutputNapi::SetMirror(napi_env env, napi_callback_info info) { MEDIA_DEBUG_LOG("SetMirror is called"); @@ -764,6 +887,27 @@ napi_value PhotoOutputNapi::SetMirror(napi_env env, napi_callback_info info) return result; } +napi_value PhotoOutputNapi::EnableQuickThumbnail(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value argv[ARGS_ONE] = {0}; + napi_value thisVar = nullptr; + CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); + NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter"); + napi_get_undefined(env, &result); + PhotoOutputNapi* photoOutputNapi = nullptr; + status = napi_unwrap(env, thisVar, reinterpret_cast(&photoOutputNapi)); + bool thumbnailSwitch; + if (status == napi_ok && photoOutputNapi != nullptr) { + napi_get_value_bool(env, argv[PARAM0], &thumbnailSwitch); + photoOutputNapi->isQuickThumbnailEnabled_ = thumbnailSwitch; + photoOutputNapi->photoOutput_->SetThumbnail(thumbnailSwitch); + } + return result; +} + napi_value PhotoOutputNapi::On(napi_env env, napi_callback_info info) { MEDIA_INFO_LOG("On is called"); @@ -802,7 +946,15 @@ napi_value PhotoOutputNapi::On(napi_env env, napi_callback_info info) napi_ref callbackRef; napi_create_reference(env, argv[PARAM1], refCount, &callbackRef); - if (!eventType.empty()) { + if (eventType == OHOS::CameraStandard::thumbnailRegisterName) { + // create thumbnail listener when eventType is thumbnail + if (!obj->isQuickThumbnailEnabled_) { + MEDIA_ERR_LOG("quickThumbnail is not enabled!"); + return undefinedResult; + } + sptr listener = new ThumbnailListener(env, callbackRef, obj->photoOutput_); + ((sptr &)(obj->photoOutput_))->SetThumbnailListener((sptr&)listener); + } else if (!eventType.empty()) { obj->photoCallback_->SetCallbackRef(eventType, callbackRef); } else { MEDIA_ERR_LOG("Failed to Register Callback: event type is empty!"); diff --git a/frameworks/js/camera_napi/src/output/preview_output_napi.cpp b/frameworks/js/camera_napi/src/output/preview_output_napi.cpp index eb0d70a00e0b0f85281c28ceb6c7d5d76763f7dd..e454edb0a6ea823ede75f2c97e7420b90a5e0d07 100644 --- a/frameworks/js/camera_napi/src/output/preview_output_napi.cpp +++ b/frameworks/js/camera_napi/src/output/preview_output_napi.cpp @@ -265,6 +265,34 @@ static void CommonCompleteCallback(napi_env env, napi_status status, void* data) delete context; } +napi_value PreviewOutputNapi::CreateDeferredPreviewOutput(napi_env env, Profile &profile) +{ + CAMERA_SYNC_TRACE; + napi_status status; + napi_value result = nullptr; + napi_value constructor; + + status = napi_get_reference_value(env, sConstructor_, &constructor); + if (status == napi_ok) { + sPreviewOutput_ = CameraManager::GetInstance()->CreateDeferredPreviewOutput(profile); + if (sPreviewOutput_ == nullptr) { + MEDIA_ERR_LOG("failed to create previewOutput"); + return result; + } + status = napi_new_instance(env, constructor, 0, nullptr, &result); + sPreviewOutput_ = nullptr; + + if (status == napi_ok && result != nullptr) { + return result; + } else { + MEDIA_ERR_LOG("Failed to create preview output instance"); + } + } + + napi_get_undefined(env, &result); + return result; +} + napi_value PreviewOutputNapi::CreatePreviewOutput(napi_env env, Profile &profile, std::string surfaceId) { MEDIA_INFO_LOG("CreatePreviewOutput is called"); @@ -385,6 +413,74 @@ napi_value PreviewOutputNapi::Release(napi_env env, napi_callback_info info) return result; } +static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_value argv[], + PreviewOutputAsyncContext &asyncContext) +{ + char buffer[PATH_MAX]; + const int32_t refCount = 1; + napi_value result; + size_t length = 0; + auto context = &asyncContext; + + NAPI_ASSERT(env, argv != nullptr, "Argument list is empty"); + + for (size_t i = PARAM0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); + if (i == PARAM0 && valueType == napi_string) { + if (napi_get_value_string_utf8(env, argv[i], buffer, PATH_MAX, &length) == napi_ok) { + MEDIA_DEBUG_LOG("surfaceId buffer: %{public}s", buffer); + context->surfaceId = std::string(buffer); + MEDIA_DEBUG_LOG("context->surfaceId after convert : %{public}s", context->surfaceId.c_str()); + } else { + MEDIA_ERR_LOG("Could not able to read surfaceId argument!"); + } + } else if (i == PARAM1 && valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &context->callbackRef); + break; + } else { + NAPI_ASSERT(env, false, "type mismatch"); + } + } + + // Return true napi_value if params are successfully obtained + napi_get_boolean(env, true, &result); + return result; +} + +napi_status PreviewOutputNapi::CreateAsyncTask(napi_env env, napi_value resource, + std::unique_ptr &asyncContext) +{ + napi_status status = napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + context->status = false; + // Start async trace + context->funcName = "PreviewOutputNapi::AddDeferredSurface"; + context->taskId = CameraNapiUtils::IncreamentAndGet(previewOutputTaskId); + CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId); + if (context->objectInfo != nullptr && context->objectInfo->previewOutput_ != nullptr) { + context->bRetBool = false; + context->status = true; + uint64_t iSurfaceId; + std::istringstream iss(context->surfaceId); + iss >> iSurfaceId; + sptr surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId); + if (!surface) { + surface = Media::ImageReceiver::getSurfaceById(context->surfaceId); + } + if (surface == nullptr) { + MEDIA_ERR_LOG("failed to get surface"); + return; + } + CameraFormat format = ((sptr &)(context->objectInfo->previewOutput_))->format; + surface->SetUserData(CameraManager::surfaceFormat, std::to_string(format)); + ((sptr &)(context->objectInfo->previewOutput_))->AddDeferredSurface(surface); + } + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + return status; +} + napi_value PreviewOutputNapi::AddDeferredSurface(napi_env env, napi_callback_info info) { MEDIA_DEBUG_LOG("AddDeferredSurface is called"); @@ -395,38 +491,22 @@ napi_value PreviewOutputNapi::AddDeferredSurface(napi_env env, napi_callback_inf size_t argc = ARGS_TWO; napi_value argv[ARGS_TWO] = {0}; napi_value thisVar = nullptr; - CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 1 parameter maximum"); - + NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameter maximum"); napi_get_undefined(env, &result); std::unique_ptr asyncContext = std::make_unique(); status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + CAMERA_NAPI_CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "Failed to obtain arguments"); if (status == napi_ok && asyncContext->objectInfo != nullptr) { if (argc == ARGS_TWO) { CAMERA_NAPI_GET_JS_ASYNC_CB_REF(env, argv[PARAM1], refCount, asyncContext->callbackRef); } - CAMERA_NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); CAMERA_NAPI_CREATE_RESOURCE_NAME(env, resource, "AddDeferredSurface"); - - status = napi_create_async_work( - env, nullptr, resource, [](napi_env env, void* data) { - auto context = static_cast(data); - context->status = false; - // Start async trace - context->funcName = "PreviewOutputNapi::AddDeferredSurface"; - context->taskId = CameraNapiUtils::IncreamentAndGet(previewOutputTaskId); - CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId); - if (context->objectInfo != nullptr && context->objectInfo->previewOutput_ != nullptr) { - context->bRetBool = false; - context->status = true; - ((sptr &)(context->objectInfo->previewOutput_))->Stop(); - } - }, - CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + status = CreateAsyncTask(env, resource, asyncContext); if (status != napi_ok) { - MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Release"); + MEDIA_ERR_LOG("Failed to create napi_create_async_work!"); napi_get_undefined(env, &result); } else { napi_queue_async_work(env, asyncContext->work); diff --git a/frameworks/native/camera/BUILD.gn b/frameworks/native/camera/BUILD.gn index 2fca9e4dc8d9ab98efaeddd1e64dcf589a8c02e5..a39ec5e15ec888f6175ed58efa2ba92aa7bcefd1 100644 --- a/frameworks/native/camera/BUILD.gn +++ b/frameworks/native/camera/BUILD.gn @@ -61,6 +61,7 @@ ohos_shared_library("camera_framework") { "src/input/camera_input.cpp", "src/input/camera_manager.cpp", "src/input/capture_input.cpp", + "src/input/prelaunch_config.cpp", "src/mode/mode_manager.cpp", "src/output/camera_output_capability.cpp", "src/output/capture_output.cpp", @@ -107,6 +108,7 @@ ohos_shared_library("camera_framework") { "hitrace_native:hitrace_meter", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "multimedia_image_framework:image_native", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/frameworks/native/camera/src/input/camera_manager.cpp b/frameworks/native/camera/src/input/camera_manager.cpp index 7293b7827d60d74233f59e49345a2817257cdc78..1a18b2df6a22d6016cf60ff503e5f76bba4d80bc 100644 --- a/frameworks/native/camera/src/input/camera_manager.cpp +++ b/frameworks/native/camera/src/input/camera_manager.cpp @@ -307,6 +307,7 @@ int CameraManager::CreatePreviewOutput(Profile &profile, sptr surface, sptr CameraManager::CreateDeferredPreviewOutput(Profile &profile) { CAMERA_SYNC_TRACE; + MEDIA_INFO_LOG("CameraManager::CreateDeferredPreviewOutput called"); sptr previewOutput = nullptr; int ret = CreateDeferredPreviewOutput(profile, &previewOutput); if (ret != CameraErrorCode::SUCCESS) { @@ -346,6 +347,7 @@ int CameraManager::CreateDeferredPreviewOutput(Profile &profile, sptrformat = profile.GetCameraFormat(); POWERMGR_SYSEVENT_CAMERA_CONFIG(PREVIEW, profile.GetSize().width, profile.GetSize().height); @@ -1028,5 +1030,47 @@ void CameraManager::MuteCamera(bool muteMode) } return; } + +void CameraManager::PrelaunchCamera() +{ + std::lock_guard lock(mutex_); + if (serviceProxy_ == nullptr) { + MEDIA_ERR_LOG("CameraManager::PrelaunchCamera serviceProxy_ is null"); + return; + } + int32_t retCode = serviceProxy_->PrelaunchCamera(); + if (retCode != CAMERA_OK) { + MEDIA_ERR_LOG("CameraManager::PrelaunchCamera failed, retCode: %{public}d", retCode); + } +} + +bool CameraManager::IsPreLaunchSupported(sptr camera) +{ + bool isPreLaunch = false; + std::shared_ptr metadata = camera->GetMetadata(); + camera_metadata_item_t item; + int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_PRELAUNCH_AVAILABLE, &item); + if (ret == 0) { + MEDIA_INFO_LOG("CameraManager::IsPreLaunchSupported() OHOS_ABILITY_PRELAUNCH_AVAILABLE is %{public}d", + item.data.u8[0]); + isPreLaunch = (item.data.u8[0] == 1); + } else { + MEDIA_ERR_LOG("Failed to get OHOS_ABILITY_PRELAUNCH_AVAILABLE ret = %{public}d", ret); + } + return isPreLaunch; +} + +void CameraManager::SetPreLaunchConfig(std::string cameraId) +{ + std::lock_guard lock(mutex_); + if (serviceProxy_ == nullptr) { + MEDIA_ERR_LOG("CameraManager::SetPrelaunchConfig serviceProxy_ is null"); + return; + } + int32_t retCode = serviceProxy_->SetPrelaunchConfig(cameraId); + if (retCode != CAMERA_OK) { + MEDIA_ERR_LOG("CameraManager::SetPrelaunchConfig failed, retCode: %{public}d", retCode); + } +} } // namespace CameraStandard } // namespace OHOS diff --git a/frameworks/native/camera/src/input/prelaunch_config.cpp b/frameworks/native/camera/src/input/prelaunch_config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e264370b05b70f421f84ecf1017125fb90789503 --- /dev/null +++ b/frameworks/native/camera/src/input/prelaunch_config.cpp @@ -0,0 +1,29 @@ +/* + * 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 "input/prelaunch_config.h" + +using namespace std; + +namespace OHOS { +namespace CameraStandard { +PreLaunchConfig::PreLaunchConfig(sptr cameraDevice): cameraDevice_(cameraDevice) {} + +sptr PreLaunchConfig::GetCameraDevice() +{ + return cameraDevice_; +} +} +} \ No newline at end of file diff --git a/frameworks/native/camera/src/output/photo_output.cpp b/frameworks/native/camera/src/output/photo_output.cpp index b7195f8c0f1c26cf7f1fbbab784feecb05afa861..0f25675df1fc9b7f652c8a6388bc858809e45af8 100644 --- a/frameworks/native/camera/src/output/photo_output.cpp +++ b/frameworks/native/camera/src/output/photo_output.cpp @@ -259,6 +259,31 @@ void PhotoOutput::SetCallback(std::shared_ptr callback) } } +void PhotoOutput::SetThumbnailListener(sptr& listener) +{ + if (thumbnailSurface_) { + SurfaceError ret = thumbnailSurface_->RegisterConsumerListener(listener); + if (ret != SURFACE_ERROR_OK) { + MEDIA_ERR_LOG("PhotoOutput::SetThumbnailListener Surface consumer listener registration failed"); + } + } else { + MEDIA_ERR_LOG("PhotoOutput SetThumbnailListener surface is null"); + } +} + +int32_t PhotoOutput::SetThumbnail(bool isEnabled) +{ + CAMERA_SYNC_TRACE; + !thumbnailSurface_ && (thumbnailSurface_ = Surface::CreateSurfaceAsConsumer("quickThumbnail")); + if (thumbnailSurface_ == nullptr) { + MEDIA_ERR_LOG("PhotoOutput::SetThumbnail Failed to create surface"); + return CAMERA_STREAM_BUFFER_LOST; + } + int32_t retCode = static_cast( + GetStream().GetRefPtr())->SetThumbnail(isEnabled, thumbnailSurface_->GetProducer()); + return retCode; +} + std::shared_ptr PhotoOutput::GetApplicationCallback() { return appCallback_; @@ -386,13 +411,36 @@ bool PhotoOutput::IsMirrorSupported() } std::shared_ptr metadata = cameraObj_->GetMetadata(); - int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item); + int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item); if (ret == CAM_META_SUCCESS) { isMirrorEnabled = ((item.data.u8[0] == 1) || (item.data.u8[0] == 0)); } return isMirrorEnabled; } +bool PhotoOutput::IsQuickThumbnailSupported() +{ + bool isQuickThumbnailEnabled = false; + camera_metadata_item_t item; + sptr cameraObj_; + CaptureSession* captureSession = GetSession(); + if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) { + MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, captureSession or inputDevice_ is nullptr"); + return isQuickThumbnailEnabled; + } + cameraObj_ = captureSession->inputDevice_->GetCameraDeviceInfo(); + if (cameraObj_ == nullptr) { + MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, cameraObj is nullptr"); + return isQuickThumbnailEnabled; + } + std::shared_ptr metadata = cameraObj_->GetMetadata(); + int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_STREAM_QUICK_THUMBNAIL_AVAILABLE, &item); + if (ret == CAM_META_SUCCESS) { + isQuickThumbnailEnabled = (item.data.u8[0] == 1); + } + return isQuickThumbnailEnabled; +} + std::shared_ptr PhotoOutput::GetDefaultCaptureSetting() { return defaultCaptureSetting_; diff --git a/frameworks/native/camera/src/output/preview_output.cpp b/frameworks/native/camera/src/output/preview_output.cpp index 07da27cc86e5152beb060ad6852a9463f49d88bf..fd4f5ad59eaa868a7a26d9b64593d1c2a41277ba 100644 --- a/frameworks/native/camera/src/output/preview_output.cpp +++ b/frameworks/native/camera/src/output/preview_output.cpp @@ -103,6 +103,7 @@ public: void PreviewOutput::AddDeferredSurface(sptr surface) { + MEDIA_INFO_LOG("PreviewOutput::AddDeferredSurface called"); if (surface == nullptr) { MEDIA_ERR_LOG("PreviewOutput::AddDeferredSurface surface is null"); return; diff --git a/interfaces/inner_api/native/camera/include/input/camera_manager.h b/interfaces/inner_api/native/camera/include/input/camera_manager.h index dfc86ca4749c860b85f917883851bc316be4fedc..92d1507685bff2275a86f2d2edee51cb96692e2c 100644 --- a/interfaces/inner_api/native/camera/include/input/camera_manager.h +++ b/interfaces/inner_api/native/camera/include/input/camera_manager.h @@ -416,6 +416,27 @@ public: */ std::vector> GetCameraMuteListener(); + /** + * @brief prelaunch the camera + * + * @return. + */ + void PrelaunchCamera(); + + /** + * @brief set prelaunch config + * + * @return. + */ + void SetPreLaunchConfig(std::string cameraId); + + /** + * @brief Get the support of camera pre launch mode. + * + * @return Returns true is supported, false is not supported. + */ + bool IsPreLaunchSupported(sptr camera); + static const std::string surfaceFormat; protected: diff --git a/interfaces/inner_api/native/camera/include/input/prelaunch_config.h b/interfaces/inner_api/native/camera/include/input/prelaunch_config.h new file mode 100644 index 0000000000000000000000000000000000000000..99c0faa2f8014be2df8b53c865758f07fc4f810b --- /dev/null +++ b/interfaces/inner_api/native/camera/include/input/prelaunch_config.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021-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. + */ + +#ifndef CAMERA_FRAMEWORK_PRELAUNCH_CONFIG_H +#define CAMERA_FRAMEWORK_PRELAUNCH_CONFIG_H + +#include "input/camera_device.h" + +namespace OHOS { +namespace CameraStandard { +class PreLaunchConfig { +public: + PreLaunchConfig(sptr cameraDevice); + + PreLaunchConfig() = default; + + virtual ~PreLaunchConfig() = default; + + /** + * @brief Get CameraDevice of the PreLaunchConfig. + * + * @return cameraDevice. + */ + sptr GetCameraDevice(); + + sptr cameraDevice_ = nullptr; +}; +} +} +#endif // CAMERA_FRAMEWORK_PRELAUNCH_CONFIG_H diff --git a/interfaces/inner_api/native/camera/include/output/photo_output.h b/interfaces/inner_api/native/camera/include/output/photo_output.h index 8c31deb4a65dcf9007c931f1f8ee1bcd89bca6fa..e11c2ba274d33d53f41dad46839741311fc04066 100644 --- a/interfaces/inner_api/native/camera/include/output/photo_output.h +++ b/interfaces/inner_api/native/camera/include/output/photo_output.h @@ -204,6 +204,20 @@ public: */ void SetCallback(std::shared_ptr callback); + /** + * @brief Set the thumbnail callback. + * + * @param listener set IBufferConsumerListener when on interface is called. + */ + void SetThumbnailListener(sptr& listener); + + /** + * @brief Set the Thumbnail profile. + * + * @param isEnabled quickThumbnail is enabled. + */ + int32_t SetThumbnail(bool isEnabled); + /** * @brief Set the photo callback. * @@ -248,6 +262,13 @@ public: */ bool IsMirrorSupported(); + /** + * @brief To check the quick thumbnail is supported or not. + * + * @return Returns true/false if the quick thumbnail is supported/not-supported respectively. + */ + bool IsQuickThumbnailSupported(); + /** * @brief Get default photo capture setting. * @@ -255,6 +276,7 @@ public: */ std::shared_ptr GetDefaultCaptureSetting(); + sptr thumbnailSurface_; private: std::shared_ptr appCallback_; sptr cameraSvcCallback_; diff --git a/interfaces/inner_api/native/camera/include/output/preview_output.h b/interfaces/inner_api/native/camera/include/output/preview_output.h index e4d760b5024aabcefe14c24f557057d785a96809..35570615390fdded56b4cc3a3bfe84f07695c2b6 100644 --- a/interfaces/inner_api/native/camera/include/output/preview_output.h +++ b/interfaces/inner_api/native/camera/include/output/preview_output.h @@ -18,6 +18,7 @@ #include "capture_output.h" #include "istream_repeat.h" +#include "camera_output_capability.h" #include "istream_repeat_callback.h" namespace OHOS { @@ -88,6 +89,10 @@ public: */ std::shared_ptr GetApplicationCallback(); + /** + * @brief Get the application callback information. + */ + CameraFormat format; private: std::shared_ptr appCallback_; sptr svcCallback_; diff --git a/interfaces/kits/js/camera_napi/BUILD.gn b/interfaces/kits/js/camera_napi/BUILD.gn index d8215546e12b4874990a13abe4363892c100b421..6fd917e48da3ca0c260204a615820ff661d909fa 100644 --- a/interfaces/kits/js/camera_napi/BUILD.gn +++ b/interfaces/kits/js/camera_napi/BUILD.gn @@ -46,6 +46,7 @@ ohos_shared_library("camera_napi") { "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/input/camera_manager_napi.cpp", "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/input/camera_mute_listener_napi.cpp", "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/input/camera_napi.cpp", + "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/input/camera_pre_launch_config_napi.cpp", "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/input/camera_profile_napi.cpp", "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/input/camera_size_napi.cpp", "${multimedia_camera_framework_path}/frameworks/js/camera_napi/src/mode/mode_manager_napi.cpp", diff --git a/interfaces/kits/js/camera_napi/include/input/camera_manager_napi.h b/interfaces/kits/js/camera_napi/include/input/camera_manager_napi.h index ff1d37912eb0683cd8aee39f35e7a70868e7b17d..446b9f415e5f31247cf79572c3e7f090a442b751 100644 --- a/interfaces/kits/js/camera_napi/include/input/camera_manager_napi.h +++ b/interfaces/kits/js/camera_napi/include/input/camera_manager_napi.h @@ -66,6 +66,9 @@ public: static napi_value IsCameraMuteSupported(napi_env env, napi_callback_info info); static napi_value MuteCamera(napi_env env, napi_callback_info info); + static napi_value PrelaunchCamera(napi_env env, napi_callback_info info); + static napi_value SetPreLaunchConfig(napi_env env, napi_callback_info info); + static napi_value IsPreLaunchSupported(napi_env env, napi_callback_info info); static napi_value GetSupportedCameras(napi_env env, napi_callback_info info); static napi_value CreateCameraInputInstance(napi_env env, napi_callback_info info); static napi_value CreateCameraSessionInstance(napi_env env, napi_callback_info info); diff --git a/interfaces/kits/js/camera_napi/include/input/camera_pre_launch_config_napi.h b/interfaces/kits/js/camera_napi/include/input/camera_pre_launch_config_napi.h new file mode 100644 index 0000000000000000000000000000000000000000..2f96bec1201a276e74e2be9653373fb44f2c0547 --- /dev/null +++ b/interfaces/kits/js/camera_napi/include/input/camera_pre_launch_config_napi.h @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#ifndef CAMERA_PRE_LAUNCH_CONFIG_NAPI_H +#define CAMERA_PRE_LAUNCH_CONFIG_NAPI_H + +#include "camera_log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#include "hilog/log.h" +#include "camera_napi_utils.h" +#include "input/prelaunch_config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace OHOS { +namespace CameraStandard { +static const char CAMERA_PRELAUNCH_CONFIG_NAPI_CLASS_NAME[] = "PreLauncherConfig"; + +class CameraPreLaunchConfigNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + static napi_value GetPreLaunchCameraDevice(napi_env env, napi_callback_info info); + CameraPreLaunchConfigNapi(); + ~CameraPreLaunchConfigNapi(); + PreLaunchConfig* preLaunchConfig_; + static thread_local PreLaunchConfig* sPreLaunchConfig_; + +private: + static void CameraPreLaunchConfigNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value CameraPreLaunchConfigNapiConstructor(napi_env env, napi_callback_info info); + napi_env env_; + napi_ref wrapper_; + + static thread_local napi_ref sConstructor_; +}; +} // namespace CameraStandard +} // namespace OHOS +#endif // CAMERA_PRE_LAUNCH_CONFIG_NAPI_H diff --git a/interfaces/kits/js/camera_napi/include/native_module_ohos_camera.h b/interfaces/kits/js/camera_napi/include/native_module_ohos_camera.h index 3766a35801fdc953e8e6330bb9ca6ca6fa431fcd..512922d21b3b9c20d33321ebb11aee0d1cbcc0cb 100644 --- a/interfaces/kits/js/camera_napi/include/native_module_ohos_camera.h +++ b/interfaces/kits/js/camera_napi/include/native_module_ohos_camera.h @@ -24,6 +24,7 @@ #include "session/camera_session_napi.h" #include "input/camera_manager_napi.h" #include "input/camera_napi.h" +#include "input/camera_pre_launch_config_napi.h" #include "output/metadata_object_napi.h" #include "mode/mode_manager_napi.h" #include "mode/portrait_session_napi.h" diff --git a/interfaces/kits/js/camera_napi/include/output/photo_output_napi.h b/interfaces/kits/js/camera_napi/include/output/photo_output_napi.h index 42f2ace75b33eb7211a3b9b9289a31bec4825f0e..3979d2fda12ad09ceb6ad1e1134219bc1683b497 100644 --- a/interfaces/kits/js/camera_napi/include/output/photo_output_napi.h +++ b/interfaces/kits/js/camera_napi/include/output/photo_output_napi.h @@ -44,6 +44,9 @@ namespace OHOS { namespace CameraStandard { +const std::string dataWidth = "dataWidth"; +const std::string dataHeight = "dataHeight"; +const std::string thumbnailRegisterName = "quickThumbnail"; static const char CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME[] = "PhotoOutput"; struct CallbackInfo { @@ -75,6 +78,20 @@ private: napi_ref errorCallbackRef_ = nullptr; }; +class ThumbnailListener : public IBufferConsumerListener { +public: + explicit ThumbnailListener(napi_env env, const napi_ref &callbackRef, const sptr photoOutput_); + ~ThumbnailListener() = default; + void OnBufferAvailable() override; + +private: + napi_env env_; + napi_ref thumbnailCallbackRef_ = nullptr; + sptr photoOutput_; + void UpdateJSCallback(sptr photoOutput) const; + void UpdateJSCallbackAsync(sptr photoOutput) const; +}; + struct PhotoOutputCallbackInfo { std::string eventName_; CallbackInfo info_; @@ -83,6 +100,13 @@ struct PhotoOutputCallbackInfo { : eventName_(eventName), info_(info), listener_(listener) {} }; +struct ThumbnailListenerInfo { + sptr photoOutput_; + const ThumbnailListener* listener_; + ThumbnailListenerInfo(sptr photoOutput, const ThumbnailListener* listener) + : photoOutput_(photoOutput), listener_(listener) {} +}; + class PhotoOutputNapi { public: static napi_value Init(napi_env env, napi_value exports); @@ -93,6 +117,8 @@ public: static napi_value Release(napi_env env, napi_callback_info info); static napi_value IsMirrorSupported(napi_env env, napi_callback_info info); static napi_value SetMirror(napi_env env, napi_callback_info info); + static napi_value EnableQuickThumbnail(napi_env env, napi_callback_info info); + static napi_value IsQuickThumbnailSupported(napi_env env, napi_callback_info info); static napi_value On(napi_env env, napi_callback_info info); static bool IsPhotoOutput(napi_env env, napi_value obj); @@ -111,6 +137,8 @@ private: napi_env env_; napi_ref wrapper_; sptr photoOutput_; + Profile profile_; + bool isQuickThumbnailEnabled_ = false; std::shared_ptr photoCallback_ = nullptr; static thread_local uint32_t photoOutputTaskId; }; diff --git a/interfaces/kits/js/camera_napi/include/output/preview_output_napi.h b/interfaces/kits/js/camera_napi/include/output/preview_output_napi.h index ae56178f0d81bd52fa4c2851cdd34ce3033dccb8..857233152e076108a90c38e77712bb04f472082a 100644 --- a/interfaces/kits/js/camera_napi/include/output/preview_output_napi.h +++ b/interfaces/kits/js/camera_napi/include/output/preview_output_napi.h @@ -43,6 +43,7 @@ namespace OHOS { namespace CameraStandard { +struct PreviewOutputAsyncContext; static const char CAMERA_PREVIEW_OUTPUT_NAPI_CLASS_NAME[] = "PreviewOutput"; class PreviewOutputCallback : public PreviewStateCallback { @@ -77,6 +78,7 @@ class PreviewOutputNapi : public CameraOutputNapi { public: static napi_value Init(napi_env env, napi_value exports); static napi_value CreatePreviewOutput(napi_env env, Profile &profile, std::string surfaceId); + static napi_value CreateDeferredPreviewOutput(napi_env env, Profile &profile); static bool IsPreviewOutput(napi_env env, napi_value obj); static napi_value AddDeferredSurface(napi_env env, napi_callback_info info); static napi_value Start(napi_env env, napi_callback_info info); @@ -90,6 +92,8 @@ public: private: static void PreviewOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); static napi_value PreviewOutputNapiConstructor(napi_env env, napi_callback_info info); + static napi_status CreateAsyncTask(napi_env env, napi_value resource, + std::unique_ptr &asyncContext); napi_env env_; napi_ref wrapper_; @@ -104,6 +108,7 @@ private: struct PreviewOutputAsyncContext : public AsyncContext { PreviewOutputNapi* objectInfo; bool bRetBool; + std::string surfaceId; ~PreviewOutputAsyncContext() { objectInfo = nullptr; diff --git a/services/camera_service/BUILD.gn b/services/camera_service/BUILD.gn index 14e34017b4b005cba2a676e0473c19433fe30a7f..7767e7760952a4b1ced0d4467225082ee6de711a 100644 --- a/services/camera_service/BUILD.gn +++ b/services/camera_service/BUILD.gn @@ -73,6 +73,7 @@ ohos_shared_library("camera_service") { "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "drivers_interface_camera:libcamera_proxy_1.0", + "drivers_interface_camera:libcamera_proxy_1.1", "drivers_interface_camera:metadata", "graphic_standard:librender_service_client", "graphic_standard:surface", diff --git a/services/camera_service/binder/base/include/icamera_service.h b/services/camera_service/binder/base/include/icamera_service.h index d4acf2d02a4f6927adf40b66968f37c870634a89..cd64c9e8e74388848f641a8b5551bdaffe8d16e1 100644 --- a/services/camera_service/binder/base/include/icamera_service.h +++ b/services/camera_service/binder/base/include/icamera_service.h @@ -60,6 +60,10 @@ public: virtual int32_t MuteCamera(bool muteMode) = 0; + virtual int32_t PrelaunchCamera() = 0; + + virtual int32_t SetPrelaunchConfig(std::string cameraId) = 0; + virtual int32_t IsCameraMuted(bool &muteMode) = 0; DECLARE_INTERFACE_DESCRIPTOR(u"ICameraService"); diff --git a/services/camera_service/binder/base/include/istream_capture.h b/services/camera_service/binder/base/include/istream_capture.h index 5967750f281fce702fa4291cafaa368c8b1463fd..623171da76cd3de4799b1be1653e7479e0282671 100644 --- a/services/camera_service/binder/base/include/istream_capture.h +++ b/services/camera_service/binder/base/include/istream_capture.h @@ -19,6 +19,7 @@ #include "camera_metadata_info.h" #include "istream_capture_callback.h" #include "istream_common.h" +#include "surface.h" namespace OHOS { namespace CameraStandard { @@ -32,6 +33,8 @@ public: virtual int32_t Release() = 0; + virtual int32_t SetThumbnail(bool isEnabled, const sptr &producer) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"IStreamCapture"); }; } // namespace CameraStandard diff --git a/services/camera_service/binder/base/include/remote_request_code.h b/services/camera_service/binder/base/include/remote_request_code.h index 3a35c7843b7064520550b4562946ace841eb4ab0..90e784921a63241b1e20480a89f016167d50ebff 100644 --- a/services/camera_service/binder/base/include/remote_request_code.h +++ b/services/camera_service/binder/base/include/remote_request_code.h @@ -76,6 +76,8 @@ enum CameraServiceRequestCode { CAMERA_SERVICE_CREATE_METADATA_OUTPUT, CAMERA_SERVICE_MUTE_CAMERA, CAMERA_SERVICE_IS_CAMERA_MUTED, + CAMERA_SERVICE_PRE_LAUNCH_CAMERA, + CAMERA_SERVICE_SET_PRE_LAUNCH_CAMERA }; /** @@ -108,7 +110,8 @@ enum StreamCaptureRequestCode { CAMERA_STREAM_CAPTURE_START = 0, CAMERA_STREAM_CAPTURE_CANCEL, CAMERA_STREAM_CAPTURE_SET_CALLBACK, - CAMERA_STREAM_CAPTURE_RELEASE + CAMERA_STREAM_CAPTURE_RELEASE, + CAMERA_SERVICE_SET_THUMBNAIL }; /** diff --git a/services/camera_service/binder/client/include/hcamera_service_proxy.h b/services/camera_service/binder/client/include/hcamera_service_proxy.h index 3479ce06ea46792ed86521bd472ec735e66ae5d8..893558dbc07086ee4cc64e31895ed7d7083c287e 100644 --- a/services/camera_service/binder/client/include/hcamera_service_proxy.h +++ b/services/camera_service/binder/client/include/hcamera_service_proxy.h @@ -58,6 +58,10 @@ public: int32_t MuteCamera(bool muteMode) override; + int32_t PrelaunchCamera() override; + + int32_t SetPrelaunchConfig(std::string cameraId) override; + int32_t IsCameraMuted(bool &muteMode) override; private: diff --git a/services/camera_service/binder/client/include/hstream_capture_proxy.h b/services/camera_service/binder/client/include/hstream_capture_proxy.h index 2cee21a1dc9edb0e3ef63389538505a0d9b1a9d3..e288c18480e4e2d8ae64b5e055bd57032f7b4940 100644 --- a/services/camera_service/binder/client/include/hstream_capture_proxy.h +++ b/services/camera_service/binder/client/include/hstream_capture_proxy.h @@ -35,6 +35,8 @@ public: int32_t SetCallback(sptr &callback) override; + int32_t SetThumbnail(bool isEnabled, const sptr &producer) override; + private: static inline BrokerDelegator delegator_; }; diff --git a/services/camera_service/binder/client/src/hcamera_service_proxy.cpp b/services/camera_service/binder/client/src/hcamera_service_proxy.cpp index 103b2b1d3c5b4d6bf67b86c9371711608b2c6726..95017d0b49981de4c8cfc0854b8e65f3234e33f5 100644 --- a/services/camera_service/binder/client/src/hcamera_service_proxy.cpp +++ b/services/camera_service/binder/client/src/hcamera_service_proxy.cpp @@ -455,6 +455,49 @@ int32_t HCameraServiceProxy::MuteCamera(bool muteMode) return error; } +int32_t HCameraServiceProxy::PrelaunchCamera() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + MEDIA_ERR_LOG("HCameraServiceProxy::PrelaunchCamera Failed to write descriptor"); + return IPC_PROXY_ERR; + } + + int error = Remote()->SendRequest(CAMERA_SERVICE_PRE_LAUNCH_CAMERA, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("HCameraServiceProxy::PrelaunchCamera failed, error: %{public}d", error); + return IPC_PROXY_ERR; + } + return error; +} + +int32_t HCameraServiceProxy::SetPrelaunchConfig(std::string cameraId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + MEDIA_ERR_LOG("HCameraServiceProxy::SetPrelaunchConfig Failed to write descriptor"); + return IPC_PROXY_ERR; + } + + if (!data.WriteString(cameraId)) { + MEDIA_ERR_LOG("HCameraServiceProxy SetPrelaunchConfig Write CameraId failed"); + return IPC_PROXY_ERR; + } + + int32_t error = Remote()->SendRequest(CAMERA_SERVICE_SET_PRE_LAUNCH_CAMERA, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("HCameraServiceProxy::SetPrelaunchConfig failed, error: %{public}d", error); + return IPC_PROXY_ERR; + } + return error; +} + int32_t HCameraServiceProxy::IsCameraMuted(bool &muteMode) { MessageParcel data; diff --git a/services/camera_service/binder/client/src/hstream_capture_proxy.cpp b/services/camera_service/binder/client/src/hstream_capture_proxy.cpp index 13056c79e5a2c0e22c1381bc12e3b86ab4f44484..d522527afe2a090bee7f183458f34a68e56418e4 100644 --- a/services/camera_service/binder/client/src/hstream_capture_proxy.cpp +++ b/services/camera_service/binder/client/src/hstream_capture_proxy.cpp @@ -109,5 +109,37 @@ int32_t HStreamCaptureProxy::SetCallback(sptr &callback) return error; } + +int32_t HStreamCaptureProxy::SetThumbnail(bool isEnabled, const sptr &producer) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (producer == nullptr) { + MEDIA_ERR_LOG("HCameraServiceProxy CreatePhotoOutput producer is null"); + return IPC_PROXY_ERR; + } + + if (!data.WriteInterfaceToken(GetDescriptor())) { + MEDIA_ERR_LOG("HCameraServiceProxy SetThumbnail Write interface token failed"); + return IPC_PROXY_ERR; + } + if (!data.WriteRemoteObject(producer->AsObject())) { + MEDIA_ERR_LOG("HCameraServiceProxy SetThumbnail write producer obj failed"); + return IPC_PROXY_ERR; + } + + if (!data.WriteBool(isEnabled)) { + MEDIA_ERR_LOG("HCameraServiceProxy SetThumbnail write isEnabled failed"); + return IPC_PROXY_ERR; + } + + int error = Remote()->SendRequest(CAMERA_SERVICE_SET_THUMBNAIL, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("HCameraServiceProxy SetThumbnail failed, error: %{public}d", error); + } + return error; +} } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/binder/server/include/hcamera_service_stub.h b/services/camera_service/binder/server/include/hcamera_service_stub.h index da1950f2020f55d109f63254c055fd5af223937f..feab0379e9b56d821d5229333d5c222b61a3895f 100644 --- a/services/camera_service/binder/server/include/hcamera_service_stub.h +++ b/services/camera_service/binder/server/include/hcamera_service_stub.h @@ -44,6 +44,8 @@ private: int HandleCreateVideoOutput(MessageParcel &data, MessageParcel &reply); int HandleMuteCamera(MessageParcel &data, MessageParcel &reply); int HandleIsCameraMuted(MessageParcel &data, MessageParcel &reply); + int HandlePrelaunchCamera(MessageParcel &data, MessageParcel &reply); + int HandleSetPrelaunchConfig(MessageParcel &data, MessageParcel &reply); int DestroyStubForPid(pid_t pid); void ClientDied(pid_t pid); int SetListenerObject(const sptr &object) override; diff --git a/services/camera_service/binder/server/include/hstream_capture_stub.h b/services/camera_service/binder/server/include/hstream_capture_stub.h index 14f4dd7fec1c630cb91fff56db0e96a0feec12b7..da25b7450a53d9137fd74d266a07dba18dd04ea3 100644 --- a/services/camera_service/binder/server/include/hstream_capture_stub.h +++ b/services/camera_service/binder/server/include/hstream_capture_stub.h @@ -29,6 +29,7 @@ public: public: int HandleCapture(MessageParcel &data); int HandleSetCallback(MessageParcel &data); + int HandleSetThumbnail(MessageParcel &data); }; } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/binder/server/src/hcamera_service_stub.cpp b/services/camera_service/binder/server/src/hcamera_service_stub.cpp index 2f3adcb366295d06261c71ef5ea37fa2d2fac25b..d73b11e92e32a16ee7262880723b40fc935ccaca 100644 --- a/services/camera_service/binder/server/src/hcamera_service_stub.cpp +++ b/services/camera_service/binder/server/src/hcamera_service_stub.cpp @@ -73,6 +73,8 @@ void HCameraServiceStub::RegisterMethod() methodFactory[CAMERA_SERVICE_CREATE_METADATA_OUTPUT] = &HCameraServiceStub::HandleCreateMetadataOutput; methodFactory[CAMERA_SERVICE_CREATE_VIDEO_OUTPUT] = &HCameraServiceStub::HandleCreateVideoOutput; methodFactory[CAMERA_SERVICE_SET_LISTENER_OBJ] = &HCameraServiceStub::SetListenerObject; + methodFactory[CAMERA_SERVICE_PRE_LAUNCH_CAMERA] = &HCameraServiceStub::HandlePrelaunchCamera; + methodFactory[CAMERA_SERVICE_SET_PRE_LAUNCH_CAMERA] = &HCameraServiceStub::HandleSetPrelaunchConfig; } int32_t HCameraServiceStub::CheckRequestCode( @@ -144,6 +146,23 @@ int HCameraServiceStub::HandleMuteCamera(MessageParcel &data, MessageParcel &rep return ret; } +int HCameraServiceStub::HandlePrelaunchCamera(MessageParcel &data, MessageParcel &reply) +{ + MEDIA_DEBUG_LOG("HCameraServiceStub HandlePrelaunchCamera enter"); + int32_t ret = PrelaunchCamera(); + MEDIA_INFO_LOG("HCameraServiceStub HandlePrelaunchCamera result: %{public}d", ret); + return ret; +} + +int HCameraServiceStub::HandleSetPrelaunchConfig(MessageParcel &data, MessageParcel &reply) +{ + MEDIA_DEBUG_LOG("HCameraServiceStub HandleSetPrelaunchConfig enter"); + std::string cameraId = data.ReadString(); + int32_t ret = SetPrelaunchConfig(cameraId); + MEDIA_INFO_LOG("HCameraServiceStub HandleSetPrelaunchConfig result: %{public}d", ret); + return ret; +} + int HCameraServiceStub::HandleIsCameraMuted(MessageParcel &data, MessageParcel &reply) { bool isMuted = false; diff --git a/services/camera_service/binder/server/src/hstream_capture_stub.cpp b/services/camera_service/binder/server/src/hstream_capture_stub.cpp index faff0b3d39362cc652498ce5359e874f0b2ddbae..a3e2842f892097f8421edeb8b48f03fd412c56cf 100644 --- a/services/camera_service/binder/server/src/hstream_capture_stub.cpp +++ b/services/camera_service/binder/server/src/hstream_capture_stub.cpp @@ -43,6 +43,9 @@ int HStreamCaptureStub::OnRemoteRequest( case CAMERA_STREAM_CAPTURE_RELEASE: errCode = Release(); break; + case CAMERA_SERVICE_SET_THUMBNAIL: + errCode = HandleSetThumbnail(data); + break; default: MEDIA_ERR_LOG("HStreamCaptureStub request code %{public}u not handled", code); errCode = IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -60,6 +63,20 @@ int HStreamCaptureStub::HandleCapture(MessageParcel &data) return Capture(metadata); } +int HStreamCaptureStub::HandleSetThumbnail(MessageParcel &data) +{ + sptr remoteObj = data.ReadRemoteObject(); + if (remoteObj == nullptr) { + MEDIA_ERR_LOG("HCameraServiceStub HandleCreatePhotoOutput BufferProducer is null"); + return IPC_STUB_INVALID_DATA_ERR; + } + sptr producer = iface_cast(remoteObj); + bool isEnabled = data.ReadBool(); + int32_t ret = SetThumbnail(isEnabled, producer); + MEDIA_DEBUG_LOG("HCameraServiceStub HandleSetThumbnail result: %{public}d", ret); + return ret; +} + int HStreamCaptureStub::HandleSetCallback(MessageParcel &data) { auto remoteObject = data.ReadRemoteObject(); diff --git a/services/camera_service/include/camera_util.h b/services/camera_service/include/camera_util.h index 1fa3ef4f258eee8fb3098a674cf74b2a8b991967..34eccea7f9d0f700b95da87a2fd712ec017ff876 100644 --- a/services/camera_service/include/camera_util.h +++ b/services/camera_service/include/camera_util.h @@ -82,6 +82,8 @@ void ReleaseCaptureId(int32_t captureId); bool IsValidTokenId(uint32_t tokenId); +int32_t GetVersionId(uint32_t major, uint32_t minor); + bool IsValidSize( std::shared_ptr cameraAbility, int32_t format, int32_t width, int32_t height); diff --git a/services/camera_service/include/hcamera_device.h b/services/camera_service/include/hcamera_device.h index 032f5423f4b22a61cdaa80593e79de71cd4d9088..9032d45f6c9562540967279d9af96dd9573469df 100644 --- a/services/camera_service/include/hcamera_device.h +++ b/services/camera_service/include/hcamera_device.h @@ -47,8 +47,8 @@ public: int32_t EnableResult(std::vector &results) override; int32_t DisableResult(std::vector &results) override; int32_t GetStreamOperator(sptr callback, - sptr &streamOperator); - sptr GetStreamOperator(); + sptr &streamOperator); + sptr GetStreamOperator(); int32_t SetCallback(sptr &callback) override; int32_t OnError(ErrorType type, int32_t errorCode) override; int32_t OnResult(uint64_t timestamp, const std::vector& result) override; @@ -63,7 +63,7 @@ public: int32_t GetCallerToken(); private: - sptr hdiCameraDevice_; + sptr hdiCameraDevice_; sptr cameraHostManager_; std::string cameraID_; bool isReleaseCameraDevice_; @@ -74,7 +74,7 @@ private: sptr deviceSvcCallback_; std::map> statusSvcCallbacks_; std::shared_ptr updateSettings_; - sptr streamOperator_; + sptr streamOperator_; uint32_t callerToken_; std::vector videoFrameRateRange_; wptr deviceOperatorsCallback_; diff --git a/services/camera_service/include/hcamera_host_manager.h b/services/camera_service/include/hcamera_host_manager.h index 387b24ffc2fa21bee83fd467f58d180536a0d7df..d4c7b51493906ebcf3b3b8b05a7fe3a291fd45df 100644 --- a/services/camera_service/include/hcamera_host_manager.h +++ b/services/camera_service/include/hcamera_host_manager.h @@ -25,6 +25,8 @@ #include "camera_metadata_info.h" #include "v1_0/icamera_device.h" #include "v1_0/icamera_host.h" +#include "v1_1/icamera_device.h" +#include "v1_1/icamera_host.h" #include "icamera_device_service.h" #include "icamera_service_callback.h" #include "iservstat_listener_hdi.h" @@ -48,6 +50,7 @@ public: int32_t Init(void); void DeInit(void); void AddCameraDevice(const std::string& cameraId, sptr cameraDevice); + int32_t GetVersionByCamera(const std::string& cameraId); void RemoveCameraDevice(const std::string& cameraId); void CloseCameraDevice(const std::string& cameraId); @@ -55,8 +58,9 @@ public: virtual int32_t GetCameraAbility(std::string &cameraId, std::shared_ptr &ability); virtual int32_t OpenCameraDevice(std::string &cameraId, const sptr &callback, - sptr &pDevice); + sptr &pDevice); virtual int32_t SetFlashlight(const std::string& cameraId, bool isEnable); + virtual int32_t PreLaunch(const std::string& cameraId); // HDI::ServiceManager::V1_0::IServStatListener void OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status) override; diff --git a/services/camera_service/include/hcamera_service.h b/services/camera_service/include/hcamera_service.h index c0dc4b4b097ffb1390fd3853790594be55af6a1c..06be96a942d2df2604d911b21103d6e57243b000 100644 --- a/services/camera_service/include/hcamera_service.h +++ b/services/camera_service/include/hcamera_service.h @@ -65,6 +65,8 @@ public: int32_t CloseCameraForDestory(pid_t pid) override; int32_t SetMuteCallback(sptr &callback) override; int32_t MuteCamera(bool muteMode) override; + int32_t PrelaunchCamera() override; + int32_t SetPrelaunchConfig(std::string cameraId) override; int32_t IsCameraMuted(bool &muteMode) override; void OnDump() override; void OnStart() override; @@ -106,6 +108,7 @@ private: void CameraDumpVideoFrameRateRange(common_metadata_header_t* metadataEntry, std::string& dumpString); bool IsCameraMuteSupported(std::string cameraId); + bool IsPrelaunchSupported(std::string cameraId); int32_t UpdateMuteSetting(sptr cameraDevice, bool muteMode); int32_t UnSetMuteCallback(pid_t pid); bool IsDeviceAlreadyOpen(pid_t& tempPid, std::string& tempCameraId, sptr &tempDevice); @@ -121,6 +124,7 @@ private: std::map> camerasForPid_; bool muteMode_; std::mutex mapOperatorsLock_; + std::string preCameraId_; }; } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/include/hcapture_session.h b/services/camera_service/include/hcapture_session.h index 4f8af14f88eef707ed46bc8ff3b21ca65d756f38..ff83e8351f5f4147133a8c9837fa166dfa6051e2 100644 --- a/services/camera_service/include/hcapture_session.h +++ b/services/camera_service/include/hcapture_session.h @@ -30,6 +30,7 @@ #include "privacy_kit.h" #include "v1_0/istream_operator_callback.h" #include "v1_0/istream_operator.h" +#include "v1_1/istream_operator.h" namespace OHOS { namespace CameraStandard { @@ -82,14 +83,14 @@ private: int32_t HandleCaptureOuputsConfig(sptr &device); int32_t CreateAndCommitStreams(sptr &device, std::shared_ptr &deviceSettings, - std::vector &streamInfos); + std::vector &streamInfos); int32_t CheckAndCommitStreams(sptr &device, std::shared_ptr &deviceSettings, - std::vector &allStreamInfos, - std::vector &newStreamInfos); + std::vector &allStreamInfos, + std::vector &newStreamInfos); int32_t GetCurrentStreamInfos(sptr &device, std::shared_ptr &deviceSettings, - std::vector &streamInfos); + std::vector &streamInfos); void UpdateSessionConfig(sptr &device); void DeleteReleasedStream(); void RestorePreviousState(sptr &device, bool isCreateReleaseStreams); diff --git a/services/camera_service/include/hstream_capture.h b/services/camera_service/include/hstream_capture.h index 782bb685613fffcfed364b990c101b17a0e33902..9ced16d910da906a22a2561a4dfe48319bc4e814 100644 --- a/services/camera_service/include/hstream_capture.h +++ b/services/camera_service/include/hstream_capture.h @@ -33,9 +33,10 @@ public: HStreamCapture(sptr producer, int32_t format, int32_t width, int32_t height); ~HStreamCapture(); - int32_t LinkInput(sptr streamOperator, + int32_t LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) override; - void SetStreamInfo(StreamInfo &streamInfo) override; + void SetStreamInfo(StreamInfo_V1_1 &streamInfo) override; + int32_t SetThumbnail(bool isEnabled, const sptr &producer) override; int32_t Capture(const std::shared_ptr &captureSettings) override; int32_t CancelCapture() override; int32_t Release() override; @@ -51,6 +52,8 @@ public: private: sptr streamCaptureCallback_; std::mutex callbackLock_; + int32_t thumbnailSwitch_ = 0; + sptr thumbnailBufferQueue_; }; } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/include/hstream_common.h b/services/camera_service/include/hstream_common.h index 0236938045b76b8356b5f991470587744db694a1..247e16527a8f0c266fe085e184dc6419b0bdc7a9 100644 --- a/services/camera_service/include/hstream_common.h +++ b/services/camera_service/include/hstream_common.h @@ -19,6 +19,7 @@ #include "camera_metadata_info.h" #include "istream_common.h" #include "v1_0/istream_operator.h" +#include "v1_1/istream_operator.h" #include #include @@ -26,14 +27,15 @@ namespace OHOS { namespace CameraStandard { using namespace OHOS::HDI::Camera::V1_0; +using OHOS::HDI::Camera::V1_1::StreamInfo_V1_1; class HStreamCommon : virtual public RefBase { public: HStreamCommon(StreamType streamType, sptr producer, int32_t format, int32_t width, int32_t height); virtual ~HStreamCommon(); - virtual int32_t LinkInput(sptr streamOperator, + virtual int32_t LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) = 0; - virtual void SetStreamInfo(StreamInfo &streamInfo) = 0; + virtual void SetStreamInfo(StreamInfo_V1_1 &streamInfo) = 0; virtual int32_t Release() = 0; virtual void DumpStreamInfo(std::string& dumpString) = 0; virtual bool IsReleaseStream() final; diff --git a/services/camera_service/include/hstream_metadata.h b/services/camera_service/include/hstream_metadata.h index 65e2bc6288c16fd675059947e00ae115d1c843b4..c0f6f1c2dc8fc6df193c8946404aa9e3354b160a 100644 --- a/services/camera_service/include/hstream_metadata.h +++ b/services/camera_service/include/hstream_metadata.h @@ -32,9 +32,9 @@ public: HStreamMetadata(sptr producer, int32_t format); ~HStreamMetadata(); - int32_t LinkInput(sptr streamOperator, + int32_t LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) override; - void SetStreamInfo(StreamInfo &streamInfo) override; + void SetStreamInfo(StreamInfo_V1_1 &streamInfo) override; int32_t Release() override; int32_t Start() override; int32_t Stop() override; diff --git a/services/camera_service/include/hstream_repeat.h b/services/camera_service/include/hstream_repeat.h index b70d7248cf1b9560da4feffc36c5f982dedc400a..94856dcace83a9fad126d21b24ef514a4fc380b0 100644 --- a/services/camera_service/include/hstream_repeat.h +++ b/services/camera_service/include/hstream_repeat.h @@ -33,9 +33,9 @@ public: HStreamRepeat(sptr producer, int32_t format, int32_t width, int32_t height, bool isVideo); ~HStreamRepeat(); - int32_t LinkInput(sptr streamOperator, + int32_t LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) override; - void SetStreamInfo(StreamInfo &streamInfo) override; + void SetStreamInfo(StreamInfo_V1_1 &streamInfo) override; int32_t Release() override; int32_t Start() override; int32_t Stop() override; diff --git a/services/camera_service/src/camera_util.cpp b/services/camera_service/src/camera_util.cpp index d58c16fb6dd5a6e17db93fca79f5f1d6549785b4..8118aaebe553f2ac0ac4feb3f1afefc3f1a85af3 100644 --- a/services/camera_service/src/camera_util.cpp +++ b/services/camera_service/src/camera_util.cpp @@ -234,5 +234,11 @@ int32_t CheckPermission(std::string permissionName, uint32_t callerToken) } return CAMERA_OK; } + +int32_t GetVersionId(uint32_t major, uint32_t minor) +{ + const uint32_t offset = 8; + return static_cast((major << offset) | minor); +} } // namespace CameraStandard } // namespace OHOS diff --git a/services/camera_service/src/hcamera_device.cpp b/services/camera_service/src/hcamera_device.cpp index e386da721465c09d70763a79ccd44509775d16da..331538d5f1acadc38e9feb51cb76873e64c45218 100644 --- a/services/camera_service/src/hcamera_device.cpp +++ b/services/camera_service/src/hcamera_device.cpp @@ -414,7 +414,7 @@ int32_t HCameraDevice::SetCallback(sptr &callback) } int32_t HCameraDevice::GetStreamOperator(sptr callback, - sptr &streamOperator) + sptr &streamOperator) { if (callback == nullptr) { MEDIA_ERR_LOG("HCameraDevice::GetStreamOperator callback is null"); @@ -425,8 +425,16 @@ int32_t HCameraDevice::GetStreamOperator(sptr callback, MEDIA_ERR_LOG("HCameraDevice::hdiCameraDevice_ is null"); return CAMERA_UNKNOWN_ERROR; } + CamRetCode rc; + if (GetVersionId(1, 1) == cameraHostManager_->GetVersionByCamera(cameraID_)) { + rc = (CamRetCode)(hdiCameraDevice_->GetStreamOperator_V1_1(callback, streamOperator)); + } else { + sptr tempStreamOperator; + rc = (CamRetCode)(hdiCameraDevice_->GetStreamOperator(callback, tempStreamOperator)); + // static_cast to V1.1 + streamOperator = static_cast(tempStreamOperator.GetRefPtr()); + } - CamRetCode rc = (CamRetCode)(hdiCameraDevice_->GetStreamOperator(callback, streamOperator)); if (rc != HDI::Camera::V1_0::NO_ERROR) { MEDIA_ERR_LOG("HCameraDevice::GetStreamOperator failed with error Code:%{public}d", rc); return HdiToServiceError(rc); @@ -445,7 +453,7 @@ int32_t HCameraDevice::SetDeviceOperatorsCallback(wptr return CAMERA_OK; } -sptr HCameraDevice::GetStreamOperator() +sptr HCameraDevice::GetStreamOperator() { return streamOperator_; } diff --git a/services/camera_service/src/hcamera_host_manager.cpp b/services/camera_service/src/hcamera_host_manager.cpp index faa81c5b761a3267be304d87ddb73922863f3055..62362fd31994102bffcb1623c6092451c105538c 100644 --- a/services/camera_service/src/hcamera_host_manager.cpp +++ b/services/camera_service/src/hcamera_host_manager.cpp @@ -66,11 +66,13 @@ public: void CameraHostDied(); bool IsCameraSupported(const std::string& cameraId); const std::string& GetName(); + int32_t GetCameraHostVersion(); int32_t GetCameras(std::vector& cameraIds); int32_t GetCameraAbility(std::string& cameraId, std::shared_ptr& ability); int32_t OpenCamera(std::string& cameraId, const sptr& callback, - sptr& pDevice); + sptr& pDevice); int32_t SetFlashlight(const std::string& cameraId, bool isEnable); + int32_t PreLaunch(const std::string& cameraId); // CameraHostCallbackStub int32_t OnCameraStatus(const std::string& cameraId, HDI::Camera::V1_0::CameraStatus status) override; @@ -84,7 +86,9 @@ private: HCameraHostManager* cameraHostManager_; std::string name_; - sptr cameraHostProxy_; + uint32_t majorVer_; + uint32_t minorVer_; + sptr cameraHostProxy_; std::mutex mutex_; std::vector cameraIds_; @@ -115,11 +119,13 @@ bool HCameraHostManager::CameraHostInfo::Init() MEDIA_ERR_LOG("CameraHostInfo::Init, no camera host proxy"); return true; } - cameraHostProxy_ = ICameraHost::Get(name_.c_str(), false); + cameraHostProxy_ = OHOS::HDI::Camera::V1_1::ICameraHost::Get(name_.c_str(), false); if (cameraHostProxy_ == nullptr) { MEDIA_ERR_LOG("Failed to get ICameraHost"); return false; } + // Get cameraHost veresion + cameraHostProxy_->GetVersion(majorVer_, minorVer_); cameraHostProxy_->SetCallback(this); sptr cameraHostDeathRecipient = new CameraHostDeathRecipient(this); const sptr &remote = OHOS::HDI::hdi_objcast(cameraHostProxy_); @@ -161,6 +167,12 @@ const std::string& HCameraHostManager::CameraHostInfo::GetName() return name_; } +int32_t HCameraHostManager::CameraHostInfo::GetCameraHostVersion() +{ + MEDIA_INFO_LOG("cameraHostProxy_ GetVersion majorVer_: %u, minorVers_: %u", majorVer_, minorVer_); + return GetVersionId(majorVer_, minorVer_); +} + int32_t HCameraHostManager::CameraHostInfo::GetCameras(std::vector& cameraIds) { std::lock_guard lock(mutex_); @@ -201,7 +213,7 @@ int32_t HCameraHostManager::CameraHostInfo::GetCameraAbility(std::string& camera int32_t HCameraHostManager::CameraHostInfo::OpenCamera(std::string& cameraId, const sptr& callback, - sptr& pDevice) + sptr& pDevice) { MEDIA_INFO_LOG("CameraHostInfo::OpenCamera %{public}s", cameraId.c_str()); auto deviceInfo = FindCameraDeviceInfo(cameraId); @@ -215,7 +227,16 @@ int32_t HCameraHostManager::CameraHostInfo::OpenCamera(std::string& cameraId, MEDIA_ERR_LOG("CameraHostInfo::OpenCamera cameraHostProxy_ is null"); return CAMERA_UNKNOWN_ERROR; } - CamRetCode rc = (CamRetCode)(cameraHostProxy_->OpenCamera(cameraId, callback, pDevice)); + CamRetCode rc; + // try to get higher version + if (GetVersionId(1, 1) == GetCameraHostVersion()) { + rc = (CamRetCode)(cameraHostProxy_->OpenCamera_V1_1(cameraId, callback, pDevice)); + } else { + sptr tempDevice; + rc = (CamRetCode)(cameraHostProxy_->OpenCamera(cameraId, callback, tempDevice)); + // static_cast to V1.1 + pDevice = static_cast(tempDevice.GetRefPtr()); + } if (rc != HDI::Camera::V1_0::NO_ERROR) { MEDIA_ERR_LOG("CameraHostInfo::OpenCamera failed with error Code:%{public}d", rc); return HdiToServiceError(rc); @@ -238,6 +259,27 @@ int32_t HCameraHostManager::CameraHostInfo::SetFlashlight(const std::string& cam return CAMERA_OK; } +int32_t HCameraHostManager::CameraHostInfo::PreLaunch(const std::string& cameraId) +{ + std::lock_guard lock(mutex_); + if (cameraHostProxy_ == nullptr) { + MEDIA_ERR_LOG("CameraHostInfo::PreLaunch cameraHostProxy_ is null"); + return CAMERA_UNKNOWN_ERROR; + } + MEDIA_INFO_LOG("CameraHostInfo::preLaunch for cameraId %{public}s", cameraId.c_str()); + OHOS::HDI::Camera::V1_1::PrelaunchConfig prelaunchConfig; + std::vector settings; + prelaunchConfig.cameraId = cameraId; + prelaunchConfig.streamInfos_V1_1 = {}; + prelaunchConfig.setting = settings; + CamRetCode rc = (CamRetCode)(cameraHostProxy_->Prelaunch(prelaunchConfig)); + if (rc != HDI::Camera::V1_0::NO_ERROR) { + MEDIA_ERR_LOG("CameraHostInfo::PreLaunch failed with error Code:%{public}d", rc); + return HdiToServiceError(rc); + } + return CAMERA_OK; +} + int32_t HCameraHostManager::CameraHostInfo::OnCameraStatus(const std::string& cameraId, HDI::Camera::V1_0::CameraStatus status) { @@ -520,9 +562,20 @@ std::vector> HCameraHostManager::CameraConflictDetect return devicesNeedClose; } +int32_t HCameraHostManager::GetVersionByCamera(const std::string& cameraId) +{ + MEDIA_INFO_LOG("GetVersionByCamera camera = %{public}s", cameraId.c_str()); + auto cameraHostInfo = FindCameraHostInfo(cameraId); + if (cameraHostInfo == nullptr) { + MEDIA_ERR_LOG("GetVersionByCamera failed with invalid device info"); + return 0; + } + return cameraHostInfo->GetCameraHostVersion(); +} + int32_t HCameraHostManager::OpenCameraDevice(std::string &cameraId, const sptr &callback, - sptr &pDevice) + sptr &pDevice) { MEDIA_INFO_LOG("HCameraHostManager::OpenCameraDevice try to open camera = %{public}s", cameraId.c_str()); auto cameraHostInfo = FindCameraHostInfo(cameraId); @@ -543,6 +596,16 @@ int32_t HCameraHostManager::SetFlashlight(const std::string& cameraId, bool isEn return cameraHostInfo->SetFlashlight(cameraId, isEnable); } +int32_t HCameraHostManager::PreLaunch(const std::string& cameraId) +{ + auto cameraHostInfo = FindCameraHostInfo(cameraId); + if (cameraHostInfo == nullptr) { + MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info"); + return CAMERA_INVALID_ARG; + } + return cameraHostInfo->PreLaunch(cameraId); +} + void HCameraHostManager::OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status) { MEDIA_INFO_LOG("HCameraHostManager::OnReceive for camera host %{public}s, status %{public}d", diff --git a/services/camera_service/src/hcamera_service.cpp b/services/camera_service/src/hcamera_service.cpp index 156b13ba48e451b134b8f5cbca7cb59bc9aa70cf..323388608450fc00ae043025b4c9b28e82c822e9 100644 --- a/services/camera_service/src/hcamera_service.cpp +++ b/services/camera_service/src/hcamera_service.cpp @@ -569,6 +569,77 @@ int32_t HCameraService::MuteCamera(bool muteMode) return ret; } +int32_t HCameraService::PrelaunchCamera() +{ + CAMERA_SYNC_TRACE; + OHOS::Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); + std::string permissionName = OHOS_PERMISSION_CAMERA; + int32_t ret = CheckPermission(permissionName, callerToken); + if (ret != CAMERA_OK) { + MEDIA_ERR_LOG("HCameraService::PrelaunchCamera failed permission is : %{public}s", permissionName.c_str()); + return ret; + } + + MEDIA_INFO_LOG("HCameraService::PrelaunchCamera"); + if (preCameraId_.empty()) { + std::vector cameraIds_; + cameraHostManager_->GetCameras(cameraIds_); + preCameraId_= cameraIds_.front(); + } + MEDIA_INFO_LOG("HCameraService::PrelaunchCamera preCameraId_ is: %{public}s", preCameraId_.c_str()); + ret = cameraHostManager_->PreLaunch(preCameraId_); + if (ret != CAMERA_OK) { + MEDIA_ERR_LOG("HCameraService::PreLaunch failed"); + } + return ret; +} + + +int32_t HCameraService::SetPrelaunchConfig(std::string cameraId) +{ + CAMERA_SYNC_TRACE; + OHOS::Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); + std::string permissionName = OHOS_PERMISSION_CAMERA; + int32_t ret = CheckPermission(permissionName, callerToken); + if (ret != CAMERA_OK) { + MEDIA_ERR_LOG("HCameraService::SetPrelaunchConfig failed permission is: %{public}s", permissionName.c_str()); + return ret; + } + + MEDIA_INFO_LOG("HCameraService::SetPrelaunchConfig"); + std::vector cameraIds_; + cameraHostManager_->GetCameras(cameraIds_); + if ((find(cameraIds_.begin(), cameraIds_.end(), cameraId) != cameraIds_.end()) && IsPrelaunchSupported(cameraId)) { + preCameraId_ = cameraId; + } else { + MEDIA_ERR_LOG("HCameraService::SetPrelaunchConfig illegal"); + ret = CAMERA_INVALID_ARG; + } + return ret; +} + +bool HCameraService::IsPrelaunchSupported(std::string cameraId) +{ + bool isPreLaunchSupported = false; + std::shared_ptr cameraAbility; + int32_t ret = cameraHostManager_->GetCameraAbility(cameraId, cameraAbility); + if (ret != CAMERA_OK) { + MEDIA_ERR_LOG("HCameraService::IsCameraMuted GetCameraAbility failed"); + return isPreLaunchSupported; + } + camera_metadata_item_t item; + common_metadata_header_t* metadata = cameraAbility->get(); + ret = OHOS::Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_PRELAUNCH_AVAILABLE, &item); + if (ret == 0) { + MEDIA_INFO_LOG("CameraManager::IsPrelaunchSupported() OHOS_ABILITY_PRELAUNCH_AVAILABLE is %{public}d", + item.data.u8[0]); + isPreLaunchSupported = (item.data.u8[0] == 1); + } else { + MEDIA_ERR_LOG("Failed to get OHOS_ABILITY_PRELAUNCH_AVAILABLE ret = %{public}d", ret); + } + return isPreLaunchSupported; +} + int32_t HCameraService::IsCameraMuted(bool &muteMode) { muteMode = muteMode_; diff --git a/services/camera_service/src/hcapture_session.cpp b/services/camera_service/src/hcapture_session.cpp index f8d0746d7747ab1619d09bfda0f7bab5b3b736a1..e18c83e2dde0f24d0ea52c69aa13443490c6aacd 100644 --- a/services/camera_service/src/hcapture_session.cpp +++ b/services/camera_service/src/hcapture_session.cpp @@ -159,7 +159,7 @@ int32_t HCaptureSession::AddInput(sptr cameraDevice) CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::AddInput")); } - sptr streamOperator; + sptr streamOperator; int32_t rc = localCameraDevice->GetStreamOperator(streamOperatorCallback_, streamOperator); if (rc != CAMERA_OK) { MEDIA_ERR_LOG("HCaptureSession::GetCameraDevice GetStreamOperator returned %{public}d", rc); @@ -346,13 +346,13 @@ int32_t HCaptureSession::GetCameraDevice(sptr &device) int32_t HCaptureSession::GetCurrentStreamInfos(sptr &device, std::shared_ptr &deviceSettings, - std::vector &streamInfos) + std::vector &streamInfos) { int32_t rc; int32_t streamId = streamId_; bool isNeedLink; - StreamInfo curStreamInfo; - sptr streamOperator; + StreamInfo_V1_1 curStreamInfo; + sptr streamOperator; if (device != nullptr) { streamOperator = device->GetStreamOperator(); } @@ -385,16 +385,28 @@ int32_t HCaptureSession::GetCurrentStreamInfos(sptr &device, int32_t HCaptureSession::CreateAndCommitStreams(sptr &device, std::shared_ptr &deviceSettings, - std::vector &streamInfos) + std::vector &streamInfos) { CamRetCode hdiRc = HDI::Camera::V1_0::NO_ERROR; - StreamInfo curStreamInfo; - sptr streamOperator; + StreamInfo_V1_1 curStreamInfo; + sptr streamOperator; if (device != nullptr) { streamOperator = device->GetStreamOperator(); } if (streamOperator != nullptr && !streamInfos.empty()) { - hdiRc = (CamRetCode)(streamOperator->CreateStreams(streamInfos)); + uint32_t major; + uint32_t minor; + streamOperator->GetVersion(major, minor); + MEDIA_INFO_LOG("streamOperator GetVersion major:%d, minor:%d", major, minor); + if (major == 1 && minor == 1) { + hdiRc = (CamRetCode)(streamOperator->CreateStreams_V1_1(streamInfos)); + } else { + std::vector streamInfos_V1_0; + for (auto streamInfo : streamInfos) { + streamInfos_V1_0.emplace_back(streamInfo.v1_0); + } + hdiRc = (CamRetCode)(streamOperator->CreateStreams(streamInfos_V1_0)); + } } else { MEDIA_INFO_LOG("HCaptureSession::CreateAndCommitStreams(), No new streams to create"); } @@ -407,7 +419,7 @@ int32_t HCaptureSession::CreateAndCommitStreams(sptr &device, std::vector streamIds; for (auto item = streamInfos.begin(); item != streamInfos.end(); ++item) { curStreamInfo = *item; - streamIds.emplace_back(curStreamInfo.streamId_); + streamIds.emplace_back(curStreamInfo.v1_0.streamId_); } MEDIA_DEBUG_LOG("HCaptureSession::CreateAndCommitStreams() streamIds size() = %{public}zu", streamIds.size()); @@ -425,8 +437,8 @@ int32_t HCaptureSession::CreateAndCommitStreams(sptr &device, int32_t HCaptureSession::CheckAndCommitStreams(sptr &device, std::shared_ptr &deviceSettings, - std::vector &allStreamInfos, - std::vector &newStreamInfos) + std::vector &allStreamInfos, + std::vector &newStreamInfos) { return CreateAndCommitStreams(device, deviceSettings, newStreamInfos); } @@ -455,8 +467,8 @@ void HCaptureSession::DeleteReleasedStream() void HCaptureSession::RestorePreviousState(sptr &device, bool isCreateReleaseStreams) { - std::vector streamInfos; - StreamInfo streamInfo; + std::vector streamInfos; + StreamInfo_V1_1 streamInfo; std::shared_ptr settings; sptr curStream; @@ -528,11 +540,11 @@ int32_t HCaptureSession::HandleCaptureOuputsConfig(sptr &device) { int32_t rc; int32_t streamId; - std::vector newStreamInfos; - std::vector allStreamInfos; - StreamInfo curStreamInfo; + std::vector newStreamInfos; + std::vector allStreamInfos; + StreamInfo_V1_1 curStreamInfo; std::shared_ptr settings; - sptr streamOperator; + sptr streamOperator; sptr curStream; if (device != nullptr) { settings = device->GetSettings(); @@ -559,6 +571,7 @@ int32_t HCaptureSession::HandleCaptureOuputsConfig(sptr &device) MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() curStream is null"); return CAMERA_UNKNOWN_ERROR; } + MEDIA_INFO_LOG("HandleCaptureOuputsConfig link Output with streamId %{public}d", streamId); rc = curStream->LinkInput(streamOperator, settings, streamId); if (rc != CAMERA_OK) { MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() Failed to link Output, %{public}d", rc); diff --git a/services/camera_service/src/hstream_capture.cpp b/services/camera_service/src/hstream_capture.cpp index 787d8e96ab17e70e5b75e88cadd4819f46cd2cac..8c4d1d87a474761e120c75d6ea9ebf400d99d1b3 100644 --- a/services/camera_service/src/hstream_capture.cpp +++ b/services/camera_service/src/hstream_capture.cpp @@ -29,17 +29,38 @@ HStreamCapture::HStreamCapture(sptr producer, int32_t for HStreamCapture::~HStreamCapture() {} -int32_t HStreamCapture::LinkInput(sptr streamOperator, +int32_t HStreamCapture::LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) { return HStreamCommon::LinkInput(streamOperator, cameraAbility, streamId); } -void HStreamCapture::SetStreamInfo(StreamInfo &streamInfo) +void HStreamCapture::SetStreamInfo(StreamInfo_V1_1 &streamInfo) { HStreamCommon::SetStreamInfo(streamInfo); - streamInfo.intent_ = STILL_CAPTURE; - streamInfo.encodeType_ = ENCODE_TYPE_JPEG; + streamInfo.v1_0.intent_ = STILL_CAPTURE; + streamInfo.v1_0.encodeType_ = ENCODE_TYPE_JPEG; + HDI::Camera::V1_1::ExtendedStreamInfo extendedStreamInfo; + extendedStreamInfo.type = HDI::Camera::V1_1::EXTENDED_STREAM_INFO_QUICK_THUMBNAIL; + extendedStreamInfo.bufferQueue = thumbnailBufferQueue_; + // quickThumbnial do not need these param + extendedStreamInfo.width = 0; + extendedStreamInfo.height = 0; + extendedStreamInfo.format = 0; + extendedStreamInfo.dataspace = 0; + streamInfo.extendedStreamInfos = {extendedStreamInfo}; +} + +int32_t HStreamCapture::SetThumbnail(bool isEnabled, const sptr &producer) +{ + if (isEnabled && producer != nullptr) { + thumbnailSwitch_ = 1; + thumbnailBufferQueue_ = new BufferProducerSequenceable(producer); + } else { + thumbnailSwitch_ = 0; + thumbnailBufferQueue_ = nullptr; + } + return CAMERA_OK; } int32_t HStreamCapture::Capture(const std::shared_ptr &captureSettings) @@ -243,6 +264,12 @@ int32_t HStreamCapture::OnFrameShutter(int32_t captureId, uint64_t timestamp) void HStreamCapture::DumpStreamInfo(std::string& dumpString) { dumpString += "capture stream:\n"; + dumpString += "ThumbnailSwitch:[" + std::to_string(thumbnailSwitch_); + if (thumbnailBufferQueue_) { + dumpString += "] ThumbnailBuffer producer Id:[" + + std::to_string(thumbnailBufferQueue_->producer_->GetUniqueId()); + } + dumpString += "]\n"; HStreamCommon::DumpStreamInfo(dumpString); } } // namespace CameraStandard diff --git a/services/camera_service/src/hstream_common.cpp b/services/camera_service/src/hstream_common.cpp index 6151a933243ca30a652bd1928491debded4e1897..0f7b3c35da8b40c406b45b67d6f322260ba75b6d 100644 --- a/services/camera_service/src/hstream_common.cpp +++ b/services/camera_service/src/hstream_common.cpp @@ -60,7 +60,7 @@ StreamType HStreamCommon::GetStreamType() return streamType_; } -int32_t HStreamCommon::LinkInput(sptr streamOperator, +int32_t HStreamCommon::LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) { if (streamOperator == nullptr || cameraAbility == nullptr) { @@ -77,7 +77,7 @@ int32_t HStreamCommon::LinkInput(sptr streamOperator, return CAMERA_OK; } -void HStreamCommon::SetStreamInfo(StreamInfo &streamInfo) +void HStreamCommon::SetStreamInfo(StreamInfo_V1_1 &streamInfo) { int32_t pixelFormat = PIXEL_FMT_YCRCB_420_SP; auto it = g_cameraToPixelFormat.find(format_); @@ -87,14 +87,20 @@ void HStreamCommon::SetStreamInfo(StreamInfo &streamInfo) MEDIA_ERR_LOG("HStreamCommon::SetStreamInfo find format error, pixelFormat use default format"); } MEDIA_INFO_LOG("HStreamCommon::SetStreamInfo pixelFormat is %{public}d", pixelFormat); - streamInfo.streamId_ = streamId_; - streamInfo.width_ = width_; - streamInfo.height_ = height_; - streamInfo.format_ = pixelFormat; - streamInfo.minFrameDuration_ = 0; - streamInfo.tunneledMode_ = true; - streamInfo.bufferQueue_ = new BufferProducerSequenceable(producer_); - streamInfo.dataspace_ = CAMERA_COLOR_SPACE; + streamInfo.v1_0.streamId_ = streamId_; + streamInfo.v1_0.width_ = width_; + streamInfo.v1_0.height_ = height_; + streamInfo.v1_0.format_ = pixelFormat; + streamInfo.v1_0.minFrameDuration_ = 0; + streamInfo.v1_0.tunneledMode_ = true; + if (producer_ != nullptr) { + MEDIA_INFO_LOG("HStreamCommon:producer is not null"); + streamInfo.v1_0.bufferQueue_ = new BufferProducerSequenceable(producer_); + } else { + streamInfo.v1_0.bufferQueue_ = nullptr; + } + streamInfo.v1_0.dataspace_ = CAMERA_COLOR_SPACE; + streamInfo.extendedStreamInfos = {}; } int32_t HStreamCommon::Release() @@ -111,31 +117,31 @@ int32_t HStreamCommon::Release() void HStreamCommon::DumpStreamInfo(std::string& dumpString) { - StreamInfo curStreamInfo; + StreamInfo_V1_1 curStreamInfo; SetStreamInfo(curStreamInfo); dumpString += "release status:[" + std::to_string(isReleaseStream_) + "]:\n"; dumpString += "stream info: \n"; std::string bufferProducerId = " Buffer producer Id:["; - if (curStreamInfo.bufferQueue_ && curStreamInfo.bufferQueue_->producer_) { - bufferProducerId += std::to_string(curStreamInfo.bufferQueue_->producer_->GetUniqueId()); + if (curStreamInfo.v1_0.bufferQueue_ && curStreamInfo.v1_0.bufferQueue_->producer_) { + bufferProducerId += std::to_string(curStreamInfo.v1_0.bufferQueue_->producer_->GetUniqueId()); } else { bufferProducerId += "empty"; } dumpString += bufferProducerId; - dumpString += "] stream Id:[" + std::to_string(curStreamInfo.streamId_); + dumpString += "] stream Id:[" + std::to_string(curStreamInfo.v1_0.streamId_); std::map::const_iterator iter = g_cameraFormat.find(format_); if (iter != g_cameraFormat.end()) { dumpString += "] format:[" + iter->second; } - dumpString += "] width:[" + std::to_string(curStreamInfo.width_); - dumpString += "] height:[" + std::to_string(curStreamInfo.height_); - dumpString += "] dataspace:[" + std::to_string(curStreamInfo.dataspace_); - dumpString += "] StreamType:[" + std::to_string(curStreamInfo.intent_); - dumpString += "] TunnelMode:[" + std::to_string(curStreamInfo.tunneledMode_); - dumpString += "] Encoding Type:[" + std::to_string(curStreamInfo.encodeType_) + "]:\n"; - if (curStreamInfo.bufferQueue_) { - delete curStreamInfo.bufferQueue_; + dumpString += "] width:[" + std::to_string(curStreamInfo.v1_0.width_); + dumpString += "] height:[" + std::to_string(curStreamInfo.v1_0.height_); + dumpString += "] dataspace:[" + std::to_string(curStreamInfo.v1_0.dataspace_); + dumpString += "] StreamType:[" + std::to_string(curStreamInfo.v1_0.intent_); + dumpString += "] TunnelMode:[" + std::to_string(curStreamInfo.v1_0.tunneledMode_); + dumpString += "] Encoding Type:[" + std::to_string(curStreamInfo.v1_0.encodeType_) + "]:\n"; + if (curStreamInfo.v1_0.bufferQueue_) { + delete curStreamInfo.v1_0.bufferQueue_; } } } // namespace CameraStandard diff --git a/services/camera_service/src/hstream_metadata.cpp b/services/camera_service/src/hstream_metadata.cpp index 121f8954f69260d109e2eacf4174c11fb793d032..41c965eb45703036f6efff5f778d4db6da7af765 100644 --- a/services/camera_service/src/hstream_metadata.cpp +++ b/services/camera_service/src/hstream_metadata.cpp @@ -28,7 +28,7 @@ HStreamMetadata::HStreamMetadata(sptr producer, int32_t f HStreamMetadata::~HStreamMetadata() {} -int32_t HStreamMetadata::LinkInput(sptr streamOperator, +int32_t HStreamMetadata::LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) { if (streamOperator == nullptr || cameraAbility == nullptr) { @@ -41,10 +41,10 @@ int32_t HStreamMetadata::LinkInput(sptr streamOperator, return CAMERA_OK; } -void HStreamMetadata::SetStreamInfo(StreamInfo &streamInfo) +void HStreamMetadata::SetStreamInfo(StreamInfo_V1_1 &streamInfo) { HStreamCommon::SetStreamInfo(streamInfo); - streamInfo.intent_ = ANALYZE; + streamInfo.v1_0.intent_ = ANALYZE; } int32_t HStreamMetadata::Start() diff --git a/services/camera_service/src/hstream_repeat.cpp b/services/camera_service/src/hstream_repeat.cpp index 385a4f19b72342d9855ff4cfbf84069a3fba0643..208c1b6ca5c34e16f4ea57ea5810fb7370165ffe 100644 --- a/services/camera_service/src/hstream_repeat.cpp +++ b/services/camera_service/src/hstream_repeat.cpp @@ -38,7 +38,7 @@ HStreamRepeat::HStreamRepeat( HStreamRepeat::~HStreamRepeat() {} -int32_t HStreamRepeat::LinkInput(sptr streamOperator, +int32_t HStreamRepeat::LinkInput(sptr streamOperator, std::shared_ptr cameraAbility, int32_t streamId) { int32_t ret = HStreamCommon::LinkInput(streamOperator, cameraAbility, streamId); @@ -51,15 +51,15 @@ int32_t HStreamRepeat::LinkInput(sptr streamOperator, return CAMERA_OK; } -void HStreamRepeat::SetStreamInfo(StreamInfo &streamInfo) +void HStreamRepeat::SetStreamInfo(StreamInfo_V1_1 &streamInfo) { HStreamCommon::SetStreamInfo(streamInfo); if (isVideo_) { - streamInfo.intent_ = VIDEO; - streamInfo.encodeType_ = ENCODE_TYPE_H264; + streamInfo.v1_0.intent_ = VIDEO; + streamInfo.v1_0.encodeType_ = ENCODE_TYPE_H264; } else { - streamInfo.intent_ = PREVIEW; - streamInfo.encodeType_ = ENCODE_TYPE_NULL; + streamInfo.v1_0.intent_ = PREVIEW; + streamInfo.v1_0.encodeType_ = ENCODE_TYPE_NULL; } } @@ -183,12 +183,28 @@ int32_t HStreamRepeat::OnFrameError(int32_t errorType) int32_t HStreamRepeat::AddDeferredSurface(const sptr &producer) { + MEDIA_INFO_LOG("HStreamRepeat::AddDeferredSurface called"); + { + std::lock_guard lock(producerLock_); + if (producer == nullptr) { + MEDIA_ERR_LOG("HStreamRepeat::AddDeferredSurface producer is null"); + return CAMERA_INVALID_ARG; + } + producer_ = producer; + } + SetStreamTransform(); + if (streamOperator_ == nullptr) { + MEDIA_ERR_LOG("HStreamRepeat::CreateAndHandleDeferredStreams(), streamOperator_ == null"); + return CAMERA_INVALID_STATE; + } + MEDIA_INFO_LOG("HStreamRepeat::AttachBufferQueue start"); std::lock_guard lock(producerLock_); - if (producer == nullptr) { - MEDIA_ERR_LOG("HStreamRepeat::AddDeferredSurface producer is null"); - return CAMERA_INVALID_ARG; + CamRetCode rc = (CamRetCode)(streamOperator_ + ->AttachBufferQueue(streamId_, new BufferProducerSequenceable(producer_))); + if (rc != HDI::Camera::V1_0::NO_ERROR) { + MEDIA_ERR_LOG("HStreamRepeat::AttachBufferQueue(), Failed to AttachBufferQueue %{public}d", rc); } - producer_ = producer; + MEDIA_INFO_LOG("HStreamRepeat::AddDeferredSurface end %{public}d", rc); return CAMERA_OK; }