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