Changeset 1416


Ignore:
Timestamp:
Aug 13, 2007 11:53:56 AM (17 years ago)
Author:
bennylp
Message:

Fixed ticket #363: Incorrect RTP marker and timestamp in DTMF event/RFC 2833 packet (thanks Pedro Sanchez)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r1413 r1416  
    6363{ 
    6464    int             event; 
    65     pj_uint32_t     start_ts; 
     65    pj_uint32_t     duration; 
    6666}; 
    6767 
     
    374374 */ 
    375375static void create_dtmf_payload(pjmedia_stream *stream,  
    376                           struct pjmedia_frame *frame_out) 
     376                                struct pjmedia_frame *frame_out, 
     377                                int *first, int *last) 
    377378{ 
    378379    pjmedia_rtp_dtmf_event *event; 
    379380    struct dtmf *digit = &stream->tx_dtmf_buf[0]; 
    380     unsigned duration; 
    381381    pj_uint32_t cur_ts; 
    382382 
    383383    pj_assert(sizeof(pjmedia_rtp_dtmf_event) == 4); 
     384 
     385    *first = *last = 0; 
    384386 
    385387    event = (pjmedia_rtp_dtmf_event*) frame_out->buf; 
    386388    cur_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts); 
    387     duration = cur_ts - digit->start_ts; 
    388  
    389     if (duration == 0) { 
     389 
     390    if (digit->duration == 0) { 
    390391        PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c",  
    391392                  digitmap[digit->event])); 
    392         duration = stream->port.info.samples_per_frame; 
    393         digit->start_ts = cur_ts - duration; 
    394     } 
     393        *first = 1; 
     394    } 
     395 
     396    digit->duration += stream->port.info.samples_per_frame; 
    395397 
    396398    event->event = (pj_uint8_t)digit->event; 
    397399    event->e_vol = 10; 
    398     event->duration = pj_htons((pj_uint16_t)duration); 
    399  
    400     if (duration >= PJMEDIA_DTMF_DURATION) { 
     400    event->duration = pj_htons((pj_uint16_t)digit->duration); 
     401 
     402 
     403    if (digit->duration >= PJMEDIA_DTMF_DURATION) { 
     404 
    401405        event->e_vol |= 0x80; 
     406        *last = 1; 
    402407 
    403408        /* Prepare next digit. */ 
    404409        pj_mutex_lock(stream->jb_mutex); 
     410 
    405411        pj_array_erase(stream->tx_dtmf_buf, sizeof(stream->tx_dtmf_buf[0]), 
    406412                       stream->tx_dtmf_count, 0); 
    407413        --stream->tx_dtmf_count; 
    408414 
    409         stream->tx_dtmf_buf[0].start_ts = cur_ts; 
    410415        pj_mutex_unlock(stream->jb_mutex); 
    411  
    412         if (stream->tx_dtmf_count) { 
    413             PJ_LOG(5,(stream->port.info.name.ptr, 
    414                       "Sending DTMF digit id %c",  
    415                       digitmap[stream->tx_dtmf_buf[0].event])); 
    416         } 
    417  
    418     } 
    419  
     416    } 
    420417 
    421418    frame_out->size = 4; 
     
    526523    void *rtphdr; 
    527524    int rtphdrlen; 
    528  
     525    int inc_timestamp = 0; 
    529526 
    530527    /* Don't do anything if stream is paused */ 
     
    555552     */ 
    556553    if (stream->tx_dtmf_count) { 
    557  
    558         create_dtmf_payload(stream, &frame_out); 
    559  
    560         /* Encapsulate. */ 
     554        int first=0, last=0; 
     555 
     556        create_dtmf_payload(stream, &frame_out, &first, &last); 
     557 
     558        /* Encapsulate into RTP packet. Note that: 
     559         *  - RTP marker should be set on the beginning of a new event 
     560         *  - RTP timestamp is constant for the same packet.  
     561         */ 
    561562        status = pjmedia_rtp_encode_rtp( &channel->rtp,  
    562                                          stream->tx_event_pt, 0,  
    563                                          frame_out.size, ts_len,  
     563                                         stream->tx_event_pt, first,  
     564                                         frame_out.size, (first?ts_len:0),  
    564565                                         (const void**)&rtphdr,  
    565566                                         &rtphdrlen); 
     567 
     568        if (last) { 
     569            /* This is the last packet for the event.  
     570             * Increment the RTP timestamp of the RTP session, for next 
     571             * RTP packets. 
     572             */ 
     573            inc_timestamp = PJMEDIA_DTMF_DURATION - ts_len; 
     574        } 
    566575 
    567576    } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE) { 
     
    667676    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); 
    668677 
     678    /* Special case for DTMF: timestamp remains constant for 
     679     * the same event, and is only updated after a complete event 
     680     * has been transmitted. 
     681     */ 
     682    if (inc_timestamp) { 
     683        pjmedia_rtp_encode_rtp( &channel->rtp, stream->tx_event_pt, 0, 
     684                                0, inc_timestamp, NULL, NULL); 
     685    } 
    669686 
    670687    /* Set RTP marker bit if currently not streaming */ 
     
    15771594 
    15781595            stream->tx_dtmf_buf[stream->tx_dtmf_count+i].event = pt; 
     1596            stream->tx_dtmf_buf[stream->tx_dtmf_count+i].duration = 0; 
    15791597        } 
    15801598 
     
    15821600            goto on_return; 
    15831601 
    1584         /* Init start_ts and end_ts only for the first digit. 
    1585          * Subsequent digits are initialized on the fly. 
    1586          */ 
    1587         if (stream->tx_dtmf_count ==0) { 
    1588             pj_uint32_t start_ts; 
    1589  
    1590             start_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts); 
    1591             stream->tx_dtmf_buf[0].start_ts = start_ts; 
    1592         } 
    1593  
    15941602        /* Increment digit count only if all digits are valid. */ 
    15951603        stream->tx_dtmf_count += digit_char->slen; 
    1596  
    15971604    } 
    15981605 
Note: See TracChangeset for help on using the changeset viewer.