UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
video_capture.c
Go to the documentation of this file.
1
15/*
16 * Copyright (c) 2005-2024 CESNET
17 * Copyright (c) 2001-2004 University of Southern California
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, is permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 *
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 *
33 * This product includes software developed by the University of Southern
34 * California Information Sciences Institute. This product also includes
35 * software developed by CESNET z.s.p.o.
36 *
37 * 4. Neither the name of the University, Institute, CESNET nor the names of
38 * its contributors may be used to endorse or promote products derived from
39 * this software without specific prior written permission.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
42 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
43 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
44 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
45 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
46 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
51 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
52 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 *
54 */
55
56#include <assert.h> // for assert
57#include <stdint.h> // for uint32_t
58#include <stdio.h> // for printf
59#include <stdlib.h> // for NULL, free, malloc, size_t
60
61#include "capture_filter.h"
62#include "debug.h"
63#include "lib_common.h"
64#include "module.h"
65#include "utils/macros.h"
66#include "video_capture.h"
68
69#define VIDCAP_MAGIC 0x76ae98f0
70
72struct vidcap {
73 struct module mod;
74 void *state;
76 uint32_t magic;
77
79};
80
81/* API for probing capture devices ****************************************************************/
83{
84 printf("Available capture devices:\n");
86}
87
97 struct vidcap_params *param,
98 struct vidcap **state)
99{
102 struct vidcap_params *tlast = param;
103 struct vidcap_params *tprev = param;
104 while ((vidcap_params_get_next(tlast))) {
105 tprev = tlast;
106 tlast = vidcap_params_get_next(tlast);
107 }
108 if (vidcap_params_get_driver(tlast) == NULL
109 && vidcap_params_get_capture_filter(tlast) != NULL) {
110 if (tprev != param) { // more than one -t
111 log_msg(LOG_LEVEL_ERROR, "Capture filter (--capture-filter) needs to be "
112 "specified before capture (-t)\n");
113 return -1;
114 }
115 if (vidcap_params_get_capture_filter(tprev) != NULL) { // one -t but -F specified both before and after it
116 log_msg(LOG_LEVEL_ERROR, "Multiple capture filter specification.\n");
117 return -1;
118 }
120 }
121 // similarly for audio connection
122 if (vidcap_params_get_driver(tlast) == NULL
123 && vidcap_params_get_flags(tlast) != 0) {
124 if (tprev != param) { // more than one -t
125 log_msg(LOG_LEVEL_ERROR, "Audio connection (-s) needs to be "
126 "specified before capture (-t)\n");
127 return -1;
128 }
129 if (vidcap_params_get_flags(tprev) != 0) { // one -t but -s specified both before and after it
130 log_msg(LOG_LEVEL_ERROR, "Multiple audio connection specification.\n");
131 return -1;
132 }
134 }
135
136 const struct video_capture_info *vci = (const struct video_capture_info *)
138
139 if (vci == NULL) {
140 log_msg(LOG_LEVEL_ERROR, "WARNING: Selected '%s' capture card "
141 "was not found.\n", vidcap_params_get_driver(param));
142 return -1;
143 }
144
145 struct vidcap *d =
146 (struct vidcap *)malloc(sizeof(struct vidcap));
147 d->magic = VIDCAP_MAGIC;
148 d->funcs = vci;
149
153
155 int ret = vci->init(param, &d->state);
156
157 switch (ret) {
158 case VIDCAP_INIT_OK:
159 break;
161 break;
162 case VIDCAP_INIT_FAIL:
164 "Unable to start video capture device %s\n",
166 break;
169 "Video capture driver does not support selected embedded/analog/AESEBU audio.\n");
170 break;
171 }
172 if (ret != 0) {
173 module_done(&d->mod);
174 free(d);
175 return ret;
176 }
177
179 &d->capture_filter);
180 if (ret < 0) {
181 log_msg(LOG_LEVEL_ERROR, "Unable to initialize capture filter: %s.\n",
183 }
184
185 if (ret != 0) {
186 module_done(&d->mod);
187 free(d);
188 return ret;
189 }
190
191 *state = d;
192 return 0;
193}
194
198{
199 assert(state->magic == VIDCAP_MAGIC);
200 state->funcs->done(state->state);
201 capture_filter_destroy(state->capture_filter);
202 module_done(&state->mod);
203 free(state);
204}
205
219{
220 assert(state->magic == VIDCAP_MAGIC);
221 struct video_frame *frame;
222 frame = state->funcs->grab(state->state, audio);
223 if (frame != NULL)
224 frame = capture_filter(state->capture_filter, frame);
225 return frame;
226}
227
234{
235 assert(state->magic == VIDCAP_MAGIC);
236 if (state->funcs->generic_fps_indicator_prefix == NULL) {
237 return NULL;
238 }
239 _Thread_local static char buf[SHORT_STR];
240
241 unsigned len = snprintf(buf, sizeof buf, "%s",
242 state->funcs->generic_fps_indicator_prefix);
243 if (len > sizeof buf - 1) { // truncated
244 len = sizeof buf - 1;
245 }
246 if (len > 0 && buf[len - 1] == ' ') { // trim trailing ' '
247 buf[len - 1] = '\0';
248 }
249 return buf;
250}
251
void ** state
struct video_frame * frame
int void size_t * len
struct audio_frame ** audio
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)
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
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_CAPTURE
Definition module.h:92
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
void list_video_capture_devices(bool full)
#define VIDCAP_INIT_OK
initialization successful
struct video_frame * vidcap_grab(struct vidcap *state, struct audio_frame **audio)
Grabs video frame. This function may block for a short period if waiting for incoming frame....
int initialize_video_capture(struct module *parent, struct vidcap_params *param, struct vidcap **state)
Initializes video capture.
void vidcap_done(struct vidcap *state)
Destroys vidap state.
#define VIDEO_CAPTURE_ABI_VERSION
const char * vidcap_get_fps_print_prefix(struct vidcap *state)
#define VIDCAP_INIT_FAIL
error ocured
#define VIDCAP_INIT_AUDIO_NOT_SUPPORTED
card does not support audio
void list_modules(enum library_class cls, int abi_version, bool full)
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_VIDEO_CAPTURE
Definition lib_common.h:78
@ SHORT_STR
Definition macros.h:133
const char * parent
Definition settings.cpp:198
const char * param
Definition settings.cpp:195
struct used to comunicate with audio capture/playback device
Definition types.h:99
enum module_class cls
Definition module.h:115
This struct represents video capture state.
const struct video_capture_info * funcs
void * state
state of the created video capture driver
uint32_t magic
For debugging. Conatins VIDCAP_MAGIC.
struct module mod
struct capture_filter * capture_filter
capture_filter_state
int(* init)(struct vidcap_params *param, void **state)
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
#define VIDCAP_MAGIC
void vidcap_params_set_parent(struct vidcap_params *params, struct module *mod)
const char * vidcap_params_get_capture_filter(const struct vidcap_params *params)
struct vidcap_params * vidcap_params_get_next(const struct vidcap_params *curr)
const char * vidcap_params_get_driver(const struct vidcap_params *params)
void vidcap_params_set_flags(struct vidcap_params *params, unsigned int flags)
void vidcap_params_set_capture_filter(struct vidcap_params *params, const char *req_capture_filter)
unsigned int vidcap_params_get_flags(const struct vidcap_params *params)