mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-22 02:40:26 +00:00
Added control to capture filters
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "capture_filter.h"
|
||||
#include "module.h"
|
||||
#include "utils/list.h"
|
||||
#include "video.h"
|
||||
|
||||
@@ -65,6 +66,7 @@ static struct capture_filter_info *capture_filters[] = {
|
||||
};
|
||||
|
||||
struct capture_filter {
|
||||
struct module mod;
|
||||
struct simple_linked_list *filters;
|
||||
};
|
||||
|
||||
@@ -73,7 +75,41 @@ struct capture_filter_instance {
|
||||
void *state;
|
||||
};
|
||||
|
||||
int capture_filter_init(const char *cfg, struct capture_filter **state)
|
||||
static bool create_filter(struct capture_filter *s, char *cfg)
|
||||
{
|
||||
unsigned int i;
|
||||
char *options = NULL;
|
||||
char *filter_name = cfg;
|
||||
if(strchr(filter_name, ':')) {
|
||||
options = strchr(filter_name, ':') + 1;
|
||||
*strchr(filter_name, ':') = '\0';
|
||||
}
|
||||
for(i = 0; i < sizeof(capture_filters) / sizeof(struct capture_filter_info *); ++i) {
|
||||
if(strcasecmp(capture_filters[i]->name, filter_name) == 0) {
|
||||
struct capture_filter_instance *instance =
|
||||
malloc(sizeof(struct capture_filter_instance));
|
||||
instance->index = i;
|
||||
int ret = capture_filters[i]->init(&s->mod, options, &instance->state);
|
||||
if(ret < 0) {
|
||||
fprintf(stderr, "Unable to initialize capture filter: %s\n",
|
||||
filter_name);
|
||||
}
|
||||
if(ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
simple_linked_list_append(s->filters, instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == sizeof(capture_filters) / sizeof(struct capture_filter_info *)) {
|
||||
fprintf(stderr, "Unable to find capture filter: %s\n",
|
||||
filter_name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int capture_filter_init(struct module *parent, const char *cfg, struct capture_filter **state)
|
||||
{
|
||||
struct capture_filter *s = calloc(1, sizeof(struct capture_filter));
|
||||
char *item, *save_ptr;
|
||||
@@ -83,6 +119,10 @@ int capture_filter_init(const char *cfg, struct capture_filter **state)
|
||||
|
||||
s->filters = simple_linked_list_init();
|
||||
|
||||
module_init_default(&s->mod);
|
||||
s->mod.cls = MODULE_CLASS_FILTER;
|
||||
module_register(&s->mod, parent);
|
||||
|
||||
if(cfg) {
|
||||
if(strcasecmp(cfg, "help") == 0) {
|
||||
printf("Available capture filters:\n");
|
||||
@@ -95,36 +135,10 @@ int capture_filter_init(const char *cfg, struct capture_filter **state)
|
||||
filter_list_str = tmp = strdup(cfg);
|
||||
|
||||
while((item = strtok_r(filter_list_str, ",", &save_ptr))) {
|
||||
unsigned int i;
|
||||
char filter_name[128];
|
||||
char *options = NULL;
|
||||
strncpy(filter_name, item, sizeof(filter_name));
|
||||
if(strchr(filter_name, ':')) {
|
||||
options = strchr(filter_name, ':') + 1;
|
||||
*strchr(filter_name, ':') = '\0';
|
||||
}
|
||||
for(i = 0; i < sizeof(capture_filters) / sizeof(struct capture_filter_info *); ++i) {
|
||||
if(strcasecmp(capture_filters[i]->name, filter_name) == 0) {
|
||||
struct capture_filter_instance *instance =
|
||||
malloc(sizeof(struct capture_filter_instance));
|
||||
instance->index = i;
|
||||
int ret = capture_filters[i]->init(options, &instance->state);
|
||||
if(ret < 0) {
|
||||
fprintf(stderr, "Unable to initialize capture filter: %s\n",
|
||||
filter_name);
|
||||
}
|
||||
if(ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
simple_linked_list_append(s->filters, instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == sizeof(capture_filters) / sizeof(struct capture_filter_info *)) {
|
||||
fprintf(stderr, "Unable to find capture filter: %s\n",
|
||||
filter_name);
|
||||
if (!create_filter(s, filter_name))
|
||||
return -1;
|
||||
}
|
||||
filter_list_str = NULL;
|
||||
}
|
||||
}
|
||||
@@ -148,12 +162,46 @@ void capture_filter_destroy(struct capture_filter *state)
|
||||
|
||||
simple_linked_list_destroy(s->filters);
|
||||
|
||||
module_done(&s->mod);
|
||||
|
||||
free(state);
|
||||
}
|
||||
|
||||
static void process_message(struct capture_filter *s, struct msg_universal *msg)
|
||||
{
|
||||
if (strncmp("delete ", msg->text, strlen("delete ")) == 0) {
|
||||
int index = atoi(msg->text + strlen("delete "));
|
||||
struct capture_filter_instance *inst =
|
||||
simple_linked_list_remove_index(s->filters, index);
|
||||
if (!inst) {
|
||||
fprintf(stderr, "Unable to remove capture filter index %d.\n",
|
||||
index);
|
||||
} else {
|
||||
printf("Capture filter #%d removed successfully.\n", index);
|
||||
}
|
||||
capture_filters[inst->index]->done(inst->state);
|
||||
} else {
|
||||
char *fmt = strdup(msg->text);
|
||||
if (!create_filter(s, fmt)) {
|
||||
fprintf(stderr, "Cannot create capture filter: %s.\n",
|
||||
msg->text);
|
||||
} else {
|
||||
printf("Capture filter \"%s\" created successfully.\n",
|
||||
msg->text);
|
||||
}
|
||||
free(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
struct video_frame *capture_filter(struct capture_filter *state, struct video_frame *frame) {
|
||||
struct capture_filter *s = state;
|
||||
|
||||
struct message *msg;
|
||||
while ((msg = check_message(&s->mod))) {
|
||||
process_message(s, (struct msg_universal *) msg);
|
||||
free_message(msg);
|
||||
}
|
||||
|
||||
for(void *it = simple_linked_list_it_init(s->filters);
|
||||
it != NULL;
|
||||
) {
|
||||
|
||||
@@ -53,20 +53,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct module;
|
||||
|
||||
struct capture_filter_info {
|
||||
const char *name;
|
||||
int (*init)(const char *cfg, void **state);
|
||||
int (*init)(struct module *parent, const char *cfg, void **state);
|
||||
void (*done)(void *state);
|
||||
struct video_frame *(*filter)(void *state, struct video_frame *);
|
||||
};
|
||||
|
||||
struct capture_filter;
|
||||
struct module;
|
||||
struct video_frame;
|
||||
|
||||
/**
|
||||
* @see display_init
|
||||
*/
|
||||
int capture_filter_init(const char *cfg, struct capture_filter **state);
|
||||
int capture_filter_init(struct module *parent, const char *cfg, struct capture_filter **state);
|
||||
void capture_filter_destroy(struct capture_filter *state);
|
||||
struct video_frame *capture_filter(struct capture_filter *state, struct video_frame *frame);
|
||||
|
||||
@@ -75,3 +78,4 @@ struct video_frame *capture_filter(struct capture_filter *state, struct video_fr
|
||||
#endif
|
||||
|
||||
#endif /* CAPTURE_FILTER_H_ */
|
||||
|
||||
|
||||
@@ -53,69 +53,88 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "capture_filter.h"
|
||||
#include "messaging.h"
|
||||
#include "module.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_codec.h"
|
||||
|
||||
static int init(const char *cfg, void **state);
|
||||
static int init(struct module *parent, const char *cfg, void **state);
|
||||
static void done(void *state);
|
||||
static struct video_frame *filter(void *state, struct video_frame *in);
|
||||
|
||||
struct state_blank {
|
||||
struct module mod;
|
||||
int x,y, width, height;
|
||||
bool outline;
|
||||
};
|
||||
|
||||
static int init(const char *cfg, void **state)
|
||||
static bool parse(struct state_blank *s, char *cfg)
|
||||
{
|
||||
int vals[4];
|
||||
unsigned int counter = 0;
|
||||
char *cfg_mutable = NULL, *tmp = NULL;
|
||||
char *item, *save_ptr;
|
||||
bool outline = false;
|
||||
|
||||
if(cfg) {
|
||||
if(strcasecmp(cfg, "help") == 0) {
|
||||
printf("Blanks specified rectangular area:\n\n");
|
||||
printf("blank usage:\n");
|
||||
printf("\tblank:x:y:widht:height[:outline]\n");
|
||||
printf("\t(all values in pixels)\n");
|
||||
return 1;
|
||||
}
|
||||
cfg_mutable = tmp = strdup(cfg);
|
||||
while ((item = strtok_r(cfg_mutable, ":", &save_ptr))) {
|
||||
vals[counter] = atoi(item);
|
||||
char *item, *save_ptr;
|
||||
while ((item = strtok_r(cfg, ":", &save_ptr))) {
|
||||
vals[counter] = atoi(item);
|
||||
|
||||
cfg_mutable = NULL;
|
||||
counter += 1;
|
||||
if (counter == sizeof(vals) / sizeof(int))
|
||||
break;
|
||||
}
|
||||
while ((item = strtok_r(cfg_mutable, ":", &save_ptr))) {
|
||||
if (strcmp(item, "outline") == 0) {
|
||||
outline = true;
|
||||
} else {
|
||||
fprintf(stderr, "[Blank] Unknown config value: %s\n",
|
||||
item);
|
||||
return -1;
|
||||
}
|
||||
cfg = NULL;
|
||||
counter += 1;
|
||||
if (counter == sizeof(vals) / sizeof(int))
|
||||
break;
|
||||
}
|
||||
while ((item = strtok_r(cfg, ":", &save_ptr))) {
|
||||
if (strcmp(item, "outline") == 0) {
|
||||
outline = true;
|
||||
} else {
|
||||
fprintf(stderr, "[Blank] Unknown config value: %s\n",
|
||||
item);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(counter != sizeof(vals) / sizeof(int)) {
|
||||
fprintf(stderr, "[Blank] Few config values.\n");
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct state_blank *s = calloc(1, sizeof(struct state_blank));
|
||||
assert(s);
|
||||
|
||||
s->x = vals[0];
|
||||
s->y = vals[1];
|
||||
s->width = vals[2];
|
||||
s->height = vals[3];
|
||||
s->outline = outline;
|
||||
|
||||
free(tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int init(struct module *parent, const char *cfg, void **state)
|
||||
{
|
||||
if (cfg && strcasecmp(cfg, "help") == 0) {
|
||||
printf("Blanks specified rectangular area:\n\n");
|
||||
printf("blank usage:\n");
|
||||
printf("\tblank:x:y:widht:height[:outline]\n");
|
||||
printf("\t(all values in pixels)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct state_blank *s = calloc(1, sizeof(struct state_blank));
|
||||
assert(s);
|
||||
|
||||
if (cfg) {
|
||||
char *tmp = strdup(cfg);
|
||||
bool ret = parse(s, tmp);
|
||||
free(tmp);
|
||||
if (!ret) {
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
module_init_default(&s->mod);
|
||||
s->mod.cls = MODULE_CLASS_DATA;
|
||||
module_register(&s->mod, parent);
|
||||
|
||||
*state = s;
|
||||
return 0;
|
||||
@@ -123,9 +142,16 @@ static int init(const char *cfg, void **state)
|
||||
|
||||
static void done(void *state)
|
||||
{
|
||||
struct state_blank *s = state;
|
||||
module_done(&s->mod);
|
||||
free(state);
|
||||
}
|
||||
|
||||
static void process_message(struct state_blank *s, struct msg_universal *msg)
|
||||
{
|
||||
parse(s, msg->text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @note v210 etc. will be green
|
||||
*/
|
||||
@@ -134,6 +160,12 @@ static struct video_frame *filter(void *state, struct video_frame *in)
|
||||
struct state_blank *s = state;
|
||||
codec_t codec = in->color_spec;
|
||||
|
||||
struct message *msg;
|
||||
while ((msg = check_message(&s->mod))) {
|
||||
process_message(s, (struct msg_universal *) msg);
|
||||
free_message(msg);
|
||||
}
|
||||
|
||||
for(int y = s->y; y < s->y + s->height; ++y) {
|
||||
if(y >= (int) in->tiles[0].height) {
|
||||
break;
|
||||
|
||||
@@ -54,12 +54,16 @@
|
||||
|
||||
#include "capture_filter.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_codec.h"
|
||||
|
||||
#define MAX_TILES 16
|
||||
|
||||
static int init(const char *cfg, void **state);
|
||||
struct module;
|
||||
|
||||
static int init(struct module *parent, const char *cfg, void **state);
|
||||
static void done(void *state);
|
||||
static struct video_frame *filter(void *state, struct video_frame *in);
|
||||
|
||||
@@ -77,8 +81,10 @@ static void usage() {
|
||||
printf("Example: every:2 - every second frame will be dropped\n");
|
||||
}
|
||||
|
||||
static int init(const char *cfg, void **state)
|
||||
static int init(struct module *parent, const char *cfg, void **state)
|
||||
{
|
||||
UNUSED(parent);
|
||||
|
||||
int n;
|
||||
int denom = 1;;
|
||||
if(cfg) {
|
||||
|
||||
@@ -261,9 +261,11 @@ static int process_msg(struct control_state *s, fd_t client_fd, char *message)
|
||||
{
|
||||
int ret = 0;
|
||||
struct response *resp = NULL;
|
||||
char path[1024] = { '\0' };
|
||||
char path[1024];
|
||||
char buf[1024];
|
||||
|
||||
memset(path, 0, sizeof(path));
|
||||
|
||||
if(prefix_matches(message, "port ")) {
|
||||
message = suffix(message, "port ");
|
||||
snprintf(path, 1024, "%s[%d]", module_class_name(MODULE_CLASS_PORT), atoi(message));
|
||||
@@ -358,9 +360,18 @@ static int process_msg(struct control_state *s, fd_t client_fd, char *message)
|
||||
} else if(strcasecmp(message, "bye") == 0) {
|
||||
ret = CONTROL_CLOSE_HANDLE;
|
||||
resp = new_response(RESPONSE_OK, NULL);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "(unrecognized control sequence: %s)", message);
|
||||
resp = new_response(RESPONSE_BAD_REQUEST, strdup(buf));
|
||||
} else { // assume message in format "path message"
|
||||
struct msg_universal *msg = (struct msg_universal *)
|
||||
new_message(sizeof(struct msg_universal));
|
||||
|
||||
if (strchr(message, ' ')) {
|
||||
memcpy(path, message, strchr(message, ' ') - message);
|
||||
strncpy(msg->text, strchr(message, ' ') + 1, sizeof(path) - 1);
|
||||
} else {
|
||||
strncpy(path, message, sizeof(path) - 1); // empty message ??
|
||||
}
|
||||
|
||||
resp = send_message(s->root_module, path, (struct message *) msg);
|
||||
}
|
||||
|
||||
if(!resp) {
|
||||
|
||||
@@ -43,14 +43,16 @@ extern struct vidcap_type *(*vidcap_get_device_details_extrn)(int i);
|
||||
extern void (*display_free_devices_extrn)(void);
|
||||
extern vidcap_id_t (*vidcap_get_null_device_id_extrn)();
|
||||
extern display_id_t (*display_get_null_device_id_extrn)();
|
||||
extern int (*vidcap_init_extrn)(vidcap_id_t id, const struct vidcap_params *, struct vidcap **);
|
||||
extern int (*vidcap_init_extrn)(struct module *parent, vidcap_id_t id,
|
||||
const struct vidcap_params *, struct vidcap **);
|
||||
extern int (*display_init_extrn)(display_id_t id, char *fmt, unsigned int flags, struct display **);
|
||||
extern int (*vidcap_get_device_count_extrn)(void);
|
||||
extern int (*display_get_device_count_extrn)(void);
|
||||
extern int (*vidcap_init_devices_extrn)(void);
|
||||
extern int (*display_init_devices_extrn)(void);
|
||||
|
||||
int initialize_video_capture(const char *requested_capture,
|
||||
int initialize_video_capture(struct module *parent,
|
||||
const char *requested_capture,
|
||||
const struct vidcap_params *params,
|
||||
struct vidcap **state)
|
||||
{
|
||||
@@ -82,7 +84,7 @@ int initialize_video_capture(const char *requested_capture,
|
||||
pthread_mutex_unlock(vidcap_lock);
|
||||
rm_release_shared_lock("VIDCAP_LOCK");
|
||||
|
||||
return vidcap_init_extrn(id, params, state);
|
||||
return vidcap_init_extrn(parent, id, params, state);
|
||||
}
|
||||
|
||||
int initialize_video_display(const char *requested_display,
|
||||
|
||||
@@ -94,10 +94,11 @@ extern bool verbose;
|
||||
// for aggregate.c
|
||||
struct vidcap;
|
||||
struct display;
|
||||
struct module;
|
||||
int initialize_video_display(const char *requested_display,
|
||||
char *fmt, unsigned int flags,
|
||||
struct display **);
|
||||
int initialize_video_capture(const char *requested_capture,
|
||||
int initialize_video_capture(struct module *parent, const char *requested_capture,
|
||||
const struct vidcap_params *params,
|
||||
struct vidcap **);
|
||||
|
||||
|
||||
@@ -1342,7 +1342,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("Display initialized-%s\n", uv->requested_display);
|
||||
|
||||
ret = initialize_video_capture(vidcap_params[0].driver, &vidcap_params[0], &uv->capture_device);
|
||||
ret = initialize_video_capture(&root_mod, vidcap_params[0].driver,
|
||||
&vidcap_params[0], &uv->capture_device);
|
||||
if (ret < 0) {
|
||||
printf("Unable to open capture device: %s\n",
|
||||
vidcap_params[0].driver);
|
||||
|
||||
@@ -91,6 +91,11 @@ struct msg_stats {
|
||||
int value;
|
||||
};
|
||||
|
||||
struct msg_universal {
|
||||
struct message m;
|
||||
char text[8192];
|
||||
};
|
||||
|
||||
struct response *new_response(int status, char *optional_message);
|
||||
|
||||
typedef struct response *(*msg_callback_t)(struct module *mod, struct message *msg);
|
||||
|
||||
@@ -129,6 +129,8 @@ const char *module_class_name_pairs[] = {
|
||||
[MODULE_CLASS_TX] = "transmit",
|
||||
[MODULE_CLASS_AUDIO] = "audio",
|
||||
[MODULE_CLASS_CONTROL] = "control",
|
||||
[MODULE_CLASS_CAPTURE] = "capture",
|
||||
[MODULE_CLASS_FILTER] = "filter",
|
||||
};
|
||||
|
||||
const char *module_class_name(enum module_class cls)
|
||||
|
||||
@@ -72,6 +72,8 @@ enum module_class {
|
||||
MODULE_CLASS_TX,
|
||||
MODULE_CLASS_AUDIO,
|
||||
MODULE_CLASS_CONTROL,
|
||||
MODULE_CLASS_CAPTURE,
|
||||
MODULE_CLASS_FILTER,
|
||||
};
|
||||
|
||||
struct module;
|
||||
|
||||
@@ -88,16 +88,21 @@ void *simple_linked_list_it_next(void **it)
|
||||
int simple_linked_list_remove(struct simple_linked_list *l, void *item)
|
||||
{
|
||||
struct node **child_ptr = &l->head;
|
||||
struct node *parent = NULL;
|
||||
bool found = false;
|
||||
|
||||
while(*child_ptr) {
|
||||
if((*child_ptr)->val == item) {
|
||||
struct node *tmp = *child_ptr;
|
||||
*child_ptr = (*child_ptr)->next;
|
||||
if (l->tail == *child_ptr) {
|
||||
l->tail = parent;
|
||||
}
|
||||
free(tmp);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
parent = *child_ptr;
|
||||
child_ptr = &(*child_ptr)->next;
|
||||
}
|
||||
|
||||
@@ -109,3 +114,32 @@ int simple_linked_list_remove(struct simple_linked_list *l, void *item)
|
||||
}
|
||||
}
|
||||
|
||||
void *simple_linked_list_remove_index(struct simple_linked_list *l, int index)
|
||||
{
|
||||
struct node **child_ptr = &l->head;
|
||||
struct node *parent = NULL;
|
||||
|
||||
for (int i = 0; i < index; ++i) {
|
||||
if (*child_ptr) {
|
||||
parent = *child_ptr;
|
||||
child_ptr = &(*child_ptr)->next;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*child_ptr)
|
||||
return NULL;
|
||||
|
||||
struct node *tmp = *child_ptr;
|
||||
void *ret = (*child_ptr)->val;
|
||||
*child_ptr = (*child_ptr)->next;
|
||||
if (l->tail == *child_ptr) {
|
||||
l->tail = parent;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
l->size -= 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ void *simple_linked_list_it_next(void **it);
|
||||
*/
|
||||
int simple_linked_list_remove(struct simple_linked_list *, void *);
|
||||
|
||||
/**
|
||||
* @retval pointer pointer to removed value
|
||||
* @retval NULL if not found
|
||||
*/
|
||||
void *simple_linked_list_remove_index(struct simple_linked_list *, int index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "capture_filter.h"
|
||||
#include "debug.h"
|
||||
#include "lib_common.h"
|
||||
#include "module.h"
|
||||
#include "video.h"
|
||||
#include "video_capture.h"
|
||||
#include "video_capture/DirectShowGrabber.h"
|
||||
@@ -89,7 +90,7 @@ void (*vidcap_free_devices_extrn)() = vidcap_free_devices;
|
||||
void (*vidcap_done_extrn)(struct vidcap *) = vidcap_done;
|
||||
vidcap_id_t (*vidcap_get_null_device_id_extrn)(void) = vidcap_get_null_device_id;
|
||||
struct vidcap_type *(*vidcap_get_device_details_extrn)(int index) = vidcap_get_device_details;
|
||||
int (*vidcap_init_extrn)(vidcap_id_t id, const struct vidcap_params *, struct vidcap **) = vidcap_init;
|
||||
int (*vidcap_init_extrn)(struct module *mod, vidcap_id_t id, const struct vidcap_params *, struct vidcap **) = vidcap_init;
|
||||
struct video_frame *(*vidcap_grab_extrn)(struct vidcap *state, struct audio_frame **audio) = vidcap_grab;
|
||||
int (*vidcap_get_device_count_extrn)(void) = vidcap_get_device_count;
|
||||
int (*vidcap_init_devices_extrn)(void) = vidcap_init_devices;
|
||||
@@ -102,6 +103,7 @@ int vidcap_init_noerr;
|
||||
|
||||
/// @brief This struct represents video capture state.
|
||||
struct vidcap {
|
||||
struct module mod;
|
||||
void *state; ///< state of the created video capture driver
|
||||
int index; ///< index to @ref vidcap_device_table
|
||||
uint32_t magic; ///< For debugging. Conatins @ref VIDCAP_MAGIC
|
||||
@@ -445,7 +447,8 @@ vidcap_id_t vidcap_get_null_device_id(void)
|
||||
* @retval <0 if initialization failed
|
||||
* @retval >0 if initialization was successful but no state was returned (eg. only having shown help).
|
||||
*/
|
||||
int vidcap_init(vidcap_id_t id, const struct vidcap_params *param, struct vidcap **state)
|
||||
int vidcap_init(struct module *parent, vidcap_id_t id, const struct vidcap_params *param,
|
||||
struct vidcap **state)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -467,14 +470,22 @@ int vidcap_init(vidcap_id_t id, const struct vidcap_params *param, struct vidcap
|
||||
free(d);
|
||||
return 1;
|
||||
}
|
||||
int ret = capture_filter_init(param->requested_capture_filter, &d->capture_filter);
|
||||
|
||||
module_init_default(&d->mod);
|
||||
d->mod.cls = MODULE_CLASS_CAPTURE;
|
||||
module_register(&d->mod, parent);
|
||||
|
||||
int ret = capture_filter_init(&d->mod, param->requested_capture_filter,
|
||||
&d->capture_filter);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "Unable to initialize capture filter: %s.\n",
|
||||
param->requested_capture_filter);
|
||||
module_done(&d->mod);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*state = d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -489,6 +500,7 @@ void vidcap_done(struct vidcap *state)
|
||||
assert(state->magic == VIDCAP_MAGIC);
|
||||
vidcap_device_table[state->index].func_done(state->state);
|
||||
capture_filter_destroy(state->capture_filter);
|
||||
module_done(&state->mod);
|
||||
free(state);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,9 +130,11 @@ int vidcap_get_device_count(void);
|
||||
struct vidcap_type *vidcap_get_device_details(int index);
|
||||
vidcap_id_t vidcap_get_null_device_id(void);
|
||||
|
||||
struct module;
|
||||
struct vidcap;
|
||||
|
||||
int vidcap_init(vidcap_id_t id, const struct vidcap_params *param, struct vidcap **);
|
||||
int vidcap_init(struct module *parent, vidcap_id_t id,
|
||||
const struct vidcap_params *param, struct vidcap **);
|
||||
void vidcap_done(struct vidcap *state);
|
||||
struct video_frame *vidcap_grab(struct vidcap *state, struct audio_frame **audio);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user