mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 11:40:22 +00:00
Added option to delay audio
This commit is contained in:
@@ -201,7 +201,7 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in
|
||||
char *audio_channel_map, const char *audio_scale,
|
||||
bool echo_cancellation, bool use_ipv6, const char *mcast_if,
|
||||
const char *audio_codec_cfg,
|
||||
bool isStd, long packet_rate)
|
||||
bool isStd, long packet_rate, int audio_delay)
|
||||
{
|
||||
struct state_audio *s = NULL;
|
||||
char *tmp, *unused = NULL;
|
||||
@@ -316,7 +316,7 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in
|
||||
s->captured = new audio_frame2;
|
||||
|
||||
tmp = strdup(addrs);
|
||||
s->audio_participants = pdb_init();
|
||||
s->audio_participants = pdb_init(audio_delay);
|
||||
addr = strtok_r(tmp, ",", &unused);
|
||||
|
||||
s->audio_network_parameters.addr = strdup(addr);
|
||||
|
||||
@@ -154,7 +154,7 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in
|
||||
char *jack_cfg, const char *fec_cfg, const char *encryption,
|
||||
char *audio_channel_map, const char *audio_scale,
|
||||
bool echo_cancellation, bool use_ipv6, const char *mcast_iface, const char *audio_codec_cfg,
|
||||
bool isStd, long packet_rate);
|
||||
bool isStd, long packet_rate, int audio_delay);
|
||||
void audio_finish(void);
|
||||
void audio_done(struct state_audio *s);
|
||||
void audio_join(struct state_audio *s);
|
||||
|
||||
15
src/main.cpp
15
src/main.cpp
@@ -124,6 +124,7 @@
|
||||
#define OPT_LDGM_DEVICE (('L' << 8) | 'D')
|
||||
#define OPT_WINDOW_TITLE (('W' << 8) | 'T')
|
||||
#define OPT_CAPABILITIES (('C' << 8) | 'C')
|
||||
#define OPT_AUDIO_DELAY (('A' << 8) | 'D')
|
||||
|
||||
#define MAX_CAPTURE_COUNT 17
|
||||
|
||||
@@ -268,6 +269,9 @@ static void usage(void)
|
||||
printf("\n");
|
||||
printf("\t--encryption <passphrase>\tKey material for encryption\n");
|
||||
printf("\n");
|
||||
printf("\t--audio-delay <delay_ms> \tAmount of time audio should be delayed to video\n");
|
||||
printf("\t \t(in non-negative miliseconds)\n");
|
||||
printf("\n");
|
||||
printf("\taddress(es) \tdestination address\n");
|
||||
printf("\n");
|
||||
printf("\t \tIf comma-separated list of addresses\n");
|
||||
@@ -447,6 +451,7 @@ int main(int argc, char *argv[])
|
||||
int bitrate = RATE_AUTO;
|
||||
|
||||
int rxtx_mode = 0;
|
||||
int audio_delay = 0;
|
||||
|
||||
#ifdef USE_MTRACE
|
||||
mtrace();
|
||||
@@ -501,6 +506,7 @@ int main(int argc, char *argv[])
|
||||
{"ldgm-device", required_argument, 0, OPT_LDGM_DEVICE},
|
||||
{"window-title", required_argument, 0, OPT_WINDOW_TITLE},
|
||||
{"capabilities", no_argument, 0, OPT_CAPABILITIES},
|
||||
{"audio-delay", required_argument, 0, OPT_AUDIO_DELAY},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int option_index = 0;
|
||||
@@ -784,6 +790,13 @@ int main(int argc, char *argv[])
|
||||
print_capabilities(CAPABILITY_CAPTURE | CAPABILITY_COMPRESS);
|
||||
return EXIT_SUCCESS;
|
||||
break;
|
||||
case OPT_AUDIO_DELAY:
|
||||
audio_delay = atoi(optarg);
|
||||
if (audio_delay < 0) {
|
||||
fprintf(stderr, "Audio delay should be non-negative!\n");
|
||||
return EXIT_FAIL_USAGE;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@@ -872,7 +885,7 @@ int main(int argc, char *argv[])
|
||||
jack_cfg, requested_audio_fec, requested_encryption,
|
||||
audio_channel_map,
|
||||
audio_scale, echo_cancellation, ipv6, requested_mcast_if,
|
||||
audio_codec, isStd, packet_rate);
|
||||
audio_codec, isStd, packet_rate, audio_delay);
|
||||
if(!uv->audio) {
|
||||
exit_uv(EXIT_FAIL_AUDIO);
|
||||
goto cleanup;
|
||||
|
||||
10
src/pdb.c
10
src/pdb.c
@@ -85,6 +85,7 @@ struct pdb {
|
||||
pdb_node_t *root;
|
||||
uint32_t magic;
|
||||
int count;
|
||||
int delay_ms;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -240,13 +241,14 @@ static pdb_node_t *pdb_delete_node(struct pdb *tree, pdb_node_t * z)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct pdb *pdb_init(void)
|
||||
struct pdb *pdb_init(int delay_ms)
|
||||
{
|
||||
struct pdb *db = malloc(sizeof(struct pdb));
|
||||
if (db != NULL) {
|
||||
db->magic = PDB_MAGIC;
|
||||
db->count = 0;
|
||||
db->root = NULL;
|
||||
db->delay_ms = delay_ms;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
@@ -266,7 +268,7 @@ void pdb_destroy(struct pdb **db_p)
|
||||
*db_p = NULL;
|
||||
}
|
||||
|
||||
static struct pdb_e *pdb_create_item(uint32_t ssrc)
|
||||
static struct pdb_e *pdb_create_item(uint32_t ssrc, int delay_ms)
|
||||
{
|
||||
struct pdb_e *p = malloc(sizeof(struct pdb_e));
|
||||
if (p != NULL) {
|
||||
@@ -282,7 +284,7 @@ static struct pdb_e *pdb_create_item(uint32_t ssrc)
|
||||
p->decoder_state = NULL;
|
||||
p->decoder_state_deleter = NULL;
|
||||
p->pt = 255;
|
||||
p->playout_buffer = pbuf_init();
|
||||
p->playout_buffer = pbuf_init(delay_ms);
|
||||
p->tfrc_state = tfrc_init(p->creation_time);
|
||||
}
|
||||
return p;
|
||||
@@ -303,7 +305,7 @@ int pdb_add(struct pdb *db, uint32_t ssrc)
|
||||
return 1;
|
||||
}
|
||||
|
||||
i = pdb_create_item(ssrc);
|
||||
i = pdb_create_item(ssrc, db->delay_ms);
|
||||
if (i == NULL) {
|
||||
debug_msg("Unable to create database entry - ssrc %x\n", ssrc);
|
||||
return 2;
|
||||
|
||||
@@ -86,7 +86,11 @@ struct pdb_e {
|
||||
|
||||
struct pdb; /* The participant database */
|
||||
|
||||
struct pdb *pdb_init(void);
|
||||
/**
|
||||
* @param delay_ms delay to be added to playback. Main reason is to give user a possibility to
|
||||
* sync audio and video.
|
||||
*/
|
||||
struct pdb *pdb_init(int delay_ms);
|
||||
void pdb_destroy(struct pdb **db);
|
||||
int pdb_add(struct pdb *db, uint32_t ssrc);
|
||||
struct pdb_e *pdb_get(struct pdb *db, uint32_t ssrc);
|
||||
|
||||
@@ -155,7 +155,7 @@ static void pbuf_validate(struct pbuf *playout_buf)
|
||||
#endif
|
||||
}
|
||||
|
||||
struct pbuf *pbuf_init(void)
|
||||
struct pbuf *pbuf_init(int delay_ms)
|
||||
{
|
||||
struct pbuf *playout_buf = NULL;
|
||||
|
||||
@@ -166,7 +166,7 @@ struct pbuf *pbuf_init(void)
|
||||
/* Playout delay... should really be adaptive, based on the */
|
||||
/* jitter, but we use a (conservative) fixed 32ms delay for */
|
||||
/* now (2 video frames at 60fps). */
|
||||
playout_buf->playout_delay = 0.032;
|
||||
playout_buf->playout_delay = 0.032 + delay_ms / 1000.0;
|
||||
} else {
|
||||
debug_msg("Failed to allocate memory for playout buffer\n");
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ typedef int decode_frame_t(struct coded_data *cdata, void *decode_data);
|
||||
/*
|
||||
* External interface:
|
||||
*/
|
||||
struct pbuf *pbuf_init(void);
|
||||
struct pbuf *pbuf_init(int delay_ms);
|
||||
void pbuf_insert(struct pbuf *playout_buf, rtp_packet *r);
|
||||
int pbuf_is_empty(struct pbuf *playout_buf);
|
||||
int pbuf_decode(struct pbuf *playout_buf, struct timeval curr_time,
|
||||
|
||||
@@ -471,7 +471,7 @@ vidcap_rtsp_init(const struct vidcap_params *params) {
|
||||
|
||||
s->vrtsp_state->device = (struct rtp *) malloc(
|
||||
(s->vrtsp_state->required_connections) * sizeof(struct rtp *));
|
||||
s->vrtsp_state->participants = pdb_init();
|
||||
s->vrtsp_state->participants = pdb_init(0);
|
||||
|
||||
s->vrtsp_state->new_frame = FALSE;
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ rtp_video_rxtx::rtp_video_rxtx(map<string, param_u> const ¶ms) :
|
||||
throw ug_runtime_error(oss.str(), EXIT_FAIL_USAGE);
|
||||
}
|
||||
|
||||
m_participants = pdb_init();
|
||||
m_participants = pdb_init(0);
|
||||
m_requested_receiver = (const char *) params.at("receiver").ptr;
|
||||
m_recv_port_number = params.at("rx_port").i;
|
||||
m_send_port_number = params.at("tx_port").i;
|
||||
|
||||
Reference in New Issue
Block a user