xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/imxx11/usbcamera/camera.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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