Browse Source

MT#55283 clean up RTCP send locking

Fixes regression from Ib4285e7aae

RTCP multiplexing requires the RTCP sender to maybe lock the same output
stream, maybe lock some other one. Allow for both.

Change-Id: I6fcef32e656f8f0de46ad777f11a19c259ce35c7
pull/1998/head
Richard Fuchs 4 months ago
parent
commit
cec0afa25e
4 changed files with 22 additions and 12 deletions
  1. +1
    -1
      daemon/codec.c
  2. +5
    -2
      daemon/media_player.c
  3. +14
    -8
      daemon/rtcp.c
  4. +2
    -1
      include/rtcp.h

+ 1
- 1
daemon/codec.c View File

@ -1371,7 +1371,7 @@ static void __rtcp_timer_run(struct codec_timer *ct) {
for (GList *l = ssrc_out.head; l; l = l->next) {
struct ssrc_entry_call *se = l->data;
rtcp_send_report(media, se);
rtcp_send_report(media, se, NULL);
}
rwlock_unlock_r(&rt->call->master_lock);


+ 5
- 2
daemon/media_player.c View File

@ -306,12 +306,13 @@ struct send_timer *send_timer_new(struct packet_stream *ps) {
// call is locked in R
// ssrc_out is locked
// st->sink is locked
static void send_timer_rtcp(struct send_timer *st, struct ssrc_entry_call *ssrc_out) {
struct call_media *media = st->sink ? st->sink->media : NULL;
if (!media)
return;
rtcp_send_report(media, ssrc_out);
rtcp_send_report(media, ssrc_out, st->sink);
ssrc_out->next_rtcp = rtpe_now;
ssrc_out->next_rtcp += 5000000 + (ssl_random() % 2000000);
@ -408,6 +409,7 @@ out:
log_info_pop();
}
// sink->lock is held
static void __send_timer_rtcp(struct send_timer *st, struct ssrc_entry_call *ssrc_out) {
// do we send RTCP?
if (!ssrc_out)
@ -436,9 +438,10 @@ static void send_timer_send_lock(struct send_timer *st, struct codec_packet *cp)
__send_timer_send_common(st, cp);
__send_timer_rtcp(st, ssrc_out);
mutex_unlock(&st->sink->lock);
__send_timer_rtcp(st, ssrc_out);
ssrc_entry_release(ssrc_out);
rwlock_unlock_r(&call->master_lock);


+ 14
- 8
daemon/rtcp.c View File

@ -1550,8 +1550,10 @@ static void rtcp_receiver_reports(ssrc_q *out, struct ssrc_hash *hash) {
// call must be locked in R
// no in_lock or out_lock must be held
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out) {
// if a `ps` is locked, it must be passed as argument
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out,
const struct packet_stream *locked)
{
// figure out where to send it
struct packet_stream *ps = media->streams.head->data;
// crypto context is held separately
@ -1562,16 +1564,15 @@ void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out
else {
if (PS_ISSET(rtcp_ps, RTCP))
ps = rtcp_ps;
else
rtcp_ps = ps;
}
LOCK(&ps->lock);
if (ps != locked)
mutex_lock(&ps->lock);
if (!ps->selected_sfd || !rtcp_ps->selected_sfd)
return;
if (!ps->selected_sfd)
goto out;
if (ps->selected_sfd->socket.fd == -1 || ps->endpoint.address.family == NULL)
return;
goto out;
log_info_stream_fd(ps->selected_sfd);
@ -1623,6 +1624,11 @@ void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out
struct ssrc_receiver_report *srr = t_queue_pop_head(&srrs);
g_free(srr);
}
out:
if (ps != locked)
mutex_unlock(&ps->lock);
}


+ 2
- 1
include/rtcp.h View File

@ -30,6 +30,7 @@ rtcp_filter_func rtcp_avpf2avp_filter;
void rtcp_init(void);
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out);
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out,
const struct packet_stream *locked);
#endif

Loading…
Cancel
Save