mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 15:40:21 +00:00
refactor audio codec fmt parse
Should be almost functional equivalent as the previous version.
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
src/main.cpp
11
src/main.cpp
@@ -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;
|
||||
|
||||
@@ -140,6 +140,7 @@ struct pixfmt_desc {
|
||||
};
|
||||
|
||||
enum {
|
||||
kHz48 = 48000,
|
||||
kHz90 = 90000, ///< timestamp time base
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user