UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
vo_postprocess.c File Reference
#include "vo_postprocess.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#include "lib_common.h"
#include "utils/color_out.h"
#include "utils/list.h"
#include "utils/macros.h"
#include "video_codec.h"
#include "video_display.h"
Include dependency graph for vo_postprocess.c:

Go to the source code of this file.

Classes

struct  vo_postprocess_state
 
struct  vo_postprocess_state_single
 

Macros

#define MAGIC   to_fourcc('V', 'P', 'S', 'T')
 
#define MAGIC_SINGLE   to_fourcc('V', 'P', 'S', 'S')
 
#define MOD_NAME   "[vo_postprocess] "
 

Functions

static _Bool init (struct vo_postprocess_state *s, const char *config_string)
 
void show_vo_postprocess_help (bool full)
 
bool vo_postprocess (struct vo_postprocess_state *s, struct video_frame *in, struct video_frame *out, int req_pitch)
 
void vo_postprocess_done (struct vo_postprocess_state *s)
 
void vo_postprocess_get_out_desc (struct vo_postprocess_state *s, struct video_desc *out, int *display_mode, int *out_frames_count)
 
bool vo_postprocess_get_property (struct vo_postprocess_state *s, int property, void *val, size_t *len)
 
struct video_frame * vo_postprocess_getf (struct vo_postprocess_state *s)
 
struct vo_postprocess_state * vo_postprocess_init (const char *config_string)
 
bool vo_postprocess_reconfigure (struct vo_postprocess_state *s, struct video_desc desc)
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z
Todo
Fix complex filters that 1. change video properties (tiling mode, codec) or
  1. producing more frames (eg. double_framerate).

Ideas for 2.:

  • change API - do not count output frames but always pass NULL to flush the queue until there are frames
  • process the filter queueue backwards - first pass NULL to filter <n>, then <n>-1 up to first

Definition in file vo_postprocess.c.

Macro Definition Documentation

◆ MAGIC

#define MAGIC   to_fourcc('V', 'P', 'S', 'T')

Definition at line 66 of file vo_postprocess.c.

Referenced by vo_postprocess_get_property(), and vo_postprocess_init().

◆ MAGIC_SINGLE

#define MAGIC_SINGLE   to_fourcc('V', 'P', 'S', 'S')

Definition at line 67 of file vo_postprocess.c.

Referenced by init(), and vo_postprocess_get_property().

◆ MOD_NAME

#define MOD_NAME   "[vo_postprocess] "

Definition at line 68 of file vo_postprocess.c.

Referenced by init(), and vo_postprocess_reconfigure().

Function Documentation

◆ init()

static _Bool init ( struct vo_postprocess_state * s,
const char * config_string )
static

Definition at line 91 of file vo_postprocess.c.

91 {
92 char *cpy = strdup(config_string);
93 char *tmp = cpy;
94 char *save_ptr = NULL;
95 char *item = NULL;
96
97 while ((item = strtok_r(tmp, ",", &save_ptr)) != NULL) {
98 const char *vo_postprocess_options = "";
99 char *lib_name = item;
100 if (strchr(lib_name, ':')) {
101 vo_postprocess_options = strchr(lib_name, ':') + 1;
102 *strchr(lib_name, ':') = '\0';
103 }
105 if (!funcs) {
106 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unknown postprocess module: %s\n", lib_name);
107 free(cpy);
108 return 0;
109 }
110 struct vo_postprocess_state_single *state = malloc(sizeof(struct vo_postprocess_state_single));
111 state->magic = MAGIC_SINGLE;
112 state->funcs = funcs;
113 state->state = state->funcs->init(vo_postprocess_options);
114 if (!state->state) {
115 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Postprocessing initialization failed: %s\n", config_string);
116 free(cpy);
117 free(state);
118 return 0;
119 }
121
122 tmp = NULL;
123 }
124 free(cpy);
125 return 1;
126}
void ** state
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_VIDEO_POSTPROCESS
Definition lib_common.h:83
void simple_linked_list_append(struct simple_linked_list *l, void *data)
Definition list.cpp:68
Definition hd-rum.c:27
vo_postprocess_init_t init
const struct vo_postprocess_info * funcs
struct simple_linked_list * postprocessors
#define MOD_NAME
#define MAGIC_SINGLE
#define VO_PP_ABI_VERSION

References vo_postprocess_state_single::funcs, vo_postprocess_info::init, LIBRARY_CLASS_VIDEO_POSTPROCESS, load_library(), LOG_LEVEL_ERROR, log_msg(), MAGIC_SINGLE, MOD_NAME, vo_postprocess_state::postprocessors, simple_linked_list_append(), state, and VO_PP_ABI_VERSION.

Referenced by vo_postprocess_init().

Here is the call graph for this function:

◆ show_vo_postprocess_help()

void show_vo_postprocess_help ( bool full)

Definition at line 82 of file vo_postprocess.c.

83{
84 printf("Usage:\n");
85 color_printf(TERM_BOLD "\t-p <postprocess_module>[:<args>] | help\n" TERM_RESET);
86 printf("\n");
87 printf("Possible postprocess modules:\n");
89}
int color_printf(const char *format,...)
#define TERM_BOLD
Definition color_out.h:48
#define TERM_RESET
Definition color_out.h:47
void list_modules(enum library_class cls, int abi_version, bool full)

References color_printf(), LIBRARY_CLASS_VIDEO_POSTPROCESS, list_modules(), TERM_BOLD, TERM_RESET, and VO_PP_ABI_VERSION.

Referenced by initialize_video_display(), and vo_postprocess_init().

Here is the call graph for this function:

◆ vo_postprocess()

bool vo_postprocess ( struct vo_postprocess_state * s,
struct video_frame * in,
struct video_frame * out,
int req_pitch )

param in will be NULL if vo_postprocess_get_out_desc() returns out_frames_count > 1 and will be called out_frames_count-1 times

Definition at line 215 of file vo_postprocess.c.

217{
218 if (s == NULL) {
219 return false;
220 }
221 assert(in == ((struct vo_postprocess_state_single *) simple_linked_list_first(s->postprocessors))->f || in == NULL);
222
223 for(void *it = simple_linked_list_it_init(s->postprocessors); it != NULL; ) {
225 struct video_frame *next = out;
226 if (it != NULL) {
228 next = state_next->f;
229 }
230
231 int pitch = vc_get_linesize(next->tiles[0].width, next->color_spec);
232 if (it == NULL) {
233 pitch = req_pitch;
234 }
235 bool ret = state->funcs->vo_postprocess(state->state, in, next, pitch);
236 if (!ret) {
237 return false;
238 }
239 in = next;
240 }
241
242 return true;
243}
int vc_get_linesize(unsigned int width, codec_t codec)
void * simple_linked_list_it_peek_next(const void *it)
Definition list.cpp:132
void * simple_linked_list_it_next(void **i)
Definition list.cpp:119
void * simple_linked_list_first(struct simple_linked_list *l)
returns first element of list, UB if empty
Definition list.cpp:98
void * simple_linked_list_it_init(struct simple_linked_list *l)
Definition list.cpp:108
unsigned int width
Definition types.h:280
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345
codec_t color_spec
Definition types.h:306
struct video_frame * f

References video_frame::color_spec, vo_postprocess_state_single::f, vo_postprocess_state::postprocessors, simple_linked_list_first(), simple_linked_list_it_init(), simple_linked_list_it_next(), simple_linked_list_it_peek_next(), state, video_frame::tiles, vc_get_linesize(), and tile::width.

Referenced by display_put_frame().

Here is the call graph for this function:

◆ vo_postprocess_done()

void vo_postprocess_done ( struct vo_postprocess_state * s)

Definition at line 245 of file vo_postprocess.c.

246{
247 if (s == NULL) {
248 return;
249 }
250 for(void *it = simple_linked_list_it_init(s->postprocessors); it != NULL; ) {
252 state->funcs->done(state->state);
253 free(state);
254 }
256 free(s);
257}
void simple_linked_list_destroy(struct simple_linked_list *l)
Definition list.cpp:58

References vo_postprocess_state::postprocessors, simple_linked_list_destroy(), simple_linked_list_it_init(), simple_linked_list_it_next(), and state.

Referenced by display_done(), process_message(), and vo_postprocess_init().

Here is the call graph for this function:

◆ vo_postprocess_get_out_desc()

void vo_postprocess_get_out_desc ( struct vo_postprocess_state * s,
struct video_desc * out,
int * display_mode,
int * out_frames_count )

Definition at line 259 of file vo_postprocess.c.

260{
261 if (s == NULL) {
262 return;
263 }
265 state->funcs->get_out_desc(state->state, out, display_mode, out_frames_count);
266}
void * simple_linked_list_last(struct simple_linked_list *l)
returns last element of list, UB if empty
Definition list.cpp:103

References vo_postprocess_state::postprocessors, simple_linked_list_last(), and state.

Referenced by display_reconfigure(), and restrict_returned_codecs().

Here is the call graph for this function:

◆ vo_postprocess_get_property()

bool vo_postprocess_get_property ( struct vo_postprocess_state * s,
int property,
void * val,
size_t * len )
Todo
This is not corrrect in a generic case - the codec may be acceptable for first filter but the output of the filter may be unacceptable for the following filter (or later on).

Definition at line 268 of file vo_postprocess.c.

269{
270 if (s == NULL) {
271 return false;
272 }
273 assert(s->magic == MAGIC);
274
277 assert(state->magic == MAGIC_SINGLE);
278 return state->funcs->get_property(state->state, property, val, len);
279 }
280
287 assert(state->magic == MAGIC_SINGLE);
288 return state->funcs->get_property(state->state, property, val, len);
289 }
290
291 return false;
292}
int void * val
int void size_t * len
int property
int simple_linked_list_size(struct simple_linked_list *l)
Definition list.cpp:93
#define MAGIC
#define VO_PP_DOES_CHANGE_TILING_MODE
#define VO_PP_PROPERTY_CODECS

References len, MAGIC, vo_postprocess_state::magic, MAGIC_SINGLE, vo_postprocess_state::postprocessors, property, simple_linked_list_first(), simple_linked_list_last(), simple_linked_list_size(), state, val, VO_PP_DOES_CHANGE_TILING_MODE, and VO_PP_PROPERTY_CODECS.

Referenced by display_ctl_property(), and display_reconfigure().

Here is the call graph for this function:

◆ vo_postprocess_getf()

struct video_frame * vo_postprocess_getf ( struct vo_postprocess_state * s)

Definition at line 188 of file vo_postprocess.c.

189{
190 if (s == NULL) {
191 return NULL;
192 }
193
194 struct video_frame *out = NULL;
195
196 for(void *it = simple_linked_list_it_init(s->postprocessors); it != NULL; ) {
198 state->f = state->funcs->getf(state->state);
199 if (state->f == NULL) {
201 return NULL;
202 }
203 if (out == NULL) {
204 out = state->f;
205 }
206 }
207
208 return out;
209}
void simple_linked_list_it_destroy(void *i)
Should be used when it != NULL, eg. when leaving the loop before the end.
Definition list.cpp:139

References vo_postprocess_state::postprocessors, simple_linked_list_it_destroy(), simple_linked_list_it_init(), simple_linked_list_it_next(), and state.

Referenced by display_get_frame().

Here is the call graph for this function:

◆ vo_postprocess_init()

struct vo_postprocess_state * vo_postprocess_init ( const char * config_string)

Definition at line 128 of file vo_postprocess.c.

129{
130 if (!config_string) {
131 return NULL;
132 }
133
134 if (strcmp(config_string, "help") == 0 || strcmp(config_string, "fullhelp") == 0) {
135 show_vo_postprocess_help(strcmp(config_string, "fullhelp") == 0);
136 return NULL;
137 }
138
139 struct vo_postprocess_state *s = (struct vo_postprocess_state *) malloc(sizeof(struct vo_postprocess_state));
140 s->magic = MAGIC;
142
143 if (!init(s, config_string)) {
145 return NULL;
146 }
147
148 return s;
149}
struct simple_linked_list * simple_linked_list_init(void)
Definition list.cpp:53
void show_vo_postprocess_help(bool full)
void vo_postprocess_done(struct vo_postprocess_state *s)
static _Bool init(struct vo_postprocess_state *s, const char *config_string)

References init(), MAGIC, vo_postprocess_state::magic, vo_postprocess_state::postprocessors, show_vo_postprocess_help(), simple_linked_list_init(), and vo_postprocess_done().

Referenced by initialize_video_display(), and process_message().

Here is the call graph for this function:

◆ vo_postprocess_reconfigure()

bool vo_postprocess_reconfigure ( struct vo_postprocess_state * s,
struct video_desc desc )

Definition at line 152 of file vo_postprocess.c.

154{
155 if (s == NULL) {
156 return false;
157 }
158
159 bool filter_complex = false;
160
161 for(void *it = simple_linked_list_it_init(s->postprocessors); it != NULL; ) {
163 const bool ret = state->funcs->reconfigure(state->state, desc);
164 if (!ret) {
166 return false;
167 }
168 // get desc for next iteration
169 int display_mode = 0;
170 int out_frames_count = 0;
171 state->funcs->get_out_desc(state->state, &desc, &display_mode, &out_frames_count);
172
173 // check if convert is simple (doesn't change display mode and out_fr_count == 1); if not, only one filter allowed
174 if (display_mode != DISPLAY_PROPERTY_VIDEO_MERGED || out_frames_count != 1) {
175 filter_complex = true;
176 }
177 }
178
179 if (filter_complex && simple_linked_list_size(s->postprocessors) > 1) {
180 log_msg(LOG_LEVEL_ERROR, MOD_NAME "One of postprocessors is complex (changing properties) and "
181 "cannot be used in filter chain (more postprocessors)!\n");
182 return false;
183 }
184
185 return true;
186}
struct video_desc desc
@ DISPLAY_PROPERTY_VIDEO_MERGED
monolithic framebuffer

References desc, DISPLAY_PROPERTY_VIDEO_MERGED, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, vo_postprocess_state::postprocessors, simple_linked_list_it_destroy(), simple_linked_list_it_init(), simple_linked_list_it_next(), simple_linked_list_size(), and state.

Referenced by display_reconfigure(), and restrict_returned_codecs().

Here is the call graph for this function: