|
Home --> Documentations --> PJSIP Reference
This is a very simple SIP User Agent application that only use PJSIP (without PJSIP-UA). It's able to make and receive call, and play media to the sound device.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00054
00055 #include <pjsip.h>
00056 #include <pjmedia.h>
00057 #include <pjmedia-codec.h>
00058 #include <pjsip_ua.h>
00059 #include <pjsip_simple.h>
00060 #include <pjlib-util.h>
00061 #include <pjlib.h>
00062
00063
00064 #define THIS_FILE "simpleua.c"
00065
00066 #include "util.h"
00067
00068
00069
00070 #define AF pj_AF_INET()
00071
00072
00073 #if 0
00074 #define SIP_PORT 5080
00075 #define RTP_PORT 5000
00076 #else
00077 #define SIP_PORT 5060
00078 #define RTP_PORT 4000
00079 #endif
00080
00081 #define MAX_MEDIA_CNT 2
00082
00083
00084
00085
00086
00087
00088 static pj_bool_t g_complete;
00089 static pjsip_endpoint *g_endpt;
00090 static pj_caching_pool cp;
00091
00092 static pjmedia_endpt *g_med_endpt;
00093
00094 static pjmedia_transport_info g_med_tpinfo[MAX_MEDIA_CNT];
00095
00096 static pjmedia_transport *g_med_transport[MAX_MEDIA_CNT];
00097
00098 static pjmedia_sock_info g_sock_info[MAX_MEDIA_CNT];
00099
00100
00101
00102 static pjsip_inv_session *g_inv;
00103 static pjmedia_stream *g_med_stream;
00104 static pjmedia_snd_port *g_snd_port;
00105
00106 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
00107 static pjmedia_vid_stream *g_med_vstream;
00108 static pjmedia_vid_port *g_vid_capturer;
00109 static pjmedia_vid_port *g_vid_renderer;
00110 #endif
00111
00112
00113
00114
00115
00116
00117 static void call_on_media_update( pjsip_inv_session *inv,
00118 pj_status_t status);
00119
00120
00121 static void call_on_state_changed( pjsip_inv_session *inv,
00122 pjsip_event *e);
00123
00124
00125 static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
00126
00127
00128 static pj_bool_t on_rx_request( pjsip_rx_data *rdata );
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 static pjsip_module mod_simpleua =
00139 {
00140 NULL, NULL,
00141 { "mod-simpleua", 12 },
00142 -1,
00143 PJSIP_MOD_PRIORITY_APPLICATION,
00144 NULL,
00145 NULL,
00146 NULL,
00147 NULL,
00148 &on_rx_request,
00149 NULL,
00150 NULL,
00151 NULL,
00152 NULL,
00153 };
00154
00155
00156
00157 static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
00158 {
00159 PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
00160 "%.*s\n"
00161 "--end msg--",
00162 rdata->msg_info.len,
00163 pjsip_rx_data_get_info(rdata),
00164 rdata->tp_info.transport->type_name,
00165 rdata->pkt_info.src_name,
00166 rdata->pkt_info.src_port,
00167 (int)rdata->msg_info.len,
00168 rdata->msg_info.msg_buf));
00169
00170
00171 return PJ_FALSE;
00172 }
00173
00174
00175 static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
00176 {
00177
00178
00179
00180
00181
00182
00183
00184 PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
00185 "%.*s\n"
00186 "--end msg--",
00187 (tdata->buf.cur - tdata->buf.start),
00188 pjsip_tx_data_get_info(tdata),
00189 tdata->tp_info.transport->type_name,
00190 tdata->tp_info.dst_name,
00191 tdata->tp_info.dst_port,
00192 (int)(tdata->buf.cur - tdata->buf.start),
00193 tdata->buf.start));
00194
00195
00196 return PJ_SUCCESS;
00197 }
00198
00199
00200 static pjsip_module msg_logger =
00201 {
00202 NULL, NULL,
00203 { "mod-msg-log", 13 },
00204 -1,
00205 PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,
00206 NULL,
00207 NULL,
00208 NULL,
00209 NULL,
00210 &logging_on_rx_msg,
00211 &logging_on_rx_msg,
00212 &logging_on_tx_msg,
00213 &logging_on_tx_msg,
00214 NULL,
00215
00216 };
00217
00218
00219
00220
00221
00222
00223
00224
00225 int main(int argc, char *argv[])
00226 {
00227 pj_pool_t *pool = NULL;
00228 pj_status_t status;
00229 unsigned i;
00230
00231
00232 status = pj_init();
00233 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00234
00235 pj_log_set_level(5);
00236
00237
00238 status = pjlib_util_init();
00239 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00240
00241
00242
00243 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
00244
00245
00246
00247 {
00248 const pj_str_t *hostname;
00249 const char *endpt_name;
00250
00251
00252
00253
00254
00255
00256 hostname = pj_gethostname();
00257 endpt_name = hostname->ptr;
00258
00259
00260
00261 status = pjsip_endpt_create(&cp.factory, endpt_name,
00262 &g_endpt);
00263 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273 {
00274 pj_sockaddr addr;
00275
00276 pj_sockaddr_init(AF, &addr, NULL, (pj_uint16_t)SIP_PORT);
00277
00278 if (AF == pj_AF_INET()) {
00279 status = pjsip_udp_transport_start( g_endpt, &addr.ipv4, NULL,
00280 1, NULL);
00281 } else if (AF == pj_AF_INET6()) {
00282 status = pjsip_udp_transport_start6(g_endpt, &addr.ipv6, NULL,
00283 1, NULL);
00284 } else {
00285 status = PJ_EAFNOTSUP;
00286 }
00287
00288 if (status != PJ_SUCCESS) {
00289 app_perror(THIS_FILE, "Unable to start UDP transport", status);
00290 return 1;
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299 status = pjsip_tsx_layer_init_module(g_endpt);
00300 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00301
00302
00303
00304
00305
00306
00307 status = pjsip_ua_init_module( g_endpt, NULL );
00308 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 {
00324 pjsip_inv_callback inv_cb;
00325
00326
00327 pj_bzero(&inv_cb, sizeof(inv_cb));
00328 inv_cb.on_state_changed = &call_on_state_changed;
00329 inv_cb.on_new_session = &call_on_forked;
00330 inv_cb.on_media_update = &call_on_media_update;
00331
00332
00333 status = pjsip_inv_usage_init(g_endpt, &inv_cb);
00334 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00335 }
00336
00337
00338 status = pjsip_100rel_init_module(g_endpt);
00339 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
00340
00341
00342
00343
00344 status = pjsip_endpt_register_module( g_endpt, &mod_simpleua);
00345 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00346
00347
00348
00349
00350 status = pjsip_endpt_register_module( g_endpt, &msg_logger);
00351 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00352
00353
00354
00355
00356
00357
00358 #if PJ_HAS_THREADS
00359 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &g_med_endpt);
00360 #else
00361 status = pjmedia_endpt_create(&cp.factory,
00362 pjsip_endpt_get_ioqueue(g_endpt),
00363 0, &g_med_endpt);
00364 #endif
00365 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00366
00367
00368
00369
00370 #if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
00371 status = pjmedia_codec_g711_init(g_med_endpt);
00372 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00373 #endif
00374
00375
00376 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
00377
00378 pool = pjmedia_endpt_create_pool(g_med_endpt, "Video subsystem", 512, 512);
00379 status = pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
00380 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00381 status = pjmedia_converter_mgr_create(pool, NULL);
00382 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00383 status = pjmedia_vid_codec_mgr_create(pool, NULL);
00384 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00385 status = pjmedia_vid_dev_subsys_init(&cp.factory);
00386 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00387
00388 # if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
00389
00390 status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
00391 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00392 # endif
00393
00394 #endif
00395
00396
00397
00398
00399
00400
00401 for (i = 0; i < PJ_ARRAY_SIZE(g_med_transport); ++i) {
00402 status = pjmedia_transport_udp_create3(g_med_endpt, AF, NULL, NULL,
00403 RTP_PORT + i*2, 0,
00404 &g_med_transport[i]);
00405 if (status != PJ_SUCCESS) {
00406 app_perror(THIS_FILE, "Unable to create media transport", status);
00407 return 1;
00408 }
00409
00410
00411
00412
00413
00414
00415 pjmedia_transport_info_init(&g_med_tpinfo[i]);
00416 pjmedia_transport_get_info(g_med_transport[i], &g_med_tpinfo[i]);
00417
00418 pj_memcpy(&g_sock_info[i], &g_med_tpinfo[i].sock_info,
00419 sizeof(pjmedia_sock_info));
00420 }
00421
00422
00423
00424
00425 if (argc > 1) {
00426 pj_sockaddr hostaddr;
00427 char hostip[PJ_INET6_ADDRSTRLEN+2];
00428 char temp[80];
00429 pj_str_t dst_uri = pj_str(argv[1]);
00430 pj_str_t local_uri;
00431 pjsip_dialog *dlg;
00432 pjmedia_sdp_session *local_sdp;
00433 pjsip_tx_data *tdata;
00434
00435 if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
00436 app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
00437 return 1;
00438 }
00439 pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
00440
00441 pj_ansi_sprintf(temp, "<sip:simpleuac@%s:%d>",
00442 hostip, SIP_PORT);
00443 local_uri = pj_str(temp);
00444
00445
00446 status = pjsip_dlg_create_uac( pjsip_ua_instance(),
00447 &local_uri,
00448 &local_uri,
00449 &dst_uri,
00450 &dst_uri,
00451 &dlg);
00452 if (status != PJ_SUCCESS) {
00453 app_perror(THIS_FILE, "Unable to create UAC dialog", status);
00454 return 1;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 status = pjmedia_endpt_create_sdp( g_med_endpt,
00479 dlg->pool,
00480 MAX_MEDIA_CNT,
00481 g_sock_info,
00482 &local_sdp);
00483 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00484
00485
00486
00487
00488
00489
00490 status = pjsip_inv_create_uac( dlg, local_sdp, 0, &g_inv);
00491 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 status = pjsip_inv_invite(g_inv, &tdata);
00524 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00525
00526
00527
00528
00529
00530
00531
00532 status = pjsip_inv_send_msg(g_inv, tdata);
00533 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00534
00535
00536 } else {
00537
00538
00539
00540 PJ_LOG(3,(THIS_FILE, "Ready to accept incoming calls..."));
00541 }
00542
00543
00544
00545 for (;!g_complete;) {
00546 pj_time_val timeout = {0, 10};
00547 pjsip_endpt_handle_events(g_endpt, &timeout);
00548 }
00549
00550
00551 dump_pool_usage(THIS_FILE, &cp);
00552
00553
00554
00555
00556
00557 if (g_snd_port)
00558 pjmedia_snd_port_destroy(g_snd_port);
00559
00560 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
00561
00562 if (g_vid_capturer)
00563 pjmedia_vid_port_destroy(g_vid_capturer);
00564 if (g_vid_renderer)
00565 pjmedia_vid_port_destroy(g_vid_renderer);
00566 #endif
00567
00568
00569 if (g_med_stream)
00570 pjmedia_stream_destroy(g_med_stream);
00571 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
00572 if (g_med_vstream)
00573 pjmedia_vid_stream_destroy(g_med_vstream);
00574
00575
00576 # if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
00577 pjmedia_codec_ffmpeg_vid_deinit();
00578 # endif
00579
00580 #endif
00581
00582
00583 for (i = 0; i < MAX_MEDIA_CNT; ++i) {
00584 if (g_med_transport[i])
00585 pjmedia_transport_close(g_med_transport[i]);
00586 }
00587
00588
00589 if (g_med_endpt)
00590 pjmedia_endpt_destroy(g_med_endpt);
00591
00592
00593 if (g_endpt)
00594 pjsip_endpt_destroy(g_endpt);
00595
00596
00597 if (pool)
00598 pj_pool_release(pool);
00599
00600 return 0;
00601 }
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 static void call_on_state_changed( pjsip_inv_session *inv,
00612 pjsip_event *e)
00613 {
00614 PJ_UNUSED_ARG(e);
00615
00616 if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
00617
00618 PJ_LOG(3,(THIS_FILE, "Call DISCONNECTED [reason=%d (%s)]",
00619 inv->cause,
00620 pjsip_get_status_text(inv->cause)->ptr));
00621
00622 PJ_LOG(3,(THIS_FILE, "One call completed, application quitting..."));
00623 g_complete = 1;
00624
00625 } else {
00626
00627 PJ_LOG(3,(THIS_FILE, "Call state changed to %s",
00628 pjsip_inv_state_name(inv->state)));
00629
00630 }
00631 }
00632
00633
00634
00635 static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
00636 {
00637
00638 PJ_UNUSED_ARG(inv);
00639 PJ_UNUSED_ARG(e);
00640 }
00641
00642
00643
00644
00645
00646
00647
00648 static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
00649 {
00650 pj_sockaddr hostaddr;
00651 char temp[80], hostip[PJ_INET6_ADDRSTRLEN];
00652 pj_str_t local_uri;
00653 pjsip_dialog *dlg;
00654 pjmedia_sdp_session *local_sdp;
00655 pjsip_tx_data *tdata;
00656 unsigned options = 0;
00657 pj_status_t status;
00658
00659
00660
00661
00662
00663 if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
00664
00665 if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
00666 pj_str_t reason = pj_str("Simple UA unable to handle "
00667 "this request");
00668
00669 pjsip_endpt_respond_stateless( g_endpt, rdata,
00670 500, &reason,
00671 NULL, NULL);
00672 }
00673 return PJ_TRUE;
00674 }
00675
00676
00677
00678
00679
00680 if (g_inv) {
00681
00682 pj_str_t reason = pj_str("Another call is in progress");
00683
00684 pjsip_endpt_respond_stateless( g_endpt, rdata,
00685 500, &reason,
00686 NULL, NULL);
00687 return PJ_TRUE;
00688
00689 }
00690
00691
00692 status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
00693 g_endpt, NULL);
00694 if (status != PJ_SUCCESS) {
00695
00696 pj_str_t reason = pj_str("Sorry Simple UA can not handle this INVITE");
00697
00698 pjsip_endpt_respond_stateless( g_endpt, rdata,
00699 500, &reason,
00700 NULL, NULL);
00701 return PJ_TRUE;
00702 }
00703
00704
00705
00706
00707 if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
00708 app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
00709 return PJ_TRUE;
00710 }
00711 pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
00712
00713 pj_ansi_sprintf(temp, "<sip:simpleuas@%s:%d>",
00714 hostip, SIP_PORT);
00715 local_uri = pj_str(temp);
00716
00717
00718
00719
00720 status = pjsip_dlg_create_uas( pjsip_ua_instance(),
00721 rdata,
00722 &local_uri,
00723 &dlg);
00724 if (status != PJ_SUCCESS) {
00725 pjsip_endpt_respond_stateless(g_endpt, rdata, 500, NULL,
00726 NULL, NULL);
00727 return PJ_TRUE;
00728 }
00729
00730
00731
00732
00733
00734 status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool,
00735 MAX_MEDIA_CNT, g_sock_info, &local_sdp);
00736 PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
00737
00738
00739
00740
00741
00742
00743 status = pjsip_inv_create_uas( dlg, rdata, local_sdp, 0, &g_inv);
00744 PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 status = pjsip_inv_initial_answer(g_inv, rdata,
00755 180,
00756 NULL, NULL, &tdata);
00757 PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
00758
00759
00760
00761 status = pjsip_inv_send_msg(g_inv, tdata);
00762 PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
00763
00764
00765
00766
00767
00768 status = pjsip_inv_answer( g_inv,
00769 200, NULL,
00770 NULL,
00771 &tdata);
00772 PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
00773
00774
00775
00776
00777 status = pjsip_inv_send_msg(g_inv, tdata);
00778 PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
00779
00780
00781
00782
00783
00784
00785 return PJ_TRUE;
00786 }
00787
00788
00789
00790
00791
00792
00793
00794
00795 static void call_on_media_update( pjsip_inv_session *inv,
00796 pj_status_t status)
00797 {
00798 pjmedia_stream_info stream_info;
00799 const pjmedia_sdp_session *local_sdp;
00800 const pjmedia_sdp_session *remote_sdp;
00801 pjmedia_port *media_port;
00802
00803 if (status != PJ_SUCCESS) {
00804
00805 app_perror(THIS_FILE, "SDP negotiation has failed", status);
00806
00807
00808
00809
00810 return;
00811 }
00812
00813
00814
00815
00816 status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
00817
00818 status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
00819
00820
00821
00822 status = pjmedia_stream_info_from_sdp(&stream_info, inv->dlg->pool,
00823 g_med_endpt,
00824 local_sdp, remote_sdp, 0);
00825 if (status != PJ_SUCCESS) {
00826 app_perror(THIS_FILE,"Unable to create audio stream info",status);
00827 return;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 status = pjmedia_stream_create(g_med_endpt, inv->dlg->pool, &stream_info,
00839 g_med_transport[0], NULL, &g_med_stream);
00840 if (status != PJ_SUCCESS) {
00841 app_perror( THIS_FILE, "Unable to create audio stream", status);
00842 return;
00843 }
00844
00845
00846 status = pjmedia_stream_start(g_med_stream);
00847 if (status != PJ_SUCCESS) {
00848 app_perror( THIS_FILE, "Unable to start audio stream", status);
00849 return;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858 pjmedia_stream_get_port(g_med_stream, &media_port);
00859
00860
00861 pjmedia_snd_port_create(inv->pool,
00862 PJMEDIA_AUD_DEFAULT_CAPTURE_DEV,
00863 PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV,
00864 PJMEDIA_PIA_SRATE(&media_port->info),
00865 PJMEDIA_PIA_CCNT(&media_port->info),
00866 PJMEDIA_PIA_SPF(&media_port->info),
00867 PJMEDIA_PIA_BITS(&media_port->info),
00868 0,
00869 &g_snd_port);
00870
00871 if (status != PJ_SUCCESS) {
00872 app_perror( THIS_FILE, "Unable to create sound port", status);
00873 PJ_LOG(3,(THIS_FILE, "%d %d %d %d",
00874 PJMEDIA_PIA_SRATE(&media_port->info),
00875 PJMEDIA_PIA_CCNT(&media_port->info),
00876 PJMEDIA_PIA_SPF(&media_port->info),
00877 PJMEDIA_PIA_BITS(&media_port->info)
00878 ));
00879 return;
00880 }
00881
00882 status = pjmedia_snd_port_connect(g_snd_port, media_port);
00883
00884
00885
00886
00887
00888
00889 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
00890 if (local_sdp->media_count > 1) {
00891 pjmedia_vid_stream_info vstream_info;
00892 pjmedia_vid_port_param vport_param;
00893
00894 pjmedia_vid_port_param_default(&vport_param);
00895
00896
00897 status = pjmedia_vid_stream_info_from_sdp(&vstream_info,
00898 inv->dlg->pool, g_med_endpt,
00899 local_sdp, remote_sdp, 1);
00900 if (status != PJ_SUCCESS) {
00901 app_perror(THIS_FILE,"Unable to create video stream info",status);
00902 return;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 status = pjmedia_vid_stream_create(g_med_endpt, NULL, &vstream_info,
00914 g_med_transport[1], NULL,
00915 &g_med_vstream);
00916 if (status != PJ_SUCCESS) {
00917 app_perror( THIS_FILE, "Unable to create video stream", status);
00918 return;
00919 }
00920
00921
00922 status = pjmedia_vid_stream_start(g_med_vstream);
00923 if (status != PJ_SUCCESS) {
00924 app_perror( THIS_FILE, "Unable to start video stream", status);
00925 return;
00926 }
00927
00928 if (vstream_info.dir & PJMEDIA_DIR_DECODING) {
00929 status = pjmedia_vid_dev_default_param(
00930 inv->pool, PJMEDIA_VID_DEFAULT_RENDER_DEV,
00931 &vport_param.vidparam);
00932 if (status != PJ_SUCCESS) {
00933 app_perror(THIS_FILE, "Unable to get default param of video "
00934 "renderer device", status);
00935 return;
00936 }
00937
00938
00939 pjmedia_vid_stream_get_port(g_med_vstream, PJMEDIA_DIR_DECODING,
00940 &media_port);
00941
00942
00943 pjmedia_format_copy(&vport_param.vidparam.fmt,
00944 &media_port->info.fmt);
00945 vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
00946 vport_param.active = PJ_TRUE;
00947
00948
00949 status = pjmedia_vid_port_create(inv->pool, &vport_param,
00950 &g_vid_renderer);
00951 if (status != PJ_SUCCESS) {
00952 app_perror(THIS_FILE, "Unable to create video renderer device",
00953 status);
00954 return;
00955 }
00956
00957
00958 status = pjmedia_vid_port_connect(g_vid_renderer, media_port,
00959 PJ_FALSE);
00960 if (status != PJ_SUCCESS) {
00961 app_perror(THIS_FILE, "Unable to connect renderer to stream",
00962 status);
00963 return;
00964 }
00965 }
00966
00967
00968 if (vstream_info.dir & PJMEDIA_DIR_ENCODING) {
00969 status = pjmedia_vid_dev_default_param(
00970 inv->pool, PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
00971 &vport_param.vidparam);
00972 if (status != PJ_SUCCESS) {
00973 app_perror(THIS_FILE, "Unable to get default param of video "
00974 "capture device", status);
00975 return;
00976 }
00977
00978
00979 pjmedia_vid_stream_get_port(g_med_vstream, PJMEDIA_DIR_ENCODING,
00980 &media_port);
00981
00982
00983 pjmedia_format_copy(&vport_param.vidparam.fmt,
00984 &media_port->info.fmt);
00985 vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
00986 vport_param.active = PJ_TRUE;
00987
00988
00989 status = pjmedia_vid_port_create(inv->pool, &vport_param,
00990 &g_vid_capturer);
00991 if (status != PJ_SUCCESS) {
00992 app_perror(THIS_FILE, "Unable to create video capture device",
00993 status);
00994 return;
00995 }
00996
00997
00998 status = pjmedia_vid_port_connect(g_vid_capturer, media_port,
00999 PJ_FALSE);
01000 if (status != PJ_SUCCESS) {
01001 app_perror(THIS_FILE, "Unable to connect capturer to stream",
01002 status);
01003 return;
01004 }
01005 }
01006
01007
01008 if (g_vid_renderer) {
01009 status = pjmedia_vid_port_start(g_vid_renderer);
01010 if (status != PJ_SUCCESS) {
01011 app_perror(THIS_FILE, "Unable to start video renderer",
01012 status);
01013 return;
01014 }
01015 }
01016 if (g_vid_capturer) {
01017 status = pjmedia_vid_port_start(g_vid_capturer);
01018 if (status != PJ_SUCCESS) {
01019 app_perror(THIS_FILE, "Unable to start video capturer",
01020 status);
01021 return;
01022 }
01023 }
01024 }
01025 #endif
01026
01027
01028 }
01029
01030
PJSIP Open Source, high performance, small footprint, and very very portable SIP stack
Copyright (C) 2006-2008 Teluu Inc.
|