UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
aggregate.c
Go to the documentation of this file.
1
7/*
8 * Copyright (c) 2012-2023 CESNET z.s.p.o.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, is permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * 3. Neither the name of CESNET nor the names of its contributors may be
23 * used to endorse or promote products derived from this software without
24 * specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
28 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
30 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
37 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#include <assert.h> // for assert
41#include <stdio.h> // for fprintf, NULL, printf, stderr
42#include <stdlib.h> // for free, calloc
43#include <string.h> // for strcmp
44#include <sys/time.h> // for gettimeofday, timeval
45
46#include "debug.h" // for log_msg, LOG_LEVEL_INFO
47#include "lib_common.h" // for REGISTER_MODULE, library_class
48#include "tv.h" // for tv_diff
49#include "types.h" // for video_frame, tile, device_info (pt...
50#include "video_capture.h" // for vidcap_done, VIDCAP_INIT_FAIL, ini...
51#include "video_capture_params.h" // for vidcap_params_get_flags, vidcap_pa...
52#include "video_frame.h" // for vf_get_tile, vf_alloc, vf_free
53
54struct audio_frame;
55struct vidcap_params;
56
57/* prototypes of functions defined in this module */
58static void show_help(void);
59
60static void show_help()
61{
62 printf("Aggregate capture\n");
63 printf("Usage\n");
64 printf("\t-t aggregate -t <dev1_config> -t <dev2_config> ....]\n");
65 printf("\t\twhere devn_config is a complete configuration string of device involved in an aggregate device\n");
66
67}
68
70 struct vidcap **devices;
72
75 int frames;
76 struct timeval t, t0;
77
79};
80
81
82static void vidcap_aggregate_probe(struct device_info **cards, int *count, void (**deleter)(void *))
83{
84 *cards = NULL;
85 *count = 0;
86 *deleter = free;
87}
88
89static int
91{
92 struct vidcap_aggregate_state *s;
93
94 printf("vidcap_aggregate_init\n");
95
96
97 s = (struct vidcap_aggregate_state *) calloc(1, sizeof(struct vidcap_aggregate_state));
98 if(s == NULL) {
99 printf("Unable to allocate aggregate capture state\n");
100 return VIDCAP_INIT_FAIL;
101 }
102
103 s->audio_source_index = -1;
104 s->frames = 0;
105 gettimeofday(&s->t0, NULL);
106
107 if(vidcap_params_get_fmt(params) && strcmp(vidcap_params_get_fmt(params), "") != 0) {
108 show_help();
109 free(s);
110 return VIDCAP_INIT_NOERR;
111 }
112
113
114 s->devices_cnt = 0;
115 struct vidcap_params *tmp = params;
116 while((tmp = vidcap_params_get_next(tmp))) {
117 if (vidcap_params_get_driver(tmp) != NULL)
118 s->devices_cnt++;
119 else
120 break;
121 }
122
123 s->devices = calloc(s->devices_cnt, sizeof(struct vidcap *));
124 tmp = params;
125 for (int i = 0; i < s->devices_cnt; ++i) {
126 tmp = vidcap_params_get_next(tmp);
127
130 }
131
133 if(ret != 0) {
134 fprintf(stderr, "[aggregate] Unable to initialize device %d (%s:%s).\n",
137 goto error;
138 }
139 }
140
141 s->captured_frames = calloc(s->devices_cnt, sizeof(struct video_frame *));
142
143 s->frame = vf_alloc(s->devices_cnt);
144
145 *state = s;
146 return VIDCAP_INIT_OK;
147
148error:
149 if(s->devices) {
150 int i;
151 for (i = 0u; i < s->devices_cnt; ++i) {
152 if(s->devices[i]) {
153 vidcap_done(s->devices[i]);
154 }
155 }
156 }
157 free(s);
158 return VIDCAP_INIT_FAIL;
159}
160
161static void
163{
165
166 assert(s != NULL);
167
168 if (s != NULL) {
169 int i;
170 for (i = 0; i < s->devices_cnt; ++i) {
171 vidcap_done(s->devices[i]);
172 }
173 }
174
175 vf_free(s->frame);
176 free(s);
177}
178
179static struct video_frame *
181{
183 struct audio_frame *audio_frame = NULL;
184 struct video_frame *frame = NULL;
185
186 for (int i = 0; i < s->devices_cnt; ++i) {
188 }
189
190 *audio = NULL;
191
192 for (int i = 0; i < s->devices_cnt; ++i) {
193 frame = NULL;
194 while(!frame) {
196 }
197 if (i == 0) {
200 s->frame->fps = frame->fps;
201 }
202 if (s->audio_source_index == -1 && audio_frame != NULL) {
203 fprintf(stderr, "[aggregate] Locking device #%d as an audio source.\n",
204 i);
205 s->audio_source_index = i;
206 }
207 if (s->audio_source_index == i) {
209 }
210 if (frame->color_spec != s->frame->color_spec ||
211 frame->fps != s->frame->fps ||
213 fprintf(stderr, "[aggregate] Different format detected: ");
214 if(frame->color_spec != s->frame->color_spec)
215 fprintf(stderr, "codec");
217 fprintf(stderr, "interlacing");
218 if(frame->fps != s->frame->fps)
219 fprintf(stderr, "FPS (%.2f and %.2f)", frame->fps, s->frame->fps);
220 fprintf(stderr, "\n");
221
222 return NULL;
223 }
228 s->captured_frames[i] = frame;
229 }
230 s->frames++;
231 gettimeofday(&s->t, NULL);
232 double seconds = tv_diff(s->t, s->t0);
233 if (seconds >= 5) {
234 float fps = s->frames / seconds;
235 log_msg(LOG_LEVEL_INFO, "[aggregate cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps);
236 s->t0 = s->t;
237 s->frames = 0;
238 }
239
240 return s->frame;
241}
242
250
252
void ** state
struct video_frame * frame
struct audio_frame ** audio
int void(** deleter)(void *))
struct video_frame * vf_alloc(int count)
Allocates blank video frame.
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct audio_frame audio_frame
struct used to comunicate with audio capture/playback device
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
#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....
#define VIDCAP_NO_GENERIC_FPS_INDICATOR
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
#define VIDCAP_INIT_FAIL
error ocured
int count
Definition hd-rum.c:44
static struct @19 params[100]
@ LIBRARY_CLASS_VIDEO_CAPTURE
Definition lib_common.h:78
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
struct used to comunicate with audio capture/playback device
Definition types.h:99
unsigned int width
Definition types.h:280
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
unsigned int data_len
length of the data
Definition types.h:288
unsigned int height
Definition types.h:281
struct timeval t t0
Definition aggregate.c:76
struct video_frame ** captured_frames
Definition aggregate.c:73
struct video_frame * frame
Definition aggregate.c:74
struct vidcap ** devices
Definition aggregate.c:70
This struct represents video capture state.
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
enum interlacing_t interlacing
Definition types.h:307
double fps
Definition types.h:308
codec_t color_spec
Definition types.h:306
double tv_diff(struct timeval curr_time, struct timeval prev_time)
Definition tv.c:97
static const struct video_capture_info vidcap_aggregate_info
Definition aggregate.c:243
static void vidcap_aggregate_done(void *state)
Definition aggregate.c:162
static struct video_frame * vidcap_aggregate_grab(void *state, struct audio_frame **audio)
Definition aggregate.c:180
static void vidcap_aggregate_probe(struct device_info **cards, int *count, void(**deleter)(void *))
Definition aggregate.c:82
static int vidcap_aggregate_init(struct vidcap_params *params, void **state)
Definition aggregate.c:90
static void show_help(void)
Definition aggregate.c:60
struct module * vidcap_params_get_parent(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)
const char * vidcap_params_get_fmt(const struct vidcap_params *params)
unsigned int vidcap_params_get_flags(const struct vidcap_params *params)
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].
#define VIDEO_FRAME_DISPOSE(frame)
Definition video_frame.h:76