UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
pipe.cpp
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2014-2023 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#include <cassert>
39#include <cstring>
40#include <iostream>
41#include <list>
42#include <mutex>
43
44#include "audio/types.h"
45#include "audio/utils.h"
46#include "debug.h"
47#include "lib_common.h"
48#include "video.h"
49#include "video_display.h"
51
52#define MOD_NAME "[pipe] "
53
54using std::cout;
55using std::list;
56using std::lock_guard;
57using std::mutex;
58
59struct state_pipe {
60 struct module *parent;
63 struct video_desc desc{};
64 list<struct audio_frame *> audio_frames{};
65 mutex audio_lock{};
66};
67
68static void display_pipe_usage() {
69 cout << "Usage:\n"
70 "\t-d pipe:<ptr>[:codec=<c>]\n";
71}
72
77static void *display_pipe_init(struct module *parent, const char *fmt, unsigned int flags)
78{
80 codec_t decode_to = VIDEO_CODEC_NONE;
81 frame_recv_delegate *delegate;
82
83 if (!fmt || strlen(fmt) == 0 || strcmp(fmt, "help") == 0) {
84 fprintf(stderr, "Pipe dummy video driver. For internal usage - please do not use.\n");
85 if (fmt != nullptr && strcmp(fmt, "help") == 0) {
87 }
88 return nullptr;
89 }
90
91 sscanf(fmt, "%p", &delegate);
92 if (strchr(fmt, ':') != nullptr) {
93 fmt = strchr(fmt, ':') + 1;
94 if (strstr(fmt, "codec=") == fmt) {
95 const char *codec_name = fmt + strlen("codec=");
96 decode_to = get_codec_from_name(codec_name);
97 if (decode_to == VIDEO_CODEC_NONE) {
98 LOG(LOG_LEVEL_ERROR) << "Wrong codec name: " << codec_name << "\n";
99 return nullptr;
100 }
101 } else {
103 return nullptr;
104 }
105 }
106
107 auto *s = new state_pipe{parent, delegate, decode_to};
108
109 return s;
110}
111
112static void display_pipe_done(void *state)
113{
114 struct state_pipe *s = (struct state_pipe *)state;
115
116 for (auto & a : s->audio_frames) {
117 free(a->data);
118 free(a);
119 }
120 delete s;
121}
122
124{
125 struct state_pipe *s = (struct state_pipe *)state;
126
127 struct video_frame *out = vf_alloc_desc_data(s->desc);
128 // explicit dispose is needed because we do not process the frame
129 // by ourselves but it is passed to further processing
131 return out;
132}
133
135 free(f->data);
136 free(f);
137}
138
140{
141 lock_guard<mutex> lk(s->audio_lock);
142 size_t len = 0;
143 if (s->audio_frames.empty()) {
144 return nullptr;
145 }
147 for (auto it = s->audio_frames.begin(); it != s->audio_frames.end(); ) {
149 LOG(LOG_LEVEL_WARNING) << "[pipe] Discarding audio - incompatible format!\n";
150 free((*it)->data);
151 free(*it);
152 it = s->audio_frames.erase(it);
153 continue;
154 }
155 len += (*it)->data_len;
156 ++it;
157 }
158 if (len == 0) {
159 return nullptr;
160 }
161 auto out = (struct audio_frame *) calloc(1, sizeof(struct audio_frame));
163 out->max_size = len;
164 out->data = (char *) malloc(len);
165 for (auto it = s->audio_frames.begin(); it != s->audio_frames.end(); ) {
166 append_audio_frame(out, (*it)->data, (*it)->data_len);
167 free((*it)->data);
168 free(*it);
169 it = s->audio_frames.erase(it);
170 }
171 out->dispose = display_pipe_dispose_audio;
172 return out;
173}
174
175static bool display_pipe_putf(void *state, struct video_frame *frame, long long flags)
176{
177 struct state_pipe *s = (struct state_pipe *) state;
178
179 if (flags == PUTF_DISCARD) {
181 return true;
182 }
183
184 struct audio_frame *af = display_pipe_get_audio(s);
186
187 return true;
188}
189
190static bool
191get_codecs(struct state_pipe *s, void *val, size_t *len)
192{
193 if (s->decode_to != VIDEO_CODEC_NONE) {
194 if (sizeof(codec_t) > *len) {
195 MSG(ERROR, "Insufficient prop length %zu B!\n", *len);
196 return false;
197 }
198 memcpy(val, &s->decode_to, sizeof(s->decode_to));
199 *len = sizeof s->decode_to;
200 return true;
201 }
202 auto *out = (codec_t *) val;
203 const void *end = (char *) val + *len;
204 for (int i = VC_FIRST; i < VIDEO_CODEC_COUNT; ++i) {
205 const auto c = (codec_t) i;
206 if (is_codec_opaque(c)) {
207 continue;
208 }
209 if (out + 1 > end) {
210 MSG(ERROR, "Insufficient prop length %zu B!\n", *len);
211 return false;
212 }
213 memcpy(out++, &c, sizeof c);
214 }
215 *len = (char *) out - (char *) val;
216 return true;
217}
218
219static bool display_pipe_get_property(void *state, int property, void *val, size_t *len)
220{
221 auto *s = static_cast<struct state_pipe *>(state);
222 enum interlacing_t supported_il_modes[] = {PROGRESSIVE, INTERLACED_MERGED, SEGMENTED_FRAME};
223 int rgb_shift[] = {0, 8, 16};
224
225 switch (property) {
227 return get_codecs(s, val, len);
228 break;
230 if(sizeof(rgb_shift) > *len) {
231 return false;
232 }
233 memcpy(val, rgb_shift, sizeof(rgb_shift));
234 *len = sizeof(rgb_shift);
235 break;
237 *(int *) val = PITCH_DEFAULT;
238 *len = sizeof(int);
239 break;
241 if(sizeof(supported_il_modes) <= *len) {
242 memcpy(val, supported_il_modes, sizeof(supported_il_modes));
243 } else {
244 return false;
245 }
246 *len = sizeof(supported_il_modes);
247 break;
250 *len = sizeof(int);
251 break;
253 {
254 assert (*len >= sizeof(struct audio_desc));
255 struct audio_desc *desc = (struct audio_desc *) val;
256 desc->codec = AC_PCM; // decompress
257 }
258 break;
259 default:
260 return false;
261 }
262 return true;
263}
264
266{
267 struct state_pipe *s = (struct state_pipe *) state;
268
269 s->desc = desc;
270
271 return true;
272}
273
274static void display_pipe_put_audio_frame(void *state, const struct audio_frame *frame)
275{
276 auto s = (struct state_pipe *) state;
277 lock_guard<mutex> lk(s->audio_lock);
278 s->audio_frames.push_back(audio_frame_copy(frame, false));
279}
280
282 int sample_rate)
283{
284 UNUSED(state);
288
289 return true;
290}
291
292static void display_pipe_probe(struct device_info **available_cards, int *count, void (**deleter)(void *)) {
294 *available_cards = nullptr;
295 *count = 0;
296}
297
311
313
#define UNUSED(x)
void ** state
int void * val
struct video_desc desc
int int int sample_rate
int int channels
struct video_frame * frame
const char * fmt
int void size_t * len
const char unsigned int flags
int void(** deleter)(void *))
int property
int quant_samples
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
codec_t get_codec_from_name(const char *name)
This file contains definition of some common audio types.
@ AC_PCM
Definition types.h:53
virtual void frame_arrived(struct video_frame *, struct audio_frame *)=0
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MSG(l, fmt,...)
Definition debug.h:96
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define PITCH_DEFAULT
default pitch, i. e. respective linesize
#define PUTF_DISCARD
#define VIDEO_DISPLAY_ABI_VERSION
#define DISPLAY_NO_GENERIC_FPS_INDICATOR
@ DISPLAY_PROPERTY_BUF_PITCH
requested framebuffer pitch - int (bytes), may be PITCH_DEFAULT
@ DISPLAY_PROPERTY_RGB_SHIFT
red,green,blue shift - int[3] (bits)
@ DISPLAY_PROPERTY_SUPPORTED_IL_MODES
display supported interlacing modes - enum interlacing_t[]
@ DISPLAY_PROPERTY_VIDEO_MODE
requested video mode - int (one of display_prop_vid_mode)
@ DISPLAY_PROPERTY_CODECS
list of natively supported codecs - codec_t[]
@ DISPLAY_PROPERTY_AUDIO_FORMAT
@ DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES
framebuffer consists of separate tiles
int count
Definition hd-rum.c:44
@ LIBRARY_CLASS_VIDEO_DISPLAY
Definition lib_common.h:79
#define REGISTER_HIDDEN_MODULE(name, info, lclass, abi)
Definition lib_common.h:156
static bool display_pipe_reconfigure_audio(void *state, int quant_samples, int channels, int sample_rate)
Definition pipe.cpp:281
static bool display_pipe_reconfigure(void *state, struct video_desc desc)
Definition pipe.cpp:265
static bool display_pipe_putf(void *state, struct video_frame *frame, long long flags)
Definition pipe.cpp:175
static struct audio_frame * display_pipe_get_audio(struct state_pipe *s)
Definition pipe.cpp:139
static struct video_frame * display_pipe_getf(void *state)
Definition pipe.cpp:123
static bool get_codecs(struct state_pipe *s, void *val, size_t *len)
Definition pipe.cpp:191
static void display_pipe_probe(struct device_info **available_cards, int *count, void(**deleter)(void *))
Definition pipe.cpp:292
static void display_pipe_usage()
Definition pipe.cpp:68
static void display_pipe_put_audio_frame(void *state, const struct audio_frame *frame)
Definition pipe.cpp:274
static bool display_pipe_get_property(void *state, int property, void *val, size_t *len)
Definition pipe.cpp:219
static void display_pipe_dispose_audio(struct audio_frame *f)
Definition pipe.cpp:134
static const struct video_display_info display_pipe_info
Definition pipe.cpp:298
static void * display_pipe_init(struct module *parent, const char *fmt, unsigned int flags)
Definition pipe.cpp:77
static void display_pipe_done(void *state)
Definition pipe.cpp:112
const char * parent
Definition settings.cpp:198
struct used to comunicate with audio capture/playback device
Definition types.h:99
char * data
Definition types.h:102
mutex audio_lock
Definition pipe.cpp:65
codec_t decode_to
Definition pipe.cpp:62
struct module * parent
Definition pipe.cpp:60
list< struct audio_frame * > audio_frames
Definition pipe.cpp:64
frame_recv_delegate * delegate
Definition pipe.cpp:61
void(* dispose)(struct video_frame *)
Definition types.h:245
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct video_frame_callbacks callbacks
Definition types.h:324
interlacing_t
Definition types.h:163
@ PROGRESSIVE
progressive frame
Definition types.h:164
@ SEGMENTED_FRAME
Segmented frame. Contains the same data as progressive frame.
Definition types.h:168
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
Definition types.h:167
codec_t
Definition types.h:65
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ VC_FIRST
Definition types.h:69
@ VIDEO_CODEC_COUNT
count of known video codecs (including VIDEO_CODEC_NONE)
Definition types.h:108
struct audio_desc audio_desc_from_frame(const struct audio_frame *frame)
Definition utils.cpp:196
bool audio_desc_eq(struct audio_desc a1, struct audio_desc a2)
Definition utils.cpp:189
void audio_frame_write_desc(struct audio_frame *f, struct audio_desc desc)
Definition utils.cpp:220
bool append_audio_frame(struct audio_frame *frame, char *data, size_t data_len)
Definition utils.cpp:620
struct audio_frame * audio_frame_copy(const struct audio_frame *src, bool keep_size)
Definition utils.cpp:633
This is an umbrella header for video functions.
bool is_codec_opaque(codec_t codec)
#define VIDEO_FRAME_DISPOSE(frame)
Definition video_frame.h:76