- Timestamp:
- May 13, 2006 10:46:23 PM (19 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/ioqueue_common_abs.c
r433 r438 71 71 pj_status_t rc; 72 72 int optlen; 73 74 PJ_UNUSED_ARG(pool); 73 75 74 76 key->ioqueue = ioqueue; -
pjproject/trunk/pjmedia/include/pjmedia/codec.h
r421 r438 111 111 struct pjmedia_codec_param 112 112 { 113 unsigned clock_rate; /**< Sampling rate in Hz */ 114 unsigned channel_cnt; /**< Channel count. */ 115 pj_uint32_t avg_bps; /**< Average bandwidth in bits/sec */ 116 117 pj_uint16_t ptime; /**< Packet time in miliseconds */ 118 pj_uint8_t pcm_bits_per_sample;/**< Bits/sample in the PCM side */ 119 120 unsigned pt:8; /**< Payload type. */ 121 unsigned vad:1; /**< Voice Activity Detector. */ 122 unsigned cng:1; /**< Comfort Noise Generator. */ 123 unsigned lpf:1; /**< Low pass filter */ 124 unsigned hpf:1; /**< High pass filter */ 125 unsigned penh:1; /**< Perceptual Enhancement */ 126 unsigned concl:1; /**< Packet loss concealment */ 127 unsigned reserved:1; /**< Reserved, must be NULL. */ 128 113 /** 114 * The "info" part of codec param describes the capability of the codec, 115 * and the value should NOT be changed by application. 116 */ 117 struct { 118 unsigned clock_rate; /**< Sampling rate in Hz */ 119 unsigned channel_cnt; /**< Channel count. */ 120 pj_uint32_t avg_bps; /**< Average bandwidth in bits/sec */ 121 pj_uint16_t frm_ptime; /**< Base frame ptime in msec. */ 122 pj_uint8_t pcm_bits_per_sample; /**< Bits/sample in the PCM side */ 123 pj_uint8_t pt; /**< Payload type. */ 124 } info; 125 126 /** 127 * The "setting" part of codec param describes various settings to be 128 * applied to the codec. When the codec param is retrieved from the codec 129 * or codec factory, the values of these will be filled by the capability 130 * of the codec. Any features that are supported by the codec (e.g. vad 131 * or plc) will be turned on, so that application can query which 132 * capabilities are supported by the codec. Application may change the 133 * settings here before instantiating the codec/stream. 134 */ 135 struct { 136 pj_uint8_t frm_per_pkt; /**< Number of frames per packet. */ 137 unsigned vad:1; /**< Voice Activity Detector. */ 138 unsigned cng:1; /**< Comfort Noise Generator. */ 139 unsigned lpf:1; /**< Low pass filter */ 140 unsigned hpf:1; /**< High pass filter */ 141 unsigned penh:1; /**< Perceptual Enhancement */ 142 unsigned plc:1; /**< Packet loss concealment */ 143 unsigned reserved:1; /**< Reserved, must be zero. */ 144 } setting; 129 145 }; 130 146 … … 183 199 /** 184 200 * Instruct the codec to inspect the specified payload/packet and 185 * split the packet info individual frames. 201 * split the packet into individual base frames. Each output frames will 202 * have ptime that is equal to basic frame ptime (i.e. the value of 203 * info.frm_ptime in #pjmedia_codec_param). 186 204 * 187 205 * @param codec The codec instance 188 206 * @param pkt The input packet. 189 207 * @param pkt_size Size of the packet. 208 * @param timestamp The timestamp of the first sample in the packet. 190 209 * @param frame_cnt On input, specifies the maximum number of frames 191 210 * in the array. On output, the codec must fill … … 196 215 * @return PJ_SUCCESS on success. 197 216 */ 198 pj_status_t (*get_frames)(pjmedia_codec *codec, 199 void *pkt, 200 pj_size_t pkt_size, 201 unsigned *frame_cnt, 202 pjmedia_frame frames[]); 203 204 /** 205 * Instruct the codec to encode the specified input frame. 217 pj_status_t (*parse)( pjmedia_codec *codec, 218 void *pkt, 219 pj_size_t pkt_size, 220 const pj_timestamp *timestamp, 221 unsigned *frame_cnt, 222 pjmedia_frame frames[]); 223 224 /** 225 * Instruct the codec to encode the specified input frame. The input 226 * PCM samples MUST have ptime that is exactly equal to base frame 227 * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param). 206 228 * 207 229 * @param codec The codec instance. … … 218 240 219 241 /** 220 * Instruct the codec to decode the specified input frame. 242 * Instruct the codec to decode the specified input frame. The input 243 * frame MUST have ptime that is exactly equal to base frame 244 * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param). 245 * Application can achieve this by parsing the packet into base 246 * frames before decoding each frame. 221 247 * 222 248 * @param codec The codec instance. … … 232 258 struct pjmedia_frame *output); 233 259 260 /** 261 * Instruct the codec to recover a missing frame. Not all codec has 262 * this capability, so this function may be NULL. 263 * 264 * @param codec The codec instance. 265 * @param out_size The length of buffer in the output frame. 266 * @param output The output frame. 267 * 268 * @return PJ_SUCCESS on success; 269 */ 270 pj_status_t (*recover)(pjmedia_codec *codec, 271 unsigned out_size, 272 struct pjmedia_frame *output); 234 273 }; 235 274 -
pjproject/trunk/pjmedia/include/pjmedia/config.h
r417 r438 78 78 /** 79 79 * Maximum frame duration (in msec) to be supported. 80 * This (among other thing) will affect the size of buffers to be allocated 81 * for outgoing packets. 80 82 */ 81 83 #ifndef PJMEDIA_MAX_FRAME_DURATION_MS -
pjproject/trunk/pjmedia/include/pjmedia/errno.h
r420 r438 276 276 */ 277 277 #define PJMEDIA_CODEC_EPCMTOOSHORT (PJMEDIA_ERRNO_START+83) /* 220083 */ 278 /** 279 * @hideinitializer 280 * Invalid codec frame length. 281 */ 282 #define PJMEDIA_CODEC_EFRMINLEN (PJMEDIA_ERRNO_START+84) /* 220084 */ 278 283 279 284 -
pjproject/trunk/pjmedia/include/pjmedia/jbuf.h
r436 r438 56 56 57 57 /** 58 * @see pjmedia_jb_frame_type. 59 */ 60 typedef enum pjmedia_jb_frame_type pjmedia_jb_frame_type; 61 62 63 /** 58 64 * This structure describes jitter buffer current status. 59 65 */ … … 79 85 */ 80 86 #define PJMEDIA_JB_DEFAULT_INIT_DELAY 15 87 88 /** 89 * Opaque declaration for jitter buffer. 90 */ 91 typedef struct pjmedia_jbuf pjmedia_jbuf; 81 92 82 93 … … 182 193 * @return PJ_SUCCESS on success. 183 194 */ 184 PJ_DECL( pj_status_t) pjmedia_jbuf_put_frame(pjmedia_jbuf *jb,185 186 187 195 PJ_DECL(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb, 196 const void *frame, 197 pj_size_t size, 198 int frame_seq); 188 199 189 200 /** … … 211 222 * buffer will copy the frame to the buffer, and frame 212 223 * type will be set to PJMEDIA_JB_NORMAL_FRAME. 213 * 214 * @return Always returns PJ_SUCCESS. 215 */ 216 PJ_DECL(pj_status_t) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, 217 void *frame, 218 char *p_frm_type); 224 */ 225 PJ_DECL(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, 226 void *frame, 227 char *p_frm_type); 219 228 220 229 -
pjproject/trunk/pjmedia/include/pjmedia/session.h
r414 r438 67 67 68 68 69 /** 70 * Initialize stream info from SDP media lines. 71 * 72 * @param si Stream info structure to be initialized. 73 * @param pool Pool. 69 /** 70 * Opaque declaration of media session. 71 */ 72 typedef struct pjmedia_session pjmedia_session; 73 74 75 /** 76 * @see pjmedia_session_info. 77 */ 78 typedef struct pjmedia_session_info pjmedia_session_info; 79 80 81 /** 82 * This function will initialize the session info based on information 83 * in both SDP session descriptors. The remaining information will be 84 * taken from default codec parameters. If socket info array is specified, 85 * the socket will be copied to the session info as well. 86 * 87 * @param pool Pool to allocate memory. 74 88 * @param endpt Pjmedia endpoint. 89 * @param max_streams Maximum number of stream infos to be created. 90 * @param si Session info structure to be initialized. 91 * @param skinfo Optional array of media socket info to be copied 92 * to the stream info. If this argument is specified, 93 * the array must contain sufficient elements for 94 * each stream to be initialized. 75 95 * @param local Local SDP session descriptor. 76 96 * @param remote Remote SDP session descriptor. … … 79 99 * @return PJ_SUCCESS if stream info is successfully initialized. 80 100 */ 81 PJ_DECL(pj_status_t) pjmedia_stream_info_from_sdp( 82 pjmedia_stream_info *si, 83 pj_pool_t *pool, 84 pjmedia_endpt *endpt, 85 const pjmedia_sdp_session *local, 86 const pjmedia_sdp_session *remote, 87 unsigned stream_idx); 88 101 PJ_DECL(pj_status_t) 102 pjmedia_session_info_from_sdp( pj_pool_t *pool, 103 pjmedia_endpt *endpt, 104 unsigned max_streams, 105 pjmedia_session_info *si, 106 const pjmedia_sock_info skinfo[], 107 const pjmedia_sdp_session *local, 108 const pjmedia_sdp_session *remote); 109 110 111 /* 112 * This function will initialize the stream info based on information 113 * in both SDP session descriptors for the specified stream index. 114 * The remaining information will be taken from default codec parameters. 115 * If socket info array is specified, the socket will be copied to the 116 * session info as well. 117 * 118 * @param si Stream info structure to be initialized. 119 * @param pool Pool to allocate memory. 120 * @param endpt PJMEDIA endpoint instance. 121 * @param skinfo Optional socket info to be copied to the stream info. 122 * @param local Local SDP session descriptor. 123 * @param remote Remote SDP session descriptor. 124 * @param stream_idx Media stream index in the session descriptor. 125 * 126 * @return PJ_SUCCESS if stream info is successfully initialized. 127 */ 128 PJ_DECL(pj_status_t) 129 pjmedia_stream_info_from_sdp( pjmedia_stream_info *si, 130 pj_pool_t *pool, 131 pjmedia_endpt *endpt, 132 const pjmedia_sock_info *skinfo, 133 const pjmedia_sdp_session *local, 134 const pjmedia_sdp_session *remote, 135 unsigned stream_idx); 89 136 90 137 /** … … 102 149 * also denotes the number of elements in the 103 150 * socket information. 104 * @param skinfo Array of socket informations. The argument stream_cnt105 * specifies the number of elements in this array. One106 * element is needed for each media stream to be107 * created in the session.108 151 * @param local_sdp The SDP describing local capability. 109 152 * @param rem_sdp The SDP describing remote capability. … … 116 159 PJ_DECL(pj_status_t) 117 160 pjmedia_session_create( pjmedia_endpt *endpt, 118 unsigned stream_cnt, 119 const pjmedia_sock_info skinfo[], 120 const pjmedia_sdp_session *local_sdp, 121 const pjmedia_sdp_session *rem_sdp, 161 const pjmedia_session_info *si, 122 162 void *user_data, 123 163 pjmedia_session **p_session ); -
pjproject/trunk/pjmedia/include/pjmedia/stream.h
r428 r438 73 73 pj_sockaddr_in rem_addr; /**< Remote RTP address */ 74 74 pjmedia_codec_info fmt; /**< Incoming codec format info. */ 75 pjmedia_codec_param *param; /**< Optional codec param. */ 75 76 unsigned tx_pt; /**< Outgoing codec paylaod type. */ 76 77 int tx_event_pt;/**< Outgoing pt for telephone-events. */ 77 78 int rx_event_pt;/**< Incoming pt for telephone-events. */ 78 79 pj_uint32_t ssrc; /**< RTP SSRC. */ 79 int jb_init; /**< Jitter buffer init delay in msec. */ 80 int jb_init; /**< Jitter buffer init delay in msec. 81 (-1 for default). */ 82 int jb_min_pre; /**< Jitter buffer minimum prefetch 83 delay in msec (-1 for default). */ 84 int jb_max_pre; /**< Jitter buffer maximum prefetch 85 delay in msec (-1 for default). */ 80 86 int jb_max; /**< Jitter buffer max delay in msec. */ 81 87 }; 88 89 90 /** 91 * @see pjmedia_stream_info. 92 */ 93 typedef struct pjmedia_stream_info pjmedia_stream_info; 94 95 96 /** 97 * Opaque declaration for media stream. 98 */ 99 typedef struct pjmedia_stream pjmedia_stream; 82 100 83 101 -
pjproject/trunk/pjmedia/include/pjmedia/types.h
r411 r438 115 115 116 116 /** 117 * Typedef for media stream information. 117 * This is a general purpose function set PCM samples to zero. 118 * Since this function is needed by many parts of the library, it is important 119 * that the library should select the best performance for this. 120 * 121 * @param samples The 16bit PCM samples. 122 * @param count Number of samples. 118 123 */ 119 typedef struct pjmedia_stream_info pjmedia_stream_info; 124 PJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count) 125 { 126 unsigned i; 127 for (i=0; i<count; ++i) 128 samples[i] = 0; 129 } 120 130 121 /**122 * Typedef for media stream statistic.123 */124 typedef struct pjmedia_stream_stat pjmedia_stream_stat;125 126 /**127 * Typedef for media stream.128 */129 typedef struct pjmedia_stream pjmedia_stream;130 131 /**132 * Individual channel statistic.133 */134 typedef struct pjmedia_channel_stat pjmedia_channel_stat;135 136 /**137 * Opaque declaration of media session.138 */139 typedef struct pjmedia_session pjmedia_session;140 141 /**142 * Media session info.143 */144 typedef struct pjmedia_session_info pjmedia_session_info;145 146 /**147 * Types of frame returned from jitter buffer (jbuf.h).148 */149 typedef enum pjmedia_jb_frame_type pjmedia_jb_frame_type;150 151 /**152 * Opaque declaration for jitter buffer.153 */154 typedef struct pjmedia_jbuf pjmedia_jbuf;155 131 156 132 #endif /* __PJMEDIA_TYPES_H__ */ -
pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c
r411 r438 55 55 pjmedia_codec_param *attr ); 56 56 static pj_status_t gsm_codec_close( pjmedia_codec *codec ); 57 static pj_status_t gsm_codec_get_frames( pjmedia_codec *codec, 58 void *pkt, 59 pj_size_t pkt_size, 60 unsigned *frame_cnt, 61 pjmedia_frame frames[]); 57 static pj_status_t gsm_codec_parse( pjmedia_codec *codec, 58 void *pkt, 59 pj_size_t pkt_size, 60 const pj_timestamp *ts, 61 unsigned *frame_cnt, 62 pjmedia_frame frames[]); 62 63 static pj_status_t gsm_codec_encode( pjmedia_codec *codec, 63 64 const struct pjmedia_frame *input, … … 75 76 &gsm_codec_open, 76 77 &gsm_codec_close, 77 &gsm_codec_ get_frames,78 &gsm_codec_parse, 78 79 &gsm_codec_encode, 79 80 &gsm_codec_decode … … 231 232 232 233 pj_memset(attr, 0, sizeof(pjmedia_codec_param)); 233 attr->clock_rate = 8000; 234 attr->channel_cnt = 1; 235 attr->avg_bps = 13200; 236 attr->pcm_bits_per_sample = 16; 237 attr->ptime = 20; 238 attr->pt = PJMEDIA_RTP_PT_GSM; 234 attr->info.clock_rate = 8000; 235 attr->info.channel_cnt = 1; 236 attr->info.avg_bps = 13200; 237 attr->info.pcm_bits_per_sample = 16; 238 attr->info.frm_ptime = 20; 239 attr->info.pt = PJMEDIA_RTP_PT_GSM; 240 241 attr->setting.frm_per_pkt = 1; 239 242 240 243 /* Default all flag bits disabled. */ … … 387 390 * Get frames in the packet. 388 391 */ 389 static pj_status_t gsm_codec_get_frames( pjmedia_codec *codec, 390 void *pkt, 391 pj_size_t pkt_size, 392 unsigned *frame_cnt, 393 pjmedia_frame frames[]) 392 static pj_status_t gsm_codec_parse( pjmedia_codec *codec, 393 void *pkt, 394 pj_size_t pkt_size, 395 const pj_timestamp *ts, 396 unsigned *frame_cnt, 397 pjmedia_frame frames[]) 394 398 { 395 399 unsigned count = 0; … … 400 404 401 405 while (pkt_size >= 33 && count < *frame_cnt) { 402 frames[0].type = PJMEDIA_FRAME_TYPE_AUDIO; 403 frames[0].buf = pkt; 404 frames[0].size = 33; 406 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 407 frames[count].buf = pkt; 408 frames[count].size = 33; 409 frames[count].timestamp.u64 = ts->u64 + count * 160; 405 410 406 411 pkt = ((char*)pkt) + 33; -
pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c
r411 r438 62 62 pjmedia_codec_param *attr ); 63 63 static pj_status_t l16_close( pjmedia_codec *codec ); 64 static pj_status_t l16_get_frames(pjmedia_codec *codec, 65 void *pkt, 66 pj_size_t pkt_size, 67 unsigned *frame_cnt, 68 pjmedia_frame frames[]); 64 static pj_status_t l16_parse(pjmedia_codec *codec, 65 void *pkt, 66 pj_size_t pkt_size, 67 const pj_timestamp *ts, 68 unsigned *frame_cnt, 69 pjmedia_frame frames[]); 69 70 static pj_status_t l16_encode( pjmedia_codec *codec, 70 71 const struct pjmedia_frame *input, … … 82 83 &l16_open, 83 84 &l16_close, 84 &l16_ get_frames,85 &l16_parse, 85 86 &l16_encode, 86 87 &l16_decode … … 235 236 236 237 pj_memset(attr, 0, sizeof(pjmedia_codec_param)); 237 attr-> pt =id->pt;238 attr-> clock_rate = id->clock_rate;239 attr-> channel_cnt = id->channel_cnt;240 attr-> avg_bps = id->clock_rate * id->channel_cnt * 16;241 attr-> pcm_bits_per_sample = 16;238 attr->info.pt = (pj_uint8_t)id->pt; 239 attr->info.clock_rate = id->clock_rate; 240 attr->info.channel_cnt = id->channel_cnt; 241 attr->info.avg_bps = id->clock_rate * id->channel_cnt * 16; 242 attr->info.pcm_bits_per_sample = 16; 242 243 243 244 /* To keep frame size below 1400 MTU, set ptime to 10ms for 244 245 * sampling rate > 35 KHz 245 246 */ 246 attr->ptime = GET_PTIME(id->clock_rate); 247 attr->info.frm_ptime = GET_PTIME(id->clock_rate); 248 249 attr->setting.frm_per_pkt = 1; 247 250 248 251 /* Default all flag bits disabled. */ … … 499 502 } 500 503 501 static pj_status_t l16_get_frames( pjmedia_codec *codec, 502 void *pkt, 503 pj_size_t pkt_size, 504 unsigned *frame_cnt, 505 pjmedia_frame frames[]) 504 static pj_status_t l16_parse( pjmedia_codec *codec, 505 void *pkt, 506 pj_size_t pkt_size, 507 const pj_timestamp *ts, 508 unsigned *frame_cnt, 509 pjmedia_frame frames[]) 506 510 { 507 511 unsigned count = 0; … … 512 516 513 517 while (pkt_size >= data->frame_size && count < *frame_cnt) { 514 frames[0].type = PJMEDIA_FRAME_TYPE_AUDIO; 515 frames[0].buf = pkt; 516 frames[0].size = data->frame_size; 518 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 519 frames[count].buf = pkt; 520 frames[count].size = data->frame_size; 521 frames[count].timestamp.u64 = ts->u64 + (count * data->frame_size); 517 522 518 523 pkt = ((char*)pkt) + data->frame_size; -
pjproject/trunk/pjmedia/src/pjmedia-codec/speex/ltp.c
r278 r438 177 177 VARDECL(spx_word32_t *energy); 178 178 VARDECL(spx_word32_t *score); 179 VARDECL(spx_word16_t *swn2);179 /*VARDECL(spx_word16_t *swn2);*/ 180 180 spx_word16_t *swn; 181 181 -
pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c
r411 r438 62 62 pjmedia_codec_param *attr ); 63 63 static pj_status_t spx_codec_close( pjmedia_codec *codec ); 64 static pj_status_t spx_codec_get_frames( pjmedia_codec *codec, 65 void *pkt, 66 pj_size_t pkt_size, 67 unsigned *frame_cnt, 68 pjmedia_frame frames[]); 64 static pj_status_t spx_codec_parse( pjmedia_codec *codec, 65 void *pkt, 66 pj_size_t pkt_size, 67 const pj_timestamp *ts, 68 unsigned *frame_cnt, 69 pjmedia_frame frames[]); 69 70 static pj_status_t spx_codec_encode( pjmedia_codec *codec, 70 71 const struct pjmedia_frame *input, … … 75 76 unsigned output_buf_len, 76 77 struct pjmedia_frame *output); 78 static pj_status_t spx_codec_recover(pjmedia_codec *codec, 79 unsigned output_buf_len, 80 struct pjmedia_frame *output); 77 81 78 82 /* Definition for Speex codec operations. */ … … 82 86 &spx_codec_open, 83 87 &spx_codec_close, 84 &spx_codec_ get_frames,88 &spx_codec_parse, 85 89 &spx_codec_encode, 86 &spx_codec_decode 90 &spx_codec_decode, 91 &spx_codec_recover 87 92 }; 88 93 … … 378 383 379 384 pj_memset(attr, 0, sizeof(pjmedia_codec_param)); 380 attr-> pt =id->pt;381 attr-> channel_cnt = 1;385 attr->info.pt = (pj_uint8_t)id->pt; 386 attr->info.channel_cnt = 1; 382 387 383 388 if (id->clock_rate <= 8000) { 384 attr-> clock_rate = spx_factory.speex_param[PARAM_NB].clock_rate;385 attr-> avg_bps = spx_factory.speex_param[PARAM_NB].bitrate;389 attr->info.clock_rate = spx_factory.speex_param[PARAM_NB].clock_rate; 390 attr->info.avg_bps = spx_factory.speex_param[PARAM_NB].bitrate; 386 391 387 392 } else if (id->clock_rate <= 16000) { 388 attr-> clock_rate = spx_factory.speex_param[PARAM_WB].clock_rate;389 attr-> avg_bps = spx_factory.speex_param[PARAM_WB].bitrate;393 attr->info.clock_rate = spx_factory.speex_param[PARAM_WB].clock_rate; 394 attr->info.avg_bps = spx_factory.speex_param[PARAM_WB].bitrate; 390 395 391 396 } else { 392 397 /* Wow.. somebody is doing ultra-wideband. Cool...! */ 393 attr->clock_rate = spx_factory.speex_param[PARAM_UWB].clock_rate; 394 attr->avg_bps = spx_factory.speex_param[PARAM_UWB].bitrate; 395 } 396 397 attr->pcm_bits_per_sample = 16; 398 attr->ptime = 20; 399 attr->pt = id->pt; 398 attr->info.clock_rate = spx_factory.speex_param[PARAM_UWB].clock_rate; 399 attr->info.avg_bps = spx_factory.speex_param[PARAM_UWB].bitrate; 400 } 401 402 attr->info.pcm_bits_per_sample = 16; 403 attr->info.frm_ptime = 20; 404 attr->info.pt = (pj_uint8_t)id->pt; 405 406 attr->setting.frm_per_pkt = 1; 400 407 401 408 /* Default flags. */ 402 attr-> cng = 1;403 attr-> concl= 1;404 attr-> hpf = 1;405 attr-> lpf =1 ;406 attr-> penh =1 ;409 attr->setting.cng = 1; 410 attr->setting.plc = 1; 411 attr->setting.hpf = 1; 412 attr->setting.lpf =1 ; 413 attr->setting.penh =1 ; 407 414 408 415 /* Default, set VAD off as it caused voice chip off */ 409 attr-> vad = 0;416 attr->setting.vad = 0; 410 417 411 418 return PJ_SUCCESS; … … 560 567 561 568 /* Sampling rate. */ 562 tmp = attr-> clock_rate;569 tmp = attr->info.clock_rate; 563 570 speex_encoder_ctl(spx->enc, SPEEX_SET_SAMPLING_RATE, 564 571 &spx_factory.speex_param[id].clock_rate); 565 572 566 573 /* VAD */ 567 tmp = attr-> vad;574 tmp = attr->setting.vad; 568 575 speex_encoder_ctl(spx->enc, SPEEX_SET_VAD, &tmp); 569 576 … … 589 596 590 597 /* PENH */ 591 tmp = attr-> penh;598 tmp = attr->setting.penh; 592 599 speex_decoder_ctl(spx->dec, SPEEX_SET_ENH, &tmp); 593 600 … … 625 632 * Get frames in the packet. 626 633 */ 627 static pj_status_t spx_codec_get_frames( pjmedia_codec *codec, 628 void *pkt, 629 pj_size_t pkt_size, 630 unsigned *frame_cnt, 631 pjmedia_frame frames[]) 634 static pj_status_t spx_codec_parse( pjmedia_codec *codec, 635 void *pkt, 636 pj_size_t pkt_size, 637 const pj_timestamp *ts, 638 unsigned *frame_cnt, 639 pjmedia_frame frames[]) 632 640 { 633 641 struct spx_private *spx; 634 unsigned speex_frame_size;642 unsigned frame_size, samples_per_frame; 635 643 unsigned count; 636 644 637 645 spx = (struct spx_private*) codec->codec_data; 638 646 639 speex_frame_size = spx_factory.speex_param[spx->param_id].framesize; 647 frame_size = spx_factory.speex_param[spx->param_id].framesize; 648 samples_per_frame = spx_factory.speex_param[spx->param_id].samples_per_frame; 640 649 641 650 /* Don't really know how to do this... */ 642 651 count = 0; 643 while (pkt_size >= speex_frame_size && count < *frame_cnt) {652 while (pkt_size >= frame_size && count < *frame_cnt) { 644 653 frames[count].buf = pkt; 645 frames[count].size = speex_frame_size;654 frames[count].size = frame_size; 646 655 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 647 frames[count].timestamp.u64 = 0;648 649 pkt_size -= speex_frame_size;656 frames[count].timestamp.u64 = ts->u64 + count * samples_per_frame; 657 658 pkt_size -= frame_size; 650 659 ++count; 651 pkt = ((char*)pkt) + speex_frame_size; 652 } 653 660 pkt = ((char*)pkt) + frame_size; 661 } 662 663 /* Just in case speex has silence frame which size is less than normal 664 * frame size... 665 */ 654 666 if (pkt_size && count < *frame_cnt) { 655 667 frames[count].buf = pkt; 656 668 frames[count].size = pkt_size; 657 669 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 658 frames[count].timestamp.u64 = 0;670 frames[count].timestamp.u64 = ts->u64 + count * samples_per_frame; 659 671 ++count; 660 672 } … … 765 777 } 766 778 779 /* 780 * Recover lost frame. 781 */ 782 static pj_status_t spx_codec_recover(pjmedia_codec *codec, 783 unsigned output_buf_len, 784 struct pjmedia_frame *output) 785 { 786 struct spx_private *spx; 787 float tmp[642]; /* 20ms at 32KHz + 2 */ 788 pj_int16_t *dst_buf; 789 unsigned i, count; 790 791 spx = (struct spx_private*) codec->codec_data; 792 793 count = spx_factory.speex_param[spx->param_id].clock_rate * 20 / 1000; 794 pj_assert((count <= output_buf_len/2) && count <= PJ_ARRAY_SIZE(tmp)); 795 796 /* Recover packet loss */ 797 speex_decode(spx->dec, NULL, tmp); 798 799 /* Copy from float to short samples. */ 800 dst_buf = output->buf; 801 for (i=0; i<count; ++i) { 802 dst_buf[i] = (pj_int16_t)tmp[i]; 803 } 804 output->size = count * 2; 805 806 return PJ_SUCCESS; 807 } 808 767 809 768 810 #endif /* PJMEDIA_HAS_SPEEX_CODEC */ -
pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
r424 r438 474 474 codec_info[i].clock_rate/1000, 475 475 codec_info[i].channel_cnt, 476 good_number(bps, param. avg_bps),477 param. ptime,478 (param. vad ? " vad" : ""),479 (param. cng ? " cng" : ""),480 (param. concl? " plc" : ""),481 (param. penh ? " penh" : ""),476 good_number(bps, param.info.avg_bps), 477 param.info.frm_ptime * param.setting.frm_per_pkt, 478 (param.setting.vad ? " vad" : ""), 479 (param.setting.cng ? " cng" : ""), 480 (param.setting.plc ? " plc" : ""), 481 (param.setting.penh ? " penh" : ""), 482 482 (prio[i]==PJMEDIA_CODEC_PRIO_DISABLED?" disabled":""))); 483 483 } -
pjproject/trunk/pjmedia/src/pjmedia/errno.c
r420 r438 88 88 { PJMEDIA_CODEC_EFRMTOOSHORT, "Codec frame is too short" }, 89 89 { PJMEDIA_CODEC_EPCMTOOSHORT, "PCM frame is too short" }, 90 { PJMEDIA_CODEC_EFRMINLEN, "Invalid codec frame length" }, 90 91 91 92 /* Media errors. */ -
pjproject/trunk/pjmedia/src/pjmedia/g711.c
r429 r438 24 24 #include <pjmedia/errno.h> 25 25 #include <pjmedia/port.h> 26 #include <pjmedia/plc.h> 26 27 #include <pj/pool.h> 27 28 #include <pj/string.h> … … 31 32 32 33 33 #define G711_BPS 64000 34 #define G711_CODEC_CNT 0 /* number of codec to preallocate in memory */ 35 #define PTIME 20 36 #define FRAME_SIZE (8000 * PTIME / 1000) 34 #define G711_BPS 64000 35 #define G711_CODEC_CNT 0 /* number of codec to preallocate in memory */ 36 #define PTIME 10 /* basic frame size is 10 msec */ 37 #define FRAME_SIZE (8000 * PTIME / 1000) /* 80 bytes */ 38 #define SAMPLES_PER_FRAME (8000 * PTIME / 1000) /* 80 samples */ 37 39 38 40 /* These are the only public functions exported to applications */ 39 PJ_DECL(pj_status_t) g711_init_factory (pjmedia_codec_factory *factory, pj_pool_t *pool); 41 PJ_DECL(pj_status_t) g711_init_factory (pjmedia_codec_factory *factory, 42 pj_pool_t *pool); 40 43 41 44 /* Algorithm prototypes. */ 42 unsigned char linear2alaw(int pcm_val); /* 2's complement (16-bit range) */45 unsigned char linear2alaw(int pcm_val); 43 46 int alaw2linear(unsigned char a_val); 44 47 unsigned char linear2ulaw(int pcm_val); … … 66 69 pjmedia_codec_param *attr ); 67 70 static pj_status_t g711_close( pjmedia_codec *codec ); 68 static pj_status_t g711_get_frames(pjmedia_codec *codec, 69 void *pkt, 70 pj_size_t pkt_size, 71 unsigned *frame_cnt, 72 pjmedia_frame frames[]); 71 static pj_status_t g711_parse(pjmedia_codec *codec, 72 void *pkt, 73 pj_size_t pkt_size, 74 const pj_timestamp *timestamp, 75 unsigned *frame_cnt, 76 pjmedia_frame frames[]); 73 77 static pj_status_t g711_encode( pjmedia_codec *codec, 74 78 const struct pjmedia_frame *input, … … 79 83 unsigned output_buf_len, 80 84 struct pjmedia_frame *output); 85 static pj_status_t g711_recover( pjmedia_codec *codec, 86 unsigned output_buf_len, 87 struct pjmedia_frame *output); 81 88 82 89 /* Definition for G711 codec operations. */ … … 86 93 &g711_open, 87 94 &g711_close, 88 &g711_ get_frames,95 &g711_parse, 89 96 &g711_encode, 90 &g711_decode 97 &g711_decode, 98 &g711_recover 91 99 }; 92 100 … … 114 122 struct g711_private 115 123 { 116 unsigned pt; 124 unsigned pt; 125 pj_bool_t plc_enabled; 126 pjmedia_plc *plc; 117 127 }; 118 128 … … 218 228 219 229 /* It's sufficient to check payload type only. */ 220 return (id->pt==PJMEDIA_RTP_PT_PCMU || id->pt==PJMEDIA_RTP_PT_PCMA) ? 0 :-1;230 return (id->pt==PJMEDIA_RTP_PT_PCMU || id->pt==PJMEDIA_RTP_PT_PCMA)? 0:-1; 221 231 } 222 232 … … 228 238 229 239 pj_memset(attr, 0, sizeof(pjmedia_codec_param)); 230 attr->clock_rate = 8000; 231 attr->channel_cnt = 1; 232 attr->avg_bps = G711_BPS; 233 attr->pcm_bits_per_sample = 16; 234 attr->ptime = PTIME; 235 attr->pt = id->pt; 240 attr->info.clock_rate = 8000; 241 attr->info.channel_cnt = 1; 242 attr->info.avg_bps = G711_BPS; 243 attr->info.pcm_bits_per_sample = 16; 244 attr->info.frm_ptime = PTIME; 245 attr->info.pt = (pj_uint8_t)id->pt; 246 247 /* Set default frames per packet to 2 (or 20ms) */ 248 attr->setting.frm_per_pkt = 2; 249 250 /* Enable plc by default. */ 251 attr->setting.plc = 1; 236 252 237 253 /* Default all flag bits disabled. */ … … 275 291 { 276 292 pjmedia_codec *codec = NULL; 293 pj_status_t status; 277 294 278 295 PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL); … … 293 310 } 294 311 312 /* Set the payload type */ 295 313 codec_priv->pt = id->pt; 314 315 /* Create PLC, always with 10ms ptime */ 316 status = pjmedia_plc_create(g711_factory.pool, 8000, 80, 317 0, &codec_priv->plc); 318 if (status != PJ_SUCCESS) { 319 pj_mutex_unlock(g711_factory.mutex); 320 return status; 321 } 296 322 297 323 codec->factory = factory; … … 351 377 { 352 378 struct g711_private *priv = codec->codec_data; 353 priv->pt = attr->pt; 379 priv->pt = attr->info.pt; 380 priv->plc_enabled = (attr->setting.plc != 0); 354 381 return PJ_SUCCESS; 355 382 } … … 362 389 } 363 390 364 static pj_status_t g711_get_frames(pjmedia_codec *codec, 365 void *pkt, 366 pj_size_t pkt_size, 367 unsigned *frame_cnt, 368 pjmedia_frame frames[]) 391 static pj_status_t g711_parse( pjmedia_codec *codec, 392 void *pkt, 393 pj_size_t pkt_size, 394 const pj_timestamp *ts, 395 unsigned *frame_cnt, 396 pjmedia_frame frames[]) 369 397 { 370 398 unsigned count = 0; 371 399 372 400 PJ_UNUSED_ARG(codec); 373 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL); 401 402 PJ_ASSERT_RETURN(ts && frame_cnt && frames, PJ_EINVAL); 374 403 375 404 while (pkt_size >= FRAME_SIZE && count < *frame_cnt) { 376 frames[0].type = PJMEDIA_FRAME_TYPE_AUDIO; 377 frames[0].buf = pkt; 378 frames[0].size = FRAME_SIZE; 405 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 406 frames[count].buf = pkt; 407 frames[count].size = FRAME_SIZE; 408 frames[count].timestamp.u64 = ts->u64 + SAMPLES_PER_FRAME * count; 379 409 380 410 pkt = ((char*)pkt) + FRAME_SIZE; … … 434 464 435 465 /* Check output buffer length */ 436 if (output_buf_len < input->size * 2) 437 return PJMEDIA_CODEC_EPCMTOOSHORT; 466 PJ_ASSERT_RETURN(output_buf_len >= input->size * 2, 467 PJMEDIA_CODEC_EPCMTOOSHORT); 468 469 /* Input buffer MUST have exactly 80 bytes long */ 470 PJ_ASSERT_RETURN(input->size == FRAME_SIZE, 471 PJMEDIA_CODEC_EFRMINLEN); 438 472 439 473 /* Decode */ … … 462 496 output->size = input->size * 2; 463 497 464 return PJ_SUCCESS; 465 } 466 498 if (priv->plc_enabled) 499 pjmedia_plc_save( priv->plc, output->buf); 500 501 return PJ_SUCCESS; 502 } 503 504 static pj_status_t g711_recover( pjmedia_codec *codec, 505 unsigned output_buf_len, 506 struct pjmedia_frame *output) 507 { 508 struct g711_private *priv = codec->codec_data; 509 510 if (!priv->plc_enabled) 511 return PJ_EINVALIDOP; 512 513 PJ_ASSERT_RETURN(output_buf_len >= SAMPLES_PER_FRAME * 2, 514 PJMEDIA_CODEC_EPCMTOOSHORT); 515 516 pjmedia_plc_generate(priv->plc, output->buf); 517 output->size = SAMPLES_PER_FRAME * 2; 518 519 return PJ_SUCCESS; 520 } 467 521 468 522 #endif /* PJMEDIA_HAS_G711_CODEC */ -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r436 r438 433 433 } 434 434 435 PJ_DEF( pj_status_t) pjmedia_jbuf_put_frame(pjmedia_jbuf *jb,436 437 438 435 PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb, 436 const void *frame, 437 pj_size_t frame_size, 438 int frame_seq) 439 439 { 440 440 pj_size_t min_frame_size; … … 476 476 jb_framelist_put_at(&jb->jb_framelist,frame_seq,frame,min_frame_size); 477 477 } 478 479 return PJ_SUCCESS;480 478 } 481 479 … … 483 481 * Get frame from jitter buffer. 484 482 */ 485 PJ_DEF( pj_status_t) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,486 487 483 PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, 484 void *frame, 485 char *p_frame_type) 488 486 { 489 487 pjmedia_jb_frame_type ftype; … … 507 505 *p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME; 508 506 509 return PJ_SUCCESS;507 return; 510 508 } 511 509 … … 516 514 *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 517 515 518 return PJ_SUCCESS;516 return; 519 517 } 520 518 … … 526 524 else 527 525 *p_frame_type = PJMEDIA_JB_MISSING_FRAME; 528 529 530 return PJ_SUCCESS;531 526 } 532 527 -
pjproject/trunk/pjmedia/src/pjmedia/plc_common.c
r417 r438 27 27 static void plc_replay_save(void*, pj_int16_t*); 28 28 static void plc_replay_generate(void*, pj_int16_t*); 29 30 static void* noplc_create(pj_pool_t*, unsigned c, unsigned f);31 static void noplc_save(void*, pj_int16_t*);32 static void noplc_generate(void*, pj_int16_t*);33 29 34 30 extern void* pjmedia_plc_g711_create(pj_pool_t*, unsigned c, unsigned f); … … 63 59 &plc_replay_save, 64 60 &plc_replay_generate 65 };66 67 68 static struct plc_alg no_plc =69 {70 &noplc_create,71 &noplc_save,72 &noplc_generate73 61 }; 74 62 … … 202 190 203 191 204 //////////////////////////////////////////////////////////////////////////////205 /*206 * No PLC207 */208 static void* noplc_create(pj_pool_t *pool, unsigned clock_rate,209 unsigned samples_per_sec)210 {211 PJ_UNUSED_ARG(pool);212 PJ_UNUSED_ARG(clock_rate);213 return (void*) samples_per_sec;214 }215 216 static void noplc_save(void *plc, pj_int16_t *frame)217 {218 PJ_UNUSED_ARG(plc);219 PJ_UNUSED_ARG(frame);220 }221 222 static void noplc_generate(void *plc, pj_int16_t *frame)223 {224 unsigned samples_per_sec = (unsigned)plc;225 pj_memset(frame, 0, samples_per_sec);226 }227 -
pjproject/trunk/pjmedia/src/pjmedia/session.c
r435 r438 65 65 pj_pool_t *pool, 66 66 pjmedia_endpt *endpt, 67 const pjmedia_sock_info *skinfo, 67 68 const pjmedia_sdp_session *local, 68 69 const pjmedia_sdp_session *remote, 69 70 unsigned stream_idx) 70 71 { 72 pjmedia_codec_mgr *mgr; 71 73 const pjmedia_sdp_attr *attr; 72 74 const pjmedia_sdp_media *local_m; … … 86 88 87 89 90 /* Get codec manager. */ 91 mgr = pjmedia_endpt_get_codec_mgr(endpt); 92 93 /* Keep SDP shortcuts */ 88 94 local_m = local->media[stream_idx]; 89 95 rem_m = remote->media[stream_idx]; … … 216 222 } 217 223 218 } else { 219 pjmedia_codec_mgr *mgr; 220 pjmedia_codec_info *p_info; 221 222 mgr = pjmedia_endpt_get_codec_mgr(endpt); 224 } else { 225 const pjmedia_codec_info *p_info; 223 226 224 227 status = pjmedia_codec_mgr_get_codec_info( mgr, pt, &p_info); … … 302 305 303 306 307 /* Now that we have codec info, get the codec param. */ 308 si->param = pj_pool_alloc(pool, sizeof(*si->param)); 309 status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt, si->param); 310 if (status != PJ_SUCCESS) 311 return status; 304 312 305 313 /* Get incomming payload type for telephone-events */ … … 335 343 } 336 344 345 /* Copy skinfo */ 346 if (skinfo) 347 si->sock_info = *skinfo; 337 348 338 349 /* Leave SSRC to random. */ 339 350 si->ssrc = pj_rand(); 340 351 341 /* Leave jitter buffer parameter. */ 342 352 /* Set default jitter buffer parameter. */ 353 si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1; 354 355 return PJ_SUCCESS; 356 } 357 358 359 /* 360 * Initialize session info from SDP session descriptors. 361 */ 362 PJ_DEF(pj_status_t) 363 pjmedia_session_info_from_sdp( pj_pool_t *pool, 364 pjmedia_endpt *endpt, 365 unsigned max_streams, 366 pjmedia_session_info *si, 367 const pjmedia_sock_info skinfo[], 368 const pjmedia_sdp_session *local, 369 const pjmedia_sdp_session *remote) 370 { 371 unsigned i; 372 373 PJ_ASSERT_RETURN(pool && endpt && si && local && remote, PJ_EINVAL); 374 375 si->stream_cnt = max_streams; 376 if (si->stream_cnt > local->media_count) 377 si->stream_cnt = local->media_count; 378 379 for (i=0; i<si->stream_cnt; ++i) { 380 pj_status_t status; 381 382 status = pjmedia_stream_info_from_sdp( &si->stream_info[i], pool, 383 endpt, 384 (skinfo ? &skinfo[i] : NULL), 385 local, remote, i); 386 if (status != PJ_SUCCESS) 387 return status; 388 389 } 390 343 391 return PJ_SUCCESS; 344 392 } … … 349 397 */ 350 398 PJ_DEF(pj_status_t) pjmedia_session_create( pjmedia_endpt *endpt, 351 unsigned stream_cnt, 352 const pjmedia_sock_info skinfo[], 353 const pjmedia_sdp_session *local_sdp, 354 const pjmedia_sdp_session *rem_sdp, 399 const pjmedia_session_info *si, 355 400 void *user_data, 356 401 pjmedia_session **p_session ) … … 362 407 363 408 /* Verify arguments. */ 364 PJ_ASSERT_RETURN(endpt && stream_cnt && skinfo && 365 local_sdp && rem_sdp && p_session, PJ_EINVAL); 409 PJ_ASSERT_RETURN(endpt && si && p_session, PJ_EINVAL); 366 410 367 411 /* Create pool for the session. */ … … 374 418 session->pool = pool; 375 419 session->endpt = endpt; 376 session->stream_cnt = s tream_cnt;420 session->stream_cnt = si->stream_cnt; 377 421 session->user_data = user_data; 378 379 /* Stream count is the lower number of stream_cnt or SDP m= lines count */ 380 if (stream_cnt < local_sdp->media_count) 381 stream_cnt = local_sdp->media_count; 382 383 /* 384 * Create streams: 385 */ 386 for (i=0; i<(int)stream_cnt; ++i) { 387 388 pjmedia_stream_info *si = &session->stream_info[i]; 389 390 /* Build stream info based on media line in local SDP */ 391 status = pjmedia_stream_info_from_sdp(si, session->pool, endpt, 392 local_sdp, rem_sdp, i); 393 if (status != PJ_SUCCESS) 394 return status; 395 396 /* Assign sockinfo */ 397 si->sock_info = skinfo[i]; 398 } 422 423 /* Copy stream info (this simple memcpy may break sometime) */ 424 pj_memcpy(session->stream_info, si->stream_info, 425 si->stream_cnt * sizeof(pjmedia_session_info)); 399 426 400 427 /* 401 428 * Now create and start the stream! 402 429 */ 403 for (i=0; i<(int)stream_cnt; ++i) { 404 430 for (i=0; i<(int)si->stream_cnt; ++i) { 431 432 /* Create the stream */ 405 433 status = pjmedia_stream_create(endpt, session->pool, 406 434 &session->stream_info[i], -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r435 r438 54 54 unsigned out_pkt_size; /**< Size of output buffer. */ 55 55 void *out_pkt; /**< Output buffer. */ 56 unsigned pcm_buf_size; /**< Size of PCM buffer. */57 void *pcm_buf; /**< PCM buffer. */58 56 pjmedia_rtp_session rtp; /**< RTP session. */ 59 57 }; … … 86 84 87 85 pjmedia_codec *codec; /**< Codec instance being used. */ 88 pj_size_t frame_size; /**< Size of encoded frame. */ 86 pjmedia_codec_param codec_param; /**< Codec param. */ 87 unsigned frame_size; /**< Size of encoded base frame.*/ 89 88 pj_mutex_t *jb_mutex; 90 89 pjmedia_jbuf *jb; /**< Jitter buffer. */ … … 155 154 pjmedia_channel *channel = stream->dec; 156 155 157 char frame_type;158 156 pj_status_t status; 159 struct pjmedia_frame frame_in, frame_out; 157 unsigned samples_count, samples_per_frame, samples_required; 158 pj_int16_t *p_out_samp; 160 159 161 160 /* Return no frame is channel is paused */ … … 165 164 } 166 165 167 /* Lock jitter buffer mutex */ 166 /* Repeat get frame from the jitter buffer and decode the frame 167 * until we have enough frames according to codec's ptime. 168 */ 169 170 /* Lock jitter buffer mutex first */ 168 171 pj_mutex_lock( stream->jb_mutex ); 169 172 170 /* Get frame from jitter buffer. */ 171 status = pjmedia_jbuf_get_frame(stream->jb, channel->out_pkt, 172 &frame_type); 173 samples_required = stream->port.info.samples_per_frame; 174 samples_per_frame = stream->codec_param.info.frm_ptime * 175 stream->codec_param.info.clock_rate * 176 stream->codec_param.info.channel_cnt / 177 1000; 178 p_out_samp = frame->buf; 179 180 for (samples_count=0; samples_count < samples_required; 181 samples_count += samples_per_frame) 182 { 183 char frame_type; 184 185 /* Get frame from jitter buffer. */ 186 pjmedia_jbuf_get_frame(stream->jb, channel->out_pkt, &frame_type); 187 188 if (frame_type == PJMEDIA_JB_MISSING_FRAME) { 189 190 /* Activate PLC */ 191 if (stream->codec->op->recover && 192 stream->codec_param.setting.plc) 193 { 194 pjmedia_frame frame_out; 195 196 frame_out.buf = p_out_samp + samples_count; 197 frame_out.size = frame->size - samples_count*2; 198 status = (*stream->codec->op->recover)(stream->codec, 199 frame_out.size, 200 &frame_out); 201 } else { 202 status = -1; 203 } 204 205 if (status != PJ_SUCCESS) { 206 /* Either PLC failed or PLC not supported/enabled */ 207 pjmedia_zero_samples(p_out_samp + samples_count, 208 samples_required - samples_count); 209 } 210 211 } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 212 213 /* Jitter buffer is empty, zero the remaining samples and break 214 * the loop. 215 */ 216 pjmedia_zero_samples(p_out_samp + samples_count, 217 samples_required - samples_count); 218 break; 219 220 } else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) { 221 222 /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */ 223 pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME); 224 225 /* Zero frame returned. We should zero the PCM buffer then.. */ 226 pjmedia_zero_samples(p_out_samp + samples_count, 227 samples_per_frame); 228 229 } else { 230 /* Got "NORMAL" frame from jitter buffer */ 231 pjmedia_frame frame_in, frame_out; 232 233 /* Decode */ 234 frame_in.buf = channel->out_pkt; 235 frame_in.size = stream->frame_size; 236 frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO; /* ignored */ 237 238 frame_out.buf = p_out_samp + samples_count; 239 frame_out.size = frame->size - samples_count*2; 240 status = stream->codec->op->decode( stream->codec, &frame_in, 241 frame_out.size, &frame_out); 242 if (status != 0) { 243 LOGERR_((port->info.name.ptr, "codec decode() error", 244 status)); 245 246 pjmedia_zero_samples(p_out_samp + samples_count, 247 samples_per_frame); 248 } 249 } 250 } 251 173 252 174 253 /* Unlock jitter buffer mutex. */ 175 254 pj_mutex_unlock( stream->jb_mutex ); 176 255 177 if (status != PJ_SUCCESS || frame_type != PJMEDIA_JB_NORMAL_FRAME) { 256 /* Return PJMEDIA_FRAME_TYPE_NONE if we have no frames at all 257 * (it can happen when jitter buffer returns PJMEDIA_JB_ZERO_EMPTY_FRAME). 258 */ 259 if (samples_count == 0) { 178 260 frame->type = PJMEDIA_FRAME_TYPE_NONE; 179 return PJ_SUCCESS; 180 } 181 182 /* Decode */ 183 frame_in.buf = channel->out_pkt; 184 frame_in.size = stream->frame_size; 185 frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO; /* ignored */ 186 frame_out.buf = channel->pcm_buf; 187 status = stream->codec->op->decode( stream->codec, &frame_in, 188 channel->pcm_buf_size, &frame_out); 189 if (status != 0) { 190 LOGERR_((port->info.name.ptr, "codec decode() error", status)); 191 192 frame->type = PJMEDIA_FRAME_TYPE_NONE; 193 return PJ_SUCCESS; 194 } 195 196 /* Put in sound buffer. */ 197 if (frame_out.size > frame->size) { 198 PJ_LOG(4,(port->info.name.ptr, 199 "Sound playout buffer truncated %d bytes", 200 frame_out.size - frame->size)); 201 frame_out.size = frame->size; 202 } 203 204 frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 205 frame->size = frame_out.size; 206 frame->timestamp.u64 = 0; 207 pj_memcpy(frame->buf, frame_out.buf, frame_out.size); 261 frame->size = 0; 262 } else { 263 frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 264 frame->size = samples_count * 2; 265 frame->timestamp.u64 = 0; 266 } 208 267 209 268 return PJ_SUCCESS; … … 319 378 pj_status_t status = 0; 320 379 struct pjmedia_frame frame_out; 321 intts_len;380 unsigned ts_len; 322 381 pj_bool_t has_tx; 323 382 void *rtphdr; … … 356 415 357 416 } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE) { 358 unsigned max_size;417 unsigned ts, samples_per_frame; 359 418 360 419 has_tx = PJ_TRUE; 361 max_size = channel->out_pkt_size - sizeof(pjmedia_rtp_hdr); 362 status = stream->codec->op->encode( stream->codec, frame, 363 max_size, 364 &frame_out); 365 if (status != 0) { 366 LOGERR_((stream->port.info.name.ptr, 367 "Codec encode() error", status)); 368 return status; 420 421 /* Repeatedly call encode if there are multiple frames to be 422 * sent. 423 */ 424 samples_per_frame = stream->codec_param.info.frm_ptime * 425 stream->codec_param.info.clock_rate * 426 stream->codec_param.info.channel_cnt / 427 1000; 428 429 for (ts=0; ts<ts_len; ts += samples_per_frame) { 430 pjmedia_frame tmp_frame; 431 unsigned max_size; 432 433 tmp_frame.buf = ((char*)frame_out.buf) + frame_out.size; 434 435 max_size = channel->out_pkt_size - sizeof(pjmedia_rtp_hdr) - 436 frame_out.size; 437 438 status = stream->codec->op->encode( stream->codec, frame, 439 max_size, 440 &tmp_frame); 441 if (status != PJ_SUCCESS) { 442 LOGERR_((stream->port.info.name.ptr, 443 "Codec encode() error", status)); 444 return status; 445 } 446 447 frame_out.size += tmp_frame.size; 369 448 } 370 449 … … 626 705 627 706 } else { 628 unsigned ext_seq; 629 ext_seq = channel->rtp.seq_ctrl.cycles | pj_ntohs(hdr->seq); 630 status = pjmedia_jbuf_put_frame(stream->jb, payload, payloadlen, 631 ext_seq); 707 /* 708 * Packets may contain more than one frames, while the jitter 709 * buffer can only take one frame per "put" operation. So we need 710 * to ask the codec to "parse" the payload into multiple frames. 711 */ 712 enum { MAX = 16 }; 713 pj_timestamp ts; 714 unsigned i, count; 715 pjmedia_frame frames[MAX]; 716 717 /* Get the timestamp of the first sample */ 718 ts.u64 = pj_ntohl(hdr->ts); 719 720 /* Parse the payload. */ 721 status = (*stream->codec->op->parse)(stream->codec, 722 (void*)payload, 723 payloadlen, 724 &ts, 725 &count, 726 frames); 727 if (status != PJ_SUCCESS) { 728 LOGERR_((stream->port.info.name.ptr, 729 "Codec parse() error", 730 status)); 731 count = 0; 732 } 733 734 /* Put each frame to jitter buffer. */ 735 for (i=0; i<count; ++i) { 736 unsigned ext_seq; 737 738 ext_seq = (unsigned)(frames[i].timestamp.u64 / 739 stream->port.info.samples_per_frame); 740 pjmedia_jbuf_put_frame(stream->jb, frames[i].buf, 741 frames[i].size, ext_seq); 742 743 } 632 744 } 633 745 pj_mutex_unlock( stream->jb_mutex ); … … 728 840 unsigned pt, 729 841 const pjmedia_stream_info *param, 730 const pjmedia_codec_param *codec_param,731 842 pjmedia_channel **p_channel) 732 843 { … … 756 867 757 868 channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) + 758 codec_param->avg_bps/8 *869 stream->codec_param.info.avg_bps/8 * 759 870 PJMEDIA_MAX_FRAME_DURATION_MS / 760 871 1000; … … 766 877 PJ_ASSERT_RETURN(channel->out_pkt != NULL, PJ_ENOMEM); 767 878 768 769 /* Allocate buffer for decoding to PCM: */770 771 channel->pcm_buf_size = codec_param->clock_rate *772 codec_param->channel_cnt *773 codec_param->pcm_bits_per_sample / 8 *774 PJMEDIA_MAX_FRAME_DURATION_MS / 1000;775 channel->pcm_buf = pj_pool_alloc (pool, channel->pcm_buf_size);776 PJ_ASSERT_RETURN(channel->pcm_buf != NULL, PJ_ENOMEM);777 879 778 880 … … 800 902 { 801 903 pjmedia_stream *stream; 802 pjmedia_codec_param codec_param;803 904 pj_ioqueue_callback ioqueue_cb; 804 905 pj_uint16_t rtcp_port; 805 unsigned jb uf_init, jbuf_max;906 unsigned jb_init, jb_max, jb_min_pre, jb_max_pre; 806 907 pj_status_t status; 807 908 … … 867 968 868 969 869 /* Get default codec param: */ 870 871 //status = stream->codec->op->default_attr(stream->codec, &codec_param); 872 status = pjmedia_codec_mgr_get_default_param( stream->codec_mgr, 873 &info->fmt, &codec_param); 970 /* Get codec param: */ 971 if (info->param) 972 stream->codec_param = *info->param; 973 else { 974 status = pjmedia_codec_mgr_get_default_param(stream->codec_mgr, 975 &info->fmt, 976 &stream->codec_param); 977 if (status != PJ_SUCCESS) 978 goto err_cleanup; 979 } 980 981 /* Check for invalid frame per packet. */ 982 if (stream->codec_param.setting.frm_per_pkt < 1) 983 stream->codec_param.setting.frm_per_pkt = 1; 984 985 /* Set additional info. */ 986 stream->port.info.bits_per_sample = 16; 987 stream->port.info.samples_per_frame = info->fmt.clock_rate * 988 stream->codec_param.info.frm_ptime * 989 stream->codec_param.setting.frm_per_pkt / 990 1000; 991 stream->port.info.bytes_per_frame = stream->codec_param.info.avg_bps/8 * 992 stream->codec_param.info.frm_ptime * 993 stream->codec_param.setting.frm_per_pkt / 994 1000; 995 996 997 /* Open the codec: */ 998 999 status = stream->codec->op->open(stream->codec, &stream->codec_param); 874 1000 if (status != PJ_SUCCESS) 875 1001 goto err_cleanup; 876 1002 877 /* Set additional info. */878 stream->port.info.bits_per_sample = 16;879 stream->port.info.samples_per_frame = info->fmt.clock_rate*codec_param.ptime/1000;880 stream->port.info.bytes_per_frame = codec_param.avg_bps/8 * codec_param.ptime/1000;881 882 883 /* Open the codec: */884 885 status = stream->codec->op->open(stream->codec, &codec_param);886 if (status != PJ_SUCCESS)887 goto err_cleanup;888 889 1003 890 1004 /* Get the frame size: */ 891 1005 892 stream->frame_size = ( codec_param.avg_bps / 8) * codec_param.ptime / 1000;893 1006 stream->frame_size = (stream->codec_param.info.avg_bps / 8) * 1007 stream->codec_param.info.frm_ptime / 1000; 894 1008 895 1009 /* Init RTCP session: */ … … 901 1015 902 1016 903 /* Create jitter buffer: */904 if (info->jb_ init)905 jb uf_init = info->jb_init;1017 /* Init jitter buffer parameters: */ 1018 if (info->jb_max > 0) 1019 jb_max = info->jb_max; 906 1020 else 907 jb uf_init = 60 / (stream->port.info.samples_per_frame * 1000 /908 info->fmt.clock_rate);909 910 if (info->jb_m ax)911 jb uf_max = info->jb_max;1021 jb_max = 240 / (stream->port.info.samples_per_frame * 1000 / 1022 info->fmt.clock_rate); 1023 1024 if (info->jb_min_pre >= 0) 1025 jb_min_pre = info->jb_min_pre; 912 1026 else 913 jbuf_max = 240 / (stream->port.info.samples_per_frame * 1000 / 914 info->fmt.clock_rate); 1027 jb_min_pre = 0; 1028 1029 if (info->jb_max_pre > 0) 1030 jb_max_pre = info->jb_max_pre; 1031 else 1032 jb_max_pre = jb_max * 4 / 5; 1033 1034 if (info->jb_init >= 0) 1035 jb_init = info->jb_init; 1036 else 1037 jb_init = jb_min_pre; 1038 1039 1040 /* Create jitter buffer */ 915 1041 status = pjmedia_jbuf_create(pool, &stream->port.info.name, 916 1042 stream->frame_size, 917 jb uf_max, &stream->jb);1043 jb_max, &stream->jb); 918 1044 if (status != PJ_SUCCESS) 919 1045 goto err_cleanup; 920 1046 921 /* Set jitter buffer to adaptive */ 922 pjmedia_jbuf_set_adaptive( stream->jb, jbuf_init, 1, jbuf_max * 4 / 5); 1047 1048 /* Set up jitter buffer */ 1049 pjmedia_jbuf_set_adaptive( stream->jb, jb_init, jb_min_pre, jb_max_pre); 923 1050 924 1051 /* Create decoder channel: */ 925 1052 926 1053 status = create_channel( pool, stream, PJMEDIA_DIR_DECODING, 927 info->fmt.pt, info, & codec_param, &stream->dec);1054 info->fmt.pt, info, &stream->dec); 928 1055 if (status != PJ_SUCCESS) 929 1056 goto err_cleanup; … … 933 1060 934 1061 status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING, 935 info->tx_pt, info, & codec_param, &stream->enc);1062 info->tx_pt, info, &stream->enc); 936 1063 if (status != PJ_SUCCESS) 937 1064 goto err_cleanup; -
pjproject/trunk/pjsip-apps/build/Samples.mak
r408 r438 2 2 include ../../build/common.mak 3 3 4 PJLIB_LIB:=../../pjlib/lib/libpj-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)5 PJLIB_UTIL_LIB:=../../pjlib-util/lib/libpjlib-util-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)6 PJMEDIA_LIB:=../../pjmedia/lib/libpjmedia-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)7 PJMEDIA_CODEC_LIB:=../../pjmedia/lib/libpjmedia-codec-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)8 PJSIP_LIB:=../../pjsip/lib/libpjsip-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)9 PJSIP_UA_LIB:=../../pjsip/lib/libpjsip-ua-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)10 PJSIP_SIMPLE_LIB:=../../pjsip/lib/libpjsip-simple-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)11 PJSUA_LIB_LIB=../../pjsip/lib/libpjsua-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(LIBEXT)4 PJLIB_LIB:=../../pjlib/lib/libpj-$(TARGET)$(LIBEXT) 5 PJLIB_UTIL_LIB:=../../pjlib-util/lib/libpjlib-util-$(TARGET)$(LIBEXT) 6 PJMEDIA_LIB:=../../pjmedia/lib/libpjmedia-$(TARGET)$(LIBEXT) 7 PJMEDIA_CODEC_LIB:=../../pjmedia/lib/libpjmedia-codec-$(TARGET)$(LIBEXT) 8 PJSIP_LIB:=../../pjsip/lib/libpjsip-$(TARGET)$(LIBEXT) 9 PJSIP_UA_LIB:=../../pjsip/lib/libpjsip-ua-$(TARGET)$(LIBEXT) 10 PJSIP_SIMPLE_LIB:=../../pjsip/lib/libpjsip-simple-$(TARGET)$(LIBEXT) 11 PJSUA_LIB_LIB=../../pjsip/lib/libpjsua-$(TARGET)$(LIBEXT) 12 12 13 13 … … 36 36 37 37 SRCDIR := ../src/samples 38 OBJDIR := ./output/samples-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)38 OBJDIR := ./output/samples-$(TARGET) 39 39 BINDIR := ../bin/samples 40 40 … … 42 42 siprtp streamutil 43 43 44 EXES := $(foreach file, $(SAMPLES), $(BINDIR)/$(file)-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(HOST_EXE))44 EXES := $(foreach file, $(SAMPLES), $(BINDIR)/$(file)-$(TARGET)$(HOST_EXE)) 45 45 46 46 all: $(OBJDIR) $(EXES) 47 47 48 $(BINDIR)/%-$( MACHINE_NAME)-$(OS_NAME)-$(CC_NAME)$(HOST_EXE): $(OBJDIR)/%$(OBJEXT) $(LIBS)48 $(BINDIR)/%-$(TARGET)$(HOST_EXE): $(OBJDIR)/%$(OBJEXT) $(LIBS) 49 49 $(LD) $(LDOUT)$(subst /,$(HOST_PSEP),$@) \ 50 50 $(subst /,$(HOST_PSEP),$<) \ -
pjproject/trunk/pjsip-apps/src/samples/debug.c
r408 r438 28 28 * #include "playfile.c" 29 29 */ 30 #include "s treamutil.c"30 #include "sndinfo.c" 31 31 -
pjproject/trunk/pjsip-apps/src/samples/playfile.c
r412 r438 77 77 78 78 79 PJ_UNUSED_ARG(argc); 79 if (argc != 2) { 80 puts("Error: filename required"); 81 puts(desc); 82 return 1; 83 } 80 84 81 85 -
pjproject/trunk/pjsip-apps/src/samples/simpleua.c
r412 r438 586 586 pj_status_t status) 587 587 { 588 pjmedia_session_info sess_info; 588 589 const pjmedia_sdp_session *local_sdp; 589 590 const pjmedia_sdp_session *remote_sdp; … … 608 609 609 610 611 /* Create session info based on the two SDPs. 612 * We only support one stream per session for now. 613 */ 614 status = pjmedia_session_info_from_sdp(inv->dlg->pool, g_med_endpt, 1, 615 &sess_info, &g_med_skinfo, 616 local_sdp, remote_sdp); 617 if (status != PJ_SUCCESS) { 618 app_perror( THIS_FILE, "Unable to create media session", status); 619 return; 620 } 621 622 /* If required, we can also change some settings in the session info, 623 * (such as jitter buffer settings, codec settings, etc) before we 624 * create the session. 625 */ 626 610 627 /* Create new media session, passing the two SDPs, and also the 611 628 * media socket that we created earlier. 612 629 * The media session is active immediately. 613 630 */ 614 status = pjmedia_session_create( g_med_endpt, 1, 615 &g_med_skinfo, 616 local_sdp, remote_sdp, 631 status = pjmedia_session_create( g_med_endpt, &sess_info, 617 632 NULL, &g_med_session ); 618 633 if (status != PJ_SUCCESS) { -
pjproject/trunk/pjsip-apps/src/samples/siprtp.c
r437 r438 1169 1169 strm->bytes_per_frame, 1170 1170 strm->samples_per_frame, 1171 &hdr, &hdrlen);1171 (const void**)&hdr, &hdrlen); 1172 1172 if (status == PJ_SUCCESS) { 1173 1173 … … 1267 1267 1268 1268 status = pjmedia_stream_info_from_sdp(&audio->si, inv->pool, app.med_endpt, 1269 local_sdp, remote_sdp, 0);1269 NULL, local_sdp, remote_sdp, 0); 1270 1270 if (status != PJ_SUCCESS) { 1271 1271 app_perror(THIS_FILE, "Error creating stream info from SDP", status); -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r422 r438 196 196 int complexity; /**< Codec complexity. */ 197 197 int quality; /**< Codec quality. */ 198 int ptime; /**< Codec ptime in msec. */ 198 199 199 200 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r422 r438 27 27 */ 28 28 29 #define THIS_FILE "pjsua_ inv.c"29 #define THIS_FILE "pjsua_call.c" 30 30 31 31 … … 154 154 call->session = NULL; 155 155 156 } 157 158 PJ_LOG(3,(THIS_FILE, "Media session for call %d is destroyed", 159 call_index)); 156 PJ_LOG(3,(THIS_FILE, "Media session for call %d is destroyed", 157 call_index)); 158 159 } 160 160 161 161 return PJ_SUCCESS; … … 524 524 pj_gettimeofday(&call->dis_time); 525 525 break; 526 default: 527 /* Nothing to do. Just to keep gcc from complaining about 528 * unused enums. 529 */ 530 break; 526 531 } 527 532 … … 557 562 st_code = e->body.tsx_state.tsx->status_code; 558 563 ev_state = PJSIP_EVSUB_STATE_TERMINATED; 564 break; 565 566 default: 567 /* Nothing to do. Just to keep gcc from complaining about 568 * unused enums. 569 */ 559 570 break; 560 571 } … … 916 927 } 917 928 929 #if 0 918 930 /* Disconnect call */ 919 931 static void call_disconnect(pjsip_inv_session *inv, … … 931 943 } 932 944 } 945 #endif 933 946 934 947 /* … … 941 954 { 942 955 pjsua_call *call; 956 pjmedia_session_info sess_info; 943 957 const pjmedia_sdp_session *local_sdp; 944 958 const pjmedia_sdp_session *remote_sdp; … … 991 1005 } 992 1006 993 /* Create new media session.994 * The media session is active immediately.995 */996 1007 if (pjsua.null_audio) 997 1008 return; 998 999 status = pjmedia_session_create( pjsua.med_endpt, 1, 1000 &call->skinfo, 1001 local_sdp, remote_sdp, 1002 call, 1003 &call->session ); 1009 1010 /* Create media session info based on SDP parameters. 1011 * We only support one stream per session at the moment 1012 */ 1013 status = pjmedia_session_info_from_sdp( call->inv->dlg->pool, 1014 pjsua.med_endpt, 1, 1015 &sess_info, &call->skinfo, 1016 local_sdp, remote_sdp); 1017 if (status != PJ_SUCCESS) { 1018 pjsua_perror(THIS_FILE, "Unable to create media session", 1019 status); 1020 //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); 1021 return; 1022 } 1023 1024 /* Override ptime, if this option is specified. */ 1025 if (pjsua.ptime) { 1026 sess_info.stream_info[0].param->setting.frm_per_pkt = (pj_uint8_t) 1027 (pjsua.ptime / sess_info.stream_info[0].param->info.frm_ptime); 1028 if (sess_info.stream_info[0].param->setting.frm_per_pkt==0) 1029 sess_info.stream_info[0].param->setting.frm_per_pkt = 1; 1030 } 1031 1032 /* Optionally, application may modify other stream settings here 1033 * (such as jitter buffer parameters, codec ptime, etc.) 1034 */ 1035 1036 /* Create session based on session info. */ 1037 status = pjmedia_session_create( pjsua.med_endpt, &sess_info, 1038 call, &call->session ); 1004 1039 if (status != PJ_SUCCESS) { 1005 1040 pjsua_perror(THIS_FILE, "Unable to create media session", -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c
r422 r438 95 95 puts (" --complexity=N Specify encoding complexity (0-10, default=none(-1))"); 96 96 puts (" --quality=N Specify encoding quality (0-10, default=4)"); 97 puts (" --ptime=MSEC Override codec ptime to MSEC (default=specific)"); 97 98 puts (""); 98 99 puts ("Buddy List (can be more than one):"); … … 228 229 OPT_AUTO_CONF, OPT_CLOCK_RATE, 229 230 OPT_PLAY_FILE, OPT_RTP_PORT, OPT_ADD_CODEC, 230 OPT_COMPLEXITY, OPT_QUALITY, 231 OPT_COMPLEXITY, OPT_QUALITY, OPT_PTIME, 231 232 OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS, OPT_UAS_REFRESH, 232 233 OPT_UAS_DURATION, … … 267 268 { "complexity", 1, 0, OPT_COMPLEXITY}, 268 269 { "quality", 1, 0, OPT_QUALITY}, 270 { "ptime", 1, 0, OPT_PTIME}, 269 271 { "next-account",0,0, OPT_NEXT_ACCOUNT}, 270 272 { "next-cred", 0, 0, OPT_NEXT_CRED}, … … 556 558 PJ_LOG(1,(THIS_FILE, 557 559 "Error: invalid --quality (expecting 0-10")); 560 return -1; 561 } 562 break; 563 564 case OPT_PTIME: 565 pjsua.ptime = my_atoi(pj_optarg); 566 if (pjsua.ptime < 10 || pjsua.ptime > 1000) { 567 PJ_LOG(1,(THIS_FILE, 568 "Error: invalid --ptime option")); 558 569 return -1; 559 570 } … … 772 783 773 784 PJ_LOG(3,(THIS_FILE, 774 " TX pt=%d, stat last update: %s\n"785 " TX pt=%d, ptime=%dms, stat last update: %s\n" 775 786 " total %spkt %sB (%sB +IP hdr)%s\n" 776 787 " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n" … … 779 790 " jitter : %7.3f %7.3f %7.3f %7.3f%s", 780 791 info.stream_info[i].tx_pt, 792 info.stream_info[i].param->info.frm_ptime * 793 info.stream_info[i].param->setting.frm_per_pkt, 781 794 last_update, 782 795 good_number(packets, stat.tx.pkt), … … 970 983 char line[128]; 971 984 985 PJ_UNUSED_ARG(max); 986 972 987 cfg.ptr = buf; 973 988 cfg.slen = 0; … … 1097 1112 pj_strcat2(&cfg, line); 1098 1113 1114 /* ptime */ 1115 if (pjsua.ptime) { 1116 pj_ansi_sprintf(line, "--ptime %d\n", 1117 pjsua.ptime); 1118 pj_strcat2(&cfg, line); 1119 } 1120 1099 1121 /* Start RTP port. */ 1100 1122 pj_ansi_sprintf(line, "--rtp-port %d\n",
Note: See TracChangeset
for help on using the changeset viewer.