UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
scale.c File Reference
#include <stdlib.h>
#include <pthread.h>
#include "debug.h"
#include "lib_common.h"
#include "gl_context.h"
#include "video.h"
#include "video_display.h"
#include "vo_postprocess.h"
Include dependency graph for scale.c:

Go to the source code of this file.

Classes

struct  state_scale
 

Functions

 REGISTER_MODULE (scale, &vo_pp_scale_info, LIBRARY_CLASS_VIDEO_POSTPROCESS, VO_PP_ABI_VERSION)
 
static void scale_done (void *state)
 
static void scale_get_out_desc (void *state, struct video_desc *out, int *in_display_mode, int *out_frames)
 
static bool scale_get_property (void *state, int property, void *val, size_t *len)
 
static struct video_frame * scale_getf (void *state)
 
static void * scale_init (const char *config)
 
static bool scale_postprocess (void *state, struct video_frame *in, struct video_frame *out, int req_pitch)
 
static bool scale_reconfigure (void *state, struct video_desc desc)
 
static void usage ()
 

Variables

static const struct vo_postprocess_info vo_pp_scale_info
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file scale.c.

Function Documentation

◆ REGISTER_MODULE()

REGISTER_MODULE ( scale ,
& vo_pp_scale_info,
LIBRARY_CLASS_VIDEO_POSTPROCESS ,
VO_PP_ABI_VERSION  )

◆ scale_done()

static void scale_done ( void * state)
static

Definition at line 309 of file scale.c.

310{
311 struct state_scale *s = (struct state_scale *) state;
312
313 glDeleteTextures(1, &s->tex_input);
314 glDeleteTextures(1, &s->tex_output);
315 glDeleteFramebuffers(1, &s->fbo);
316
317 free(s->in->tiles[0].data);
318
319 vf_free(s->in);
320
322
323 free(state);
324}
void ** state
void vf_free(struct video_frame *buf)
Frees video_frame structure.
void destroy_gl_context(struct gl_context *context)
Definition gl_context.c:223
struct gl_context context
Definition scale.c:56
GLuint fbo
Definition scale.c:61
GLuint tex_output
Definition scale.c:60
struct video_frame * in
Definition scale.c:55
GLuint tex_input
Definition scale.c:59
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345

References state_scale::context, tile::data, destroy_gl_context(), state_scale::fbo, state_scale::in, state, state_scale::tex_input, state_scale::tex_output, video_frame::tiles, and vf_free().

Here is the call graph for this function:

◆ scale_get_out_desc()

static void scale_get_out_desc ( void * state,
struct video_desc * out,
int * in_display_mode,
int * out_frames )
static

Definition at line 326 of file scale.c.

327{
328 struct state_scale *s = (struct state_scale *) state;
329
330 out->width = s->scaled_width;
331 out->height = s->scaled_height;
332 out->color_spec = s->in->color_spec;
333 out->interlacing = s->in->interlacing;
334 out->fps = s->in->fps;
335 out->tile_count = 1;
336
337 *in_display_mode = DISPLAY_PROPERTY_VIDEO_MERGED;
338 *out_frames = 1;
339}
@ DISPLAY_PROPERTY_VIDEO_MERGED
monolithic framebuffer
int scaled_width
Definition scale.c:58
int scaled_height
Definition scale.c:58
unsigned int tile_count
Definition types.h:185
codec_t color_spec
Definition types.h:182
enum interlacing_t interlacing
Definition types.h:184
double fps
Definition types.h:183
unsigned int width
width of every tile (!)
Definition types.h:179
unsigned int height
height of every tile (!)
Definition types.h:180
enum interlacing_t interlacing
Definition types.h:307
double fps
Definition types.h:308
codec_t color_spec
Definition types.h:306

References video_desc::color_spec, video_frame::color_spec, DISPLAY_PROPERTY_VIDEO_MERGED, video_desc::fps, video_frame::fps, video_desc::height, state_scale::in, video_desc::interlacing, video_frame::interlacing, state_scale::scaled_height, state_scale::scaled_width, state, video_desc::tile_count, and video_desc::width.

◆ scale_get_property()

static bool scale_get_property ( void * state,
int property,
void * val,
size_t * len )
static

Definition at line 64 of file scale.c.

65{
66 bool ret = false;
67 codec_t supported[] = {UYVY, RGBA};
68
70
71 switch(property) {
73 if(*len < (int) sizeof(supported)) {
74 fprintf(stderr, "Scale postprocessor query little space.\n");
75 *len = 0;
76 } else {
77 memcpy(val, &supported, sizeof(supported));
78 *len = sizeof(supported);
79 }
80 ret = true;
81 break;
82 }
83
84 return ret;
85}
#define UNUSED(x)
int void * val
int void size_t * len
int property
codec_t
Definition types.h:65
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
#define VO_PP_PROPERTY_CODECS

References len, property, RGBA, state, UNUSED, UYVY, val, and VO_PP_PROPERTY_CODECS.

◆ scale_getf()

static struct video_frame * scale_getf ( void * state)
static

Definition at line 223 of file scale.c.

224{
225 struct state_scale *s = (struct state_scale *) state;
226
227 return s->in;
228}

References state_scale::in, and state.

◆ scale_init()

static void * scale_init ( const char * config)
static

Definition at line 93 of file scale.c.

93 {
94 char *save_ptr = NULL;
95 char *ptr;
96
97 if (strcmp(config, "help") == 0) {
98 usage();
99 return NULL;
100 }
101
102 char *tmp = strdup(config);
103 assert(tmp != NULL);
104
105 struct state_scale *s = (struct state_scale *)
106 calloc(1, sizeof(struct state_scale));
107 assert(s != NULL);
108
109 ptr = strtok_r(tmp, ":", &save_ptr);
110 if (ptr != NULL) {
111 s->scaled_width = atoi(ptr);
112 }
113 ptr = strtok_r(NULL, ":", &save_ptr);
114 if (ptr != NULL) {
115 s->scaled_height = atoi(ptr);
116 }
117 if (s->scaled_width <= 0 || s->scaled_height <= 0) {
118 fprintf(stderr, "Scale postprocessor incorrect usage.\n");
119 usage();
120 free(s);
121 free(tmp);
122 return NULL;
123 }
124
125 free(tmp);
126
127 s->in = NULL;
128
131
132 glEnable(GL_TEXTURE_2D);
133
134 glGenTextures(1, &s->tex_input);
135 glBindTexture(GL_TEXTURE_2D, s->tex_input);
136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
140
141 glGenTextures(1, &s->tex_output);
142 glBindTexture(GL_TEXTURE_2D, s->tex_input);
143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
147
148 glGenFramebuffers(1, &s->fbo);
149
150 return s;
151}
bool init_gl_context(struct gl_context *context, int which)
initializes specified OpenGL context
Definition gl_context.c:69
void gl_context_make_current(struct gl_context *context)
Definition gl_context.c:236
#define GL_CONTEXT_LEGACY
Definition gl_context.h:73
static void usage()
Definition scale.c:87

References state_scale::context, state_scale::fbo, GL_CONTEXT_LEGACY, gl_context_make_current(), state_scale::in, init_gl_context(), state_scale::scaled_height, state_scale::scaled_width, state_scale::tex_input, state_scale::tex_output, and usage().

Here is the call graph for this function:

◆ scale_postprocess()

static bool scale_postprocess ( void * state,
struct video_frame * in,
struct video_frame * out,
int req_pitch )
static

Definition at line 230 of file scale.c.

231{
232 struct state_scale *s = (struct state_scale *) state;
233 int i;
234 int width, height;
235
236 int src_linesize = vc_get_linesize(out->tiles[0].width, out->color_spec);
237
238 char *tmp_data = NULL;
239
240 if(req_pitch != src_linesize) {
241 tmp_data = malloc(src_linesize *
242 out->tiles[0].height);
243 }
244
246
247 for(i = 0; i < (int) in->tile_count; ++i) {
248 struct tile *in_tile = vf_get_tile(s->in, i);
249
250 glBindTexture(GL_TEXTURE_2D, s->tex_input);
251 width = in_tile->width;
252 height = in_tile->height;
253 if(s->in->color_spec == UYVY) {
254 width /= 2;
255 }
256 if(s->in->interlacing == INTERLACED_MERGED) {
257 width *= 2;
258 height /= 2;
259 }
260 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
261 GL_RGBA, GL_UNSIGNED_BYTE, in_tile->data);
262
263 glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
264 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, s->tex_output, 0);
265
266 width = s->scaled_width;
268 if(s->in->color_spec == UYVY) {
269 width /= 2;
270 }
271 if(s->in->interlacing == INTERLACED_MERGED) {
272 width *= 2;
273 height /= 2;
274 }
275 glViewport(0, 0, width, height);
276 glBindTexture(GL_TEXTURE_2D, s->tex_input);
277
278 glClearColor(1,0,0,1);
279 glClear(GL_COLOR_BUFFER_BIT);
280
281 glBegin(GL_QUADS);
282 glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
283 glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
284 glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
285 glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
286 glEnd();
287
288 glBindTexture(GL_TEXTURE_2D, s->tex_output);
289 if(tmp_data) { /* we need to change pitch */
290 int y;
291 glReadPixels(0, 0, width , height, GL_RGBA, GL_UNSIGNED_BYTE, tmp_data);
292 char *src = tmp_data;
293 char *dst = out->tiles[i].data;
294 for (y = 0; y < (int) out->tiles[i].height; y += 1) {
295 memcpy(dst, src, src_linesize);
296 dst += req_pitch;
297 src += src_linesize;
298 }
299 } else {
300 glReadPixels(0, 0, width , height, GL_RGBA, GL_UNSIGNED_BYTE, out->tiles[i].data);
301 }
302 }
303
304 free(tmp_data);
305
306 return true;
307}
int vc_get_linesize(unsigned int width, codec_t codec)
Struct tile is an area of video_frame.
Definition types.h:279
unsigned int width
Definition types.h:280
unsigned int height
Definition types.h:281
unsigned int tile_count
Definition types.h:344
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
Definition types.h:167
struct tile * vf_get_tile(struct video_frame *buf, int pos)
Returns pointer to n-th tile from video frame Equivalent to &video_frame::tiles[pos].

References video_frame::color_spec, state_scale::context, tile::data, state_scale::fbo, gl_context_make_current(), tile::height, state_scale::in, INTERLACED_MERGED, video_frame::interlacing, state_scale::scaled_height, state_scale::scaled_width, state, state_scale::tex_input, state_scale::tex_output, video_frame::tile_count, video_frame::tiles, UYVY, vc_get_linesize(), vf_get_tile(), and tile::width.

Here is the call graph for this function:

◆ scale_reconfigure()

static bool scale_reconfigure ( void * state,
struct video_desc desc )
static

Definition at line 154 of file scale.c.

155{
156 struct state_scale *s = (struct state_scale *) state;
157 struct tile *in_tile;
158 int i;
159 int width, height;
160
161 if(s->in) {
162 int i;
163 for(i = 0; i < (int) s->in->tile_count; ++i) {
164 free(s->in->tiles[i].data);
165 }
166 vf_free(s->in);
167 }
168
170
171
173 s->in->fps = desc.fps;
175
176 for(i = 0; i < (int) desc.tile_count; ++i) {
177 in_tile = vf_get_tile(s->in, i);
178 in_tile->width = desc.width;
179 in_tile->height = desc.height;
180
181 in_tile->data_len =
183 in_tile->data = malloc(in_tile->data_len);
184 }
185
186 assert(desc.tile_count >= 1);
187 in_tile = vf_get_tile(s->in, 0);
188
190
191 glBindTexture(GL_TEXTURE_2D, s->tex_input);
192 width = in_tile->width;
193 height = in_tile->height;
194 if(s->in->color_spec == UYVY) {
195 width /= 2;
196 }
197 if(s->in->interlacing == INTERLACED_MERGED) {
198 width *= 2;
199 height /= 2;
200 }
201 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
202 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
203
204
205
206 glBindTexture(GL_TEXTURE_2D, s->tex_output);
207 width = s->scaled_width;
209 if(s->in->color_spec == UYVY) {
210 width /= 2;
211 }
212 if(s->in->interlacing == INTERLACED_MERGED) {
213 width *= 2;
214 height /= 2;
215 }
216 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
217 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
218
219
220 return true;
221}
struct video_desc desc
struct video_frame * vf_alloc(int count)
Allocates blank video frame.
unsigned int data_len
length of the data
Definition types.h:288

References video_desc::color_spec, video_frame::color_spec, state_scale::context, tile::data, tile::data_len, desc, video_desc::fps, video_frame::fps, gl_context_make_current(), tile::height, video_desc::height, state_scale::in, INTERLACED_MERGED, video_desc::interlacing, video_frame::interlacing, state_scale::scaled_height, state_scale::scaled_width, state, state_scale::tex_input, state_scale::tex_output, video_desc::tile_count, video_frame::tile_count, video_frame::tiles, UYVY, vc_get_linesize(), vf_alloc(), vf_free(), vf_get_tile(), tile::width, and video_desc::width.

Here is the call graph for this function:

◆ usage()

static void usage ( void )
static

Definition at line 87 of file scale.c.

88{
89 printf("Scale postprocessor settings:\n");
90 printf("\t-p scale:width:height\n");
91}

Referenced by scale_init().

Variable Documentation

◆ vo_pp_scale_info

const struct vo_postprocess_info vo_pp_scale_info
static
Initial value:
= {
}
static bool scale_postprocess(void *state, struct video_frame *in, struct video_frame *out, int req_pitch)
Definition scale.c:230
static bool scale_get_property(void *state, int property, void *val, size_t *len)
Definition scale.c:64
static bool scale_reconfigure(void *state, struct video_desc desc)
Definition scale.c:154
static void * scale_init(const char *config)
Definition scale.c:93
static struct video_frame * scale_getf(void *state)
Definition scale.c:223
static void scale_done(void *state)
Definition scale.c:309
static void scale_get_out_desc(void *state, struct video_desc *out, int *in_display_mode, int *out_frames)
Definition scale.c:326

Definition at line 341 of file scale.c.