1 /******************************************************************************
2     Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
17 
18 #pragma once
19 
20 #include "media-io-defs.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 struct video_frame;
27 
28 /* Base video output component.  Use this to create a video output track. */
29 
30 struct video_output;
31 typedef struct video_output video_t;
32 
33 enum video_format {
34 	VIDEO_FORMAT_NONE,
35 
36 	/* planar 420 format */
37 	VIDEO_FORMAT_I420, /* three-plane */
38 	VIDEO_FORMAT_NV12, /* two-plane, luma and packed chroma */
39 
40 	/* packed 422 formats */
41 	VIDEO_FORMAT_YVYU,
42 	VIDEO_FORMAT_YUY2, /* YUYV */
43 	VIDEO_FORMAT_UYVY,
44 
45 	/* packed uncompressed formats */
46 	VIDEO_FORMAT_RGBA,
47 	VIDEO_FORMAT_BGRA,
48 	VIDEO_FORMAT_BGRX,
49 	VIDEO_FORMAT_Y800, /* grayscale */
50 
51 	/* planar 4:4:4 */
52 	VIDEO_FORMAT_I444,
53 
54 	/* more packed uncompressed formats */
55 	VIDEO_FORMAT_BGR3,
56 
57 	/* planar 4:2:2 */
58 	VIDEO_FORMAT_I422,
59 
60 	/* planar 4:2:0 with alpha */
61 	VIDEO_FORMAT_I40A,
62 
63 	/* planar 4:2:2 with alpha */
64 	VIDEO_FORMAT_I42A,
65 
66 	/* planar 4:4:4 with alpha */
67 	VIDEO_FORMAT_YUVA,
68 
69 	/* packed 4:4:4 with alpha */
70 	VIDEO_FORMAT_AYUV,
71 };
72 
73 enum video_colorspace {
74 	VIDEO_CS_DEFAULT,
75 	VIDEO_CS_601,
76 	VIDEO_CS_709,
77 	VIDEO_CS_SRGB,
78 };
79 
80 enum video_range_type {
81 	VIDEO_RANGE_DEFAULT,
82 	VIDEO_RANGE_PARTIAL,
83 	VIDEO_RANGE_FULL
84 };
85 
86 struct video_data {
87 	uint8_t *data[MAX_AV_PLANES];
88 	uint32_t linesize[MAX_AV_PLANES];
89 	uint64_t timestamp;
90 };
91 
92 struct video_output_info {
93 	const char *name;
94 
95 	enum video_format format;
96 	uint32_t fps_num;
97 	uint32_t fps_den;
98 	uint32_t width;
99 	uint32_t height;
100 	size_t cache_size;
101 
102 	enum video_colorspace colorspace;
103 	enum video_range_type range;
104 };
105 
format_is_yuv(enum video_format format)106 static inline bool format_is_yuv(enum video_format format)
107 {
108 	switch (format) {
109 	case VIDEO_FORMAT_I420:
110 	case VIDEO_FORMAT_NV12:
111 	case VIDEO_FORMAT_I422:
112 	case VIDEO_FORMAT_YVYU:
113 	case VIDEO_FORMAT_YUY2:
114 	case VIDEO_FORMAT_UYVY:
115 	case VIDEO_FORMAT_I444:
116 	case VIDEO_FORMAT_I40A:
117 	case VIDEO_FORMAT_I42A:
118 	case VIDEO_FORMAT_YUVA:
119 	case VIDEO_FORMAT_AYUV:
120 		return true;
121 	case VIDEO_FORMAT_NONE:
122 	case VIDEO_FORMAT_RGBA:
123 	case VIDEO_FORMAT_BGRA:
124 	case VIDEO_FORMAT_BGRX:
125 	case VIDEO_FORMAT_Y800:
126 	case VIDEO_FORMAT_BGR3:
127 		return false;
128 	}
129 
130 	return false;
131 }
132 
get_video_format_name(enum video_format format)133 static inline const char *get_video_format_name(enum video_format format)
134 {
135 	switch (format) {
136 	case VIDEO_FORMAT_I420:
137 		return "I420";
138 	case VIDEO_FORMAT_NV12:
139 		return "NV12";
140 	case VIDEO_FORMAT_I422:
141 		return "I422";
142 	case VIDEO_FORMAT_YVYU:
143 		return "YVYU";
144 	case VIDEO_FORMAT_YUY2:
145 		return "YUY2";
146 	case VIDEO_FORMAT_UYVY:
147 		return "UYVY";
148 	case VIDEO_FORMAT_RGBA:
149 		return "RGBA";
150 	case VIDEO_FORMAT_BGRA:
151 		return "BGRA";
152 	case VIDEO_FORMAT_BGRX:
153 		return "BGRX";
154 	case VIDEO_FORMAT_I444:
155 		return "I444";
156 	case VIDEO_FORMAT_Y800:
157 		return "Y800";
158 	case VIDEO_FORMAT_BGR3:
159 		return "BGR3";
160 	case VIDEO_FORMAT_I40A:
161 		return "I40A";
162 	case VIDEO_FORMAT_I42A:
163 		return "I42A";
164 	case VIDEO_FORMAT_YUVA:
165 		return "YUVA";
166 	case VIDEO_FORMAT_AYUV:
167 		return "AYUV";
168 	case VIDEO_FORMAT_NONE:;
169 	}
170 
171 	return "None";
172 }
173 
get_video_colorspace_name(enum video_colorspace cs)174 static inline const char *get_video_colorspace_name(enum video_colorspace cs)
175 {
176 	switch (cs) {
177 	case VIDEO_CS_DEFAULT:
178 	case VIDEO_CS_709:
179 		return "709";
180 	case VIDEO_CS_SRGB:
181 		return "sRGB";
182 	case VIDEO_CS_601:;
183 	}
184 
185 	return "601";
186 }
187 
188 static inline enum video_range_type
resolve_video_range(enum video_format format,enum video_range_type range)189 resolve_video_range(enum video_format format, enum video_range_type range)
190 {
191 	if (range == VIDEO_RANGE_DEFAULT) {
192 		range = format_is_yuv(format) ? VIDEO_RANGE_PARTIAL
193 					      : VIDEO_RANGE_FULL;
194 	}
195 
196 	return range;
197 }
198 
get_video_range_name(enum video_format format,enum video_range_type range)199 static inline const char *get_video_range_name(enum video_format format,
200 					       enum video_range_type range)
201 {
202 	range = resolve_video_range(format, range);
203 	return range == VIDEO_RANGE_FULL ? "Full" : "Partial";
204 }
205 
206 enum video_scale_type {
207 	VIDEO_SCALE_DEFAULT,
208 	VIDEO_SCALE_POINT,
209 	VIDEO_SCALE_FAST_BILINEAR,
210 	VIDEO_SCALE_BILINEAR,
211 	VIDEO_SCALE_BICUBIC,
212 };
213 
214 struct video_scale_info {
215 	enum video_format format;
216 	uint32_t width;
217 	uint32_t height;
218 	enum video_range_type range;
219 	enum video_colorspace colorspace;
220 };
221 
222 EXPORT enum video_format video_format_from_fourcc(uint32_t fourcc);
223 
224 EXPORT bool video_format_get_parameters(enum video_colorspace color_space,
225 					enum video_range_type range,
226 					float matrix[16], float min_range[3],
227 					float max_range[3]);
228 
229 #define VIDEO_OUTPUT_SUCCESS 0
230 #define VIDEO_OUTPUT_INVALIDPARAM -1
231 #define VIDEO_OUTPUT_FAIL -2
232 
233 EXPORT int video_output_open(video_t **video, struct video_output_info *info);
234 EXPORT void video_output_close(video_t *video);
235 
236 EXPORT bool
237 video_output_connect(video_t *video, const struct video_scale_info *conversion,
238 		     void (*callback)(void *param, struct video_data *frame),
239 		     void *param);
240 EXPORT void video_output_disconnect(video_t *video,
241 				    void (*callback)(void *param,
242 						     struct video_data *frame),
243 				    void *param);
244 
245 EXPORT bool video_output_active(const video_t *video);
246 
247 EXPORT const struct video_output_info *
248 video_output_get_info(const video_t *video);
249 EXPORT bool video_output_lock_frame(video_t *video, struct video_frame *frame,
250 				    int count, uint64_t timestamp);
251 EXPORT void video_output_unlock_frame(video_t *video);
252 EXPORT uint64_t video_output_get_frame_time(const video_t *video);
253 EXPORT void video_output_stop(video_t *video);
254 EXPORT bool video_output_stopped(video_t *video);
255 
256 EXPORT enum video_format video_output_get_format(const video_t *video);
257 EXPORT uint32_t video_output_get_width(const video_t *video);
258 EXPORT uint32_t video_output_get_height(const video_t *video);
259 EXPORT double video_output_get_frame_rate(const video_t *video);
260 
261 EXPORT uint32_t video_output_get_skipped_frames(const video_t *video);
262 EXPORT uint32_t video_output_get_total_frames(const video_t *video);
263 
264 extern void video_output_inc_texture_encoders(video_t *video);
265 extern void video_output_dec_texture_encoders(video_t *video);
266 extern void video_output_inc_texture_frames(video_t *video);
267 extern void video_output_inc_texture_skipped_frames(video_t *video);
268 
269 #ifdef __cplusplus
270 }
271 #endif
272