xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/allwinner/camera/camera/Camera.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include "Camera.h"
2 #include "ui_Camera.h"
3 #include <sys/ioctl.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <QStringList>
10 #include <QWidget>
11 #include <QDebug>
12 #include <QImage>
13 #include <QMessageBox>
14 #include <QThreadPool>
15 #include <unistd.h>
16 #include <string.h>
17 #include <linux/videodev2.h>
18 
19 #include "sunxi_camera_v2.h"
20 #include "videocapture.h"
21 #include <QComboBox>
22 #include <QPushButton>
23 #include <QLabel>
24 #include <QGridLayout>
25 #include <QVBoxLayout>
26 #include <sys/mman.h>
27 
28 QLabel *label;
29 QPushButton *PushStart;
30 QPushButton *PushStop;
31 QPushButton *PushPicture;
32 QPushButton *PushQuit;
33 QComboBox *comboBox;
34 QComboBox *resolution;
35 #define ALIGN(x,a) (((x) + (a-1)) & ~(a-1))
36 
37 static struct v4l2_capability cap;
Camera(QWidget * parent)38 Camera::Camera(QWidget *parent)
39     : IWidget(parent)
40     , ui(new Ui::Camera)
41 {
42     ui->setupUi(this);
43     threadStatus = 0;
44 
45     int i=0, ret = 0;
46     char devname[100];
47     int fd = 0;
48     capture = nullptr;
49     QGridLayout *gradLayout = new QGridLayout(this);
50 
51     comboBox = new QComboBox();
52     comboBox->setFixedHeight(20);
53     resolution = new QComboBox();
54     resolution->setMinimumHeight(20);
55     PushStop = new QPushButton();
56      PushStop->setMinimumHeight(20);
57     PushStop->setText("Stop");
58     PushStart = new QPushButton();
59     PushStart->setMinimumHeight(20);
60     PushStart->setText("Start");
61     PushPicture = new QPushButton();
62     PushPicture->setMinimumHeight(20);
63     PushPicture->setText("picture");
64 
65     label = new QLabel;
66     label->setText("wait video ....");
67     label->setAlignment(Qt::AlignCenter);
68     label->setMinimumSize(640, 480);
69 
70     gradLayout->addWidget(label, 0, 0, 6, 6);
71 
72     QVBoxLayout *verticallayer = new QVBoxLayout();
73     verticallayer->setSpacing(20);
74     verticallayer->addWidget(comboBox);
75     verticallayer->addWidget(resolution);
76     verticallayer->addWidget(PushStart);
77     verticallayer->addWidget(PushStop);
78     verticallayer->addWidget(PushPicture);
79     verticallayer->addStretch();
80     gradLayout->addLayout(verticallayer, 0, 7, 6, 1);
81 
82     comboBox->addItem(QWidget::tr("camera video"));
83     resolution->addItem(QWidget::tr("camera resolution"));
84 
85     while(i < 100) {
86         sprintf(devname,"/dev/video%d",i++);
87 
88         fd = ::open(devname,O_RDWR);
89         if(fd < 0)
90             continue;
91 
92         memset(&cap, 0x00, sizeof(cap));
93         ret = ::ioctl(fd, VIDIOC_QUERYCAP, &cap);//摄像头主要功能获取
94         if ((ret == 0) &&
95                 ((::strstr(reinterpret_cast<const char *>(cap.driver), "vin") != NULL)
96                  || (::strstr(reinterpret_cast<const char *>(cap.driver), "uvc") != NULL)))
97         {
98             comboBox->addItem(QWidget::tr(devname));
99         }
100         ::close(fd);
101     }
102 
103     resolution->addItem(QWidget::tr("640x480"));
104     resolution->addItem(QWidget::tr("1280x720"));
105     resolution->addItem(QWidget::tr("1920x1080"));
106     resolution->addItem((QWidget::tr("2592x1944")));
107 
108 
109     connect(PushPicture, SIGNAL(clicked(bool)), this, SLOT(SaveImge()));
110     connect(PushStart, SIGNAL(clicked(bool)), this, SLOT(StartWorkThread()));
111     connect(PushStop, SIGNAL(clicked(bool)), this, SLOT(StopWorkThread()));
112     connect(comboBox,
113             SIGNAL(currentIndexChanged(const QString &)),
114             this, SLOT(GetVideoDevName(const QString &)));
115 
116     connect(resolution,
117             SIGNAL(currentIndexChanged(const QString &)),
118             this, SLOT(GetVideoResolution(const QString &)));
119 }
120 
ApplictionQuit()121 void Camera::ApplictionQuit()
122 {
123     if (capture) {
124         capture->stop();
125         QThreadPool::globalInstance()->waitForDone(-1);
126     }
127 }
128 
GetVideoDevName(const QString & name)129 void Camera::GetVideoDevName(const QString &name)
130 {
131     sprintf(DevName, "%s", name.toStdString().data());
132 }
133 
GetVideoResolution(const QString & name)134 void Camera::GetVideoResolution(const QString &name)
135 {
136     sprintf(DevResolution, "%s", name.toStdString().data());
137 }
138 
~Camera()139 Camera::~Camera()
140 {
141     this->ApplictionQuit();
142     delete ui;
143 }
144 
id()145 QString Camera::id()
146 {
147     return "camera";
148 }
149 
SaveImge(void)150 void Camera::SaveImge(void)
151 {
152     if ((capture != nullptr) && (capture->take == 0))
153         capture->take = 1;
154     //   QMetaObject::connectSlotsByName(this);
155 }
156 
StartWorkThread()157 void Camera::StartWorkThread()
158 {
159     if(!threadStatus) {
160         threadStatus = 1;
161         const char *res = DevResolution;
162         char *devname = DevName;
163         if (strcmp("", DevName) == 0) {
164             QMessageBox::information(this,
165                                      "Title", "no video dev",
166                                      QMessageBox::Yes | QMessageBox::No,
167                                      QMessageBox::Yes);
168             threadStatus = 0;
169             return ;
170         }
171 
172         if (strcmp(res, "") == 0) {
173             QMessageBox::information(this,
174                                      "Title", "no resolution",
175                                      QMessageBox::Yes | QMessageBox::No,
176                                      QMessageBox::Yes);
177 
178             threadStatus = 0;
179             return ;
180         }
181 
182         int videofd = ::open(devname, O_RDWR);
183         if (videofd < 0) {
184             QMessageBox::information(this,
185                                      "Title", "no video device",
186                                      QMessageBox::Yes | QMessageBox::No,
187                                      QMessageBox::Yes);
188             threadStatus = 0;
189             return ;
190         }
191 
192         int w = 0, h = 0;
193         int issupport = 0;
194         ::sscanf(res, "%dx%d", &w, &h);
195         qDebug() << "w:" << w <<"h: " << h;
196 
197         memset(&cap, 0x00, sizeof(cap));
198         int ret = ::ioctl(videofd, VIDIOC_QUERYCAP, &cap);//摄像头主要功能获取
199         if ((ret == 0) &&
200                 (::strstr(reinterpret_cast<const char *>(cap.driver), "uvc") != NULL)) {
201             enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
202             struct v4l2_fmtdesc fmt_1;
203             struct v4l2_frmsizeenum frmsize;
204             fmt_1.index = 0;
205             fmt_1.type = type;
206             while (::ioctl(videofd, VIDIOC_ENUM_FMT, &fmt_1) >= 0) {
207                 frmsize.pixel_format = fmt_1.pixelformat;
208                 frmsize.index = 0;
209                 while (::ioctl(videofd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0){
210                     qDebug() << "width: " << frmsize.discrete.width << "height: " << frmsize.discrete.height;
211                     if ((w == frmsize.discrete.width)
212                             && (h == frmsize.discrete.height)) {
213                         issupport = 1;
214                         break;
215                     }
216                     frmsize.index++;
217                 }
218 
219                 fmt_1.index++;
220             }
221 
222             if (!issupport) {
223                 QMessageBox::information(this,
224                                          "Title", "not support resolution",
225                                          QMessageBox::Yes | QMessageBox::No,
226                                          QMessageBox::Yes);
227                 ::close(videofd);
228                 return ;
229             }
230         }
231         ::close(videofd);
232 
233 
234         if ((w != 0) && (h != 0)) {
235             capture = new VideoCapture(this,
236                                        devname, w, h);
237         } else {
238             QMessageBox::information(this,
239                                      "Title", "no resolution",
240                                      QMessageBox::Yes | QMessageBox::No,
241                                      QMessageBox::Yes);
242             return ;
243         }
244 
245         if (capture->Init() >= 0) {
246 
247             //  connect(capture, SIGNAL(SetShowImageData(uchar *, int , int )),\
248             //this, SLOT(&Camera::ShowImage(uchar *, int , int )));
249             capture->SetImg(label);
250             capture->setAutoDelete(true);
251             QThreadPool::globalInstance()->setMaxThreadCount(1);
252             QThreadPool::globalInstance()->setExpiryTimeout(2);
253             QThreadPool::globalInstance()->start(capture);
254         }
255 
256     }
257     //    QMetaObject::connectSlotsByName(this);
258 }
259 
260 
StopWorkThread()261 void Camera::StopWorkThread()
262 {
263     int i = 0;
264     int ret;
265     if(threadStatus) {
266 #if 1
267         capture->stop();
268         QThreadPool::globalInstance()->waitForDone(-1);
269 
270         if(capture->csi_type) {
271             enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
272             ret = ::ioctl(capture->fd, VIDIOC_STREAMOFF, &type);
273             if(ret < 0) {
274                 qDebug() << "VIDIOC_STREAMOFF" << strerror(errno);
275             }
276 
277             for (i = 0; i < BUFINFOR_NUM; i++) {
278                 for (int j = 0; j < capture->nplanes; j++) {
279                     ::munmap(capture->buffers[i].start[j], capture->buffers[i].length[j]);
280                 }
281             }
282         } else {
283             enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
284             ret = ::ioctl(capture->fd, VIDIOC_STREAMOFF, &type);
285             if(ret < 0) {
286                 qDebug() << "VIDIOC_STREAMOFF" << strerror(errno);
287             }
288 
289             for (i = 0; i < BUFINFOR_NUM; i++) {
290                 ::munmap(capture->buffers[i].start[0], capture->buffers[i].length[0]);
291             }
292         }
293 
294         ::free(capture->buffers);
295         ::close(capture->fd);
296 
297 #endif
298         threadStatus = 0;
299     }
300 }
301 
ShowImage(uchar * rgb,int width,int height)302 void Camera::ShowImage(uchar *rgb, int width, int height)
303 {
304     Q_UNUSED(rgb)
305     Q_UNUSED(width)
306     Q_UNUSED(height)
307     //    QImage *mage = new QImage(rgb, width,
308     //                              height, QImage::Format_RGB888);
309     //    QImage resultimg = mage->scaled(ui->label->size());
310     //    ui->label->setPixmap(QPixmap::fromImage(resultimg));
311 
312     //    delete mage;
313 }
314 
315