1 /*
2 * Copyright (c) 2020 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
16 #include "camera_server.h"
17 #include <cstdio>
18 #include <list>
19 #include <string>
20 #include "camera_device.h"
21 #include "camera_service.h"
22 #include "camera_type.h"
23 #include "media_log.h"
24 #include "meta_data.h"
25 #include "surface.h"
26 #include "surface_impl.h"
27
28 using namespace std;
29 namespace OHOS {
30 namespace Media {
GetInstance()31 CameraServer *CameraServer::GetInstance()
32 {
33 static CameraServer server;
34 return &server;
35 }
36
CameraServerRequestHandle(int funcId,void * origin,IpcIo * req,IpcIo * reply)37 void CameraServer::CameraServerRequestHandle(int funcId, void *origin, IpcIo *req, IpcIo *reply)
38 {
39 switch (funcId) {
40 case CAMERA_SERVER_GET_CAMERA_ABILITY:
41 CameraServer::GetInstance()->GetCameraAbility(req, reply);
42 break;
43 case CAMERA_SERVER_GET_CAMERA_INFO:
44 CameraServer::GetInstance()->GetCameraInfo(req, reply);
45 break;
46 case CAMERA_SERVER_GET_CAMERAIDLIST:
47 CameraServer::GetInstance()->GetCameraIdList(req, reply);
48 break;
49 case CAMERA_SERVER_CREATE_CAMERA:
50 CameraServer::GetInstance()->CreateCamera(req, reply);
51 break;
52 case CAMERA_SERVER_CLOSE_CAMERA:
53 CameraServer::GetInstance()->CloseCamera(req, reply);
54 break;
55 case CAEMRA_SERVER_SET_CAMERA_CONFIG:
56 CameraServer::GetInstance()->SetCameraConfig(req, reply);
57 break;
58 case CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE:
59 CameraServer::GetInstance()->TriggerLoopingCapture(req, reply);
60 break;
61 case CAMERA_SERVER_STOP_LOOPING_CAPTURE:
62 CameraServer::GetInstance()->StopLoopingCapture(req, reply);
63 break;
64 case CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE:
65 CameraServer::GetInstance()->TriggerSingleCapture(req, reply);
66 break;
67 case CAMERA_SERVER_SET_CAMERA_CALLBACK:
68 CameraServer::GetInstance()->SetCameraCallback(req, reply);
69 break;
70 case CAMERA_SERVER_SET_CAMERA_MODE_NUM:
71 CameraServer::GetInstance()->SetCameraMode(req, reply);
72 break;
73 case CAMERA_SERVER_GET_CAMERA_MODE_NUM:
74 CameraServer::GetInstance()->GetCameraModeNum(req, reply);
75 break;
76 default:
77 MEDIA_ERR_LOG("code not support:%d!", funcId);
78 break;
79 }
80 }
InitCameraServer()81 void CameraServer::InitCameraServer()
82 {
83 CameraService *service = CameraService::GetInstance();
84 service->Initialize();
85 }
86
GetCameraAbility(IpcIo * req,IpcIo * reply)87 void CameraServer::GetCameraAbility(IpcIo *req, IpcIo *reply)
88 {
89 size_t sz;
90 string cameraId((const char*)(IpcIoPopString(req, &sz)));
91 CameraAbility *ability = CameraService::GetInstance()->GetCameraAbility(cameraId);
92 if (ability == nullptr) {
93 return;
94 }
95 list<CameraPicSize> supportSizeList = ability->GetSupportedSizes(CAM_FORMAT_YVU420);
96 uint32_t supportProperties = 0;
97 IpcIoPushUint32(reply, supportProperties);
98 uint32_t listSize = supportSizeList.size();
99 IpcIoPushUint32(reply, listSize);
100 for (auto supportSizeItem : supportSizeList) {
101 IpcIoPushFlatObj(reply, &supportSizeItem, sizeof(CameraPicSize));
102 }
103 // af
104 list<int32_t> afModeList = ability->GetSupportedAfModes();
105 uint32_t afListSize = afModeList.size();
106 IpcIoPushUint32(reply, afListSize);
107 for (auto supportAfMode : afModeList) {
108 IpcIoPushInt32(reply, supportAfMode);
109 }
110 // ae
111 list<int32_t> aeModeList = ability->GetSupportedAeModes();
112 uint32_t aeListSize = aeModeList.size();
113 IpcIoPushUint32(reply, aeListSize);
114 for (auto supportAeMode : aeModeList) {
115 IpcIoPushInt32(reply, supportAeMode);
116 }
117 }
118
GetCameraInfo(IpcIo * req,IpcIo * reply)119 void CameraServer::GetCameraInfo(IpcIo *req, IpcIo *reply)
120 {
121 size_t sz;
122 string cameraId((const char*)(IpcIoPopString(req, &sz)));
123 CameraInfo *info = CameraService::GetInstance()->GetCameraInfo(cameraId);
124 if (info == nullptr) {
125 return;
126 }
127 IpcIoPushInt32(reply, info->GetCameraType());
128 IpcIoPushInt32(reply, info->GetCameraFacingType());
129 }
130
GetCameraIdList(IpcIo * req,IpcIo * reply)131 void CameraServer::GetCameraIdList(IpcIo *req, IpcIo *reply)
132 {
133 list<string> cameraIdList = CameraService::GetInstance()->GetCameraIdList();
134 IpcIoPushUint32(reply, cameraIdList.size());
135 for (string cameraId : cameraIdList) {
136 IpcIoPushString(reply, cameraId.c_str());
137 }
138 }
139
GetCameraModeNum(IpcIo * req,IpcIo * reply)140 void CameraServer::GetCameraModeNum(IpcIo *req, IpcIo *reply)
141 {
142 uint8_t num = CameraService::GetInstance()->GetCameraModeNum();
143 IpcIoPushUint8(reply, num);
144 }
145
CreateCamera(IpcIo * req,IpcIo * reply)146 void CameraServer::CreateCamera(IpcIo *req, IpcIo *reply)
147 {
148 size_t sz;
149 string cameraId((const char*)(IpcIoPopString(req, &sz)));
150 int32_t cameraStatus = CameraService::GetInstance()->CreateCamera(cameraId);
151 SvcIdentity *sid = IpcIoPopSvc(req);
152 if (sid == nullptr) {
153 MEDIA_ERR_LOG("sid is null, failed.");
154 return;
155 }
156 #ifdef __LINUX__
157 BinderAcquire(sid->ipcContext, sid->handle);
158 #endif
159 OnCameraStatusChange(cameraStatus, sid);
160 }
161
CloseCamera(IpcIo * req,IpcIo * reply)162 void CameraServer::CloseCamera(IpcIo *req, IpcIo *reply)
163 {
164 size_t sz;
165 string cameraId((const char*)(IpcIoPopString(req, &sz)));
166 int32_t cameraStatus = CameraService::GetInstance()->CloseCamera(cameraId);
167 SvcIdentity *sid = IpcIoPopSvc(req);
168 if (sid == nullptr) {
169 MEDIA_ERR_LOG("sid is null, failed.");
170 return;
171 }
172 #ifdef __LINUX__
173 BinderAcquire(sid->ipcContext, sid->handle);
174 #endif
175 OnCameraStatusChange(cameraStatus, sid);
176 }
177
SetCameraConfig(IpcIo * req,IpcIo * reply)178 void CameraServer::SetCameraConfig(IpcIo *req, IpcIo *reply)
179 {
180 size_t sz;
181 string cameraId((const char*)(IpcIoPopString(req, &sz)));
182 CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
183 int32_t setStatus = device_->SetCameraConfig();
184 IpcIoPushInt32(reply, setStatus);
185 OnCameraConfigured(setStatus);
186 }
187
SetCameraCallback(IpcIo * req,IpcIo * reply)188 void CameraServer::SetCameraCallback(IpcIo *req, IpcIo *reply)
189 {
190 SvcIdentity *sid = IpcIoPopSvc(req);
191 if (sid == nullptr) {
192 MEDIA_ERR_LOG("sid is null, failed.");
193 return;
194 }
195 sid_ = *sid;
196 #ifdef __LINUX__
197 BinderAcquire(sid_.ipcContext, sid_.handle);
198 #endif
199 }
200
DeserializeFrameConfig(IpcIo & io)201 FrameConfig *DeserializeFrameConfig(IpcIo &io)
202 {
203 int32_t type = IpcIoPopInt32(&io);
204 auto fc = new FrameConfig(type);
205
206 uint32_t surfaceNum = IpcIoPopUint32(&io);
207 for (uint32_t i = 0; i < surfaceNum; i++) {
208 Surface *surface = SurfaceImpl::GenericSurfaceByIpcIo(io);
209 if (surface == nullptr) {
210 MEDIA_ERR_LOG("Camera server receive null surface.");
211 delete fc;
212 return nullptr;
213 }
214 fc->AddSurface(*surface);
215 }
216
217 int32_t qfactor = IpcIoPopInt32(&io);
218 if (qfactor >= 0) {
219 fc->SetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor);
220 }
221
222 int32_t streamFps = IpcIoPopInt32(&io);
223 fc->SetParameter(CAM_FRAME_FPS, streamFps);
224
225 int32_t invertMode = IpcIoPopInt32(&io);
226 fc->SetParameter(CAM_IMAGE_INVERT_MODE, invertMode);
227
228 CameraRect streamCrop;
229 streamCrop.x = IpcIoPopInt32(&io);
230 streamCrop.y = IpcIoPopInt32(&io);
231 streamCrop.w = IpcIoPopInt32(&io);
232 streamCrop.h = IpcIoPopInt32(&io);
233
234 int32_t streamFormat = IpcIoPopInt32(&io);
235 fc->SetParameter(CAM_IMAGE_FORMAT, streamFormat);
236 MEDIA_INFO_LOG("streamFormat is %d", streamFormat);
237
238 if (type != FRAME_CONFIG_RECORD) {
239 BuffPtr *dataBuff = IpcIoPopDataBuff(&io);
240 if (dataBuff == nullptr || dataBuff->buff == nullptr) {
241 MEDIA_ERR_LOG("dataBuff is nullptr.");
242 return fc;
243 }
244 fc->SetVendorParameter((uint8_t *)dataBuff->buff, dataBuff->buffSz);
245 FreeBuffer(nullptr, dataBuff->buff);
246 }
247 return fc;
248 }
249
SetFrameConfig(IpcIo * req,IpcIo * reply)250 void CameraServer::SetFrameConfig(IpcIo *req, IpcIo *reply)
251 {
252 size_t sz;
253 string cameraId((const char *)(IpcIoPopString(req, &sz)));
254 int32_t streamId = IpcIoPopInt32(req);
255 MEDIA_ERR_LOG("SetFrameConfig streamId(%d).", streamId);
256 FrameConfig *fc = DeserializeFrameConfig(*req);
257 if (fc == nullptr) {
258 MEDIA_ERR_LOG("Deserialize frame config failed.");
259 return;
260 }
261 delete fc;
262 }
263
264
TriggerLoopingCapture(IpcIo * req,IpcIo * reply)265 void CameraServer::TriggerLoopingCapture(IpcIo *req, IpcIo *reply)
266 {
267 size_t sz;
268 string cameraId((const char*)(IpcIoPopString(req, &sz)));
269 CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
270 FrameConfig *fc = DeserializeFrameConfig(*req);
271 if (fc == nullptr) {
272 MEDIA_ERR_LOG("Deserialize frame config failed.");
273 return;
274 }
275 uint32_t streamId = 0;
276 int32_t loopingCaptureStatus = device_->TriggerLoopingCapture(*fc, &streamId);
277 OnTriggerLoopingCaptureFinished(loopingCaptureStatus, streamId);
278 delete fc;
279 }
280
TriggerSingleCapture(IpcIo * req,IpcIo * reply)281 void CameraServer::TriggerSingleCapture(IpcIo *req, IpcIo *reply)
282 {
283 size_t sz;
284 string cameraId((const char *)(IpcIoPopString(req, &sz)));
285 CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
286 FrameConfig *fc = DeserializeFrameConfig(*req);
287 if (fc == nullptr) {
288 MEDIA_ERR_LOG("Deserialize frame config failed.");
289 return;
290 }
291 uint32_t streamId = 0;
292 int32_t singleCaptureStatus = device_->TriggerSingleCapture(*fc, &streamId);
293 OnTriggerSingleCaptureFinished(singleCaptureStatus);
294 delete fc;
295 }
296
StopLoopingCapture(IpcIo * req,IpcIo * reply)297 void CameraServer::StopLoopingCapture(IpcIo *req, IpcIo *reply)
298 {
299 size_t sz;
300 string cameraId((const char *)(IpcIoPopString(req, &sz)));
301 CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
302 if (device_ == nullptr) {
303 MEDIA_INFO_LOG("device_ is null in camera_server.cpp!");
304 return;
305 }
306 device_->StopLoopingCapture();
307 }
308
OnCameraStatusChange(int32_t ret,SvcIdentity * sid)309 void CameraServer::OnCameraStatusChange(int32_t ret, SvcIdentity *sid)
310 {
311 IpcIo io;
312 uint8_t tmpData[DEFAULT_IPC_SIZE];
313 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
314 IpcIoPushInt32(&io, ret);
315 int32_t ans = Transact(nullptr, *sid, ON_CAMERA_STATUS_CHANGE, &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr);
316 if (ans != LITEIPC_OK) {
317 MEDIA_ERR_LOG("Create camera callback : on camera status change failed.");
318 }
319 }
320
OnTriggerSingleCaptureFinished(int32_t ret)321 void CameraServer::OnTriggerSingleCaptureFinished(int32_t ret)
322 {
323 IpcIo io;
324 uint8_t tmpData[DEFAULT_IPC_SIZE];
325 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
326 IpcIoPushInt32(&io, ret);
327 int32_t ans = Transact(nullptr, sid_, ON_TRIGGER_SINGLE_CAPTURE_FINISHED,
328 &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr);
329 if (ans != LITEIPC_OK) {
330 MEDIA_ERR_LOG("Trigger single capture callback : on trigger single capture frame finished failed.");
331 return;
332 }
333 }
334
OnTriggerLoopingCaptureFinished(int32_t ret,int32_t streamId)335 void CameraServer::OnTriggerLoopingCaptureFinished(int32_t ret, int32_t streamId)
336 {
337 IpcIo io;
338 uint8_t tmpData[DEFAULT_IPC_SIZE];
339 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
340 IpcIoPushInt32(&io, ret);
341 int32_t ans = Transact(nullptr, sid_, ON_TRIGGER_LOOPING_CAPTURE_FINISHED,
342 &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr);
343 if (ans != LITEIPC_OK) {
344 MEDIA_ERR_LOG("Trigger looping capture callback : on trigger looping capture finished failed.");
345 }
346 }
347
OnCameraConfigured(int32_t ret)348 void CameraServer::OnCameraConfigured(int32_t ret)
349 {
350 IpcIo io;
351 uint8_t tmpData[DEFAULT_IPC_SIZE];
352 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
353 IpcIoPushInt32(&io, ret);
354 int32_t ans = Transact(nullptr, sid_, ON_CAMERA_CONFIGURED,
355 &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr);
356 if (ans != LITEIPC_OK) {
357 MEDIA_ERR_LOG("Camera config callback : on trigger looping capture finished failed.");
358 }
359 }
360
SetCameraMode(IpcIo * req,IpcIo * reply)361 void CameraServer::SetCameraMode(IpcIo *req, IpcIo *reply)
362 {
363 uint8_t modeIndex = IpcIoPopUint8(req);
364 int32_t cameraStatus = CameraService::GetInstance()->SetCameraMode(modeIndex);
365 IpcIoPushInt32(reply, cameraStatus);
366 }
367 } // namespace Media
368 } // namespace OHOS