1 /* $Id$ */
2 /*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include <pjmedia/stream.h>
21 #include <pjmedia/errno.h>
22 #include <pjmedia/rtp.h>
23 #include <pjmedia/rtcp.h>
24 #include <pjmedia/jbuf.h>
25 #include <pj/array.h>
26 #include <pj/assert.h>
27 #include <pj/ctype.h>
28 #include <pj/compat/socket.h>
29 #include <pj/errno.h>
30 #include <pj/ioqueue.h>
31 #include <pj/log.h>
32 #include <pj/os.h>
33 #include <pj/pool.h>
34 #include <pj/rand.h>
35 #include <pj/sock_select.h>
36 #include <pj/string.h> /* memcpy() */
37
38
39 #define THIS_FILE "stream.c"
40 #define ERRLEVEL 1
41 #define LOGERR_(expr) PJ_PERROR(4,expr);
42 #define TRC_(expr) PJ_LOG(5,expr)
43
44 #define BYTES_PER_SAMPLE 2
45
46 /* Limit the number of synthetic audio samples that are generated by PLC.
47 * Normally PLC should have it's own means to limit the number of
48 * synthetic frames, so we need to set this to a reasonably large value
49 * just as precaution
50 */
51 #define MAX_PLC_MSEC PJMEDIA_MAX_PLC_DURATION_MSEC
52
53
54 /* Tracing jitter buffer operations in a stream session to a CSV file.
55 * The trace will contain JB operation timestamp, frame info, RTP info, and
56 * the JB state right after the operation.
57 */
58 #define TRACE_JB 0 /* Enable/disable trace. */
59 #define TRACE_JB_PATH_PREFIX "" /* Optional path/prefix
60 for the CSV filename. */
61 #if TRACE_JB
62 # include <pj/file_io.h>
63 # define TRACE_JB_INVALID_FD ((pj_oshandle_t)-1)
64 # define TRACE_JB_OPENED(s) (s->trace_jb_fd != TRACE_JB_INVALID_FD)
65 #endif
66
67 #ifndef PJMEDIA_STREAM_SIZE
68 # define PJMEDIA_STREAM_SIZE 1000
69 #endif
70
71 #ifndef PJMEDIA_STREAM_INC
72 # define PJMEDIA_STREAM_INC 1000
73 #endif
74
75 /* Number of DTMF E bit transmissions */
76 #define DTMF_EBIT_RETRANSMIT_CNT 3
77
78 /* Number of send error before repeat the report. */
79 #define SEND_ERR_COUNT_TO_REPORT 50
80
81 /**
82 * Media channel.
83 */
84 struct pjmedia_channel
85 {
86 pjmedia_stream *stream; /**< Parent stream. */
87 pjmedia_dir dir; /**< Channel direction. */
88 unsigned pt; /**< Payload type. */
89 pj_bool_t paused; /**< Paused?. */
90 unsigned out_pkt_size; /**< Size of output buffer. */
91 void *out_pkt; /**< Output buffer. */
92 pjmedia_rtp_session rtp; /**< RTP session. */
93 };
94
95
96 struct dtmf
97 {
98 int event;
99 pj_uint32_t duration;
100 int ebit_cnt; /**< # of E bit transmissions */
101 };
102
103
104 /**
105 * This structure describes media stream.
106 * A media stream is bidirectional media transmission between two endpoints.
107 * It consists of two channels, i.e. encoding and decoding channels.
108 * A media stream corresponds to a single "m=" line in a SDP session
109 * description.
110 */
111 struct pjmedia_stream
112 {
113 pjmedia_endpt *endpt; /**< Media endpoint. */
114 pjmedia_codec_mgr *codec_mgr; /**< Codec manager instance. */
115 pjmedia_stream_info si; /**< Creation parameter. */
116 pjmedia_port port; /**< Port interface. */
117 pjmedia_channel *enc; /**< Encoding channel. */
118 pjmedia_channel *dec; /**< Decoding channel. */
119
120 pj_pool_t *own_pool; /**< Only created if not given */
121
122 pjmedia_dir dir; /**< Stream direction. */
123 void *user_data; /**< User data. */
124 pj_str_t cname; /**< SDES CNAME */
125
126 pjmedia_transport *transport; /**< Stream transport. */
127
128 pjmedia_codec *codec; /**< Codec instance being used. */
129 pjmedia_codec_param codec_param; /**< Codec param. */
130 pj_int16_t *enc_buf; /**< Encoding buffer, when enc's
131 ptime is different than dec.
132 Otherwise it's NULL. */
133
134 unsigned enc_samples_per_pkt;
135 unsigned enc_buf_size; /**< Encoding buffer size, in
136 samples. */
137 unsigned enc_buf_pos; /**< First position in buf. */
138 unsigned enc_buf_count; /**< Number of samples in the
139 encoding buffer. */
140
141 pj_int16_t *dec_buf; /**< Decoding buffer. */
142 unsigned dec_buf_size; /**< Decoding buffer size, in
143 samples. */
144 unsigned dec_buf_pos; /**< First position in buf. */
145 unsigned dec_buf_count; /**< Number of samples in the
146 decoding buffer. */
147
148 pj_uint16_t dec_ptime; /**< Decoder frame ptime in ms. */
149 pj_bool_t detect_ptime_change;
150 /**< Detect decode ptime change */
151
152 unsigned plc_cnt; /**< # of consecutive PLC frames*/
153 unsigned max_plc_cnt; /**< Max # of PLC frames */
154
155 unsigned vad_enabled; /**< VAD enabled in param. */
156 unsigned frame_size; /**< Size of encoded base frame.*/
157 pj_bool_t is_streaming; /**< Currently streaming?. This
158 is used to put RTP marker
159 bit. */
160 pj_uint32_t ts_vad_disabled;/**< TS when VAD was disabled. */
161 pj_uint32_t tx_duration; /**< TX duration in timestamp. */
162
163 pj_mutex_t *jb_mutex;
164 pjmedia_jbuf *jb; /**< Jitter buffer. */
165 char jb_last_frm; /**< Last frame type from jb */
166 unsigned jb_last_frm_cnt;/**< Last JB frame type counter*/
167 unsigned soft_start_cnt;/**< Stream soft start counter */
168
169 pjmedia_rtcp_session rtcp; /**< RTCP for incoming RTP. */
170
171 pj_uint32_t rtcp_last_tx; /**< RTCP tx time in timestamp */
172 pj_uint32_t rtcp_interval; /**< Interval, in timestamp. */
173 pj_bool_t initial_rr; /**< Initial RTCP RR sent */
174 pj_bool_t rtcp_sdes_bye_disabled;/**< Send RTCP SDES/BYE?*/
175 void *out_rtcp_pkt; /**< Outgoing RTCP packet. */
176 unsigned out_rtcp_pkt_size;
177 /**< Outgoing RTCP packet size. */
178
179 /* RFC 2833 DTMF transmission queue: */
180 unsigned dtmf_duration; /**< DTMF duration(in timestamp)*/
181 int tx_event_pt; /**< Outgoing pt for dtmf. */
182 int tx_dtmf_count; /**< # of digits in tx dtmf buf.*/
183 struct dtmf tx_dtmf_buf[32];/**< Outgoing dtmf queue. */
184
185 /* Incoming DTMF: */
186 int rx_event_pt; /**< Incoming pt for dtmf. */
187 int last_dtmf; /**< Current digit, or -1. */
188 pj_uint32_t last_dtmf_dur; /**< Start ts for cur digit. */
189 pj_bool_t last_dtmf_ended;
190 unsigned rx_dtmf_count; /**< # of digits in dtmf rx buf.*/
191 char rx_dtmf_buf[32];/**< Incoming DTMF buffer. */
192
193 /* DTMF callback */
194 void (*dtmf_cb)(pjmedia_stream*, void*, int);
195 void *dtmf_cb_user_data;
196
197 void (*dtmf_event_cb)(pjmedia_stream*, void*,
198 const pjmedia_stream_dtmf_event*);
199 void *dtmf_event_cb_user_data;
200
201 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
202 /* Enable support to handle codecs with inconsistent clock rate
203 * between clock rate in SDP/RTP & the clock rate that is actually used.
204 * This happens for example with G.722 and MPEG audio codecs.
205 */
206 pj_bool_t has_g722_mpeg_bug;
207 /**< Flag to specify whether
208 normalization process
209 is needed */
210 unsigned rtp_tx_ts_len_per_pkt;
211 /**< Normalized ts length per packet
212 transmitted according to
213 'erroneous' definition */
214 unsigned rtp_rx_ts_len_per_frame;
215 /**< Normalized ts length per frame
216 received according to
217 'erroneous' definition */
218 unsigned rtp_rx_last_cnt;/**< Nb of frames in last pkt */
219 unsigned rtp_rx_check_cnt;
220 /**< Counter of remote timestamp
221 checking */
222 #endif
223
224 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
225 pj_uint32_t rtcp_xr_last_tx; /**< RTCP XR tx time
226 in timestamp. */
227 pj_uint32_t rtcp_xr_interval; /**< Interval, in timestamp. */
228 pj_sockaddr rtcp_xr_dest; /**< Additional remote RTCP XR
229 dest. If sin_family is
230 zero, it will be ignored*/
231 unsigned rtcp_xr_dest_len; /**< Length of RTCP XR dest
232 address */
233 #endif
234
235 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
236 pj_bool_t use_ka; /**< Stream keep-alive with non-
237 codec-VAD mechanism is
238 enabled? */
239 pj_timestamp last_frm_ts_sent; /**< Timestamp of last sending
240 packet */
241 unsigned start_ka_count; /**< The number of keep-alive
242 to be sent after it is
243 created */
244 unsigned start_ka_interval;/**< The keepalive sending
245 interval after the stream
246 is created */
247 #endif
248
249 pj_sockaddr rem_rtp_addr; /**< Remote RTP address */
250 unsigned rem_rtp_flag; /**< Indicator flag about
251 packet from this addr.
252 0=no pkt, 1=good ssrc,
253 2=bad ssrc pkts */
254 unsigned rtp_src_cnt; /**< How many pkt from
255 this addr. */
256
257 #if TRACE_JB
258 pj_oshandle_t trace_jb_fd; /**< Jitter tracing file handle.*/
259 char *trace_jb_buf; /**< Jitter tracing buffer. */
260 #endif
261
262 pj_uint32_t rtp_rx_last_ts; /**< Last received RTP
263 timestamp */
264 pj_uint32_t rtp_tx_err_cnt; /**< The number of RTP
265 send() error */
266 pj_uint32_t rtcp_tx_err_cnt; /**< The number of RTCP
267 send() error */
268
269 /* RTCP Feedback */
270 pj_bool_t send_rtcp_fb_nack; /**< Send NACK? */
271 pjmedia_rtcp_fb_nack rtcp_fb_nack; /**< TX NACK state. */
272 int rtcp_fb_nack_cap_idx; /**< RX NACK cap idx. */
273
274
275 };
276
277
278 /* RFC 2833 digit */
279 static const char digitmap[17] = { '0', '1', '2', '3',
280 '4', '5', '6', '7',
281 '8', '9', '*', '#',
282 'A', 'B', 'C', 'D',
283 'R'};
284
285 /* Zero audio frame samples */
286 static pj_int16_t zero_frame[2 * 30 * 16000 / 1000];
287
288
289 static void on_rx_rtcp( void *data,
290 void *pkt,
291 pj_ssize_t bytes_read);
292
293 static pj_status_t send_rtcp(pjmedia_stream *stream,
294 pj_bool_t with_sdes,
295 pj_bool_t with_bye,
296 pj_bool_t with_xr,
297 pj_bool_t with_fb);
298
299
300 #if TRACE_JB
301
trace_jb_print_timestamp(char ** buf,pj_ssize_t len)302 PJ_INLINE(int) trace_jb_print_timestamp(char **buf, pj_ssize_t len)
303 {
304 pj_time_val now;
305 pj_parsed_time ptime;
306 char *p = *buf;
307
308 if (len < 14)
309 return -1;
310
311 pj_gettimeofday(&now);
312 pj_time_decode(&now, &ptime);
313 p += pj_utoa_pad(ptime.hour, p, 2, '0');
314 *p++ = ':';
315 p += pj_utoa_pad(ptime.min, p, 2, '0');
316 *p++ = ':';
317 p += pj_utoa_pad(ptime.sec, p, 2, '0');
318 *p++ = '.';
319 p += pj_utoa_pad(ptime.msec, p, 3, '0');
320 *p++ = ',';
321
322 *buf = p;
323
324 return 0;
325 }
326
trace_jb_print_state(pjmedia_stream * stream,char ** buf,pj_ssize_t len)327 PJ_INLINE(int) trace_jb_print_state(pjmedia_stream *stream,
328 char **buf, pj_ssize_t len)
329 {
330 char *p = *buf;
331 char *endp = *buf + len;
332 pjmedia_jb_state state;
333
334 pjmedia_jbuf_get_state(stream->jb, &state);
335
336 len = pj_ansi_snprintf(p, endp-p, "%d, %d, %d",
337 state.size, state.burst, state.prefetch);
338 if ((len < 0) || (len >= endp-p))
339 return -1;
340
341 p += len;
342 *buf = p;
343 return 0;
344 }
345
trace_jb_get(pjmedia_stream * stream,pjmedia_jb_frame_type ft,pj_size_t fsize)346 static void trace_jb_get(pjmedia_stream *stream, pjmedia_jb_frame_type ft,
347 pj_size_t fsize)
348 {
349 char *p = stream->trace_jb_buf;
350 char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;
351 pj_ssize_t len = 0;
352 const char* ft_st;
353
354 if (!TRACE_JB_OPENED(stream))
355 return;
356
357 /* Print timestamp. */
358 if (trace_jb_print_timestamp(&p, endp-p))
359 goto on_insuff_buffer;
360
361 /* Print frame type and size */
362 switch(ft) {
363 case PJMEDIA_JB_MISSING_FRAME:
364 ft_st = "missing";
365 break;
366 case PJMEDIA_JB_NORMAL_FRAME:
367 ft_st = "normal";
368 break;
369 case PJMEDIA_JB_ZERO_PREFETCH_FRAME:
370 ft_st = "prefetch";
371 break;
372 case PJMEDIA_JB_ZERO_EMPTY_FRAME:
373 ft_st = "empty";
374 break;
375 default:
376 ft_st = "unknown";
377 break;
378 }
379
380 /* Print operation, size, frame count, frame type */
381 len = pj_ansi_snprintf(p, endp-p, "GET,%d,1,%s,,,,", fsize, ft_st);
382 if ((len < 0) || (len >= endp-p))
383 goto on_insuff_buffer;
384 p += len;
385
386 /* Print JB state */
387 if (trace_jb_print_state(stream, &p, endp-p))
388 goto on_insuff_buffer;
389
390 /* Print end of line */
391 if (endp-p < 2)
392 goto on_insuff_buffer;
393 *p++ = '\n';
394
395 /* Write and flush */
396 len = p - stream->trace_jb_buf;
397 pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);
398 pj_file_flush(stream->trace_jb_fd);
399 return;
400
401 on_insuff_buffer:
402 pj_assert(!"Trace buffer too small, check PJ_LOG_MAX_SIZE!");
403 }
404
trace_jb_put(pjmedia_stream * stream,const pjmedia_rtp_hdr * hdr,unsigned payloadlen,unsigned frame_cnt)405 static void trace_jb_put(pjmedia_stream *stream, const pjmedia_rtp_hdr *hdr,
406 unsigned payloadlen, unsigned frame_cnt)
407 {
408 char *p = stream->trace_jb_buf;
409 char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;
410 pj_ssize_t len = 0;
411
412 if (!TRACE_JB_OPENED(stream))
413 return;
414
415 /* Print timestamp. */
416 if (trace_jb_print_timestamp(&p, endp-p))
417 goto on_insuff_buffer;
418
419 /* Print operation, size, frame count, RTP info */
420 len = pj_ansi_snprintf(p, endp-p,
421 "PUT,%d,%d,,%d,%d,%d,",
422 payloadlen, frame_cnt,
423 pj_ntohs(hdr->seq), pj_ntohl(hdr->ts), hdr->m);
424 if ((len < 0) || (len >= endp-p))
425 goto on_insuff_buffer;
426 p += len;
427
428 /* Print JB state */
429 if (trace_jb_print_state(stream, &p, endp-p))
430 goto on_insuff_buffer;
431
432 /* Print end of line */
433 if (endp-p < 2)
434 goto on_insuff_buffer;
435 *p++ = '\n';
436
437 /* Write and flush */
438 len = p - stream->trace_jb_buf;
439 pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);
440 pj_file_flush(stream->trace_jb_fd);
441 return;
442
443 on_insuff_buffer:
444 pj_assert(!"Trace buffer too small, check PJ_LOG_MAX_SIZE!");
445 }
446
447 #endif /* TRACE_JB */
448
449
450 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
451 /*
452 * Send keep-alive packet using non-codec frame.
453 */
send_keep_alive_packet(pjmedia_stream * stream)454 static void send_keep_alive_packet(pjmedia_stream *stream)
455 {
456 #if PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP
457
458 /* Keep-alive packet is empty RTP */
459 pj_status_t status;
460 void *pkt;
461 int pkt_len;
462
463 TRC_((stream->port.info.name.ptr,
464 "Sending keep-alive (RTCP and empty RTP)"));
465
466 /* Send RTP */
467 status = pjmedia_rtp_encode_rtp( &stream->enc->rtp,
468 stream->enc->pt, 0,
469 1,
470 0,
471 (const void**)&pkt,
472 &pkt_len);
473 pj_assert(status == PJ_SUCCESS);
474
475 pj_memcpy(stream->enc->out_pkt, pkt, pkt_len);
476 pjmedia_transport_send_rtp(stream->transport, stream->enc->out_pkt,
477 pkt_len);
478
479 /* Send RTCP */
480 send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE, PJ_FALSE);
481
482 /* Update stats in case the stream is paused */
483 stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);
484
485 #elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER
486
487 /* Keep-alive packet is defined in PJMEDIA_STREAM_KA_USER_PKT */
488 int pkt_len;
489 const pj_str_t str_ka = PJMEDIA_STREAM_KA_USER_PKT;
490
491 TRC_((stream->port.info.name.ptr,
492 "Sending keep-alive (custom RTP/RTCP packets)"));
493
494 /* Send to RTP port */
495 pj_memcpy(stream->enc->out_pkt, str_ka.ptr, str_ka.slen);
496 pkt_len = str_ka.slen;
497 pjmedia_transport_send_rtp(stream->transport, stream->enc->out_pkt,
498 pkt_len);
499
500 /* Send to RTCP port */
501 pjmedia_transport_send_rtcp(stream->transport, stream->enc->out_pkt,
502 pkt_len);
503
504 #else
505
506 PJ_UNUSED_ARG(stream);
507
508 #endif
509 }
510 #endif /* defined(PJMEDIA_STREAM_ENABLE_KA) */
511
512 /*
513 * play_callback()
514 *
515 * This callback is called by sound device's player thread when it
516 * needs to feed the player with some frames.
517 */
get_frame(pjmedia_port * port,pjmedia_frame * frame)518 static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
519 {
520 pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
521 pjmedia_channel *channel = stream->dec;
522 unsigned samples_count, samples_per_frame, samples_required;
523 pj_int16_t *p_out_samp;
524 pj_status_t status;
525
526
527 /* Return no frame is channel is paused */
528 if (channel->paused) {
529 frame->type = PJMEDIA_FRAME_TYPE_NONE;
530 return PJ_SUCCESS;
531 }
532
533 if (stream->soft_start_cnt) {
534 if (stream->soft_start_cnt == PJMEDIA_STREAM_SOFT_START) {
535 PJ_LOG(4,(stream->port.info.name.ptr,
536 "Resetting jitter buffer in stream playback start"));
537 pj_mutex_lock( stream->jb_mutex );
538 pjmedia_jbuf_reset(stream->jb);
539 pj_mutex_unlock( stream->jb_mutex );
540 }
541 --stream->soft_start_cnt;
542 frame->type = PJMEDIA_FRAME_TYPE_NONE;
543 return PJ_SUCCESS;
544 }
545
546 /* Repeat get frame from the jitter buffer and decode the frame
547 * until we have enough frames according to codec's ptime.
548 */
549
550 /* Lock jitter buffer mutex first */
551 pj_mutex_lock( stream->jb_mutex );
552
553 samples_required = PJMEDIA_PIA_SPF(&stream->port.info);
554 samples_per_frame = stream->dec_ptime *
555 stream->codec_param.info.clock_rate *
556 stream->codec_param.info.channel_cnt /
557 1000;
558 p_out_samp = (pj_int16_t*) frame->buf;
559
560 for (samples_count=0; samples_count < samples_required;) {
561 char frame_type;
562 pj_size_t frame_size = channel->out_pkt_size;
563 pj_uint32_t bit_info;
564
565 if (stream->dec_buf && stream->dec_buf_pos < stream->dec_buf_count) {
566 unsigned nsamples_req = samples_required - samples_count;
567 unsigned nsamples_avail = stream->dec_buf_count -
568 stream->dec_buf_pos;
569 unsigned nsamples_copy = PJ_MIN(nsamples_req, nsamples_avail);
570
571 pjmedia_copy_samples(p_out_samp + samples_count,
572 stream->dec_buf + stream->dec_buf_pos,
573 nsamples_copy);
574 samples_count += nsamples_copy;
575 stream->dec_buf_pos += nsamples_copy;
576 continue;
577 }
578
579 /* Get frame from jitter buffer. */
580 pjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size,
581 &frame_type, &bit_info);
582
583 #if TRACE_JB
584 trace_jb_get(stream, frame_type, frame_size);
585 #endif
586
587 if (frame_type == PJMEDIA_JB_MISSING_FRAME) {
588
589 /* Activate PLC */
590 if (stream->codec->op->recover &&
591 stream->codec_param.setting.plc &&
592 stream->plc_cnt < stream->max_plc_cnt)
593 {
594 pjmedia_frame frame_out;
595
596 frame_out.buf = p_out_samp + samples_count;
597 frame_out.size = frame->size - samples_count*2;
598 status = pjmedia_codec_recover(stream->codec,
599 (unsigned)frame_out.size,
600 &frame_out);
601
602 ++stream->plc_cnt;
603
604 } else {
605 status = -1;
606 }
607
608 if (status != PJ_SUCCESS) {
609 /* Either PLC failed or PLC not supported/enabled */
610 pjmedia_zero_samples(p_out_samp + samples_count,
611 samples_required - samples_count);
612 }
613
614 if (frame_type != stream->jb_last_frm) {
615 /* Report changing frame type event */
616 PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost%s!",
617 (status == PJ_SUCCESS? ", recovered":"")));
618
619 stream->jb_last_frm = frame_type;
620 stream->jb_last_frm_cnt = 1;
621 } else {
622 stream->jb_last_frm_cnt++;
623 }
624
625 samples_count += samples_per_frame;
626 } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
627
628 const char *with_plc = "";
629
630 /* Jitter buffer is empty. If this is the first "empty" state,
631 * activate PLC to smoothen the fade-out, otherwise zero
632 * the frame.
633 */
634 //Using this "if" will only invoke PLC for the first packet
635 //lost and not the subsequent ones.
636 //if (frame_type != stream->jb_last_frm) {
637 if (1) {
638 /* Activate PLC to smoothen the missing frame */
639 if (stream->codec->op->recover &&
640 stream->codec_param.setting.plc &&
641 stream->plc_cnt < stream->max_plc_cnt)
642 {
643 pjmedia_frame frame_out;
644
645 do {
646 frame_out.buf = p_out_samp + samples_count;
647 frame_out.size = frame->size - samples_count*2;
648 status = pjmedia_codec_recover(stream->codec,
649 (unsigned)frame_out.size,
650 &frame_out);
651 if (status != PJ_SUCCESS)
652 break;
653
654 samples_count += samples_per_frame;
655 ++stream->plc_cnt;
656
657 } while (samples_count < samples_required &&
658 stream->plc_cnt < stream->max_plc_cnt);
659
660 with_plc = ", plc invoked";
661 }
662 }
663
664 if (samples_count < samples_required) {
665 pjmedia_zero_samples(p_out_samp + samples_count,
666 samples_required - samples_count);
667 samples_count = samples_required;
668 }
669
670 if (stream->jb_last_frm != frame_type) {
671 pjmedia_jb_state jb_state;
672
673 /* Report changing frame type event */
674 pjmedia_jbuf_get_state(stream->jb, &jb_state);
675 PJ_LOG(5,(stream->port.info.name.ptr,
676 "Jitter buffer empty (prefetch=%d)%s",
677 jb_state.prefetch, with_plc));
678
679 stream->jb_last_frm = frame_type;
680 stream->jb_last_frm_cnt = 1;
681 } else {
682 stream->jb_last_frm_cnt++;
683 }
684 break;
685
686 } else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) {
687
688 const char *with_plc = "";
689
690 /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */
691 pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME);
692
693 /* Always activate PLC when it's available.. */
694 if (stream->codec->op->recover &&
695 stream->codec_param.setting.plc &&
696 stream->plc_cnt < stream->max_plc_cnt)
697 {
698 pjmedia_frame frame_out;
699
700 do {
701 frame_out.buf = p_out_samp + samples_count;
702 frame_out.size = frame->size - samples_count*2;
703 status = pjmedia_codec_recover(stream->codec,
704 (unsigned)frame_out.size,
705 &frame_out);
706 if (status != PJ_SUCCESS)
707 break;
708 samples_count += samples_per_frame;
709
710 ++stream->plc_cnt;
711
712 } while (samples_count < samples_required &&
713 stream->plc_cnt < stream->max_plc_cnt);
714
715 with_plc = ", plc invoked";
716 }
717
718 if (samples_count < samples_required) {
719 pjmedia_zero_samples(p_out_samp + samples_count,
720 samples_required - samples_count);
721 samples_count = samples_required;
722 }
723
724 if (stream->jb_last_frm != frame_type) {
725 pjmedia_jb_state jb_state;
726
727 /* Report changing frame type event */
728 pjmedia_jbuf_get_state(stream->jb, &jb_state);
729 PJ_LOG(5,(stream->port.info.name.ptr,
730 "Jitter buffer is bufferring (prefetch=%d)%s",
731 jb_state.prefetch, with_plc));
732
733 stream->jb_last_frm = frame_type;
734 stream->jb_last_frm_cnt = 1;
735 } else {
736 stream->jb_last_frm_cnt++;
737 }
738 break;
739
740 } else {
741 /* Got "NORMAL" frame from jitter buffer */
742 pjmedia_frame frame_in, frame_out;
743 pj_bool_t use_dec_buf = PJ_FALSE;
744
745 stream->plc_cnt = 0;
746
747 /* Decode */
748 frame_in.buf = channel->out_pkt;
749 frame_in.size = frame_size;
750 frame_in.bit_info = bit_info;
751 frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO; /* ignored */
752
753 frame_out.buf = p_out_samp + samples_count;
754 frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE;
755 if (stream->dec_buf &&
756 bit_info * sizeof(pj_int16_t) > frame_out.size)
757 {
758 stream->dec_buf_pos = 0;
759 stream->dec_buf_count = bit_info;
760
761 use_dec_buf = PJ_TRUE;
762 frame_out.buf = stream->dec_buf;
763 frame_out.size = stream->dec_buf_size;
764 }
765
766 status = pjmedia_codec_decode( stream->codec, &frame_in,
767 (unsigned)frame_out.size,
768 &frame_out);
769 if (status != 0) {
770 LOGERR_((port->info.name.ptr, status,
771 "codec decode() error"));
772
773 if (use_dec_buf) {
774 pjmedia_zero_samples(p_out_samp + samples_count,
775 samples_per_frame);
776 } else {
777 pjmedia_zero_samples(stream->dec_buf,
778 stream->dec_buf_count);
779 }
780 } else if (use_dec_buf) {
781 stream->dec_buf_count = frame_out.size / sizeof(pj_int16_t);
782 }
783
784 if (stream->jb_last_frm != frame_type) {
785 /* Report changing frame type event */
786 PJ_LOG(5,(stream->port.info.name.ptr,
787 "Jitter buffer starts returning normal frames "
788 "(after %d empty/lost)",
789 stream->jb_last_frm_cnt, stream->jb_last_frm));
790
791 stream->jb_last_frm = frame_type;
792 stream->jb_last_frm_cnt = 1;
793 } else {
794 stream->jb_last_frm_cnt++;
795 }
796 if (!use_dec_buf)
797 samples_count += samples_per_frame;
798 }
799 }
800
801
802 /* Unlock jitter buffer mutex. */
803 pj_mutex_unlock( stream->jb_mutex );
804
805 /* Return PJMEDIA_FRAME_TYPE_NONE if we have no frames at all
806 * (it can happen when jitter buffer returns PJMEDIA_JB_ZERO_EMPTY_FRAME).
807 */
808 if (samples_count == 0) {
809 frame->type = PJMEDIA_FRAME_TYPE_NONE;
810 frame->size = 0;
811 } else {
812 frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
813 frame->size = samples_count * BYTES_PER_SAMPLE;
814 frame->timestamp.u64 = 0;
815 }
816
817 return PJ_SUCCESS;
818 }
819
820
821 /* The other version of get_frame callback used when stream port format
822 * is non linear PCM.
823 */
get_frame_ext(pjmedia_port * port,pjmedia_frame * frame)824 static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
825 {
826 pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
827 pjmedia_channel *channel = stream->dec;
828 pjmedia_frame_ext *f = (pjmedia_frame_ext*)frame;
829 unsigned samples_per_frame, samples_required;
830 pj_status_t status;
831
832 /* Return no frame if channel is paused */
833 if (channel->paused) {
834 frame->type = PJMEDIA_FRAME_TYPE_NONE;
835 return PJ_SUCCESS;
836 }
837
838 /* Repeat get frame from the jitter buffer and decode the frame
839 * until we have enough frames according to codec's ptime.
840 */
841
842 samples_required = PJMEDIA_PIA_SPF(&stream->port.info);
843 samples_per_frame = stream->codec_param.info.frm_ptime *
844 stream->codec_param.info.clock_rate *
845 stream->codec_param.info.channel_cnt /
846 1000;
847
848 pj_bzero(f, sizeof(pjmedia_frame_ext));
849 f->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
850
851 while (f->samples_cnt < samples_required) {
852 char frame_type;
853 pj_size_t frame_size = channel->out_pkt_size;
854 pj_uint32_t bit_info;
855
856 /* Lock jitter buffer mutex first */
857 pj_mutex_lock( stream->jb_mutex );
858
859 /* Get frame from jitter buffer. */
860 pjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size,
861 &frame_type, &bit_info);
862
863 #if TRACE_JB
864 trace_jb_get(stream, frame_type, frame_size);
865 #endif
866
867 /* Unlock jitter buffer mutex. */
868 pj_mutex_unlock( stream->jb_mutex );
869
870 if (frame_type == PJMEDIA_JB_NORMAL_FRAME) {
871 /* Got "NORMAL" frame from jitter buffer */
872 pjmedia_frame frame_in;
873
874 /* Decode */
875 frame_in.buf = channel->out_pkt;
876 frame_in.size = frame_size;
877 frame_in.bit_info = bit_info;
878 frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO;
879
880 status = pjmedia_codec_decode( stream->codec, &frame_in,
881 0, frame);
882 if (status != PJ_SUCCESS) {
883 LOGERR_((port->info.name.ptr, status,
884 "codec decode() error"));
885 pjmedia_frame_ext_append_subframe(f, NULL, 0,
886 (pj_uint16_t)samples_per_frame);
887 }
888
889 if (stream->jb_last_frm != frame_type) {
890 /* Report changing frame type event */
891 PJ_LOG(5,(stream->port.info.name.ptr,
892 "Jitter buffer starts returning normal frames "
893 "(after %d empty/lost)",
894 stream->jb_last_frm_cnt, stream->jb_last_frm));
895
896 stream->jb_last_frm = frame_type;
897 stream->jb_last_frm_cnt = 1;
898 } else {
899 stream->jb_last_frm_cnt++;
900 }
901
902 } else {
903
904 /* Try to generate frame by invoking PLC (when any) */
905 status = PJ_SUCCESS;
906 if (stream->codec->op->recover) {
907 status = pjmedia_codec_recover(stream->codec, 0, frame);
908 }
909
910 /* No PLC or PLC failed */
911 if (!stream->codec->op->recover || status != PJ_SUCCESS) {
912 pjmedia_frame_ext_append_subframe(f, NULL, 0,
913 (pj_uint16_t)samples_per_frame);
914 }
915
916 if (frame_type == PJMEDIA_JB_MISSING_FRAME) {
917 if (frame_type != stream->jb_last_frm) {
918 /* Report changing frame type event */
919 PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost!"));
920
921 stream->jb_last_frm = frame_type;
922 stream->jb_last_frm_cnt = 1;
923 } else {
924 stream->jb_last_frm_cnt++;
925 }
926 } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
927 if (frame_type != stream->jb_last_frm) {
928 pjmedia_jb_state jb_state;
929
930 /* Report changing frame type event */
931 pjmedia_jbuf_get_state(stream->jb, &jb_state);
932 PJ_LOG(5,(stream->port.info.name.ptr,
933 "Jitter buffer empty (prefetch=%d)",
934 jb_state.prefetch));
935
936 stream->jb_last_frm = frame_type;
937 stream->jb_last_frm_cnt = 1;
938 } else {
939 stream->jb_last_frm_cnt++;
940 }
941 } else {
942
943 /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */
944 pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME);
945
946 if (stream->jb_last_frm != frame_type) {
947 pjmedia_jb_state jb_state;
948
949 /* Report changing frame type event */
950 pjmedia_jbuf_get_state(stream->jb, &jb_state);
951 PJ_LOG(5,(stream->port.info.name.ptr,
952 "Jitter buffer is bufferring (prefetch=%d)",
953 jb_state.prefetch));
954
955 stream->jb_last_frm = frame_type;
956 stream->jb_last_frm_cnt = 1;
957 } else {
958 stream->jb_last_frm_cnt++;
959 }
960 }
961 }
962 }
963
964 return PJ_SUCCESS;
965 }
966
967
968 /*
969 * Transmit DTMF
970 */
create_dtmf_payload(pjmedia_stream * stream,struct pjmedia_frame * frame_out,int forced_last,int * first,int * last)971 static void create_dtmf_payload(pjmedia_stream *stream,
972 struct pjmedia_frame *frame_out,
973 int forced_last, int *first, int *last)
974 {
975 pjmedia_rtp_dtmf_event *event;
976 struct dtmf *digit = &stream->tx_dtmf_buf[0];
977
978 pj_assert(sizeof(pjmedia_rtp_dtmf_event) == 4);
979
980 *first = *last = 0;
981
982 event = (pjmedia_rtp_dtmf_event*) frame_out->buf;
983
984 if (digit->duration == 0) {
985 PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c",
986 digitmap[digit->event]));
987 *first = 1;
988 }
989
990 digit->duration += stream->rtp_tx_ts_len_per_pkt;
991 if (digit->duration >= stream->dtmf_duration)
992 digit->duration = stream->dtmf_duration;
993
994 event->event = (pj_uint8_t)digit->event;
995 event->e_vol = 10;
996 event->duration = pj_htons((pj_uint16_t)digit->duration);
997
998 if (forced_last) {
999 digit->duration = stream->dtmf_duration;
1000 }
1001
1002 if (digit->duration >= stream->dtmf_duration) {
1003
1004 event->e_vol |= 0x80;
1005
1006 if (++digit->ebit_cnt >= DTMF_EBIT_RETRANSMIT_CNT) {
1007 *last = 1;
1008
1009 /* Prepare next digit. */
1010 pj_mutex_lock(stream->jb_mutex);
1011
1012 pj_array_erase(stream->tx_dtmf_buf, sizeof(stream->tx_dtmf_buf[0]),
1013 stream->tx_dtmf_count, 0);
1014 --stream->tx_dtmf_count;
1015
1016 pj_mutex_unlock(stream->jb_mutex);
1017 }
1018 }
1019
1020 frame_out->size = 4;
1021 }
1022
1023
build_rtcp_fb(pjmedia_stream * stream,void * buf,pj_size_t * length)1024 static pj_status_t build_rtcp_fb(pjmedia_stream *stream, void *buf,
1025 pj_size_t *length)
1026 {
1027 pj_status_t status;
1028
1029 /* Generic NACK */
1030 if (stream->send_rtcp_fb_nack && stream->rtcp_fb_nack.pid >= 0)
1031 {
1032 status = pjmedia_rtcp_fb_build_nack(&stream->rtcp, buf, length, 1,
1033 &stream->rtcp_fb_nack);
1034 if (status != PJ_SUCCESS)
1035 return status;
1036
1037 /* Reset Packet ID */
1038 stream->rtcp_fb_nack.pid = -1;
1039 }
1040
1041 return PJ_SUCCESS;
1042 }
1043
1044
1045 /**
1046 * Publish transport error event.
1047 */
publish_tp_event(pjmedia_event_type event_type,pj_status_t status,pj_bool_t is_rtp,pjmedia_dir dir,pjmedia_stream * stream)1048 static void publish_tp_event(pjmedia_event_type event_type,
1049 pj_status_t status,
1050 pj_bool_t is_rtp,
1051 pjmedia_dir dir,
1052 pjmedia_stream *stream)
1053 {
1054 pjmedia_event ev;
1055 pj_timestamp ts_now;
1056
1057 pj_get_timestamp(&ts_now);
1058 pj_bzero(&ev.data.med_tp_err, sizeof(ev.data.med_tp_err));
1059
1060 /* Publish event. */
1061 pjmedia_event_init(&ev, event_type,
1062 &ts_now, stream);
1063 ev.data.med_tp_err.type = PJMEDIA_TYPE_AUDIO;
1064 ev.data.med_tp_err.is_rtp = is_rtp;
1065 ev.data.med_tp_err.dir = dir;
1066 ev.data.med_tp_err.status = status;
1067
1068 pjmedia_event_publish(NULL, stream, &ev, 0);
1069 }
1070
1071
send_rtcp(pjmedia_stream * stream,pj_bool_t with_sdes,pj_bool_t with_bye,pj_bool_t with_xr,pj_bool_t with_fb)1072 static pj_status_t send_rtcp(pjmedia_stream *stream,
1073 pj_bool_t with_sdes,
1074 pj_bool_t with_bye,
1075 pj_bool_t with_xr,
1076 pj_bool_t with_fb)
1077 {
1078 void *sr_rr_pkt;
1079 pj_uint8_t *pkt;
1080 int len, max_len;
1081 pj_status_t status;
1082
1083 /* Build RTCP RR/SR packet */
1084 pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);
1085
1086 #if !defined(PJMEDIA_HAS_RTCP_XR) || (PJMEDIA_HAS_RTCP_XR == 0)
1087 with_xr = PJ_FALSE;
1088 #endif
1089
1090 if (with_sdes || with_bye || with_xr || with_fb) {
1091 pkt = (pj_uint8_t*) stream->out_rtcp_pkt;
1092 pj_memcpy(pkt, sr_rr_pkt, len);
1093 max_len = stream->out_rtcp_pkt_size;
1094 } else {
1095 pkt = (pj_uint8_t*)sr_rr_pkt;
1096 max_len = len;
1097 }
1098
1099 /* RTCP FB must be sent in compound (i.e: with RR/SR and SDES) */
1100 if (with_fb)
1101 with_sdes = PJ_TRUE;
1102
1103 /* Build RTCP SDES packet */
1104 if (with_sdes) {
1105 pjmedia_rtcp_sdes sdes;
1106 pj_size_t sdes_len;
1107
1108 pj_bzero(&sdes, sizeof(sdes));
1109 sdes.cname = stream->cname;
1110 sdes_len = max_len - len;
1111 status = pjmedia_rtcp_build_rtcp_sdes(&stream->rtcp, pkt+len,
1112 &sdes_len, &sdes);
1113 if (status != PJ_SUCCESS) {
1114 PJ_PERROR(4,(stream->port.info.name.ptr, status,
1115 "Error generating RTCP SDES"));
1116 } else {
1117 len += (int)sdes_len;
1118 }
1119 }
1120
1121 if (with_fb) {
1122 pj_size_t fb_len = max_len - len;
1123 status = build_rtcp_fb(stream, pkt+len, &fb_len);
1124 if (status != PJ_SUCCESS) {
1125 PJ_PERROR(4,(stream->port.info.name.ptr, status,
1126 "Error generating RTCP FB"));
1127 } else {
1128 len += (int)fb_len;
1129 }
1130 }
1131
1132 /* Build RTCP XR packet */
1133 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
1134 if (with_xr) {
1135 int i;
1136 pjmedia_jb_state jb_state;
1137 void *xr_pkt;
1138 int xr_len;
1139
1140 /* Update RTCP XR with current JB states */
1141 pjmedia_jbuf_get_state(stream->jb, &jb_state);
1142
1143 i = jb_state.avg_delay;
1144 status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
1145 PJMEDIA_RTCP_XR_INFO_JB_NOM, i);
1146 pj_assert(status == PJ_SUCCESS);
1147
1148 i = jb_state.max_delay;
1149 status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
1150 PJMEDIA_RTCP_XR_INFO_JB_MAX, i);
1151 pj_assert(status == PJ_SUCCESS);
1152
1153 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0,
1154 &xr_pkt, &xr_len);
1155
1156 if (xr_len + len <= max_len) {
1157 pj_memcpy(pkt+len, xr_pkt, xr_len);
1158 len += xr_len;
1159
1160 /* Send the RTCP XR to third-party destination if specified */
1161 if (stream->rtcp_xr_dest_len) {
1162 pjmedia_transport_send_rtcp2(stream->transport,
1163 &stream->rtcp_xr_dest,
1164 stream->rtcp_xr_dest_len,
1165 xr_pkt, xr_len);
1166 }
1167
1168 } else {
1169 PJ_PERROR(4,(stream->port.info.name.ptr, PJ_ETOOBIG,
1170 "Error generating RTCP-XR"));
1171 }
1172 }
1173 #endif
1174
1175 /* Build RTCP BYE packet */
1176 if (with_bye) {
1177 pj_size_t bye_len;
1178
1179 bye_len = max_len - len;
1180 status = pjmedia_rtcp_build_rtcp_bye(&stream->rtcp, pkt+len,
1181 &bye_len, NULL);
1182 if (status != PJ_SUCCESS) {
1183 PJ_PERROR(4,(stream->port.info.name.ptr, status,
1184 "Error generating RTCP BYE"));
1185 } else {
1186 len += (int)bye_len;
1187 }
1188 }
1189
1190 /* Send! */
1191 status = pjmedia_transport_send_rtcp(stream->transport, pkt, len);
1192 if (status != PJ_SUCCESS) {
1193 if (stream->rtcp_tx_err_cnt++ == 0) {
1194 LOGERR_((stream->port.info.name.ptr, status,
1195 "Error sending RTCP"));
1196 }
1197 if (stream->rtcp_tx_err_cnt > SEND_ERR_COUNT_TO_REPORT) {
1198 stream->rtcp_tx_err_cnt = 0;
1199 }
1200 }
1201
1202 return status;
1203 }
1204
1205 /**
1206 * check_tx_rtcp()
1207 *
1208 * This function is can be called by either put_frame() or get_frame(),
1209 * to transmit periodic RTCP SR/RR report.
1210 */
check_tx_rtcp(pjmedia_stream * stream,pj_uint32_t timestamp)1211 static void check_tx_rtcp(pjmedia_stream *stream, pj_uint32_t timestamp)
1212 {
1213 /* Note that timestamp may represent local or remote timestamp,
1214 * depending on whether this function is called from put_frame()
1215 * or get_frame().
1216 */
1217
1218 if (stream->rtcp_last_tx == 0) {
1219
1220 stream->rtcp_last_tx = timestamp;
1221
1222 } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) {
1223 pj_bool_t with_xr = PJ_FALSE;
1224 pj_status_t status;
1225
1226 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
1227 if (stream->rtcp.xr_enabled) {
1228 if (stream->rtcp_xr_last_tx == 0) {
1229 stream->rtcp_xr_last_tx = timestamp;
1230 } else if (timestamp - stream->rtcp_xr_last_tx >=
1231 stream->rtcp_xr_interval)
1232 {
1233 with_xr = PJ_TRUE;
1234
1235 /* Update last tx RTCP XR */
1236 stream->rtcp_xr_last_tx = timestamp;
1237 }
1238 }
1239 #endif
1240
1241 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE,
1242 with_xr, PJ_FALSE);
1243 if (status == PJ_SUCCESS) {
1244 stream->rtcp_last_tx = timestamp;
1245 }
1246 }
1247 }
1248
1249
1250 /**
1251 * Rebuffer the frame when encoder and decoder has different ptime
1252 * (such as when different iLBC modes are used by local and remote)
1253 */
rebuffer(pjmedia_stream * stream,pjmedia_frame * frame)1254 static void rebuffer(pjmedia_stream *stream,
1255 pjmedia_frame *frame)
1256 {
1257 /* How many samples are needed */
1258 unsigned count;
1259
1260 /* Normalize frame */
1261 if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO)
1262 frame->size = 0;
1263
1264 /* Remove used frame from the buffer. */
1265 if (stream->enc_buf_pos) {
1266 if (stream->enc_buf_count) {
1267 pj_memmove(stream->enc_buf,
1268 stream->enc_buf + stream->enc_buf_pos,
1269 (stream->enc_buf_count << 1));
1270 }
1271 stream->enc_buf_pos = 0;
1272 }
1273
1274 /* Make sure we have space to store the new frame */
1275 pj_assert(stream->enc_buf_count + (frame->size >> 1) <
1276 stream->enc_buf_size);
1277
1278 /* Append new frame to the buffer */
1279 if (frame->size) {
1280 /* Handle case when there is no port transmitting to this port */
1281 if (frame->buf) {
1282 pj_memcpy(stream->enc_buf + stream->enc_buf_count,
1283 frame->buf, frame->size);
1284 } else {
1285 pj_bzero(stream->enc_buf + stream->enc_buf_count, frame->size);
1286 }
1287 stream->enc_buf_count += ((unsigned)frame->size >> 1);
1288 }
1289
1290 /* How many samples are needed */
1291 count = stream->codec_param.info.enc_ptime *
1292 PJMEDIA_PIA_SRATE(&stream->port.info) / 1000;
1293
1294 /* See if we have enough samples */
1295 if (stream->enc_buf_count >= count) {
1296
1297 frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
1298 frame->buf = stream->enc_buf;
1299 frame->size = (count << 1);
1300
1301 stream->enc_buf_pos = count;
1302 stream->enc_buf_count -= count;
1303
1304 } else {
1305 /* We don't have enough samples */
1306 frame->type = PJMEDIA_FRAME_TYPE_NONE;
1307 }
1308 }
1309
1310
1311 /**
1312 * put_frame_imp()
1313 */
put_frame_imp(pjmedia_port * port,pjmedia_frame * frame)1314 static pj_status_t put_frame_imp( pjmedia_port *port,
1315 pjmedia_frame *frame )
1316 {
1317 pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
1318 pjmedia_channel *channel = stream->enc;
1319 pj_status_t status = 0;
1320 pjmedia_frame frame_out;
1321 unsigned ts_len, rtp_ts_len;
1322 void *rtphdr;
1323 int rtphdrlen;
1324 int inc_timestamp = 0;
1325
1326
1327 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
1328 /* If the interval since last sending packet is greater than
1329 * PJMEDIA_STREAM_KA_INTERVAL, send keep-alive packet.
1330 */
1331 if (stream->use_ka)
1332 {
1333 pj_uint32_t dtx_duration, ka_interval;
1334
1335 dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent,
1336 &frame->timestamp);
1337 if (stream->start_ka_count) {
1338 ka_interval = stream->start_ka_interval *
1339 PJMEDIA_PIA_SRATE(&stream->port.info) / 1000;
1340 } else {
1341 ka_interval = PJMEDIA_STREAM_KA_INTERVAL *
1342 PJMEDIA_PIA_SRATE(&stream->port.info);
1343 }
1344 if (dtx_duration > ka_interval) {
1345 send_keep_alive_packet(stream);
1346 stream->last_frm_ts_sent = frame->timestamp;
1347
1348 if (stream->start_ka_count)
1349 stream->start_ka_count--;
1350 }
1351 }
1352 #endif
1353
1354 /* Number of samples in the frame */
1355 if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO)
1356 ts_len = ((unsigned)frame->size >> 1) /
1357 stream->codec_param.info.channel_cnt;
1358 else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED)
1359 ts_len = PJMEDIA_PIA_SPF(&stream->port.info) /
1360 PJMEDIA_PIA_CCNT(&stream->port.info);
1361 else
1362 ts_len = 0;
1363
1364 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
1365 /* Handle special case for audio codec with RTP timestamp inconsistence
1366 * e.g: G722, MPEG audio.
1367 */
1368 if (stream->has_g722_mpeg_bug)
1369 rtp_ts_len = stream->rtp_tx_ts_len_per_pkt;
1370 else
1371 rtp_ts_len = ts_len;
1372 #else
1373 rtp_ts_len = ts_len;
1374 #endif
1375
1376 /* Don't do anything if stream is paused, except updating RTP timestamp */
1377 if (channel->paused) {
1378 stream->enc_buf_pos = stream->enc_buf_count = 0;
1379
1380 /* Update RTP session's timestamp. */
1381 status = pjmedia_rtp_encode_rtp( &channel->rtp, 0, 0, 0, rtp_ts_len,
1382 NULL, NULL);
1383
1384 /* Update RTCP stats with last RTP timestamp. */
1385 stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(channel->rtp.out_hdr.ts);
1386
1387 return PJ_SUCCESS;
1388 }
1389
1390 /* Increment transmit duration */
1391 stream->tx_duration += ts_len;
1392
1393 /* Init frame_out buffer. */
1394 frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
1395 frame_out.size = 0;
1396
1397 /* If we have DTMF digits in the queue, transmit the digits.
1398 * Otherwise encode the PCM buffer.
1399 */
1400 if (stream->tx_dtmf_count) {
1401 int first=0, last=0;
1402
1403 create_dtmf_payload(stream, &frame_out, 0, &first, &last);
1404
1405 /* Encapsulate into RTP packet. Note that:
1406 * - RTP marker should be set on the beginning of a new event
1407 * - RTP timestamp is constant for the same packet.
1408 */
1409 status = pjmedia_rtp_encode_rtp( &channel->rtp,
1410 stream->tx_event_pt, first,
1411 (int)frame_out.size,
1412 (first ? rtp_ts_len : 0),
1413 (const void**)&rtphdr,
1414 &rtphdrlen);
1415
1416 if (last) {
1417 /* This is the last packet for the event.
1418 * Increment the RTP timestamp of the RTP session, for next
1419 * RTP packets.
1420 */
1421 inc_timestamp = stream->dtmf_duration +
1422 ((DTMF_EBIT_RETRANSMIT_CNT-1) *
1423 stream->rtp_tx_ts_len_per_pkt)
1424 - rtp_ts_len;
1425 }
1426
1427
1428 /*
1429 * Special treatment for FRAME_TYPE_AUDIO but with frame->buf==NULL.
1430 * This happens when stream input is disconnected from the bridge.
1431 * In this case we periodically transmit RTP frame to keep NAT binding
1432 * open, by giving zero PCM frame to the codec.
1433 *
1434 * This was originally done in http://trac.pjsip.org/repos/ticket/56,
1435 * but then disabled in http://trac.pjsip.org/repos/ticket/439, but
1436 * now it's enabled again.
1437 */
1438 } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO &&
1439 frame->buf == NULL &&
1440 stream->port.info.fmt.id == PJMEDIA_FORMAT_L16 &&
1441 (stream->dir & PJMEDIA_DIR_ENCODING) &&
1442 stream->enc_samples_per_pkt < PJ_ARRAY_SIZE(zero_frame))
1443 {
1444 pjmedia_frame silence_frame;
1445
1446 pj_bzero(&silence_frame, sizeof(silence_frame));
1447 silence_frame.buf = zero_frame;
1448 silence_frame.size = stream->enc_samples_per_pkt * 2;
1449 silence_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
1450 silence_frame.timestamp.u32.lo = pj_ntohl(stream->enc->rtp.out_hdr.ts);
1451
1452 /* Encode! */
1453 status = pjmedia_codec_encode( stream->codec, &silence_frame,
1454 channel->out_pkt_size -
1455 sizeof(pjmedia_rtp_hdr),
1456 &frame_out);
1457 if (status != PJ_SUCCESS) {
1458 LOGERR_((stream->port.info.name.ptr, status,
1459 "Codec encode() error"));
1460 return status;
1461 }
1462
1463 /* Encapsulate. */
1464 status = pjmedia_rtp_encode_rtp( &channel->rtp,
1465 channel->pt, 0,
1466 (int)frame_out.size, rtp_ts_len,
1467 (const void**)&rtphdr,
1468 &rtphdrlen);
1469
1470
1471 /* Encode audio frame */
1472 } else if ((frame->type == PJMEDIA_FRAME_TYPE_AUDIO &&
1473 frame->buf != NULL) ||
1474 (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED))
1475 {
1476 /* Encode! */
1477 status = pjmedia_codec_encode( stream->codec, frame,
1478 channel->out_pkt_size -
1479 sizeof(pjmedia_rtp_hdr),
1480 &frame_out);
1481 if (status != PJ_SUCCESS) {
1482 LOGERR_((stream->port.info.name.ptr, status,
1483 "Codec encode() error"));
1484 return status;
1485 }
1486
1487 /* Encapsulate. */
1488 status = pjmedia_rtp_encode_rtp( &channel->rtp,
1489 channel->pt, 0,
1490 (int)frame_out.size, rtp_ts_len,
1491 (const void**)&rtphdr,
1492 &rtphdrlen);
1493
1494 } else {
1495
1496 /* Just update RTP session's timestamp. */
1497 status = pjmedia_rtp_encode_rtp( &channel->rtp,
1498 0, 0,
1499 0, rtp_ts_len,
1500 (const void**)&rtphdr,
1501 &rtphdrlen);
1502
1503 }
1504
1505 if (status != PJ_SUCCESS) {
1506 LOGERR_((stream->port.info.name.ptr, status,
1507 "RTP encode_rtp() error"));
1508 return status;
1509 }
1510
1511 /* Check if now is the time to transmit RTCP SR/RR report.
1512 * We only do this when stream direction is not "decoding only", because
1513 * when it is, check_tx_rtcp() will be handled by get_frame().
1514 */
1515 if (stream->dir != PJMEDIA_DIR_DECODING) {
1516 check_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts));
1517 }
1518
1519 /* Do nothing if we have nothing to transmit */
1520 if (frame_out.size == 0) {
1521 if (stream->is_streaming) {
1522 PJ_LOG(5,(stream->port.info.name.ptr,"Starting silence"));
1523 stream->is_streaming = PJ_FALSE;
1524 }
1525
1526 return PJ_SUCCESS;
1527 }
1528
1529
1530 /* Copy RTP header to the beginning of packet */
1531 pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));
1532
1533 /* Special case for DTMF: timestamp remains constant for
1534 * the same event, and is only updated after a complete event
1535 * has been transmitted.
1536 */
1537 if (inc_timestamp) {
1538 pjmedia_rtp_encode_rtp( &channel->rtp, stream->tx_event_pt, 0,
1539 0, inc_timestamp, NULL, NULL);
1540 }
1541
1542 /* Set RTP marker bit if currently not streaming */
1543 if (stream->is_streaming == PJ_FALSE) {
1544 pjmedia_rtp_hdr *rtp = (pjmedia_rtp_hdr*) channel->out_pkt;
1545
1546 rtp->m = 1;
1547 PJ_LOG(5,(stream->port.info.name.ptr,"Start talksprut.."));
1548 }
1549
1550 stream->is_streaming = PJ_TRUE;
1551
1552 /* Send the RTP packet to the transport. */
1553 status = pjmedia_transport_send_rtp(stream->transport, channel->out_pkt,
1554 frame_out.size +
1555 sizeof(pjmedia_rtp_hdr));
1556
1557 if (status != PJ_SUCCESS) {
1558 if (stream->rtp_tx_err_cnt++ == 0) {
1559 LOGERR_((stream->port.info.name.ptr, status, "Error sending RTP"));
1560 }
1561 if (stream->rtp_tx_err_cnt > SEND_ERR_COUNT_TO_REPORT) {
1562 stream->rtp_tx_err_cnt = 0;
1563 }
1564 return PJ_SUCCESS;
1565 }
1566
1567 /* Update stat */
1568 pjmedia_rtcp_tx_rtp(&stream->rtcp, (unsigned)frame_out.size);
1569 stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);
1570 stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);
1571
1572 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
1573 /* Update timestamp of last sending packet. */
1574 stream->last_frm_ts_sent = frame->timestamp;
1575 #endif
1576
1577 return PJ_SUCCESS;
1578 }
1579
1580
1581 /**
1582 * put_frame()
1583 *
1584 * This callback is called by upstream component when it has PCM frame
1585 * to transmit. This function encodes the PCM frame, pack it into
1586 * RTP packet, and transmit to peer.
1587 */
put_frame(pjmedia_port * port,pjmedia_frame * frame)1588 static pj_status_t put_frame( pjmedia_port *port,
1589 pjmedia_frame *frame )
1590 {
1591 pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
1592 pjmedia_frame tmp_zero_frame;
1593 unsigned samples_per_frame;
1594
1595 samples_per_frame = stream->enc_samples_per_pkt;
1596
1597 /* http://www.pjsip.org/trac/ticket/56:
1598 * when input is PJMEDIA_FRAME_TYPE_NONE, feed zero PCM frame
1599 * instead so that encoder can decide whether or not to transmit
1600 * silence frame.
1601 */
1602 if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {
1603 pj_memcpy(&tmp_zero_frame, frame, sizeof(pjmedia_frame));
1604 frame = &tmp_zero_frame;
1605
1606 tmp_zero_frame.buf = NULL;
1607 tmp_zero_frame.size = samples_per_frame * 2;
1608 tmp_zero_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
1609 }
1610
1611 #if 0
1612 // This is no longer needed because each TYPE_NONE frame will
1613 // be converted into zero frame above
1614
1615 /* If VAD is temporarily disabled during creation, feed zero PCM frame
1616 * to the codec.
1617 */
1618 if (stream->vad_enabled != stream->codec_param.setting.vad &&
1619 stream->vad_enabled != 0 &&
1620 frame->type == PJMEDIA_FRAME_TYPE_NONE &&
1621 samples_per_frame <= ZERO_PCM_MAX_SIZE)
1622 {
1623 pj_memcpy(&tmp_in_frame, frame, sizeof(pjmedia_frame));
1624 frame = &tmp_in_frame;
1625
1626 tmp_in_frame.buf = NULL;
1627 tmp_in_frame.size = samples_per_frame * 2;
1628 tmp_in_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
1629 }
1630 #endif
1631
1632 /* If VAD is temporarily disabled during creation, enable it
1633 * after transmitting for VAD_SUSPEND_SEC seconds.
1634 */
1635 if (stream->vad_enabled != stream->codec_param.setting.vad &&
1636 (stream->tx_duration - stream->ts_vad_disabled) >
1637 PJMEDIA_PIA_SRATE(&stream->port.info) *
1638 PJMEDIA_STREAM_VAD_SUSPEND_MSEC / 1000)
1639 {
1640 stream->codec_param.setting.vad = stream->vad_enabled;
1641 pjmedia_codec_modify(stream->codec, &stream->codec_param);
1642 PJ_LOG(4,(stream->port.info.name.ptr,"VAD re-enabled"));
1643 }
1644
1645
1646 /* If encoder has different ptime than decoder, then the frame must
1647 * be passed through the encoding buffer via rebuffer() function.
1648 */
1649 if (stream->enc_buf != NULL) {
1650 pjmedia_frame tmp_rebuffer_frame;
1651 pj_status_t status = PJ_SUCCESS;
1652
1653 /* Copy original frame to temporary frame since we need
1654 * to modify it.
1655 */
1656 pj_memcpy(&tmp_rebuffer_frame, frame, sizeof(pjmedia_frame));
1657
1658 /* Loop while we have full frame in enc_buffer */
1659 for (;;) {
1660 pj_status_t st;
1661
1662 /* Run rebuffer() */
1663 rebuffer(stream, &tmp_rebuffer_frame);
1664
1665 /* Process this frame */
1666 st = put_frame_imp(port, &tmp_rebuffer_frame);
1667 if (st != PJ_SUCCESS)
1668 status = st;
1669
1670 /* If we still have full frame in the buffer, re-run
1671 * rebuffer() with NULL frame.
1672 */
1673 if (stream->enc_buf_count >= stream->enc_samples_per_pkt) {
1674
1675 tmp_rebuffer_frame.type = PJMEDIA_FRAME_TYPE_NONE;
1676
1677 } else {
1678
1679 /* Otherwise break */
1680 break;
1681 }
1682 }
1683
1684 return status;
1685
1686 } else {
1687 return put_frame_imp(port, frame);
1688 }
1689 }
1690
1691
1692 #if 0
1693 static void dump_bin(const char *buf, unsigned len)
1694 {
1695 unsigned i;
1696
1697 PJ_LOG(3,(THIS_FILE, "begin dump"));
1698 for (i=0; i<len; ++i) {
1699 int j;
1700 char bits[9];
1701 unsigned val = buf[i] & 0xFF;
1702
1703 bits[8] = '\0';
1704 for (j=0; j<8; ++j) {
1705 if (val & (1 << (7-j)))
1706 bits[j] = '1';
1707 else
1708 bits[j] = '0';
1709 }
1710
1711 PJ_LOG(3,(THIS_FILE, "%2d %s [%d]", i, bits, val));
1712 }
1713 PJ_LOG(3,(THIS_FILE, "end dump"));
1714 }
1715 #endif
1716
1717 /*
1718 * Handle incoming DTMF digits.
1719 */
handle_incoming_dtmf(pjmedia_stream * stream,const pj_timestamp * timestamp,const void * payload,unsigned payloadlen)1720 static void handle_incoming_dtmf( pjmedia_stream *stream,
1721 const pj_timestamp *timestamp,
1722 const void *payload, unsigned payloadlen)
1723 {
1724 pjmedia_rtp_dtmf_event *event = (pjmedia_rtp_dtmf_event*) payload;
1725 pj_uint16_t event_duration;
1726 pjmedia_stream_dtmf_event dtmf_event;
1727 pj_bool_t is_event_end;
1728 pj_bool_t emit_event;
1729
1730 /* Check compiler packing. */
1731 pj_assert(sizeof(pjmedia_rtp_dtmf_event)==4);
1732
1733 /* Must have sufficient length before we proceed. */
1734 if (payloadlen < sizeof(pjmedia_rtp_dtmf_event))
1735 return;
1736
1737 //dump_bin(payload, payloadlen);
1738
1739 /* Ignore unknown event. */
1740 #if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0
1741 if (event->event > 16) {
1742 #else
1743 if (event->event > 15) {
1744 #endif
1745 PJ_LOG(5,(stream->port.info.name.ptr,
1746 "Ignored RTP pkt with bad DTMF event %d",
1747 event->event));
1748 return;
1749 }
1750
1751 /* Extract event data. */
1752 event_duration = pj_ntohs(event->duration);
1753 is_event_end = (event->e_vol & PJMEDIA_RTP_DTMF_EVENT_END_MASK) != 0;
1754
1755 /* Check if this is the same/current digit of the last packet. */
1756 if (stream->last_dtmf != -1 &&
1757 event->event == stream->last_dtmf &&
1758 event_duration >= stream->last_dtmf_dur)
1759 {
1760 /* Emit all updates but hide duplicate end frames. */
1761 emit_event = !is_event_end || stream->last_dtmf_ended != is_event_end;
1762
1763 /* Yes, this is the same event. */
1764 stream->last_dtmf_dur = event_duration;
1765 stream->last_dtmf_ended = is_event_end;
1766
1767 /* If DTMF callback is installed and end of event hasn't been reported
1768 * already, call it.
1769 */
1770 if (stream->dtmf_event_cb && emit_event) {
1771 dtmf_event.digit = digitmap[event->event];
1772 dtmf_event.timestamp = (pj_uint32_t)(timestamp->u64 /
1773 (stream->codec_param.info.clock_rate / 1000));
1774 dtmf_event.duration = (pj_uint16_t)(event_duration /
1775 (stream->codec_param.info.clock_rate / 1000));
1776 dtmf_event.flags = PJMEDIA_STREAM_DTMF_IS_UPDATE;
1777 if (is_event_end) {
1778 dtmf_event.flags |= PJMEDIA_STREAM_DTMF_IS_END;
1779 }
1780 stream->dtmf_event_cb(stream, stream->dtmf_event_cb_user_data,
1781 &dtmf_event);
1782 }
1783 return;
1784 }
1785
1786 /* New event! */
1787 PJ_LOG(5,(stream->port.info.name.ptr, "Received DTMF digit %c, vol=%d",
1788 digitmap[event->event],
1789 (event->e_vol & PJMEDIA_RTP_DTMF_EVENT_VOLUME_MASK)));
1790
1791 stream->last_dtmf = event->event;
1792 stream->last_dtmf_dur = event_duration;
1793 stream->last_dtmf_ended = is_event_end;
1794
1795 /* If DTMF callback is installed, call the callback, otherwise keep
1796 * the DTMF digits in the buffer.
1797 */
1798 if (stream->dtmf_event_cb) {
1799 dtmf_event.digit = digitmap[event->event];
1800 dtmf_event.timestamp = (pj_uint32_t)(timestamp->u64 /
1801 (stream->codec_param.info.clock_rate / 1000));
1802 dtmf_event.duration = (pj_uint16_t)(event_duration /
1803 (stream->codec_param.info.clock_rate / 1000));
1804 dtmf_event.flags = 0;
1805 if (is_event_end) {
1806 dtmf_event.flags |= PJMEDIA_STREAM_DTMF_IS_END;
1807 }
1808 stream->dtmf_event_cb(stream, stream->dtmf_event_cb_user_data,
1809 &dtmf_event);
1810 } else if (stream->dtmf_cb) {
1811 stream->dtmf_cb(stream, stream->dtmf_cb_user_data,
1812 digitmap[event->event]);
1813 } else {
1814 /* By convention, we use jitter buffer's mutex to access shared
1815 * DTMF variables.
1816 */
1817 pj_mutex_lock(stream->jb_mutex);
1818 if (stream->rx_dtmf_count >= PJ_ARRAY_SIZE(stream->rx_dtmf_buf)) {
1819 /* DTMF digits overflow. Discard the oldest digit. */
1820 pj_array_erase(stream->rx_dtmf_buf,
1821 sizeof(stream->rx_dtmf_buf[0]),
1822 stream->rx_dtmf_count, 0);
1823 --stream->rx_dtmf_count;
1824 }
1825 stream->rx_dtmf_buf[stream->rx_dtmf_count++] = digitmap[event->event];
1826 pj_mutex_unlock(stream->jb_mutex);
1827 }
1828 }
1829
1830
1831 /*
1832 * This callback is called by stream transport on receipt of packets
1833 * in the RTP socket.
1834 */
1835 static void on_rx_rtp( pjmedia_tp_cb_param *param)
1836 {
1837 pjmedia_stream *stream = (pjmedia_stream*) param->user_data;
1838 void *pkt = param->pkt;
1839 pj_ssize_t bytes_read = param->size;
1840 pjmedia_channel *channel = stream->dec;
1841 const pjmedia_rtp_hdr *hdr;
1842 const void *payload;
1843 unsigned payloadlen;
1844 pjmedia_rtp_status seq_st;
1845 pj_bool_t check_pt;
1846 pj_status_t status;
1847 pj_bool_t pkt_discarded = PJ_FALSE;
1848
1849 /* Check for errors */
1850 if (bytes_read < 0) {
1851 status = (pj_status_t)-bytes_read;
1852 if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
1853 return;
1854 }
1855
1856 LOGERR_((stream->port.info.name.ptr, status,
1857 "Unable to receive RTP packet"));
1858
1859 if (status == PJ_ESOCKETSTOP) {
1860 /* Publish receive error event. */
1861 publish_tp_event(PJMEDIA_EVENT_MEDIA_TP_ERR, status, PJ_TRUE,
1862 PJMEDIA_DIR_DECODING, stream);
1863 }
1864 return;
1865 }
1866
1867 /* Ignore keep-alive packets */
1868 if (bytes_read < (pj_ssize_t) sizeof(pjmedia_rtp_hdr))
1869 return;
1870
1871 /* Update RTP and RTCP session. */
1872 status = pjmedia_rtp_decode_rtp(&channel->rtp, pkt, (int)bytes_read,
1873 &hdr, &payload, &payloadlen);
1874 if (status != PJ_SUCCESS) {
1875 LOGERR_((stream->port.info.name.ptr, status, "RTP decode error"));
1876 stream->rtcp.stat.rx.discard++;
1877 return;
1878 }
1879
1880 /* Check if multiplexing is allowed and the payload indicates RTCP. */
1881 if (stream->si.rtcp_mux && hdr->pt >= 64 && hdr->pt <= 95) {
1882 on_rx_rtcp(stream, pkt, bytes_read);
1883 return;
1884 }
1885
1886 /* Ignore the packet if decoder is paused */
1887 pj_bzero(&seq_st, sizeof(seq_st));
1888 if (channel->paused)
1889 goto on_return;
1890
1891 /* Update RTP session (also checks if RTP session can accept
1892 * the incoming packet.
1893 */
1894 check_pt = (hdr->pt != stream->rx_event_pt) && PJMEDIA_STREAM_CHECK_RTP_PT;
1895 pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st, check_pt);
1896 #if !PJMEDIA_STREAM_CHECK_RTP_PT
1897 if (!check_pt && hdr->pt != channel->rtp.out_pt &&
1898 hdr->pt != stream->rx_event_pt)
1899 {
1900 seq_st.status.flag.badpt = 1;
1901 }
1902 #endif
1903 if (seq_st.status.value) {
1904 TRC_ ((stream->port.info.name.ptr,
1905 "RTP status: badpt=%d, badssrc=%d, dup=%d, "
1906 "outorder=%d, probation=%d, restart=%d",
1907 seq_st.status.flag.badpt,
1908 seq_st.status.flag.badssrc,
1909 seq_st.status.flag.dup,
1910 seq_st.status.flag.outorder,
1911 seq_st.status.flag.probation,
1912 seq_st.status.flag.restart));
1913
1914 if (seq_st.status.flag.badpt) {
1915 PJ_LOG(4,(stream->port.info.name.ptr,
1916 "Bad RTP pt %d (expecting %d)",
1917 hdr->pt, channel->rtp.out_pt));
1918 }
1919
1920 if (!stream->si.has_rem_ssrc && seq_st.status.flag.badssrc) {
1921 PJ_LOG(4,(stream->port.info.name.ptr,
1922 "Changed RTP peer SSRC %d (previously %d)",
1923 channel->rtp.peer_ssrc, stream->rtcp.peer_ssrc));
1924 stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;
1925 }
1926
1927
1928 }
1929
1930 /* Skip bad RTP packet */
1931 if (seq_st.status.flag.bad) {
1932 pkt_discarded = PJ_TRUE;
1933 goto on_return;
1934 }
1935
1936 /* Ignore if payloadlen is zero */
1937 if (payloadlen == 0) {
1938 pkt_discarded = PJ_TRUE;
1939 goto on_return;
1940 }
1941
1942 /* See if source address of RTP packet is different than the
1943 * configured address, and check if we need to tell the
1944 * media transport to switch RTP remote address.
1945 */
1946 if (param->src_addr) {
1947 pj_bool_t badssrc = (stream->si.has_rem_ssrc &&
1948 seq_st.status.flag.badssrc);
1949
1950 if (pj_sockaddr_cmp(&stream->rem_rtp_addr, param->src_addr) == 0) {
1951 /* We're still receiving from rem_rtp_addr. */
1952 stream->rtp_src_cnt = 0;
1953 stream->rem_rtp_flag = badssrc? 2: 1;
1954 } else {
1955 stream->rtp_src_cnt++;
1956
1957 if (stream->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {
1958 if (stream->rem_rtp_flag == 1 ||
1959 (stream->rem_rtp_flag == 2 && badssrc))
1960 {
1961 /* Only discard if:
1962 * - we have ever received packet with good ssrc from
1963 * remote address (rem_rtp_addr), or
1964 * - we have ever received packet with bad ssrc from
1965 * remote address and this packet also has bad ssrc.
1966 */
1967 pkt_discarded = PJ_TRUE;
1968 goto on_return;
1969 }
1970 if (stream->si.has_rem_ssrc && !seq_st.status.flag.badssrc &&
1971 stream->rem_rtp_flag != 1)
1972 {
1973 /* Immediately switch if we receive packet with the
1974 * correct ssrc AND we never receive packets with
1975 * good ssrc from rem_rtp_addr.
1976 */
1977 param->rem_switch = PJ_TRUE;
1978 }
1979 } else {
1980 /* Switch. We no longer receive packets from rem_rtp_addr. */
1981 param->rem_switch = PJ_TRUE;
1982 }
1983
1984 if (param->rem_switch) {
1985 /* Set remote RTP address to source address */
1986 pj_sockaddr_cp(&stream->rem_rtp_addr, param->src_addr);
1987
1988 /* Reset counter and flag */
1989 stream->rtp_src_cnt = 0;
1990 stream->rem_rtp_flag = badssrc? 2: 1;
1991
1992 /* Update RTCP peer ssrc */
1993 stream->rtcp.peer_ssrc = pj_ntohl(hdr->ssrc);
1994 }
1995 }
1996 }
1997
1998 /* Handle incoming DTMF. */
1999 if (hdr->pt == stream->rx_event_pt) {
2000 pj_timestamp ts;
2001
2002 /* Ignore out-of-order packet as it will be detected as new
2003 * digit. Also ignore duplicate packet as it serves no use.
2004 */
2005 if (seq_st.status.flag.outorder || seq_st.status.flag.dup) {
2006 goto on_return;
2007 }
2008
2009 /* Get the timestamp of the event */
2010 ts.u64 = pj_ntohl(hdr->ts);
2011
2012 handle_incoming_dtmf(stream, &ts, payload, payloadlen);
2013 goto on_return;
2014 }
2015
2016 /* Put "good" packet to jitter buffer, or reset the jitter buffer
2017 * when RTP session is restarted.
2018 */
2019 pj_mutex_lock( stream->jb_mutex );
2020 if (seq_st.status.flag.restart) {
2021 status = pjmedia_jbuf_reset(stream->jb);
2022 PJ_LOG(4,(stream->port.info.name.ptr, "Jitter buffer reset"));
2023 } else {
2024 /*
2025 * Packets may contain more than one frames, while the jitter
2026 * buffer can only take one frame per "put" operation. So we need
2027 * to ask the codec to "parse" the payload into multiple frames.
2028 */
2029 enum { MAX = 16 };
2030 pj_timestamp ts;
2031 unsigned i, count = MAX;
2032 unsigned ts_span;
2033 pjmedia_frame frames[MAX];
2034
2035 /* Get the timestamp of the first sample */
2036 ts.u64 = pj_ntohl(hdr->ts);
2037
2038 /* Parse the payload. */
2039 status = pjmedia_codec_parse(stream->codec, (void*)payload,
2040 payloadlen, &ts, &count, frames);
2041 if (status != PJ_SUCCESS) {
2042 LOGERR_((stream->port.info.name.ptr, status,
2043 "Codec parse() error"));
2044 count = 0;
2045 } else if (stream->detect_ptime_change &&
2046 frames[0].bit_info > 0xFFFF)
2047 {
2048 unsigned dec_ptime;
2049
2050 PJ_LOG(4, (stream->port.info.name.ptr, "codec decode "
2051 "ptime change detected"));
2052 frames[0].bit_info &= 0xFFFF;
2053 dec_ptime = frames[0].bit_info * 1000 /
2054 stream->codec_param.info.clock_rate;
2055 stream->rtp_rx_ts_len_per_frame= stream->rtp_rx_ts_len_per_frame *
2056 dec_ptime / stream->dec_ptime;
2057 stream->dec_ptime = (pj_uint16_t)dec_ptime;
2058 pjmedia_jbuf_set_ptime(stream->jb, stream->dec_ptime);
2059
2060 /* Reset jitter buffer after ptime changed */
2061 pjmedia_jbuf_reset(stream->jb);
2062 }
2063
2064 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
2065 /* This code is used to learn the samples per frame value that is put
2066 * by remote endpoint, for codecs with inconsistent clock rate such
2067 * as G.722 or MPEG audio. We need to learn the samples per frame
2068 * value as it is used as divider when inserting frames into the
2069 * jitter buffer.
2070 */
2071 if (stream->has_g722_mpeg_bug) {
2072 if (stream->rtp_rx_check_cnt) {
2073 /* Make sure the detection performed only on two consecutive
2074 * packets with valid RTP sequence and no wrapped timestamp.
2075 */
2076 if (seq_st.diff == 1 && stream->rtp_rx_last_ts &&
2077 ts.u64 > stream->rtp_rx_last_ts &&
2078 stream->rtp_rx_last_cnt > 0)
2079 {
2080 unsigned peer_frm_ts_diff;
2081 unsigned frm_ts_span;
2082
2083 /* Calculate actual frame timestamp span */
2084 frm_ts_span = PJMEDIA_PIA_SPF(&stream->port.info) /
2085 stream->codec_param.setting.frm_per_pkt/
2086 PJMEDIA_PIA_CCNT(&stream->port.info);
2087
2088 /* Get remote frame timestamp span */
2089 peer_frm_ts_diff =
2090 ((pj_uint32_t)ts.u64-stream->rtp_rx_last_ts) /
2091 stream->rtp_rx_last_cnt;
2092
2093 /* Possibilities remote's samples per frame for G.722
2094 * are only (frm_ts_span) and (frm_ts_span/2), this
2095 * validation is needed to avoid wrong decision because
2096 * of silence frames.
2097 */
2098 if (stream->codec_param.info.pt == PJMEDIA_RTP_PT_G722 &&
2099 (peer_frm_ts_diff == frm_ts_span ||
2100 peer_frm_ts_diff == (frm_ts_span>>1)))
2101 {
2102 if (peer_frm_ts_diff < stream->rtp_rx_ts_len_per_frame)
2103 {
2104 stream->rtp_rx_ts_len_per_frame = peer_frm_ts_diff;
2105 /* Done, stop the check immediately */
2106 stream->rtp_rx_check_cnt = 1;
2107 }
2108
2109 if (--stream->rtp_rx_check_cnt == 0) {
2110 PJ_LOG(4, (THIS_FILE, "G722 codec used, remote"
2111 " samples per frame detected = %d",
2112 stream->rtp_rx_ts_len_per_frame));
2113
2114 /* Reset jitter buffer once detection done */
2115 pjmedia_jbuf_reset(stream->jb);
2116 }
2117 }
2118 }
2119
2120 stream->rtp_rx_last_ts = (pj_uint32_t)ts.u64;
2121 stream->rtp_rx_last_cnt = count;
2122 }
2123
2124 ts_span = stream->rtp_rx_ts_len_per_frame;
2125
2126 /* Adjust the timestamp of the parsed frames */
2127 for (i=0; i<count; ++i) {
2128 frames[i].timestamp.u64 = ts.u64 + (pj_uint64_t)ts_span * i;
2129 }
2130
2131 } else {
2132 ts_span = stream->dec_ptime *
2133 stream->codec_param.info.clock_rate /
2134 1000;
2135 }
2136 #else
2137 ts_span = stream->dec_ptime *
2138 stream->codec_param.info.clock_rate /
2139 1000;
2140 #endif
2141
2142 /* Put each frame to jitter buffer. */
2143 for (i=0; i<count; ++i) {
2144 unsigned ext_seq;
2145 pj_bool_t discarded;
2146
2147 ext_seq = (unsigned)(frames[i].timestamp.u64 / ts_span);
2148 pjmedia_jbuf_put_frame2(stream->jb, frames[i].buf, frames[i].size,
2149 frames[i].bit_info, ext_seq, &discarded);
2150 if (discarded)
2151 pkt_discarded = PJ_TRUE;
2152 }
2153
2154 #if TRACE_JB
2155 trace_jb_put(stream, hdr, payloadlen, count);
2156 #endif
2157
2158 }
2159 pj_mutex_unlock( stream->jb_mutex );
2160
2161
2162 /* Check if now is the time to transmit RTCP SR/RR report.
2163 * We only do this when stream direction is "decoding only" or
2164 * if the encoder is paused,
2165 * because otherwise check_tx_rtcp() will be handled by put_frame()
2166 */
2167 if (stream->dir == PJMEDIA_DIR_DECODING || stream->enc->paused) {
2168 check_tx_rtcp(stream, pj_ntohl(hdr->ts));
2169 }
2170
2171 if (status != 0) {
2172 LOGERR_((stream->port.info.name.ptr, status,
2173 "Jitter buffer put() error"));
2174 pkt_discarded = PJ_TRUE;
2175 goto on_return;
2176 }
2177
2178 on_return:
2179 /* Update RTCP session */
2180 if (stream->rtcp.peer_ssrc == 0)
2181 stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;
2182
2183 pjmedia_rtcp_rx_rtp2(&stream->rtcp, pj_ntohs(hdr->seq),
2184 pj_ntohl(hdr->ts), payloadlen, pkt_discarded);
2185
2186 /* RTCP-FB generic NACK */
2187 if (stream->rtcp.received >= 10 && seq_st.diff > 1 &&
2188 stream->send_rtcp_fb_nack && pj_ntohs(hdr->seq) >= seq_st.diff)
2189 {
2190 int i;
2191 pj_bzero(&stream->rtcp_fb_nack, sizeof(stream->rtcp_fb_nack));
2192 stream->rtcp_fb_nack.pid = pj_ntohs(hdr->seq) - seq_st.diff + 1;
2193 for (i = 0; i < (seq_st.diff - 1); ++i) {
2194 stream->rtcp_fb_nack.blp <<= 1;
2195 stream->rtcp_fb_nack.blp |= 1;
2196 }
2197
2198 /* Send it immediately */
2199 status = send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE, PJ_TRUE);
2200 if (status != PJ_SUCCESS) {
2201 PJ_PERROR(4,(stream->port.info.name.ptr, status,
2202 "Error sending RTCP FB generic NACK"));
2203 } else {
2204 stream->initial_rr = PJ_TRUE;
2205 }
2206 }
2207
2208 /* Send RTCP RR and SDES after we receive some RTP packets */
2209 if (stream->rtcp.received >= 10 && !stream->initial_rr) {
2210 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled,
2211 PJ_FALSE, PJ_FALSE, PJ_FALSE);
2212 if (status != PJ_SUCCESS) {
2213 PJ_PERROR(4,(stream->port.info.name.ptr, status,
2214 "Error sending initial RTCP RR"));
2215 } else {
2216 stream->initial_rr = PJ_TRUE;
2217 }
2218 }
2219 }
2220
2221
2222 /*
2223 * This callback is called by stream transport on receipt of packets
2224 * in the RTCP socket.
2225 */
2226 static void on_rx_rtcp( void *data,
2227 void *pkt,
2228 pj_ssize_t bytes_read)
2229 {
2230 pjmedia_stream *stream = (pjmedia_stream*) data;
2231 pj_status_t status;
2232
2233 /* Check for errors */
2234 if (bytes_read < 0) {
2235 status = (pj_status_t)-bytes_read;
2236 if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
2237 return;
2238 }
2239 LOGERR_((stream->port.info.name.ptr, status,
2240 "Unable to receive RTCP packet"));
2241
2242 if (status == PJ_ESOCKETSTOP) {
2243 /* Publish receive error event. */
2244 publish_tp_event(PJMEDIA_EVENT_MEDIA_TP_ERR, status, PJ_FALSE,
2245 PJMEDIA_DIR_DECODING, stream);
2246 }
2247 return;
2248 }
2249
2250 pjmedia_rtcp_rx_rtcp(&stream->rtcp, pkt, bytes_read);
2251 }
2252
2253
2254 /*
2255 * Create media channel.
2256 */
2257 static pj_status_t create_channel( pj_pool_t *pool,
2258 pjmedia_stream *stream,
2259 pjmedia_dir dir,
2260 unsigned pt,
2261 const pjmedia_stream_info *param,
2262 pjmedia_channel **p_channel)
2263 {
2264 pjmedia_channel *channel;
2265 pj_status_t status;
2266
2267 /* Allocate memory for channel descriptor */
2268
2269 channel = PJ_POOL_ZALLOC_T(pool, pjmedia_channel);
2270 PJ_ASSERT_RETURN(channel != NULL, PJ_ENOMEM);
2271
2272 /* Init channel info. */
2273
2274 channel->stream = stream;
2275 channel->dir = dir;
2276 channel->paused = 1;
2277 channel->pt = pt;
2278
2279
2280 /* Allocate buffer for outgoing packet. */
2281
2282 if (param->type == PJMEDIA_TYPE_AUDIO) {
2283 unsigned max_rx_based_size;
2284 unsigned max_bps_based_size;
2285
2286 /* out_pkt buffer is used for sending and receiving, so lets calculate
2287 * its size based on both. For receiving, we have stream->frame_size,
2288 * which is used in configuring jitter buffer frame length.
2289 * For sending, it is based on codec max_bps info.
2290 */
2291 max_rx_based_size = stream->frame_size;
2292 max_bps_based_size = stream->codec_param.info.max_bps *
2293 PJMEDIA_MAX_FRAME_DURATION_MS / 8 / 1000;
2294 channel->out_pkt_size = PJ_MAX(max_rx_based_size, max_bps_based_size);
2295
2296 /* Also include RTP header size (for sending) */
2297 channel->out_pkt_size += sizeof(pjmedia_rtp_hdr);
2298
2299 if (channel->out_pkt_size > PJMEDIA_MAX_MTU -
2300 PJMEDIA_STREAM_RESV_PAYLOAD_LEN)
2301 {
2302 channel->out_pkt_size = PJMEDIA_MAX_MTU -
2303 PJMEDIA_STREAM_RESV_PAYLOAD_LEN;
2304 }
2305 } else {
2306 return PJ_ENOTSUP;
2307 }
2308
2309 channel->out_pkt = pj_pool_alloc(pool, channel->out_pkt_size);
2310 PJ_ASSERT_RETURN(channel->out_pkt != NULL, PJ_ENOMEM);
2311
2312
2313
2314 /* Create RTP and RTCP sessions: */
2315 {
2316 pjmedia_rtp_session_setting settings;
2317
2318 settings.flags = (pj_uint8_t)((param->rtp_seq_ts_set << 2) |
2319 (param->has_rem_ssrc << 4) | 3);
2320 settings.default_pt = pt;
2321 settings.sender_ssrc = param->ssrc;
2322 settings.peer_ssrc = param->rem_ssrc;
2323 settings.seq = param->rtp_seq;
2324 settings.ts = param->rtp_ts;
2325 status = pjmedia_rtp_session_init2(&channel->rtp, settings);
2326 }
2327 if (status != PJ_SUCCESS)
2328 return status;
2329
2330 /* Done. */
2331 *p_channel = channel;
2332 return PJ_SUCCESS;
2333 }
2334
2335
2336 /*
2337 * Handle events.
2338 */
2339 static pj_status_t stream_event_cb(pjmedia_event *event,
2340 void *user_data)
2341 {
2342 pjmedia_stream *stream = (pjmedia_stream*)user_data;
2343
2344 /* Set RTCP FB capability in the event */
2345 if (event->type==PJMEDIA_EVENT_RX_RTCP_FB &&
2346 event->epub==&stream->rtcp)
2347 {
2348 pjmedia_event_rx_rtcp_fb_data *data = (pjmedia_event_rx_rtcp_fb_data*)
2349 &event->data.rx_rtcp_fb;
2350
2351 /* Application not configured to listen to NACK, discard this event */
2352 if (stream->rtcp_fb_nack_cap_idx < 0)
2353 return PJ_SUCCESS;
2354
2355 data->cap = stream->si.loc_rtcp_fb.caps[stream->rtcp_fb_nack_cap_idx];
2356 }
2357
2358 /* Republish events */
2359 return pjmedia_event_publish(NULL, stream, event,
2360 PJMEDIA_EVENT_PUBLISH_POST_EVENT);
2361 }
2362
2363
2364 /*
2365 * Create media stream.
2366 */
2367 PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
2368 pj_pool_t *pool,
2369 const pjmedia_stream_info *info,
2370 pjmedia_transport *tp,
2371 void *user_data,
2372 pjmedia_stream **p_stream)
2373
2374 {
2375 enum { M = 32 };
2376 pjmedia_stream *stream;
2377 pj_str_t name;
2378 unsigned jb_init, jb_max, jb_min_pre, jb_max_pre;
2379 pjmedia_audio_format_detail *afd;
2380 pj_pool_t *own_pool = NULL;
2381 char *p;
2382 pj_status_t status;
2383 pjmedia_transport_attach_param att_param;
2384
2385 PJ_ASSERT_RETURN(endpt && info && p_stream, PJ_EINVAL);
2386
2387 if (pool == NULL) {
2388 own_pool = pjmedia_endpt_create_pool( endpt, "strm%p",
2389 PJMEDIA_STREAM_SIZE,
2390 PJMEDIA_STREAM_INC);
2391 PJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM);
2392 pool = own_pool;
2393 }
2394
2395 /* Allocate the media stream: */
2396
2397 stream = PJ_POOL_ZALLOC_T(pool, pjmedia_stream);
2398 PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);
2399 stream->own_pool = own_pool;
2400
2401 /* Duplicate stream info */
2402 pj_memcpy(&stream->si, info, sizeof(*info));
2403 pj_strdup(pool, &stream->si.fmt.encoding_name, &info->fmt.encoding_name);
2404 if (info->param)
2405 stream->si.param = pjmedia_codec_param_clone(pool, info->param);
2406 pjmedia_rtcp_fb_info_dup(pool, &stream->si.loc_rtcp_fb,
2407 &info->loc_rtcp_fb);
2408 pjmedia_rtcp_fb_info_dup(pool, &stream->si.rem_rtcp_fb,
2409 &info->rem_rtcp_fb);
2410
2411 /* Init stream/port name */
2412 name.ptr = (char*) pj_pool_alloc(pool, M);
2413 name.slen = pj_ansi_snprintf(name.ptr, M, "strm%p", stream);
2414
2415 /* Init some port-info. Some parts of the info will be set later
2416 * once we have more info about the codec.
2417 */
2418 pjmedia_port_info_init(&stream->port.info, &name,
2419 PJMEDIA_SIG_PORT_STREAM,
2420 info->fmt.clock_rate, info->fmt.channel_cnt,
2421 16, 80);
2422 afd = pjmedia_format_get_audio_format_detail(&stream->port.info.fmt, 1);
2423
2424 /* Init port. */
2425
2426 //No longer there in 2.0
2427 //pj_strdup(pool, &stream->port.info.encoding_name, &info->fmt.encoding_name);
2428 afd->clock_rate = info->fmt.clock_rate;
2429 afd->channel_count = info->fmt.channel_cnt;
2430 stream->port.port_data.pdata = stream;
2431
2432 /* Init stream: */
2433 stream->endpt = endpt;
2434 stream->codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
2435 stream->dir = info->dir;
2436 stream->user_data = user_data;
2437 stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) *
2438 info->fmt.clock_rate / 1000;
2439 stream->rtcp_sdes_bye_disabled = info->rtcp_sdes_bye_disabled;
2440
2441 stream->tx_event_pt = info->tx_event_pt ? info->tx_event_pt : -1;
2442 stream->rx_event_pt = info->rx_event_pt ? info->rx_event_pt : -1;
2443 stream->last_dtmf = -1;
2444 stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME;
2445 stream->rtcp_fb_nack.pid = -1;
2446 stream->soft_start_cnt = PJMEDIA_STREAM_SOFT_START;
2447
2448 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
2449 stream->use_ka = info->use_ka;
2450 stream->start_ka_count = info->ka_cfg.start_count;
2451 stream->start_ka_interval = info->ka_cfg.start_interval;
2452 #endif
2453
2454 stream->cname = info->cname;
2455 if (stream->cname.slen == 0) {
2456 /* Build random RTCP CNAME. CNAME has user@host format */
2457 stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20);
2458 pj_create_random_string(p, 5);
2459 p += 5;
2460 *p++ = '@'; *p++ = 'p'; *p++ = 'j';
2461 pj_create_random_string(p, 6);
2462 p += 6;
2463 *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g';
2464 stream->cname.slen = p - stream->cname.ptr;
2465 }
2466
2467 /* Create mutex to protect jitter buffer: */
2468
2469 status = pj_mutex_create_simple(pool, NULL, &stream->jb_mutex);
2470 if (status != PJ_SUCCESS)
2471 goto err_cleanup;
2472
2473
2474 /* Create and initialize codec: */
2475
2476 status = pjmedia_codec_mgr_alloc_codec( stream->codec_mgr,
2477 &info->fmt, &stream->codec);
2478 if (status != PJ_SUCCESS)
2479 goto err_cleanup;
2480
2481
2482 /* Get codec param: */
2483 if (info->param)
2484 stream->codec_param = *stream->si.param;
2485 else {
2486 status = pjmedia_codec_mgr_get_default_param(stream->codec_mgr,
2487 &info->fmt,
2488 &stream->codec_param);
2489 if (status != PJ_SUCCESS)
2490 goto err_cleanup;
2491 }
2492
2493 /* Check for invalid max_bps. */
2494 if (stream->codec_param.info.max_bps < stream->codec_param.info.avg_bps)
2495 stream->codec_param.info.max_bps = stream->codec_param.info.avg_bps;
2496
2497 /* Check for invalid frame per packet. */
2498 if (stream->codec_param.setting.frm_per_pkt < 1)
2499 stream->codec_param.setting.frm_per_pkt = 1;
2500
2501 /* Init the codec. */
2502 status = pjmedia_codec_init(stream->codec, pool);
2503 if (status != PJ_SUCCESS)
2504 goto err_cleanup;
2505
2506 /* Open the codec. */
2507
2508 /* The clock rate for Opus codec is not static,
2509 * it's negotiated in the SDP.
2510 */
2511 if (!pj_stricmp2(&info->fmt.encoding_name, "opus")) {
2512 stream->codec_param.info.clock_rate = info->fmt.clock_rate;
2513 stream->codec_param.info.channel_cnt = info->fmt.channel_cnt;
2514
2515 /* Allocate decoding buffer as Opus can send a packet duration of
2516 * up to 120 ms.
2517 */
2518 stream->dec_buf_size = stream->codec_param.info.clock_rate * 120 /
2519 1000;
2520 stream->dec_buf = (pj_int16_t*)pj_pool_alloc(pool,
2521 stream->dec_buf_size *
2522 sizeof(pj_int16_t));
2523 }
2524
2525 status = pjmedia_codec_open(stream->codec, &stream->codec_param);
2526 if (status != PJ_SUCCESS)
2527 goto err_cleanup;
2528
2529 /* Set additional info and callbacks. */
2530 stream->dec_ptime = stream->codec_param.info.frm_ptime;
2531 afd->bits_per_sample = 16;
2532 afd->frame_time_usec = stream->codec_param.info.frm_ptime *
2533 stream->codec_param.setting.frm_per_pkt * 1000;
2534 stream->port.info.fmt.id = stream->codec_param.info.fmt_id;
2535 if (stream->codec_param.info.fmt_id == PJMEDIA_FORMAT_L16) {
2536 /* Raw format */
2537 afd->avg_bps = afd->max_bps = afd->clock_rate * afd->channel_count *
2538 afd->bits_per_sample;
2539
2540 stream->port.put_frame = &put_frame;
2541 stream->port.get_frame = &get_frame;
2542 } else {
2543 /* Encoded format */
2544 afd->avg_bps = stream->codec_param.info.avg_bps;
2545 afd->max_bps = stream->codec_param.info.max_bps;
2546
2547 /* Not applicable for 2.0
2548 if ((stream->codec_param.info.max_bps *
2549 stream->codec_param.info.frm_ptime *
2550 stream->codec_param.setting.frm_per_pkt) % 8000 != 0)
2551 {
2552 ++stream->port.info.bytes_per_frame;
2553 }
2554 stream->port.info.format.bitrate = stream->codec_param.info.avg_bps;
2555 stream->port.info.format.vad = (stream->codec_param.setting.vad != 0);
2556 */
2557
2558 stream->port.put_frame = &put_frame;
2559 stream->port.get_frame = &get_frame_ext;
2560 }
2561
2562 /* If encoder and decoder's ptime are asymmetric, then we need to
2563 * create buffer on the encoder side. This could happen for example
2564 * with iLBC
2565 */
2566 if (stream->codec_param.info.enc_ptime!=0 &&
2567 stream->codec_param.info.enc_ptime!=stream->codec_param.info.frm_ptime)
2568 {
2569 unsigned ptime;
2570
2571 stream->enc_samples_per_pkt = stream->codec_param.info.enc_ptime *
2572 stream->codec_param.info.channel_cnt *
2573 afd->clock_rate / 1000;
2574
2575 /* Set buffer size as twice the largest ptime value between
2576 * stream's ptime, encoder ptime, or decoder ptime.
2577 */
2578
2579 ptime = afd->frame_time_usec / 1000;
2580
2581 if (stream->codec_param.info.enc_ptime > ptime)
2582 ptime = stream->codec_param.info.enc_ptime;
2583
2584 if (stream->codec_param.info.frm_ptime > ptime)
2585 ptime = stream->codec_param.info.frm_ptime;
2586
2587 ptime <<= 1;
2588
2589 /* Allocate buffer */
2590 stream->enc_buf_size = afd->clock_rate * ptime / 1000;
2591 stream->enc_buf = (pj_int16_t*)
2592 pj_pool_alloc(pool, stream->enc_buf_size * 2);
2593
2594 } else {
2595 stream->enc_samples_per_pkt = PJMEDIA_AFD_SPF(afd);
2596 }
2597
2598
2599 /* Initially disable the VAD in the stream, to help traverse NAT better */
2600 stream->vad_enabled = stream->codec_param.setting.vad;
2601 if (PJMEDIA_STREAM_VAD_SUSPEND_MSEC > 0 && stream->vad_enabled) {
2602 stream->codec_param.setting.vad = 0;
2603 stream->ts_vad_disabled = 0;
2604 pjmedia_codec_modify(stream->codec, &stream->codec_param);
2605 PJ_LOG(4,(stream->port.info.name.ptr,"VAD temporarily disabled"));
2606 }
2607
2608 /* Get the frame size */
2609 if (stream->codec_param.info.max_rx_frame_size > 0) {
2610 stream->frame_size = stream->codec_param.info.max_rx_frame_size;
2611 } else {
2612 stream->frame_size = stream->codec_param.info.max_bps *
2613 stream->codec_param.info.frm_ptime / 8 / 1000;
2614 if ((stream->codec_param.info.max_bps *
2615 stream->codec_param.info.frm_ptime) % 8000 != 0)
2616 {
2617 ++stream->frame_size;
2618 }
2619 }
2620
2621 /* How many consecutive PLC frames can be generated */
2622 stream->max_plc_cnt = (MAX_PLC_MSEC+stream->codec_param.info.frm_ptime-1)/
2623 stream->codec_param.info.frm_ptime;
2624 /* Disable PLC until a "NORMAL" frame is gotten from the jitter buffer. */
2625 stream->plc_cnt = stream->max_plc_cnt;
2626
2627 #if defined(PJMEDIA_DTMF_DURATION_MSEC) && (PJMEDIA_DTMF_DURATION_MSEC > 0)
2628 stream->dtmf_duration = PJMEDIA_DTMF_DURATION_MSEC *
2629 afd->clock_rate / 1000;
2630 #else
2631 stream->dtmf_duration = PJMEDIA_DTMF_DURATION;
2632 #endif
2633
2634 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
2635 stream->rtp_rx_check_cnt = 50;
2636 stream->has_g722_mpeg_bug = PJ_FALSE;
2637 stream->rtp_rx_last_ts = 0;
2638 stream->rtp_rx_last_cnt = 0;
2639 stream->rtp_tx_ts_len_per_pkt = stream->enc_samples_per_pkt /
2640 stream->codec_param.info.channel_cnt;
2641 stream->rtp_rx_ts_len_per_frame = PJMEDIA_AFD_SPF(afd) /
2642 stream->codec_param.setting.frm_per_pkt /
2643 stream->codec_param.info.channel_cnt;
2644
2645 if (info->fmt.pt == PJMEDIA_RTP_PT_G722) {
2646 stream->has_g722_mpeg_bug = PJ_TRUE;
2647 /* RTP clock rate = 1/2 real clock rate */
2648 stream->rtp_tx_ts_len_per_pkt >>= 1;
2649 #if defined(PJMEDIA_DTMF_DURATION_MSEC) && (PJMEDIA_DTMF_DURATION_MSEC > 0)
2650 stream->dtmf_duration >>= 1;
2651 #endif
2652 } else if (!pj_stricmp2(&info->fmt.encoding_name, "opus")) {
2653 unsigned opus_ts_modifier = 48000 / afd->clock_rate;
2654 stream->rtp_rx_check_cnt = 0;
2655 stream->has_g722_mpeg_bug = PJ_TRUE;
2656 stream->rtp_tx_ts_len_per_pkt *= opus_ts_modifier;
2657 stream->rtp_rx_ts_len_per_frame *= opus_ts_modifier;
2658 stream->detect_ptime_change = PJ_TRUE;
2659 #if defined(PJMEDIA_DTMF_DURATION_MSEC) && (PJMEDIA_DTMF_DURATION_MSEC > 0)
2660 stream->dtmf_duration *= opus_ts_modifier;
2661 #endif
2662 }
2663 #endif
2664
2665 /* Init jitter buffer parameters: */
2666 if (info->jb_max >= stream->codec_param.info.frm_ptime)
2667 jb_max = (info->jb_max + stream->codec_param.info.frm_ptime - 1) /
2668 stream->codec_param.info.frm_ptime;
2669 else
2670 jb_max = 500 / stream->codec_param.info.frm_ptime;
2671
2672 if (info->jb_min_pre >= stream->codec_param.info.frm_ptime)
2673 jb_min_pre = info->jb_min_pre / stream->codec_param.info.frm_ptime;
2674 else
2675 //jb_min_pre = 60 / stream->codec_param.info.frm_ptime;
2676 jb_min_pre = 1;
2677
2678 if (info->jb_max_pre >= stream->codec_param.info.frm_ptime)
2679 jb_max_pre = info->jb_max_pre / stream->codec_param.info.frm_ptime;
2680 else
2681 //jb_max_pre = 240 / stream->codec_param.info.frm_ptime;
2682 jb_max_pre = jb_max * 4 / 5;
2683
2684 if (info->jb_init >= stream->codec_param.info.frm_ptime)
2685 jb_init = info->jb_init / stream->codec_param.info.frm_ptime;
2686 else
2687 //jb_init = (jb_min_pre + jb_max_pre) / 2;
2688 jb_init = 0;
2689
2690 /* Create jitter buffer */
2691 status = pjmedia_jbuf_create(pool, &stream->port.info.name,
2692 stream->frame_size,
2693 stream->codec_param.info.frm_ptime,
2694 jb_max, &stream->jb);
2695 if (status != PJ_SUCCESS)
2696 goto err_cleanup;
2697
2698
2699 /* Set up jitter buffer */
2700 pjmedia_jbuf_set_adaptive( stream->jb, jb_init, jb_min_pre, jb_max_pre);
2701 pjmedia_jbuf_set_discard(stream->jb, info->jb_discard_algo);
2702
2703 /* Create decoder channel: */
2704
2705 status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,
2706 info->rx_pt, info, &stream->dec);
2707 if (status != PJ_SUCCESS)
2708 goto err_cleanup;
2709
2710
2711 /* Create encoder channel: */
2712
2713 status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING,
2714 info->tx_pt, info, &stream->enc);
2715 if (status != PJ_SUCCESS)
2716 goto err_cleanup;
2717
2718
2719 /* Init RTCP session: */
2720
2721 {
2722 pjmedia_rtcp_session_setting rtcp_setting;
2723
2724 pjmedia_rtcp_session_setting_default(&rtcp_setting);
2725 rtcp_setting.name = stream->port.info.name.ptr;
2726 rtcp_setting.ssrc = info->ssrc;
2727 rtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts);
2728 rtcp_setting.clock_rate = info->fmt.clock_rate;
2729 rtcp_setting.samples_per_frame = PJMEDIA_AFD_SPF(afd);
2730
2731 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
2732 /* Special case for G.722 */
2733 if (info->fmt.pt == PJMEDIA_RTP_PT_G722) {
2734 rtcp_setting.clock_rate = 8000;
2735 rtcp_setting.samples_per_frame = 160;
2736 }
2737 #endif
2738
2739 pjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting);
2740
2741 if (info->rtp_seq_ts_set) {
2742 stream->rtcp.stat.rtp_tx_last_seq = info->rtp_seq;
2743 stream->rtcp.stat.rtp_tx_last_ts = info->rtp_ts;
2744 }
2745
2746 /* Subscribe to RTCP events */
2747 pjmedia_event_subscribe(NULL, &stream_event_cb, stream,
2748 &stream->rtcp);
2749 }
2750
2751 /* Allocate outgoing RTCP buffer, should be enough to hold SR/RR, SDES,
2752 * BYE, and XR.
2753 */
2754 stream->out_rtcp_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) +
2755 sizeof(pjmedia_rtcp_common) +
2756 (4 + (unsigned)stream->cname.slen) +
2757 32;
2758 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
2759 if (info->rtcp_xr_enabled) {
2760 stream->out_rtcp_pkt_size += sizeof(pjmedia_rtcp_xr_pkt);
2761 }
2762 #endif
2763
2764 if (stream->out_rtcp_pkt_size > PJMEDIA_MAX_MTU)
2765 stream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU;
2766
2767 stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);
2768 pj_bzero(&att_param, sizeof(att_param));
2769 att_param.stream = stream;
2770 att_param.media_type = PJMEDIA_TYPE_AUDIO;
2771 att_param.user_data = stream;
2772 pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr);
2773 pj_sockaddr_cp(&stream->rem_rtp_addr, &info->rem_addr);
2774 if (stream->si.rtcp_mux) {
2775 pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_addr);
2776 } else if (pj_sockaddr_has_addr(&info->rem_rtcp.addr)) {
2777 pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);
2778 }
2779 att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr);
2780 att_param.rtp_cb2 = &on_rx_rtp;
2781 att_param.rtcp_cb = &on_rx_rtcp;
2782
2783 /* Only attach transport when stream is ready. */
2784 status = pjmedia_transport_attach2(tp, &att_param);
2785 if (status != PJ_SUCCESS)
2786 goto err_cleanup;
2787
2788 stream->transport = tp;
2789
2790 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
2791 /* Enable RTCP XR and update stream info/config to RTCP XR */
2792 if (info->rtcp_xr_enabled) {
2793 int i;
2794
2795 pjmedia_rtcp_enable_xr(&stream->rtcp, PJ_TRUE);
2796
2797 /* Set RTCP XR TX interval */
2798 if (info->rtcp_xr_interval != 0)
2799 stream->rtcp_xr_interval = info->rtcp_xr_interval;
2800 else
2801 stream->rtcp_xr_interval = (PJMEDIA_RTCP_INTERVAL +
2802 (pj_rand() % 8000)) *
2803 info->fmt.clock_rate / 1000;
2804
2805 /* Additional third-party RTCP XR destination */
2806 if (info->rtcp_xr_dest.addr.sa_family != 0) {
2807 stream->rtcp_xr_dest_len = pj_sockaddr_get_len(&info->rtcp_xr_dest);
2808 pj_memcpy(&stream->rtcp_xr_dest, &info->rtcp_xr_dest,
2809 stream->rtcp_xr_dest_len);
2810 }
2811
2812 /* jitter buffer adaptive info */
2813 i = PJMEDIA_RTCP_XR_JB_ADAPTIVE;
2814 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
2815 PJMEDIA_RTCP_XR_INFO_CONF_JBA,
2816 i);
2817
2818 /* Jitter buffer aggressiveness info (estimated) */
2819 i = 7;
2820 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
2821 PJMEDIA_RTCP_XR_INFO_CONF_JBR,
2822 i);
2823
2824 /* Jitter buffer absolute maximum delay */
2825 i = jb_max * stream->codec_param.info.frm_ptime;
2826 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
2827 PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX,
2828 i);
2829
2830 /* PLC info */
2831 if (stream->codec_param.setting.plc == 0)
2832 i = PJMEDIA_RTCP_XR_PLC_DIS;
2833 else
2834 #if PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA
2835 i = PJMEDIA_RTCP_XR_PLC_ENH;
2836 #else
2837 i = PJMEDIA_RTCP_XR_PLC_DIS;
2838 #endif
2839 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
2840 PJMEDIA_RTCP_XR_INFO_CONF_PLC,
2841 i);
2842 }
2843 #endif
2844
2845 /* Check if we should send RTCP-FB */
2846 if (stream->si.rem_rtcp_fb.cap_count) {
2847 pjmedia_rtcp_fb_info *rfi = &stream->si.rem_rtcp_fb;
2848 unsigned i;
2849
2850 for (i = 0; i < rfi->cap_count; ++i) {
2851 if (rfi->caps[i].type == PJMEDIA_RTCP_FB_NACK &&
2852 rfi->caps[i].param.slen == 0)
2853 {
2854 stream->send_rtcp_fb_nack = PJ_TRUE;
2855 PJ_LOG(4,(stream->port.info.name.ptr,
2856 "Send RTCP-FB generic NACK"));
2857 break;
2858 }
2859 }
2860 }
2861
2862 /* Check if we should process incoming RTCP-FB */
2863 stream->rtcp_fb_nack_cap_idx = -1;
2864 if (stream->si.loc_rtcp_fb.cap_count) {
2865 pjmedia_rtcp_fb_info *lfi = &stream->si.loc_rtcp_fb;
2866 unsigned i;
2867
2868 for (i = 0; i < lfi->cap_count; ++i) {
2869 if (lfi->caps[i].type == PJMEDIA_RTCP_FB_NACK &&
2870 lfi->caps[i].param.slen == 0)
2871 {
2872 stream->rtcp_fb_nack_cap_idx = i;
2873 PJ_LOG(4,(stream->port.info.name.ptr,
2874 "Receive RTCP-FB generic NACK"));
2875 break;
2876 }
2877 }
2878 }
2879
2880 /* Update the stream info's codec param */
2881 stream->si.param = &stream->codec_param;
2882
2883 /* Send RTCP SDES */
2884 if (!stream->rtcp_sdes_bye_disabled) {
2885 pjmedia_stream_send_rtcp_sdes(stream);
2886 }
2887
2888 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
2889 /* NAT hole punching by sending KA packet via RTP transport. */
2890 if (stream->use_ka)
2891 send_keep_alive_packet(stream);
2892 #endif
2893
2894 #if TRACE_JB
2895 {
2896 char trace_name[PJ_MAXPATH];
2897 pj_ssize_t len;
2898
2899 pj_ansi_snprintf(trace_name, sizeof(trace_name),
2900 TRACE_JB_PATH_PREFIX "%s.csv",
2901 stream->port.info.name.ptr);
2902 status = pj_file_open(pool, trace_name, PJ_O_WRONLY,
2903 &stream->trace_jb_fd);
2904 if (status != PJ_SUCCESS) {
2905 stream->trace_jb_fd = TRACE_JB_INVALID_FD;
2906 PJ_PERROR(3,(THIS_FILE, status,
2907 "Failed creating RTP trace file '%s'", trace_name));
2908 } else {
2909 stream->trace_jb_buf = (char*)pj_pool_alloc(pool, PJ_LOG_MAX_SIZE);
2910
2911 /* Print column header */
2912 len = pj_ansi_snprintf(stream->trace_jb_buf, PJ_LOG_MAX_SIZE,
2913 "Time, Operation, Size, Frame Count, "
2914 "Frame type, RTP Seq, RTP TS, RTP M, "
2915 "JB size, JB burst level, JB prefetch\n");
2916 if (len < 1 || len >= PJ_LOG_MAX_SIZE)
2917 len = PJ_LOG_MAX_SIZE-1;
2918 pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);
2919 pj_file_flush(stream->trace_jb_fd);
2920 }
2921 }
2922 #endif
2923
2924 /* Success! */
2925 *p_stream = stream;
2926
2927 PJ_LOG(5,(THIS_FILE, "Stream %s created", stream->port.info.name.ptr));
2928
2929 return PJ_SUCCESS;
2930
2931
2932 err_cleanup:
2933 pjmedia_stream_destroy(stream);
2934 return status;
2935 }
2936
2937
2938 /*
2939 * Destroy stream.
2940 */
2941 PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
2942 {
2943 pj_status_t status;
2944
2945 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
2946
2947 /* Send RTCP BYE (also SDES & XR) */
2948 if (stream->transport && !stream->rtcp_sdes_bye_disabled) {
2949 send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_TRUE, PJ_FALSE);
2950 }
2951
2952 /* If we're in the middle of transmitting DTMF digit, send one last
2953 * RFC 2833 RTP packet with 'End' flag set.
2954 */
2955 if (stream->tx_dtmf_count && stream->tx_dtmf_buf[0].duration != 0) {
2956 pjmedia_frame frame_out;
2957 pjmedia_channel *channel = stream->enc;
2958 int first=0, last=0;
2959 void *rtphdr;
2960 int rtphdrlen;
2961
2962 pj_bzero(&frame_out, sizeof(frame_out));
2963 frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
2964 frame_out.size = 0;
2965
2966 create_dtmf_payload(stream, &frame_out, 1, &first, &last);
2967
2968 /* Encapsulate into RTP packet. Note that:
2969 * - RTP marker should be set on the beginning of a new event
2970 * - RTP timestamp is constant for the same packet.
2971 */
2972 status = pjmedia_rtp_encode_rtp( &channel->rtp,
2973 stream->tx_event_pt, first,
2974 (int)frame_out.size, 0,
2975 (const void**)&rtphdr,
2976 &rtphdrlen);
2977 if (status == PJ_SUCCESS) {
2978 /* Copy RTP header to the beginning of packet */
2979 pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));
2980
2981 /* Send the RTP packet to the transport. */
2982 status = pjmedia_transport_send_rtp(stream->transport,
2983 channel->out_pkt,
2984 frame_out.size +
2985 sizeof(pjmedia_rtp_hdr));
2986 }
2987
2988 if (status != PJ_SUCCESS) {
2989 PJ_PERROR(4,(stream->port.info.name.ptr, status,
2990 "Error sending RTP/DTMF end packet"));
2991 }
2992 }
2993
2994 /* Unsubscribe from RTCP session events */
2995 pjmedia_event_unsubscribe(NULL, &stream_event_cb, stream,
2996 &stream->rtcp);
2997
2998 /* Detach from transport
2999 * MUST NOT hold stream mutex while detaching from transport, as
3000 * it may cause deadlock. See ticket #460 for the details.
3001 */
3002 if (stream->transport) {
3003 pjmedia_transport_detach(stream->transport, stream);
3004 stream->transport = NULL;
3005 }
3006
3007 /* This function may be called when stream is partly initialized. */
3008 if (stream->jb_mutex)
3009 pj_mutex_lock(stream->jb_mutex);
3010
3011
3012 /* Free codec. */
3013
3014 if (stream->codec) {
3015 pjmedia_codec_close(stream->codec);
3016 pjmedia_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec);
3017 stream->codec = NULL;
3018 }
3019
3020 /* Free mutex */
3021
3022 if (stream->jb_mutex) {
3023 pj_mutex_unlock(stream->jb_mutex);
3024 pj_mutex_destroy(stream->jb_mutex);
3025 stream->jb_mutex = NULL;
3026 }
3027
3028 /* Destroy jitter buffer */
3029 if (stream->jb)
3030 pjmedia_jbuf_destroy(stream->jb);
3031
3032 #if TRACE_JB
3033 if (TRACE_JB_OPENED(stream)) {
3034 pj_file_close(stream->trace_jb_fd);
3035 stream->trace_jb_fd = TRACE_JB_INVALID_FD;
3036 }
3037 #endif
3038
3039 pj_pool_safe_release(&stream->own_pool);
3040
3041 return PJ_SUCCESS;
3042 }
3043
3044
3045 /*
3046 * Get the last frame frame type retreived from the jitter buffer.
3047 */
3048 PJ_DEF(char) pjmedia_stream_get_last_jb_frame_type(pjmedia_stream *stream)
3049 {
3050 return stream->jb_last_frm;
3051 }
3052
3053
3054 /*
3055 * Get the port interface.
3056 */
3057 PJ_DEF(pj_status_t) pjmedia_stream_get_port( pjmedia_stream *stream,
3058 pjmedia_port **p_port )
3059 {
3060 *p_port = &stream->port;
3061 return PJ_SUCCESS;
3062 }
3063
3064
3065 /*
3066 * Get the transport object
3067 */
3068 PJ_DEF(pjmedia_transport*) pjmedia_stream_get_transport(pjmedia_stream *st)
3069 {
3070 return st->transport;
3071 }
3072
3073
3074 /*
3075 * Start stream.
3076 */
3077 PJ_DEF(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream)
3078 {
3079
3080 PJ_ASSERT_RETURN(stream && stream->enc && stream->dec, PJ_EINVALIDOP);
3081
3082 if (stream->enc && (stream->dir & PJMEDIA_DIR_ENCODING)) {
3083 stream->enc->paused = 0;
3084 //pjmedia_snd_stream_start(stream->enc->snd_stream);
3085 PJ_LOG(4,(stream->port.info.name.ptr, "Encoder stream started"));
3086 } else {
3087 PJ_LOG(4,(stream->port.info.name.ptr, "Encoder stream paused"));
3088 }
3089
3090 if (stream->dec && (stream->dir & PJMEDIA_DIR_DECODING)) {
3091 stream->dec->paused = 0;
3092 //pjmedia_snd_stream_start(stream->dec->snd_stream);
3093 PJ_LOG(4,(stream->port.info.name.ptr, "Decoder stream started"));
3094 } else {
3095 PJ_LOG(4,(stream->port.info.name.ptr, "Decoder stream paused"));
3096 }
3097
3098 return PJ_SUCCESS;
3099 }
3100
3101
3102 PJ_DEF(pj_status_t) pjmedia_stream_get_info( const pjmedia_stream *stream,
3103 pjmedia_stream_info *info)
3104 {
3105 PJ_ASSERT_RETURN(stream && info, PJ_EINVAL);
3106
3107 pj_memcpy(info, &stream->si, sizeof(pjmedia_stream_info));
3108 return PJ_SUCCESS;
3109 }
3110
3111 /*
3112 * Get stream statistics.
3113 */
3114 PJ_DEF(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream,
3115 pjmedia_rtcp_stat *stat)
3116 {
3117 PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL);
3118
3119 pj_memcpy(stat, &stream->rtcp.stat, sizeof(pjmedia_rtcp_stat));
3120 return PJ_SUCCESS;
3121 }
3122
3123
3124 /*
3125 * Reset the stream statistics in the middle of a stream session.
3126 */
3127 PJ_DEF(pj_status_t) pjmedia_stream_reset_stat(pjmedia_stream *stream)
3128 {
3129 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3130
3131 pjmedia_rtcp_init_stat(&stream->rtcp.stat);
3132
3133 return PJ_SUCCESS;
3134 }
3135
3136
3137 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
3138 /*
3139 * Get stream extended statistics.
3140 */
3141 PJ_DEF(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream,
3142 pjmedia_rtcp_xr_stat *stat)
3143 {
3144 PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL);
3145
3146 if (stream->rtcp.xr_enabled) {
3147 pj_memcpy(stat, &stream->rtcp.xr_session.stat, sizeof(pjmedia_rtcp_xr_stat));
3148 return PJ_SUCCESS;
3149 }
3150 return PJ_ENOTFOUND;
3151 }
3152 #endif
3153
3154 /*
3155 * Get jitter buffer state.
3156 */
3157 PJ_DEF(pj_status_t) pjmedia_stream_get_stat_jbuf(const pjmedia_stream *stream,
3158 pjmedia_jb_state *state)
3159 {
3160 PJ_ASSERT_RETURN(stream && state, PJ_EINVAL);
3161 return pjmedia_jbuf_get_state(stream->jb, state);
3162 }
3163
3164 /*
3165 * Pause stream.
3166 */
3167 PJ_DEF(pj_status_t) pjmedia_stream_pause( pjmedia_stream *stream,
3168 pjmedia_dir dir)
3169 {
3170 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3171
3172 if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {
3173 stream->enc->paused = 1;
3174 PJ_LOG(4,(stream->port.info.name.ptr, "Encoder stream paused"));
3175 }
3176
3177 if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {
3178 stream->dec->paused = 1;
3179
3180 /* Also reset jitter buffer */
3181 pj_mutex_lock( stream->jb_mutex );
3182 pjmedia_jbuf_reset(stream->jb);
3183 pj_mutex_unlock( stream->jb_mutex );
3184
3185 PJ_LOG(4,(stream->port.info.name.ptr, "Decoder stream paused"));
3186 }
3187
3188 return PJ_SUCCESS;
3189 }
3190
3191
3192 /*
3193 * Resume stream
3194 */
3195 PJ_DEF(pj_status_t) pjmedia_stream_resume( pjmedia_stream *stream,
3196 pjmedia_dir dir)
3197 {
3198 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3199
3200 if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {
3201 stream->enc->paused = 0;
3202 PJ_LOG(4,(stream->port.info.name.ptr, "Encoder stream resumed"));
3203 }
3204
3205 if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {
3206 stream->dec->paused = 0;
3207 stream->soft_start_cnt = PJMEDIA_STREAM_SOFT_START;
3208 PJ_LOG(4,(stream->port.info.name.ptr, "Decoder stream resumed"));
3209 }
3210
3211 return PJ_SUCCESS;
3212 }
3213
3214 /*
3215 * Dial DTMF
3216 */
3217 PJ_DEF(pj_status_t) pjmedia_stream_dial_dtmf( pjmedia_stream *stream,
3218 const pj_str_t *digit_char)
3219 {
3220 pj_status_t status = PJ_SUCCESS;
3221
3222 /* By convention we use jitter buffer mutex to access DTMF
3223 * queue.
3224 */
3225 PJ_ASSERT_RETURN(stream && digit_char, PJ_EINVAL);
3226
3227 /* Check that remote can receive DTMF events. */
3228 if (stream->tx_event_pt < 0) {
3229 return PJMEDIA_RTP_EREMNORFC2833;
3230 }
3231
3232 pj_mutex_lock(stream->jb_mutex);
3233
3234 if (stream->tx_dtmf_count+digit_char->slen >=
3235 (long)PJ_ARRAY_SIZE(stream->tx_dtmf_buf))
3236 {
3237 status = PJ_ETOOMANY;
3238 } else {
3239 int i;
3240
3241 /* convert ASCII digits into payload type first, to make sure
3242 * that all digits are valid.
3243 */
3244 for (i=0; i<digit_char->slen; ++i) {
3245 unsigned pt;
3246 int dig = pj_tolower(digit_char->ptr[i]);
3247
3248 if (dig >= '0' && dig <= '9')
3249 {
3250 pt = dig - '0';
3251 }
3252 else if (dig >= 'a' && dig <= 'd')
3253 {
3254 pt = dig - 'a' + 12;
3255 }
3256 else if (dig == '*')
3257 {
3258 pt = 10;
3259 }
3260 else if (dig == '#')
3261 {
3262 pt = 11;
3263 }
3264 #if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0
3265 else if (dig == 'r')
3266 {
3267 pt = 16;
3268 }
3269 #endif
3270 else
3271 {
3272 status = PJMEDIA_RTP_EINDTMF;
3273 break;
3274 }
3275
3276 stream->tx_dtmf_buf[stream->tx_dtmf_count+i].event = pt;
3277 stream->tx_dtmf_buf[stream->tx_dtmf_count+i].duration = 0;
3278 stream->tx_dtmf_buf[stream->tx_dtmf_count+i].ebit_cnt = 0;
3279 }
3280
3281 if (status != PJ_SUCCESS)
3282 goto on_return;
3283
3284 /* Increment digit count only if all digits are valid. */
3285 stream->tx_dtmf_count += (int)digit_char->slen;
3286 }
3287
3288 on_return:
3289 pj_mutex_unlock(stream->jb_mutex);
3290
3291 return status;
3292 }
3293
3294
3295 /*
3296 * See if we have DTMF digits in the rx buffer.
3297 */
3298 PJ_DEF(pj_bool_t) pjmedia_stream_check_dtmf(pjmedia_stream *stream)
3299 {
3300 return stream->rx_dtmf_count != 0;
3301 }
3302
3303
3304 /*
3305 * Retrieve incoming DTMF digits from the stream's DTMF buffer.
3306 */
3307 PJ_DEF(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,
3308 char *digits,
3309 unsigned *size)
3310 {
3311 PJ_ASSERT_RETURN(stream && digits && size, PJ_EINVAL);
3312
3313 /* By convention, we use jitter buffer's mutex to access DTMF
3314 * digits resources.
3315 */
3316 pj_mutex_lock(stream->jb_mutex);
3317
3318 if (stream->rx_dtmf_count < *size)
3319 *size = stream->rx_dtmf_count;
3320
3321 if (*size) {
3322 pj_memcpy(digits, stream->rx_dtmf_buf, *size);
3323 stream->rx_dtmf_count -= *size;
3324 if (stream->rx_dtmf_count) {
3325 pj_memmove(stream->rx_dtmf_buf,
3326 &stream->rx_dtmf_buf[*size],
3327 stream->rx_dtmf_count);
3328 }
3329 }
3330
3331 pj_mutex_unlock(stream->jb_mutex);
3332
3333 return PJ_SUCCESS;
3334 }
3335
3336
3337 /*
3338 * Set callback to be called upon receiving DTMF digits.
3339 */
3340 PJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
3341 void (*cb)(pjmedia_stream*,
3342 void *user_data,
3343 int digit),
3344 void *user_data)
3345 {
3346 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3347
3348 /* By convention, we use jitter buffer's mutex to access DTMF
3349 * digits resources.
3350 */
3351 pj_mutex_lock(stream->jb_mutex);
3352
3353 stream->dtmf_cb = cb;
3354 stream->dtmf_cb_user_data = user_data;
3355
3356 pj_mutex_unlock(stream->jb_mutex);
3357
3358 return PJ_SUCCESS;
3359 }
3360
3361 PJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_event_callback(pjmedia_stream *stream,
3362 void (*cb)(pjmedia_stream*,
3363 void *user_data,
3364 const pjmedia_stream_dtmf_event *event),
3365 void *user_data)
3366 {
3367 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3368
3369 /* By convention, we use jitter buffer's mutex to access DTMF
3370 * digits resources.
3371 */
3372 pj_mutex_lock(stream->jb_mutex);
3373
3374 stream->dtmf_event_cb = cb;
3375 stream->dtmf_event_cb_user_data = user_data;
3376
3377 pj_mutex_unlock(stream->jb_mutex);
3378
3379 return PJ_SUCCESS;
3380 }
3381
3382 /*
3383 * Send RTCP SDES.
3384 */
3385 PJ_DEF(pj_status_t)
3386 pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream )
3387 {
3388 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3389
3390 return send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE, PJ_FALSE);
3391 }
3392
3393 /*
3394 * Send RTCP BYE.
3395 */
3396 PJ_DEF(pj_status_t)
3397 pjmedia_stream_send_rtcp_bye( pjmedia_stream *stream )
3398 {
3399 PJ_ASSERT_RETURN(stream, PJ_EINVAL);
3400
3401 if (stream->enc && stream->transport) {
3402 return send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_FALSE, PJ_FALSE);
3403 }
3404
3405 return PJ_SUCCESS;
3406 }
3407
3408
3409 /**
3410 * Get RTP session information from stream.
3411 */
3412 PJ_DEF(pj_status_t)
3413 pjmedia_stream_get_rtp_session_info(pjmedia_stream *stream,
3414 pjmedia_stream_rtp_sess_info *session_info)
3415 {
3416 session_info->rx_rtp = &stream->dec->rtp;
3417 session_info->tx_rtp = &stream->enc->rtp;
3418 session_info->rtcp = &stream->rtcp;
3419 return PJ_SUCCESS;
3420 }
3421