diff --git a/frameworks/BUILD.gn b/frameworks/BUILD.gn old mode 100644 new mode 100755 index 4751027..a38e43a --- a/frameworks/BUILD.gn +++ b/frameworks/BUILD.gn @@ -3,41 +3,54 @@ import("//build/lite/config/component/lite_component.gni") shared_library("camera_lite") { sources = [ "camera_ability.cpp", + "camera_info_impl.cpp", "camera_config.cpp", - "camera_device.cpp", "camera_impl.cpp", "camera_kit.cpp", "camera_manager.cpp", - "camera_service.cpp", "event_handler.cpp", "frame_config.cpp", + "camera_client.cpp", + "camera_device_client.cpp", + "camera_service_client.cpp", + ] + include_dirs = [ + "//foundation/multimedia/camera_lite/services/include", + "//utils/native/lite/include", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/communication/broadcast", + "//foundation/communication/ipc_lite/interfaces/kits", + "//base/security/permission/interfaces/kits/permission_lite", + ] + public_configs = [ ":camera_client_external_library_config" ] + + ldflags = [ + "-lstdc++", + "-lpthread", + "-lcodec", + "-lhdi_videodisplayer", + "-L$ohos_root_path/$root_out_dir", ] cflags = [ "-fPIC" ] cflags += [ "-Wall" ] cflags_cc = cflags - include_dirs = [ - "//base/security/permission/interfaces/kits/permission_lite", - "//drivers/peripheral/codec/interfaces/include", - "//foundation/multimedia/utils/lite/hals", - ] - - ldflags = [ "-lstdc++" ] - ldflags += [ "-lcodec" ] - ldflags += [ "-lhdi_media" ] - ldflags += [ "-L$ohos_root_path/$root_out_dir" ] - public_configs = [ ":camera_external_library_config" ] deps = [ - "$ohos_vendor_adapter_dir:hardware_media_sdk", - "$ohos_vendor_adapter_dir/../modules/middleware:middleware_source_sdk", - "$ohos_vendor_adapter_dir/multimedia:libhdi_media", "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", "//base/security/permission/services/permission_lite/pms_client:pms_client", + "//device/hisilicon/hardware:hardware_media_sdk", + "//device/hisilicon/modules/middleware:middleware_source_sdk", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", "//third_party/bounds_checking_function:libsec_shared", ] - public_deps = [ "//foundation/graphic/surface:lite_surface" ] + public_deps = [ + "//foundation/graphic/surface:lite_surface", + "//foundation/multimedia/media_lite/frameworks/recorder_lite:recorder_lite", + "//foundation/multimedia/utils/lite:media_common", + ] } -config("camera_external_library_config") { +config("camera_client_external_library_config") { include_dirs = [ "//foundation/multimedia/camera_lite/interfaces/kits" ] include_dirs += [ "//foundation/multimedia/utils/lite/interfaces/kits" ] } diff --git a/frameworks/camera_ability.cpp b/frameworks/camera_ability.cpp index 72d2296..aaa96b7 100755 --- a/frameworks/camera_ability.cpp +++ b/frameworks/camera_ability.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ #include "camera_ability.h" - #include "media_log.h" using namespace std; @@ -24,10 +23,20 @@ CameraAbility::~CameraAbility() {} list CameraAbility::GetSupportedSizes(int format) const { - auto target = SizeMap_.find(PARAM_KEY_SIZE); + auto target = SizeMap_.find((uint32_t)format); return target->second; } +std::list CameraAbility::GetSupportedAfModes() const +{ + return afModes; +} + +std::list CameraAbility::GetSupportedAeModes() const +{ + return aeModes; +} + list CameraAbility::GetSupportParameterRange(uint32_t key) const { switch (key) { @@ -43,11 +52,21 @@ list CameraAbility::GetSupportParameterRange(uint32_t key) const } void CameraAbility::SetSupportParameterRange(uint32_t key, list &rangeList) +{ + SizeMap_[key] = rangeList; + supportProperties_.emplace(PARAM_KEY_SIZE); +} + +void CameraAbility::SetSupportParameterRange(uint32_t key, list &rangeList) { switch (key) { - case PARAM_KEY_SIZE: + case CAM_AF_MODE: supportProperties_.emplace(key); - SizeMap_[key] = rangeList; + afModes = rangeList; + break; + case CAM_AE_MODE: + supportProperties_.emplace(key); + aeModes = rangeList; break; default: break; @@ -56,9 +75,6 @@ void CameraAbility::SetSupportParameterRange(uint32_t key, list & bool CameraAbility::IsParameterSupport(uint32_t key) const { - if (key != PARAM_KEY_SIZE) { - return false; - } return true; } } // namespace Media diff --git a/frameworks/camera_ability_impl.cpp b/frameworks/camera_ability_impl.cpp new file mode 100755 index 0000000..9cbaaed --- /dev/null +++ b/frameworks/camera_ability_impl.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020-2021 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 "camera_ability_impl.h" +#include "media_log.h" + +using namespace std; +namespace OHOS { +namespace Media { + +list CameraAbilityImpl::GetSupportedFormats() const +{ +// auto target = SizeMap_.find(PARAM_KEY_SIZE); +// return target->second; + list test; + return test; +} + +list CameraAbilityImpl::GetSupportedSizes(int format) const +{ + auto target = SizeMap_.find(PARAM_KEY_SIZE); + return target->second; +} + +list CameraAbilityImpl::GetSupportParameterRange(uint32_t key) const +{ + switch (key) { + case PARAM_KEY_SIZE: { + auto target = SizeMap_.find(PARAM_KEY_SIZE); + return target->second; + } + default: { + list emptyList; + return emptyList; + } + } +} + +void CameraAbilityImpl::SetSupportParameterRange(uint32_t key, list &rangeList) +{ + switch (key) { + case PARAM_KEY_SIZE: + supportProperties_.emplace(key); + SizeMap_[key] = rangeList; + break; + default: + break; + } +} + +bool CameraAbilityImpl::IsParameterSupport(uint32_t key) const +{ + if (key != PARAM_KEY_SIZE) { + return false; + } + return true; +} + + +} // namespace Media +} // namespace OHOS diff --git a/frameworks/camera_ability_impl.h b/frameworks/camera_ability_impl.h new file mode 100755 index 0000000..d8b5c21 --- /dev/null +++ b/frameworks/camera_ability_impl.h @@ -0,0 +1,43 @@ +/* + * Copyright(c) 2020-2021 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 OHOS_CAMERA_ABILITY_IMPL_H +#define OHOS_CAMERA_ABILITY_IMPL_H + +#include "camera_ability.h" + +namespace OHOS { +namespace Media { +class CameraAbilityImpl : public CameraAbility { +public: + CameraAbilityImpl() {} + ~CameraAbilityImpl() = default; + std::list GetSupportedFormats() const; + std::list GetSupportedSizes(int format) const; + + template int32_t SetParameterRange(uint32_t key, std::list rangeList); + template std::list GetParameterRange(uint32_t key) const; + +private: + void SetSupportParameterRange(uint32_t key, std::list &rangeList); + std::list GetSupportParameterRange(uint32_t key) const; + bool IsParameterSupport(uint32_t key) const; + std::map> SizeMap_; + std::set supportProperties_; +}; +} // namespace Media +} // namespace + + +#endif // OHOS_CAMERA_ABILITY_IMPL_H \ No newline at end of file diff --git a/frameworks/camera_client.cpp b/frameworks/camera_client.cpp new file mode 100755 index 0000000..93a4b9f --- /dev/null +++ b/frameworks/camera_client.cpp @@ -0,0 +1,76 @@ +/* + * Copyright(c) 2020-2021 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 "camera_client.h" +#include "media_log.h" +#include "samgr_lite.h" +#include "camera_type.h" +#include "liteipc_adapter.h" + +#include + +extern "C" void __attribute__((weak)) HOS_SystemInit(void) +{ + SAMGR_Bootstrap(); +} + +using namespace std; +namespace OHOS { +namespace Media { +CameraClient *CameraClient::GetInstance() +{ + static CameraClient client; + return &client; +} + +bool CameraClient::InitCameraClient() +{ + HOS_SystemInit(); + if (proxy_ == nullptr) { + IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(SERVICE_NAME); + if (iUnknown == nullptr) { + MEDIA_ERR_LOG("Camera server connecting failed."); + return false; + } + (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy_); + if (proxy_ == nullptr) { + MEDIA_ERR_LOG("QueryInterface failed."); + return false; + } + } + return true; +} + +IClientProxy *CameraClient::GetIClientProxy() +{ + return proxy_; +} + +void CameraClient::ClearIpcMsg(void *ipcMsg) +{ + if (ipcMsg == nullptr) { + return; + } + uint32_t flag = 0; + GetFlag(ipcMsg, &flag); + if (flag == LITEIPC_FLAG_DEFAULT) { + // send reply to client, the second param is reply + SendReply(nullptr, ipcMsg, nullptr); + } else { + FreeBuffer(nullptr, ipcMsg); + } +} +} +} \ No newline at end of file diff --git a/frameworks/camera_client.h b/frameworks/camera_client.h new file mode 100755 index 0000000..000f2b5 --- /dev/null +++ b/frameworks/camera_client.h @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2020-2021 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_CLIENT_H +#define CAMERA_CLIENT_H + +#include "iproxy_client.h" + +namespace OHOS { +namespace Media { +class CameraClient { +public: + static CameraClient *GetInstance(); + bool InitCameraClient(); + IClientProxy *GetIClientProxy(); + void ClearIpcMsg(void *ipcMsg); + +private: + CameraClient() {} + ~CameraClient() {} + IClientProxy *proxy_ = nullptr; +}; +} +} +#endif // CAMERA_CLIENT_H diff --git a/frameworks/camera_device.cpp b/frameworks/camera_device.cpp deleted file mode 100755 index 60f37b1..0000000 --- a/frameworks/camera_device.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright (c) 2020-2021 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 "camera_device.h" - -#include "codec_interface.h" -#include "hal_display.h" -#include "media_log.h" -#include "meta_data.h" -#include "securec.h" - -#include -#include - -using namespace OHOS; -using namespace OHOS::Media; -using namespace std; - -const int32_t KEY_IS_SYNC_FRAME = 1; // "is-sync-frame" -const int32_t KEY_TIME_US = 2; // "timeUs" - -namespace OHOS { -namespace Media { -inline PicSize Convert2CodecSize(int32_t width, int32_t height) -{ - struct SizeMap { - PicSize res_; - int32_t width_; - int32_t height_; - }; - static SizeMap sizeMap[] = {{RESOLUTION_CIF, 352, 288}, {RESOLUTION_360P, 640, 360}, - {RESOLUTION_D1_PAL, 720, 576}, {RESOLUTION_D1_NTSC, 720, 480}, - {RESOLUTION_720P, 1280, 720}, {RESOLUTION_1080P, 1920, 1080}}; - for (uint32_t i = 0; i < sizeof(sizeMap) / sizeof(SizeMap); i++) { - if (sizeMap[i].width_ == width && sizeMap[i].height_ == height) { - return sizeMap[i].res_; - } - } - return RESOLUTION_INVALID; -} - -static int32_t SetVencSource(CODEC_HANDLETYPE codecHdl, uint32_t deviceId) -{ - Param param = {.key = KEY_DEVICE_ID, .val = (void *)&deviceId, .size = sizeof(uint32_t)}; - int32_t ret = CodecSetParameter(codecHdl, ¶m, 1); - if (ret != 0) { - MEDIA_ERR_LOG("Set enc source failed.(ret=%d)", ret); - return ret; - } - return MEDIA_OK; -} - -static int32_t - CameraCreateVideoEnc(FrameConfig &fc, HalVideoProcessorAttr *attr, uint32_t srcDev, CODEC_HANDLETYPE *codecHdl) -{ - const char *name = "codec.video.hardware.encoder"; - const uint32_t maxParamNum = 10; - uint32_t paramIndex = 0; - Param param[maxParamNum]; - - CodecType domainKind = VIDEO_ENCODER; - param[paramIndex].key = KEY_CODEC_TYPE; - param[paramIndex].val = &domainKind; - param[paramIndex].size = sizeof(CodecType); - paramIndex++; - - AvCodecMime codecMime = MEDIA_MIMETYPE_VIDEO_HEVC; - param[paramIndex].key = KEY_MIMETYPE; - param[paramIndex].val = &codecMime; - param[paramIndex].size = sizeof(AvCodecMime); - paramIndex++; - - VenCodeRcMode rcMode = VENCOD_RC_CBR; - param[paramIndex].key = KEY_VIDEO_RC_MODE; - param[paramIndex].val = &rcMode; - param[paramIndex].size = sizeof(VenCodeRcMode); - paramIndex++; - - VenCodeGopMode gopMode = VENCOD_GOPMODE_NORMALP; - param[paramIndex].key = KEY_VIDEO_GOP_MODE; - param[paramIndex].val = &gopMode; - param[paramIndex].size = sizeof(VenCodeGopMode); - paramIndex++; - - Profile profile = HEVC_MAIN_PROFILE; - param[paramIndex].key = KEY_VIDEO_PROFILE; - param[paramIndex].val = &profile; - param[paramIndex].size = sizeof(Profile); - paramIndex++; - - PicSize picSize = Convert2CodecSize(attr->width, attr->height); - MEDIA_DEBUG_LOG("picSize=%d", picSize); - param[paramIndex].key = KEY_VIDEO_PIC_SIZE; - param[paramIndex].val = &picSize; - param[paramIndex].size = sizeof(PicSize); - paramIndex++; - - uint32_t frameRate = attr->fps; - MEDIA_DEBUG_LOG("frameRate=%u", frameRate); - param[paramIndex].key = KEY_VIDEO_FRAME_RATE; - param[paramIndex].val = &frameRate; - param[paramIndex].size = sizeof(uint32_t); - paramIndex++; - - int32_t ret = CodecCreate(name, param, paramIndex, codecHdl); - if (ret != 0) { - MEDIA_ERR_LOG("Create video encoder failed."); - return HAL_MEDIA_ERR; - } - - ret = SetVencSource(*codecHdl, srcDev); - if (ret != 0) { - CodecDestroy(codecHdl); - return HAL_MEDIA_ERR; - } - - return HAL_MEDIA_OK; -} - -static int32_t - CameraCreateJpegEnc(FrameConfig &fc, uint32_t srcDev, HalVideoProcessorAttr *attr, CODEC_HANDLETYPE *codecHdl) -{ - const char *videoEncName = "codec.jpeg.hardware.encoder"; - const uint32_t maxParamNum = 5; - Param param[maxParamNum]; - uint32_t paramIndex = 0; - - CodecType domainKind = VIDEO_ENCODER; - param[paramIndex].key = KEY_CODEC_TYPE; - param[paramIndex].val = &domainKind; - param[paramIndex].size = sizeof(CodecType); - paramIndex++; - - AvCodecMime codecMime = MEDIA_MIMETYPE_IMAGE_JPEG; - param[paramIndex].key = KEY_MIMETYPE; - param[paramIndex].val = &codecMime; - param[paramIndex].size = sizeof(AvCodecMime); - paramIndex++; - - PicSize picSize = Convert2CodecSize(attr->width, attr->height); - param[paramIndex].key = KEY_VIDEO_PIC_SIZE; - param[paramIndex].val = &picSize; - param[paramIndex].size = sizeof(PicSize); - paramIndex++; - - int32_t ret = CodecCreate(videoEncName, param, paramIndex, codecHdl); - if (ret != 0) { - return HAL_MEDIA_ERR; - } - - int32_t qfactor = -1; - fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor); - if (qfactor != -1) { - MEDIA_DEBUG_LOG("qfactor=%d", qfactor); - Param jpegParam = { - .key = KEY_IMAGE_Q_FACTOR, - .val = &qfactor, - .size = sizeof(qfactor) - }; - ret = CodecSetParameter(*codecHdl, &jpegParam, 1); - if (ret != 0) { - MEDIA_ERR_LOG("CodecSetParameter set jpeg qfactor failed.(ret=%u)", ret); - } - } - - ret = SetVencSource(*codecHdl, srcDev); - if (ret != 0) { - MEDIA_ERR_LOG("Set video encoder source failed."); - CodecDestroy(*codecHdl); - return HAL_MEDIA_ERR; - } - - return HAL_MEDIA_OK; -} - -static int32_t CopyCodecOutput(void *dst, uint32_t *size, OutputInfo *buffer) -{ - char *dstBuf = reinterpret_cast(dst); - for (uint32_t i = 0; i < buffer->bufferCnt; i++) { - uint32_t packSize = buffer->buffers[i].length - buffer->buffers[i].offset; - errno_t ret = memcpy_s(dstBuf, *size, buffer->buffers[i].addr + buffer->buffers[i].offset, packSize); - if (ret != EOK) { - return HAL_MEDIA_ERR; - } - *size -= packSize; - dstBuf += packSize; - } - return MEDIA_OK; -} - -static int32_t FindAvailProcessorIdx(Surface &surface, vector &attrs) -{ - for (uint32_t i = 0; i < attrs.size(); i++) { - if (attrs[i].width == surface.GetWidth() && attrs[i].height == surface.GetHeight()) { - return i; - } - } - return -1; -} - -int RecordAssistant::OnVencBufferAvailble(UINTPTR hComponent, UINTPTR dataIn, OutputInfo *buffer) -{ - CODEC_HANDLETYPE hdl = reinterpret_cast(hComponent); - RecordAssistant *assistant = reinterpret_cast(dataIn); - list *surfaceList = nullptr; - for (uint32_t idx = 0; idx < assistant->vencHdls_.size(); idx++) { - if (assistant->vencHdls_[idx] == hdl) { - surfaceList = &(assistant->vencSurfaces_[idx]); - break; - } - } - if (surfaceList == nullptr || surfaceList->empty()) { - MEDIA_ERR_LOG("Encoder handle is illegal."); - return -1; - } - int32_t ret = -1; - for (auto &surface : *surfaceList) { - SurfaceBuffer *surfaceBuf = surface->RequestBuffer(); - if (surfaceBuf == nullptr) { - MEDIA_ERR_LOG("No available buffer in surface."); - break; - } - - uint32_t size = surface->GetSize(); - void *buf = surfaceBuf->GetVirAddr(); - if (buf == nullptr) { - MEDIA_ERR_LOG("Invalid buffer address."); - break; - } - ret = CopyCodecOutput(buf, &size, buffer); - if (ret != HAL_MEDIA_OK) { - MEDIA_ERR_LOG("No available buffer in surface."); - surface->CancelBuffer(surfaceBuf); - break; - } - surfaceBuf->SetInt32(KEY_IS_SYNC_FRAME, (((buffer->flag & STREAM_FLAG_KEYFRAME) == 0) ? 0 : 1)); - surfaceBuf->SetInt64(KEY_TIME_US, buffer->timeStamp); - surfaceBuf->SetSize(surface->GetSize() - size); - - if (surface->FlushBuffer(surfaceBuf) != 0) { - MEDIA_ERR_LOG("Flush surface failed."); - surface->CancelBuffer(surfaceBuf); - ret = -1; - break; - } - } - if (CodecQueueOutput(hdl, buffer, 0, -1) != 0) { - MEDIA_ERR_LOG("Codec queue output failed."); - } - - return ret; -} - -CodecCallback RecordAssistant::recordCodecCb_ = {nullptr, nullptr, RecordAssistant::OnVencBufferAvailble}; - -int32_t RecordAssistant::SetFrameConfig(FrameConfig &fc, - vector &hdls, - vector &attrs) -{ - fc_ = &fc; - - auto surfaceList = fc.GetSurfaces(); - if (surfaceList.size() != 1) { - MEDIA_ERR_LOG("Only support one surface in frame config now."); - return MEDIA_ERR; - } - for (auto &surface : surfaceList) { - CODEC_HANDLETYPE codecHdl = nullptr; - int32_t ProcessorIdx = FindAvailProcessorIdx(*surface, attrs); - if (ProcessorIdx < 0) { - MEDIA_ERR_LOG("No suitble procesor for recording."); - return MEDIA_ERR; - } - uint32_t deviceId = HalGetProcessorDeviceId(hdls[ProcessorIdx]); - int32_t encIdx = VideoEncIsExist(&attrs[deviceId]); - if (encIdx >= 0) { - vencSurfaces_[encIdx].emplace_back(surface); - continue; - } - - int32_t ret = CameraCreateVideoEnc(fc, &attrs[ProcessorIdx], deviceId, &codecHdl); - if (ret != MEDIA_OK) { - MEDIA_ERR_LOG("Cannot create suitble video encoder."); - return MEDIA_ERR; - } - - ret = CodecSetCallback(codecHdl, &recordCodecCb_, reinterpret_cast(this)); - if (ret != 0) { - MEDIA_ERR_LOG("Set codec callback failed.(ret=%d)", ret); - CodecDestroy(codecHdl); - return MEDIA_ERR; - } - vencHdls_.emplace_back(codecHdl); - list conList({surface}); - vencSurfaces_.emplace_back(conList); - vencAttr_.emplace_back(&attrs[deviceId]); - } - state_ = LOOP_READY; - return MEDIA_OK; -} - -int32_t RecordAssistant::Start() -{ - if (state_ != LOOP_READY) { - return MEDIA_ERR; - } - - int32_t ret = HAL_MEDIA_OK; - int32_t i; - for (i = 0; static_cast(i) < vencHdls_.size(); i++) { - ret = CodecStart(vencHdls_[i]); - if (ret != HAL_MEDIA_OK) { - MEDIA_ERR_LOG("Video encoder start failed."); - ret = MEDIA_ERR; - break; - } - } - if (ret == MEDIA_ERR) { - /* rollback */ - for (; i >= 0; i--) { - CodecStop(vencHdls_[i]); - } - return MEDIA_ERR; - } - state_ = LOOP_LOOPING; - - MEDIA_DEBUG_LOG("Start camera recording succeed."); - return MEDIA_OK; -} - -int32_t RecordAssistant::Stop() -{ - if (state_ != LOOP_LOOPING) { - return MEDIA_ERR; - } - - for (uint32_t i = 0; i < vencHdls_.size(); i++) { - CodecStop(vencHdls_[i]); - CodecDestroy(vencHdls_[i]); - } - vencHdls_.clear(); - vencAttr_.clear(); - vencSurfaces_.clear(); - - state_ = LOOP_STOP; - return MEDIA_OK; -} - -int32_t RecordAssistant::VideoEncIsExist(HalVideoProcessorAttr *attr) -{ - for (uint32_t i = 0; i < vencAttr_.size(); i++) { - if (vencAttr_[i] == attr) { - return i; - } - } - return -1; -} - -static void GetSurfaceRect(Surface *surface, HalVideoOutputAttr *attr) -{ - attr->regionPositionX = std::stoi(surface->GetUserData("region_position_x")); - attr->regionPositionY = std::stoi(surface->GetUserData("region_position_y")); - attr->regionWidth = std::stoi(surface->GetUserData("region_width")); - attr->regionHeight = std::stoi(surface->GetUserData("region_height")); -} - -int32_t PreviewAssistant::SetFrameConfig(FrameConfig &fc, - vector &hdls, - vector &attrs) -{ - fc_ = &fc; - - auto surfaceList = fc.GetSurfaces(); - if (surfaceList.size() != 1) { - MEDIA_ERR_LOG("Only support one surface in frame config now."); - return MEDIA_ERR; - } - auto surface = surfaceList.front(); - int32_t ProcessorIdx = FindAvailProcessorIdx(*surface, attrs); - if (ProcessorIdx < 0) { - MEDIA_ERR_LOG("No suitble procesor for preview."); - return MEDIA_ERR; - } - uint32_t deviceId = HalGetProcessorDeviceId(hdls[ProcessorIdx]); - - HalVideoOutputAttr attr; - GetSurfaceRect(surface, &attr); - int32_t ret = HalCreateCameraVideoOutput(deviceId, &attr); - if (ret != 0) { - MEDIA_ERR_LOG("Create preview video output failed."); - return MEDIA_ERR; - } - - return MEDIA_OK; -} - -int32_t PreviewAssistant::Start() -{ - // enable vo - return MEDIA_OK; -} - -int32_t PreviewAssistant::Stop() -{ - HalDestroyCameraVideoOutput(); - return MEDIA_OK; -} - -int32_t CaptureAssistant::SetFrameConfig(FrameConfig &fc, - vector &hdls, - vector &attrs) -{ - auto surfaceList = fc.GetSurfaces(); - if (surfaceList.size() != 1) { - MEDIA_ERR_LOG("Only support one surface in frame config now."); - return MEDIA_ERR; - } - if (surfaceList.empty()) { - MEDIA_ERR_LOG("Frame config with empty surface list."); - return MEDIA_ERR; - } - if (surfaceList.size() > 1) { - MEDIA_WARNING_LOG("Capture only fullfill the first surface in frame config."); - } - Surface *surface = surfaceList.front(); - int32_t idx = FindAvailProcessorIdx(*surface, attrs); - if (idx < 0) { - MEDIA_ERR_LOG("No suitble procesor for venc."); - return MEDIA_ERR; - } - uint32_t deviceId = HalGetProcessorDeviceId(hdls[idx]); - int32_t ret = CameraCreateJpegEnc(fc, deviceId, &attrs[idx], &vencHdl_); - if (ret != HAL_MEDIA_OK) { - MEDIA_ERR_LOG("Create capture venc failed."); - return MEDIA_ERR; - } - - capSurface_ = surface; - - state_ = LOOP_READY; - return MEDIA_OK; -} - -/* Block method, waiting for capture completed */ -int32_t CaptureAssistant::Start() -{ - state_ = LOOP_LOOPING; - int32_t ret = CodecStart(vencHdl_); - if (ret != 0) { - MEDIA_ERR_LOG("Start capture encoder failed.(ret=%d)", ret); - return MEDIA_ERR; - } - MEDIA_DEBUG_LOG("surface = %p", capSurface_); - - SurfaceBuffer *surfaceBuf = capSurface_->RequestBuffer(); - if (surfaceBuf == nullptr) { - MEDIA_ERR_LOG("No available buffer in surface."); - return -1; - } - - OutputInfo outInfo; - ret = CodecDequeueOutput(vencHdl_, 0, nullptr, &outInfo); - if (ret != 0) { - capSurface_->CancelBuffer(surfaceBuf); - MEDIA_ERR_LOG("Dequeue capture frame failed.(ret=%d)", ret); - return MEDIA_ERR; - } - - uint32_t size = capSurface_->GetSize(); - void *buf = surfaceBuf->GetVirAddr(); - if (buf == nullptr) { - MEDIA_ERR_LOG("Invalid buffer address."); - return -1; - } - ret = CopyCodecOutput(buf, &size, &outInfo); - if (ret != HAL_MEDIA_OK) { - MEDIA_ERR_LOG("No available buffer in capSurface_."); - capSurface_->CancelBuffer(surfaceBuf); - return -1; - } - surfaceBuf->SetSize(capSurface_->GetSize() - size); - - if (capSurface_->FlushBuffer(surfaceBuf) != 0) { - MEDIA_ERR_LOG("Flush surface buffer failed."); - capSurface_->CancelBuffer(surfaceBuf); - return -1; - } - - CodecQueueOutput(vencHdl_, &outInfo, 0, -1); // 0:no timeout -1:no fd - CodecStop(vencHdl_); - CodecDestroy(vencHdl_); - - state_ = LOOP_STOP; - - return MEDIA_OK; -} - -int32_t CaptureAssistant::Stop() -{ - MEDIA_DEBUG_LOG("No support method."); - return MEDIA_OK; -} - -CameraDevice::CameraDevice() {} - -CameraDevice::~CameraDevice() {} - -int32_t CameraDevice::Initialize(CameraAbility &ability) -{ - /* Need to be Refactored when delete config file */ - int32_t ret = HalCreateVideoProcessor(nullptr); - if (ret != HAL_MEDIA_OK) { - MEDIA_ERR_LOG("Init camera device failed.(ret=%d)", ret); - return MEDIA_ERR; - } - HalVideoProcessorAttr attrs[HAL_MAX_VPSS_NUM]; - HalProcessorHdl hdls[HAL_MAX_VPSS_NUM]; - int32_t size; - list range; - HalCameraGetProcessorAttr(hdls, attrs, &size); - for (int i = 0; i < size; i++) { - prcessorAttrs_.emplace_back(attrs[i]); - prcessorHdls_.emplace_back(hdls[i]); - CameraPicSize tmpSize = {.width = attrs[i].width, .height = attrs[i].height}; - range.emplace_back(tmpSize); - } - ability.SetParameterRange(PARAM_KEY_SIZE, range); - - ret = CodecInit(); - if (ret != 0) { - MEDIA_ERR_LOG("Codec module init failed.(ret=%d)", ret); - return MEDIA_ERR; - } - MEDIA_DEBUG_LOG("Codec module init succeed."); - - captureAssistant_.state_ = LOOP_READY; - previewAssistant_.state_ = LOOP_READY; - recordAssistant_.state_ = LOOP_READY; - return MEDIA_OK; -} - -int32_t CameraDevice::UnInitialize() -{ - HalDestroyVideoProcessor(); - return MEDIA_OK; -} - -int32_t CameraDevice::TriggerLoopingCapture(FrameConfig &fc) -{ - MEDIA_DEBUG_LOG("Camera device start looping capture."); - - DeviceAssistant *assistant = nullptr; - int fcType = fc.GetFrameConfigType(); - switch (fcType) { - case FRAME_CONFIG_RECORD: - assistant = &recordAssistant_; - break; - case FRAME_CONFIG_PREVIEW: - assistant = &previewAssistant_; - break; - case FRAME_CONFIG_CAPTURE: - assistant = &captureAssistant_; - break; - default: - break; - } - if (assistant == nullptr) { - MEDIA_ERR_LOG("Invalid frame config type.(type=%d)", fcType); - return MEDIA_ERR; - } - if (assistant->state_ == LOOP_IDLE || assistant->state_ == LOOP_LOOPING || assistant->state_ == LOOP_ERROR) { - MEDIA_ERR_LOG("Device state is %d, cannot start looping capture.", assistant->state_); - return MEDIA_ERR; - } - - int ret = assistant->SetFrameConfig(fc, prcessorHdls_, prcessorAttrs_); - if (ret != MEDIA_OK) { - MEDIA_ERR_LOG("Check and set frame config failed.(ret=%d)", ret); - return MEDIA_ERR; - } - - ret = assistant->Start(); - if (ret != MEDIA_OK) { - MEDIA_ERR_LOG("Start looping capture failed.(ret=%d)", ret); - return MEDIA_ERR; - } - - return MEDIA_OK; -} - -void CameraDevice::StopLoopingCapture() -{ - previewAssistant_.Stop(); - recordAssistant_.Stop(); -} - -int32_t CameraDevice::TriggerSingleCapture(FrameConfig &fc) -{ - return TriggerLoopingCapture(fc); -} - -int32_t CameraDevice::SetCameraConfig(CameraConfig &config) -{ - cc_ = &config; - return MEDIA_OK; -} -} // namespace Media -} // namespace OHOS diff --git a/frameworks/camera_device_client.cpp b/frameworks/camera_device_client.cpp new file mode 100755 index 0000000..7d931de --- /dev/null +++ b/frameworks/camera_device_client.cpp @@ -0,0 +1,297 @@ +/* + * Copyright(c) 2020-2021 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 "camera_device_client.h" +#include "liteipc_adapter.h" +#include "serializer.h" +#include "camera_type.h" +#include "media_log.h" +#include "camera_config.h" +#include "frame_config.h" +#include "surface.h" +#include "surface_impl.h" +#include "camera_impl.h" + +#include + +using namespace std; +namespace OHOS { +namespace Media { +CameraDeviceClient *CameraDeviceClient::GetInstance() +{ + static CameraDeviceClient client; + return &client; +} + +CameraDeviceClient::CameraDeviceClient() +{ + cameraClient_ = CameraClient::GetInstance(); + if (cameraClient_->InitCameraClient()) { + proxy_ = cameraClient_->GetIClientProxy(); + } +} + +CameraDeviceClient::~CameraDeviceClient() +{ + if (para_ != nullptr) { + delete para_; + para_ = nullptr; + } + UnregisterIpcCallback(sid_); +} + +void CameraDeviceClient::SetCameraId(string cameraId) +{ + cameraId_ = cameraId; +} + +void CameraDeviceClient::SetCameraImpl(CameraImpl *cameraImpl) +{ + cameraImpl_ = cameraImpl; +} + +int CameraDeviceClient::Callback(void* owner, int code, IpcIo *reply) +{ + if (code != 0) { + MEDIA_ERR_LOG("Callback error. (code=%d)", code); + return -1; + } + if (owner == nullptr) { + return -1; + } + CallBackPara* para = (CallBackPara*)owner; + switch (para->funcId) { + case CAMERA_SERVER_SET_CAMERA_CALLBACK: + MEDIA_INFO_LOG("Camera server set callback success."); + break; + default: + break; + } + return 0; +} + +int32_t CameraDeviceClient::SetCameraConfig(CameraConfig &cc) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + if (cameraId_.empty()) { + MEDIA_ERR_LOG("no camera exist."); + return MEDIA_ERR; + } + IpcIoPushString(&io, cameraId_.c_str()); + para_->data = this; + para_->cameraConfig = &cc; + uint32_t ret = proxy_->Invoke(proxy_, CAEMRA_SERVER_SET_CAMERA_CONFIG, &io, NULL, NULL); + if (ret != 0) { + MEDIA_ERR_LOG("Set camera config ipc transmission failed. (ret=%d)", ret); + return MEDIA_ERR; + } + return MEDIA_OK; +} + +int32_t SerilizeFrameConfig(IpcIo &io, FrameConfig &fc, uint32_t maxSurfaceNum) +{ + IpcIoPushInt32(&io, fc.GetFrameConfigType()); + list surfaceList = fc.GetSurfaces(); + if (maxSurfaceNum < surfaceList.size()) { + MEDIA_ERR_LOG("Too many surfaces. (maxSurfaceNum=%u, sufaceNum=%d)", maxSurfaceNum, surfaceList.size()); + return MEDIA_ERR; + } + IpcIoPushUint32(&io, surfaceList.size()); + for (auto &surface : surfaceList) { + dynamic_cast(surface)->WriteIoIpcIo(io); + MEDIA_DEBUG_LOG("Add surface"); + } + int32_t qfactor = -1; + fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor); + IpcIoPushInt32(&io, qfactor); + // FPS, format, private Tag + int32_t frameRate = -1; + fc.GetParameter(PARAM_KEY_STREAM_FPS, frameRate); + IpcIoPushInt32(&io, frameRate); + + int32_t format = -1; + fc.GetParameter(CAM_IMAGE_FORMAT, format); + IpcIoPushInt32(&io, format); + + uint8_t data[PRIVATE_TAG_LEN]; + fc.GetVendorParameter(data, sizeof(data)); + BuffPtr dataBuff = { + .buffSz = sizeof(data), + .buff = (void *)data + }; + IpcIoPushDataBuff(&io, &dataBuff); + return MEDIA_OK; +} + + +int32_t CameraDeviceClient::TriggerLoopingCapture(FrameConfig &fc) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + constexpr uint32_t maxSurfaceNum = 2; // 2 surfaces at most + /* serilize parameters */ + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, maxSurfaceNum); + if (cameraId_.empty()) { + MEDIA_ERR_LOG("no camera exist."); + return MEDIA_ERR; + } + IpcIoPushString(&io, cameraId_.c_str()); + if (SerilizeFrameConfig(io, fc, maxSurfaceNum) != MEDIA_OK) { + MEDIA_ERR_LOG("Serilize the frameconfig failed."); + return MEDIA_ERR; + } + para_->data = this; + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE, &io, NULL, NULL); + if (ret != 0) { + MEDIA_ERR_LOG("Trigger looping capture ipc transmission failed. (ret=%d)", ret); + } + return MEDIA_OK; +} + +int32_t CameraDeviceClient::TriggerSingleCapture(FrameConfig &fc) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + constexpr uint32_t maxSurfaceNum = 2; // 2 surfaces at most + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, maxSurfaceNum); + + if (cameraId_.empty()) { + MEDIA_ERR_LOG("no camera exist."); + return MEDIA_ERR; + } + IpcIoPushString(&io, cameraId_.c_str()); + if (SerilizeFrameConfig(io, fc, maxSurfaceNum) != MEDIA_OK) { + MEDIA_ERR_LOG("Serilize the frameconfig failed."); + return MEDIA_ERR; + } + para_->frameConfig = &fc; + para_->data = this; + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE, &io, NULL, NULL); + if (ret != 0) { + MEDIA_ERR_LOG("Trigger single capture ipc transmission failed. (ret=%d)", ret); + return MEDIA_ERR; + } + return MEDIA_OK; +} + +void CameraDeviceClient::StopLoopingCapture() +{ + int32_t streamId = 0; + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + if (cameraId_.empty()) { + MEDIA_ERR_LOG("no camera exist."); + return; + } + IpcIoPushString(&io, cameraId_.c_str()); + CallBackPara para = {}; + para.funcId = CAMERA_SERVER_STOP_LOOPING_CAPTURE; + para.data = this; + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_STOP_LOOPING_CAPTURE, &io, NULL, NULL); + if (ret != 0) { + MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ret); + } +} + +void CameraDeviceClient::Release() +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + if (cameraId_.empty()) { + MEDIA_ERR_LOG("no camera exist."); + return; + } + if (proxy_ == nullptr) { + return; + } + IpcIoPushString(&io, cameraId_.c_str()); + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_CLOSE_CAMERA, &io, NULL, NULL); + if (ret != 0) { + MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ret); + } +} + +void CameraDeviceClient::SetCameraCallback() +{ + para_ = new (nothrow) CallBackPara; + if (para_ == nullptr) { + MEDIA_ERR_LOG("para_ is null."); + return; + } + int32_t ret = RegisterIpcCallback(DeviceClientCallback, 0, IPC_WAIT_FOREVER, &sid_, para_); + if (ret != LITEIPC_OK) { + MEDIA_ERR_LOG("RegisteIpcCallback failed\n"); + return; + } + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1); + IpcIoPushSvc(&io, &sid_); + CallBackPara para = {}; + para.funcId = CAMERA_SERVER_SET_CAMERA_CALLBACK; + uint32_t ans = proxy_->Invoke(proxy_, CAMERA_SERVER_SET_CAMERA_CALLBACK, &io, ¶, Callback); + if (ans != 0) { + MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ans); + } +} + +int32_t CameraDeviceClient::DeviceClientCallback(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg) +{ + if (ipcMsg == nullptr) { + MEDIA_ERR_LOG("call back error, ipcMsg is null\n"); + return MEDIA_ERR; + } + if (arg == nullptr) { + MEDIA_ERR_LOG("call back error, arg is null\n"); + return MEDIA_ERR; + } + CallBackPara *para = static_cast(arg); + CameraDeviceClient *client = static_cast(para->data); + uint32_t funcId; + (void)GetCode(ipcMsg, &funcId); + MEDIA_INFO_LOG("DeviceCallback, funcId=%d", funcId); + switch (funcId) { + case ON_CAMERA_CONFIGURED: { + int32_t ret = IpcIoPopInt32(io); + CameraConfig *cc = static_cast(para->cameraConfig); + client->cameraImpl_->OnConfigured(ret, *cc); + break; + } + case ON_TRIGGER_SINGLE_CAPTURE_FINISHED: { + int32_t ret = IpcIoPopInt32(io); + FrameConfig *fc = static_cast(para->frameConfig); + client->cameraImpl_->OnFrameFinished(ret, *fc); + break; + } + case ON_TRIGGER_LOOPING_CAPTURE_FINISHED: { + int32_t ret = IpcIoPopInt32(io); + int32_t streamId = IpcIoPopInt32(io); + MEDIA_INFO_LOG("ON_TRIGGER_LOOPING_CAPTURE_FINISHED : (ret=%d, streamId=%d).", ret, streamId); + break; + } + default: { + MEDIA_ERR_LOG("unsupport funId\n"); + break; + } + } + client->cameraClient_->ClearIpcMsg(ipcMsg); + return MEDIA_OK; +} +} +} diff --git a/frameworks/camera_device_client.h b/frameworks/camera_device_client.h new file mode 100755 index 0000000..94f0872 --- /dev/null +++ b/frameworks/camera_device_client.h @@ -0,0 +1,60 @@ +/* + * Copyright(c) 2020-2021 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_DEVICE_CLIENT_H +#define CAMERA_DEVICE_CLIENT_H + +#include "camera_config.h" +#include "camera_client.h" +#include "iproxy_client.h" +#include "media_log.h" +#include "liteipc_adapter.h" +#include "camera_type.h" + +#include + +namespace OHOS { +namespace Media { +class CameraImpl; +class CameraDeviceClient { +public: + static CameraDeviceClient *GetInstance(); + static int Callback(void* owner, int code, IpcIo *reply); + + ~CameraDeviceClient(); + + int32_t SetCameraConfig(CameraConfig &cc); + int32_t TriggerLoopingCapture(FrameConfig &fc); + void StopLoopingCapture(); + int32_t TriggerSingleCapture(FrameConfig &fc); + void Release(); + + void SetCameraId(std::string cameraId); + void SetCameraImpl(CameraImpl *cameraImpl); + void SetCameraCallback(); + static int32_t SurfaceRequestHandler(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg); + static int32_t DeviceClientCallback(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg); +private: + CameraDeviceClient(); + CameraClient *cameraClient_ = nullptr; + IClientProxy *proxy_ = nullptr; + std::string cameraId_; + CameraImpl *cameraImpl_ = nullptr; + CallBackPara *para_ = nullptr; + SvcIdentity sid_; +}; +} +} +#endif // CAMERA_DEVICE_CLIENT_H \ No newline at end of file diff --git a/frameworks/camera_impl.cpp b/frameworks/camera_impl.cpp index 42971ce..556552b 100755 --- a/frameworks/camera_impl.cpp +++ b/frameworks/camera_impl.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, @@ -14,17 +14,18 @@ */ #include "camera_impl.h" -#include "camera_service.h" #include "media_log.h" +#include "camera_device_client.h" +#include using namespace std; - namespace OHOS { namespace Media { -CameraImpl::CameraImpl(std::string &id, const CameraAbility *ability) +CameraImpl::CameraImpl(std::string &id, const CameraAbility *ability, const CameraInfo *info) { id_ = id; ability_ = ability; + info_ = info; } string CameraImpl::GetCameraId() @@ -57,12 +58,20 @@ void CameraImpl::Configure(CameraConfig &config) return; } - int32_t ret = device_->SetCameraConfig(config); + int32_t ret = deviceClient_->SetCameraConfig(config); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("Set camera config failed in cameraImpl."); + return; + } + config_ = &config; +} + +void CameraImpl::OnConfigured(int32_t ret, CameraConfig &config) +{ if (ret != MEDIA_OK) { handler_->Post([this, ret] { this->stateCb_->OnConfigureFailed(this->GetCameraId(), ret); }); return; } - config_ = &config; handler_->Post([this] { this->stateCb_->OnConfigured(*this); }); } @@ -72,6 +81,13 @@ void CameraImpl::Release() delete config_; config_ = nullptr; } + if (deviceClient_ == nullptr) { + return; + } + deviceClient_->Release(); + if (handler_== nullptr) { + return; + } handler_->Post([this] { this->stateCb_->OnReleased(*this); }); } @@ -86,19 +102,27 @@ int32_t CameraImpl::TriggerLoopingCapture(FrameConfig &fc) MEDIA_ERR_LOG("Frame config of the input type is already existed."); return MEDIA_OK; } - int32_t ret = device_->TriggerLoopingCapture(dynamic_cast(fc)); + if (deviceClient_ == nullptr) { + return MEDIA_ERR; + } + int32_t ret = deviceClient_->TriggerLoopingCapture(fc); if (ret != MEDIA_OK) { MEDIA_ERR_LOG("Camera device start looping capture failed.(ret=%d)", ret); return MEDIA_ERR; } frameConfigs_.emplace_back(&fc); - return MEDIA_OK; } void CameraImpl::StopLoopingCapture() { - device_->StopLoopingCapture(); + if (deviceClient_ == nullptr) { + return; + } + deviceClient_->StopLoopingCapture(); + if (config_ == nullptr) { + return; + } FrameStateCallback *fsc = config_->GetFrameStateCb(); if (fsc == nullptr) { return; @@ -119,31 +143,14 @@ void CameraImpl::StopLoopingCapture() int32_t CameraImpl::TriggerSingleCapture(FrameConfig &fc) { - if (config_ == nullptr) { + if (deviceClient_ == nullptr) { MEDIA_ERR_LOG("Cannot find available configuration, configure the camera first."); return MEDIA_INVALID_PARAM; } - MEDIA_DEBUG_LOG("Capture frame.(device=%p)", device_); - int32_t ret = device_->TriggerSingleCapture(dynamic_cast(fc)); - FrameStateCallback *fsc = config_->GetFrameStateCb(); - if (fsc == nullptr) { - return MEDIA_ERR; - } - EventHandler *eventhdl = config_->GetEventHandler(); - if (eventhdl == nullptr) { - return MEDIA_ERR; - } + int32_t ret = deviceClient_->TriggerSingleCapture(dynamic_cast(fc)); if (ret != MEDIA_OK) { - eventhdl->Post([fsc, this, &fc] { - FrameResult frameResult; - fsc->OnFrameError(*this, fc, -1, frameResult); - }); return MEDIA_ERR; } - eventhdl->Post([fsc, this, &fc] { - FrameResult frameResult; - fsc->OnFrameFinished(*this, fc, frameResult); - }); return MEDIA_OK; } @@ -152,15 +159,49 @@ const CameraAbility *CameraImpl::GetAbility() return ability_; } -void CameraImpl::OnCreate(CameraDevice *device) +const CameraInfo *CameraImpl::GetInfo() { - device_ = device; + return info_; +} + +void CameraImpl::OnCreate(string cameraId) +{ + deviceClient_ = CameraDeviceClient::GetInstance(); + if (deviceClient_ == nullptr) { + return; + } + deviceClient_->SetCameraId(cameraId); + deviceClient_->SetCameraImpl(this); + deviceClient_->SetCameraCallback(); if (stateCb_ == nullptr || handler_ == nullptr) { return; } handler_->Post([this] { this->stateCb_->OnCreated(*this); }); } +void CameraImpl::OnFrameFinished(int32_t ret, FrameConfig &fc) +{ + FrameStateCallback *fsc = config_->GetFrameStateCb(); + if (fsc == nullptr) { + return; + } + EventHandler *eventhdl = config_->GetEventHandler(); + if (eventhdl == nullptr) { + return; + } + if (ret != MEDIA_OK) { + eventhdl->Post([fsc, this, &fc] { + FrameResult frameResult; + fsc->OnFrameError(*this, fc, -1, frameResult); + }); + return; + } + eventhdl->Post([fsc, this, &fc] { + FrameResult frameResult; + fsc->OnFrameFinished(*this, fc, frameResult); + }); +} + void CameraImpl::OnCreateFailed() { if (stateCb_ == nullptr || handler_ == nullptr) { diff --git a/frameworks/camera_impl.h b/frameworks/camera_impl.h index 9654898..f5a80ed 100755 --- a/frameworks/camera_impl.h +++ b/frameworks/camera_impl.h @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, @@ -17,7 +17,8 @@ #include "camera.h" #include "camera_ability.h" -#include "camera_device.h" +#include "camera_info.h" +#include "camera_device_client.h" #include "camera_state_callback.h" namespace OHOS { @@ -25,7 +26,7 @@ namespace Media { class CameraImpl : public Camera { public: CameraImpl() = delete; - CameraImpl(std::string &id, const CameraAbility *ability); + CameraImpl(std::string &id, const CameraAbility *ability, const CameraInfo *info); ~CameraImpl() = default; std::string GetCameraId() override; @@ -40,8 +41,11 @@ public: int32_t TriggerSingleCapture(FrameConfig &frameConfig) override; const CameraAbility *GetAbility(); - void OnCreate(CameraDevice *device); + const CameraInfo *GetInfo(); + void OnCreate(std::string cameraId); void OnCreateFailed(); + void OnFrameFinished(int32_t ret, FrameConfig &fc); + void OnConfigured(int32_t ret, CameraConfig &config); void RegistCb(CameraStateCallback &callback, EventHandler &handler); private: @@ -51,7 +55,8 @@ private: CameraStateCallback *stateCb_ = nullptr; EventHandler *handler_ = nullptr; const CameraAbility *ability_ = nullptr; - CameraDevice *device_ = nullptr; + const CameraInfo *info_ = nullptr; + CameraDeviceClient *deviceClient_ = nullptr; }; } // namespace Media } // namespace OHOS diff --git a/frameworks/camera_info_impl.cpp b/frameworks/camera_info_impl.cpp new file mode 100755 index 0000000..af24fce --- /dev/null +++ b/frameworks/camera_info_impl.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020-2021 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 "camera_info_impl.h" +#include "media_log.h" + +using namespace std; +namespace OHOS { +namespace Media { + +CameraInfoImpl::CameraInfoImpl(int32_t cameraType, int32_t cameraFacingType) +{ + this->cameraType = cameraType; + this->cameraFacingType = cameraFacingType; +} +int32_t CameraInfoImpl::GetCameraType() const +{ + return cameraType; +} + +void CameraInfoImpl::SetCameraType(int32_t cameraType) +{ + this->cameraType = cameraType; + return; +} + +int32_t CameraInfoImpl::GetCameraFacingType() const +{ + return cameraFacingType; +} + +void CameraInfoImpl::SetCameraFacingType(int32_t cameraFacingType) +{ + this->cameraFacingType = cameraFacingType; + return; +} + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/camera_info_impl.h b/frameworks/camera_info_impl.h new file mode 100755 index 0000000..0f85030 --- /dev/null +++ b/frameworks/camera_info_impl.h @@ -0,0 +1,41 @@ +/* + * Copyright(c) 2020-2021 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 OHOS_CAMERA_INFO_IMPL_H +#define OHOS_CAMERA_INFO_IMPL_H + +#include "camera_info.h" + +namespace OHOS { +namespace Media { +class CameraInfoImpl : public CameraInfo { +public: + CameraInfoImpl() = delete; + ~CameraInfoImpl() = default; + CameraInfoImpl(int32_t cameraType, int32_t cameraFacingType); + + void SetCameraType(int32_t cameraType); + int32_t GetCameraType() const override; + void SetCameraFacingType(int32_t cameraFacingType); + int32_t GetCameraFacingType() const override; + +private: + int32_t cameraType; + int32_t cameraFacingType; +}; +} // namespace Media +} // namespace OHOS + + +#endif // OHOS_CAMERA_INFO_IMPL_H diff --git a/frameworks/camera_kit.cpp b/frameworks/camera_kit.cpp index 250ac2b..619e9de 100755 --- a/frameworks/camera_kit.cpp +++ b/frameworks/camera_kit.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, @@ -47,6 +47,11 @@ const CameraAbility *CameraKit::GetCameraAbility(string cameraId) return cameraManager_->GetCameraAbility(cameraId); } +const CameraInfo *CameraKit::GetCameraInfo(string cameraId) +{ + return cameraManager_->GetCameraInfo(cameraId); +} + void CameraKit::RegisterCameraDeviceCallback(CameraDeviceCallback &callback, EventHandler &handler) { cameraManager_->RegisterCameraDeviceCallback(callback, handler); diff --git a/frameworks/camera_manager.cpp b/frameworks/camera_manager.cpp index f046d95..74d8976 100755 --- a/frameworks/camera_manager.cpp +++ b/frameworks/camera_manager.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, @@ -13,12 +13,13 @@ * limitations under the License. */ #include "camera_manager.h" - -#include -#include - #include "camera_impl.h" -#include "camera_service.h" +#include "camera_service_client.h" +#include "camera_service_callback.h" +#include "media_log.h" + +#include +#include using namespace std; namespace OHOS { @@ -27,10 +28,8 @@ class CameraManagerImpl : public CameraManager, public CameraServiceCallback { public: CameraManagerImpl() { - // get client instance of camera service - cameraService_ = CameraService::GetInstance(); - // Since service is running in the current process now, it always succeed - cameraService_->Initialize(this); + cameraServiceClient_ = CameraServiceClient::GetInstance(); + cameraServiceClient_->InitCameraServiceClient(this); } ~CameraManagerImpl() { @@ -41,14 +40,13 @@ public: void OnCameraServiceInitialized(list &availCameraIdList) override { - MEDIA_DEBUG_LOG("Camera manager initializing."); /* cameraService_ cannot be nullptr as OnCameraServiceInitialized is a callback of cameraService_ */ for (auto &cameraId : availCameraIdList) { InitCameraAbility(cameraId); } } - void OnCameraStatusChange(string &cameraId, CameraStauts status, CameraDevice *device = nullptr) override + void OnCameraStatusChange(string &cameraId, CameraStauts status) override { auto p = cameraMapCache_.find(cameraId); switch (status) { @@ -74,7 +72,7 @@ public: break; case CAMERA_STATUS_CREATED: if (p != cameraMapCache_.end()) { - p->second->OnCreate(device); + p->second->OnCreate(cameraId); } break; case CAMERA_STATUS_CREATE_FAILED: @@ -119,29 +117,42 @@ public: const CameraAbility *GetCameraAbility(const string &cameraId) override { auto camera = cameraMapCache_.find(cameraId); + if (camera == cameraMapCache_.end()) { + return nullptr; + } return camera->second->GetAbility(); } + const CameraInfo *GetCameraInfo(const string &cameraId) override + { + auto camera = cameraMapCache_.find(cameraId); + if (camera == cameraMapCache_.end()) { + return nullptr; + } + return camera->second->GetInfo(); + } + void CreateCamera(const string &cameraId, CameraStateCallback &callback, EventHandler &handler) override { auto p = cameraMapCache_.find(cameraId); if (p == cameraMapCache_.end()) { + MEDIA_ERR_LOG("The cameraId %s is not available", cameraId.c_str()); handler.Post([&callback, &cameraId] { callback.OnCreateFailed(cameraId, MEDIA_ERR); }); return; } p->second->RegistCb(callback, handler); - cameraService_->CreateCamera(cameraId); + cameraServiceClient_->CreateCamera(cameraId); } - private: - CameraService *cameraService_; + CameraServiceClient *cameraServiceClient_; map cameraMapCache_; list> deviceCbList_; void InitCameraAbility(string &cameraId) { - auto ability = cameraService_->GetCameraAbility(cameraId); - CameraImpl *cam = new (nothrow) CameraImpl(cameraId, ability); + auto ability = cameraServiceClient_->GetCameraAbility(cameraId); + auto info = cameraServiceClient_->GetCameraInfo(cameraId); + CameraImpl *cam = new (nothrow) CameraImpl(cameraId, ability, info); if (cam == nullptr) { MEDIA_FATAL_LOG("New object failed."); return; diff --git a/frameworks/camera_manager.h b/frameworks/camera_manager.h index df49f44..9b62ffe 100755 --- a/frameworks/camera_manager.h +++ b/frameworks/camera_manager.h @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, @@ -19,6 +19,7 @@ #include #include "camera_ability.h" +#include "camera_info.h" #include "camera_device_callback.h" #include "camera_state_callback.h" #include "event_handler.h" @@ -28,6 +29,7 @@ namespace Media { class CameraManager { public: ~CameraManager() = default; + static CameraManager *GetInstance(); virtual std::list GetCameraIds() @@ -39,10 +41,16 @@ public: { return nullptr; } + + virtual const CameraInfo *GetCameraInfo(const std::string &cameraId) + { + return nullptr; + } + virtual void RegisterCameraDeviceCallback(CameraDeviceCallback &callback, EventHandler &handler) {} + virtual void UnregisterCameraDeviceCallback(CameraDeviceCallback &callback) {} virtual void CreateCamera(const std::string &cameraId, CameraStateCallback &callback, EventHandler &handler) {} - protected: CameraManager() {} }; diff --git a/frameworks/camera_service.cpp b/frameworks/camera_service.cpp deleted file mode 100755 index 9527d75..0000000 --- a/frameworks/camera_service.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2020-2021 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 "camera_service.h" -#ifdef __LINUX__ -#include "hal_display.h" -#include "hal_media.h" -#endif -#include "media_log.h" - -using namespace std; -namespace OHOS { -namespace Media { -const string g_mainCamera = "main"; - -CameraService::CameraService() {} - -CameraService::~CameraService() -{ - if (ability_) { - delete ability_; - } - - if (device_) { - device_->UnInitialize(); - delete device_; - } -} - -CameraService *CameraService::GetInstance() -{ - static CameraService instance; - return &instance; -} - -void CameraService::Initialize(CameraServiceCallback *callback) -{ - MEDIA_DEBUG_LOG("Camera service initializing."); - cameraServiceCb_ = callback; - // TODO: init camera devices asycronize - InitCameraDevices(); - - list cameraList = {g_mainCamera}; - cameraServiceCb_->OnCameraServiceInitialized(cameraList); -} - -const CameraAbility *CameraService::GetCameraAbility(std::string &cameraId) -{ - // TODO:fill ability - if (cameraId == g_mainCamera && device_ != nullptr) { - return ability_; - } else { - return nullptr; - } -} - -void CameraService::CreateCamera(string cameraId) -{ - if (cameraId != g_mainCamera) { - MEDIA_ERR_LOG("This camera does not exists. (cameraId=%s)", cameraId.c_str()); - return; - } -#ifdef __LINUX__ - VoLayerInit(0); -#endif - cameraServiceCb_->OnCameraStatusChange(cameraId, CameraServiceCallback::CAMERA_STATUS_CREATED, device_); -} - -int32_t CameraService::InitCameraDevices() -{ - /* Only one camera device now, support more camera in future */ - device_ = new (nothrow) CameraDevice; - if (device_ == nullptr) { - goto NEW_ERROR; - } - ability_ = new (nothrow) CameraAbility; - if (ability_ == nullptr) { - delete device_; - device_ = nullptr; - goto NEW_ERROR; - } - - if (device_->Initialize(*ability_) != MEDIA_OK) { - delete device_; - delete ability_; - device_ = nullptr; - ability_ = nullptr; - return MEDIA_ERR; - } - return MEDIA_OK; - -NEW_ERROR: - MEDIA_FATAL_LOG("New object failed."); - return MEDIA_ERR; -} -} // namespace Media -} // namespace OHOS diff --git a/frameworks/camera_service_callback.h b/frameworks/camera_service_callback.h index b8ada0c..da72c53 100755 --- a/frameworks/camera_service_callback.h +++ b/frameworks/camera_service_callback.h @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, @@ -18,8 +18,6 @@ #include #include -#include "camera_device.h" - namespace OHOS { namespace Media { class CameraServiceCallback { @@ -31,10 +29,11 @@ public: CAMERA_STATUS_AVAIL, CAMERA_STATUS_UNAVAIL, CAMERA_STATUS_CREATED, - CAMERA_STATUS_CREATE_FAILED + CAMERA_STATUS_CREATE_FAILED, + CAMERA_STATUS_CLOSE, }; virtual void OnCameraServiceInitialized(std::list &availCameraIdList) {} - virtual void OnCameraStatusChange(std::string &cameraId, CameraStauts status, CameraDevice *device) {} + virtual void OnCameraStatusChange(std::string &cameraId, CameraStauts status) {} }; } // namespace Media } // namespace OHOS diff --git a/frameworks/camera_service_client.cpp b/frameworks/camera_service_client.cpp new file mode 100755 index 0000000..1859192 --- /dev/null +++ b/frameworks/camera_service_client.cpp @@ -0,0 +1,268 @@ +/* + * Copyright(c) 2020-2021 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 "camera_service_client.h" +#include "media_log.h" +#include "samgr_lite.h" +#include "camera_type.h" +#include "camera_manager.h" +#include "meta_data.h" +#include "camera_client.h" + +#include +#include + +using namespace std; +namespace OHOS { +namespace Media { +CameraServiceClient *CameraServiceClient::GetInstance() +{ + static CameraServiceClient client; + return &client; +} + +CameraServiceClient::CameraServiceClient() +{ + cameraClient_ = CameraClient::GetInstance(); +} + +CameraServiceClient::~CameraServiceClient() +{ + if (para_ != nullptr) { + delete para_; + para_ = nullptr; + } + UnregisterIpcCallback(sid_); +} + +void CameraServiceClient::InitCameraServiceClient(CameraServiceCallback *callback) +{ + cameraServiceCb_ = callback; + if (cameraClient_->InitCameraClient()) { + MEDIA_INFO_LOG("Camera client initialize success."); + proxy_ = cameraClient_->GetIClientProxy(); + list cameraList = CameraServiceClient::GetInstance()->GetCameraIdList(); + cameraServiceCb_->OnCameraServiceInitialized(cameraList); + } +} + +int CameraServiceClient::Callback(void* owner, int code, IpcIo *reply) +{ + if (code != 0) { + MEDIA_ERR_LOG("Callback error. (code=%d)", code); + return -1; + } + if (owner == nullptr) { + return -1; + } + CallBackPara* para = (CallBackPara*)owner; + switch (para->funcId) { + case CAMERA_SERVER_GET_CAMERA_ABILITY: { + CameraServiceClient *client = static_cast(para->data); + uint32_t supportProperties = IpcIoPopUint32(reply); + // Get supported resolution. + uint32_t listSize = IpcIoPopUint32(reply); + uint32_t size; + list supportSizeList; + for (uint32_t i = 0; i < listSize; i++) { + CameraPicSize *cameraPicSize = static_cast(IpcIoPopFlatObj(reply, &size)); + supportSizeList.emplace_back(*cameraPicSize); + } + // Get supported AfModes. + uint32_t afListSize = IpcIoPopUint32(reply); + list afModeList; + for (uint32_t i = 0; i < afListSize; i++) { + afModeList.emplace_back(IpcIoPopInt32(reply)); + } + // Get supported AeModes. + uint32_t aeListSize = IpcIoPopUint32(reply); + list aeModeList; + for (uint32_t i = 0; i < aeListSize; i++) { + aeModeList.emplace_back(IpcIoPopInt32(reply)); + } + + CameraAbility *cameraAbility = new (nothrow) CameraAbility; + if (cameraAbility != nullptr) { + cameraAbility->SetParameterRange(CAM_IMAGE_YUV420, supportSizeList); + cameraAbility->SetParameterRange(CAM_AF_MODE, afModeList); + cameraAbility->SetParameterRange(CAM_AE_MODE, aeModeList); + client->deviceAbilityMap_.insert(pair(client->cameraIdForAbility, cameraAbility)); + } else { + MEDIA_ERR_LOG("Callback : cameraAbility construct failed."); + } + break; + } + case CAMERA_SERVER_GET_CAMERA_INFO: { + CameraServiceClient *client = static_cast(para->data); + int32_t cameraType = IpcIoPopInt32(reply); + int32_t cameraFacingType = IpcIoPopInt32(reply); + CameraInfo *cameraInfo = new (nothrow) CameraInfoImpl(cameraType, cameraFacingType); + if (cameraInfo != nullptr) { + client->deviceInfoMap_.insert(pair(client->cameraIdForInfo, cameraInfo)); + } else { + MEDIA_ERR_LOG("Callback : cameraAbility construct failed."); + } + break; + } + + case CAMERA_SERVER_GET_CAMERAIDLIST: { + CameraServiceClient *client = static_cast(para->data); + uint32_t listSize = IpcIoPopUint32(reply); + for (uint32_t i = 0; i < listSize; i++) { + size_t sz; + string cameraId((const char*)(IpcIoPopString(reply, &sz))); + client->list_.emplace_back(cameraId); + MEDIA_INFO_LOG("Callback : cameraId %s", cameraId.c_str()); + } + break; + } + default: + MEDIA_ERR_LOG("unsupport funcId."); + break; + } + return 0; +} + +list CameraServiceClient::GetCameraIdList() +{ + if (list_.empty()) { + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {}; + para.funcId = CAMERA_SERVER_GET_CAMERAIDLIST; + para.data = this; + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERAIDLIST, &io, ¶, Callback); + if (ret != 0) { + MEDIA_ERR_LOG("Get cameraId list ipc transmission failed. (ret=%d)", ret); + } + } + return list_; +} + +CameraAbility *CameraServiceClient::GetCameraAbility(string &cameraId) +{ + std::map::iterator iter = deviceAbilityMap_.find(cameraId); + if (iter != deviceAbilityMap_.end()) { + return iter->second; + } + cameraIdForAbility = cameraId; + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushString(&io, cameraId.c_str()); + CallBackPara para = {}; + para.funcId = CAMERA_SERVER_GET_CAMERA_ABILITY; + para.data = this; + + // wait for callback. + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERA_ABILITY, &io, ¶, Callback); + if (ret != 0) { + MEDIA_ERR_LOG("Get camera ability ipc transmission failed. (ret=%d)", ret); + } + // find cameraAbility again. + iter = deviceAbilityMap_.find(cameraId); + if (iter != deviceAbilityMap_.end()) { + return iter->second; + } + MEDIA_ERR_LOG("Get cameraAbility of camera %d from cameraService failded", cameraId.c_str()); + return nullptr; +} + +CameraInfo *CameraServiceClient::GetCameraInfo(string &cameraId) +{ + std::map::iterator iter = deviceInfoMap_.find(cameraId); + if (iter != deviceInfoMap_.end()) { + return iter->second; + } + cameraIdForInfo = cameraId; + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushString(&io, cameraId.c_str()); + CallBackPara para = {}; + para.funcId = CAMERA_SERVER_GET_CAMERA_INFO; + para.data = this; + // wait for callback. + uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERA_INFO, &io, ¶, Callback); + if (ret != 0) { + MEDIA_ERR_LOG("Get camera info ipc transmission failed. (ret=%d)", ret); + } + + iter = deviceInfoMap_.find(cameraId); + if (iter != deviceInfoMap_.end()) { + return iter->second; + } + MEDIA_ERR_LOG("Get cameraInfo of camera %d from cameraService failded", cameraId.c_str()); + return nullptr; +} + +int32_t CameraServiceClient::ServiceClientCallback(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg) +{ + if (ipcMsg == nullptr) { + MEDIA_ERR_LOG("call back error, ipcMsg is null\n"); + return MEDIA_ERR; + } + if (arg == nullptr) { + MEDIA_ERR_LOG("call back error, arg is null\n"); + return MEDIA_ERR; + } + CallBackPara* para = static_cast(arg); + CameraServiceClient *client = static_cast(para->data); + uint32_t funcId; + (void)GetCode(ipcMsg, &funcId); + MEDIA_INFO_LOG("ServiceClientCallback, funcId=%d", funcId); + switch (funcId) { + case ON_CAMERA_STATUS_CHANGE: { + CameraServiceCallback::CameraStauts cameraStatus = + static_cast(IpcIoPopInt32(io)); + string cameraId = para->cameraId; + client->cameraServiceCb_->OnCameraStatusChange(cameraId, cameraStatus); + break; + } + default: { + MEDIA_ERR_LOG("unsupport funId\n"); + break; + } + } + client->cameraClient_->ClearIpcMsg(ipcMsg); + return MEDIA_OK; +} + +void CameraServiceClient::CreateCamera(string cameraId) +{ + para_ = new (nothrow) CallBackPara; + if (para_ == nullptr) { + MEDIA_ERR_LOG("para_ is null, failed."); + return; + } + para_->cameraId = cameraId; + para_->data = this; + int32_t ret = RegisterIpcCallback(ServiceClientCallback, 0, IPC_WAIT_FOREVER, &sid_, para_); + if (ret != LITEIPC_OK) { + MEDIA_ERR_LOG("RegisteIpcCallback failed, (ret=%d).", ret); + return; + } + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1); + IpcIoPushString(&io, cameraId.c_str()); + IpcIoPushSvc(&io, &sid_); + uint32_t ans = proxy_->Invoke(proxy_, CAMERA_SERVER_CREATE_CAMERA, &io, NULL, NULL); + if (ans != 0) { + MEDIA_ERR_LOG("Create camera ipc transmission failed. (ret=%d)", ans); + } +} +} +} \ No newline at end of file diff --git a/frameworks/camera_service_client.h b/frameworks/camera_service_client.h new file mode 100755 index 0000000..7b16def --- /dev/null +++ b/frameworks/camera_service_client.h @@ -0,0 +1,59 @@ +/* + * Copyright(c) 2020-2021 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_SERVICE_CLIENT_H +#define CAMERA_SERVICE_CLIENT_H + +#include "liteipc_adapter.h" +#include "serializer.h" +// #include "camera_ability_impl.h" +#include "camera_ability.h" +#include "camera_info_impl.h" +#include "iproxy_client.h" +#include "camera_service_callback.h" +#include "camera_client.h" +#include "camera_type.h" + +namespace OHOS { +namespace Media { +class CameraServiceClient { +public: + ~CameraServiceClient(); + static CameraServiceClient *GetInstance(); + static int Callback(void* owner, int code, IpcIo *reply); + void InitCameraServiceClient(CameraServiceCallback *callback); + std::list GetCameraIdList(); + CameraAbility *GetCameraAbility(std::string &cameraId); + CameraInfo *GetCameraInfo(std::string &cameraId); + void CreateCamera(std::string cameraId); + static int32_t ServiceClientCallback(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg); + +private: + CameraServiceClient(); + IClientProxy* proxy_ = nullptr; + CameraClient *cameraClient_ = nullptr; + std::list list_; + CameraAbility *ability_ = nullptr; + std::string cameraIdForAbility; + std::map deviceAbilityMap_; + std::string cameraIdForInfo; + std::map deviceInfoMap_; + CameraServiceCallback *cameraServiceCb_ = nullptr; + SvcIdentity sid_; + CallBackPara *para_ = nullptr; +}; +} // namespace Media +} // namespace OHOS + +#endif // CAMERA_SERVICE_CLIENT_H diff --git a/frameworks/event_handler.cpp b/frameworks/event_handler.cpp index 8483132..fe9af14 100755 --- a/frameworks/event_handler.cpp +++ b/frameworks/event_handler.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020-2021 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 + * 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, diff --git a/frameworks/frame_config.cpp b/frameworks/frame_config.cpp index cf17675..22c5442 100755 --- a/frameworks/frame_config.cpp +++ b/frameworks/frame_config.cpp @@ -14,6 +14,7 @@ */ #include "frame_config.h" #include "media_log.h" +#include "securec.h" using namespace std; @@ -45,10 +46,46 @@ void *FrameConfig::GetValue(uint32_t key) return (p == keyMap_.end()) ? nullptr : (&p->second); } +void FrameConfig::SetVendorParameter(uint8_t *value, uint32_t len) +{ + if (value == nullptr) { + MEDIA_ERR_LOG("value is a nullptr"); + return; + } + errno_t ret = memset_s(privateTag_, sizeof(privateTag_), 0, sizeof(privateTag_)); + if (ret != EOK) { + MEDIA_ERR_LOG("memset failed when set private tag, ret(%d)", ret); + return; + } + ret = memcpy_s(privateTag_, sizeof(privateTag_), value, len); + if (ret != EOK) { + MEDIA_ERR_LOG("memcpy failed when set private tag, ret(%d)", ret); + } +} + +void FrameConfig::GetVendorParameter(uint8_t *value, uint32_t len) +{ + if (value == nullptr) { + MEDIA_ERR_LOG("value is a nullptr"); + return; + } + uint32_t realLength = len > PRIVATE_TAG_LEN ? PRIVATE_TAG_LEN : len; + errno_t ret = memcpy_s(value, realLength, privateTag_, realLength); + if (ret != EOK) { + MEDIA_ERR_LOG("memcpy failed when get private tag, ret(%d)", ret); + } +} + void FrameConfig::SetValue(uint32_t key, const void *value) { + if (value == nullptr) { + MEDIA_ERR_LOG("value is a nullptr"); + return; + } switch (key) { case PARAM_KEY_IMAGE_ENCODE_QFACTOR: + case PARAM_KEY_STREAM_FPS: + case CAM_IMAGE_FORMAT: keyMap_[key] = *(static_cast(value)); break; default: diff --git a/interfaces/kits/camera_ability.h b/interfaces/kits/camera_ability.h index f64226e..db6ae8b 100755 --- a/interfaces/kits/camera_ability.h +++ b/interfaces/kits/camera_ability.h @@ -75,6 +75,20 @@ public: */ std::list GetSupportedSizes(int format) const; + /** + * @brief Obtains the supported autofocus (AF) modes. + * + * @return Returns the autofocus modes. + */ + std::list GetSupportedAfModes() const; + + /** + * @brief Obtains the supported auto exposure (AE) modes. + * + * @return Returns the auto exposure modes. + */ + std::list GetSupportedAeModes() const; + /** * @brief Sets value ranges for a specified parameter. * @@ -102,15 +116,18 @@ public: if (supportProperties_.find(key) != supportProperties_.end()) { return GetSupportParameterRange(key); } + return nullptr; } private: void SetSupportParameterRange(uint32_t key, std::list &rangeList); + void SetSupportParameterRange(uint32_t key, std::list &rangeList); std::list GetSupportParameterRange(uint32_t key) const; bool IsParameterSupport(uint32_t key) const; - std::map> SizeMap_; std::set supportProperties_; + std::list afModes; + std::list aeModes; }; } // namespace Media } // namespace OHOS diff --git a/interfaces/kits/camera_info.h b/interfaces/kits/camera_info.h new file mode 100755 index 0000000..419ab42 --- /dev/null +++ b/interfaces/kits/camera_info.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020-2021 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. + */ + +/** + * @addtogroup MultiMedia_CameraInfo + * @{ + * + * @brief Defines the camera info set for applications to achieve and access the info. + * + * @since 2.0 + * @version 2.0 + */ + +/** + * @file camera_info.h + * + * @brief Declares functions of the CameraInfo class. + * + * + * @since 2.0 + * @version 2.0 + */ + +#ifndef OHOS_CAMERA_INFO_H +#define OHOS_CAMERA_INFO_H + +#include "media_log.h" +#include "meta_data.h" + +namespace OHOS { +namespace Media { + +typedef enum { + /* Wide angle camera */ + WIDE_ANGLE, + /* Fisheye camera */ + FISH_EYE, + /* Depth camera */ + TRUE_DEPTH, + /* Other camera */ + OTHER_TYPE +} CameraType; + +typedef enum { + /* front */ + CAMERA_FACING_FRONT, + /* back */ + CAMERA_FACING_BACK, + /* other */ + CAMERA_FACING_OTHERS +} FacingType; + +class CameraInfo { +public: + /** + * @brief A constructor used to create a CameraInfo instance. + * + */ + CameraInfo() = default; + + /** + * @brief A destructor used to delete the CameraInfo instance. + * + */ + virtual ~CameraInfo() = default; + + /** + * @brief Obtains the camera type. + * + * @return Returns the caemra type, whick can be {@link CameraType}. + */ + virtual int32_t GetCameraType() const + { + return -1; + } + + /** + * @brief Obtains the camera type. + * + * @return Returns the caemra type, whick can be {@link FacingType}. + */ + virtual int32_t GetCameraFacingType() const + { + return -1; + } +}; + +} +} +#endif // OHOS_CAMERA_INFO_H \ No newline at end of file diff --git a/interfaces/kits/camera_kit.h b/interfaces/kits/camera_kit.h index ce93c80..738898f 100755 --- a/interfaces/kits/camera_kit.h +++ b/interfaces/kits/camera_kit.h @@ -39,6 +39,7 @@ #include #include "camera_ability.h" +#include "camera_info.h" #include "camera_device_callback.h" #include "camera_state_callback.h" #include "event_handler.h" @@ -81,6 +82,14 @@ public: */ const CameraAbility *GetCameraAbility(std::string cameraId); + /** + * @brief Obtains the camera device info, including the camera type and facing type. + * + * @param cameraId Indicates the camera ID. + * @return Returns the CameraInfo object. + */ + const CameraInfo *GetCameraInfo(std::string cameraId); + /** * @brief Registers a camera callback for camera status changes * and an event callback to respond to a triggered event. diff --git a/interfaces/kits/frame_config.h b/interfaces/kits/frame_config.h index d80a0bf..2c13959 100755 --- a/interfaces/kits/frame_config.h +++ b/interfaces/kits/frame_config.h @@ -44,9 +44,13 @@ namespace OHOS { namespace Media { + constexpr int32_t FRAME_CONFIG_PREVIEW = 0; constexpr int32_t FRAME_CONFIG_RECORD = 1; constexpr int32_t FRAME_CONFIG_CAPTURE = 2; +constexpr int32_t FRAME_CONFIG_CALLBACK = 3; +constexpr int32_t PRIVATE_TAG_LEN = 32; + /** * @brief Provides functions to configure frames. * @@ -113,7 +117,7 @@ public: * @param key Indicates the common parameter key to set. * @param value Indicates the common parameter value to set. */ - template void SetParameter(uint32_t key, const T value) + template void SetParameter(uint32_t key, const T value) { SetValue(key, static_cast(&value)); } @@ -130,10 +134,26 @@ public: value = *pvalue; } } + + /** + * @brief set the private config value + * @param value Indicates the private config value. + * @param len Indicates the length of the private config value; + */ + void SetVendorParameter(uint8_t *value, uint32_t len); + + /** + * @brief get the private config value + * @param value Indicates the private config value. + * @param len Indicates the length of the private config value; + */ + void GetVendorParameter(uint8_t *value, uint32_t len); + private: int32_t type_; std::list surfaceList_; std::map keyMap_; + uint8_t privateTag_[PRIVATE_TAG_LEN]; void *GetValue(uint32_t key); void SetValue(uint32_t key, const void *value); }; diff --git a/interfaces/kits/meta_data.h b/interfaces/kits/meta_data.h index 1bf350f..78259c2 100755 --- a/interfaces/kits/meta_data.h +++ b/interfaces/kits/meta_data.h @@ -72,6 +72,14 @@ typedef enum { CAM_IMAGE_DENOISE_MODE, /* Image denoising level */ CAM_IMAGE_DENOISE_LEVEL, + /*Only vaild when frameConfigType is callback*/ + CAM_IMAGE_FORMAT, + /* Auto foucue mode */ + CAM_AF_MODE, + /* Image denoising level */ + PARAM_KEY_STREAM_FPS, + PARAM_KEY_SIZE, + PARAM_KEY_IMAGE_ENCODE_QFACTOR } CameraFuncKey; /** @@ -85,11 +93,31 @@ typedef enum { CAM_ROTATION_180 = 4, /**< 180-degree rotation */ } CameraInvertMode; -#define PARAM_KEY_SIZE 0 -#define PARAM_KEY_IMAGE_ENCODE_QFACTOR 1 +//#define PARAM_KEY_SIZE 0 +//#define PARAM_KEY_IMAGE_ENCODE_QFACTOR 1 #define ENCODER_TYPE 0 -typedef enum { CAM_ENCODE_JPEG, CAM_ENCODE_H264, CAM_ENCODE_H265, CAM_ENCODE_FORMAT_BUTT } CameraEncodeFormat; +typedef enum { + CAM_ENCODE_JPEG, + CAM_ENCODE_H264, + CAM_ENCODE_H265, + CAM_ENCODE_FORMAT_BUTT +} CameraEncodeFormat; + +typedef enum { + CAM_IMAGE_YUV420, + CAM_IMAGE_RAW12 +} CameraImageFormat; + +typedef enum { + AF_MODE_CONTINUOUS, + AF_MODE_CLOSE +} AfMode; + +typedef enum { + AE_MODE_OPEN, + AE_MODE_CLOSE +} AeMode; #ifdef __cplusplus #if __cplusplus diff --git a/services/BUILD.gn b/services/BUILD.gn new file mode 100755 index 0000000..e43829c --- /dev/null +++ b/services/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (c) 2020 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. + +import("//build/lite/config/component/lite_component.gni") + +shared_library("camera_server") { + sources = [ + "./src/camera_device.cpp", + "./src/camera_server.cpp", + "./src/camera_service.cpp", + "./src/samgr_camera.cpp", + ] + include_dirs = ["./include"] + public_configs = [ ":external_camera_server_library" ] + ldflags = [ + "-lstdc++", + "-lcodec", + "-lhdi_camera", + "-lhdi_videodisplayer", + "-lpthread", + "-Wl,-rpath-link=$ohos_root_path/$root_out_dir", + ] + cflags = [ "-Wall" ] + cflags += [ "-fPIC" ] + cflags_cc = cflags + deps = [ + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", + "//base/security/permission/services/permission_lite/pms_client:pms_client", + "//device/hisilicon/hardware:hardware_media_sdk", + "//device/hisilicon/modules/middleware:middleware_source_sdk", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", + "//third_party/bounds_checking_function:libsec_shared", + ] + public_deps = [ + "//foundation/graphic/surface:lite_surface", + "//foundation/multimedia/camera_lite/frameworks:camera_lite", + "//foundation/multimedia/utils/lite:media_common", + ] +} + +config("external_camera_server_library") { + include_dirs = [ + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + "//utils/native/lite/include", + "//foundation/multimedia/utils/lite/interfaces/kits", + "//drivers/peripheral/format/interfaces/include", + "//foundation/multimedia/utils/lite/hals", + "//base/security/permission/interfaces/kits/permission_lite", + "//foundation/multimedia/services/camera_lite/include", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/communication/broadcast", + "//foundation/communication/ipc_lite/interfaces/kits", + "//drivers/peripheral/codec/interfaces/include", + "//foundation/multimedia/utils/lite/hals", + "//foundation/multimedia/camera_lite/frameworks", + "//drivers/peripheral/display/interfaces/include", + "//drivers/peripheral/base" + ] +} diff --git a/frameworks/camera_device.h b/services/include/camera_device.h similarity index 56% rename from frameworks/camera_device.h rename to services/include/camera_device.h index cfd8bb5..ac5e89b 100755 --- a/frameworks/camera_device.h +++ b/services/include/camera_device.h @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020 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 + * 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, @@ -24,9 +24,7 @@ #include "camera_config.h" #include "codec_type.h" #include "frame_config.h" -#include "hal_media.h" #include "surface.h" - using namespace std; namespace OHOS { namespace Media { @@ -43,13 +41,14 @@ public: std::thread *thrd_ = nullptr; LoopState state_ = LOOP_IDLE; FrameConfig *fc_ = nullptr; + uint32_t cameraId_; + uint32_t streamId_; - virtual int32_t - SetFrameConfig(FrameConfig &fc, std::vector &hdls, std::vector &attrs) + virtual int32_t SetFrameConfig(FrameConfig &fc, uint32_t *streamId) { return -1; } - virtual int32_t Start() + virtual int32_t Start(uint32_t streamId) { return -1; } @@ -61,60 +60,67 @@ public: class RecordAssistant : public DeviceAssistant { public: - int32_t SetFrameConfig(FrameConfig &fc, - std::vector &hdls, - std::vector &attrs) override; - int32_t Start() override; + int32_t SetFrameConfig(FrameConfig &fc, uint32_t *streamId) override; + int32_t Start(uint32_t streamId) override; int32_t Stop() override; vector vencHdls_; vector> vencSurfaces_; - vector vencAttr_; - int32_t VideoEncIsExist(HalVideoProcessorAttr *attr); static int OnVencBufferAvailble(UINTPTR hComponent, UINTPTR dataIn, OutputInfo *buffer); static CodecCallback recordCodecCb_; }; class PreviewAssistant : public DeviceAssistant { public: - int32_t SetFrameConfig(FrameConfig &fc, - std::vector &hdls, - std::vector &attrs) override; - int32_t Start() override; + int32_t SetFrameConfig(FrameConfig &fc, uint32_t *streamId) override; + int32_t Start(uint32_t streamId) override; virtual int32_t Stop() override; + Surface *capSurface_ = nullptr; +private: + int32_t sourceIdx = 0; + // uint32_t streamId = 0; + pthread_t threadId; + static void *YuvCopyProcess(void *arg); }; class CaptureAssistant : public DeviceAssistant { - int32_t SetFrameConfig(FrameConfig &fc, - std::vector &hdls, - std::vector &attrs) override; - int32_t Start() override; + int32_t SetFrameConfig(FrameConfig &fc, uint32_t *streamId) override; + int32_t Start(uint32_t streamId) override; virtual int32_t Stop() override; CODEC_HANDLETYPE vencHdl_ = nullptr; Surface *capSurface_ = nullptr; }; +class CallbackAssistant : public DeviceAssistant { +public: + int32_t SetFrameConfig(FrameConfig &fc, uint32_t *streamId) override; + int32_t Start(uint32_t streamId) override; + virtual int32_t Stop() override; + Surface *capSurface_ = nullptr; +private: + pthread_t threadId; + static void *StreamCopyProcess(void *arg); +}; + class CameraDevice { public: CameraDevice(); + CameraDevice(uint32_t cameraId); virtual ~CameraDevice(); - int32_t Initialize(CameraAbility &ability); + int32_t Initialize(); int32_t UnInitialize(); - int32_t SetCameraConfig(CameraConfig &cc); - - int32_t TriggerLoopingCapture(FrameConfig &fc); + int32_t SetCameraConfig(); + int32_t TriggerLoopingCapture(FrameConfig &fc, uint32_t *streamId); void StopLoopingCapture(); - - int32_t TriggerSingleCapture(FrameConfig &fc); - + int32_t TriggerSingleCapture(FrameConfig &fc, uint32_t *streamId); + uint32_t GetCameraId(); private: - CameraConfig *cc_ = nullptr; - std::vector prcessorHdls_; - std::vector prcessorAttrs_; + uint32_t cameraId; RecordAssistant recordAssistant_; PreviewAssistant previewAssistant_; CaptureAssistant captureAssistant_; + CallbackAssistant callbackAssistant_; }; } // namespace Media } // namespace OHOS diff --git a/services/include/camera_server.h b/services/include/camera_server.h new file mode 100755 index 0000000..5c32512 --- /dev/null +++ b/services/include/camera_server.h @@ -0,0 +1,53 @@ +/* + * Copyright(c) 2020 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_SERVER_H +#define CAMERA_SERVER_H + +#include "camera_service.h" +#include "liteipc_adapter.h" +#include "serializer.h" +#include "camera_ability.h" + +namespace OHOS { +namespace Media { +class CameraServer { +public: + static CameraServer *GetInstance(); + ~CameraServer() {} + + static void CameraServerRequestHandle(int funcId, void *origin, IpcIo *req, IpcIo *reply); + void InitCameraServer(); + void GetCameraAbility(IpcIo *req, IpcIo *reply); + void GetCameraInfo(IpcIo *req, IpcIo *reply); + void GetCameraIdList(IpcIo *req, IpcIo *reply); + void CreateCamera(IpcIo *req, IpcIo *reply); + void CloseCamera(IpcIo *req, IpcIo *reply); + void SetCameraConfig(IpcIo *req, IpcIo *reply); + void SetFrameConfig(IpcIo *req, IpcIo *reply); + void TriggerLoopingCapture(IpcIo *req, IpcIo *reply); + void StopLoopingCapture(IpcIo *req, IpcIo *reply); + void TriggerSingleCapture(IpcIo *req, IpcIo *reply); + void SetCameraCallback(IpcIo *req, IpcIo *reply); + void OnTriggerSingleCaptureFinished(int32_t ret); + void OnTriggerLoopingCaptureFinished(int32_t ret, int32_t streamId); + void OnCameraStatusChange(int32_t ret, SvcIdentity *sid); + void OnCameraConfigured(int32_t ret); +private: + CameraServer() {} + SvcIdentity sid_; +}; +} // namespace Media +} // namespace OHOS +#endif // CAMERA_SERVER_H diff --git a/frameworks/camera_service.h b/services/include/camera_service.h similarity index 56% rename from frameworks/camera_service.h rename to services/include/camera_service.h index a57fac7..21281d1 100755 --- a/frameworks/camera_service.h +++ b/services/include/camera_service.h @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright(c) 2020 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 + * 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, @@ -17,6 +17,8 @@ #include "camera_device.h" #include "camera_service_callback.h" +#include "camera_ability.h" +#include "camera_info_impl.h" namespace OHOS { namespace Media { @@ -25,15 +27,19 @@ public: ~CameraService(); static CameraService *GetInstance(); - void Initialize(CameraServiceCallback *callback); - const CameraAbility *GetCameraAbility(std::string &cameraId); - void CreateCamera(std::string cameraId); - + void Initialize(); + CameraAbility *GetCameraAbility(std::string &cameraId); + CameraInfo *GetCameraInfo(std::string &cameraId); + CameraDevice *GetCameraDevice(std::string &cameraId); + int32_t CreateCamera(std::string cameraId); + int32_t CloseCamera(string cameraId); + list GetCameraIdList(); private: CameraService(); int32_t InitCameraDevices(); - CameraDevice *device_ = nullptr; - CameraAbility *ability_ = nullptr; + std::map deviceMap_; // pair(deviceId, device) + std::map deviceAbilityMap_; // pair(deviceId, ability) + std::map deviceInfoMap_; // pair(deviceId, info) CameraServiceCallback *cameraServiceCb_ = nullptr; }; } // namespace Media diff --git a/services/include/camera_type.h b/services/include/camera_type.h new file mode 100755 index 0000000..928a56d --- /dev/null +++ b/services/include/camera_type.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 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_TYPE_H +#define CAMERA_TYPE_H + +#include + +namespace OHOS { +namespace Media { +typedef enum { + CAMERA_SERVER_GET_CAMERA_ABILITY, + CAMERA_SERVER_GET_CAMERA_INFO, + CAMERA_SERVER_GET_CAMERAIDLIST, + CAMERA_SERVER_CREATE_CAMERA, + CAMERA_SERVER_CLOSE_CAMERA, + CAEMRA_SERVER_SET_CAMERA_CONFIG, + CAEMRA_SERVER_SET_FRAME_CONFIG, + CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE, + CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE, + CAMERA_SERVER_STOP_LOOPING_CAPTURE, + CAMERA_SERVER_SET_CAMERA_CALLBACK, +} CameraServerCall; + +typedef enum { + ON_CAMERA_STATUS_CHANGE, + ON_CAMERA_CONFIGURED, + ON_TRIGGER_SINGLE_CAPTURE_FINISHED, + ON_TRIGGER_LOOPING_CAPTURE_FINISHED +} CameraServerback; + +struct CallBackPara { + int funcId; + std::string cameraId; + void* data; + void* frameConfig; + void* cameraConfig; +}; +const char SERVICE_NAME[] = "CameraServer"; +static const int32_t DEFAULT_IPC_SIZE = 100; +} +} +#endif diff --git a/services/src/camera_device.cpp b/services/src/camera_device.cpp new file mode 100755 index 0000000..b4a0d8c --- /dev/null +++ b/services/src/camera_device.cpp @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2020 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 "camera_device.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "codec_interface.h" +#include "display_layer.h" +#include "hal_camera.h" +#include "media_log.h" +#include "meta_data.h" +#include "securec.h" + +#include +#include +#include + +using namespace OHOS; +using namespace OHOS::Media; +using namespace std; +#define DELAY_TIME_ONE_FRAME 40000 + +/** Indicates that the current frame is an Instantaneous Decoder Refresh (IDR) frame. */ +const int32_t KEY_IS_SYNC_FRAME = 1; +/** Indicates the frame timestamp. */ +const int32_t KEY_TIME_US = 2; + +const int32_t IMAGE_WIDTH = 3; // "DATA_PIX_FORMAT" +const int32_t IMAGE_HEIGHT = 4; // "DATA_PIX_FORMAT" +const int32_t IMAGE_SIZE = 5; // "DATA_PIX_FORMAT" + +namespace OHOS { +namespace Media { + +extern Surface *g_surface; +inline PicSize Convert2CodecSize(int32_t width, int32_t height) +{ + struct SizeMap { + PicSize res_; + int32_t width_; + int32_t height_; + }; + static SizeMap sizeMap[] = { + {RESOLUTION_CIF, 352, 288}, + {RESOLUTION_360P, 640, 360}, + {RESOLUTION_D1_PAL, 720, 576}, + {RESOLUTION_D1_NTSC, 720, 480}, + {RESOLUTION_720P, 1280, 720}, + {RESOLUTION_1080P, 1920, 1080} + }; + for (uint32_t i = 0; i < sizeof(sizeMap) / sizeof(SizeMap); i++) { + if (sizeMap[i].width_ == width && sizeMap[i].height_ == height) { + return sizeMap[i].res_; + } + } + return RESOLUTION_INVALID; +} + +static int32_t SetVencSource(CODEC_HANDLETYPE codecHdl, uint32_t deviceId) +{ + Param param = {.key = KEY_DEVICE_ID, .val = (void *)&deviceId, .size = sizeof(uint32_t)}; + int32_t ret = CodecSetParameter(codecHdl, ¶m, 1); + if (ret != 0) { + MEDIA_ERR_LOG("Set enc source failed.(ret=%d)", ret); + return ret; + } + return MEDIA_OK; +} + +static int32_t CameraCreateVideoEnc(FrameConfig &fc, + StreamAttr stream, + uint32_t srcDev, + CODEC_HANDLETYPE *codecHdl) +{ + const char *name = "codec.video.hardware.encoder"; + const uint32_t maxParamNum = 10; + uint32_t paramIndex = 0; + Param param[maxParamNum]; + + CodecType domainKind = VIDEO_ENCODER; + param[paramIndex].key = KEY_CODEC_TYPE; + param[paramIndex].val = &domainKind; + param[paramIndex].size = sizeof(CodecType); + paramIndex++; + + AvCodecMime codecMime = MEDIA_MIMETYPE_VIDEO_HEVC; + param[paramIndex].key = KEY_MIMETYPE; + param[paramIndex].val = &codecMime; + param[paramIndex].size = sizeof(AvCodecMime); + paramIndex++; + + VenCodeRcMode rcMode = VENCOD_RC_CBR; + param[paramIndex].key = KEY_VIDEO_RC_MODE; + param[paramIndex].val = &rcMode; + param[paramIndex].size = sizeof(VenCodeRcMode); + paramIndex++; + + VenCodeGopMode gopMode = VENCOD_GOPMODE_NORMALP; + param[paramIndex].key = KEY_VIDEO_GOP_MODE; + param[paramIndex].val = &gopMode; + param[paramIndex].size = sizeof(VenCodeGopMode); + paramIndex++; + + Profile profile = HEVC_MAIN_PROFILE; + param[paramIndex].key = KEY_VIDEO_PROFILE; + param[paramIndex].val = &profile; + param[paramIndex].size = sizeof(Profile); + paramIndex++; + + + auto surfaceList = fc.GetSurfaces(); +#ifdef __LINUX__ + Surface *surface = g_surface; +#else + Surface *surface = surfaceList.front(); +#endif + + PicSize picSize = Convert2CodecSize(surface->GetWidth(), surface->GetHeight()); + MEDIA_DEBUG_LOG("picSize=%d", picSize); + param[paramIndex].key = KEY_VIDEO_PIC_SIZE; + param[paramIndex].val = &picSize; + param[paramIndex].size = sizeof(PicSize); + paramIndex++; + + uint32_t frameRate = stream.fps; + MEDIA_DEBUG_LOG("frameRate=%u", frameRate); + param[paramIndex].key = KEY_VIDEO_FRAME_RATE; + param[paramIndex].val = &frameRate; + param[paramIndex].size = sizeof(uint32_t); + paramIndex++; + + int32_t ret = CodecCreate(name, param, paramIndex, codecHdl); + if (ret != 0) { + MEDIA_ERR_LOG("Create video encoder failed."); + return MEDIA_ERR; + } + + ret = SetVencSource(*codecHdl, srcDev); + if (ret != 0) { + CodecDestroy(codecHdl); + return MEDIA_ERR; + } + + return MEDIA_OK; +} + +static int32_t CameraCreateJpegEnc(FrameConfig &fc, uint32_t srcDev, CODEC_HANDLETYPE *codecHdl) +{ + const char *videoEncName = "codec.jpeg.hardware.encoder"; + const uint32_t maxParamNum = 5; + Param param[maxParamNum]; + uint32_t paramIndex = 0; + + CodecType domainKind = VIDEO_ENCODER; + param[paramIndex].key = KEY_CODEC_TYPE; + param[paramIndex].val = &domainKind; + param[paramIndex].size = sizeof(CodecType); + paramIndex++; + + AvCodecMime codecMime = MEDIA_MIMETYPE_IMAGE_JPEG; + param[paramIndex].key = KEY_MIMETYPE; + param[paramIndex].val = &codecMime; + param[paramIndex].size = sizeof(AvCodecMime); + paramIndex++; + + auto surfaceList = fc.GetSurfaces(); + Surface *surface = surfaceList.front(); + + std::cout<<"------2: CameraCreateJpegEnc: surface width and height: "<GetWidth()<<", "<GetHeight()<GetWidth(), surface->GetHeight()); + param[paramIndex].key = KEY_VIDEO_PIC_SIZE; + param[paramIndex].val = &picSize; + param[paramIndex].size = sizeof(PicSize); + paramIndex++; + + int32_t ret = CodecCreate(videoEncName, param, paramIndex, codecHdl); + if (ret != 0) { + return MEDIA_ERR; + } + int32_t qfactor = -1; + fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor); + if (qfactor != -1) { + Param jpegParam = { + .key = KEY_IMAGE_Q_FACTOR, + .val = &qfactor, + .size = sizeof(qfactor) + }; + ret = CodecSetParameter(*codecHdl, &jpegParam, 1); + if (ret != 0) { + MEDIA_ERR_LOG("CodecSetParameter set jpeg qfactor failed.(ret=%u)", ret); + } + } + + ret = SetVencSource(*codecHdl, srcDev); + if (ret != 0) { + MEDIA_ERR_LOG("Set video encoder source failed."); + CodecDestroy(*codecHdl); + return MEDIA_ERR; + } + + return MEDIA_OK; +} + +static int32_t CopyCodecOutput(void *dst, uint32_t *size, OutputInfo *buffer) +{ + char *dstBuf = reinterpret_cast(dst); + for (uint32_t i = 0; i < buffer->bufferCnt; i++) { + uint32_t packSize = buffer->buffers[i].length - buffer->buffers[i].offset; + errno_t ret = memcpy_s(dstBuf, *size, buffer->buffers[i].addr + buffer->buffers[i].offset, packSize); + if (ret != EOK) { + return MEDIA_ERR; + } + *size -= packSize; + dstBuf += packSize; + } + return MEDIA_OK; +} + +static void StreamAttrInitialize(StreamAttr *streamAttr, Surface *surface, + StreamType streamType, ImageFormat streamFormat) +{ + if (streamAttr == nullptr || surface == nullptr) { + return; + } + memset_s(streamAttr, sizeof(StreamAttr), 0, sizeof(StreamAttr)); + streamAttr->type = streamType; + streamAttr->format = streamFormat; + streamAttr->width = surface->GetWidth(); + streamAttr->height = surface->GetHeight(); + streamAttr->fps = 30; +} + +static ImageFormat Convert2HalImageFormat(uint32_t format) +{ + if (format == CAM_IMAGE_RAW12) { + return FORMAT_RGB_BAYER_12BPP; + } + return FORMAT_YVU420; +} + +int32_t RecordAssistant::OnVencBufferAvailble(UINTPTR hComponent, UINTPTR dataIn, OutputInfo *buffer) +{ + CODEC_HANDLETYPE hdl = reinterpret_cast(hComponent); + RecordAssistant *assistant = reinterpret_cast(dataIn); + list *surfaceList = nullptr; + for (uint32_t idx = 0; idx < assistant->vencHdls_.size(); idx++) { + if (assistant->vencHdls_[idx] == hdl) { + surfaceList = &(assistant->vencSurfaces_[idx]); + break; + } + } + if (surfaceList == nullptr || surfaceList->empty()) { + MEDIA_ERR_LOG("Encoder handle is illegal."); + return MEDIA_ERR; + } + int32_t ret = -1; + for (auto &surface : *surfaceList) { +#ifdef __LINUX__ + SurfaceBuffer *surfaceBuf = g_surface->RequestBuffer(); +#else + SurfaceBuffer *surfaceBuf = surface->RequestBuffer(); +#endif + if (surfaceBuf == nullptr) { + MEDIA_ERR_LOG("No available buffer in surface."); + break; + } +#ifdef __LINUX__ + uint32_t size = g_surface->GetSize(); +#else + uint32_t size = surface->GetSize(); +#endif + void *buf = surfaceBuf->GetVirAddr(); + if (buf == nullptr) { + MEDIA_ERR_LOG("Invalid buffer address."); + break; + } + ret = CopyCodecOutput(buf, &size, buffer); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("No available buffer in surface."); +#ifdef __LINUX__ + g_surface->CancelBuffer(surfaceBuf); +#else + surface->CancelBuffer(surfaceBuf); +#endif + + break; + } + surfaceBuf->SetInt32(KEY_IS_SYNC_FRAME, (((buffer->flag & STREAM_FLAG_KEYFRAME) == 0) ? 0 : 1)); + surfaceBuf->SetInt64(KEY_TIME_US, buffer->timeStamp); +#ifdef __LINUX__ + surfaceBuf->SetSize(g_surface->GetSize() - size); + if (g_surface->FlushBuffer(surfaceBuf) != 0) { + MEDIA_ERR_LOG("Flush surface failed."); + g_surface->CancelBuffer(surfaceBuf); + ret = -1; + break; + } +#else + surfaceBuf->SetSize(surface->GetSize() - size); + if (surface->FlushBuffer(surfaceBuf) != 0) { + MEDIA_ERR_LOG("Flush surface failed."); + surface->CancelBuffer(surfaceBuf); + ret = -1; + break; + } +#endif + } + if (CodecQueueOutput(hdl, buffer, 0, -1) != 0) { + MEDIA_ERR_LOG("Codec queue output failed."); + } + + return ret; +} + +CodecCallback RecordAssistant::recordCodecCb_ = {nullptr, nullptr, RecordAssistant::OnVencBufferAvailble}; + +int32_t RecordAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) +{ + fc_ = &fc; + auto surfaceList = fc.GetSurfaces(); + if (surfaceList.size() != 1) { + MEDIA_ERR_LOG("Only support one surface in frame config now."); + return MEDIA_ERR; + } + for (auto &surface : surfaceList) { + CODEC_HANDLETYPE codecHdl = nullptr; + StreamAttr stream; +#ifdef __LINUX__ + StreamAttrInitialize(&stream, g_surface, STREAM_VIDEO, FORMAT_YVU420); +#else + StreamAttrInitialize(&stream, surface, STREAM_VIDEO, FORMAT_YVU420); +#endif + HalCameraStreamCreate(cameraId_, &stream, streamId); + streamId_ = *streamId; + + StreamInfo streamInfo; + streamInfo.type = STERAM_INFO_PRIVATE; + fc.GetVendorParameter(streamInfo.u.data, PRIVATE_TAG_LEN); + HalCameraStreamSetInfo(cameraId_, *streamId, &streamInfo); + MEDIA_INFO_LOG("dataBuff is %d-%d-%d-%d", streamInfo.u.data[0], streamInfo.u.data[1], + streamInfo.u.data[30], streamInfo.u.data[31]); + + uint32_t deviceId; + HalCameraGetDeviceId(cameraId_, *streamId, &deviceId); + int32_t ret = CameraCreateVideoEnc(fc, stream, deviceId, &codecHdl); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("Cannot create suitble video encoder."); + return MEDIA_ERR; + } + ret = CodecSetCallback(codecHdl, &recordCodecCb_, reinterpret_cast(this)); + if (ret != 0) { + MEDIA_ERR_LOG("Set codec callback failed.(ret=%d)", ret); + CodecDestroy(codecHdl); + return MEDIA_ERR; + } + vencHdls_.emplace_back(codecHdl); +#ifdef __LINUX__ + list conList({g_surface}); +#else + list conList({surface}); +#endif + vencSurfaces_.emplace_back(conList); + } + state_ = LOOP_READY; + return MEDIA_OK; +} + +int32_t RecordAssistant::Start(uint32_t streamId) +{ + if (state_ != LOOP_READY) { + return MEDIA_ERR; + } + HalCameraStreamOn(cameraId_, streamId); + int32_t ret = MEDIA_OK; + int32_t i; + for (i = 0; static_cast(i) < vencHdls_.size(); i++) { + ret = CodecStart(vencHdls_[i]); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("Video encoder start failed."); + ret = MEDIA_ERR; + break; + } + } + if (ret == MEDIA_ERR) { + /* rollback */ + for (; i >= 0; i--) { + CodecStop(vencHdls_[i]); + } + return MEDIA_ERR; + } + state_ = LOOP_LOOPING; + MEDIA_INFO_LOG("Start camera recording succeed."); + return MEDIA_OK; +} + +int32_t RecordAssistant::Stop() +{ + if (state_ != LOOP_LOOPING) { + return MEDIA_ERR; + } + for (uint32_t i = 0; i < vencHdls_.size(); i++) { + CodecStop(vencHdls_[i]); + CodecDestroy(vencHdls_[i]); + } + vencHdls_.clear(); + vencSurfaces_.clear(); + HalCameraStreamOff(cameraId_, streamId_); + HalCameraStreamDestroy(cameraId_, streamId_); + state_ = LOOP_STOP; + return MEDIA_OK; +} + +static void GetSurfaceRect(Surface *surface, IRect *attr) +{ + attr->x = std::stoi(surface->GetUserData(string("region_position_x"))); + attr->y = std::stoi(surface->GetUserData(string("region_position_y"))); + attr->w = std::stoi(surface->GetUserData(string("region_width"))); + attr->h = std::stoi(surface->GetUserData(string("region_height"))); +} + +void* PreviewAssistant::YuvCopyProcess(void *arg) +{ + return nullptr; +} + +int32_t PreviewAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) +{ + fc_ = &fc; + auto surfaceList = fc.GetSurfaces(); + if (surfaceList.size() != 1) { + MEDIA_ERR_LOG("Only support one surface in frame config now."); + return MEDIA_ERR; + } + Surface *surface = surfaceList.front(); + StreamAttr stream; + StreamAttrInitialize(&stream, surface, STREAM_PREVIEW, FORMAT_YVU420); + HalCameraStreamCreate(cameraId_, &stream, streamId); + StreamInfo streamInfo; + streamInfo.type = STREAM_INFO_POS; + streamInfo.u.pos.x = std::stoi(surface->GetUserData(string("region_position_x"))); + streamInfo.u.pos.y = std::stoi(surface->GetUserData(string("region_position_y"))); + + HalCameraStreamSetInfo(cameraId_, *streamId, &streamInfo); + streamId_ = *streamId; + return MEDIA_OK; +} + +int32_t PreviewAssistant::Start(uint32_t streamId) +{ + if (state_ == LOOP_LOOPING) { + return MEDIA_ERR; + } + state_ = LOOP_LOOPING; + + int32_t retCode = pthread_create(&threadId, nullptr, YuvCopyProcess, this); + if (retCode != 0) { + MEDIA_ERR_LOG("fork thread YuvCopyProcess failed: %d.", retCode); + } + + HalCameraStreamOn(cameraId_, streamId); + return MEDIA_OK; +} + +int32_t PreviewAssistant::Stop() +{ + if (state_ != LOOP_LOOPING) { + return MEDIA_ERR; + } + state_ = LOOP_STOP; + pthread_join(threadId, NULL); + HalCameraStreamOff(cameraId_, streamId_); + HalCameraStreamDestroy(cameraId_, streamId_); + return MEDIA_OK; +} + +int32_t CaptureAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) +{ + auto surfaceList = fc.GetSurfaces(); + if (surfaceList.size() != 1) { + MEDIA_ERR_LOG("Only support one surface in frame config now."); + return MEDIA_ERR; + } + if (surfaceList.empty()) { + MEDIA_ERR_LOG("Frame config with empty surface list."); + return MEDIA_ERR; + } + if (surfaceList.size() > 1) { + MEDIA_WARNING_LOG("Capture only fullfill the first surface in frame config."); + } + Surface *surface = surfaceList.front(); + + StreamAttr stream; + StreamAttrInitialize(&stream, surface, STREAM_PREVIEW, FORMAT_YVU420); + + uint32_t deviceId; + HalCameraStreamCreate(cameraId_, &stream, streamId); + streamId_ = *streamId; + HalCameraGetDeviceId(cameraId_, *streamId, &deviceId); + int32_t ret = CameraCreateJpegEnc(fc, deviceId, &vencHdl_); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("Create capture venc failed."); + return MEDIA_ERR; + } + + capSurface_ = surface; + state_ = LOOP_READY; + return MEDIA_OK; +} + +/* Block method, waiting for capture completed */ +int32_t CaptureAssistant::Start(uint32_t streamId) +{ + state_ = LOOP_LOOPING; + HalCameraStreamOn(cameraId_, streamId); + int32_t ret = CodecStart(vencHdl_); + if (ret != 0) { + MEDIA_ERR_LOG("Start capture encoder failed.(ret=%d)", ret); + state_ = LOOP_STOP; + return MEDIA_ERR; + } + do { + SurfaceBuffer *surfaceBuf = capSurface_->RequestBuffer(); + if (surfaceBuf == nullptr) { + MEDIA_ERR_LOG("No available buffer in surface."); + break; + } + + OutputInfo outInfo; + ret = CodecDequeueOutput(vencHdl_, 0, nullptr, &outInfo); + if (ret != 0) { + capSurface_->CancelBuffer(surfaceBuf); + MEDIA_ERR_LOG("Dequeue capture frame failed.(ret=%d)", ret); + ret = MEDIA_ERR; + break; + } + + uint32_t size = capSurface_->GetSize(); + void *buf = surfaceBuf->GetVirAddr(); + if (buf == nullptr) { + MEDIA_ERR_LOG("Invalid buffer address."); + ret = MEDIA_ERR; + break; + } + ret = CopyCodecOutput(buf, &size, &outInfo); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("No available buffer in capSurface_."); + capSurface_->CancelBuffer(surfaceBuf); + ret = MEDIA_ERR; + break; + } + surfaceBuf->SetSize(capSurface_->GetSize() - size); + + if (capSurface_->FlushBuffer(surfaceBuf) != 0) { + MEDIA_ERR_LOG("Flush surface buffer failed."); + capSurface_->CancelBuffer(surfaceBuf); + ret = MEDIA_ERR; + break; + } + + ret = MEDIA_OK; + CodecQueueOutput(vencHdl_, &outInfo, 0, -1); // 0:no timeout -1:no fd + } while (0); + + CodecStop(vencHdl_); + CodecDestroy(vencHdl_); + state_ = LOOP_STOP; + + return ret; +} + +int32_t CaptureAssistant::Stop() +{ + MEDIA_DEBUG_LOG("No support method."); + return MEDIA_OK; +} + +int32_t CallbackAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) +{ + fc_ = &fc; + auto surfaceList = fc.GetSurfaces(); + if (surfaceList.size() != 1) { + MEDIA_ERR_LOG("Only support one surface in frame config now."); + return MEDIA_ERR; + } + uint32_t imageFormat = 0; + fc.GetParameter(CAM_IMAGE_FORMAT, imageFormat); + ImageFormat halImageFormat = Convert2HalImageFormat(imageFormat); + MEDIA_INFO_LOG("Imageformat is %d", imageFormat); + Surface *surface = surfaceList.front(); + StreamAttr stream; + StreamAttrInitialize(&stream, surface, STREAM_CALLBACK, halImageFormat); + HalCameraStreamCreate(cameraId_, &stream, streamId); + streamId_ = *streamId; + capSurface_ = surface; + state_ = LOOP_READY; + return MEDIA_OK; +} + +int32_t CallbackAssistant::Start(uint32_t streamId) +{ + if (state_ == LOOP_LOOPING) { + return MEDIA_ERR; + } + state_ = LOOP_LOOPING; + int32_t retCode = pthread_create(&threadId, nullptr, StreamCopyProcess, this); + if (retCode != 0) { + MEDIA_ERR_LOG("fork thread StreamCopyProcess failed: %d.", retCode); + } + HalCameraStreamOn(cameraId_, streamId); + return MEDIA_OK; +} + +void* CallbackAssistant::StreamCopyProcess(void *arg) +{ + CallbackAssistant *assistant = (CallbackAssistant *)arg; + if (assistant == nullptr) { + MEDIA_ERR_LOG("CallbackAssistant create failed."); + return nullptr; + } + if (assistant->capSurface_ == nullptr) { + MEDIA_ERR_LOG("capSurface_ is null.\n"); + return nullptr; + } + while (assistant->state_ == LOOP_LOOPING) { + SurfaceBuffer *surfaceBuf = assistant->capSurface_->RequestBuffer(); + if (surfaceBuf == nullptr) { + usleep(DELAY_TIME_ONE_FRAME); + continue; + } + HalBuffer streamBuffer; + int32_t ret = HalCameraDequeueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); + if (ret != MEDIA_OK) { + usleep(DELAY_TIME_ONE_FRAME); + continue; + } + void *buf = surfaceBuf->GetVirAddr(); + if (buf == nullptr) { + MEDIA_ERR_LOG("Invalid buffer address."); + break; + } + uint32_t size = (uint32_t)streamBuffer.size; + ret = memcpy_s(buf, assistant->capSurface_->GetSize(), streamBuffer.virAddr, size); + if (ret != MEDIA_OK) { + return nullptr; + } + + surfaceBuf->SetInt32(IMAGE_WIDTH, streamBuffer.width); + surfaceBuf->SetInt32(IMAGE_HEIGHT, streamBuffer.height); + surfaceBuf->SetInt32(IMAGE_SIZE, streamBuffer.size); + + if (assistant->capSurface_->FlushBuffer(surfaceBuf) != 0) { + MEDIA_ERR_LOG("Flush surface failed."); + assistant->capSurface_->CancelBuffer(surfaceBuf); + break; + } + ret = HalCameraQueueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); + if (ret != MEDIA_OK) { + break; + } + usleep(DELAY_TIME_ONE_FRAME); + } + + return nullptr; +} + +int32_t CallbackAssistant::Stop() +{ + MEDIA_DEBUG_LOG("CallbackAssistant£ºNo support method."); + state_ = LOOP_STOP; + pthread_join(threadId, NULL); + HalCameraStreamOff(cameraId_, streamId_); + HalCameraStreamDestroy(cameraId_, streamId_); + return MEDIA_OK; +} + +CameraDevice::CameraDevice() {} +CameraDevice::CameraDevice(uint32_t cameraId) +{ + this->cameraId = cameraId; +} + +CameraDevice::~CameraDevice() {} + +int32_t CameraDevice::Initialize() +{ + /* Need to be Refactored when delete config file */ + int32_t ret; + ret = CodecInit(); + if (ret != 0) { + MEDIA_ERR_LOG("Codec module init failed.(ret=%d)", ret); + return MEDIA_ERR; + } + MEDIA_INFO_LOG("Codec module init succeed."); + captureAssistant_.state_ = LOOP_READY; + previewAssistant_.state_ = LOOP_READY; + recordAssistant_.state_ = LOOP_READY; + callbackAssistant_.state_ = LOOP_READY; + captureAssistant_.cameraId_ = cameraId; + previewAssistant_.cameraId_ = cameraId; + recordAssistant_.cameraId_ = cameraId; + callbackAssistant_.cameraId_ = cameraId; + return MEDIA_OK; +} + +int32_t CameraDevice::UnInitialize() +{ + return MEDIA_OK; +} + +int32_t CameraDevice::TriggerLoopingCapture(FrameConfig &fc, uint32_t *streamId) +{ + MEDIA_DEBUG_LOG("Camera device start looping capture."); + DeviceAssistant *assistant = nullptr; + int32_t fcType = fc.GetFrameConfigType(); + switch (fcType) { + case FRAME_CONFIG_RECORD: + assistant = &recordAssistant_; + break; + case FRAME_CONFIG_PREVIEW: + assistant = &previewAssistant_; + break; + case FRAME_CONFIG_CAPTURE: + assistant = &captureAssistant_; + break; + case FRAME_CONFIG_CALLBACK: + assistant = &callbackAssistant_; + break; + default: + break; + } + if (assistant == nullptr) { + MEDIA_ERR_LOG("Invalid frame config type.(type=%d)", fcType); + return MEDIA_ERR; + } + if (assistant->state_ == LOOP_IDLE || assistant->state_ == LOOP_LOOPING || assistant->state_ == LOOP_ERROR) { + MEDIA_ERR_LOG("Device state is %d, cannot start looping capture.", assistant->state_); + return MEDIA_ERR; + } + + int32_t ret = assistant->SetFrameConfig(fc, streamId); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("Check and set frame config failed.(ret=%d)", ret); + return MEDIA_ERR; + } + + ret = assistant->Start(*streamId); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("Start looping capture failed.(ret=%d)", ret); + return MEDIA_ERR; + } + return MEDIA_OK; +} + +void CameraDevice::StopLoopingCapture() +{ + MEDIA_INFO_LOG("Stop looping capture in camera_device.cpp"); + previewAssistant_.Stop(); + recordAssistant_.Stop(); +} + +int32_t CameraDevice::TriggerSingleCapture(FrameConfig &fc, uint32_t *streamId) +{ + return TriggerLoopingCapture(fc, streamId); +} + +int32_t CameraDevice::SetCameraConfig() +{ + return MEDIA_OK; +} +} // namespace Media +} // namespace OHOS diff --git a/services/src/camera_server.cpp b/services/src/camera_server.cpp new file mode 100755 index 0000000..6df4b32 --- /dev/null +++ b/services/src/camera_server.cpp @@ -0,0 +1,338 @@ +/* + * Copyright(c) 2020 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 "camera_server.h" +#include +#include +#include +#include "camera_device.h" +#include "camera_service.h" +#include "camera_type.h" +#include "media_log.h" +#include "meta_data.h" +#include "surface.h" +#include "surface_impl.h" + +using namespace std; +namespace OHOS { +namespace Media { +CameraServer *CameraServer::GetInstance() +{ + static CameraServer server; + return &server; +} + +void CameraServer::CameraServerRequestHandle(int funcId, void *origin, IpcIo *req, IpcIo *reply) +{ + switch (funcId) { + case CAMERA_SERVER_GET_CAMERA_ABILITY: + CameraServer::GetInstance()->GetCameraAbility(req, reply); + break; + case CAMERA_SERVER_GET_CAMERA_INFO: + CameraServer::GetInstance()->GetCameraInfo(req, reply); + break; + case CAMERA_SERVER_GET_CAMERAIDLIST: + CameraServer::GetInstance()->GetCameraIdList(req, reply); + break; + case CAMERA_SERVER_CREATE_CAMERA: + CameraServer::GetInstance()->CreateCamera(req, reply); + break; + case CAMERA_SERVER_CLOSE_CAMERA: + CameraServer::GetInstance()->CloseCamera(req, reply); + break; + case CAEMRA_SERVER_SET_CAMERA_CONFIG: + CameraServer::GetInstance()->SetCameraConfig(req, reply); + break; + case CAEMRA_SERVER_SET_FRAME_CONFIG: + CameraServer::GetInstance()->SetFrameConfig(req, reply); + break; + case CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE: + CameraServer::GetInstance()->TriggerLoopingCapture(req, reply); + break; + case CAMERA_SERVER_STOP_LOOPING_CAPTURE: + CameraServer::GetInstance()->StopLoopingCapture(req, reply); + break; + case CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE: + CameraServer::GetInstance()->TriggerSingleCapture(req, reply); + break; + case CAMERA_SERVER_SET_CAMERA_CALLBACK: + CameraServer::GetInstance()->SetCameraCallback(req, reply); + break; + default: + MEDIA_ERR_LOG("code not support:%d!", funcId); + break; + } +} +void CameraServer::InitCameraServer() +{ + CameraService *service = CameraService::GetInstance(); + service->Initialize(); +} + +void CameraServer::GetCameraAbility(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + CameraAbility *ability = CameraService::GetInstance()->GetCameraAbility(cameraId); + if (ability == nullptr) { + return; + } + list supportSizeList = ability->GetSupportedSizes(PARAM_KEY_SIZE); + uint32_t supportProperties = 0; + IpcIoPushUint32(reply, supportProperties); + uint32_t listSize = supportSizeList.size(); + IpcIoPushUint32(reply, listSize); + for (auto supportSizeItem : supportSizeList) { + IpcIoPushFlatObj(reply, &supportSizeItem, sizeof(CameraPicSize)); + } + // af + list afModeList = ability->GetSupportedAfModes(); + uint32_t afListSize = afModeList.size(); + IpcIoPushUint32(reply, afListSize); + for (auto supportAfMode : afModeList) { + IpcIoPushInt32(reply, supportAfMode); + } + // ae + list aeModeList = ability->GetSupportedAeModes(); + uint32_t aeListSize = aeModeList.size(); + IpcIoPushUint32(reply, aeListSize); + for (auto supportAeMode : aeModeList) { + IpcIoPushInt32(reply, supportAeMode); + } +} + +void CameraServer::GetCameraInfo(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + CameraInfo *info = CameraService::GetInstance()->GetCameraInfo(cameraId); + if (info == nullptr) { + return; + } + IpcIoPushInt32(reply, info->GetCameraType()); + IpcIoPushInt32(reply, info->GetCameraFacingType()); +} + +void CameraServer::GetCameraIdList(IpcIo *req, IpcIo *reply) +{ + list cameraIdList = CameraService::GetInstance()->GetCameraIdList(); + IpcIoPushUint32(reply, cameraIdList.size()); + for (string cameraId : cameraIdList) { + IpcIoPushString(reply, cameraId.c_str()); + } +} + +void CameraServer::CreateCamera(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + int32_t cameraStatus = CameraService::GetInstance()->CreateCamera(cameraId); + SvcIdentity *sid = IpcIoPopSvc(req); +#ifdef __LINUX__ + BinderAcquire(sid->ipcContext, sid->handle); +#endif + if (sid == nullptr) { + MEDIA_ERR_LOG("sid is null, failed."); + return; + } + OnCameraStatusChange(cameraStatus, sid); +} + +void CameraServer::CloseCamera(IpcIo *req, IpcIo *reply) +{ + MEDIA_INFO_LOG("CloseCamera enter."); + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + int32_t cameraStatus = CameraService::GetInstance()->CloseCamera(cameraId); + SvcIdentity *sid = IpcIoPopSvc(req); +#ifdef __LINUX__ + BinderAcquire(sid->ipcContext, sid->handle); +#endif + if (sid == nullptr) { + MEDIA_ERR_LOG("sid is null, failed."); + return; + } + OnCameraStatusChange(cameraStatus, sid); +} + +void CameraServer::SetCameraConfig(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId); + int32_t setStatus = device_->SetCameraConfig(); + IpcIoPushInt32(reply, setStatus); + OnCameraConfigured(setStatus); +} + +void CameraServer::SetCameraCallback(IpcIo *req, IpcIo *reply) +{ + sid_ = *IpcIoPopSvc(req); +#ifdef __LINUX__ + BinderAcquire(sid_.ipcContext, sid_.handle); +#endif +} + +FrameConfig *DeserializeFrameConfig(IpcIo &io) +{ + int32_t type = IpcIoPopInt32(&io); + auto fc = new FrameConfig(type); + + uint32_t surfaceNum = IpcIoPopUint32(&io); + for (uint32_t i = 0; i < surfaceNum; i++) { + Surface *surface = SurfaceImpl::GenericSurfaceByIpcIo(io); + if (surface == nullptr) { + MEDIA_ERR_LOG("Camera server receive null surface."); + delete fc; + return nullptr; + } + fc->AddSurface(*surface); + } + + int32_t qfactor = IpcIoPopInt32(&io); + if (qfactor >= 0) { + fc->SetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor); + } + int32_t frameRate = IpcIoPopInt32(&io); + fc->SetParameter(PARAM_KEY_STREAM_FPS, frameRate); + MEDIA_INFO_LOG("frameRate is %d", frameRate); + int32_t streamFormat = IpcIoPopInt32(&io); + fc->SetParameter(CAM_IMAGE_FORMAT, streamFormat); + MEDIA_INFO_LOG("streamFormat is %d", streamFormat); + BuffPtr *dataBuff = IpcIoPopDataBuff(&io); + if (dataBuff == nullptr || dataBuff->buff == nullptr) { + MEDIA_ERR_LOG("dataBuff is nullptr."); + return fc; + } + uint8_t *data = (uint8_t *)dataBuff->buff; + fc->SetVendorParameter((uint8_t *)dataBuff->buff, dataBuff->buffSz); + MEDIA_INFO_LOG("dataBuff is %d-%d-%d-%d", data[0], data[1], data[30], data[31]); + return fc; +} + +void CameraServer::SetFrameConfig(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + int32_t streamId = IpcIoPopInt32(req); + MEDIA_ERR_LOG("SetFrameConfig streamId(%d).", streamId); + CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId); + FrameConfig *fc = DeserializeFrameConfig(*req); + if (fc == nullptr) { + MEDIA_ERR_LOG("Deserialize frame config failed."); + return; + } + delete fc; +} + + +void CameraServer::TriggerLoopingCapture(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId); + FrameConfig *fc = DeserializeFrameConfig(*req); + if (fc == nullptr) { + MEDIA_ERR_LOG("Deserialize frame config failed."); + return; + } + uint32_t streamId = 0; + int32_t loopingCaptureStatus = device_->TriggerLoopingCapture(*fc, &streamId); + OnTriggerLoopingCaptureFinished(loopingCaptureStatus, streamId); + delete fc; +} + +void CameraServer::TriggerSingleCapture(IpcIo *req, IpcIo *reply) +{ + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId); + FrameConfig *fc = DeserializeFrameConfig(*req); + if (fc == nullptr) { + MEDIA_ERR_LOG("Deserialize frame config failed."); + return; + } + uint32_t streamId = 0; + int32_t singleCaptureStatus = device_->TriggerSingleCapture(*fc, &streamId); + OnTriggerSingleCaptureFinished(singleCaptureStatus); + delete fc; +} + +void CameraServer::StopLoopingCapture(IpcIo *req, IpcIo *reply) +{ + MEDIA_INFO_LOG("StopLoopingCapture in camera_server.cpp!"); + size_t sz; + string cameraId((const char*)(IpcIoPopString(req, &sz))); + CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId); + if (device_ == nullptr) { + MEDIA_INFO_LOG("device_ is null in camera_server.cpp!"); + } + device_->StopLoopingCapture(); +} + +void CameraServer::OnCameraStatusChange(int32_t ret, SvcIdentity *sid) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushInt32(&io, ret); + int32_t ans = Transact(nullptr, *sid, ON_CAMERA_STATUS_CHANGE, &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr); + if (ans != LITEIPC_OK) { + MEDIA_ERR_LOG("Create camera callback : on camera status change failed."); + } +} + +void CameraServer::OnTriggerSingleCaptureFinished(int32_t ret) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushInt32(&io, ret); + int32_t ans = Transact(nullptr, sid_, ON_TRIGGER_SINGLE_CAPTURE_FINISHED, + &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr); + if (ans != LITEIPC_OK) { + MEDIA_ERR_LOG("Trigger single capture callback : on trigger single capture frame finished failed."); + return; + } +} + +void CameraServer::OnTriggerLoopingCaptureFinished(int32_t ret, int32_t streamId) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushInt32(&io, ret); + int32_t ans = Transact(nullptr, sid_, ON_TRIGGER_LOOPING_CAPTURE_FINISHED, + &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr); + if (ans != LITEIPC_OK) { + MEDIA_ERR_LOG("Trigger looping capture callback : on trigger looping capture finished failed."); + } +} + +void CameraServer::OnCameraConfigured(int32_t ret) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushInt32(&io, ret); + int32_t ans = Transact(nullptr, sid_, ON_CAMERA_CONFIGURED, + &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr); + if (ans != LITEIPC_OK) { + MEDIA_ERR_LOG("Camera config callback : on trigger looping capture finished failed."); + } +} +} // namespace Media +} // namespace OHOS + diff --git a/services/src/camera_service.cpp b/services/src/camera_service.cpp new file mode 100755 index 0000000..cd804bb --- /dev/null +++ b/services/src/camera_service.cpp @@ -0,0 +1,167 @@ +/* + * Copyright(c) 2020 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 "camera_service.h" +#include +#include +#include +#include "hal_camera.h" +#include "media_log.h" + +using namespace std; +namespace OHOS { +namespace Media { +CameraService::CameraService() {} + +CameraService::~CameraService() +{ + int32_t ret = HalCameraDeinit(); // Smart lock add + if (ret != 0) { + MEDIA_ERR_LOG("HiCameraDeInit return failed ret(%d).", ret); + } +} + +CameraService *CameraService::GetInstance() +{ + static CameraService instance; + return &instance; +} + +void CameraService::Initialize() +{ + int32_t ret = HalCameraInit(); // Smart lock add + if (ret != 0) { + MEDIA_ERR_LOG("HiCameraInit failed. ret(%d)", ret); + } +} + +CameraAbility *CameraService::GetCameraAbility(std::string &cameraId) +{ + std::map::iterator iter = deviceAbilityMap_.find(cameraId); + if (iter != deviceAbilityMap_.end()) { + return iter->second; + } + CameraAbility *ability = new (nothrow) CameraAbility; + if (ability == nullptr) { + return nullptr; + } + uint32_t streamCapNum; + StreamCap *streamCap = nullptr; + int32_t ret = HalCameraGetStreamCapNum(atoi(cameraId.c_str()), &streamCapNum); + streamCap = new StreamCap[streamCapNum]; + for (int pos = 0; pos < streamCapNum; pos++) { + streamCap[pos].type = CAP_DESC_ENUM; + } + ret = HalCameraGetStreamCap(atoi(cameraId.c_str()), streamCap, streamCapNum); + list range; + for (int pos = 0; pos < streamCapNum; pos++) { + CameraPicSize tmpSize = {.width = (uint32_t)streamCap[pos].u.formatEnum.width, .height = (uint32_t)streamCap[pos].u.formatEnum.height}; + range.emplace_back(tmpSize); + } + ability->SetParameterRange(PARAM_KEY_SIZE, range); + + AbilityInfo cameraAbility; + HalCameraGetAbility(atoi(cameraId.c_str()), &cameraAbility); + // Get supported AF Modes + list afModes; + for (int i = 0; i < cameraAbility.afModeNum; i++) { + afModes.emplace_back(cameraAbility.afModes[i]); + } + ability->SetParameterRange(CAM_AF_MODE, afModes); + + // Get supported AE Modes + list aeModes; + for (int i = 0; i < cameraAbility.aeModeNum; i++) { + aeModes.emplace_back(cameraAbility.aeModes[i]); + } + ability->SetParameterRange(CAM_AE_MODE, aeModes); + + delete[] streamCap; + deviceAbilityMap_.insert(pair(cameraId, ability)); + return ability; +} + +CameraInfo *CameraService::GetCameraInfo(std::string &cameraId) +{ + std::map::iterator iter = deviceInfoMap_.find(cameraId); + if (iter != deviceInfoMap_.end()) { + return iter->second; + } + AbilityInfo deviceAbility; + int32_t ret = HalCameraGetAbility((uint32_t)std::atoi(cameraId.c_str()), &deviceAbility); + if (ret != MEDIA_OK) { + MEDIA_ERR_LOG("HalCameraGetAbility failed. ret(%d)", ret); + return nullptr; + } + CameraInfo *info = new (nothrow) CameraInfoImpl(deviceAbility.type, deviceAbility.orientation); + if (info == nullptr) { + return nullptr; + } + deviceInfoMap_.insert(pair(cameraId, info)); + return info; +} + +CameraDevice *CameraService::GetCameraDevice(std::string &cameraId) +{ + std::map::iterator iter = deviceMap_.find(cameraId); + if (iter != deviceMap_.end()) { + return iter->second; + } + return nullptr; +} + +list CameraService::GetCameraIdList() +{ + uint8_t camNum = 0; + HalCameraGetDeviceNum(&camNum); + uint32_t *cameraList = new uint32_t[camNum]; + HalCameraGetDeviceList(cameraList, camNum); + list cameraStrList; + for (uint32_t pos = 0; pos < camNum; pos++) { + cameraStrList.push_back(to_string(cameraList[pos])); + } + return cameraStrList; +} + +int32_t CameraService::CreateCamera(string cameraId) +{ + int32_t ret = HalCameraDeviceOpen((uint32_t)std::atoi(cameraId.c_str())); // Smart lock add + if (ret != 0) { + MEDIA_ERR_LOG("HalCameraDeviceOpen failed. ret(%d)", ret); + return CameraServiceCallback::CAMERA_STATUS_CREATE_FAILED; + } + CameraDevice *device = new (nothrow) CameraDevice((uint32_t)std::atoi(cameraId.c_str())); + if (device == nullptr) { + MEDIA_FATAL_LOG("New device object failed."); + return MEDIA_ERR; + } + if (device->Initialize() != MEDIA_OK) { + MEDIA_FATAL_LOG("device Initialize failed."); + return MEDIA_ERR; + } + deviceMap_.insert(pair(cameraId, device)); + return CameraServiceCallback::CAMERA_STATUS_CREATED; +} + +int32_t CameraService::CloseCamera(string cameraId) +{ + int32_t ret = HalCameraDeviceClose((uint32_t)std::atoi(cameraId.c_str())); + if (ret != 0) { + MEDIA_ERR_LOG("HalCameraDeviceClose failed. ret(%d)", ret); + } + return CameraServiceCallback::CAMERA_STATUS_CLOSE; +} + +} // namespace Media +} // namespace OHOS diff --git a/services/src/samgr_camera.cpp b/services/src/samgr_camera.cpp new file mode 100755 index 0000000..da2ae59 --- /dev/null +++ b/services/src/samgr_camera.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 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 +#include +#include + +#include "feature.h" +#include "media_log.h" +#include "iproxy_client.h" +#include "iproxy_server.h" +#include "iunknown.h" +#include "samgr_lite.h" +#include "service.h" + +#include "camera_type.h" +#include "camera_server.h" + +namespace OHOS { +struct DefaultFeatureApi { + INHERIT_SERVER_IPROXY; +}; + +struct CameraService { + INHERIT_SERVICE; + INHERIT_IUNKNOWNENTRY(DefaultFeatureApi); + Identity identity; +}; + +static const char* GetName(Service* service) +{ + (void)service; + return Media::SERVICE_NAME; +} + +static BOOL Initialize(Service* service, Identity identity) +{ + CameraService* example = (CameraService*)service; + example->identity = identity; + MEDIA_INFO_LOG("Initialize(%s)! Identity<%d, %d, %p>", Media::SERVICE_NAME, + identity.serviceId, identity.featureId, identity.queueId); + return TRUE; +} + +static BOOL MessageHandle(Service* service, Request* msg) +{ + MEDIA_INFO_LOG("MessageHandle(%s)! Request<%d, %d, %p>", + service->GetName(service), msg->msgId, msg->msgValue, msg->data); + return FALSE; +} + +static TaskConfig GetTaskConfig(Service* service) +{ + (void)service; + TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 0x800, 20, SHARED_TASK}; + return config; +} + +static int32 Invoke(IServerProxy* iProxy, int funcId, void* origin, IpcIo* req, IpcIo* reply) +{ + Media::CameraServer::CameraServerRequestHandle(funcId, origin, req, reply); + return EC_SUCCESS; +} + +static CameraService g_example = { + .GetName = GetName, + .Initialize = Initialize, + .MessageHandle = MessageHandle, + .GetTaskConfig = GetTaskConfig, + SERVER_IPROXY_IMPL_BEGIN, + .Invoke = Invoke, + IPROXY_END, +}; + +static void Init(void) +{ + SAMGR_GetInstance()->RegisterService((Service*)&g_example); + SAMGR_GetInstance()->RegisterDefaultFeatureApi(Media::SERVICE_NAME, GET_IUNKNOWN(g_example)); +} + +SYSEX_SERVICE_INIT(Init); +} // namespace OHOS \ No newline at end of file