• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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