refactor audio codec fmt parse

Should be almost functional equivalent as the previous version.
This commit is contained in:
Martin Pulec
2023-11-29 09:53:24 +01:00
parent 042a854209
commit 288b2c5804
5 changed files with 73 additions and 72 deletions

View File

@@ -88,6 +88,7 @@
#include "rtp/pbuf.h"
#include "tv.h"
#include "transmit.h"
#include "types.h"
#include "pdb.h"
#include "ug_runtime_error.hpp"
#include "utils/color_out.h"
@@ -305,7 +306,7 @@ int audio_init(struct state_audio **ret, struct module *parent,
s->audio_scale = opt->scale;
s->audio_sender_thread_started = s->audio_receiver_thread_started = false;
s->resample_to = get_audio_codec_sample_rate(opt->codec_cfg);
s->resample_to = parse_audio_codec_params(opt->codec_cfg).sample_rate;
s->exporter = exporter;
@@ -417,8 +418,14 @@ int audio_init(struct state_audio **ret, struct module *parent,
}
if ((s->audio_tx_mode & MODE_SENDER) && strcasecmp(opt->proto, "sdp") == 0) {
if (sdp_add_audio(rtp_is_ipv6(s->audio_network_device), opt->send_port, IF_NOT_NULL_ELSE(get_audio_codec_sample_rate(opt->codec_cfg), 48000),
audio_capture_channels, get_audio_codec(opt->codec_cfg), sdp_change_address_callback, get_root_module(parent)) != 0) {
const audio_codec_params params =
parse_audio_codec_params(opt->codec_cfg);
if (sdp_add_audio(rtp_is_ipv6(s->audio_network_device),
opt->send_port,
IF_NOT_NULL_ELSE(params.sample_rate, kHz48),
audio_capture_channels, params.codec,
sdp_change_address_callback,
get_root_module(parent)) != 0) {
assert(0 && "[SDP] Cannot add audio");
}
}

View File

@@ -43,6 +43,7 @@
#include "audio/codec.h"
#include "audio/utils.h"
#include "compat/misc.h"
#include "debug.h"
#include "lib_common.h"
#include "utils/macros.h"
@@ -169,9 +170,9 @@ struct audio_codec_state *audio_codec_init_cfg(const char *audio_codec_cfg,
static struct audio_codec_state *audio_codec_init_real(const char *audio_codec_cfg,
audio_codec_direction_t direction, bool silent) {
audio_codec_t audio_codec = get_audio_codec(audio_codec_cfg);
int bitrate = get_audio_codec_bitrate(audio_codec_cfg);
if (bitrate < 0) {
const struct audio_codec_params params =
parse_audio_codec_params(audio_codec_cfg);
if (params.codec == AC_NONE) {
return nullptr;
}
void *state = NULL;
@@ -182,9 +183,10 @@ static struct audio_codec_state *audio_codec_init_real(const char *audio_codec_c
for (auto const &it : audio_compressions) {
aci = static_cast<const struct audio_compress_info *>(it.second);
for (unsigned int j = 0; aci->supported_codecs[j] != AC_NONE; ++j) {
if (aci->supported_codecs[j] == audio_codec) {
state = aci->init(audio_codec, direction, silent, bitrate);
if(state) {
if (aci->supported_codecs[j] == params.codec) {
state = aci->init(params.codec, direction,
silent, params.bitrate);
if (state) {
break;
}
if (!silent) {
@@ -202,7 +204,7 @@ static struct audio_codec_state *audio_codec_init_real(const char *audio_codec_c
if (!silent) {
log_msg(LOG_LEVEL_ERROR,
"Unable to find encoder for audio codec '%s'\n",
get_name_to_audio_codec(audio_codec));
get_name_to_audio_codec(params.codec));
}
return NULL;
}
@@ -213,9 +215,9 @@ static struct audio_codec_state *audio_codec_init_real(const char *audio_codec_c
s->state[0] = state;
s->state_count = 1;
s->funcs = aci;
s->desc.codec = audio_codec;
s->desc.codec = params.codec;
s->direction = direction;
s->bitrate = bitrate;
s->bitrate = params.bitrate;
return s;
}
@@ -379,71 +381,51 @@ void audio_codec_done(struct audio_codec_state *s)
free(s);
}
audio_codec_t get_audio_codec(const char *codec_str) {
char *codec = strdup(codec_str);
if (strchr(codec, ':')) {
*strchr(codec, ':') = '\0';
}
static audio_codec_t
get_audio_codec(const char *codec)
{
for (auto const &it : audio_codec_info) {
if(strcasecmp(it.second.name, codec) == 0) {
free(codec);
if (strcasecmp(it.second.name, codec) == 0) {
return it.first;
}
}
free(codec);
return AC_NONE;
}
/**
* Caller must free() the returned buffer
*/
static char *get_val_from_cfg(const char *audio_codec_cfg, const char *key)
struct audio_codec_params
parse_audio_codec_params(const char *ccfg)
{
char *cfg = strdup(audio_codec_cfg);
char *tmp = cfg;
char *item, *save_ptr, *ret;
char *cfg = strdupa(ccfg);
char *save_ptr = nullptr;
char *tmp = cfg;
char *item = nullptr;
while ((item = strtok_r(cfg, ":", &save_ptr)) != NULL) {
if (strncasecmp(key, item, strlen(key)) == 0) {
ret = strdup(item + strlen(key));
free(tmp);
return ret;
struct audio_codec_params params {
};
while ((item = strtok_r(tmp, ":", &save_ptr)) != nullptr) {
tmp = nullptr;
if (params.codec == AC_NONE) {
params.codec = get_audio_codec(item);
if (params.codec == AC_NONE) {
return {};
}
continue;
}
cfg = NULL;
}
free(tmp);
return NULL;
}
/**
* @returns user specified sample rate or 0 if unspecified
*/
int get_audio_codec_sample_rate(const char *audio_codec_cfg)
{
char *val = get_val_from_cfg(audio_codec_cfg, "sample_rate=");
if (val) {
int ret = atoi(val);
free(val);
return ret;
} else {
return 0;
}
}
int get_audio_codec_bitrate(const char *audio_codec_cfg)
{
char *val = get_val_from_cfg(audio_codec_cfg, "bitrate=");
if (val) {
long long ret = unit_evaluate(val);
if (ret <= 0 && ret > INT_MAX) {
LOG(LOG_LEVEL_ERROR) << "Wrong bitrate: " << val << "\n";
return -1;
if (strstr(item, "sample_rate=") == item) {
params.sample_rate = atoi(strchr(item, '=') + 1);
}
if (strstr(item, "bitrate=") == item) {
const char *val = strchr(item, '=') + 1;
long long rate = unit_evaluate(val);
if (rate <= 0 && rate > INT_MAX) {
LOG(LOG_LEVEL_ERROR)
<< "Wrong bitrate: " << val << "\n";
return {};
}
params.bitrate = (int) rate;
}
free(val);
return ret;
} else {
return 0;
}
return params;
}
const char *get_name_to_audio_codec(audio_codec_t codec)
@@ -468,7 +450,9 @@ audio_codec_t get_audio_codec_to_tag(uint32_t tag)
bool check_audio_codec(const char *audio_codec_cfg)
{
if (get_audio_codec(audio_codec_cfg) == AC_NONE) {
const struct audio_codec_params params =
parse_audio_codec_params(audio_codec_cfg);
if (params.codec == AC_NONE) {
LOG(LOG_LEVEL_ERROR) << "Unknown audio codec given!\n";
return false;
}

View File

@@ -89,9 +89,13 @@ extern "C" {
#endif // defined __cplusplus
void list_audio_codecs(void);
audio_codec_t get_audio_codec(const char *audio_codec_cfg);
int get_audio_codec_sample_rate(const char *audio_codec_cfg);
int get_audio_codec_bitrate(const char *audio_codec_cfg);
struct audio_codec_params {
audio_codec_t codec;
int sample_rate;
int bitrate;
};
struct audio_codec_params parse_audio_codec_params(const char *ccfg);
const char *get_name_to_audio_codec(audio_codec_t codec);
uint32_t get_audio_tag(audio_codec_t codec);
audio_codec_t get_audio_codec_to_tag(uint32_t audio_tag);

View File

@@ -1350,7 +1350,10 @@ int main(int argc, char *argv[])
col() << TBOLD("Audio playback : ") << opt.audio.recv_cfg << "\n";
col() << TBOLD("MTU : ") << opt.requested_mtu << " B\n";
col() << TBOLD("Video compression: ") << opt.requested_compression << "\n";
col() << TBOLD("Audio codec : ") << get_name_to_audio_codec(get_audio_codec(opt.audio.codec_cfg)) << "\n";
col() << TBOLD("Audio codec : ")
<< get_name_to_audio_codec(
parse_audio_codec_params(opt.audio.codec_cfg).codec)
<< "\n";
col() << TBOLD("Network protocol : ") << video_rxtx::get_long_name(opt.video_protocol) << "\n";
col() << TBOLD("Audio FEC : ") << opt.audio.fec_cfg << "\n";
col() << TBOLD("Video FEC : ") << opt.requested_video_fec << "\n";
@@ -1472,8 +1475,10 @@ int main(int argc, char *argv[])
params["opts"].str = opt.video_protocol_opts;
// RTSP
params["audio_codec"].l = get_audio_codec(opt.audio.codec_cfg);
params["audio_sample_rate"].i = get_audio_codec_sample_rate(opt.audio.codec_cfg) ? get_audio_codec_sample_rate(opt.audio.codec_cfg) : 48000;
auto ac_params = parse_audio_codec_params(opt.audio.codec_cfg);
params["audio_codec"].l = ac_params.codec;
params["audio_sample_rate"].i =
IF_NOT_NULL_ELSE(ac_params.sample_rate, kHz48);
params["audio_channels"].i = audio_capture_channels;
params["audio_bps"].i = 2;
params["a_rx_port"].i = opt.audio.recv_port;

View File

@@ -140,6 +140,7 @@ struct pixfmt_desc {
};
enum {
kHz48 = 48000,
kHz90 = 90000, ///< timestamp time base
};