21
21
#include "camera.h"
22
22
#include "device.h"
23
23
24
- int init_device (const char * dev_name , int * fd_ref , char * * driver_ref )
24
+ static int camera_init_device (const char * dev_name , int * fd_ref , char * * driver_ref )
25
25
{
26
26
* fd_ref = open (dev_name , O_RDWR );
27
27
if (* fd_ref < 0 )
@@ -43,7 +43,7 @@ int init_device(const char *dev_name, int *fd_ref, char **driver_ref)
43
43
return 0 ;
44
44
}
45
45
46
- int configure_format (const int fd , int * width_ref , int * height_ref , uint32_t * format_ref )
46
+ static int camera_configure_format (const int fd , int * width_ref , int * height_ref , uint32_t * format_ref )
47
47
{
48
48
struct v4l2_format fmt = {0 };
49
49
fmt .type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
@@ -80,7 +80,7 @@ int configure_format(const int fd, int *width_ref, int *height_ref, uint32_t *fo
80
80
return 0 ;
81
81
}
82
82
83
- int request_buffer (const int fd )
83
+ static int camera_request_buffer (const int fd )
84
84
{
85
85
struct v4l2_requestbuffers reqbuf = {0 };
86
86
reqbuf .count = 1 ;
@@ -96,7 +96,7 @@ int request_buffer(const int fd)
96
96
return 0 ;
97
97
}
98
98
99
- int query_buffer (const int fd , uint8_t * * buf_ref , struct v4l2_buffer * buf_info_ref , int * size_ref )
99
+ static int camera_query_buffer (const int fd , uint8_t * * buf_ref , struct v4l2_buffer * buf_info_ref )
100
100
{
101
101
buf_info_ref -> type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
102
102
buf_info_ref -> memory = V4L2_MEMORY_MMAP ;
@@ -115,12 +115,10 @@ int query_buffer(const int fd, uint8_t **buf_ref, struct v4l2_buffer *buf_info_r
115
115
return -1 ;
116
116
}
117
117
118
- * size_ref = buf_info_ref -> length ;
119
-
120
118
return 0 ;
121
119
}
122
120
123
- int capture_frame (const int fd , struct v4l2_buffer * buf_info )
121
+ static int camera_capture_frame (const int fd , struct v4l2_buffer * buf_info )
124
122
{
125
123
if (ioctl (fd , VIDIOC_QBUF , buf_info ))
126
124
{
@@ -147,41 +145,12 @@ int capture_frame(const int fd, struct v4l2_buffer *buf_info)
147
145
return 0 ;
148
146
}
149
147
150
- void yuyv_to_rgb (uint8_t * rgb_ref , const uint8_t * yuyv , const int width , const int height )
151
- {
152
- int frame_size = width * height * 2 ;
153
-
154
- for (int i = 0 , j = 0 ; i < frame_size ; i += 4 , j += 6 )
155
- {
156
- int Y0 = yuyv [i ];
157
- int U = yuyv [i + 1 ] - 128 ;
158
- int Y1 = yuyv [i + 2 ];
159
- int V = yuyv [i + 3 ] - 128 ;
160
-
161
- int R1 = Y0 + 1.140 * V ;
162
- int G1 = Y0 - 0.395 * U - 0.581 * V ;
163
- int B1 = Y0 + 2.032 * U ;
164
-
165
- int R2 = Y1 + 1.140 * V ;
166
- int G2 = Y1 - 0.395 * U - 0.581 * V ;
167
- int B2 = Y1 + 2.032 * U ;
168
-
169
- rgb_ref [j + 0 ] = (uint8_t )(R1 < 0 ? 0 : (R1 > 255 ? 255 : R1 ));
170
- rgb_ref [j + 1 ] = (uint8_t )(G1 < 0 ? 0 : (G1 > 255 ? 255 : G1 ));
171
- rgb_ref [j + 2 ] = (uint8_t )(B1 < 0 ? 0 : (B1 > 255 ? 255 : B1 ));
172
- rgb_ref [j + 3 ] = (uint8_t )(R2 < 0 ? 0 : (R2 > 255 ? 255 : R2 ));
173
- rgb_ref [j + 4 ] = (uint8_t )(G2 < 0 ? 0 : (G2 > 255 ? 255 : G2 ));
174
- rgb_ref [j + 5 ] = (uint8_t )(B2 < 0 ? 0 : (B2 > 255 ? 255 : B2 ));
175
- }
176
- }
177
-
178
- void rgb_to_jpeg (uint8_t * * jpeg_ref , unsigned long * size_ref , const uint8_t * rgb , const int width , const int height )
148
+ static int camera_yuyv_to_jpeg (uint8_t * * jpeg_ref , unsigned long * size_ref , const uint8_t * yuyv , const int width , const int height )
179
149
{
180
150
struct jpeg_compress_struct cinfo ;
181
151
struct jpeg_error_mgr jerr ;
182
152
183
153
JSAMPROW row_pointer [1 ];
184
- int row_stride ;
185
154
186
155
cinfo .err = jpeg_std_error (& jerr );
187
156
jpeg_create_compress (& cinfo );
@@ -191,108 +160,113 @@ void rgb_to_jpeg(uint8_t **jpeg_ref, unsigned long *size_ref, const uint8_t *rgb
191
160
cinfo .image_width = width ;
192
161
cinfo .image_height = height ;
193
162
cinfo .input_components = 3 ;
194
- cinfo .in_color_space = JCS_RGB ;
163
+ cinfo .in_color_space = JCS_YCbCr ;
195
164
196
165
jpeg_set_defaults (& cinfo );
197
- jpeg_set_quality (& cinfo , 75 , TRUE);
166
+ jpeg_set_quality (& cinfo , 100 , TRUE);
198
167
199
168
jpeg_start_compress (& cinfo , TRUE);
200
169
201
- row_stride = width * 3 ;
170
+ uint8_t * row_buffer = (uint8_t * )malloc (width * 3 * sizeof (uint8_t ));
171
+ if (!row_buffer )
172
+ {
173
+ fprintf (stderr , "Memory allocation failed\n" );
174
+ jpeg_destroy_compress (& cinfo );
175
+ return -1 ;
176
+ }
202
177
203
- while (cinfo .next_scanline < cinfo . image_height )
178
+ while (cinfo .next_scanline < height )
204
179
{
205
- row_pointer [0 ] = (JSAMPROW )& rgb [cinfo .next_scanline * row_stride ];
180
+ const uint32_t offset = cinfo .next_scanline * width * 2 ;
181
+ for (uint32_t i = 0 , j = 0 ; i < width * 2 ; i += 4 , j += 6 )
182
+ {
183
+ row_buffer [j + 0 ] = yuyv [offset + i + 0 ];
184
+ row_buffer [j + 1 ] = yuyv [offset + i + 1 ];
185
+ row_buffer [j + 2 ] = yuyv [offset + i + 3 ];
186
+ row_buffer [j + 3 ] = yuyv [offset + i + 2 ];
187
+ row_buffer [j + 4 ] = yuyv [offset + i + 1 ];
188
+ row_buffer [j + 5 ] = yuyv [offset + i + 3 ];
189
+ }
190
+ row_pointer [0 ] = row_buffer ;
206
191
jpeg_write_scanlines (& cinfo , row_pointer , 1 );
207
192
}
208
193
209
194
jpeg_finish_compress (& cinfo );
210
195
jpeg_destroy_compress (& cinfo );
196
+
197
+ free (row_buffer );
198
+
199
+ return 0 ;
211
200
}
212
201
213
202
int camera_capture_jpeg (uint8_t * * buffer_ref , unsigned long * size_ref , const char * video_device )
214
203
{
215
204
int fd = -1 ;
216
205
uint8_t * raw_buffer = NULL ;
217
- int raw_size = 0 ;
218
-
219
- void cleanup ()
220
- {
221
- if (fd >= 0 )
222
- {
223
- close (fd );
224
- }
225
- if (raw_buffer != NULL )
226
- {
227
- munmap (raw_buffer , raw_size );
228
- }
229
- }
230
206
231
207
int ret = 0 ;
232
- char * driver_str ;
208
+ char * driver_str = NULL ;
233
209
234
- fprintf (stderr , "Opening device: %s\n" , video_device );
235
- ret = init_device (video_device , & fd , & driver_str );
210
+ int width , height = 0 ;
211
+ uint32_t format = 0 ;
212
+
213
+ struct v4l2_buffer buf_info = {0 };
214
+
215
+ uint8_t * jpeg = NULL ;
216
+
217
+ ret = camera_init_device (video_device , & fd , & driver_str );
236
218
if (ret < 0 )
237
219
{
238
- cleanup ();
239
- return -1 ;
220
+ goto cleanup ;
240
221
}
241
222
242
- int width , height ;
243
- uint32_t format ;
244
- ret = configure_format (fd , & width , & height , & format );
223
+ ret = camera_configure_format (fd , & width , & height , & format );
245
224
if (ret < 0 )
246
225
{
247
- cleanup ();
248
- return -1 ;
226
+ goto cleanup ;
249
227
}
250
228
251
229
fprintf (stderr , "Driver: %s, Resolution: %dx%d, Format: %c%c%c%c\n" , driver_str , width , height ,
252
230
(char )((format >> 0 ) & 0xFF ), (char )((format >> 8 ) & 0xFF ), (char )((format >> 16 ) & 0xFF ), (char )((format >> 24 ) & 0xFF ));
253
231
free (driver_str );
254
232
255
- ret = request_buffer (fd );
233
+ ret = camera_request_buffer (fd );
256
234
if (ret < 0 )
257
235
{
258
- cleanup ();
259
- return -1 ;
236
+ goto cleanup ;
260
237
}
261
238
262
- struct v4l2_buffer buf_info = {0 };
263
-
264
- ret = query_buffer (fd , & raw_buffer , & buf_info , & raw_size );
239
+ ret = camera_query_buffer (fd , & raw_buffer , & buf_info );
265
240
if (ret < 0 )
266
241
{
267
- cleanup ();
268
- return -1 ;
242
+ goto cleanup ;
269
243
}
270
244
271
- capture_frame (fd , & buf_info );
245
+ camera_capture_frame (fd , & buf_info );
272
246
273
- uint8_t * jpeg = NULL ;
274
247
switch (format )
275
248
{
276
249
case V4L2_PIX_FMT_YUYV :
277
- {
278
- uint8_t * rgb = (uint8_t * )malloc (width * height * 3 );
279
-
280
- yuyv_to_rgb (rgb , raw_buffer , width , height );
281
- rgb_to_jpeg (& jpeg , size_ref , rgb , width , height );
282
-
283
- free (rgb );
250
+ camera_yuyv_to_jpeg (& jpeg , size_ref , raw_buffer , width , height );
284
251
break ;
285
- }
286
252
287
253
default :
288
254
fprintf (stderr , "Unsupported format\n" );
289
- cleanup () ;
290
- return -1 ;
255
+ ret = -1 ;
256
+ goto cleanup ;
291
257
}
292
258
293
259
* buffer_ref = jpeg ;
294
260
295
- cleanup ();
261
+ cleanup :
262
+ if (fd >= 0 )
263
+ {
264
+ close (fd );
265
+ }
266
+ if (raw_buffer != NULL )
267
+ {
268
+ munmap (raw_buffer , buf_info .length );
269
+ }
296
270
297
- return 0 ;
271
+ return ret ;
298
272
}
0 commit comments