45#include <unordered_map>
55#define MOD_NAME "[acodec] "
63using std::unordered_map;
66static const unordered_map<audio_codec_t, audio_codec_info_t, hash<int>>
69 {
AC_PCM, {
"PCM", 0x0001 } },
70 {
AC_ALAW, {
"A-law", 0x0006 } },
74 {
"Opus", 0x7375704F }},
75 {
AC_G722, {
"G.722", 0x028F } },
76 {
AC_MP3, {
"MP3", 0x0055 } },
77 {
AC_AAC, {
"AAC", 0x00FF } },
78 {
AC_FLAC, {
"FLAC", 0xF1AC } },
102 if (ret ==
nullptr) {
108vector<tuple<audio_codec_info_t, bool, string>>
111 vector<tuple<audio_codec_info_t, bool, string>> ret;
118 bool available =
false;
125 ret.emplace_back(it.second, available,
desc);
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";
145 printf(
"Supported audio codecs:\n");
149 notes +=
" " TRED(
"unavailable");
154 << (notes.empty() ?
"" :
" - ") << notes <<
"\n";
156 col() <<
"\nCodecs marked as \"deprecated\" may be removed in future.\n"
157 "Codec coder marked with '*' is default.\n";
183 for (
auto const &it : audio_compressions) {
194 "Error: initialization of "
195 "audio codec failed!\n");
206 "Unable to find encoder for audio codec '%s'\n",
214 s->
state = (
void **) calloc(1,
sizeof(
void*));
228 if (old !=
nullptr && old->
desc.
codec == audio_codec) {
249 if (
frame !=
nullptr) {
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) {
254 if (s->
state[i] ==
nullptr) {
270 int nonzero_channels = 0;
275 encode_channel = &channel;
278 if (out ==
nullptr) {
290 nonzero_channels += 1;
293 if (nonzero_channels == 0) {
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) {
305 if(s->
state[i] == NULL) {
307 "Error: initialization of audio codec "
316 if (s->out->ch_count !=
frame->ch_count) {
317 s->out->ch_count =
frame->ch_count;
323 int nonzero_channels = 0;
324 bool out_frame_initialized =
false;
325 for (
int i = 0; i <
frame->get_channel_count(); ++i) {
332 if (!out_frame_initialized) {
335 out_frame_initialized =
true;
341 nonzero_channels += 1;
345 if (nonzero_channels !=
frame->get_channel_count()) {
347 "[Audio decompress] %d empty channel(s) returned!\n",
348 frame->get_channel_count() - nonzero_channels);
352 for(
int i = 0; i <
frame->get_channel_count(); ++i) {
355 for(
int i = 0; i <
frame->get_channel_count(); ++i) {
357 if (
len != max_len) {
388 if (strcasecmp(it.second.name,
codec) == 0) {
392 if (strcasecmp(
codec,
"PCMA") == 0) {
395 if (strcasecmp(
codec,
"PCMU") == 0) {
405 char *save_ptr =
nullptr;
407 char *
item =
nullptr;
411 while ((
item = strtok_r(tmp,
":", &save_ptr)) !=
nullptr) {
417 "Unknown audio codec \"%s\" given!\n",
424 params.sample_rate = stoi(strchr(
item,
'=') + 1);
425 if (
params.sample_rate < 0) {
427 "Sample rate cannot be negative! given "
433 const char *
val = strchr(
item,
'=') + 1;
434 const char *endptr =
nullptr;
436 if (rate <= 0 || rate > INT_MAX || endptr[0] !=
'\0') {
438 <<
"Wrong bitrate: " <<
val <<
"\n";
441 params.bitrate = (int) rate;
443 MSG(ERROR,
"Unknown audio option: %s\n",
item);
463 if(it.second.tag == tag) {
struct video_frame * frame
void resize(int channel, size_t len)
char * get_data(int channel)
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.
void set_duration(double duration)
void set_timestamp(int64_t ts)
size_t get_data_len(int channel) const
int get_sample_rate() const
void append(audio_frame2 const &frame)
static const unordered_map< audio_codec_t, audio_codec_info_t, hash< int > > audio_codec_info
struct audio_codec_state * audio_codec_init_cfg(const char *audio_codec_cfg, audio_codec_direction_t direction)
static string get_codec_desc(struct audio_codec_state *st)
audio_codec_t get_audio_codec_to_tag(uint32_t tag)
struct audio_codec_params parse_audio_codec_params(const char *ccfg)
struct audio_codec_state * audio_codec_init(audio_codec_t audio_codec, audio_codec_direction_t direction)
vector< tuple< audio_codec_info_t, bool, string > > get_audio_codec_list()
audio_frame2 audio_codec_decompress(struct audio_codec_state *s, audio_frame2 *frame)
const char * get_name_to_audio_codec(audio_codec_t codec)
static struct audio_codec_state * audio_codec_init_real(const char *audio_codec_cfg, audio_codec_direction_t direction, bool try_init)
audio_frame2 audio_codec_compress(struct audio_codec_state *s, const audio_frame2 *frame)
static audio_codec_t get_audio_codec(const char *codec)
struct audio_codec_state * audio_codec_reconfigure(struct audio_codec_state *old, audio_codec_t audio_codec, audio_codec_direction_t direction)
const int * audio_codec_get_supported_samplerates(struct audio_codec_state *s)
uint32_t get_audio_tag(audio_codec_t codec)
void list_audio_codecs(void)
void audio_codec_done(struct audio_codec_state *s)
#define AUDIO_COMPRESS_ABI_VERSION
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
static struct @19 params[100]
map< string, const void * > get_libraries_for_class(enum library_class cls, int abi_version, bool include_hidden)
@ LIBRARY_CLASS_AUDIO_COMPRESS
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
@ STR_LEN
"standard" string length placeholder
long long unit_evaluate(const char *str, const char **endptr)
Audio channel is a non-owning view on audio_frame2 isolating one channel.
const struct audio_compress_info * funcs
audio_codec_direction_t direction
audio_channel *(* compress)(void *, audio_channel *)
const char *(* get_codec_info)(void *, size_t buflen, char *buffer)
returns additional text data to be printed in help
audio_channel *(* decompress)(void *, audio_channel *)
const int *(* get_samplerates)(void *)
void *(* init)(audio_codec_t, audio_codec_direction_t, bool, int bitrate)
const audio_codec_t * supported_codecs
void audio_channel_demux(const audio_frame2 *frame, int index, audio_channel *channel)