1/*
2 * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "camera_service.h"
16#include "hal_camera.h"
17#include "media_log.h"
18#include "codec_interface.h"
19
20using namespace std;
21namespace OHOS {
22namespace Media {
23CameraService::CameraService() {}
24
25CameraService::~CameraService()
26{
27    auto iter = deviceMap_.begin();
28    while (iter != deviceMap_.end()) {
29        if (iter->second != nullptr) {
30            iter->second->StopLoopingCapture(-1);
31            int32_t ret = HalCameraDeviceClose((uint32_t)std::atoi(iter->first.c_str()));
32            if (ret != 0) {
33                MEDIA_ERR_LOG("HalCameraDeviceClose failed. ret(%d)", ret);
34            }
35            deviceMap_.erase(iter++);
36        } else {
37            ++iter;
38        }
39    }
40    int32_t ret = HalCameraDeinit();
41    if (ret != 0) {
42        MEDIA_ERR_LOG("HiCameraDeInit return failed ret(%d).", ret);
43    }
44}
45
46CameraService *CameraService::GetInstance()
47{
48    static CameraService instance;
49    return &instance;
50}
51
52void CameraService::Initialize()
53{
54    int32_t ret = HalCameraInit();
55    if (ret != 0) {
56        MEDIA_ERR_LOG("HiCameraInit failed. ret(%d)", ret);
57    }
58}
59
60CameraAbility *CameraService::GetCameraAbility(std::string &cameraId)
61{
62    std::map<string, CameraAbility*>::iterator iter = deviceAbilityMap_.find(cameraId);
63    if (iter != deviceAbilityMap_.end()) {
64        return iter->second;
65    }
66    CameraAbility *ability = new (nothrow) CameraAbility;
67    if (ability == nullptr) {
68        return nullptr;
69    }
70    uint32_t streamCapNum;
71    StreamCap *streamCap = nullptr;
72    int32_t ret = HalCameraGetStreamCapNum(atoi(cameraId.c_str()), &streamCapNum);
73    streamCap = new StreamCap[streamCapNum];
74    for (uint32_t pos = 0; pos < streamCapNum; pos++) {
75        streamCap[pos].type = CAP_DESC_ENUM;
76    }
77    ret = HalCameraGetStreamCap(atoi(cameraId.c_str()), streamCap, streamCapNum);
78    list<CameraPicSize> range;
79    for (int pos = 0; pos < streamCapNum; pos++) {
80        CameraPicSize tmpSize = {.width = (uint32_t)streamCap[pos].u.formatEnum.width,
81            .height = (uint32_t)streamCap[pos].u.formatEnum.height};
82        range.emplace_back(tmpSize);
83    }
84    ability->SetParameterRange(CAM_FORMAT_YVU420, range);
85    ability->SetParameterRange(CAM_FORMAT_JPEG, range);
86    ability->SetParameterRange(CAM_FORMAT_H264, range);
87    ability->SetParameterRange(CAM_FORMAT_H265, range);
88    AbilityInfo cameraAbility = {};
89    HalCameraGetAbility(atoi(cameraId.c_str()), &cameraAbility);
90    list<int32_t> afModes;
91    for (int i = 0; i < cameraAbility.afModeNum; i++) {
92        afModes.emplace_back(cameraAbility.afModes[i]);
93    }
94    ability->SetParameterRange(CAM_AF_MODE, afModes);
95    list<int32_t> aeModes;
96    for (int i = 0; i < cameraAbility.aeModeNum; i++) {
97        aeModes.emplace_back(cameraAbility.aeModes[i]);
98    }
99    ability->SetParameterRange(CAM_AE_MODE, aeModes);
100    delete[] streamCap;
101    deviceAbilityMap_.insert(pair<string, CameraAbility*>(cameraId, ability));
102    return ability;
103}
104
105CameraInfo *CameraService::GetCameraInfo(std::string &cameraId)
106{
107    std::map<string, CameraInfo*>::iterator iter = deviceInfoMap_.find(cameraId);
108    if (iter != deviceInfoMap_.end()) {
109        return iter->second;
110    }
111    AbilityInfo deviceAbility;
112    int32_t ret = HalCameraGetAbility((uint32_t)std::atoi(cameraId.c_str()), &deviceAbility);
113    if (ret != MEDIA_OK) {
114        MEDIA_ERR_LOG("HalCameraGetAbility failed. ret(%d)", ret);
115        return nullptr;
116    }
117    CameraInfo *info = new (nothrow) CameraInfoImpl(deviceAbility.type, deviceAbility.orientation);
118    if (info == nullptr) {
119        return nullptr;
120    }
121    deviceInfoMap_.insert(pair<string, CameraInfo*>(cameraId, info));
122    return info;
123}
124
125CameraDevice *CameraService::GetCameraDevice(std::string &cameraId)
126{
127    std::map<string, CameraDevice*>::iterator iter = deviceMap_.find(cameraId);
128    if (iter != deviceMap_.end()) {
129        return iter->second;
130    }
131    return nullptr;
132}
133
134list<string> CameraService::GetCameraIdList()
135{
136    uint8_t camNum = 0;
137    HalCameraGetDeviceNum(&camNum);
138    uint32_t *cameraList = new uint32_t[camNum];
139    HalCameraGetDeviceList(cameraList, camNum);
140    list<string> cameraStrList;
141    for (uint32_t pos = 0; pos < camNum; pos++) {
142        cameraStrList.push_back(to_string(cameraList[pos]));
143    }
144    delete[] cameraList;
145    return cameraStrList;
146}
147
148uint8_t CameraService::GetCameraModeNum()
149{
150    uint8_t num;
151    int32_t ret = HalCameraGetModeNum(&num);
152    if (ret == MEDIA_OK) {
153        return num;
154    }
155    return 0;
156}
157
158int32_t CameraService::CreateCamera(string cameraId)
159{
160    int32_t ret = HalCameraDeviceOpen((uint32_t)std::atoi(cameraId.c_str()));
161    if (ret != 0) {
162        MEDIA_ERR_LOG("HalCameraDeviceOpen failed. ret(%d)", ret);
163        return CameraServiceCallback::CAMERA_STATUS_CREATE_FAILED;
164    }
165    CameraDevice *device = new (nothrow) CameraDevice((uint32_t)std::atoi(cameraId.c_str()));
166    if (device == nullptr) {
167        MEDIA_FATAL_LOG("New device object failed.");
168        return MEDIA_ERR;
169    }
170    if (device->Initialize() != MEDIA_OK) {
171        MEDIA_FATAL_LOG("device Initialize failed.");
172        delete device;
173        return MEDIA_ERR;
174    }
175    deviceMap_.insert(pair<string, CameraDevice*>(cameraId, device));
176    return CameraServiceCallback::CAMERA_STATUS_CREATED;
177}
178
179int32_t CameraService::CloseCamera(string cameraId)
180{
181    CameraDevice *device = GetCameraDevice(cameraId);
182    if (device != NULL) {
183        device->StopLoopingCapture(-1);
184        deviceMap_.erase(cameraId);
185    }
186    int32_t ret = HalCameraDeviceClose((uint32_t)std::atoi(cameraId.c_str()));
187    if (ret != 0) {
188        MEDIA_ERR_LOG("HalCameraDeviceClose failed. ret(%d)", ret);
189    }
190    return CameraServiceCallback::CAMERA_STATUS_CLOSE;
191}
192
193int32_t CameraService::SetCameraMode(uint8_t modeIndex)
194{
195    CodecDeinit();
196    int32_t ret = HalCameraSetMode(modeIndex);
197    CodecInit();
198    return ret;
199}
200} // namespace Media
201} // namespace OHOS