1 /*****************************************************************************
2 #                                                                            #
3 #    uStreamer - Lightweight and fast MJPG-HTTP streamer.                    #
4 #                                                                            #
5 #    Copyright (C) 2018-2021  Maxim Devaev <mdevaev@gmail.com>               #
6 #                                                                            #
7 #    This program is free software: you can redistribute it and/or modify    #
8 #    it under the terms of the GNU General Public License as published by    #
9 #    the Free Software Foundation, either version 3 of the License, or       #
10 #    (at your option) any later version.                                     #
11 #                                                                            #
12 #    This program is distributed in the hope that it will be useful,         #
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of          #
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           #
15 #    GNU General Public License for more details.                            #
16 #                                                                            #
17 #    You should have received a copy of the GNU General Public License       #
18 #    along with this program.  If not, see <https://www.gnu.org/licenses/>.  #
19 #                                                                            #
20 *****************************************************************************/
21 
22 
23 #pragma once
24 
25 #include <stdlib.h>
26 #include <stddef.h>
27 #include <stdint.h>
28 #include <stdbool.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <assert.h>
35 
36 #include <sys/select.h>
37 #include <sys/mman.h>
38 #include <sys/time.h>
39 
40 #include <pthread.h>
41 #include <linux/videodev2.h>
42 #include <linux/v4l2-controls.h>
43 #ifdef WITH_OMX
44 #	include <interface/vcsm/user-vcsm.h>
45 #endif
46 
47 #include "../libs/tools.h"
48 #include "../libs/logging.h"
49 #include "../libs/threading.h"
50 #include "../libs/frame.h"
51 
52 #include "xioctl.h"
53 
54 
55 #define VIDEO_MIN_WIDTH		((unsigned)160)
56 #define VIDEO_MAX_WIDTH		((unsigned)10240)
57 
58 #define VIDEO_MIN_HEIGHT	((unsigned)120)
59 #define VIDEO_MAX_HEIGHT	((unsigned)4320)
60 
61 #define VIDEO_MAX_FPS		((unsigned)120)
62 
63 #define STANDARD_UNKNOWN	V4L2_STD_UNKNOWN
64 #define STANDARDS_STR		"PAL, NTSC, SECAM"
65 
66 #define FORMAT_UNKNOWN	-1
67 #define FORMATS_STR		"YUYV, UYVY, RGB565, RGB24, MJPEG, JPEG"
68 
69 #define IO_METHOD_UNKNOWN	-1
70 #define IO_METHODS_STR		"MMAP, USERPTR"
71 
72 
73 typedef struct {
74 	frame_s raw;
75 
76 	struct v4l2_buffer buf_info;
77 
78 #	ifdef WITH_OMX
79 	int dma_fd;
80 	int vcsm_handle;
81 #	endif
82 
83 	pthread_mutex_t grabbed_mutex;
84 	bool			grabbed;
85 } hw_buffer_s;
86 
87 typedef struct {
88 	int			fd;
89 	unsigned	width;
90 	unsigned	height;
91 	unsigned	format;
92 	unsigned	stride;
93 	unsigned	hw_fps;
94 	unsigned	jpeg_quality;
95 	size_t		raw_size;
96 	unsigned	n_bufs;
97 	hw_buffer_s	*hw_bufs;
98 	bool		capturing;
99 	bool		persistent_timeout_reported;
100 } device_runtime_s;
101 
102 typedef enum {
103 	CTL_MODE_NONE = 0,
104 	CTL_MODE_VALUE,
105 	CTL_MODE_AUTO,
106 	CTL_MODE_DEFAULT,
107 } control_mode_e;
108 
109 typedef struct {
110 	control_mode_e	mode;
111 	int				value;
112 } control_s;
113 
114 typedef struct {
115 	control_s brightness;
116 	control_s contrast;
117 	control_s saturation;
118 	control_s hue;
119 	control_s gamma;
120 	control_s sharpness;
121 	control_s backlight_compensation;
122 	control_s white_balance;
123 	control_s gain;
124 	control_s color_effect;
125 	control_s rotate;
126 	control_s flip_vertical;
127 	control_s flip_horizontal;
128 } controls_s;
129 
130 typedef struct {
131 	char				*path;
132 	unsigned			input;
133 	unsigned			width;
134 	unsigned			height;
135 	unsigned			format;
136 	unsigned			jpeg_quality;
137 	v4l2_std_id			standard;
138 	enum v4l2_memory	io_method;
139 	bool				dv_timings;
140 	unsigned			n_bufs;
141 	unsigned			desired_fps;
142 	size_t				min_frame_size;
143 	bool				persistent;
144 	unsigned			timeout;
145 
146 	controls_s ctl;
147 
148 	device_runtime_s *run;
149 } device_s;
150 
151 
152 device_s *device_init(void);
153 void device_destroy(device_s *dev);
154 
155 int device_parse_format(const char *str);
156 v4l2_std_id device_parse_standard(const char *str);
157 int device_parse_io_method(const char *str);
158 
159 int device_open(device_s *dev);
160 void device_close(device_s *dev);
161 
162 #ifdef WITH_OMX
163 int device_export_to_vcsm(device_s *dev);
164 #endif
165 int device_switch_capturing(device_s *dev, bool enable);
166 int device_select(device_s *dev, bool *has_read, bool *has_write, bool *has_error);
167 int device_grab_buffer(device_s *dev, hw_buffer_s **hw);
168 int device_release_buffer(device_s *dev, hw_buffer_s *hw);
169 int device_consume_event(device_s *dev);
170