1 #include "camera.h"
2 #include "ui_camera.h"
3 #include <QDate>
4 #include <QTime>
5
6 extern "C"{
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <sys/mman.h>
11 #include <sys/types.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <string.h>
15 #include <time.h>
16 #include <sys/select.h>
17 #include <sys/time.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20 #include <jpeglib.h>
21 #include <linux/videodev2.h>
22 }
23
yuv422to420p(char * yuv422buf,char * yuv420pbuf,int width,int height)24 void yuv422to420p(char *yuv422buf, char *yuv420pbuf,
25 int width, int height)
26 {
27 char *src, *dest, *dest2;
28 int i, j;
29
30 src = yuv422buf;
31 dest = yuv420pbuf;
32 for (i = 0; i < width * height * 2; i++) {
33 if (i % 2 != 0) {
34 continue;
35 }
36 *dest++ = *(src + i);
37 }
38
39 src = yuv422buf;
40 dest = yuv420pbuf + width * height;
41 dest2 = dest + (width * height) / 4;
42 for (i = 0; i < height; i += 2) {
43 for (j = 1; j < width * 2; j += 4) {
44 *dest++ = *(src + i * width * 2 + j);
45 *dest2++ = *(src + i * width * 2 + j + 2);
46 }
47 }
48 }
49
convert_yuv_to_rgb_pixel(int y,int u,int v)50 int convert_yuv_to_rgb_pixel(int y, int u, int v)
51 {
52 unsigned int pixel32 = 0;
53 unsigned char *pixel = (unsigned char *)&pixel32;
54 int r, g, b;
55 r = y + (1.370705 * (v-128));
56 g = y - (0.698001 * (v-128)) - (0.337633 * (u-128));
57 b = y + (1.732446 * (u-128));
58 if(r > 255) r = 255;
59 if(g > 255) g = 255;
60 if(b > 255) b = 255;
61 if(r < 0) r = 0;
62 if(g < 0) g = 0;
63 if(b < 0) b = 0;
64 pixel[0] = r ;
65 pixel[1] = g ;
66 pixel[2] = b ;
67 return pixel32;
68 }
69
70
convert_yuv_to_rgb_buffer(unsigned char * yuv,unsigned char * rgb,unsigned int width,unsigned int height)71 int convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
72 {
73 unsigned int in, out = 0;
74 unsigned int pixel_16;
75 unsigned char pixel_24[3];
76 unsigned int pixel32;
77 int y0, u, y1, v;
78
79 for(in = 0; in < width * height * 2; in += 4)
80 {
81 pixel_16 =
82 yuv[in + 3] << 24 |
83 yuv[in + 2] << 16 |
84 yuv[in + 1] << 8 |
85 yuv[in + 0];
86 y0 = (pixel_16 & 0x000000ff);
87 u = (pixel_16 & 0x0000ff00) >> 8;
88 y1 = (pixel_16 & 0x00ff0000) >> 16;
89 v = (pixel_16 & 0xff000000) >> 24;
90 pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
91 pixel_24[0] = (pixel32 & 0x000000ff);
92 pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
93 pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
94 rgb[out++] = pixel_24[0];
95 rgb[out++] = pixel_24[1];
96 rgb[out++] = pixel_24[2];
97 pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
98 pixel_24[0] = (pixel32 & 0x000000ff);
99 pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
100 pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
101 rgb[out++] = pixel_24[0];
102 rgb[out++] = pixel_24[1];
103 rgb[out++] = pixel_24[2];
104 }
105 return 0;
106 }
107
camera_init()108 int camera::camera_init()
109 {
110 int ret=0,i=0,count=0;
111 struct v4l2_capability cap;
112 struct v4l2_fmtdesc fmtdesc;
113 struct v4l2_format format;
114 struct v4l2_requestbuffers reqbuf;
115 struct v4l2_buffer buf;
116
117 fmtdesc.index = 0;
118 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
119
120 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
121 ret = ::ioctl(fd, VIDIOC_G_FMT, &format);
122 if(ret < 0){
123 perror("VIDIOC_G_FMT");
124 exit(1);
125 }
126
127 printf("width:%d\n", format.fmt.pix.width);
128 printf("height:%d\n", format.fmt.pix.height);
129 printf("pixelformat:%x\n", format.fmt.pix.pixelformat);
130 printf("field:%x\n", format.fmt.pix.field);
131 printf("bytesperline:%d\n", format.fmt.pix.bytesperline);
132 printf("sizeimage:%d\n", format.fmt.pix.sizeimage);
133 printf("colorspace:%d\n", format.fmt.pix.colorspace);
134 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
135 format.fmt.pix.width = 640;
136 format.fmt.pix.height = 480;
137 format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
138
139 ret = ::ioctl(fd, VIDIOC_S_FMT, &format);
140 if(ret < 0){
141 fprintf(stderr, "Not support jepg");
142 perror("VIDIOC_S_FMT");
143 exit(1);
144 }
145 reqbuf.count = 3;
146 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
147 reqbuf.memory = V4L2_MEMORY_MMAP;
148 ret = ::ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
149 if(ret < 0){
150 perror("VIDIOC_REQBUFS");
151 exit(1);
152 }
153
154 bufinf = (struct bufinfor *)calloc(reqbuf.count, sizeof(struct bufinfor));
155 if(!bufinf){
156 perror("calloc");
157 exit(1);
158 }
159 for(count = 0; count < reqbuf.count; count++){
160 buf.index = count;
161 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
162 buf.memory = V4L2_MEMORY_MMAP;
163 ret = ::ioctl(fd, VIDIOC_QUERYBUF, &buf);
164 if(ret < 0){
165 perror("VIDIOC_REQBUFS");
166 exit(1);
167 }
168 bufinf[buf.index].length = buf.length;
169 bufinf[buf.index].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
170 if(!(bufinf[buf.index].start)){
171 perror("mmap");
172 exit(1);
173 }
174 }
175 for(i = 0; i < reqbuf.count; i++){
176 buf.index = i;
177 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
178 buf.memory = V4L2_MEMORY_MMAP;
179 ret = ::ioctl(fd, VIDIOC_QBUF, &buf);
180 if(ret < 0){
181 perror("VIDIOC_QBUF");
182 exit(1);
183 }
184 }
185 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
186 ret = ::ioctl(fd, VIDIOC_STREAMON, &type);
187 if(ret < 0){
188 perror("VIDIOC_STREAMON");
189 exit(1);
190 }
191
192 return 0;
193 }
194
camera(QWidget * parent)195 camera::camera(QWidget *parent) :
196 QMainWindow(parent),
197 ui(new Ui::camera)
198 {
199
200 char devname[32];
201 int i=0;
202 // struct v4l2_capability cap;
203 ui->setupUi(this);
204 while(i < 100)
205 {
206 sprintf(devname,"/dev/video%d",i++);
207
208 fd = ::open(devname,O_RDWR);
209 if(fd < 0)
210 {
211 continue;
212 }
213
214 ui->comboBox->addItem(QWidget::tr(devname));
215 ::close(fd);
216 }
217 }
218
~camera()219 camera::~camera()
220 {
221 free(bufinf);
222
223 ::close(fd);
224 delete ui;
225 }
moveEvent(QMoveEvent *)226 void camera::moveEvent(QMoveEvent *)
227 {
228 this->move(QPoint(0,0));
229 }
resizeEvent(QResizeEvent *)230 void camera::resizeEvent(QResizeEvent *)
231 {
232 this->showMaximized();
233 }
234
235
on_pushButton_2_clicked()236 void camera::on_pushButton_2_clicked()
237 {
238 take_photo();
239 }
240
241 static bool take = 0;
242
show_()243 void camera::show_()
244 {
245 int ret;
246 unsigned char *rgb=new unsigned char [640 * 480 *3];
247 struct v4l2_buffer buf;
248
249 fd_set readset;
250 FD_ZERO(&readset);
251 FD_SET(fd, &readset);
252 ret = select(fd + 1, &readset, NULL, NULL, NULL);
253 if(ret < 0){
254 perror("select");
255 exit(1);
256 }
257
258 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
259 buf.memory = V4L2_MEMORY_MMAP;
260 ret = ioctl(fd, VIDIOC_DQBUF, &buf);
261 if(ret < 0){
262 perror("VIDIOC_DQBUF");
263 exit(1);
264 }
265
266 convert_yuv_to_rgb_buffer((unsigned char *)bufinf[buf.index].start,rgb,640,480);
267 ret = ioctl(fd, VIDIOC_QBUF, &buf);
268 if(ret < 0){
269 perror("VIDIOC_QBUF");
270 exit(1);
271 }
272
273 QImage *mage = new QImage(rgb,640,480,QImage::Format_RGB888);
274 if (take == 1)
275 {
276 mage->save(tr("%1.jpg").arg("/root/IMG" + QDate::currentDate().toString("yyyyMMdd") + QTime::currentTime().toString("hhmmss")),"JPG");
277 take = 0;
278 }
279 QImage resultimg=mage->scaled(ui->label->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
280 ui->label->setPixmap(QPixmap::fromImage(resultimg));
281 delete mage;
282 delete rgb;
283
284 }
take_photo()285 void camera::take_photo()
286 {
287 take = 1;
288 }
289
on_comboBox_activated(const QString & arg1)290 void camera::on_comboBox_activated(const QString &arg1)
291 {
292 QString text=ui->comboBox->currentText();
293 QByteArray devtext=text.toLatin1();
294 char *devname=devtext.data();
295 //struct v4l2_capability cap;
296
297 fd = ::open(devname, O_RDWR);
298
299 if(fd < 0)
300 {
301 perror("open error");
302 }
303 camera::camera_init();
304 QTimer *timer;
305 timer=new QTimer();
306 timer->setInterval(100);
307 connect(timer,SIGNAL(timeout()),this,SLOT(show_()));
308 timer->start(100);
309 camera_flag=1;
310 }
311