MT#55283 Add output-mixed-per-media

closes #1808

Change-Id: I70098382060b7522e7efd2fc8703ce526a61d461
pull/1819/head
Richard Fuchs 1 year ago
parent ff98b83f6f
commit 57c490f817

@ -2866,6 +2866,9 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q *
* the dialogue */
media = __get_media(monologue, sp, flags, 0);
other_media = __get_media(other_ml, sp, flags, 0);
media->media_sdp_id = sp->media_sdp_id;
other_media->media_sdp_id = sp->media_sdp_id;
/* OTHER is the side which has sent the message. SDP parameters in
* "sp" are as advertised by OTHER side. The message will be sent to
* THIS side. Parameters sent to THIS side may be overridden by

@ -946,9 +946,9 @@ static void setup_stream_proc(struct packet_stream *stream) {
if (ML_ISSET(ml, NO_RECORDING))
return;
len = snprintf(buf, sizeof(buf), "TAG %u MEDIA %u TAG-MEDIA %u COMPONENT %u FLAGS %" PRIu64,
ml->unique_id, media->unique_id, media->index, stream->component,
atomic64_get_na(&stream->ps_flags));
len = snprintf(buf, sizeof(buf), "TAG %u MEDIA %u TAG-MEDIA %u COMPONENT %u FLAGS %" PRIu64 " MEDIA-SDP-ID %i",
ml->unique_id, media->unique_id, media->index, stream->component,
atomic64_get_na(&stream->ps_flags), media->media_sdp_id);
append_meta_chunk(recording, buf, len, "STREAM %u details", stream->unique_id);
len = snprintf(buf, sizeof(buf), "tag-%u-media-%u-component-%u-%s-id-%u",

@ -137,6 +137,8 @@ struct sdp_media {
struct sdp_attributes attributes;
GQueue format_list; /* list of slice-alloc'd str objects */
enum media_type media_type_id;
int media_sdp_id;
unsigned int legacy_osrtp:1;
};
@ -1252,6 +1254,7 @@ int sdp_parse(str *body, sdp_sessions_q *sessions, const sdp_ng_flags *flags) {
struct sdp_attributes *attrs;
struct sdp_attribute *attr;
str *adj_s;
int media_sdp_id = 0;
b = body->s;
end = str_end(body);
@ -1332,7 +1335,7 @@ new_session:
t_queue_push_tail(&session->media_streams, media);
media->s.s = b;
media->rr = media->rs = -1;
media->media_sdp_id = media_sdp_id++;
break;
case 'c':
@ -1810,6 +1813,7 @@ int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_f
sp = g_slice_alloc0(sizeof(*sp));
sp->index = ++num;
codec_store_init(&sp->codecs, NULL);
sp->media_sdp_id = media->media_sdp_id;
errstr = "No address info found for stream";
if (!flags->fragment

@ -355,6 +355,10 @@ sufficient for a standard installation of rtpengine.
Remove the local file if the HTTP request was successful. Note that this
option is only useful if __\-\-notify-record__ is also enabled.
- __\-\-output-mixed-per-media__
Forces one channel per media instead of SSRC. Note that this
option is only useful if __\-\-output-mixed__ is also enabled.
## EXIT STATUS
- __0__

@ -396,6 +396,7 @@ struct stream_params {
str media_id;
struct t38_options t38_options;
str tls_id;
int media_sdp_id;
};
struct endpoint_map {
@ -549,6 +550,7 @@ struct call_media {
// lists are append-only
dtmf_event_q dtmf_recv;
dtmf_event_q dtmf_send;
int media_sdp_id;
#ifdef WITH_TRANSCODING
encoder_callback_t encoder_callback;

@ -115,7 +115,7 @@ static int decoder_got_frame(decoder_t *dec, AVFrame *frame, void *sp, void *dp)
if (metafile->mix_out) {
dbg("adding packet from stream #%lu to mix output", stream->id);
if (G_UNLIKELY(deco->mixer_idx == (unsigned int) -1))
deco->mixer_idx = mix_get_index(metafile->mix, ssrc);
deco->mixer_idx = mix_get_index(metafile->mix, ssrc, stream->media_sdp_id);
format_t actual_format;
if (output_config(metafile->mix_out, &dec->dest_format, &actual_format))
goto no_mix_out;

@ -67,6 +67,7 @@ int notify_threads = 5;
int notify_retries = 10;
gboolean notify_record;
gboolean notify_purge;
gboolean mix_output_per_media = 0;
static GQueue threads = G_QUEUE_INIT; // only accessed from main thread
@ -225,6 +226,7 @@ static void options(int *argc, char ***argv) {
{ "notify-no-verify", 0, 0, G_OPTION_ARG_NONE, &notify_nverify,"Don't verify HTTPS peer certificate", NULL },
{ "notify-concurrency", 0, 0, G_OPTION_ARG_INT, &notify_threads,"How many simultaneous requests", "INT" },
{ "notify-retries", 0, 0, G_OPTION_ARG_INT, &notify_retries,"How many times to retry failed requesets","INT" },
{ "output-mixed-per-media",0,0, G_OPTION_ARG_NONE, &mix_output_per_media,"Mix participating sources into a single output", NULL },
#if CURL_AT_LEAST_VERSION(7,56,0)
{ "notify-record", 0, 0, G_OPTION_ARG_NONE, &notify_record, "Also attach recorded file to request", NULL },
{ "notify-purge", 0, 0, G_OPTION_ARG_NONE, &notify_purge, "Remove the local file if notify success", NULL },

@ -49,7 +49,7 @@ extern int notify_threads;
extern int notify_retries;
extern gboolean notify_record;
extern gboolean notify_purge;
extern gboolean mix_output_per_media;
extern volatile int shutdown_flag;

@ -105,12 +105,12 @@ static void meta_stream_interface(metafile_t *mf, unsigned long snum, char *cont
// mf is locked
static void meta_stream_details(metafile_t *mf, unsigned long snum, char *content) {
dbg("stream %lu details %s", snum, content);
unsigned int tag, media, tm, cmp;
unsigned int tag, media, tm, cmp, media_sdp_id;
uint64_t flags;
if (sscanf_match(content, "TAG %u MEDIA %u TAG-MEDIA %u COMPONENT %u FLAGS %" PRIu64,
&tag, &media, &tm, &cmp, &flags) != 5)
if (sscanf_match(content, "TAG %u MEDIA %u TAG-MEDIA %u COMPONENT %u FLAGS %" PRIu64 " MEDIA-SDP-ID %i",
&tag, &media, &tm, &cmp, &flags, &media_sdp_id) != 6)
return;
stream_details(mf, snum, tag);
stream_details(mf, snum, tag, media_sdp_id);
}

@ -83,8 +83,15 @@ static void mix_input_reset(mix_t *mix, unsigned int idx) {
}
unsigned int mix_get_index(mix_t *mix, void *ptr) {
unsigned int mix_get_index(mix_t *mix, void *ptr, unsigned int media_sdp_id) {
unsigned int next = mix->next_idx++;
if (mix_output_per_media) {
next = media_sdp_id;
if (next >= mix_num_inputs) {
ilog(LOG_WARNING, "Error with mix_output_per_media sdp_label next %i is bigger than mix_num_inputs %i", next, mix_num_inputs );
}
}
if (next < mix_num_inputs) {
// must be unused
mix->input_ref[next] = ptr;
@ -182,6 +189,8 @@ int mix_config(mix_t *mix, const format_t *format) {
err = "failed to link abuffer to amix";
if (avfilter_link(mix->src_ctxs[i], 0, mix->amix_ctx, i))
goto err;
}
// sink
@ -198,6 +207,7 @@ int mix_config(mix_t *mix, const format_t *format) {
if (avfilter_link(mix->amix_ctx, 0, mix->sink_ctx, 0))
goto err;
// finish up
err = "failed to configure filter chain";
if (avfilter_graph_config(mix->graph, NULL))

@ -10,8 +10,6 @@ mix_t *mix_new(void);
void mix_destroy(mix_t *mix);
int mix_config(mix_t *, const format_t *format);
int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *, output_t *output);
unsigned int mix_get_index(mix_t *, void *);
unsigned int mix_get_index(mix_t *, void *, unsigned int);
#endif

@ -138,9 +138,10 @@ void stream_open(metafile_t *mf, unsigned long id, char *name) {
epoll_add(stream->fd, EPOLLIN, &stream->handler);
}
void stream_details(metafile_t *mf, unsigned long id, unsigned int tag) {
void stream_details(metafile_t *mf, unsigned long id, unsigned int tag, unsigned int media_sdp_id) {
stream_t *stream = stream_get(mf, id);
stream->tag = tag;
stream->media_sdp_id = media_sdp_id;
}
void stream_forwarding_on(metafile_t *mf, unsigned long id, unsigned int on) {

@ -4,8 +4,9 @@
#include "types.h"
void stream_open(metafile_t *mf, unsigned long id, char *name);
void stream_details(metafile_t *mf, unsigned long id, unsigned int tag);
void stream_details(metafile_t *mf, unsigned long id, unsigned int tag, unsigned int media_sdp_id);
void stream_forwarding_on(metafile_t *mf, unsigned long id, unsigned int on);
void stream_sdp_label(metafile_t *mf, unsigned long id, unsigned long *label);
void stream_close(stream_t *stream);
void stream_free(stream_t *stream);

@ -57,6 +57,7 @@ struct stream_s {
handler_t handler;
unsigned int forwarding_on:1;
double start_time;
unsigned int media_sdp_id;
};
typedef struct stream_s stream_t;

Loading…
Cancel
Save