Skip to content

Conversation

@trengginas
Copy link
Member

PR #4344 added support for RT Text, including text stream redundancy level.
The default PT is configured from PJMEDIA_RTP_PT_REDUNDANCY/PJMEDIA_RTP_PT_T140.
When PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT is set, the library will rewrite the PT number to match the PT number as the remote offer.
Currently, the redundancy PT is not updated and still hardcoded to PJMEDIA_RTP_PT_T140 instead matching to the offer.
e,g: offer:

m=text 19742 RTP/SAVP 112 111
a=sendrecv
a=rtpmap:112 red/1000
a=fmtp:112 111/111/111
a=rtpmap:111 t140/1000

answer:

m=text 12026 RTP/SAVP 112 111
a=sendrecv
a=rtpmap:112 red/1000
a=fmtp:112 98/98/98
a=rtpmap:111 t140/1000

This PR will update the redundancy PT based on the offer to ensure the symmetric PT.

Enhanced SDP negotiation to correctly map redundancy payload types in fmtp attributes, ensuring proper PT translation. Also added support for configuring txt_red_level in account modification to propagate text redundancy settings.
@trengginas trengginas added this to the release-2.16 milestone Aug 19, 2025
@trengginas trengginas self-assigned this Aug 19, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue with symmetric payload type (PT) handling for RT Text redundancy streams in SDP negotiation. When PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT is enabled, the library now properly updates redundancy PT numbers in fmtp attributes to match the remote offer, instead of keeping them hardcoded.

  • Added text redundancy level configuration update in account modification
  • Enhanced SDP negotiation to handle redundancy PT mapping symmetrically
  • Updated fmtp attribute processing to rewrite redundancy PT values based on offer

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
pjsip/src/pjsua-lib/pjsua_acc.c Adds text redundancy level configuration update during account modification
pjmedia/src/pjmedia/sdp_neg.c Implements symmetric PT handling for redundancy streams by updating fmtp attributes

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

if (a) {
rewrite_pt(pool, &a->value, &pt_answer[i], &pt_offer[i]);
if (is_red) {
enum { MAX_FMTP_STR_LEN = 32 };
Copy link

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 32 for MAX_FMTP_STR_LEN should be defined as a named constant at the file or function level to improve maintainability and make the buffer size limit more explicit.

Suggested change
enum { MAX_FMTP_STR_LEN = 32 };

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining const as enum is common use in other parts of the code.

(j==0)?"%d":"/%d", pt_o);
buf_len = PJ_MIN(buf_len + len,
MAX_FMTP_STR_LEN);
}
Copy link

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buffer length calculation using PJ_MIN could lead to truncated output without proper error handling. If the buffer becomes full, the function continues processing but may produce incomplete fmtp strings. Consider adding bounds checking and error handling.

Suggested change
}
if ((unsigned)len >= MAX_FMTP_STR_LEN - buf_len) {
/* Truncation occurred, stop processing further. */
buf_len = MAX_FMTP_STR_LEN - 1;
buf[buf_len] = '\0';
PJ_LOG(2, (THIS_FILE, "FMTP string truncated due to buffer size limit"));
break;
} else {
buf_len += len;
}

Copilot uses AI. Check for mistakes.

pt_o = pj_strtoul(&pt_offer[i]);
pt_a = pj_strtoul(&pt_answer[i]);
buf_len = pj_ansi_snprintf(buf, MAX_FMTP_STR_LEN, "%d ", pt_o);
Copy link

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value of pj_ansi_snprintf is not checked for potential buffer overflow. If the formatted string exceeds MAX_FMTP_STR_LEN, this could lead to undefined behavior. Add bounds checking.

Suggested change
buf_len = pj_ansi_snprintf(buf, MAX_FMTP_STR_LEN, "%d ", pt_o);
buf_len = pj_ansi_snprintf(buf, MAX_FMTP_STR_LEN, "%d ", pt_o);
if (buf_len < 0 || buf_len >= MAX_FMTP_STR_LEN) {
/* Truncate and null-terminate to be safe */
buf_len = MAX_FMTP_STR_LEN - 1;
buf[buf_len] = '\0';
}

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With MAX_FMTP_STR_LEN is set to 32, buffer overflow most likely not going to happen

/* Update the fmtp redundancy PT. */
for (j = 0; j < fmtp.cnt; ++j) {
pt_o = pj_strtoul(&fmtp.param[j].val);
for (k = 0; k < pt_cnt ;++k) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm understanding this correctly, it looks like we're searching for the text pt for every redundancy level (instead of just once)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct. The goal is to be generic, since redundant audio data might have a different number.
e.g.: https://datatracker.ietf.org/doc/html/rfc2198#section-5

       m=audio 12345 RTP/AVP 121 0 5
       a=rtpmap:121 red/8000/1
       a=fmtp:121 0/5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants