UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
capture_filter.cpp
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2014-2021 CESNET, z. s. p. o.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, is permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of CESNET nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
26 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
28 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#include "config_unix.h"
41#include "config_win32.h"
42#endif /* HAVE_CONFIG_H */
43
44#include "capture_filter.h"
45#include "debug.h"
46#include "lib_common.h"
47#include "module.h"
48#include "utils/color_out.h"
49#include "utils/list.h"
50#include "video.h"
51
52using namespace std;
53
58
63
64static int create_filter(struct capture_filter *s, char *cfg)
65{
66 bool found = false;
67 const char *options = "";
68 char *filter_name = cfg;
69 if(strchr(filter_name, ':')) {
70 options = strchr(filter_name, ':') + 1;
71 *strchr(filter_name, ':') = '\0';
72 }
74 for (auto && item : capture_filters) {
75 auto capture_filter_info = static_cast<const struct capture_filter_info*>(item.second);
76 if(strcasecmp(item.first.c_str(), filter_name) == 0) {
78 malloc(sizeof(struct capture_filter_instance));
79 instance->functions = capture_filter_info;
80 int ret = capture_filter_info->init(&s->mod, options, &instance->state);
81 if(ret < 0) {
82 fprintf(stderr, "Unable to initialize capture filter: %s\n",
83 filter_name);
84 }
85 if(ret != 0) {
86 free(instance);
87 return ret;
88 }
90 found = true;
91 break;
92 }
93 }
94 if (!found) {
95 fprintf(stderr, "Unable to find capture filter: %s\n",
96 filter_name);
97 return -1;
98 }
99 return 0;
100}
101
102int capture_filter_init(struct module *parent, const char *cfg, struct capture_filter **state)
103{
104 if (cfg && (strcasecmp(cfg, "help") == 0 || strcasecmp(cfg, "fullhelp") == 0)) {
105 printf("Usage:\n");
106 color_printf(TERM_BOLD "\t--capture-filter <filter1>[:opts][,<filter2>[:opts][,<filter3>[:<opts>]]]" TERM_RESET " -t <capture>\n\n");
107 printf("Available capture filters:\n");
108 list_modules(LIBRARY_CLASS_CAPTURE_FILTER, CAPTURE_FILTER_ABI_VERSION, strcasecmp(cfg, "fullhelp") == 0);
109 if (strcasecmp(cfg, "fullhelp") != 0) {
110 printf("(use \"fullhelp\" to show hidden filters)\n");
111 }
112 return 1;
113 }
114
115 struct capture_filter *s = (struct capture_filter *) calloc(1, sizeof(struct capture_filter));
116 char *item, *save_ptr;
117 assert(s);
118 char *filter_list_str = NULL,
119 *tmp = NULL;
120
122
126
127 if(cfg) {
128 filter_list_str = tmp = strdup(cfg);
129
130 while((item = strtok_r(filter_list_str, ",", &save_ptr))) {
131 char filter_name[128];
132 strncpy(filter_name, item, sizeof filter_name - 1);
133
134 int ret = create_filter(s, filter_name);
135 if (ret != 0) {
136 module_done(&s->mod);
137 free(tmp);
138 free(s);
139 return ret;
140 }
141 filter_list_str = NULL;
142 }
143 }
144
145 free(tmp);
146
147 *state = s;
148
149 return 0;
150}
151
153{
154 struct capture_filter *s = state;
155
156 while(simple_linked_list_size(s->filters) > 0) {
158 inst->functions->done(inst->state);
159 free(inst);
160 }
161
163
164 module_done(&s->mod);
165
166 free(state);
167}
168
169static struct response *process_message(struct capture_filter *s, struct msg_universal *msg)
170{
171 if (strncmp("delete ", msg->text, strlen("delete ")) == 0) {
172 int index = atoi(msg->text + strlen("delete "));
173 struct capture_filter_instance *inst = (struct capture_filter_instance *)
175 if (!inst) {
176 fprintf(stderr, "Unable to remove capture filter index %d.\n",
177 index);
179 } else {
180 printf("Capture filter #%d removed successfully.\n", index);
181 inst->functions->done(inst->state);
182 free(inst);
183 }
184 } else if (strcmp("flush", msg->text) == 0) {
185 while(simple_linked_list_size(s->filters) > 0) {
187 inst->functions->done(inst->state);
188 free(inst);
189 }
190 } else if (strcmp("help", msg->text) == 0) {
191 printf("Capture filter control:\n"
192 "\tflush - remove all filters\n"
193 "\tdelete <x> - delete x-th filter\n"
194 "\t<filter> - append a filter named <filter>\n");
195 } else {
196 char *fmt = strdup(msg->text);
197 if (create_filter(s, fmt) != 0) {
198 fprintf(stderr, "Cannot create capture filter: %s.\n",
199 msg->text);
200 free(fmt);
202 } else {
203 printf("Capture filter \"%s\" created successfully.\n",
204 msg->text);
205 }
206 free(fmt);
207 }
208
209 return new_response(RESPONSE_OK, NULL);
210}
211
213 struct capture_filter *s = state;
214
215 struct message *msg;
216 while ((msg = check_message(&s->mod))) {
217 struct response *r = process_message(s, (struct msg_universal *) msg);
218 free_message(msg, r);
219 }
220
221 for(void *it = simple_linked_list_it_init(s->filters);
222 it != NULL;
223 ) {
225 frame = inst->functions->filter(inst->state, frame);
226 if(!frame)
227 return NULL;
228 }
229 return frame;
230}
231
void ** state
struct video_frame * frame
const char * fmt
static struct response * process_message(struct capture_filter *s, struct msg_universal *msg)
static int create_filter(struct capture_filter *s, char *cfg)
void capture_filter_destroy(struct capture_filter *state)
struct video_frame * capture_filter(struct capture_filter *state, struct video_frame *frame)
int capture_filter_init(struct module *parent, const char *cfg, struct capture_filter **state)
#define CAPTURE_FILTER_ABI_VERSION
int color_printf(const char *format,...)
#define TERM_BOLD
Definition color_out.h:48
#define TERM_RESET
Definition color_out.h:47
void module_init_default(struct module *module_data)
Definition module.c:48
void module_register(struct module *module_data, struct module *parent)
Definition module.c:82
void module_done(struct module *module_data)
Definition module.c:93
@ MODULE_CLASS_FILTER
Definition module.h:93
map< string, const void * > get_libraries_for_class(enum library_class cls, int abi_version, bool include_hidden)
void list_modules(enum library_class cls, int abi_version, bool full)
@ LIBRARY_CLASS_CAPTURE_FILTER
Definition lib_common.h:75
void simple_linked_list_append(struct simple_linked_list *l, void *data)
Definition list.cpp:68
void * simple_linked_list_it_next(void **i)
Definition list.cpp:119
int simple_linked_list_size(struct simple_linked_list *l)
Definition list.cpp:93
struct simple_linked_list * simple_linked_list_init(void)
Definition list.cpp:53
void simple_linked_list_destroy(struct simple_linked_list *l)
Definition list.cpp:58
void * simple_linked_list_pop(struct simple_linked_list *l)
Definition list.cpp:82
void * simple_linked_list_remove_index(struct simple_linked_list *l, int index)
Definition list.cpp:155
void * simple_linked_list_it_init(struct simple_linked_list *l)
Definition list.cpp:108
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct message * check_message(struct module *mod)
#define RESPONSE_OK
Definition messaging.h:57
#define RESPONSE_INT_SERV_ERR
Definition messaging.h:63
struct msghdr msg
const char * parent
Definition settings.cpp:198
void(* done)(void *state)
int(* init)(struct module *parent, const char *cfg, void **state)
Initializes capture filter.
struct video_frame *(* filter)(void *state, struct video_frame *f)
Performs filtering.
const struct capture_filter_info * functions
struct module mod
struct simple_linked_list * filters
Definition hd-rum.c:27
enum module_class cls
Definition module.h:115
Definition rtp.c:253
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
This is an umbrella header for video functions.
static class worker_pool instance
Definition worker.cpp:250