Changeset 214 for pjproject/trunk/pjmedia/src/pjmedia/stream.c
- Timestamp:
- Feb 22, 2006 9:21:09 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r213 r214 23 23 #include <pjmedia/jbuf.h> 24 24 #include <pj/os.h> 25 #include <pj/ctype.h> 25 26 #include <pj/log.h> 26 27 #include <pj/string.h> /* memcpy() */ … … 40 41 #define PJMEDIA_MAX_BUFFER_SIZE_MS 2000 41 42 #define PJMEDIA_MAX_MTU 1500 42 43 #define PJMEDIA_DTMF_DURATION 1600 /* in timestamp */ 43 44 44 45 … … 64 65 65 66 67 struct dtmf 68 { 69 int event; 70 pj_uint32_t start_ts; 71 pj_uint32_t end_ts; 72 }; 73 66 74 /** 67 75 * This structure describes media stream. … … 94 102 pj_bool_t quit_flag; /**< To signal thread exit. */ 95 103 pj_thread_t *thread; /**< Jitter buffer's thread. */ 104 105 /* RFC 2833 DTMF transmission queue: */ 106 int dtmf_count; /**< # of digits in queue. */ 107 struct dtmf dtmf_queue[32];/**< Outgoing dtmf queue. */ 96 108 }; 97 109 … … 179 191 180 192 193 /* 194 * Transmit DTMF 195 */ 196 static void transmit_dtmf(pjmedia_stream *stream, 197 struct pjmedia_frame *frame_out) 198 { 199 pjmedia_rtp_dtmf_event *event; 200 struct dtmf *digit = &stream->dtmf_queue[0]; 201 pj_uint32_t cur_ts; 202 203 event = frame_out->buf; 204 cur_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts); 205 206 event->event = (pj_uint8_t)digit->event; 207 event->e_vol = 10; 208 event->duration = pj_htonl(cur_ts - digit->start_ts); 209 } 210 181 211 /** 182 212 * rec_callback() … … 203 233 return -1; 204 234 205 /* Encode. */ 235 /* Number of samples in the frame */ 236 ts_len = frame->size / (channel->snd_info.bits_per_sample / 8); 237 238 /* Init frame_out buffer. */ 206 239 frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr); 207 status = stream->codec->op->encode( stream->codec, frame, 208 channel->out_pkt_size - sizeof(pjmedia_rtp_hdr), 209 &frame_out); 210 if (status != 0) { 211 TRACE_((THIS_FILE, "Codec encode() error", status)); 212 return status; 240 241 /* If we have DTMF digits in the queue, transmit the digits. 242 * Otherwise encode the PCM buffer. 243 */ 244 if (stream->dtmf_count) { 245 transmit_dtmf(stream, &frame_out); 246 } else { 247 unsigned max_size; 248 249 max_size = channel->out_pkt_size - sizeof(pjmedia_rtp_hdr); 250 status = stream->codec->op->encode( stream->codec, frame, 251 max_size, 252 &frame_out); 253 if (status != 0) { 254 TRACE_((THIS_FILE, "Codec encode() error", status)); 255 return status; 256 } 213 257 } 214 258 215 259 /* Encapsulate. */ 216 ts_len = frame->size / (channel->snd_info.bits_per_sample / 8);217 260 status = pjmedia_rtp_encode_rtp( &channel->rtp, 218 261 channel->pt, 0, … … 247 290 } 248 291 292 293 static void dump_bin(const char *buf, unsigned len) 294 { 295 unsigned i; 296 297 PJ_LOG(3,(THIS_FILE, "begin dump")); 298 for (i=0; i<len; ++i) { 299 int j; 300 char bits[9]; 301 unsigned val = buf[i] & 0xFF; 302 303 bits[8] = '\0'; 304 for (j=0; j<8; ++j) { 305 if (val & (1 << (7-j))) 306 bits[j] = '1'; 307 else 308 bits[j] = '0'; 309 } 310 311 PJ_LOG(3,(THIS_FILE, "%2d %s [%d]", i, bits, val)); 312 } 313 PJ_LOG(3,(THIS_FILE, "end dump")); 314 } 249 315 250 316 /* … … 311 377 } 312 378 379 #if 1 380 if (hdr->pt == 101) { 381 dump_bin((char*)payload, payloadlen); 382 continue; 383 } 384 #endif 385 313 386 status = pjmedia_rtp_session_update(&channel->rtp, hdr); 314 387 if (status != 0 && … … 739 812 } 740 813 814 /* 815 * Dial DTMF 816 */ 817 PJ_DEF(pj_status_t) pjmedia_stream_dial_dtmf( pjmedia_stream *stream, 818 const pj_str_t *digit_char) 819 { 820 pj_status_t status = PJ_SUCCESS; 821 822 /* By convention we use jitter buffer mutex to access DTMF 823 * queue. 824 */ 825 PJ_ASSERT_RETURN(stream && digit_char, PJ_EINVAL); 826 827 pj_mutex_lock(stream->jb_mutex); 828 829 if (stream->dtmf_count+digit_char->slen >= 830 PJ_ARRAY_SIZE(stream->dtmf_queue)) 831 { 832 status = PJ_ETOOMANY; 833 } else { 834 int i; 835 836 /* convert ASCII digits into payload type first, to make sure 837 * that all digits are valid. 838 */ 839 for (i=0; i<digit_char->slen; ++i) { 840 unsigned pt; 841 842 if (digit_char->ptr[i] >= '0' && 843 digit_char->ptr[i] <= '9') 844 { 845 pt = digit_char->ptr[i] - '0'; 846 } 847 else if (pj_tolower(digit_char->ptr[i]) >= 'a' && 848 pj_tolower(digit_char->ptr[i]) <= 'd') 849 { 850 pt = pj_tolower(digit_char->ptr[i]) - 'a' + 12; 851 } 852 else if (digit_char->ptr[i] == '*') 853 { 854 pt = 10; 855 } 856 else if (digit_char->ptr[i] == '#') 857 { 858 pt = 11; 859 } 860 else 861 { 862 status = PJMEDIA_RTP_EINDTMF; 863 break; 864 } 865 866 stream->dtmf_queue[stream->dtmf_count+1].event = pt; 867 stream->dtmf_queue[stream->dtmf_count+1].start_ts = start_ts; 868 stream->dtmf_queue[stream->dtmf_count+1].end_ts = 869 start_ts + PJMEDIA_DTMF_DURATION; 870 871 start_ts += PJMEDIA_DTMF_DURATION + 320; 872 } 873 874 if (status != PJ_SUCCESS) 875 goto on_return; 876 877 if (stream->dtmf_count ==0) { 878 pj_uint32_t start_ts; 879 880 start_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts); 881 stream->dtmf_queue[0].start_ts = start_ts; 882 stream->dtmf_queue[0].end_ts = start_ts + PJMEDIA_DTMF_DURATION; 883 } 884 885 /* Increment digit count only if all digits are valid. */ 886 stream->dtmf_count += digit_char->slen; 887 888 } 889 890 on_return: 891 pj_mutex_unlock(stream->jb_mutex); 892 893 return status; 894 } 895
Note: See TracChangeset
for help on using the changeset viewer.