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