diff options
author | Benny Prijono <bennylp@teluu.com> | 2012-09-14 13:18:57 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2012-09-14 13:18:57 +0000 |
commit | 48490799d1baa87cd9491cbe13e63bdaa60b44b7 (patch) | |
tree | c357b8a0e67c8accb4ef1f8bca5f751015ab8372 /pjmedia/src | |
parent | 69848a09610618abe49a4b5211af0a0d784a54a4 (diff) |
Transmit DTMF with 'End' bit when the stream is being destroyed. This closes #1582
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4255 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src')
-rw-r--r-- | pjmedia/src/pjmedia/stream.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c index 54dfb831..6d886824 100644 --- a/pjmedia/src/pjmedia/stream.c +++ b/pjmedia/src/pjmedia/stream.c @@ -876,7 +876,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame) */ static void create_dtmf_payload(pjmedia_stream *stream, struct pjmedia_frame *frame_out, - int *first, int *last) + int forced_last, int *first, int *last) { pjmedia_rtp_dtmf_event *event; struct dtmf *digit = &stream->tx_dtmf_buf[0]; @@ -902,7 +902,7 @@ static void create_dtmf_payload(pjmedia_stream *stream, event->duration = pj_htons((pj_uint16_t)digit->duration); - if (digit->duration >= PJMEDIA_DTMF_DURATION) { + if (forced_last || digit->duration >= PJMEDIA_DTMF_DURATION) { event->e_vol |= 0x80; *last = 1; @@ -1217,7 +1217,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port, if (stream->tx_dtmf_count) { int first=0, last=0; - create_dtmf_payload(stream, &frame_out, &first, &last); + create_dtmf_payload(stream, &frame_out, 0, &first, &last); /* Encapsulate into RTP packet. Note that: * - RTP marker should be set on the beginning of a new event @@ -2415,6 +2415,8 @@ err_cleanup: */ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) { + pj_status_t status; + PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); /* Send RTCP BYE (also SDES & XR) */ @@ -2422,6 +2424,48 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_TRUE); } + /* If we're in the middle of transmitting DTMF digit, send one last + * RFC 2833 RTP packet with 'End' flag set. + */ + if (stream->tx_dtmf_count && stream->tx_dtmf_buf[0].duration != 0) { + pjmedia_frame frame_out; + pjmedia_channel *channel = stream->enc; + int first=0, last=0; + void *rtphdr; + int rtphdrlen; + + pj_bzero(&frame_out, sizeof(frame_out)); + frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr); + frame_out.size = 0; + + create_dtmf_payload(stream, &frame_out, 1, &first, &last); + + /* Encapsulate into RTP packet. Note that: + * - RTP marker should be set on the beginning of a new event + * - RTP timestamp is constant for the same packet. + */ + status = pjmedia_rtp_encode_rtp( &channel->rtp, + stream->tx_event_pt, first, + frame_out.size, 0, + (const void**)&rtphdr, + &rtphdrlen); + if (status == PJ_SUCCESS) { + /* Copy RTP header to the beginning of packet */ + pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); + + /* Send the RTP packet to the transport. */ + status = pjmedia_transport_send_rtp(stream->transport, + channel->out_pkt, + frame_out.size + + sizeof(pjmedia_rtp_hdr)); + } + + if (status != PJ_SUCCESS) { + PJ_PERROR(4,(stream->port.info.name.ptr, status, + "Error sending RTP/DTMF end packet")); + } + } + /* Detach from transport * MUST NOT hold stream mutex while detaching from transport, as * it may cause deadlock. See ticket #460 for the details. |