UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
codec.h File Reference
#include "audio/types.h"
#include <string>
#include <tuple>
Include dependency graph for codec.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  audio_codec_info_t
 
struct  audio_codec_params
 
struct  audio_compress_info
 

Macros

#define AUDIO_COMPRESS_ABI_VERSION   4
 

Enumerations

enum  audio_codec_direction_t { AUDIO_CODER , AUDIO_DECODER }
 

Functions

audio_frame2 audio_codec_compress (struct audio_codec_state *, const audio_frame2 *)
 
audio_frame2 audio_codec_decompress (struct audio_codec_state *, audio_frame2 *)
 
void audio_codec_done (struct audio_codec_state *)
 
const int * audio_codec_get_supported_samplerates (struct audio_codec_state *)
 
struct audio_codec_state * audio_codec_init (audio_codec_t audio_codec, audio_codec_direction_t)
 
struct audio_codec_state * audio_codec_init_cfg (const char *audio_codec_cfg, audio_codec_direction_t)
 
struct audio_codec_state * audio_codec_reconfigure (struct audio_codec_state *old, audio_codec_t audio_codec, audio_codec_direction_t)
 
std::vector< std::tuple< audio_codec_info_t, bool, std::string > > get_audio_codec_list ()
 
audio_codec_t get_audio_codec_to_tag (uint32_t audio_tag)
 
uint32_t get_audio_tag (audio_codec_t codec)
 
const char * get_name_to_audio_codec (audio_codec_t codec)
 
void list_audio_codecs (void)
 
struct audio_codec_params parse_audio_codec_params (const char *ccfg)
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file codec.h.

Macro Definition Documentation

◆ AUDIO_COMPRESS_ABI_VERSION

#define AUDIO_COMPRESS_ABI_VERSION   4

Definition at line 43 of file codec.h.

Referenced by audio_codec_init_real().

Enumeration Type Documentation

◆ audio_codec_direction_t

Enumerator
AUDIO_CODER 
AUDIO_DECODER 

Definition at line 45 of file codec.h.

45 {
audio_codec_direction_t
Definition codec.h:45
@ AUDIO_DECODER
Definition codec.h:47
@ AUDIO_CODER
Definition codec.h:46

Function Documentation

◆ audio_codec_compress()

audio_frame2 audio_codec_compress ( struct audio_codec_state * s,
const audio_frame2 * frame )

Audio_codec_compress compresses given audio frame.

This function has to be called iterativelly, in first iteration with frame, the others with NULL

Parameters
sstate
framein first iteration audio frame to be compressed, in following NULL
Return values
pointerpointing to data
NULLindicating that there are no data left

Definition at line 245 of file codec.cpp.

246{
247 audio_frame2 res;
248
249 if (frame != nullptr) {
250 if (s->state_count < frame->get_channel_count()) {
251 s->state = (void **) realloc(s->state, sizeof(void *) * frame->get_channel_count());
252 for (int i = s->state_count; i < frame->get_channel_count(); ++i) {
253 s->state[i] = s->funcs->init(s->desc.codec, s->direction, false, s->bitrate);
254 if (s->state[i] == nullptr) {
255 LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Error: initialization of audio codec failed!\n";
256 return {};
257 }
258 }
259 s->state_count = frame->get_channel_count();
260 }
261
262 s->desc.ch_count = frame->get_channel_count();
263 s->desc.bps = frame->get_bps();
264 s->desc.sample_rate = frame->get_sample_rate();
265 res.set_timestamp(frame->get_timestamp());
266 }
267
268 audio_channel channel;
269 channel.timestamp = frame == nullptr ? -1 : frame->get_timestamp();
270 int nonzero_channels = 0;
271 for (int i = 0; i < s->desc.ch_count; ++i) {
272 audio_channel *encode_channel = NULL;
273 if(frame) {
274 audio_channel_demux(frame, i, &channel);
275 encode_channel = &channel;
276 }
277 audio_channel *out = s->funcs->compress(s->state[i], encode_channel);
278 if (out == nullptr) {
279 continue;
280 }
281 if (!res) {
282 res.init(s->desc.ch_count, out->codec, out->bps, out->sample_rate);
283 res.set_duration(out->duration);
284 } else {
285 assert(out->bps == res.get_bps()
286 && out->sample_rate == res.get_sample_rate());
287 }
288 res.append(i, out->data, out->data_len);
289 res.set_timestamp(out->timestamp);
290 nonzero_channels += 1;
291 }
292
293 if (nonzero_channels == 0) {
294 return {};
295 }
296 return res;
297}
struct video_frame * frame
void init(int nr_channels, audio_codec_t codec, int bps, int sample_rate)
Initializes audio_frame2 for use. If already initialized, data are dropped.
Definition types.cpp:115
void set_duration(double duration)
Definition types.cpp:288
void set_timestamp(int64_t ts)
Definition types.cpp:335
int get_sample_rate() const
Definition types.cpp:275
int get_bps() const
Definition types.cpp:200
void append(audio_frame2 const &frame)
Definition types.cpp:125
#define MOD_NAME
Definition codec.cpp:55
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG(level)
Definition debug.h:313
Audio channel is a non-owning view on audio_frame2 isolating one channel.
Definition types.h:122
audio_codec_t codec
Definition types.h:127
int64_t timestamp
Definition types.h:128
const char * data
Definition types.h:125
int sample_rate
Definition types.h:124
double duration
Definition types.h:129
int data_len
Definition types.h:126
audio_desc desc
Definition codec.cpp:88
const struct audio_compress_info * funcs
Definition codec.cpp:87
void ** state
Definition codec.cpp:85
audio_codec_direction_t direction
Definition codec.cpp:89
audio_channel *(* compress)(void *, audio_channel *)
Definition codec.h:53
void *(* init)(audio_codec_t, audio_codec_direction_t, bool, int bitrate)
Definition codec.h:52
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
int bps
Definition types.h:77
audio_codec_t codec
Definition types.h:80
void audio_channel_demux(const audio_frame2 *frame, int index, audio_channel *channel)
Definition utils.cpp:528

References audio_frame2::append(), audio_channel_demux(), audio_codec_state::bitrate, audio_channel::bps, audio_desc::bps, audio_desc::ch_count, audio_channel::codec, audio_desc::codec, audio_compress_info::compress, audio_channel::data, audio_channel::data_len, audio_codec_state::desc, audio_codec_state::direction, audio_channel::duration, frame, audio_codec_state::funcs, audio_frame2::get_bps(), audio_frame2::get_sample_rate(), audio_compress_info::init, audio_frame2::init(), LOG, LOG_LEVEL_ERROR, MOD_NAME, audio_channel::sample_rate, audio_desc::sample_rate, audio_frame2::set_duration(), audio_frame2::set_timestamp(), audio_codec_state::state, audio_codec_state::state_count, and audio_channel::timestamp.

Referenced by audio_sender_thread(), and state_audio_mixer::worker().

Here is the call graph for this function:

◆ audio_codec_decompress()

audio_frame2 audio_codec_decompress ( struct audio_codec_state * s,
audio_frame2 * frame )

Definition at line 299 of file codec.cpp.

300{
301 if (s->state_count < frame->get_channel_count()) {
302 s->state = (void **) realloc(s->state, sizeof(void *) * frame->get_channel_count());
303 for(int i = s->state_count; i < frame->get_channel_count(); ++i) {
304 s->state[i] = s->funcs->init(s->desc.codec, s->direction, false, 0);
305 if(s->state[i] == NULL) {
307 "Error: initialization of audio codec "
308 "failed!\n");
309 return {};
310 }
311 }
312 s->state_count = frame->get_channel_count();
313 }
314
315#if 0
316 if (s->out->ch_count != frame->ch_count) {
317 s->out->ch_count = frame->ch_count;
318 }
319#endif
320
321 audio_frame2 ret;
322 audio_channel channel;
323 int nonzero_channels = 0;
324 bool out_frame_initialized = false;
325 for (int i = 0; i < frame->get_channel_count(); ++i) {
326 audio_channel_demux(frame, i, &channel);
327 if (channel.data_len == 0) {
328 continue;
329 }
330 audio_channel *out = s->funcs->decompress(s->state[i], &channel);
331 if (out) {
332 if (!out_frame_initialized) {
333 ret.init(frame->get_channel_count(), AC_PCM, out->bps, out->sample_rate);
334 ret.set_timestamp(frame->get_timestamp());
335 out_frame_initialized = true;
336 } else {
337 assert(out->bps == ret.get_bps()
338 && out->sample_rate == ret.get_sample_rate());
339 }
340 ret.append(i, out->data, out->data_len);
341 nonzero_channels += 1;
342 }
343 }
344
345 if (nonzero_channels != frame->get_channel_count()) {
347 "[Audio decompress] %d empty channel(s) returned!\n",
348 frame->get_channel_count() - nonzero_channels);
349 return {};
350 }
351 int max_len = 0;
352 for(int i = 0; i < frame->get_channel_count(); ++i) {
353 max_len = max<int>(max_len, ret.get_data_len(i));
354 }
355 for(int i = 0; i < frame->get_channel_count(); ++i) {
356 int len = ret.get_data_len(i);
357 if (len != max_len) {
358 LOG(LOG_LEVEL_WARNING) << "[Audio decompress] Inequal channel length detected (" << ret.get_data_len(i) << " vs " << max_len << ")!\n",
359 ret.resize(i, max_len);
360 memset(ret.get_data(i) + len, 0, max_len - len);
361 }
362 }
363
364 return ret;
365}
int void size_t * len
@ AC_PCM
Definition types.h:53
void resize(int channel, size_t len)
Definition types.cpp:183
char * get_data(int channel)
Definition types.cpp:218
size_t get_data_len(int channel) const
Definition types.cpp:228
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define max(a, b)
Definition rtp.c:98
audio_channel *(* decompress)(void *, audio_channel *)
Definition codec.h:54

References AC_PCM, audio_frame2::append(), audio_channel_demux(), audio_channel::bps, audio_desc::codec, audio_channel::data, audio_channel::data_len, audio_compress_info::decompress, audio_codec_state::desc, audio_codec_state::direction, frame, audio_codec_state::funcs, audio_frame2::get_bps(), audio_frame2::get_data(), audio_frame2::get_data_len(), audio_frame2::get_sample_rate(), audio_compress_info::init, audio_frame2::init(), len, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, log_msg(), max, audio_frame2::resize(), audio_channel::sample_rate, audio_frame2::set_timestamp(), audio_codec_state::state, and audio_codec_state::state_count.

Referenced by decode_audio_frame().

Here is the call graph for this function:

◆ audio_codec_done()

void audio_codec_done ( struct audio_codec_state * s)

Definition at line 372 of file codec.cpp.

373{
374 if(!s)
375 return;
376 for(int i = 0; i < s->state_count; ++i) {
377 s->funcs->done(s->state[i]);
378 }
379 free(s->state);
380
381 free(s);
382}
void(* done)(void *)
Definition codec.h:58

References audio_compress_info::done, audio_codec_state::funcs, audio_codec_state::state, and audio_codec_state::state_count.

Referenced by state_audio_mixer::state_audio_mixer(), am_participant::~am_participant(), audio_codec_reconfigure(), audio_decoder_destroy(), audio_done(), audio_init(), and get_audio_codec_list().

◆ audio_codec_get_supported_samplerates()

const int * audio_codec_get_supported_samplerates ( struct audio_codec_state * s)

Definition at line 367 of file codec.cpp.

368{
369 return s->funcs->get_samplerates(s->state[0]);
370}
const int *(* get_samplerates)(void *)
Definition codec.h:55

References audio_codec_state::funcs, audio_compress_info::get_samplerates, and audio_codec_state::state.

Referenced by audio_sender_thread().

◆ audio_codec_init()

struct audio_codec_state * audio_codec_init ( audio_codec_t audio_codec,
audio_codec_direction_t direction )

Definition at line 160 of file codec.cpp.

161 {
162 return audio_codec_init_real(get_name_to_audio_codec(audio_codec), direction, false);
163}
const char * get_name_to_audio_codec(audio_codec_t codec)
Definition codec.cpp:450
static struct audio_codec_state * audio_codec_init_real(const char *audio_codec_cfg, audio_codec_direction_t direction, bool try_init)
Definition codec.cpp:171

References audio_codec_init_real(), audio_codec_state::direction, and get_name_to_audio_codec().

Referenced by audio_codec_reconfigure().

Here is the call graph for this function:

◆ audio_codec_init_cfg()

struct audio_codec_state * audio_codec_init_cfg ( const char * audio_codec_cfg,
audio_codec_direction_t direction )

Definition at line 165 of file codec.cpp.

166 {
167 return audio_codec_init_real(audio_codec_cfg, direction, false);
168}

References audio_codec_init_real(), and audio_codec_state::direction.

Referenced by am_participant::am_participant(), state_audio_mixer::state_audio_mixer(), and audio_init().

Here is the call graph for this function:

◆ audio_codec_reconfigure()

struct audio_codec_state * audio_codec_reconfigure ( struct audio_codec_state * old,
audio_codec_t audio_codec,
audio_codec_direction_t direction )

Definition at line 225 of file codec.cpp.

227{
228 if (old != nullptr && old->desc.codec == audio_codec) {
229 return old;
230 }
231 audio_codec_done(old);
232 return audio_codec_init(audio_codec, direction);
233}
struct audio_codec_state * audio_codec_init(audio_codec_t audio_codec, audio_codec_direction_t direction)
Definition codec.cpp:160
void audio_codec_done(struct audio_codec_state *s)
Definition codec.cpp:372

References audio_codec_done(), audio_codec_init(), audio_desc::codec, audio_codec_state::desc, and audio_codec_state::direction.

Referenced by audio_decoder_reconfigure().

Here is the call graph for this function:

◆ get_audio_codec_list()

std::vector< std::tuple< audio_codec_info_t, bool, std::string > > get_audio_codec_list ( )

Definition at line 109 of file codec.cpp.

110{
111 vector<tuple<audio_codec_info_t, bool, string>> ret;
112
113 for (auto const &it : audio_codec_info) {
114 if(it.first != AC_NONE) {
115 struct audio_codec_state *st = (struct audio_codec_state *)
117 AUDIO_CODER, true);
118 bool available = false;
119 string desc;
120 if(st){
121 available = true;
122 desc = get_codec_desc(st);
124 }
125 ret.emplace_back(it.second, available, desc);
126 }
127 }
128
129 return ret;
130}
struct video_desc desc
@ AC_NONE
Definition types.h:52
static const unordered_map< audio_codec_t, audio_codec_info_t, hash< int > > audio_codec_info
Definition codec.cpp:67
static string get_codec_desc(struct audio_codec_state *st)
Definition codec.cpp:94

References AC_NONE, audio_codec_done(), audio_codec_info, audio_codec_init_real(), AUDIO_CODER, desc, get_codec_desc(), and get_name_to_audio_codec().

Referenced by list_audio_codecs(), and print_capabilities().

Here is the call graph for this function:

◆ get_audio_codec_to_tag()

audio_codec_t get_audio_codec_to_tag ( uint32_t audio_tag)

Definition at line 460 of file codec.cpp.

461{
462 for (auto const &it : audio_codec_info) {
463 if(it.second.tag == tag) {
464 return it.first;
465 }
466 }
467 return AC_NONE;
468}

References AC_NONE, and audio_codec_info.

Referenced by audio_decoder_reconfigure(), audio_fec_decode(), decode_audio_frame(), and parse_audio_hdr().

◆ get_audio_tag()

uint32_t get_audio_tag ( audio_codec_t codec)

Definition at line 455 of file codec.cpp.

456{
457 return audio_codec_info.at(codec).tag;
458}

References audio_codec_info.

Referenced by format_audio_header().

◆ get_name_to_audio_codec()

◆ list_audio_codecs()

void list_audio_codecs ( void )

Definition at line 132 of file codec.cpp.

132 {
133 printf("Syntax:\n");
134 col() << SBOLD(
135 SRED("\t-A <codec_name>")
136 << "[:sample_rate=<sampling_rate>][:bitrate=<bitrate>]\n");
137 col() << "\nwhere\n";
138 col() << "\t" << SBOLD("codec_name ") << " - one of the list below\n";
139 col() << "\t" << SBOLD("sample_rate")
140 << " - sample rate that will the codec used (may differ from\n"
141 << "\t\t captured)\n";
142 col() << "\t" << SBOLD("bitrate ") << " - codec bitrate "
143 << SBOLD("per channel") << " (with optional k/M suffix)\n";
144 col() << "\n";
145 printf("Supported audio codecs:\n");
146 for (auto const &it : get_audio_codec_list()) {
147 string notes;
148 if (!get<1>(it)) {
149 notes += " " TRED("unavailable");
150 } else {
151 notes = get<2>(it);
152 }
153 col() << SBOLD("\t" << get<0>(it).name)
154 << (notes.empty() ? "" : " - ") << notes << "\n";
155 }
156 col() << "\nCodecs marked as \"deprecated\" may be removed in future.\n"
157 "Codec coder marked with '*' is default.\n";
158}
vector< tuple< audio_codec_info_t, bool, string > > get_audio_codec_list()
Definition codec.cpp:109
#define SRED(x)
Definition color_out.h:85
#define SBOLD(x)
Definition color_out.h:80
#define TRED(x)
Definition color_out.h:75
const char * name
Definition settings.cpp:193

References get_audio_codec_list(), name, SBOLD, SRED, and TRED.

Referenced by parse_options_internal().

Here is the call graph for this function:

◆ parse_audio_codec_params()

struct audio_codec_params parse_audio_codec_params ( const char * ccfg)

Definition at line 402 of file codec.cpp.

403{
404 char *cfg = strdupa(ccfg);
405 char *save_ptr = nullptr;
406 char *tmp = cfg;
407 char *item = nullptr;
408
410 };
411 while ((item = strtok_r(tmp, ":", &save_ptr)) != nullptr) {
412 tmp = nullptr;
413 if (params.codec == AC_NONE) {
414 params.codec = get_audio_codec(item);
415 if (params.codec == AC_NONE) {
416 MSG(ERROR,
417 "Unknown audio codec \"%s\" given!\n",
418 item);
419 return {};
420 }
421 continue;
422 }
423 if (IS_KEY_PREFIX(item, "sample_rate")) {
424 params.sample_rate = stoi(strchr(item, '=') + 1);
425 if (params.sample_rate < 0) {
426 MSG(ERROR,
427 "Sample rate cannot be negative! given "
428 "%d\n",
429 params.sample_rate);
430 return {};
431 }
432 } else if (IS_KEY_PREFIX(item, "bitrate")) {
433 const char *val = strchr(item, '=') + 1;
434 const char *endptr = nullptr;
435 long long rate = unit_evaluate(val, &endptr);
436 if (rate <= 0 || rate > INT_MAX || endptr[0] != '\0') {
438 << "Wrong bitrate: " << val << "\n";
439 return {};
440 }
441 params.bitrate = (int) rate;
442 } else {
443 MSG(ERROR, "Unknown audio option: %s\n", item);
444 return {};
445 }
446 }
447 return params;
448}
int void * val
static audio_codec_t get_audio_codec(const char *codec)
Definition codec.cpp:385
#define MSG(l, fmt,...)
Definition debug.h:96
static struct @19 params[100]
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
Definition macros.h:138
long long unit_evaluate(const char *str, const char **endptr)
Definition misc.cpp:81
#define strdupa(s)
Definition strings.h:77
Definition hd-rum.c:27

References AC_NONE, get_audio_codec(), IS_KEY_PREFIX, LOG, LOG_LEVEL_ERROR, MSG, params, strdupa, unit_evaluate(), and val.

Referenced by audio_codec_init_real(), audio_init(), and main().

Here is the call graph for this function: