Changeset 3609
- Timestamp:
- Jul 7, 2011 7:46:33 AM (13 years ago)
- Location:
- pjproject/branches/projects/2.0-dev
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjsip-apps/src/pjsua/pjsua_app.c
r3519 r3609 312 312 puts (" --extra-audio Add one more audio stream"); 313 313 314 #if PJ MEDIA_HAS_VIDEO314 #if PJSUA_HAS_VIDEO 315 315 puts (""); 316 316 puts ("Video Options:"); … … 2646 2646 } 2647 2647 2648 /* General processing for media state. "mi" is the media index */ 2649 static void on_call_generic_media_state(pjsua_call_info *ci, unsigned mi, 2650 pj_bool_t *has_error) 2651 { 2652 const char *status_name[] = { 2653 "None", 2654 "Active", 2655 "Local hold", 2656 "Remote hold", 2657 "Error" 2658 }; 2659 2660 pj_assert(ci->media[mi].status <= PJ_ARRAY_SIZE(status_name)); 2661 pj_assert(PJSUA_CALL_MEDIA_ERROR == 4); 2662 2663 PJ_LOG(4,(THIS_FILE, "Call %d media %d [type=%s], status is %s", 2664 ci->id, mi, pjmedia_type_name(ci->media[mi].type), 2665 status_name[ci->media[mi].status])); 2666 } 2667 2668 /* Process audio media state. "mi" is the media index. */ 2669 static void on_call_audio_state(pjsua_call_info *ci, unsigned mi, 2670 pj_bool_t *has_error) 2671 { 2672 /* Stop ringback */ 2673 ring_stop(ci->id); 2674 2675 /* Connect ports appropriately when media status is ACTIVE or REMOTE HOLD, 2676 * otherwise we should NOT connect the ports. 2677 */ 2678 if (ci->media[mi].status == PJSUA_CALL_MEDIA_ACTIVE || 2679 ci->media[mi].status == PJSUA_CALL_MEDIA_REMOTE_HOLD) 2680 { 2681 pj_bool_t connect_sound = PJ_TRUE; 2682 pjsua_conf_port_id call_conf_slot; 2683 2684 call_conf_slot = ci->media[mi].stream.aud.conf_slot; 2685 2686 /* Loopback sound, if desired */ 2687 if (app_config.auto_loop) { 2688 pjsua_conf_connect(call_conf_slot, call_conf_slot); 2689 connect_sound = PJ_FALSE; 2690 } 2691 2692 /* Automatically record conversation, if desired */ 2693 if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) { 2694 pjsua_conf_connect(call_conf_slot, app_config.rec_port); 2695 } 2696 2697 /* Stream a file, if desired */ 2698 if ((app_config.auto_play || app_config.auto_play_hangup) && 2699 app_config.wav_port != PJSUA_INVALID_ID) 2700 { 2701 pjsua_conf_connect(app_config.wav_port, call_conf_slot); 2702 connect_sound = PJ_FALSE; 2703 } 2704 2705 /* Put call in conference with other calls, if desired */ 2706 if (app_config.auto_conf) { 2707 pjsua_call_id call_ids[PJSUA_MAX_CALLS]; 2708 unsigned call_cnt=PJ_ARRAY_SIZE(call_ids); 2709 unsigned i; 2710 2711 /* Get all calls, and establish media connection between 2712 * this call and other calls. 2713 */ 2714 pjsua_enum_calls(call_ids, &call_cnt); 2715 2716 for (i=0; i<call_cnt; ++i) { 2717 if (call_ids[i] == ci->id) 2718 continue; 2719 2720 if (!pjsua_call_has_media(call_ids[i])) 2721 continue; 2722 2723 pjsua_conf_connect(call_conf_slot, 2724 pjsua_call_get_conf_port(call_ids[i])); 2725 pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]), 2726 call_conf_slot); 2727 2728 /* Automatically record conversation, if desired */ 2729 if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) { 2730 pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]), 2731 app_config.rec_port); 2732 } 2733 2734 } 2735 2736 /* Also connect call to local sound device */ 2737 connect_sound = PJ_TRUE; 2738 } 2739 2740 /* Otherwise connect to sound device */ 2741 if (connect_sound) { 2742 pjsua_conf_connect(call_conf_slot, 0); 2743 pjsua_conf_connect(0, call_conf_slot); 2744 2745 /* Automatically record conversation, if desired */ 2746 if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) { 2747 pjsua_conf_connect(call_conf_slot, app_config.rec_port); 2748 pjsua_conf_connect(0, app_config.rec_port); 2749 } 2750 } 2751 } 2752 } 2753 2754 /* Process video media state. "mi" is the media index. */ 2755 static void on_call_video_state(pjsua_call_info *ci, unsigned mi, 2756 pj_bool_t *has_error) 2757 { 2758 } 2648 2759 2649 2760 /* … … 2655 2766 { 2656 2767 pjsua_call_info call_info; 2768 unsigned mi; 2769 pj_bool_t has_error = PJ_FALSE; 2657 2770 2658 2771 pjsua_call_get_info(call_id, &call_info); 2659 2772 2660 /* Stop ringback */ 2661 ring_stop(call_id); 2662 2663 /* Connect ports appropriately when media status is ACTIVE or REMOTE HOLD, 2664 * otherwise we should NOT connect the ports. 2665 */ 2666 if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE || 2667 call_info.media_status == PJSUA_CALL_MEDIA_REMOTE_HOLD) 2668 { 2669 pj_bool_t connect_sound = PJ_TRUE; 2670 2671 /* Loopback sound, if desired */ 2672 if (app_config.auto_loop) { 2673 pjsua_conf_connect(call_info.conf_slot, call_info.conf_slot); 2674 connect_sound = PJ_FALSE; 2773 for (mi=0; mi<call_info.media_cnt; ++mi) { 2774 on_call_generic_media_state(&call_info, mi, &has_error); 2775 2776 switch (call_info.media[mi].type) { 2777 case PJMEDIA_TYPE_AUDIO: 2778 on_call_audio_state(&call_info, mi, &has_error); 2779 break; 2780 case PJMEDIA_TYPE_VIDEO: 2781 on_call_video_state(&call_info, mi, &has_error); 2782 break; 2675 2783 } 2676 2677 /* Automatically record conversation, if desired */ 2678 if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) { 2679 pjsua_conf_connect(call_info.conf_slot, app_config.rec_port); 2680 } 2681 2682 /* Stream a file, if desired */ 2683 if ((app_config.auto_play || app_config.auto_play_hangup) && 2684 app_config.wav_port != PJSUA_INVALID_ID) 2685 { 2686 pjsua_conf_connect(app_config.wav_port, call_info.conf_slot); 2687 connect_sound = PJ_FALSE; 2688 } 2689 2690 /* Put call in conference with other calls, if desired */ 2691 if (app_config.auto_conf) { 2692 pjsua_call_id call_ids[PJSUA_MAX_CALLS]; 2693 unsigned call_cnt=PJ_ARRAY_SIZE(call_ids); 2694 unsigned i; 2695 2696 /* Get all calls, and establish media connection between 2697 * this call and other calls. 2698 */ 2699 pjsua_enum_calls(call_ids, &call_cnt); 2700 2701 for (i=0; i<call_cnt; ++i) { 2702 if (call_ids[i] == call_id) 2703 continue; 2704 2705 if (!pjsua_call_has_media(call_ids[i])) 2706 continue; 2707 2708 pjsua_conf_connect(call_info.conf_slot, 2709 pjsua_call_get_conf_port(call_ids[i])); 2710 pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]), 2711 call_info.conf_slot); 2712 2713 /* Automatically record conversation, if desired */ 2714 if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) { 2715 pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]), 2716 app_config.rec_port); 2717 } 2718 2719 } 2720 2721 /* Also connect call to local sound device */ 2722 connect_sound = PJ_TRUE; 2723 } 2724 2725 /* Otherwise connect to sound device */ 2726 if (connect_sound) { 2727 pjsua_conf_connect(call_info.conf_slot, 0); 2728 pjsua_conf_connect(0, call_info.conf_slot); 2729 2730 /* Automatically record conversation, if desired */ 2731 if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) { 2732 pjsua_conf_connect(call_info.conf_slot, app_config.rec_port); 2733 pjsua_conf_connect(0, app_config.rec_port); 2734 } 2735 } 2736 } 2737 2738 /* Handle media status */ 2739 switch (call_info.media_status) { 2740 case PJSUA_CALL_MEDIA_ACTIVE: 2741 PJ_LOG(3,(THIS_FILE, "Media for call %d is active", call_id)); 2742 break; 2743 2744 case PJSUA_CALL_MEDIA_LOCAL_HOLD: 2745 PJ_LOG(3,(THIS_FILE, "Media for call %d is suspended (hold) by local", 2746 call_id)); 2747 break; 2748 2749 case PJSUA_CALL_MEDIA_REMOTE_HOLD: 2750 PJ_LOG(3,(THIS_FILE, 2751 "Media for call %d is suspended (hold) by remote", 2752 call_id)); 2753 break; 2754 2755 case PJSUA_CALL_MEDIA_ERROR: 2756 PJ_LOG(3,(THIS_FILE, 2757 "Media has reported error, disconnecting call")); 2758 { 2759 pj_str_t reason = pj_str("ICE negotiation failed"); 2760 pjsua_call_hangup(call_id, 500, &reason, NULL); 2761 } 2762 break; 2763 2764 case PJSUA_CALL_MEDIA_NONE: 2765 PJ_LOG(3,(THIS_FILE, 2766 "Media for call %d is inactive", 2767 call_id)); 2768 break; 2769 2770 default: 2771 pj_assert(!"Unhandled media status"); 2772 break; 2784 } 2785 2786 if (has_error) { 2787 pj_str_t reason = pj_str("Media failed"); 2788 pjsua_call_hangup(call_id, 500, &reason, NULL); 2773 2789 } 2774 2790 } … … 3256 3272 puts("| | V Adjust audio Volume | f Save config |"); 3257 3273 puts("| S Send arbitrary REQUEST | Cp Codec priorities | |"); 3258 puts("+------------------------------+--------------------------+-------------------+"); 3274 puts("+-----------------------------------------------------------------------------+"); 3275 #if PJSUA_HAS_VIDEO 3276 puts("| Video: \"vid help\" for more info |"); 3277 puts("+-----------------------------------------------------------------------------+"); 3278 #endif 3259 3279 puts("| q QUIT L ReLoad sleep MS echo [0|1|txt] n: detect NAT type |"); 3260 3280 puts("+=============================================================================+"); … … 3272 3292 } 3273 3293 3294 /* Help screen for video */ 3295 static void vid_show_help(void) 3296 { 3297 #if PJSUA_HAS_VIDEO 3298 puts("+=============================================================================+"); 3299 puts("| Video commands: |"); 3300 puts("| |"); 3301 puts("| vid help Show this help screen |"); 3302 puts("| vid call rx on|off Enable/disable incoming video for current call |"); 3303 puts("| vid call tx on|off Enable/disable video tx for current call |"); 3304 puts("| vid dev list List all video devices |"); 3305 puts("| vid dev refresh Refresh video device list |"); 3306 puts("| vid dev prev on|off ID Enable/disable preview for specified device ID |"); 3307 puts("| vid codec list List video codecs |"); 3308 puts("| vid codec prio PT PRIO Set codec with pt PT priority to PRIO |"); 3309 puts("| vid win list List all active video windows |"); 3310 puts("| vid win show|hide ID Show/hide the specified video window ID |"); 3311 puts("| vid win move ID X Y Move window ID to position X,Y |"); 3312 puts("| vid win resize ID w h Resize window ID to the specified width, height |"); 3313 puts("+=============================================================================+"); 3314 #endif 3315 } 3274 3316 3275 3317 /* … … 3550 3592 } 3551 3593 3552 #if PJ MEDIA_HAS_VIDEO3594 #if PJSUA_HAS_VIDEO 3553 3595 puts(""); 3554 3596 printf("List of video codecs:\n"); … … 3592 3634 status = pjsua_codec_set_priority(pj_cstr(&id, codec), 3593 3635 (pj_uint8_t)new_prio); 3594 #if PJ MEDIA_HAS_VIDEO3636 #if PJSUA_HAS_VIDEO 3595 3637 if (status != PJ_SUCCESS) { 3596 3638 status = pjsua_vid_codec_set_priority(pj_cstr(&id, codec), … … 3601 3643 pjsua_perror(THIS_FILE, "Error setting codec priority", status); 3602 3644 } 3645 3646 3647 #if PJSUA_HAS_VIDEO 3648 static void vid_print_dev(int id, const pjmedia_vid_dev_info *vdi, 3649 const char *title) 3650 { 3651 char capnames[120]; 3652 char formats[120]; 3653 const char *dirname; 3654 unsigned i; 3655 3656 if (vdi->dir == PJMEDIA_DIR_CAPTURE_RENDER) { 3657 dirname = "capture, render"; 3658 } else if (vdi->dir == PJMEDIA_DIR_CAPTURE) { 3659 dirname = "capture"; 3660 } else { 3661 dirname = "render"; 3662 } 3663 3664 3665 capnames[0] = '\0'; 3666 for (i=0; i<sizeof(int)*8 && (1 << i) < PJMEDIA_VID_DEV_CAP_MAX; ++i) { 3667 if (vdi->caps & (1 << i)) { 3668 const char *capname = pjmedia_vid_dev_cap_name(1 << i, NULL); 3669 if (capname) { 3670 if (*capnames) 3671 strcat(capnames, ", "); 3672 strncat(capnames, capname, 3673 sizeof(capnames)-strlen(capnames)-1); 3674 } 3675 } 3676 } 3677 3678 formats[0] = '\0'; 3679 for (i=0; i<vdi->fmt_cnt; ++i) { 3680 const pjmedia_video_format_info *vfi = 3681 pjmedia_get_video_format_info(NULL, vdi->fmt[i].id); 3682 if (vfi) { 3683 if (*formats) 3684 strcat(formats, ", "); 3685 strncat(formats, vfi->name, sizeof(formats)-strlen(formats)-1); 3686 } 3687 } 3688 3689 PJ_LOG(3,(THIS_FILE, "%3d %s [%s][%s] %s", id, vdi->name, vdi->driver, 3690 dirname, title)); 3691 PJ_LOG(3,(THIS_FILE, " Supported capabilities: %s", capnames)); 3692 PJ_LOG(3,(THIS_FILE, " Supported formats: %s", formats)); 3693 } 3694 3695 static void vid_list_devs(void) 3696 { 3697 unsigned i, count; 3698 pjmedia_vid_dev_info vdi; 3699 pj_status_t status; 3700 3701 PJ_LOG(3,(THIS_FILE, "Video device list:")); 3702 count = pjsua_vid_dev_count(); 3703 if (count == 0) { 3704 PJ_LOG(3,(THIS_FILE, " - no device detected -")); 3705 return; 3706 } else { 3707 PJ_LOG(3,(THIS_FILE, "%d device(s) detected:", count)); 3708 } 3709 3710 status = pjsua_vid_dev_get_info(PJMEDIA_VID_DEFAULT_RENDER_DEV, &vdi); 3711 if (status == PJ_SUCCESS) 3712 vid_print_dev(PJMEDIA_VID_DEFAULT_RENDER_DEV, &vdi, 3713 "(default renderer device)"); 3714 3715 status = pjsua_vid_dev_get_info(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &vdi); 3716 if (status == PJ_SUCCESS) 3717 vid_print_dev(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &vdi, 3718 "(default capture device)"); 3719 3720 for (i=0; i<count; ++i) { 3721 status = pjsua_vid_dev_get_info(i, &vdi); 3722 if (status == PJ_SUCCESS) 3723 vid_print_dev(i, &vdi, ""); 3724 } 3725 } 3726 3727 static void vid_handle_menu(char *menuin) 3728 { 3729 char *argv[8]; 3730 int argc = 0; 3731 3732 /* Tokenize */ 3733 argv[argc] = strtok(menuin, " \t\r\n"); 3734 while (argv[argc] && *argv[argc]) { 3735 argc++; 3736 argv[argc] = strtok(NULL, " \t\r\n"); 3737 } 3738 3739 if (strcmp(argv[1], "help")==0 || argc == 1) { 3740 vid_show_help(); 3741 } else if (strcmp(argv[1], "call")==0) { 3742 pj_bool_t tx = (strcmp(argv[2], "tx") == 0); 3743 pj_bool_t on = (strcmp(argv[3], "on") == 0); 3744 3745 PJ_TODO(vid_enable_disable_video_on_call); 3746 PJ_LOG(1,(THIS_FILE, "Not implemented")); 3747 } else if (strcmp(argv[1], "dev")==0) { 3748 if (strcmp(argv[2], "list")==0) { 3749 vid_list_devs(); 3750 } else if (strcmp(argv[2], "refresh")==0) { 3751 pjmedia_vid_dev_refresh(); 3752 } else if (strcmp(argv[2], "prev")==0) { 3753 if (argc != 5) { 3754 goto on_error; 3755 } else { 3756 pj_bool_t on = (strcmp(argv[3], "on") == 0); 3757 int dev_id = atoi(argv[4]); 3758 if (on) { 3759 pjsua_vid_preview_start(dev_id, NULL); 3760 } else { 3761 pjsua_vid_preview_stop(dev_id); 3762 } 3763 } 3764 } else 3765 goto on_error; 3766 } else if (strcmp(argv[1], "win")==0) { 3767 if (argc==3 && strcmp(argv[2], "list")==0) { 3768 PJ_LOG(1,(THIS_FILE, "Not implemented")); 3769 PJ_TODO(vid_list_window); 3770 } else if (argc==4 && (strcmp(argv[2], "show")==0 || 3771 strcmp(argv[2], "hide")==0)) 3772 { 3773 pj_bool_t show = (strcmp(argv[2], "show")==0); 3774 pjsua_vid_win_id wid = atoi(argv[3]); 3775 3776 pjsua_vid_win_set_show(wid, show); 3777 3778 } else if (argc==6 && strcmp(argv[2], "move")==0) { 3779 pjsua_vid_win_id wid = atoi(argv[3]); 3780 pjmedia_coord pos; 3781 3782 pos.x = atoi(argv[4]); 3783 pos.y = atoi(argv[4]); 3784 pjsua_vid_win_set_pos(wid, &pos); 3785 3786 } else if (argc==6 && strcmp(argv[2], "resize")==0) { 3787 pjsua_vid_win_id wid = atoi(argv[3]); 3788 pjmedia_rect_size size; 3789 3790 size.w = atoi(argv[4]); 3791 size.h = atoi(argv[4]); 3792 pjsua_vid_win_set_size(wid, &size); 3793 } else 3794 goto on_error; 3795 } else if (strcmp(argv[1], "codec")==0) { 3796 pjmedia_vid_codec_info ci[PJMEDIA_CODEC_MGR_MAX_CODECS]; 3797 unsigned prio[PJMEDIA_CODEC_MGR_MAX_CODECS]; 3798 unsigned count = PJMEDIA_CODEC_MGR_MAX_CODECS; 3799 pj_status_t status; 3800 3801 if (argc==3 && strcmp(argv[2], "list")==0) { 3802 status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, ci, prio); 3803 if (status != PJ_SUCCESS) { 3804 PJ_PERROR(1,(THIS_FILE, status, "Error enumerating codecs")); 3805 } else { 3806 unsigned i; 3807 PJ_LOG(3,(THIS_FILE, "Found %d video codecs:", count)); 3808 PJ_LOG(3,(THIS_FILE, " PT Prio Name")); 3809 PJ_LOG(3,(THIS_FILE, "-------------------------")); 3810 for (i=0; i<count; ++i) { 3811 PJ_LOG(3,(THIS_FILE, "% 3d % 3d %.*s", ci[i].pt, prio[i], 3812 (int)ci[i].encoding_name.slen, 3813 ci[i].encoding_name.ptr)); 3814 } 3815 } 3816 } else if (argc==5 && strcmp(argv[2], "prio")==0) { 3817 int pt = atoi(argv[3]); 3818 int prio = atoi(argv[4]); 3819 const pjmedia_vid_codec_info *pci; 3820 3821 status = pjmedia_vid_codec_mgr_get_codec_info(NULL, pt, &pci); 3822 if (status != PJ_SUCCESS) { 3823 PJ_PERROR(1,(THIS_FILE, status, "Unable to find codec")); 3824 } else { 3825 char codec_id[40]; 3826 if (pjmedia_vid_codec_info_to_id(pci, codec_id, 3827 sizeof(codec_id)) == NULL) 3828 { 3829 PJ_PERROR(1,(THIS_FILE, status, "Unable to get codec id")); 3830 } else { 3831 pj_str_t cid = pj_str(codec_id); 3832 status = pjsua_vid_codec_set_priority(&cid, 3833 (pj_uint8_t)prio); 3834 } 3835 } 3836 3837 } else 3838 goto on_error; 3839 } else 3840 goto on_error; 3841 3842 return; 3843 3844 on_error: 3845 PJ_LOG(1,(THIS_FILE, "Invalid command, use 'vid help'")); 3846 } 3847 3848 #endif /* PJSUA_HAS_VIDEO */ 3603 3849 3604 3850 … … 4032 4278 4033 4279 case 'v': 4034 /* 4035 * Send re-INVITE (to release hold, etc). 4036 */ 4280 #if PJSUA_HAS_VIDEO 4281 if (menuin[1]=='i' && menuin[2]=='d' && menuin[3]==' ') { 4282 4283 vid_handle_menu(menuin); 4284 4285 } else 4286 #endif 4037 4287 if (current_call != -1) { 4038 4288 /* 4289 * re-INVITE 4290 */ 4039 4291 pjsua_call_reinvite(current_call, PJ_TRUE, NULL); 4040 4292 … … 5090 5342 for (i=0; i<app_config.codec_dis_cnt; ++i) { 5091 5343 pjsua_codec_set_priority(&app_config.codec_dis[i],PJMEDIA_CODEC_PRIO_DISABLED); 5092 #if PJ MEDIA_HAS_VIDEO5344 #if PJSUA_HAS_VIDEO 5093 5345 pjsua_vid_codec_set_priority(&app_config.codec_dis[i],PJMEDIA_CODEC_PRIO_DISABLED); 5094 5346 #endif … … 5099 5351 pjsua_codec_set_priority(&app_config.codec_arg[i], 5100 5352 (pj_uint8_t)(PJMEDIA_CODEC_PRIO_NORMAL+i+9)); 5101 #if PJ MEDIA_HAS_VIDEO5353 #if PJSUA_HAS_VIDEO 5102 5354 pjsua_vid_codec_set_priority(&app_config.codec_arg[i], 5103 5355 (pj_uint8_t)(PJMEDIA_CODEC_PRIO_NORMAL+i+9)); … … 5138 5390 } 5139 5391 5140 #if PJ MEDIA_HAS_VIDEO5392 #if PJSUA_HAS_VIDEO 5141 5393 if (app_config.vcapture_dev != PJSUA_INVALID_ID || 5142 5394 app_config.vrender_dev != PJSUA_INVALID_ID) 5143 5395 { 5144 status = pjsua_vid_set_dev(app_config.vcapture_dev, 5145 app_config.vrender_dev); 5396 //status = pjsua_vid_set_dev(app_config.vcapture_dev, 5397 // app_config.vrender_dev); 5398 PJ_TODO(vid_implement_pjsua_vid_set_dev); 5146 5399 if (status != PJ_SUCCESS) 5147 5400 goto on_error; -
pjproject/branches/projects/2.0-dev/pjsip/build/Makefile
r3457 r3609 76 76 export PJSUA_LIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 77 77 pjsua_acc.o pjsua_call.o pjsua_core.o \ 78 pjsua_im.o pjsua_media.o pjsua_pres.o 78 pjsua_im.o pjsua_media.o pjsua_pres.o \ 79 pjsua_dump.o pjsua_vid.o 79 80 export PJSUA_LIB_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS) 80 81 -
pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua.h
r3500 r3609 325 325 #endif 326 326 327 /** 328 * Is video enabled. 329 */ 330 #ifndef PJSUA_HAS_VIDEO 331 # define PJSUA_HAS_VIDEO PJMEDIA_HAS_VIDEO 332 #endif 327 333 328 334 /** … … 2439 2445 * Maximum number of simultaneous active video streams to be allowed 2440 2446 * for calls on this account. Setting this to zero will disable video 2441 * in calls on this account .2442 * 2443 * Default: 02447 * in calls on this account, regardless of other video settings. 2448 * 2449 * Default: 1 2444 2450 */ 2445 2451 unsigned max_video_cnt; 2452 2453 /** 2454 * Specify whether incoming video should be shown to screen by default. 2455 * This applies to incoming call (INVITE), incoming re-INVITE, and 2456 * incoming UPDATE requests. 2457 * 2458 * Regardless of this setting, application can detect incoming video 2459 * by implementing \a on_call_media_state() callback and enumerating 2460 * the media stream(s) with #pjsua_call_get_info(). Once incoming 2461 * video is recognised, application may retrieve the window associated 2462 * with the incoming video and show or hide it with 2463 * #pjsua_vid_win_set_show(). 2464 * 2465 * Default: PJ_FALSE 2466 */ 2467 pj_bool_t vid_in_auto_show; 2468 2469 /** 2470 * Specify whether outgoing video should be activated by default when 2471 * making outgoing calls and/or when incoming video is detected. This 2472 * applies to incoming and outgoing calls, incoming re-INVITE, and 2473 * incoming UPDATE. If the setting is non-zero, outgoing video 2474 * transmission will be started as soon as response to these requests 2475 * is sent (or received). 2476 * 2477 * Regardless of the value of this setting, application can start and 2478 * stop outgoing video transmission with #pjsua_call_set_vid_out(). 2479 * 2480 * Default: PJ_FALSE 2481 */ 2482 pj_bool_t vid_out_auto_transmit; 2483 2484 /** 2485 * Specify the default capture device to be used by this account. If 2486 * \a vid_out_auto_transmit is enabled, this device will be used for 2487 * capturing video. 2488 * 2489 * Default: PJMEDIA_VID_DEFAULT_CAPTURE_DEV 2490 */ 2491 pjmedia_vid_dev_index vid_cap_dev; 2492 2493 /** 2494 * Specify the default rendering device to be used by this account. 2495 * 2496 * Default: PJMEDIA_VID_DEFAULT_RENDER_DEV 2497 */ 2498 pjmedia_vid_dev_index vid_rend_dev; 2446 2499 2447 2500 /** … … 2976 3029 #endif 2977 3030 3031 /** 3032 * Maximum active video windows 3033 */ 3034 #ifndef PJSUA_MAX_VID_WINS 3035 # define PJSUA_MAX_VID_WINS 16 3036 #endif 3037 3038 /** 3039 * Video window ID. 3040 */ 3041 typedef int pjsua_vid_win_id; 2978 3042 2979 3043 … … 3084 3148 /** Audio stream */ 3085 3149 struct { 3086 pjsua_conf_port_id conf_slot; /**< The conference port3087 number for the call. */3088 } aud io;3150 /** The conference port number for the call. */ 3151 pjsua_conf_port_id conf_slot; 3152 } aud; 3089 3153 3090 3154 /** Video stream */ 3091 3155 struct { 3092 pjmedia_vid_port *capturer; /**< Video capturer. */ 3093 pjmedia_vid_port *renderer; /**< Video renderer. */ 3094 } video; 3156 /** 3157 * The window id for incoming video, if any, or 3158 * PJSUA_INVALID_ID. 3159 */ 3160 pjsua_vid_win_id win_in; 3161 3162 /** The video capture device for outgoing transmission, 3163 * if any, or PJMEDIA_VID_INVALID_DEV 3164 */ 3165 pjmedia_vid_dev_index cap_dev; 3166 3167 } vid; 3095 3168 } stream; 3096 3169 … … 3118 3191 3119 3192 3193 /** 3194 * Media stream info. 3195 */ 3196 typedef struct pjsua_stream_info 3197 { 3198 /** Media type of this stream. */ 3199 pjmedia_type type; 3200 3201 /** Stream info (union). */ 3202 union { 3203 /** Audio stream info */ 3204 pjmedia_stream_info aud; 3205 3206 /** Video stream info */ 3207 pjmedia_vid_stream_info vid; 3208 } info; 3209 3210 } pjsua_stream_info; 3211 3212 3213 /** 3214 * Media stream statistic. 3215 */ 3216 typedef struct pjsua_stream_stat 3217 { 3218 /** RTCP statistic. */ 3219 pjmedia_rtcp_stat rtcp; 3220 3221 /** Jitter buffer statistic. */ 3222 pjmedia_jb_state jbuf; 3223 3224 } pjsua_stream_stat; 3225 3120 3226 3121 3227 /** … … 3191 3297 3192 3298 3193 #if DISABLED_FOR_TICKET_1185 3194 /** 3195 * Retrieve the media session associated with this call. Note that the media 3196 * session may not be available depending on the current call's media status 3197 * (the pjsua_call_media_status information in pjsua_call_info). Application 3198 * may use the media session to retrieve more detailed information about the 3199 * call's media. 3299 /** 3300 * Get the conference port identification associated with the call. 3200 3301 * 3201 3302 * @param call_id Call identification. 3202 3303 * 3203 * @return Call media session. 3204 */ 3205 PJ_DECL(pjmedia_session*) pjsua_call_get_media_session(pjsua_call_id call_id); 3206 3207 /** 3208 * Retrieve the media transport instance that is used for this call. 3209 * Application may use the media transport to query more detailed information 3210 * about the media transport. 3211 * 3212 * @param cid Call identification (the call_id). 3213 * 3214 * @return Call media transport. 3215 */ 3216 PJ_DECL(pjmedia_transport*) pjsua_call_get_media_transport(pjsua_call_id cid); 3217 #endif /* DISABLED_FOR_TICKET_1185 */ 3218 3219 /** 3220 * Get the conference port identification associated with the call. 3221 * 3222 * @param call_id Call identification. 3223 * 3224 * @return Conference port ID, or PJSUA_INVALID_ID when the 3304 * @return Conference port ID, or PJSUA_INVALID_ID when the 3225 3305 * media has not been established or is not active. 3226 3306 */ … … 3571 3651 unsigned maxlen, 3572 3652 const char *indent); 3653 3654 /** 3655 * Get the media stream index of the default video stream in the call. 3656 * Typically this will just retrieve the stream index of the first 3657 * activated video stream in the call. 3658 * 3659 * @param call_id Call identification. 3660 * 3661 * @return The media stream index or -1 if no video stream 3662 * is present in the call. 3663 */ 3664 PJ_DECL(int) pjsua_call_get_vid_stream_idx(pjsua_call_id call_id); 3665 3666 /** 3667 * Start, stop, and/or manipulate video transmission for the specified 3668 * call. This would trigger a re-INVITE or UPDATE to be sent for the 3669 * call. This function may add, remove, or modify existing video media 3670 * stream, depending on the media index specified (the \a med_idx argument). 3671 * 3672 * To add a new or edit existing video stream (for transmission), specify 3673 * a valid video capture device ID or PJMEDIA_VID_DEFAULT_CAPTURE_DEV in 3674 * the \a cap_dev argument. If \a med_idx is set to default stream (-1), 3675 * then the function will modify existing video stream if one exists, or 3676 * add a new one if it doesn't. If \a med_idx is set to a specific stream 3677 * index, the function will modify that video stream. Otherwise if \a med_idx 3678 * is set to value larger than the current media count, a new video stream 3679 * will be added to the call. 3680 * 3681 * To remove an existing video stream, specify PJMEDIA_VID_INVALID_DEV in 3682 * \a cap_dev argument. If \a med_idx is set to default stream (-1), this 3683 * will remove the default/first video stream in the call, otherwise 3684 * application can put a specific value to request removal of that particular 3685 * video stream. 3686 * 3687 * @param call_id Call identification. 3688 * @param med_idx The media stream index. Currently the value MUST 3689 * be -1 to denote the default video stream in the 3690 * call. 3691 * @param cap_dev To add or modify existing video media stream, 3692 * specify PJMEDIA_VID_DEFAULT_CAPTURE_DEV to use 3693 * the default capture device as configured in the 3694 * account, or specify a specific capture device ID. 3695 * To disable an existing video stream, specify 3696 * PJMEDIA_VID_INVALID_DEV for this parameter. 3697 * 3698 * @return PJ_SUCCESS on success or the appropriate error. 3699 */ 3700 PJ_DECL(pj_status_t) pjsua_call_set_vid_out(pjsua_call_id call_id, 3701 int med_idx, 3702 pjmedia_vid_dev_index cap_dev); 3703 3704 /** 3705 * Get media stream info for the specified media index. 3706 * 3707 * @param call_id The call identification. 3708 * @param med_idx Media stream index. 3709 * @param psi To be filled with the stream info. 3710 * 3711 * @return PJ_SUCCESS on success or the appropriate error. 3712 */ 3713 PJ_DECL(pj_status_t) pjsua_call_get_stream_info(pjsua_call_id call_id, 3714 unsigned med_idx, 3715 pjsua_stream_info *psi); 3716 3717 /** 3718 * Get media stream statistic for the specified media index. 3719 * 3720 * @param call_id The call identification. 3721 * @param med_idx Media stream index. 3722 * @param psi To be filled with the stream statistic. 3723 * 3724 * @return PJ_SUCCESS on success or the appropriate error. 3725 */ 3726 PJ_DECL(pj_status_t) pjsua_call_get_stream_stat(pjsua_call_id call_id, 3727 unsigned med_idx, 3728 pjsua_stream_stat *stat); 3729 3730 /** 3731 * Get media transport info for the specified media index. 3732 * 3733 * @param call_id The call identification. 3734 * @param med_idx Media stream index. 3735 * @param t To be filled with the transport info. 3736 * 3737 * @return PJ_SUCCESS on success or the appropriate error. 3738 */ 3739 PJ_DECL(pj_status_t) pjsua_call_get_transport_info(pjsua_call_id call_id, 3740 unsigned med_idx, 3741 pjmedia_transport_info *t); 3742 3743 3573 3744 3574 3745 /** … … 4448 4619 4449 4620 4450 4451 4452 4621 /** 4453 4622 * Get maxinum number of conference ports. … … 4940 5109 4941 5110 /***************************************************************************** 4942 * Video devices.4943 */4944 4945 /**4946 * Enum all video devices installed in the system.4947 *4948 * @param info Array of info to be initialized.4949 * @param count On input, specifies max elements in the array.4950 * On return, it contains actual number of elements4951 * that have been initialized.4952 *4953 * @return PJ_SUCCESS on success, or the appropriate error code.4954 */4955 PJ_DECL(pj_status_t) pjsua_vid_enum_devs(pjmedia_vid_dev_info info[],4956 unsigned *count);4957 4958 4959 /**4960 * Get currently active video devices. If video devices has not been created4961 * (for example when pjsua_start() is not called), it is possible that4962 * the function returns PJ_SUCCESS with -1 as device IDs.4963 *4964 * @param capture_dev On return it will be filled with device ID of the4965 * capture device.4966 * @param render_dev On return it will be filled with device ID of the4967 * device ID of the render device.4968 *4969 * @return PJ_SUCCESS on success, or the appropriate error code.4970 */4971 PJ_DECL(pj_status_t) pjsua_vid_get_dev(int *capture_dev, int *render_dev);4972 4973 4974 /**4975 * Select video device for the next video sessions.4976 *4977 * @param capture_dev Device ID of the capture device.4978 * @param render_dev Device ID of the render device.4979 *4980 * @return PJ_SUCCESS on success, or the appropriate error code.4981 */4982 PJ_DECL(pj_status_t) pjsua_vid_set_dev(int capture_dev, int render_dev);4983 4984 4985 /**4986 * Configure video device setting to the video device being used. If video4987 * device is currently active, the function will forward the setting to the4988 * video device instance to be applied immediately, if it supports it.4989 *4990 * The setting will be saved for future opening of the video device, if the4991 * "keep" argument is set to non-zero. If the video device is currently4992 * inactive, and the "keep" argument is false, this function will return4993 * error.4994 *4995 * Note that in case the setting is kept for future use, it will be applied4996 * to any devices, even when application has changed the video device to be4997 * used.4998 *4999 * See also #pjmedia_vid_dev_stream_set_cap() for more information about5000 * setting an video device capability.5001 *5002 * @param cap The video device setting to change.5003 * @param pval Pointer to value. Please see #pjmedia_vid_dev_cap5004 * documentation about the type of value to be5005 * supplied for each setting.5006 * @param keep Specify whether the setting is to be kept for future5007 * use.5008 *5009 * @return PJ_SUCCESS on success or the appropriate error code.5010 */5011 PJ_DECL(pj_status_t) pjsua_vid_set_setting(pjmedia_vid_dev_cap cap,5012 const void *pval,5013 pj_bool_t keep);5014 5015 /**5016 * Retrieve a video device setting. If video device is currently active,5017 * the function will forward the request to the video device. If video device5018 * is currently inactive, and if application had previously set the setting5019 * and mark the setting as kept, then that setting will be returned.5020 * Otherwise, this function will return error.5021 *5022 * @param cap The video device setting to retrieve.5023 * @param pval Pointer to receive the value.5024 * Please see #pjmedia_vid_dev_cap documentation about5025 * the type of value to be supplied for each setting.5026 *5027 * @return PJ_SUCCESS on success or the appropriate error code.5028 */5029 PJ_DECL(pj_status_t) pjsua_vid_get_setting(pjmedia_vid_dev_cap cap,5030 void *pval);5031 5032 5033 /*****************************************************************************5034 5111 * Codecs. 5035 5112 */ … … 5088 5165 const pjmedia_codec_param *param); 5089 5166 5090 /*****************************************************************************5091 * Video codecs.5092 */5093 5094 /**5095 * Enum all supported video codecs in the system.5096 *5097 * @param id Array of ID to be initialized.5098 * @param count On input, specifies max elements in the array.5099 * On return, it contains actual number of elements5100 * that have been initialized.5101 *5102 * @return PJ_SUCCESS on success, or the appropriate error code.5103 */5104 PJ_DECL(pj_status_t) pjsua_vid_enum_codecs( pjsua_codec_info id[],5105 unsigned *count );5106 5107 5108 /**5109 * Change video codec priority.5110 *5111 * @param codec_id Codec ID, which is a string that uniquely identify5112 * the codec (such as "H263/90000"). Please see pjsua5113 * manual or pjmedia codec reference for details.5114 * @param priority Codec priority, 0-255, where zero means to disable5115 * the codec.5116 *5117 * @return PJ_SUCCESS on success, or the appropriate error code.5118 */5119 PJ_DECL(pj_status_t) pjsua_vid_codec_set_priority( const pj_str_t *codec_id,5120 pj_uint8_t priority );5121 5122 5123 /**5124 * Get video codec parameters.5125 *5126 * @param codec_id Codec ID.5127 * @param param Structure to receive video codec parameters.5128 *5129 * @return PJ_SUCCESS on success, or the appropriate error code.5130 */5131 PJ_DECL(pj_status_t) pjsua_vid_codec_get_param(5132 const pj_str_t *codec_id,5133 pjmedia_vid_codec_param *param);5134 5135 5136 /**5137 * Set video codec parameters.5138 *5139 * @param codec_id Codec ID.5140 * @param param Codec parameter to set. Set to NULL to reset5141 * codec parameter to library default settings.5142 *5143 * @return PJ_SUCCESS on success, or the appropriate error code.5144 */5145 PJ_DECL(pj_status_t) pjsua_vid_codec_set_param(5146 const pj_str_t *codec_id,5147 const pjmedia_vid_codec_param *param);5148 5149 5167 5150 5168 #if DISABLED_FOR_TICKET_1185 … … 5159 5177 * @return PJ_SUCCESS on success, or the appropriate error code. 5160 5178 */ 5161 PJ_DECL(pj_status_t) 5179 PJ_DECL(pj_status_t) 5162 5180 pjsua_media_transports_create(const pjsua_transport_config *cfg); 5163 5181 … … 5176 5194 * @return PJ_SUCCESS on success, or the appropriate error code. 5177 5195 */ 5178 PJ_DECL(pj_status_t) 5196 PJ_DECL(pj_status_t) 5179 5197 pjsua_media_transports_attach( pjsua_media_transport tp[], 5180 5198 unsigned count, … … 5183 5201 5184 5202 5203 /* end of MEDIA API */ 5185 5204 /** 5186 5205 * @} … … 5188 5207 5189 5208 5190 5209 /***************************************************************************** 5210 * VIDEO API 5211 */ 5212 5213 5214 /** 5215 * @defgroup PJSUA_LIB_VIDEO PJSUA-API Video 5216 * @ingroup PJSUA_LIB 5217 * @brief Video support 5218 * @{ 5219 */ 5220 5221 /* 5222 * Video devices API 5223 */ 5224 5225 /** 5226 * Get the number of video devices installed in the system. 5227 * 5228 * @return The number of devices. 5229 */ 5230 PJ_DECL(unsigned) pjsua_vid_dev_count(void); 5231 5232 /** 5233 * Retrieve the video device info for the specified device index. 5234 * 5235 * @param id The device index. 5236 * @param vdi Device info to be initialized. 5237 * 5238 * @return PJ_SUCCESS on success, or the appropriate error code. 5239 */ 5240 PJ_DECL(pj_status_t) pjsua_vid_dev_get_info(pjmedia_vid_dev_index id, 5241 pjmedia_vid_dev_info *vdi); 5242 5243 /** 5244 * Enum all video devices installed in the system. 5245 * 5246 * @param info Array of info to be initialized. 5247 * @param count On input, specifies max elements in the array. 5248 * On return, it contains actual number of elements 5249 * that have been initialized. 5250 * 5251 * @return PJ_SUCCESS on success, or the appropriate error code. 5252 */ 5253 PJ_DECL(pj_status_t) pjsua_vid_enum_devs(pjmedia_vid_dev_info info[], 5254 unsigned *count); 5255 5256 5257 /* 5258 * Video preview API 5259 */ 5260 5261 /** 5262 * Parameters for starting video preview with pjsua_vid_preview_start(). 5263 * Application should initialize this structure with 5264 * pjsua_vid_preview_param_default(). 5265 */ 5266 typedef struct pjsua_vid_preview_param 5267 { 5268 /** 5269 * Device ID for the video renderer to be used for rendering the 5270 * capture stream for preview. 5271 */ 5272 pjmedia_vid_dev_index rend_id; 5273 } pjsua_vid_preview_param; 5274 5275 5276 /** 5277 * Start video preview window for the specified capture device. 5278 * 5279 * @param id The capture device ID where its preview will be 5280 * started. 5281 * @param prm Optional video preview parameters. Specify NULL 5282 * to use default values. 5283 * 5284 * @return PJ_SUCCESS on success, or the appropriate error code. 5285 */ 5286 PJ_DECL(pj_status_t) pjsua_vid_preview_start(pjmedia_vid_dev_index id, 5287 pjsua_vid_preview_param *prm); 5288 5289 /** 5290 * Get the preview window handle associated with the capture device, if any. 5291 * 5292 * @param id The capture device ID. 5293 * 5294 * @return The window ID of the preview window for the 5295 * specified capture device ID, or NULL if preview 5296 * does not exist. 5297 */ 5298 PJ_DECL(pjsua_vid_win_id) pjsua_vid_preview_get_win(pjmedia_vid_dev_index id); 5299 5300 /** 5301 * Stop video preview. 5302 * 5303 * @param id The capture device ID. 5304 * 5305 * @return PJ_SUCCESS on success, or the appropriate error code. 5306 */ 5307 PJ_DECL(pj_status_t) pjsua_vid_preview_stop(pjmedia_vid_dev_index id); 5308 5309 5310 /* 5311 * Video window manipulation API. 5312 */ 5313 5314 /** 5315 * This structure describes video window info. 5316 */ 5317 typedef struct pjsua_vid_win_info 5318 { 5319 /** 5320 * Window show status. The window is hidden if false. 5321 */ 5322 pj_bool_t show; 5323 5324 /** 5325 * Window position. 5326 */ 5327 pjmedia_coord pos; 5328 5329 /** 5330 * Window size. 5331 */ 5332 pjmedia_rect_size size; 5333 5334 } pjsua_vid_win_info; 5335 5336 5337 /** 5338 * Get window info. 5339 * 5340 * @param wid The video window ID. 5341 * @param wi The video window info to be initialized. 5342 * 5343 * @return PJ_SUCCESS on success, or the appropriate error code. 5344 */ 5345 PJ_DECL(pj_status_t) pjsua_vid_win_get_info(pjsua_vid_win_id wid, 5346 pjsua_vid_win_info *wi); 5347 5348 /** 5349 * Show or hide window. 5350 * 5351 * @param wid The video window ID. 5352 * @param show Set to PJ_TRUE to show the window, PJ_FALSE to 5353 * hide the window. 5354 * 5355 * @return PJ_SUCCESS on success, or the appropriate error code. 5356 */ 5357 PJ_DECL(pj_status_t) pjsua_vid_win_set_show(pjsua_vid_win_id wid, 5358 pj_bool_t show); 5359 5360 /** 5361 * Set video window position. 5362 * 5363 * @param wid The video window ID. 5364 * @param pos The window position. 5365 * 5366 * @return PJ_SUCCESS on success, or the appropriate error code. 5367 */ 5368 PJ_DECL(pj_status_t) pjsua_vid_win_set_pos(pjsua_vid_win_id wid, 5369 const pjmedia_coord *pos); 5370 5371 /** 5372 * Resize window. 5373 * 5374 * @param wid The video window ID. 5375 * @param size The new window size. 5376 * 5377 * @return PJ_SUCCESS on success, or the appropriate error code. 5378 */ 5379 PJ_DECL(pj_status_t) pjsua_vid_win_set_size(pjsua_vid_win_id wid, 5380 const pjmedia_rect_size *size); 5381 5382 5383 5384 /* 5385 * Video codecs API 5386 */ 5387 5388 /** 5389 * Enum all supported video codecs in the system. 5390 * 5391 * @param id Array of ID to be initialized. 5392 * @param count On input, specifies max elements in the array. 5393 * On return, it contains actual number of elements 5394 * that have been initialized. 5395 * 5396 * @return PJ_SUCCESS on success, or the appropriate error code. 5397 */ 5398 PJ_DECL(pj_status_t) pjsua_vid_enum_codecs( pjsua_codec_info id[], 5399 unsigned *count ); 5400 5401 5402 /** 5403 * Change video codec priority. 5404 * 5405 * @param codec_id Codec ID, which is a string that uniquely identify 5406 * the codec (such as "H263/90000"). Please see pjsua 5407 * manual or pjmedia codec reference for details. 5408 * @param priority Codec priority, 0-255, where zero means to disable 5409 * the codec. 5410 * 5411 * @return PJ_SUCCESS on success, or the appropriate error code. 5412 */ 5413 PJ_DECL(pj_status_t) pjsua_vid_codec_set_priority( const pj_str_t *codec_id, 5414 pj_uint8_t priority ); 5415 5416 5417 /** 5418 * Get video codec parameters. 5419 * 5420 * @param codec_id Codec ID. 5421 * @param param Structure to receive video codec parameters. 5422 * 5423 * @return PJ_SUCCESS on success, or the appropriate error code. 5424 */ 5425 PJ_DECL(pj_status_t) pjsua_vid_codec_get_param( 5426 const pj_str_t *codec_id, 5427 pjmedia_vid_codec_param *param); 5428 5429 5430 /** 5431 * Set video codec parameters. 5432 * 5433 * @param codec_id Codec ID. 5434 * @param param Codec parameter to set. Set to NULL to reset 5435 * codec parameter to library default settings. 5436 * 5437 * @return PJ_SUCCESS on success, or the appropriate error code. 5438 */ 5439 PJ_DECL(pj_status_t) pjsua_vid_codec_set_param( 5440 const pj_str_t *codec_id, 5441 const pjmedia_vid_codec_param *param); 5442 5443 5444 5445 /* end of VIDEO API */ 5191 5446 /** 5192 5447 * @} 5193 5448 */ 5194 5449 5450 5451 /** 5452 * @} 5453 */ 5454 5195 5455 PJ_END_DECL 5196 5456 -
pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h
r3560 r3609 304 304 } pjsua_stun_resolve; 305 305 306 typedef enum pjsua_vid_win_type 307 { 308 PJSUA_WND_TYPE_NONE, 309 PJSUA_WND_TYPE_PREVIEW, 310 PJSUA_WND_TYPE_STREAM 311 } pjsua_vid_win_type; 312 313 typedef struct pjsua_vid_win 314 { 315 pjsua_vid_win_type type; /**< Type. */ 316 pj_pool_t *pool; /**< Own pool. */ 317 pjsua_call_id call_id; /**< Owner call or -1 */ 318 pjmedia_vid_port *vp_cap; /**< Capture vidport. */ 319 pjmedia_vid_port *vp_rend; /**< Renderer vidport */ 320 pjmedia_vid_dev_index preview_cap_id;/* Capture dev id */ 321 } pjsua_vid_win; 306 322 307 323 /** … … 398 414 unsigned rec_cnt; /**< Number of file recorders. */ 399 415 pjsua_file_data recorder[PJSUA_MAX_RECORDERS];/**< Array of recs.*/ 416 417 /* Video windows */ 418 #if PJSUA_HAS_VIDEO 419 pjsua_vid_win win[PJSUA_MAX_VID_WINS]; /**< Array of windows */ 420 #endif 400 421 }; 401 422 … … 632 653 char *buf, pj_size_t size); 633 654 655 /* 656 * Video 657 */ 658 pj_status_t pjsua_vid_subsys_init(void); 659 pj_status_t pjsua_vid_subsys_start(void); 660 pj_status_t pjsua_vid_subsys_destroy(void); 661 662 PJ_INLINE(void) pjsua_vid_win_reset(pjsua_vid_win_id wid) 663 { 664 #if PJSUA_HAS_VIDEO 665 pjsua_vid_win *w = &pjsua_var.win[wid]; 666 pj_pool_t *pool = w->pool; 667 668 pj_bzero(w, sizeof(*w)); 669 if (pool) pj_pool_reset(pool); 670 w->call_id = PJSUA_INVALID_ID; 671 w->pool = pool; 672 w->preview_cap_id = PJMEDIA_VID_INVALID_DEV; 673 #endif 674 } 675 634 676 635 677 PJ_END_DECL -
pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_call.c
r3573 r3609 1117 1117 1118 1118 1119 #if DISABLED_FOR_TICKET_11851120 /*1121 * Retrieve the media session associated with this call.1122 */1123 PJ_DEF(pjmedia_session*) pjsua_call_get_media_session(pjsua_call_id call_id)1124 {1125 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,1126 NULL);1127 return pjsua_var.calls[call_id].session;1128 }1129 1130 1131 /*1132 * Retrieve the media transport instance that is used for this call.1133 */1134 PJ_DEF(pjmedia_transport*) pjsua_call_get_media_transport(pjsua_call_id cid)1135 {1136 PJ_ASSERT_RETURN(cid>=0 && cid<(int)pjsua_var.ua_cfg.max_calls,1137 NULL);1138 return pjsua_var.calls[cid].tp;1139 }1140 #endif /* Removed in 2.0 */1141 1142 1119 /* Acquire lock to the specified call_id */ 1143 1120 pj_status_t acquire_call(const char *title, … … 1337 1314 1338 1315 if (call_med->type == PJMEDIA_TYPE_AUDIO) { 1339 info->media[info->media_cnt].stream.aud io.conf_slot =1316 info->media[info->media_cnt].stream.aud.conf_slot = 1340 1317 call_med->strm.a.conf_slot; 1341 1318 } else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 1342 info->media[info->media_cnt].stream.video.capturer =1343 call_med->strm.v.capturer;1344 info->media[info->media_cnt].stream.vid eo.renderer=1345 call_med->strm.v.renderer;1319 PJ_TODO(vid_fill_in_call_info); 1320 info->media[info->media_cnt].stream.vid.win_in = PJSUA_INVALID_ID; 1321 info->media[info->media_cnt].stream.vid.cap_dev = 1322 PJMEDIA_VID_INVALID_DEV; 1346 1323 } else { 1347 1324 continue; … … 2183 2160 } 2184 2161 2185 2186 const char *good_number(char *buf, pj_int32_t val)2187 {2188 if (val < 1000) {2189 pj_ansi_sprintf(buf, "%d", val);2190 } else if (val < 1000000) {2191 pj_ansi_sprintf(buf, "%d.%dK",2192 val / 1000,2193 (val % 1000) / 100);2194 } else {2195 pj_ansi_sprintf(buf, "%d.%02dM",2196 val / 1000000,2197 (val % 1000000) / 10000);2198 }2199 2200 return buf;2201 }2202 2203 static unsigned dump_media_stat(const char *indent,2204 char *buf, unsigned maxlen,2205 const pjmedia_rtcp_stat *stat,2206 const char *rx_info, const char *tx_info)2207 {2208 char last_update[64];2209 char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32];2210 pj_time_val media_duration, now;2211 char *p = buf, *end = buf+maxlen;2212 int len;2213 2214 if (stat->rx.update_cnt == 0)2215 strcpy(last_update, "never");2216 else {2217 pj_gettimeofday(&now);2218 PJ_TIME_VAL_SUB(now, stat->rx.update);2219 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",2220 now.sec / 3600,2221 (now.sec % 3600) / 60,2222 now.sec % 60,2223 now.msec);2224 }2225 2226 pj_gettimeofday(&media_duration);2227 PJ_TIME_VAL_SUB(media_duration, stat->start);2228 if (PJ_TIME_VAL_MSEC(media_duration) == 0)2229 media_duration.msec = 1;2230 2231 len = pj_ansi_snprintf(p, end-p,2232 "%s RX %s last update:%s\n"2233 "%s total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n"2234 "%s pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n"2235 "%s (msec) min avg max last dev\n"2236 "%s loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"2237 "%s jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n"2238 #if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=02239 "%s raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n"2240 #endif2241 #if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=02242 "%s IPDV : %7.3f %7.3f %7.3f %7.3f %7.3f\n"2243 #endif2244 "%s",2245 indent,2246 rx_info? rx_info : "",2247 last_update,2248 2249 indent,2250 good_number(packets, stat->rx.pkt),2251 good_number(bytes, stat->rx.bytes),2252 good_number(ipbytes, stat->rx.bytes + stat->rx.pkt * 40),2253 good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),2254 good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->rx.bytes + stat->rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),2255 indent,2256 stat->rx.loss,2257 (stat->rx.loss? stat->rx.loss * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),2258 stat->rx.discard,2259 (stat->rx.discard? stat->rx.discard * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),2260 stat->rx.dup,2261 (stat->rx.dup? stat->rx.dup * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),2262 stat->rx.reorder,2263 (stat->rx.reorder? stat->rx.reorder * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),2264 indent, indent,2265 stat->rx.loss_period.min / 1000.0,2266 stat->rx.loss_period.mean / 1000.0,2267 stat->rx.loss_period.max / 1000.0,2268 stat->rx.loss_period.last / 1000.0,2269 pj_math_stat_get_stddev(&stat->rx.loss_period) / 1000.0,2270 indent,2271 stat->rx.jitter.min / 1000.0,2272 stat->rx.jitter.mean / 1000.0,2273 stat->rx.jitter.max / 1000.0,2274 stat->rx.jitter.last / 1000.0,2275 pj_math_stat_get_stddev(&stat->rx.jitter) / 1000.0,2276 #if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=02277 indent,2278 stat->rx_raw_jitter.min / 1000.0,2279 stat->rx_raw_jitter.mean / 1000.0,2280 stat->rx_raw_jitter.max / 1000.0,2281 stat->rx_raw_jitter.last / 1000.0,2282 pj_math_stat_get_stddev(&stat->rx_raw_jitter) / 1000.0,2283 #endif2284 #if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=02285 indent,2286 stat->rx_ipdv.min / 1000.0,2287 stat->rx_ipdv.mean / 1000.0,2288 stat->rx_ipdv.max / 1000.0,2289 stat->rx_ipdv.last / 1000.0,2290 pj_math_stat_get_stddev(&stat->rx_ipdv) / 1000.0,2291 #endif2292 ""2293 );2294 2295 if (len < 1 || len > end-p) {2296 *p = '\0';2297 return (p-buf);2298 }2299 p += len;2300 2301 if (stat->tx.update_cnt == 0)2302 strcpy(last_update, "never");2303 else {2304 pj_gettimeofday(&now);2305 PJ_TIME_VAL_SUB(now, stat->tx.update);2306 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",2307 now.sec / 3600,2308 (now.sec % 3600) / 60,2309 now.sec % 60,2310 now.msec);2311 }2312 2313 len = pj_ansi_snprintf(p, end-p,2314 "%s TX %s last update:%s\n"2315 "%s total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n"2316 "%s pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"2317 "%s (msec) min avg max last dev \n"2318 "%s loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"2319 "%s jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n",2320 indent,2321 tx_info,2322 last_update,2323 2324 indent,2325 good_number(packets, stat->tx.pkt),2326 good_number(bytes, stat->tx.bytes),2327 good_number(ipbytes, stat->tx.bytes + stat->tx.pkt * 40),2328 good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),2329 good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->tx.bytes + stat->tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),2330 2331 indent,2332 stat->tx.loss,2333 (stat->tx.loss? stat->tx.loss * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),2334 stat->tx.dup,2335 (stat->tx.dup? stat->tx.dup * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),2336 stat->tx.reorder,2337 (stat->tx.reorder? stat->tx.reorder * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),2338 2339 indent, indent,2340 stat->tx.loss_period.min / 1000.0,2341 stat->tx.loss_period.mean / 1000.0,2342 stat->tx.loss_period.max / 1000.0,2343 stat->tx.loss_period.last / 1000.0,2344 pj_math_stat_get_stddev(&stat->tx.loss_period) / 1000.0,2345 indent,2346 stat->tx.jitter.min / 1000.0,2347 stat->tx.jitter.mean / 1000.0,2348 stat->tx.jitter.max / 1000.0,2349 stat->tx.jitter.last / 1000.0,2350 pj_math_stat_get_stddev(&stat->tx.jitter) / 1000.02351 );2352 2353 if (len < 1 || len > end-p) {2354 *p = '\0';2355 return (p-buf);2356 }2357 p += len;2358 2359 len = pj_ansi_snprintf(p, end-p,2360 "%s RTT msec : %7.3f %7.3f %7.3f %7.3f %7.3f\n",2361 indent,2362 stat->rtt.min / 1000.0,2363 stat->rtt.mean / 1000.0,2364 stat->rtt.max / 1000.0,2365 stat->rtt.last / 1000.0,2366 pj_math_stat_get_stddev(&stat->rtt) / 1000.02367 );2368 if (len < 1 || len > end-p) {2369 *p = '\0';2370 return (p-buf);2371 }2372 p += len;2373 2374 return (p-buf);2375 }2376 2377 2378 /* Dump media session */2379 static void dump_media_session(const char *indent,2380 char *buf, unsigned maxlen,2381 pjsua_call *call)2382 {2383 unsigned i;2384 char *p = buf, *end = buf+maxlen;2385 int len;2386 2387 for (i=0; i<call->med_cnt; ++i) {2388 pjsua_call_media *call_med = &call->media[i];2389 pjmedia_rtcp_stat stat;2390 pj_bool_t has_stat;2391 pjmedia_transport_info tp_info;2392 char rem_addr_buf[80];2393 char codec_info[32] = {'0'};2394 char rx_info[80] = {'\0'};2395 char tx_info[80] = {'\0'};2396 const char *rem_addr;2397 const char *dir_str;2398 const char *media_type_str;2399 2400 switch (call_med->type) {2401 case PJMEDIA_TYPE_AUDIO:2402 media_type_str = "audio";2403 break;2404 case PJMEDIA_TYPE_VIDEO:2405 media_type_str = "video";2406 break;2407 case PJMEDIA_TYPE_APPLICATION:2408 media_type_str = "application";2409 break;2410 default:2411 media_type_str = "unknown";2412 break;2413 }2414 2415 /* Check if the stream is deactivated */2416 if (call_med->tp == NULL ||2417 (!call_med->strm.a.stream && !call_med->strm.v.stream))2418 {2419 len = pj_ansi_snprintf(p, end-p,2420 "%s #%d %s deactivated\n",2421 indent, i, media_type_str);2422 if (len < 1 || len > end-p) {2423 *p = '\0';2424 return;2425 }2426 2427 p += len;2428 continue;2429 }2430 2431 pjmedia_transport_info_init(&tp_info);2432 pjmedia_transport_get_info(call_med->tp, &tp_info);2433 2434 // rem_addr will contain actual address of RTP originator, instead of2435 // remote RTP address specified by stream which is fetched from the SDP.2436 // Please note that we are assuming only one stream per call.2437 //rem_addr = pj_sockaddr_print(&info.stream_info[i].rem_addr,2438 // rem_addr_buf, sizeof(rem_addr_buf), 3);2439 if (pj_sockaddr_has_addr(&tp_info.src_rtp_name)) {2440 rem_addr = pj_sockaddr_print(&tp_info.src_rtp_name, rem_addr_buf,2441 sizeof(rem_addr_buf), 3);2442 } else {2443 pj_ansi_snprintf(rem_addr_buf, sizeof(rem_addr_buf), "-");2444 rem_addr = rem_addr_buf;2445 }2446 2447 if (call_med->dir == PJMEDIA_DIR_NONE) {2448 /* To handle when the stream that is currently being paused2449 * (http://trac.pjsip.org/repos/ticket/1079)2450 */2451 dir_str = "inactive";2452 } else if (call_med->dir == PJMEDIA_DIR_ENCODING)2453 dir_str = "sendonly";2454 else if (call_med->dir == PJMEDIA_DIR_DECODING)2455 dir_str = "recvonly";2456 else if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING)2457 dir_str = "sendrecv";2458 else2459 dir_str = "inactive";2460 2461 if (call_med->type == PJMEDIA_TYPE_AUDIO) {2462 pjmedia_stream *stream = call_med->strm.a.stream;2463 pjmedia_stream_info info;2464 2465 pjmedia_stream_get_stat(stream, &stat);2466 has_stat = PJ_TRUE;2467 2468 pjmedia_stream_get_info(stream, &info);2469 pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s @%dkHz",2470 (int)info.fmt.encoding_name.slen,2471 info.fmt.encoding_name.ptr,2472 info.fmt.clock_rate / 1000);2473 pj_ansi_snprintf(rx_info, sizeof(rx_info), "pt=%d,",2474 info.fmt.pt);2475 pj_ansi_snprintf(tx_info, sizeof(tx_info), "pt=%d, ptime=%d,",2476 info.tx_pt,2477 info.param->setting.frm_per_pkt*2478 info.param->info.frm_ptime);2479 } else if (call_med->type == PJMEDIA_TYPE_VIDEO) {2480 pjmedia_vid_stream *stream = call_med->strm.v.stream;2481 pjmedia_vid_stream_info info;2482 2483 pjmedia_vid_stream_get_stat(stream, &stat);2484 has_stat = PJ_TRUE;2485 2486 pjmedia_vid_stream_get_info(stream, &info);2487 pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s",2488 (int)info.codec_info.encoding_name.slen,2489 info.codec_info.encoding_name.ptr);2490 if (call_med->dir & PJMEDIA_DIR_DECODING) {2491 pjmedia_video_format_detail *vfd;2492 vfd = pjmedia_format_get_video_format_detail(2493 &info.codec_param->dec_fmt, PJ_TRUE);2494 pj_ansi_snprintf(rx_info, sizeof(rx_info),2495 "pt=%d, size=%dx%d, fps=%.2f,",2496 info.rx_pt,2497 vfd->size.w, vfd->size.h,2498 vfd->fps.num*1.0/vfd->fps.denum);2499 }2500 if (call_med->dir & PJMEDIA_DIR_ENCODING) {2501 pjmedia_video_format_detail *vfd;2502 vfd = pjmedia_format_get_video_format_detail(2503 &info.codec_param->enc_fmt, PJ_TRUE);2504 pj_ansi_snprintf(tx_info, sizeof(tx_info),2505 "pt=%d, size=%dx%d, fps=%.2f,",2506 info.tx_pt,2507 vfd->size.w, vfd->size.h,2508 vfd->fps.num*1.0/vfd->fps.denum);2509 }2510 } else {2511 has_stat = PJ_FALSE;2512 }2513 2514 len = pj_ansi_snprintf(p, end-p,2515 "%s #%d %s%s, %s, peer=%s\n",2516 indent,2517 call_med->idx,2518 media_type_str,2519 codec_info,2520 dir_str,2521 rem_addr);2522 if (len < 1 || len > end-p) {2523 *p = '\0';2524 return;2525 }2526 p += len;2527 2528 /* Get and ICE SRTP status */2529 if (call_med->tp) {2530 pjmedia_transport_info tp_info;2531 2532 pjmedia_transport_info_init(&tp_info);2533 pjmedia_transport_get_info(call_med->tp, &tp_info);2534 if (tp_info.specific_info_cnt > 0) {2535 unsigned j;2536 for (j = 0; j < tp_info.specific_info_cnt; ++j) {2537 if (tp_info.spc_info[j].type == PJMEDIA_TRANSPORT_TYPE_SRTP)2538 {2539 pjmedia_srtp_info *srtp_info =2540 (pjmedia_srtp_info*) tp_info.spc_info[j].buffer;2541 2542 len = pj_ansi_snprintf(p, end-p,2543 " %s SRTP status: %s Crypto-suite: %s",2544 indent,2545 (srtp_info->active?"Active":"Not active"),2546 srtp_info->tx_policy.name.ptr);2547 if (len > 0 && len < end-p) {2548 p += len;2549 *p++ = '\n';2550 *p = '\0';2551 }2552 } else if (tp_info.spc_info[j].type==PJMEDIA_TRANSPORT_TYPE_ICE) {2553 const pjmedia_ice_transport_info *ii;2554 2555 ii = (const pjmedia_ice_transport_info*)2556 tp_info.spc_info[j].buffer;2557 2558 len = pj_ansi_snprintf(p, end-p,2559 " %s ICE role: %s, state: %s, comp_cnt: %u",2560 indent,2561 pj_ice_sess_role_name(ii->role),2562 pj_ice_strans_state_name(ii->sess_state),2563 ii->comp_cnt);2564 if (len > 0 && len < end-p) {2565 p += len;2566 *p++ = '\n';2567 *p = '\0';2568 }2569 }2570 }2571 }2572 }2573 2574 2575 if (has_stat) {2576 len = dump_media_stat(indent, p, end-p, &stat,2577 rx_info, tx_info);2578 p += len;2579 }2580 2581 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)2582 # define SAMPLES_TO_USEC(usec, samples, clock_rate) \2583 do { \2584 if (samples <= 4294) \2585 usec = samples * 1000000 / clock_rate; \2586 else { \2587 usec = samples * 1000 / clock_rate; \2588 usec *= 1000; \2589 } \2590 } while(0)2591 2592 # define PRINT_VOIP_MTC_VAL(s, v) \2593 if (v == 127) \2594 sprintf(s, "(na)"); \2595 else \2596 sprintf(s, "%d", v)2597 2598 # define VALIDATE_PRINT_BUF() \2599 if (len < 1 || len > end-p) { *p = '\0'; return; } \2600 p += len; *p++ = '\n'; *p = '\0'2601 2602 2603 if (call_med->type == PJMEDIA_TYPE_AUDIO) {2604 pjmedia_stream_info info;2605 char last_update[64];2606 char loss[16], dup[16];2607 char jitter[80];2608 char toh[80];2609 char plc[16], jba[16], jbr[16];2610 char signal_lvl[16], noise_lvl[16], rerl[16];2611 char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16];2612 pjmedia_rtcp_xr_stat xr_stat;2613 unsigned clock_rate;2614 pj_time_val now;2615 2616 if (pjmedia_stream_get_stat_xr(call_med->strm.a.stream,2617 &xr_stat) != PJ_SUCCESS)2618 {2619 continue;2620 }2621 2622 if (pjmedia_stream_get_info(call_med->strm.a.stream, &info)2623 != PJ_SUCCESS)2624 {2625 continue;2626 }2627 2628 clock_rate = info.fmt.clock_rate;2629 pj_gettimeofday(&now);2630 2631 len = pj_ansi_snprintf(p, end-p, "\n%s Extended reports:", indent);2632 VALIDATE_PRINT_BUF();2633 2634 /* Statistics Summary */2635 len = pj_ansi_snprintf(p, end-p, "%s Statistics Summary", indent);2636 VALIDATE_PRINT_BUF();2637 2638 if (xr_stat.rx.stat_sum.l)2639 sprintf(loss, "%d", xr_stat.rx.stat_sum.lost);2640 else2641 sprintf(loss, "(na)");2642 2643 if (xr_stat.rx.stat_sum.d)2644 sprintf(dup, "%d", xr_stat.rx.stat_sum.dup);2645 else2646 sprintf(dup, "(na)");2647 2648 if (xr_stat.rx.stat_sum.j) {2649 unsigned jmin, jmax, jmean, jdev;2650 2651 SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min,2652 clock_rate);2653 SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max,2654 clock_rate);2655 SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean,2656 clock_rate);2657 SAMPLES_TO_USEC(jdev,2658 pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),2659 clock_rate);2660 sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",2661 jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);2662 } else2663 sprintf(jitter, "(report not available)");2664 2665 if (xr_stat.rx.stat_sum.t) {2666 sprintf(toh, "%11d %11d %11d %11d",2667 xr_stat.rx.stat_sum.toh.min,2668 xr_stat.rx.stat_sum.toh.mean,2669 xr_stat.rx.stat_sum.toh.max,2670 pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));2671 } else2672 sprintf(toh, "(report not available)");2673 2674 if (xr_stat.rx.stat_sum.update.sec == 0)2675 strcpy(last_update, "never");2676 else {2677 pj_gettimeofday(&now);2678 PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update);2679 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",2680 now.sec / 3600,2681 (now.sec % 3600) / 60,2682 now.sec % 60,2683 now.msec);2684 }2685 2686 len = pj_ansi_snprintf(p, end-p,2687 "%s RX last update: %s\n"2688 "%s begin seq=%d, end seq=%d\n"2689 "%s pkt loss=%s, dup=%s\n"2690 "%s (msec) min avg max dev\n"2691 "%s jitter : %s\n"2692 "%s toh : %s",2693 indent, last_update,2694 indent,2695 xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq,2696 indent, loss, dup,2697 indent,2698 indent, jitter,2699 indent, toh2700 );2701 VALIDATE_PRINT_BUF();2702 2703 if (xr_stat.tx.stat_sum.l)2704 sprintf(loss, "%d", xr_stat.tx.stat_sum.lost);2705 else2706 sprintf(loss, "(na)");2707 2708 if (xr_stat.tx.stat_sum.d)2709 sprintf(dup, "%d", xr_stat.tx.stat_sum.dup);2710 else2711 sprintf(dup, "(na)");2712 2713 if (xr_stat.tx.stat_sum.j) {2714 unsigned jmin, jmax, jmean, jdev;2715 2716 SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min,2717 clock_rate);2718 SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max,2719 clock_rate);2720 SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean,2721 clock_rate);2722 SAMPLES_TO_USEC(jdev,2723 pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),2724 clock_rate);2725 sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",2726 jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);2727 } else2728 sprintf(jitter, "(report not available)");2729 2730 if (xr_stat.tx.stat_sum.t) {2731 sprintf(toh, "%11d %11d %11d %11d",2732 xr_stat.tx.stat_sum.toh.min,2733 xr_stat.tx.stat_sum.toh.mean,2734 xr_stat.tx.stat_sum.toh.max,2735 pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));2736 } else2737 sprintf(toh, "(report not available)");2738 2739 if (xr_stat.tx.stat_sum.update.sec == 0)2740 strcpy(last_update, "never");2741 else {2742 pj_gettimeofday(&now);2743 PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update);2744 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",2745 now.sec / 3600,2746 (now.sec % 3600) / 60,2747 now.sec % 60,2748 now.msec);2749 }2750 2751 len = pj_ansi_snprintf(p, end-p,2752 "%s TX last update: %s\n"2753 "%s begin seq=%d, end seq=%d\n"2754 "%s pkt loss=%s, dup=%s\n"2755 "%s (msec) min avg max dev\n"2756 "%s jitter : %s\n"2757 "%s toh : %s",2758 indent, last_update,2759 indent,2760 xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq,2761 indent, loss, dup,2762 indent,2763 indent, jitter,2764 indent, toh2765 );2766 VALIDATE_PRINT_BUF();2767 2768 2769 /* VoIP Metrics */2770 len = pj_ansi_snprintf(p, end-p, "%s VoIP Metrics", indent);2771 VALIDATE_PRINT_BUF();2772 2773 PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl);2774 PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl);2775 PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl);2776 PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor);2777 PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor);2778 PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq);2779 PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq);2780 2781 switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) {2782 case PJMEDIA_RTCP_XR_PLC_DIS:2783 sprintf(plc, "DISABLED");2784 break;2785 case PJMEDIA_RTCP_XR_PLC_ENH:2786 sprintf(plc, "ENHANCED");2787 break;2788 case PJMEDIA_RTCP_XR_PLC_STD:2789 sprintf(plc, "STANDARD");2790 break;2791 case PJMEDIA_RTCP_XR_PLC_UNK:2792 default:2793 sprintf(plc, "UNKNOWN");2794 break;2795 }2796 2797 switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) {2798 case PJMEDIA_RTCP_XR_JB_FIXED:2799 sprintf(jba, "FIXED");2800 break;2801 case PJMEDIA_RTCP_XR_JB_ADAPTIVE:2802 sprintf(jba, "ADAPTIVE");2803 break;2804 default:2805 sprintf(jba, "UNKNOWN");2806 break;2807 }2808 2809 sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F);2810 2811 if (xr_stat.rx.voip_mtc.update.sec == 0)2812 strcpy(last_update, "never");2813 else {2814 pj_gettimeofday(&now);2815 PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update);2816 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",2817 now.sec / 3600,2818 (now.sec % 3600) / 60,2819 now.sec % 60,2820 now.msec);2821 }2822 2823 len = pj_ansi_snprintf(p, end-p,2824 "%s RX last update: %s\n"2825 "%s packets : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"2826 "%s burst : density=%d (%.2f%%), duration=%d%s\n"2827 "%s gap : density=%d (%.2f%%), duration=%d%s\n"2828 "%s delay : round trip=%d%s, end system=%d%s\n"2829 "%s level : signal=%s%s, noise=%s%s, RERL=%s%s\n"2830 "%s quality : R factor=%s, ext R factor=%s\n"2831 "%s MOS LQ=%s, MOS CQ=%s\n"2832 "%s config : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"2833 "%s JB delay : cur=%d%s, max=%d%s, abs max=%d%s",2834 indent,2835 last_update,2836 /* packets */2837 indent,2838 xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256,2839 xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256,2840 /* burst */2841 indent,2842 xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256,2843 xr_stat.rx.voip_mtc.burst_dur, "ms",2844 /* gap */2845 indent,2846 xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256,2847 xr_stat.rx.voip_mtc.gap_dur, "ms",2848 /* delay */2849 indent,2850 xr_stat.rx.voip_mtc.rnd_trip_delay, "ms",2851 xr_stat.rx.voip_mtc.end_sys_delay, "ms",2852 /* level */2853 indent,2854 signal_lvl, "dB",2855 noise_lvl, "dB",2856 rerl, "",2857 /* quality */2858 indent,2859 r_factor, ext_r_factor,2860 indent,2861 mos_lq, mos_cq,2862 /* config */2863 indent,2864 plc, jba, jbr, xr_stat.rx.voip_mtc.gmin,2865 /* JB delay */2866 indent,2867 xr_stat.rx.voip_mtc.jb_nom, "ms",2868 xr_stat.rx.voip_mtc.jb_max, "ms",2869 xr_stat.rx.voip_mtc.jb_abs_max, "ms"2870 );2871 VALIDATE_PRINT_BUF();2872 2873 PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl);2874 PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl);2875 PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl);2876 PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor);2877 PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor);2878 PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq);2879 PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq);2880 2881 switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) {2882 case PJMEDIA_RTCP_XR_PLC_DIS:2883 sprintf(plc, "DISABLED");2884 break;2885 case PJMEDIA_RTCP_XR_PLC_ENH:2886 sprintf(plc, "ENHANCED");2887 break;2888 case PJMEDIA_RTCP_XR_PLC_STD:2889 sprintf(plc, "STANDARD");2890 break;2891 case PJMEDIA_RTCP_XR_PLC_UNK:2892 default:2893 sprintf(plc, "unknown");2894 break;2895 }2896 2897 switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) {2898 case PJMEDIA_RTCP_XR_JB_FIXED:2899 sprintf(jba, "FIXED");2900 break;2901 case PJMEDIA_RTCP_XR_JB_ADAPTIVE:2902 sprintf(jba, "ADAPTIVE");2903 break;2904 default:2905 sprintf(jba, "unknown");2906 break;2907 }2908 2909 sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F);2910 2911 if (xr_stat.tx.voip_mtc.update.sec == 0)2912 strcpy(last_update, "never");2913 else {2914 pj_gettimeofday(&now);2915 PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update);2916 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",2917 now.sec / 3600,2918 (now.sec % 3600) / 60,2919 now.sec % 60,2920 now.msec);2921 }2922 2923 len = pj_ansi_snprintf(p, end-p,2924 "%s TX last update: %s\n"2925 "%s packets : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"2926 "%s burst : density=%d (%.2f%%), duration=%d%s\n"2927 "%s gap : density=%d (%.2f%%), duration=%d%s\n"2928 "%s delay : round trip=%d%s, end system=%d%s\n"2929 "%s level : signal=%s%s, noise=%s%s, RERL=%s%s\n"2930 "%s quality : R factor=%s, ext R factor=%s\n"2931 "%s MOS LQ=%s, MOS CQ=%s\n"2932 "%s config : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"2933 "%s JB delay : cur=%d%s, max=%d%s, abs max=%d%s",2934 indent,2935 last_update,2936 /* pakcets */2937 indent,2938 xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256,2939 xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256,2940 /* burst */2941 indent,2942 xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256,2943 xr_stat.tx.voip_mtc.burst_dur, "ms",2944 /* gap */2945 indent,2946 xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256,2947 xr_stat.tx.voip_mtc.gap_dur, "ms",2948 /* delay */2949 indent,2950 xr_stat.tx.voip_mtc.rnd_trip_delay, "ms",2951 xr_stat.tx.voip_mtc.end_sys_delay, "ms",2952 /* level */2953 indent,2954 signal_lvl, "dB",2955 noise_lvl, "dB",2956 rerl, "",2957 /* quality */2958 indent,2959 r_factor, ext_r_factor,2960 indent,2961 mos_lq, mos_cq,2962 /* config */2963 indent,2964 plc, jba, jbr, xr_stat.tx.voip_mtc.gmin,2965 /* JB delay */2966 indent,2967 xr_stat.tx.voip_mtc.jb_nom, "ms",2968 xr_stat.tx.voip_mtc.jb_max, "ms",2969 xr_stat.tx.voip_mtc.jb_abs_max, "ms"2970 );2971 VALIDATE_PRINT_BUF();2972 2973 2974 /* RTT delay (by receiver side) */2975 len = pj_ansi_snprintf(p, end-p,2976 "%s RTT (from recv) min avg max last dev",2977 indent);2978 VALIDATE_PRINT_BUF();2979 len = pj_ansi_snprintf(p, end-p,2980 "%s RTT msec : %7.3f %7.3f %7.3f %7.3f %7.3f",2981 indent,2982 xr_stat.rtt.min / 1000.0,2983 xr_stat.rtt.mean / 1000.0,2984 xr_stat.rtt.max / 1000.0,2985 xr_stat.rtt.last / 1000.0,2986 pj_math_stat_get_stddev(&xr_stat.rtt) / 1000.02987 );2988 VALIDATE_PRINT_BUF();2989 } /* if audio */;2990 #endif2991 2992 }2993 }2994 2995 2996 /* Print call info */2997 void print_call(const char *title,2998 int call_id,2999 char *buf, pj_size_t size)3000 {3001 int len;3002 pjsip_inv_session *inv = pjsua_var.calls[call_id].inv;3003 pjsip_dialog *dlg = inv->dlg;3004 char userinfo[128];3005 3006 /* Dump invite sesion info. */3007 3008 len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));3009 if (len < 0)3010 pj_ansi_strcpy(userinfo, "<--uri too long-->");3011 else3012 userinfo[len] = '\0';3013 3014 len = pj_ansi_snprintf(buf, size, "%s[%s] %s",3015 title,3016 pjsip_inv_state_name(inv->state),3017 userinfo);3018 if (len < 1 || len >= (int)size) {3019 pj_ansi_strcpy(buf, "<--uri too long-->");3020 len = 18;3021 } else3022 buf[len] = '\0';3023 }3024 3025 3026 /*3027 * Dump call and media statistics to string.3028 */3029 PJ_DEF(pj_status_t) pjsua_call_dump( pjsua_call_id call_id,3030 pj_bool_t with_media,3031 char *buffer,3032 unsigned maxlen,3033 const char *indent)3034 {3035 pjsua_call *call;3036 pjsip_dialog *dlg;3037 pj_time_val duration, res_delay, con_delay;3038 char tmp[128];3039 char *p, *end;3040 pj_status_t status;3041 int len;3042 3043 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,3044 PJ_EINVAL);3045 3046 status = acquire_call("pjsua_call_dump()", call_id, &call, &dlg);3047 if (status != PJ_SUCCESS)3048 return status;3049 3050 *buffer = '\0';3051 p = buffer;3052 end = buffer + maxlen;3053 len = 0;3054 3055 print_call(indent, call_id, tmp, sizeof(tmp));3056 3057 len = pj_ansi_strlen(tmp);3058 pj_ansi_strcpy(buffer, tmp);3059 3060 p += len;3061 *p++ = '\r';3062 *p++ = '\n';3063 3064 /* Calculate call duration */3065 if (call->conn_time.sec != 0) {3066 pj_gettimeofday(&duration);3067 PJ_TIME_VAL_SUB(duration, call->conn_time);3068 con_delay = call->conn_time;3069 PJ_TIME_VAL_SUB(con_delay, call->start_time);3070 } else {3071 duration.sec = duration.msec = 0;3072 con_delay.sec = con_delay.msec = 0;3073 }3074 3075 /* Calculate first response delay */3076 if (call->res_time.sec != 0) {3077 res_delay = call->res_time;3078 PJ_TIME_VAL_SUB(res_delay, call->start_time);3079 } else {3080 res_delay.sec = res_delay.msec = 0;3081 }3082 3083 /* Print duration */3084 len = pj_ansi_snprintf(p, end-p,3085 "%s Call time: %02dh:%02dm:%02ds, "3086 "1st res in %d ms, conn in %dms",3087 indent,3088 (int)(duration.sec / 3600),3089 (int)((duration.sec % 3600)/60),3090 (int)(duration.sec % 60),3091 (int)PJ_TIME_VAL_MSEC(res_delay),3092 (int)PJ_TIME_VAL_MSEC(con_delay));3093 3094 if (len > 0 && len < end-p) {3095 p += len;3096 *p++ = '\n';3097 *p = '\0';3098 }3099 3100 /* Dump session statistics */3101 if (with_media && pjsua_call_has_media(call_id))3102 dump_media_session(indent, p, end-p, call);3103 3104 pjsip_dlg_dec_lock(dlg);3105 3106 return PJ_SUCCESS;3107 }3108 2162 3109 2163 /* Proto */ -
pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_core.c
r3471 r3609 68 68 69 69 pjsua_config_default(&pjsua_var.ua_cfg); 70 71 for (i=0; i<PJSUA_MAX_VID_WINS; ++i) { 72 pjsua_vid_win_reset(i); 73 } 70 74 } 71 75 … … 176 180 cfg->ka_data = pj_str("\r\n"); 177 181 cfg->max_audio_cnt = 1; 182 cfg->vid_cap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; 183 cfg->vid_rend_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV; 178 184 pjsua_transport_config_default(&cfg->rtp_cfg); 179 185 cfg->use_srtp = pjsua_var.ua_cfg.use_srtp; -
pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c
r3579 r3609 276 276 #endif /* PJMEDIA_HAS_L16_CODEC */ 277 277 278 #if PJMEDIA_HAS_VIDEO279 status = pjmedia_video_format_mgr_create(pjsua_var.pool, 64, 0, NULL);280 if (status != PJ_SUCCESS) {281 pjsua_perror(THIS_FILE, "Error creating PJMEDIA video format manager",282 status);283 return status;284 }285 286 status = pjmedia_converter_mgr_create(pjsua_var.pool, NULL);287 if (status != PJ_SUCCESS) {288 pjsua_perror(THIS_FILE, "Error creating PJMEDIA converter manager",289 status);290 return status;291 }292 293 status = pjmedia_vid_codec_mgr_create(pjsua_var.pool, NULL);294 if (status != PJ_SUCCESS) {295 pjsua_perror(THIS_FILE, "Error creating PJMEDIA video codec manager",296 status);297 return status;298 }299 300 status = pjmedia_vid_dev_subsys_init(&pjsua_var.cp.factory);301 if (status != PJ_SUCCESS) {302 pjsua_perror(THIS_FILE, "Error creating PJMEDIA video subsystem",303 status);304 return status;305 }306 #endif307 308 #if PJMEDIA_HAS_VIDEO && PJMEDIA_HAS_FFMPEG_CODEC309 /* Init ffmpeg video codecs */310 status = pjmedia_codec_ffmpeg_init(NULL, &pjsua_var.cp.factory);311 if (status != PJ_SUCCESS) {312 pjsua_perror(THIS_FILE, "Error initializing ffmpeg library",313 status);314 return status;315 }316 #endif317 278 318 279 /* Save additional conference bridge parameters for future … … 337 298 } 338 299 339 340 300 /* Init conference bridge. */ 341 301 status = pjmedia_conf_create(pjsua_var.pool, … … 375 335 #endif 376 336 337 /* Video */ 338 #if PJMEDIA_HAS_VIDEO 339 status = pjsua_vid_subsys_init(); 340 if (status != PJ_SUCCESS) 341 return status; 342 #endif 343 377 344 return PJ_SUCCESS; 378 345 } … … 472 439 pj_timer_entry_init(&pjsua_var.snd_idle_timer, PJ_FALSE, NULL, 473 440 &close_snd_timer_cb); 441 442 /* Video */ 443 #if PJMEDIA_HAS_VIDEO 444 status = pjsua_vid_subsys_start(); 445 if (status != PJ_SUCCESS) 446 return status; 447 #endif 474 448 475 449 /* Perform NAT detection */ … … 539 513 if (pjsua_var.med_endpt) { 540 514 541 /* Videodev */542 515 # if PJMEDIA_HAS_VIDEO 543 pj media_vid_dev_subsys_shutdown();516 pjsua_vid_subsys_destroy(); 544 517 # endif 545 546 /* ffmpeg */547 # if PJMEDIA_HAS_VIDEO && PJMEDIA_HAS_FFMPEG_CODEC548 pjmedia_codec_ffmpeg_deinit();549 # endif550 551 518 /* Shutdown all codecs: */ 552 519 # if PJMEDIA_HAS_SPEEX_CODEC … … 3938 3905 3939 3906 3940 #if PJMEDIA_HAS_VIDEO3941 3942 /*****************************************************************************3943 * Video codecs.3944 */3945 3946 /*3947 * Enum all supported video codecs in the system.3948 */3949 PJ_DEF(pj_status_t) pjsua_vid_enum_codecs( pjsua_codec_info id[],3950 unsigned *p_count )3951 {3952 pjmedia_vid_codec_info info[32];3953 unsigned i, j, count, prio[32];3954 pj_status_t status;3955 3956 count = PJ_ARRAY_SIZE(info);3957 status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, prio);3958 if (status != PJ_SUCCESS) {3959 *p_count = 0;3960 return status;3961 }3962 3963 for (i=0, j=0; i<count && j<*p_count; ++i) {3964 if (info[i].has_rtp_pack) {3965 pj_bzero(&id[j], sizeof(pjsua_codec_info));3966 3967 pjmedia_vid_codec_info_to_id(&info[i], id[j].buf_, sizeof(id[j].buf_));3968 id[j].codec_id = pj_str(id[j].buf_);3969 id[j].priority = (pj_uint8_t) prio[i];3970 3971 if (id[j].codec_id.slen < sizeof(id[j].buf_)) {3972 id[j].desc.ptr = id[j].codec_id.ptr + id[j].codec_id.slen + 1;3973 pj_strncpy(&id[j].desc, &info[i].encoding_desc,3974 sizeof(id[j].buf_) - id[j].codec_id.slen - 1);3975 }3976 3977 ++j;3978 }3979 }3980 3981 *p_count = j;3982 3983 return PJ_SUCCESS;3984 }3985 3986 3987 /*3988 * Change video codec priority.3989 */3990 PJ_DEF(pj_status_t) pjsua_vid_codec_set_priority( const pj_str_t *codec_id,3991 pj_uint8_t priority )3992 {3993 const pj_str_t all = { NULL, 0 };3994 3995 if (codec_id->slen==1 && *codec_id->ptr=='*')3996 codec_id = &all;3997 3998 return pjmedia_vid_codec_mgr_set_codec_priority(NULL, codec_id,3999 priority);4000 }4001 4002 4003 /*4004 * Get video codec parameters.4005 */4006 PJ_DEF(pj_status_t) pjsua_vid_codec_get_param(4007 const pj_str_t *codec_id,4008 pjmedia_vid_codec_param *param)4009 {4010 const pj_str_t all = { NULL, 0 };4011 const pjmedia_vid_codec_info *info;4012 unsigned count = 1;4013 pj_status_t status;4014 4015 if (codec_id->slen==1 && *codec_id->ptr=='*')4016 codec_id = &all;4017 4018 status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, codec_id,4019 &count, &info, NULL);4020 if (status != PJ_SUCCESS)4021 return status;4022 4023 if (count != 1)4024 return (count > 1? PJ_ETOOMANY : PJ_ENOTFOUND);4025 4026 status = pjmedia_vid_codec_mgr_get_default_param(NULL, info, param);4027 return status;4028 }4029 4030 4031 /*4032 * Set video codec parameters.4033 */4034 PJ_DEF(pj_status_t) pjsua_vid_codec_set_param(4035 const pj_str_t *codec_id,4036 const pjmedia_vid_codec_param *param)4037 {4038 const pjmedia_vid_codec_info *info[2];4039 unsigned count = 2;4040 pj_status_t status;4041 4042 status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, codec_id,4043 &count, info, NULL);4044 if (status != PJ_SUCCESS)4045 return status;4046 4047 /* Codec ID should be specific */4048 if (count > 1) {4049 pj_assert(!"Codec ID is not specific");4050 return PJ_ETOOMANY;4051 }4052 4053 status = pjmedia_vid_codec_mgr_set_default_param(NULL, pjsua_var.pool,4054 info[0], param);4055 return status;4056 }4057 4058 4059 /*****************************************************************************4060 * Video devices.4061 */4062 4063 /*4064 * Enum all video devices installed in the system.4065 */4066 PJ_DEF(pj_status_t) pjsua_vid_enum_devs(pjmedia_vid_dev_info info[],4067 unsigned *count)4068 {4069 unsigned i, dev_count;4070 4071 dev_count = pjmedia_vid_dev_count();4072 4073 if (dev_count > *count) dev_count = *count;4074 4075 for (i=0; i<dev_count; ++i) {4076 pj_status_t status;4077 4078 status = pjmedia_vid_dev_get_info(i, &info[i]);4079 if (status != PJ_SUCCESS)4080 return status;4081 }4082 4083 *count = dev_count;4084 4085 return PJ_SUCCESS;4086 }4087 4088 4089 /*4090 * Get currently active video devices.4091 */4092 PJ_DEF(pj_status_t) pjsua_vid_get_dev(int *capture_dev, int *render_dev)4093 {4094 if (capture_dev)4095 *capture_dev = pjsua_var.vcap_dev;4096 if (render_dev)4097 *render_dev = pjsua_var.vrdr_dev;4098 4099 return PJ_SUCCESS;4100 }4101 4102 4103 /*4104 * Select video device for the next video sessions.4105 */4106 PJ_DEF(pj_status_t) pjsua_vid_set_dev(int capture_dev, int render_dev)4107 {4108 pjmedia_vid_dev_info info;4109 pj_status_t status;4110 4111 if (capture_dev < 0)4112 capture_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;4113 if (render_dev < 0)4114 render_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV;4115 4116 status = pjmedia_vid_dev_get_info(capture_dev, &info);4117 if (status != PJ_SUCCESS)4118 return status;4119 4120 status = pjmedia_vid_dev_get_info(render_dev, &info);4121 if (status != PJ_SUCCESS)4122 return status;4123 4124 pjsua_var.vcap_dev = capture_dev;4125 pjsua_var.vrdr_dev = render_dev;4126 4127 return PJ_SUCCESS;4128 }4129 4130 4131 /*4132 * Configure video device setting to the video device being used.4133 */4134 PJ_DEF(pj_status_t) pjsua_vid_set_setting(pjmedia_vid_dev_cap cap,4135 const void *pval,4136 pj_bool_t keep)4137 {4138 PJ_UNUSED_ARG(cap);4139 PJ_UNUSED_ARG(pval);4140 PJ_UNUSED_ARG(keep);4141 return PJ_ENOTSUP;4142 }4143 4144 4145 /*4146 * Retrieve a video device setting.4147 */4148 PJ_DEF(pj_status_t) pjsua_vid_get_setting(pjmedia_vid_dev_cap cap,4149 void *pval)4150 {4151 PJ_UNUSED_ARG(cap);4152 PJ_UNUSED_ARG(pval);4153 return PJ_ENOTSUP;4154 }4155 4156 #endif /* PJMEDIA_HAS_VIDEO */
Note: See TracChangeset
for help on using the changeset viewer.