1 /*
2 * Copyright (c) 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 "v4l2_dev.h"
17 #include <sys/prctl.h>
18
19 namespace OHOS::Camera {
20 std::map<std::string, std::string> HosV4L2Dev::deviceMatch = HosV4L2Dev::CreateDevMap();
21 std::map<std::string, int> HosV4L2Dev::fdMatch = HosV4L2Dev::CreateFdMap();
22 std::mutex HosV4L2Dev::deviceFdLock_ = {};
23
24 static constexpr uint32_t WATING_TIME = 1000 * 100;
25
HosV4L2Dev()26 HosV4L2Dev::HosV4L2Dev() {}
~HosV4L2Dev()27 HosV4L2Dev::~HosV4L2Dev() {}
28
GetCurrentFd(const std::string & cameraID)29 int HosV4L2Dev::GetCurrentFd(const std::string& cameraID)
30 {
31 auto itr = HosV4L2Dev::fdMatch.find(cameraID);
32 if (itr == HosV4L2Dev::fdMatch.end()) {
33 CAMERA_LOGE("error: GetCurrentFd no camera fd\n");
34 return RCERRORFD;
35 }
36
37 return itr->second;
38 }
39
start(const std::string & cameraID)40 RetCode HosV4L2Dev::start(const std::string& cameraID)
41 {
42 std::string devName;
43 int fd;
44
45 CAMERA_LOGI("HosV4L2Dev::start enter %{public}s\n", cameraID.c_str());
46
47 if (myFileFormat_ == nullptr) {
48 myFileFormat_ = std::make_shared<HosFileFormat>();
49 if (myFileFormat_ == nullptr) {
50 CAMERA_LOGE("error: InitMatch: myFileFormat_ make_shared is NULL\n");
51 return RC_ERROR;
52 }
53 }
54
55 auto itr = HosV4L2Dev::deviceMatch.find(cameraID);
56 if (itr == HosV4L2Dev::deviceMatch.end()) {
57 CAMERA_LOGE("error:find V4L2 devname fail\n");
58 return RC_ERROR;
59 }
60 devName = itr->second;
61
62 fd = myFileFormat_->V4L2OpenDevice(devName);
63 if (fd < 0) {
64 CAMERA_LOGE("error:myFileFormat_->V4L2OpenDevice fail fd == %{public}d\n", fd);
65 return RC_ERROR;
66 }
67
68 bufferType_ = static_cast<enum v4l2_buf_type>(myFileFormat_->V4L2SearchBufType(fd));
69 if (bufferType_ == V4L2_BUF_TYPE_PRIVATE) {
70 CAMERA_LOGE("error:myFileFormat_->V4L2SearchBufType bufferType_ == 0\n");
71 return RC_ERROR;
72 }
73
74 std::lock_guard<std::mutex> l(HosV4L2Dev::deviceFdLock_);
75 HosV4L2Dev::fdMatch.insert(std::make_pair(cameraID, fd));
76 CAMERA_LOGI("HosV4L2Dev::start out cameraID:%{public}s, devName:%{public}s\n", cameraID.c_str(), devName.c_str());
77 return RC_OK;
78 }
79
stop(const std::string & cameraID)80 RetCode HosV4L2Dev::stop(const std::string& cameraID)
81 {
82 int fd;
83
84 CAMERA_LOGI("HosV4L2Dev::stop enter %{public}s\n", cameraID.c_str());
85
86 if (myFileFormat_ == nullptr) {
87 CAMERA_LOGE("HosV4L2Dev::stop myFileFormat_ == nullptr\n");
88 return RC_ERROR;
89 }
90
91 auto itr = HosV4L2Dev::fdMatch.find(cameraID);
92 if (itr == HosV4L2Dev::fdMatch.end()) {
93 CAMERA_LOGE("HosV4L2Dev::stop GetCurrentFd error\n");
94 return RC_ERROR;
95 }
96
97 fd = itr->second;
98 if (fd < 0) {
99 CAMERA_LOGE("HosV4L2Dev::stop fd error = %d\n", fd);
100 return RC_ERROR;
101 }
102
103 myFileFormat_->V4L2CloseDevice(fd);
104
105 std::lock_guard<std::mutex> l(HosV4L2Dev::deviceFdLock_);
106 HosV4L2Dev::fdMatch.erase(itr);
107 CAMERA_LOGI("HosV4L2Dev::stop out %{public}s\n", cameraID.c_str());
108 return RC_OK;
109 }
110
Init(const std::vector<std::string> & cameraIDs)111 RetCode HosV4L2Dev::Init(const std::vector<std::string>& cameraIDs)
112 {
113 CAMERA_LOGI("HosV4L2Dev::Init enter\n");
114 auto myFileFormat = std::make_shared<HosFileFormat>();
115 if (myFileFormat == nullptr) {
116 CAMERA_LOGE("error: InitMatch: myFileFormat_ make_shared is NULL\n");
117 return RC_ERROR;
118 }
119
120 myFileFormat->V4L2MatchDevice(cameraIDs);
121 CAMERA_LOGI("HosV4L2Dev::Init out\n");
122 return RC_OK;
123 }
124
ReqBuffers(const std::string & cameraID,unsigned int buffCont)125 RetCode HosV4L2Dev::ReqBuffers(const std::string& cameraID, unsigned int buffCont)
126 {
127 int rc, fd;
128 CAMERA_LOGI("HosV4L2Dev::ReqBuffers enters %{public}s\n", cameraID.c_str());
129 fd = GetCurrentFd(cameraID);
130 if (fd < 0) {
131 CAMERA_LOGE("error: ReqBuffers: GetCurrentFd error\n");
132 return RC_ERROR;
133 }
134
135 if (myBuffers_ == nullptr) {
136 myBuffers_ = HosV4L2Buffers::CreateHosV4L2Buffers(memoryType_, bufferType_);
137 if (myBuffers_ == nullptr) {
138 CAMERA_LOGE("error: Creatbuffer: myBuffers_ make_shared is NULL\n");
139 return RC_ERROR;
140 }
141 }
142
143 rc = myBuffers_->V4L2ReqBuffers(fd, buffCont);
144 if (rc == RC_ERROR) {
145 CAMERA_LOGE("error: Creatbuffer: V4L2ReqBuffers error\n");
146 return RC_ERROR;
147 }
148 CAMERA_LOGI("HosV4L2Dev::ReqBuffers exit %{public}s\n", cameraID.c_str());
149 return RC_OK;
150 }
151
CreatBuffer(const std::string & cameraID,const std::shared_ptr<FrameSpec> & frameSpec)152 RetCode HosV4L2Dev::CreatBuffer(const std::string& cameraID, const std::shared_ptr<FrameSpec>& frameSpec)
153 {
154 int rc, fd;
155 CAMERA_LOGI("HosV4L2Dev::CreatBuffer in %{public}s\n", cameraID.c_str());
156 fd = GetCurrentFd(cameraID);
157 if (fd < 0) {
158 CAMERA_LOGE("error: ReqBuffers: GetCurrentFd error\n");
159 return RC_ERROR;
160 }
161
162 if (frameSpec == nullptr || myBuffers_ == nullptr) {
163 CAMERA_LOGE("error: Creatbuffer frameSpec or myBuffers_ is NULL\n");
164 return RC_ERROR;
165 }
166
167 CAMERA_LOGI("Creatbuffer frameSpec->buffer index == %d\n", frameSpec->buffer_->GetIndex());
168
169 rc = myBuffers_->V4L2AllocBuffer(fd, frameSpec);
170 if (rc == RC_ERROR) {
171 CAMERA_LOGE("error: Creatbuffer: V4L2AllocBuffer error\n");
172 return RC_ERROR;
173 }
174
175 rc = myBuffers_->V4L2QueueBuffer(fd, frameSpec);
176 if (rc == RC_ERROR) {
177 CAMERA_LOGE("error: Creatbuffer: V4L2QueueBuffer error\n");
178 return RC_ERROR;
179 }
180 CAMERA_LOGI("HosV4L2Dev::CreatBuffer out %{public}s\n", cameraID.c_str());
181 return RC_OK;
182 }
183
QueueBuffer(const std::string & cameraID,const std::shared_ptr<FrameSpec> & frameSpec)184 RetCode HosV4L2Dev::QueueBuffer(const std::string& cameraID, const std::shared_ptr<FrameSpec>& frameSpec)
185 {
186 int rc, fd;
187 CAMERA_LOGI("HosV4L2Dev::QueueBuffer in %{public}s\n", cameraID.c_str());
188 fd = GetCurrentFd(cameraID);
189 if (fd < 0) {
190 CAMERA_LOGE("QueueBuffer: GetCurrentFd error\n");
191 return RC_ERROR;
192 }
193
194 if (frameSpec == nullptr || myBuffers_ == nullptr) {
195 CAMERA_LOGE(" QueueBuffer frameSpec or myBuffers_ is NULL\n");
196 return RC_ERROR;
197 }
198
199 rc = myBuffers_->V4L2QueueBuffer(fd, frameSpec);
200 if (rc == RC_ERROR) {
201 CAMERA_LOGE("QueueBuffer: V4L2QueueBuffer error\n");
202 return RC_ERROR;
203 }
204 CAMERA_LOGI("HosV4L2Dev::QueueBuffer out %{public}s\n", cameraID.c_str());
205 return RC_OK;
206 }
207
ReleaseBuffers(const std::string & cameraID)208 RetCode HosV4L2Dev::ReleaseBuffers(const std::string& cameraID)
209 {
210 int fd;
211 int rc = 0;
212 CAMERA_LOGI("HosV4L2Dev::ReleaseBuffers in %{public}s\n", cameraID.c_str());
213 if (myBuffers_ == nullptr) {
214 CAMERA_LOGE("ReleaseBuffers myBuffers_ is NULL\n");
215 return RC_ERROR;
216 }
217
218 fd = GetCurrentFd(cameraID);
219 if (fd < 0) {
220 CAMERA_LOGE("ReleaseBuffers: GetCurrentFd error\n");
221 return RC_ERROR;
222 }
223
224 rc = myBuffers_->V4L2ReleaseBuffers(fd);
225 if (rc == RC_ERROR) {
226 CAMERA_LOGE("ReleaseBuffers: V4L2ReleaseBuffers error\n");
227 return RC_ERROR;
228 }
229 CAMERA_LOGI("HosV4L2Dev::ReleaseBuffers out %{public}s\n", cameraID.c_str());
230 return RC_OK;
231 }
232
dequeueBuffers()233 void HosV4L2Dev::dequeueBuffers()
234 {
235 int nfds;
236 int rc;
237 struct epoll_event events[MAXSTREAMCOUNT];
238 nfds = epoll_wait(epollFd_, events, MAXSTREAMCOUNT, -1);
239 CAMERA_LOGI("loopBuffers: epoll_wait rc = %{public}d streamNumber_ == %{public}d\n", nfds, streamNumber_);
240
241 for (int n = 0; nfds > 0; ++n, --nfds) {
242 if ((events[n].events & EPOLLIN) && (events[n].data.fd != eventFd_)) {
243 CHECK_IF_PTR_NULL_RETURN_VOID(myBuffers_);
244 rc = myBuffers_->V4L2DequeueBuffer(events[n].data.fd);
245 if (rc == RC_ERROR) {
246 continue;
247 }
248 } else {
249 CAMERA_LOGI("loopBuffers: epoll invalid events = 0x%{public}x or eventFd exit = %{public}d\n",
250 events[n].events, (events[n].data.fd == eventFd_));
251 usleep(WATING_TIME);
252 }
253 }
254 }
255
loopBuffers()256 void HosV4L2Dev::loopBuffers()
257 {
258 CAMERA_LOGI("!!! loopBuffers enter, streamNumber_=%{public}d\n", streamNumber_);
259 prctl(PR_SET_NAME, "v4l2_loopbuffer");
260
261 while (true) {
262 {
263 std::lock_guard<std::mutex> l(streamLock_);
264 if (streamNumber_ <= 0) {
265 break;
266 }
267 }
268 dequeueBuffers();
269 }
270 CAMERA_LOGI("!!! loopBuffers exit, streamNumber_=%{public}d\n", streamNumber_);
271 }
272
CreateEpoll(int fd,const unsigned int streamNumber)273 RetCode HosV4L2Dev::CreateEpoll(int fd, const unsigned int streamNumber)
274 {
275 struct epoll_event epollevent = {};
276 CAMERA_LOGI("CreateEpoll enter, fd=%{public}d\n", fd);
277 if (streamNumber == 0) {
278 epollFd_ = epoll_create(MAXSTREAMCOUNT);
279 if (epollFd_ < 0) {
280 CAMERA_LOGE("V4L2 StartStream create_epoll failed\n");
281 return RC_ERROR;
282 }
283 epollevent.events = EPOLLIN;
284 epollevent.data.fd = fd;
285 int ret = epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &epollevent);
286 if (ret < 0) {
287 CAMERA_LOGE("add fd=%{public}d to epoll failed, ret=%{public}d, errno=%{public}d", fd, ret, errno);
288 }
289
290 std::lock_guard<std::mutex> l(epollLock_);
291 epollEvent_.push_back(epollevent);
292
293 eventFd_ = eventfd(0, 0);
294 epollevent = {};
295 epollevent.events = EPOLLIN;
296 epollevent.data.fd = eventFd_;
297 ret = epoll_ctl(epollFd_, EPOLL_CTL_ADD, eventFd_, &epollevent);
298 if (ret < 0) {
299 CAMERA_LOGE("add eventFd_=%{public}d to epoll failed, ret=%{public}d, errno=%{public}d",
300 eventFd_, ret, errno);
301 return RC_ERROR;
302 }
303 } else {
304 epollevent.events = EPOLLIN;
305 epollevent.data.fd = fd;
306
307 std::lock_guard<std::mutex> l(epollLock_);
308 epollEvent_.push_back(epollevent);
309
310 int ret = epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &epollevent);
311 if (ret < 0) {
312 CAMERA_LOGE("add fd = %{public}d to epoll failed, ret=%{public}d, errno=%{public}d", fd, ret, errno);
313 return RC_ERROR;
314 }
315 }
316 CAMERA_LOGI("CreateEpoll out, fd=%{public}d\n", fd);
317 return RC_OK;
318 }
319
EraseEpoll(int fd)320 void HosV4L2Dev::EraseEpoll(int fd)
321 {
322 CAMERA_LOGI("EraseEpoll enter, fd = %{public}d\n", fd);
323 auto itr = std::find_if(epollEvent_.begin(), epollEvent_.end(), [fd](const epoll_event& event) {
324 if (event.data.fd == fd) {
325 return true;
326 } else {
327 return false;
328 }
329 });
330 if (itr != epollEvent_.end()) {
331 struct epoll_event event = *itr;
332 int ret = epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, &event);
333 if (ret < 0) {
334 CAMERA_LOGE("del fd=%{public}d to epoll failed, ret=%{public}d, errno=%{public}d", fd, ret, errno);
335 }
336 std::lock_guard<std::mutex> l(epollLock_);
337 epollEvent_.erase(itr);
338 }
339 CAMERA_LOGI("EraseEpoll out, fd = %{public}d\n", fd);
340 }
341
StartStream(const std::string & cameraID)342 RetCode HosV4L2Dev::StartStream(const std::string& cameraID)
343 {
344 int rc, fd;
345 CAMERA_LOGI("StartStream enter, cameraID = %{public}s\n", cameraID.c_str());
346 fd = GetCurrentFd(cameraID);
347 if (fd < 0) {
348 CAMERA_LOGE("error: ReqBuffers: GetCurrentFd error\n");
349 return RC_ERROR;
350 }
351
352 if (myStreams_ == nullptr) {
353 myStreams_ = std::make_shared<HosV4L2Streams>(bufferType_);
354 if (myStreams_ == nullptr) {
355 CAMERA_LOGE("error: StartStream: myStreams_ make_shared is NULL\n");
356 return RC_ERROR;
357 }
358 }
359
360 rc = myStreams_->V4L2StreamOn(fd);
361 if (rc == RC_ERROR) {
362 CAMERA_LOGE("error: StartStream: V4L2StreamOn error\n");
363 return RC_ERROR;
364 }
365
366 rc = CreateEpoll(fd, streamNumber_);
367 if (rc == RC_ERROR) {
368 CAMERA_LOGE("StartStream: CreateEpoll error\n");
369 return RC_ERROR;
370 }
371
372 if (streamNumber_ == 0) {
373 streamNumber_++;
374 CAMERA_LOGE("go start thread loopBuffers, streamNumber_=%{public}d\n", streamNumber_);
375 streamThread_ = new (std::nothrow) std::thread([this] {this->loopBuffers();});
376 if (streamThread_ == nullptr) {
377 CAMERA_LOGE("V4L2 StartStream start thread failed\n");
378 streamNumber_--;
379 return RC_ERROR;
380 }
381 }
382 CAMERA_LOGI("StartStream out, cameraID = %{public}s\n", cameraID.c_str());
383 return RC_OK;
384 }
385
StopStream(const std::string & cameraID)386 RetCode HosV4L2Dev::StopStream(const std::string& cameraID)
387 {
388 CAMERA_LOGI("StartStream enter, cameraID = %{public}s\n", cameraID.c_str());
389 if (myStreams_ == nullptr || streamThread_ == nullptr) {
390 CAMERA_LOGE("error: StopStream: myStreams_ or streamThread_ is nullptr");
391 return RC_ERROR;
392 }
393
394 int fd = GetCurrentFd(cameraID);
395 if (fd < 0) {
396 CAMERA_LOGE("error: StopStream: GetCurrentFd error\n");
397 return RC_ERROR;
398 }
399
400 unsigned int streamNum = 0;
401 {
402 std::lock_guard<std::mutex> l(streamLock_);
403 streamNum = --streamNumber_;
404 CAMERA_LOGI("HosV4L2Dev::StopStream streamNumber_ = %{public}d\n", streamNumber_);
405 }
406
407 if (streamNum == 0) {
408 CAMERA_LOGI("waiting loopBuffers stop\n");
409 uint64_t one = 1;
410 ssize_t ret = write(eventFd_, &one, sizeof(one));
411 if (ret != sizeof(one)) {
412 CAMERA_LOGE("HosV4L2Dev::StopStream write fd: %{public}d, failed, ret = %{public}zd\n", eventFd_, ret);
413 }
414 streamThread_->join();
415 close(eventFd_);
416 CAMERA_LOGI("waiting loopBuffers exit\n");
417 }
418
419 if (myStreams_->V4L2StreamOff(fd) == RC_ERROR) {
420 CAMERA_LOGE("error: StopStream: V4L2StreamOn error\n");
421 return RC_ERROR;
422 }
423
424 EraseEpoll(fd);
425 {
426 std::lock_guard<std::mutex> l(streamLock_);
427 if (streamNumber_ == 0) {
428 close(epollFd_);
429 delete streamThread_;
430 streamThread_ = nullptr;
431 }
432 }
433 CAMERA_LOGI("StartStream out, cameraID = %{public}s\n", cameraID.c_str());
434 return RC_OK;
435 }
436
SetCtrlByCondition(int32_t fd,AdapterCmd command,const int * args,int & rc,std::shared_ptr<HosV4L2Control> myControl_)437 void SetCtrlByCondition(int32_t fd, AdapterCmd command, const int* args,
438 int &rc, std::shared_ptr<HosV4L2Control> myControl_)
439 {
440 switch (command) {
441 case CMD_EXPOSURE_MODE:
442 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_EXPOSURE_AUTO, *args);
443 break;
444 case CMD_AE_EXPOTIME:
445 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_EXPOSURE_ABSOLUTE, *args);
446 break;
447 case CMD_EXPOSURE_COMPENSATION:
448 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_EXPOSURE, *args);
449 break;
450 case CMD_AWB_MODE:
451 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, *args);
452 break;
453 case CMD_AE_LOCK:
454 case CMD_EXPOSURE_LOCK:
455 case CMD_FOCUS_LOCK:
456 case CMD_AWB_LOCK:
457 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_3A_LOCK, *args);
458 break;
459 case CMD_FOCUS_AUTO:
460 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_FOCUS_AUTO, *args);
461 break;
462 case CMD_FOCUS_ABSOLUTE:
463 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_FOCUS_ABSOLUTE, *args);
464 break;
465 case CMD_AUTO_FOCUS_START:
466 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_AUTO_FOCUS_START, *args);
467 break;
468 case CMD_AUTO_FOCUS_STOP:
469 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_AUTO_FOCUS_STOP, *args);
470 break;
471 case CMD_METER_MODE:
472 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_EXPOSURE_METERING, *args);
473 break;
474 case CMD_FLASH_MODE:
475 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_FLASH_LED_MODE, *args);
476 break;
477 case CMD_AE_EXPO:
478 rc = myControl_->V4L2SetCtrl(fd, V4L2_CID_BRIGHTNESS, *args);
479 break;
480 default:
481 break;
482 }
483 }
484
UpdateSetting(const std::string & cameraID,AdapterCmd command,const int * args)485 RetCode HosV4L2Dev::UpdateSetting(const std::string& cameraID, AdapterCmd command, const int* args)
486 {
487 CAMERA_LOGI("UpdateSetting enter, cameraID = %{public}s\n", cameraID.c_str());
488 int32_t fd;
489 int rc = 0;
490 if (args == nullptr) {
491 CAMERA_LOGE("HosV4L2Dev::UpdateSetting: args is NULL\n");
492 return RC_ERROR;
493 }
494 if (myControl_ == nullptr) {
495 myControl_ = std::make_shared<HosV4L2Control>();
496 if (myControl_ == nullptr) {
497 CAMERA_LOGE("HosV4L2Dev::UpdateSetting: myControl_ make_shared is NULL\n");
498 return RC_ERROR;
499 }
500 }
501 fd = GetCurrentFd(cameraID);
502 if (fd < 0) {
503 CAMERA_LOGE("UpdateSetting: GetCurrentFd error\n");
504 return RC_ERROR;
505 }
506 SetCtrlByCondition(fd, command, args, rc, myControl_);
507 if (rc != RC_OK) {
508 return RC_ERROR;
509 }
510 CAMERA_LOGI("UpdateSetting out, cameraID = %{public}s\n", cameraID.c_str());
511 return RC_OK;
512 }
513
QuerySetting(const std::string & cameraID,unsigned int command,int * args)514 RetCode HosV4L2Dev::QuerySetting(const std::string& cameraID, unsigned int command, int* args)
515 {
516 int32_t fd;
517 int32_t value = 0;
518 int rc = 0;
519 CAMERA_LOGI("QuerySetting enter, cameraID = %{public}s\n", cameraID.c_str());
520 if (args == nullptr) {
521 CAMERA_LOGE("HosV4L2Dev::QuerySetting: args is NULL\n");
522 return RC_ERROR;
523 }
524
525 if (myControl_ == nullptr) {
526 myControl_ = std::make_shared<HosV4L2Control>();
527 if (myControl_ == nullptr) {
528 CAMERA_LOGE("HosV4L2Dev::QuerySetting: myControl_ make_shared is NULL\n");
529 return RC_ERROR;
530 }
531 }
532
533 fd = GetCurrentFd(cameraID);
534 if (fd < 0) {
535 CAMERA_LOGE("QuerySetting: GetCurrentFd error\n");
536 return RC_ERROR;
537 }
538
539 rc = myControl_->V4L2GetCtrl(fd, command, value);
540 if (rc != RC_OK) {
541 return RC_ERROR;
542 }
543
544 *(reinterpret_cast<int32_t*>(args)) = value;
545 CAMERA_LOGI("QuerySetting out, cameraID = %{public}s\n", cameraID.c_str());
546 return RC_OK;
547 }
548
GetNumberCtrls(const std::string & cameraID,std::vector<DeviceControl> & control)549 RetCode HosV4L2Dev::GetNumberCtrls(const std::string& cameraID, std::vector<DeviceControl>& control)
550 {
551 int32_t fd;
552 CAMERA_LOGI("GetNumberCtrls enter, cameraID = %{public}s\n", cameraID.c_str());
553 if (myControl_ == nullptr) {
554 myControl_ = std::make_shared<HosV4L2Control>();
555 if (myControl_ == nullptr) {
556 CAMERA_LOGE("HosV4L2Dev::GetNumberCtrls: myControl_ make_shared is NULL\n");
557 return RC_ERROR;
558 }
559 }
560
561 fd = GetCurrentFd(cameraID);
562 if (fd < 0) {
563 CAMERA_LOGE("GetNumberCtrls: GetCurrentFd error\n");
564 return RC_ERROR;
565 }
566
567 return myControl_->V4L2GetCtrls(fd, control, control.size());
568 }
569
SetNumberCtrls(const std::string & cameraID,std::vector<DeviceControl> & control)570 RetCode HosV4L2Dev::SetNumberCtrls(const std::string& cameraID, std::vector<DeviceControl>& control)
571 {
572 int32_t fd;
573 CAMERA_LOGI("SetNumberCtrls enter, cameraID = %{public}s\n", cameraID.c_str());
574 if (myControl_ == nullptr) {
575 myControl_ = std::make_shared<HosV4L2Control>();
576 if (myControl_ == nullptr) {
577 CAMERA_LOGE("HosV4L2Dev::SetNumberCtrls: myControl_ make_shared is NULL\n");
578 return RC_ERROR;
579 }
580 }
581
582 fd = GetCurrentFd(cameraID);
583 if (fd < 0) {
584 CAMERA_LOGE("SetNumberCtrls: GetCurrentFd error\n");
585 return RC_ERROR;
586 }
587
588 return myControl_->V4L2SetCtrls(fd, control, control.size());
589 }
590
GetControls(const std::string & cameraID,std::vector<DeviceControl> & control)591 RetCode HosV4L2Dev::GetControls(const std::string& cameraID, std::vector<DeviceControl>& control)
592 {
593 int fd, rc;
594 CAMERA_LOGI("GetControls enter, cameraID = %{public}s\n", cameraID.c_str());
595 if (myControl_ == nullptr) {
596 myControl_ = std::make_shared<HosV4L2Control>();
597 if (myControl_ == nullptr) {
598 CAMERA_LOGE("HosV4L2Dev::GetControls: myControl_ make_shared is NULL\n");
599 return RC_ERROR;
600 }
601 }
602
603 fd = GetCurrentFd(cameraID);
604 if (fd < 0) {
605 CAMERA_LOGE("GetControls: GetCurrentFd error\n");
606 return RC_ERROR;
607 }
608
609 rc = myControl_->V4L2GetControls(fd, control);
610 if (rc == RC_ERROR) {
611 CAMERA_LOGE("myControl_->V4L2GetControls fail\n");
612 return RC_ERROR;
613 }
614 CAMERA_LOGI("GetControls out, cameraID = %{public}s\n", cameraID.c_str());
615 return RC_OK;
616 }
617
GetFmtDescs(const std::string & cameraID,std::vector<DeviceFormat> & fmtDesc)618 RetCode HosV4L2Dev::GetFmtDescs(const std::string& cameraID, std::vector<DeviceFormat>& fmtDesc)
619 {
620 int fd, rc;
621 CAMERA_LOGI("GetFmtDescs enter, cameraID = %{public}s\n", cameraID.c_str());
622 if (myFileFormat_ == nullptr) {
623 CAMERA_LOGE("GetFmtDescs: myFileFormat_ == nullptr\n");
624 return RC_ERROR;
625 }
626
627 fd = GetCurrentFd(cameraID);
628 if (fd < 0) {
629 CAMERA_LOGE("GetFmtDescs: GetCurrentFd error\n");
630 return RC_ERROR;
631 }
632
633 rc = myFileFormat_->V4L2GetFmtDescs(fd, fmtDesc);
634 if (rc == RC_ERROR) {
635 CAMERA_LOGE("myFileFormat_->V4L2GetFmtDescs fail\n");
636 return RC_ERROR;
637 }
638 CAMERA_LOGI("GetFmtDescs out, cameraID = %{public}s\n", cameraID.c_str());
639 return RC_OK;
640 }
641
ConfigFps(const int fd,DeviceFormat & format,V4l2FmtCmd command)642 RetCode HosV4L2Dev::ConfigFps(const int fd, DeviceFormat& format, V4l2FmtCmd command)
643 {
644 RetCode rc = RC_OK;
645 CAMERA_LOGI("ConfigFps enter, fd = %{public}d\n", fd);
646 if (myStreams_ == nullptr) {
647 myStreams_ = std::make_shared<HosV4L2Streams>(bufferType_);
648 if (myStreams_ == nullptr) {
649 CAMERA_LOGE("error: ConfigSys: myStreams_ make_shared is nullptr\n");
650 return RC_ERROR;
651 }
652 }
653
654 if (command == CMD_V4L2_SET_FPS) {
655 rc = myStreams_->V4L2StreamFPSSet(fd, format);
656 } else {
657 rc = myStreams_->V4L2StreamFPSGet(fd, format);
658 }
659
660 if (rc != RC_OK) {
661 CAMERA_LOGE("ConfigFps CMD %d fail\n", command);
662 }
663 CAMERA_LOGI("ConfigFps out, fd = %{public}d\n", fd);
664 return rc;
665 }
666
ConfigSys(const std::string & cameraID,V4l2FmtCmd command,DeviceFormat & format)667 RetCode HosV4L2Dev::ConfigSys(const std::string& cameraID, V4l2FmtCmd command, DeviceFormat& format)
668 {
669 int fd;
670 RetCode rc = RC_OK;
671 CAMERA_LOGI("ConfigSys enter, cameraID = %{public}s\n", cameraID.c_str());
672 if (myFileFormat_ == nullptr) {
673 CAMERA_LOGE("GetFmtDescs: ConfigSys == nullptr\n");
674 return RC_ERROR;
675 }
676
677 fd = GetCurrentFd(cameraID);
678 if (fd < 0) {
679 CAMERA_LOGE("ConfigSys: GetCurrentFd error\n");
680 return RC_ERROR;
681 }
682
683 switch (command) {
684 case CMD_V4L2_GET_FORMAT:
685 rc = myFileFormat_->V4L2GetFmt(fd, format);
686 break;
687
688 case CMD_V4L2_SET_FORMAT:
689 rc = myFileFormat_->V4L2SetFmt(fd, format);
690 break;
691
692 case CMD_V4L2_GET_CROPCAP:
693 rc = myFileFormat_->V4L2GetCropCap(fd, format);
694 break;
695
696 case CMD_V4L2_GET_CROP:
697 rc = myFileFormat_->V4L2GetCrop(fd, format);
698 break;
699
700 case CMD_V4L2_SET_CROP:
701 rc = myFileFormat_->V4L2SetCrop(fd, format);
702 break;
703
704 case CMD_V4L2_SET_FPS:
705 case CMD_V4L2_GET_FPS:
706 rc = ConfigFps(fd, format, command);
707 break;
708
709 default:
710 CAMERA_LOGE("HosV4L2Dev::ConfigSys unknown command\n");
711 break;
712 }
713
714 if (rc != RC_OK) {
715 CAMERA_LOGE("ConfigSys CMD %d fail\n", command);
716 }
717
718 return rc;
719 }
720
SetV4L2DevCallback(BufCallback cb)721 RetCode HosV4L2Dev::SetV4L2DevCallback(BufCallback cb)
722 {
723 if (cb == nullptr) {
724 CAMERA_LOGE("HosV4L2Dev::SetCallback is null");
725 return RC_ERROR;
726 }
727 if (myBuffers_ == nullptr) {
728 CAMERA_LOGE("SetCallback myBuffers_ is NULL\n");
729 return RC_ERROR;
730 }
731
732 myBuffers_->SetV4L2BuffersCallback(cb);
733
734 return RC_OK;
735 }
Flush(const std::string & cameraID)736 RetCode HosV4L2Dev::Flush(const std::string& cameraID)
737 {
738 int rc, fd;
739 CAMERA_LOGI("Flush enter, cameraID = %{public}s\n", cameraID.c_str());
740 fd = GetCurrentFd(cameraID);
741 if (fd < 0) {
742 CAMERA_LOGE("HosV4L2Dev::Flush: GetCurrentFd error\n");
743 return RC_ERROR;
744 }
745
746 if (myBuffers_ == nullptr) {
747 CAMERA_LOGE(" HosV4L2Dev::Flush myBuffers_ is NULL\n");
748 return RC_ERROR;
749 }
750
751 rc = myBuffers_->Flush(fd);
752 if (rc == RC_ERROR) {
753 CAMERA_LOGE("HosV4L2Dev::Flush: error\n");
754 return RC_ERROR;
755 }
756 CAMERA_LOGI("Flush out, cameraID = %{public}s\n", cameraID.c_str());
757 return RC_OK;
758 }
759
SetMemoryType(uint8_t & memType)760 void HosV4L2Dev::SetMemoryType(uint8_t &memType)
761 {
762 CAMERA_LOGI("func[HosV4L2Dev::%{public}s] memType[%{public}d]", __func__, memType);
763 if (memType == V4L2_MEMORY_MMAP) {
764 memoryType_ = V4L2_MEMORY_MMAP;
765 } else if (memType == V4L2_MEMORY_DMABUF) {
766 memoryType_ = V4L2_MEMORY_DMABUF;
767 }
768 }
769 } // namespace OHOS::Camera
770