- Timestamp:
- Jul 12, 2011 11:08:32 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c
r3609 r3629 1836 1836 1837 1837 1838 void stop_video_stream(pjsua_call_media *call_med); 1839 1838 1840 static void stop_media_session(pjsua_call_id call_id) 1839 1841 { … … 1881 1883 #if PJMEDIA_HAS_VIDEO 1882 1884 else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 1883 pjmedia_vid_stream *strm = call_med->strm.v.stream; 1884 1885 if (strm) { 1886 pjmedia_rtcp_stat stat; 1887 1888 if (call_med->strm.v.capturer) { 1889 pjmedia_vid_port_stop(call_med->strm.v.capturer); 1890 pjmedia_vid_port_destroy(call_med->strm.v.capturer); 1891 call_med->strm.v.capturer = NULL; 1892 } 1893 1894 if (call_med->strm.v.renderer) { 1895 pjmedia_vid_port_stop(call_med->strm.v.renderer); 1896 pjmedia_vid_port_destroy(call_med->strm.v.renderer); 1897 call_med->strm.v.renderer = NULL; 1898 } 1899 1900 if ((call_med->dir & PJMEDIA_DIR_ENCODING) && 1901 (pjmedia_vid_stream_get_stat(strm, &stat) == PJ_SUCCESS)) 1902 { 1903 /* Save RTP timestamp & sequence, so when media session is 1904 * restarted, those values will be restored as the initial 1905 * RTP timestamp & sequence of the new media session. So in 1906 * the same call session, RTP timestamp and sequence are 1907 * guaranteed to be contigue. 1908 */ 1909 call_med->rtp_tx_seq_ts_set = 1 | (1 << 1); 1910 call_med->rtp_tx_seq = stat.rtp_tx_last_seq; 1911 call_med->rtp_tx_ts = stat.rtp_tx_last_ts; 1912 } 1913 1914 pjmedia_vid_stream_destroy(strm); 1915 call_med->strm.v.stream = NULL; 1916 } 1885 stop_video_stream(call_med); 1917 1886 } 1918 1887 #endif … … 2183 2152 2184 2153 2185 #if PJMEDIA_HAS_VIDEO 2186 2187 static pj_status_t video_channel_update(pjsua_call_media *call_med, 2188 pj_pool_t *tmp_pool, 2189 const pjmedia_sdp_session *local_sdp, 2190 const pjmedia_sdp_session *remote_sdp) 2191 { 2192 pjsua_call *call = call_med->call; 2193 pjmedia_vid_stream_info the_si, *si = &the_si; 2194 pjmedia_port *media_port; 2195 unsigned strm_idx = call_med->idx; 2196 pj_status_t status; 2197 2198 status = pjmedia_vid_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt, 2199 local_sdp, remote_sdp, strm_idx); 2200 if (status != PJ_SUCCESS) 2201 return status; 2202 2203 /* Check if no media is active */ 2204 if (si->dir == PJMEDIA_DIR_NONE) { 2205 /* Call media state */ 2206 call_med->state = PJSUA_CALL_MEDIA_NONE; 2207 2208 /* Call media direction */ 2209 call_med->dir = PJMEDIA_DIR_NONE; 2210 2211 } else { 2212 pjmedia_transport_info tp_info; 2213 2214 /* Start/restart media transport */ 2215 status = pjmedia_transport_media_start(call_med->tp, 2216 tmp_pool, local_sdp, 2217 remote_sdp, strm_idx); 2218 if (status != PJ_SUCCESS) 2219 return status; 2220 2221 call_med->tp_st = PJSUA_MED_TP_RUNNING; 2222 2223 /* Get remote SRTP usage policy */ 2224 pjmedia_transport_info_init(&tp_info); 2225 pjmedia_transport_get_info(call_med->tp, &tp_info); 2226 if (tp_info.specific_info_cnt > 0) { 2227 unsigned i; 2228 for (i = 0; i < tp_info.specific_info_cnt; ++i) { 2229 if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP) 2230 { 2231 pjmedia_srtp_info *srtp_info = 2232 (pjmedia_srtp_info*) tp_info.spc_info[i].buffer; 2233 2234 call_med->rem_srtp_use = srtp_info->peer_use; 2235 break; 2236 } 2237 } 2238 } 2239 2240 /* Optionally, application may modify other stream settings here 2241 * (such as jitter buffer parameters, codec ptime, etc.) 2242 */ 2243 si->jb_init = pjsua_var.media_cfg.jb_init; 2244 si->jb_min_pre = pjsua_var.media_cfg.jb_min_pre; 2245 si->jb_max_pre = pjsua_var.media_cfg.jb_max_pre; 2246 si->jb_max = pjsua_var.media_cfg.jb_max; 2247 2248 /* Set SSRC */ 2249 si->ssrc = call_med->ssrc; 2250 2251 /* Set RTP timestamp & sequence, normally these value are intialized 2252 * automatically when stream session created, but for some cases (e.g: 2253 * call reinvite, call update) timestamp and sequence need to be kept 2254 * contigue. 2255 */ 2256 si->rtp_ts = call_med->rtp_tx_ts; 2257 si->rtp_seq = call_med->rtp_tx_seq; 2258 si->rtp_seq_ts_set = call_med->rtp_tx_seq_ts_set; 2259 2260 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 2261 /* Enable/disable stream keep-alive and NAT hole punch. */ 2262 si->use_ka = pjsua_var.acc[call->acc_id].cfg.use_stream_ka; 2263 #endif 2264 2265 /* Try to get shared format ID between the capture device and 2266 * the encoder to avoid format conversion in the capture device. 2267 */ 2268 if (si->dir & PJMEDIA_DIR_ENCODING) { 2269 pjmedia_vid_dev_info dev_info; 2270 pjmedia_vid_codec_info *codec_info = &si->codec_info; 2271 unsigned i, j; 2272 2273 status = pjmedia_vid_dev_get_info(pjsua_var.vcap_dev, &dev_info); 2274 if (status != PJ_SUCCESS) 2275 return status; 2276 2277 /* Find matched format ID */ 2278 for (i = 0; i < codec_info->dec_fmt_id_cnt; ++i) { 2279 for (j = 0; j < dev_info.fmt_cnt; ++j) { 2280 if (codec_info->dec_fmt_id[i] == 2281 (pjmedia_format_id)dev_info.fmt[j].id) 2282 { 2283 /* Apply the matched format ID to the codec */ 2284 si->codec_param->dec_fmt.id = codec_info->dec_fmt_id[i]; 2285 /* Force outer loop to break */ 2286 i = codec_info->dec_fmt_id_cnt; 2287 break; 2288 } 2289 } 2290 } 2291 } 2292 2293 /* Create session based on session info. */ 2294 status = pjmedia_vid_stream_create(pjsua_var.med_endpt, NULL, si, 2295 call_med->tp, NULL, 2296 &call_med->strm.v.stream); 2297 if (status != PJ_SUCCESS) 2298 return status; 2299 2300 /* Start stream */ 2301 status = pjmedia_vid_stream_start(call_med->strm.v.stream); 2302 if (status != PJ_SUCCESS) 2303 return status; 2304 2305 /* Setup decoding direction */ 2306 if (si->dir & PJMEDIA_DIR_DECODING) { 2307 pjmedia_vid_port_param vport_param; 2308 2309 status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 2310 PJMEDIA_DIR_DECODING, 2311 &media_port); 2312 if (status != PJ_SUCCESS) 2313 return status; 2314 2315 status = pjmedia_vid_dev_default_param( 2316 tmp_pool, pjsua_var.vrdr_dev, 2317 &vport_param.vidparam); 2318 if (status != PJ_SUCCESS) 2319 return status; 2320 2321 pjmedia_format_copy(&vport_param.vidparam.fmt, 2322 &media_port->info.fmt); 2323 2324 vport_param.vidparam.dir = PJMEDIA_DIR_RENDER; 2325 vport_param.active = PJ_TRUE; 2326 2327 /* Create video renderer */ 2328 status = pjmedia_vid_port_create(tmp_pool, &vport_param, 2329 &call_med->strm.v.renderer); 2330 if (status != PJ_SUCCESS) 2331 return status; 2332 2333 /* Connect the video renderer to media_port */ 2334 status = pjmedia_vid_port_connect(call_med->strm.v.renderer, 2335 media_port, PJ_FALSE); 2336 if (status != PJ_SUCCESS) 2337 return status; 2338 2339 /* Start the video renderer */ 2340 status = pjmedia_vid_port_start(call_med->strm.v.renderer); 2341 if (status != PJ_SUCCESS) 2342 return status; 2343 } 2344 2345 /* Setup encoding direction */ 2346 if (si->dir & PJMEDIA_DIR_ENCODING && !call->local_hold) { 2347 pjmedia_vid_port_param vport_param; 2348 2349 status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 2350 PJMEDIA_DIR_ENCODING, 2351 &media_port); 2352 if (status != PJ_SUCCESS) 2353 return status; 2354 2355 status = pjmedia_vid_dev_default_param( 2356 tmp_pool, pjsua_var.vcap_dev, 2357 &vport_param.vidparam); 2358 if (status != PJ_SUCCESS) 2359 return status; 2360 2361 pjmedia_format_copy(&vport_param.vidparam.fmt, 2362 &media_port->info.fmt); 2363 vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE; 2364 vport_param.active = PJ_TRUE; 2365 2366 /* Create video capturer */ 2367 status = pjmedia_vid_port_create(tmp_pool, &vport_param, 2368 &call_med->strm.v.capturer); 2369 if (status != PJ_SUCCESS) 2370 return status; 2371 2372 /* Connect the video capturer to media_port */ 2373 status = pjmedia_vid_port_connect(call_med->strm.v.capturer, 2374 media_port, PJ_FALSE); 2375 if (status != PJ_SUCCESS) 2376 return status; 2377 2378 /* Start the video capturer */ 2379 status = pjmedia_vid_port_start(call_med->strm.v.capturer); 2380 if (status != PJ_SUCCESS) 2381 return status; 2382 } 2383 2384 /* Call media direction */ 2385 call_med->dir = si->dir; 2386 2387 /* Call media state */ 2388 if (call->local_hold) 2389 call_med->state = PJSUA_CALL_MEDIA_LOCAL_HOLD; 2390 else if (call_med->dir == PJMEDIA_DIR_DECODING) 2391 call_med->state = PJSUA_CALL_MEDIA_REMOTE_HOLD; 2392 else 2393 call_med->state = PJSUA_CALL_MEDIA_ACTIVE; 2394 } 2395 2396 /* Print info. */ 2397 { 2398 char info[80]; 2399 int info_len = 0; 2400 int len; 2401 const char *dir; 2402 2403 switch (si->dir) { 2404 case PJMEDIA_DIR_NONE: 2405 dir = "inactive"; 2406 break; 2407 case PJMEDIA_DIR_ENCODING: 2408 dir = "sendonly"; 2409 break; 2410 case PJMEDIA_DIR_DECODING: 2411 dir = "recvonly"; 2412 break; 2413 case PJMEDIA_DIR_ENCODING_DECODING: 2414 dir = "sendrecv"; 2415 break; 2416 default: 2417 dir = "unknown"; 2418 break; 2419 } 2420 len = pj_ansi_sprintf( info+info_len, 2421 ", stream #%d: %.*s (%s)", strm_idx, 2422 (int)si->codec_info.encoding_name.slen, 2423 si->codec_info.encoding_name.ptr, 2424 dir); 2425 if (len > 0) 2426 info_len += len; 2427 PJ_LOG(4,(THIS_FILE,"Media updates%s", info)); 2428 } 2429 2430 return PJ_SUCCESS; 2431 } 2432 2433 #endif 2434 2154 pj_status_t video_channel_update(pjsua_call_media *call_med, 2155 pj_pool_t *tmp_pool, 2156 const pjmedia_sdp_session *local_sdp, 2157 const pjmedia_sdp_session *remote_sdp); 2435 2158 2436 2159 pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
Note: See TracChangeset
for help on using the changeset viewer.