1 /*
2 * Copyright (c) 2020-2021 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_device_client.h"
17 #include "liteipc_adapter.h"
18 #include "serializer.h"
19 #include "camera_type.h"
20 #include "media_log.h"
21 #include "camera_config.h"
22 #include "frame_config.h"
23 #include "surface.h"
24 #include "surface_impl.h"
25 #include "camera_impl.h"
26
27 #include <list>
28
29 using namespace std;
30 namespace OHOS {
31 namespace Media {
GetInstance()32 CameraDeviceClient *CameraDeviceClient::GetInstance()
33 {
34 static CameraDeviceClient client;
35 return &client;
36 }
37
CameraDeviceClient()38 CameraDeviceClient::CameraDeviceClient()
39 {
40 cameraClient_ = CameraClient::GetInstance();
41 if (cameraClient_->InitCameraClient()) {
42 proxy_ = cameraClient_->GetIClientProxy();
43 }
44 }
45
~CameraDeviceClient()46 CameraDeviceClient::~CameraDeviceClient()
47 {
48 if (para_ != nullptr) {
49 delete para_;
50 para_ = nullptr;
51 }
52 UnregisterIpcCallback(sid_);
53 }
54
SetCameraId(string & cameraId)55 void CameraDeviceClient::SetCameraId(string &cameraId)
56 {
57 cameraId_ = cameraId;
58 }
59
SetCameraImpl(CameraImpl * cameraImpl)60 void CameraDeviceClient::SetCameraImpl(CameraImpl *cameraImpl)
61 {
62 cameraImpl_ = cameraImpl;
63 }
64
Callback(void * owner,int code,IpcIo * reply)65 int CameraDeviceClient::Callback(void* owner, int code, IpcIo *reply)
66 {
67 if (code != 0) {
68 MEDIA_ERR_LOG("Callback error. (code=%d)", code);
69 return -1;
70 }
71 if (owner == nullptr) {
72 return -1;
73 }
74 CallBackPara* para = (CallBackPara*)owner;
75 switch (para->funcId) {
76 case CAMERA_SERVER_SET_CAMERA_CALLBACK:
77 MEDIA_INFO_LOG("Camera server set callback success.");
78 break;
79 default:
80 break;
81 }
82 return 0;
83 }
84
SetCameraConfig(CameraConfig & cc)85 int32_t CameraDeviceClient::SetCameraConfig(CameraConfig &cc)
86 {
87 IpcIo io;
88 uint8_t tmpData[DEFAULT_IPC_SIZE];
89 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
90 if (cameraId_.empty()) {
91 MEDIA_ERR_LOG("no camera exist.");
92 return MEDIA_ERR;
93 }
94 IpcIoPushString(&io, cameraId_.c_str());
95 para_->data = this;
96 para_->cameraConfig = &cc;
97 CallBackPara para = {};
98 para.funcId = CAEMRA_SERVER_SET_CAMERA_CONFIG;
99 para.data = this;
100 uint32_t ret = proxy_->Invoke(proxy_, CAEMRA_SERVER_SET_CAMERA_CONFIG, &io, ¶, Callback);
101 if (ret != 0) {
102 MEDIA_ERR_LOG("Set camera config ipc transmission failed. (ret=%d)", ret);
103 return MEDIA_ERR;
104 }
105 return MEDIA_OK;
106 }
107
SerilizeFrameConfig(IpcIo & io,FrameConfig & fc,uint32_t maxSurfaceNum)108 int32_t SerilizeFrameConfig(IpcIo &io, FrameConfig &fc, uint32_t maxSurfaceNum)
109 {
110 IpcIoPushInt32(&io, fc.GetFrameConfigType());
111 list<Surface*> surfaceList = fc.GetSurfaces();
112 if (maxSurfaceNum < surfaceList.size()) {
113 MEDIA_ERR_LOG("Too many surfaces. (maxSurfaceNum=%u, sufaceNum=%d)", maxSurfaceNum, surfaceList.size());
114 return MEDIA_ERR;
115 }
116 IpcIoPushUint32(&io, surfaceList.size());
117 for (auto &surface : surfaceList) {
118 dynamic_cast<SurfaceImpl *>(surface)->WriteIoIpcIo(io);
119 MEDIA_DEBUG_LOG("Add surface");
120 }
121 int32_t qfactor = -1;
122 fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor);
123 IpcIoPushInt32(&io, qfactor);
124
125 int32_t streamFps = 0;
126 fc.GetParameter(CAM_FRAME_FPS, streamFps);
127 IpcIoPushInt32(&io, streamFps);
128
129 int32_t invertMode = 0;
130 fc.GetParameter(CAM_IMAGE_INVERT_MODE, invertMode);
131 IpcIoPushInt32(&io, invertMode);
132
133 CameraRect streamCrop;
134 fc.GetParameter(CAM_IMAGE_CROP_RECT, streamCrop);
135 IpcIoPushInt32(&io, streamCrop.x);
136 IpcIoPushInt32(&io, streamCrop.y);
137 IpcIoPushInt32(&io, streamCrop.w);
138 IpcIoPushInt32(&io, streamCrop.h);
139
140 int32_t format = -1;
141 fc.GetParameter(CAM_IMAGE_FORMAT, format);
142 IpcIoPushInt32(&io, format);
143 if (fc.GetFrameConfigType() != FRAME_CONFIG_RECORD) {
144 uint8_t data[PRIVATE_TAG_LEN];
145 fc.GetVendorParameter(data, sizeof(data));
146 BuffPtr dataBuff = {
147 .buffSz = sizeof(data),
148 .buff = (void *)data
149 };
150 IpcIoPushDataBuff(&io, &dataBuff);
151 }
152
153 return MEDIA_OK;
154 }
155
156
TriggerLoopingCapture(FrameConfig & fc)157 int32_t CameraDeviceClient::TriggerLoopingCapture(FrameConfig &fc)
158 {
159 IpcIo io;
160 uint8_t tmpData[DEFAULT_IPC_SIZE];
161 constexpr uint32_t maxSurfaceNum = 2; // 2 surfaces at most
162 /* serilize parameters */
163 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, maxSurfaceNum);
164 if (cameraId_.empty()) {
165 MEDIA_ERR_LOG("no camera exist.");
166 return MEDIA_ERR;
167 }
168 IpcIoPushString(&io, cameraId_.c_str());
169 if (SerilizeFrameConfig(io, fc, maxSurfaceNum) != MEDIA_OK) {
170 MEDIA_ERR_LOG("Serilize the frameconfig failed.");
171 return MEDIA_ERR;
172 }
173 para_->data = this;
174 CallBackPara para = {};
175 para.funcId = CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE;
176 para.data = this;
177 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE, &io, ¶, Callback);
178 if (ret != 0) {
179 MEDIA_ERR_LOG("Trigger looping capture ipc transmission failed. (ret=%d)", ret);
180 return MEDIA_ERR;
181 }
182 return ret_;
183 }
184
TriggerSingleCapture(FrameConfig & fc)185 int32_t CameraDeviceClient::TriggerSingleCapture(FrameConfig &fc)
186 {
187 IpcIo io;
188 uint8_t tmpData[DEFAULT_IPC_SIZE];
189 constexpr uint32_t maxSurfaceNum = 2; // 2 surfaces at most
190 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, maxSurfaceNum);
191
192 if (cameraId_.empty()) {
193 MEDIA_ERR_LOG("no camera exist.");
194 return MEDIA_ERR;
195 }
196 IpcIoPushString(&io, cameraId_.c_str());
197 if (SerilizeFrameConfig(io, fc, maxSurfaceNum) != MEDIA_OK) {
198 MEDIA_ERR_LOG("Serilize the frameconfig failed.");
199 return MEDIA_ERR;
200 }
201 para_->frameConfig = &fc;
202 para_->data = this;
203 CallBackPara para = {};
204 para.funcId = CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE;
205 para.data = this;
206 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE, &io, ¶, Callback);
207 if (ret != 0) {
208 MEDIA_ERR_LOG("Trigger single capture ipc transmission failed. (ret=%d)", ret);
209 return MEDIA_ERR;
210 }
211 return ret_;
212 }
213
StopLoopingCapture()214 void CameraDeviceClient::StopLoopingCapture()
215 {
216 IpcIo io;
217 uint8_t tmpData[DEFAULT_IPC_SIZE];
218 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
219 if (cameraId_.empty()) {
220 MEDIA_ERR_LOG("no camera exist.");
221 return;
222 }
223 IpcIoPushString(&io, cameraId_.c_str());
224 CallBackPara para = {};
225 para.funcId = CAMERA_SERVER_STOP_LOOPING_CAPTURE;
226 para.data = this;
227 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_STOP_LOOPING_CAPTURE, &io, ¶, Callback);
228 if (ret != 0) {
229 MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ret);
230 }
231 }
232
Release()233 void CameraDeviceClient::Release()
234 {
235 IpcIo io;
236 uint8_t tmpData[DEFAULT_IPC_SIZE];
237 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
238 if (cameraId_.empty()) {
239 MEDIA_ERR_LOG("no camera exist.");
240 return;
241 }
242 if (proxy_ == nullptr) {
243 return;
244 }
245 IpcIoPushString(&io, cameraId_.c_str());
246 IpcIoPushSvc(&io, &sid_);
247 para_->data = this;
248 CallBackPara para = {};
249 para.funcId = CAMERA_SERVER_CLOSE_CAMERA;
250 para.data = this;
251 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_CLOSE_CAMERA, &io, ¶, Callback);
252 if (ret != 0) {
253 MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ret);
254 }
255 }
256
SetCameraCallback()257 void CameraDeviceClient::SetCameraCallback()
258 {
259 para_ = new (nothrow) CallBackPara;
260 if (para_ == nullptr) {
261 MEDIA_ERR_LOG("para_ is null.");
262 return;
263 }
264 int32_t ret = RegisterIpcCallback(DeviceClientCallback, 0, IPC_WAIT_FOREVER, &sid_, para_);
265 if (ret != LITEIPC_OK) {
266 MEDIA_ERR_LOG("RegisteIpcCallback failed\n");
267 return;
268 }
269 IpcIo io;
270 uint8_t tmpData[DEFAULT_IPC_SIZE];
271 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
272 IpcIoPushSvc(&io, &sid_);
273 CallBackPara para = {};
274 para.funcId = CAMERA_SERVER_SET_CAMERA_CALLBACK;
275 uint32_t ans = proxy_->Invoke(proxy_, CAMERA_SERVER_SET_CAMERA_CALLBACK, &io, ¶, Callback);
276 if (ans != 0) {
277 MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ans);
278 }
279 }
280
DeviceClientCallback(const IpcContext * context,void * ipcMsg,IpcIo * io,void * arg)281 int32_t CameraDeviceClient::DeviceClientCallback(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg)
282 {
283 if (ipcMsg == nullptr) {
284 MEDIA_ERR_LOG("call back error, ipcMsg is null\n");
285 return MEDIA_ERR;
286 }
287 if (arg == nullptr) {
288 MEDIA_ERR_LOG("call back error, arg is null\n");
289 return MEDIA_ERR;
290 }
291 CallBackPara *para = static_cast<CallBackPara*>(arg);
292 CameraDeviceClient *client = static_cast<CameraDeviceClient*>(para->data);
293 uint32_t funcId;
294 (void)GetCode(ipcMsg, &funcId);
295 MEDIA_INFO_LOG("DeviceCallback, funcId=%d", funcId);
296 switch (funcId) {
297 case ON_CAMERA_CONFIGURED: {
298 int32_t ret = IpcIoPopInt32(io);
299 CameraConfig *cc = static_cast<CameraConfig*>(para->cameraConfig);
300 client->cameraImpl_->OnConfigured(ret, *cc);
301 break;
302 }
303 case ON_TRIGGER_SINGLE_CAPTURE_FINISHED: {
304 int32_t ret = IpcIoPopInt32(io);
305 FrameConfig *fc = static_cast<FrameConfig*>(para->frameConfig);
306 client->cameraImpl_->OnFrameFinished(ret, *fc);
307 client->ret_ = ret;
308 break;
309 }
310 case ON_TRIGGER_LOOPING_CAPTURE_FINISHED: {
311 int32_t ret = IpcIoPopInt32(io);
312 int32_t streamId = IpcIoPopInt32(io);
313 MEDIA_INFO_LOG("ON_TRIGGER_LOOPING_CAPTURE_FINISHED : (ret=%d, streamId=%d).", ret, streamId);
314 client->ret_ = ret;
315 break;
316 }
317 case ON_CAMERA_STATUS_CHANGE: {
318 int32_t ret = IpcIoPopInt32(io);
319 MEDIA_INFO_LOG("ON_CAMERA_STATUS_CHANGE : ret=%d.", ret);
320 break;
321 }
322 default: {
323 MEDIA_ERR_LOG("unsupport funId\n");
324 break;
325 }
326 }
327 client->cameraClient_->ClearIpcMsg(ipcMsg);
328 return MEDIA_OK;
329 }
330 }
331 }