Ignore:
Timestamp:
Apr 1, 2019 7:28:24 AM (6 years ago)
Author:
ming
Message:

Re #2187: Delay the creation of video capture until it is needed

Also in this commit: add PJSUA_LOCK() and UNLOCK() around access of pjsua_vid_win

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c

    r5961 r5962  
    250250{ 
    251251    pj_status_t status = PJ_SUCCESS; 
    252     pjsua_vid_win_id wid = vid_preview_get_win(id, PJ_FALSE); 
     252    pjsua_vid_win_id wid; 
    253253     
     254    PJSUA_LOCK(); 
     255    wid = vid_preview_get_win(id, PJ_FALSE); 
    254256    if (wid != PJSUA_INVALID_ID) { 
    255257        pjsua_vid_win *w; 
     
    260262 
    261263        status = pjmedia_vid_dev_stream_set_cap(cap_dev, cap, pval); 
    262         if (status != PJ_SUCCESS) 
     264        if (status != PJ_SUCCESS) { 
     265            PJSUA_UNLOCK(); 
    263266            return status; 
     267        } 
    264268    } else { 
    265269        status = PJ_ENOTFOUND; 
    266270    } 
     271    PJSUA_UNLOCK(); 
    267272 
    268273    if (keep) { 
     
    293298{ 
    294299    pj_status_t status = PJ_SUCCESS; 
    295     pjsua_vid_win_id wid = vid_preview_get_win(id, PJ_FALSE); 
     300    pjsua_vid_win_id wid; 
    296301     
     302    PJSUA_LOCK(); 
     303    wid = vid_preview_get_win(id, PJ_FALSE);     
    297304    if (wid != PJSUA_INVALID_ID) { 
    298305        pjsua_vid_win *w; 
     
    303310 
    304311        status = pjmedia_vid_dev_stream_get_cap(cap_dev, cap, pval); 
     312         
     313        PJSUA_UNLOCK(); 
    305314    } else { 
    306315        pjmedia_vid_dev_info info; 
    307              
     316         
     317        PJSUA_UNLOCK(); 
     318 
    308319        status = pjmedia_vid_dev_get_info(id, &info); 
    309320        if (status != PJ_SUCCESS) 
     
    535546    pjsua_vid_win_id wid; 
    536547    pjsua_vid_win *w; 
    537  
     548    pjsua_conf_port_id conf_id = PJSUA_INVALID_ID; 
     549 
     550    PJSUA_LOCK(); 
    538551    wid = vid_preview_get_win(id, PJ_TRUE); 
    539     if (wid == PJSUA_INVALID_ID) 
    540         return PJSUA_INVALID_ID; 
    541  
    542     w = &pjsua_var.win[wid]; 
    543     return w->cap_slot; 
    544 } 
    545  
    546  
    547 PJ_DEF(void) pjsua_vid_win_reset(pjsua_vid_win_id wid) 
     552    if (wid != PJSUA_INVALID_ID) { 
     553        w = &pjsua_var.win[wid]; 
     554        conf_id = w->cap_slot; 
     555    } 
     556    PJSUA_UNLOCK(); 
     557     
     558    return conf_id; 
     559} 
     560 
     561 
     562void pjsua_vid_win_reset(pjsua_vid_win_id wid) 
    548563{ 
    549564    pjsua_vid_win *w = &pjsua_var.win[wid]; 
     
    896911} 
    897912 
     913static pj_status_t setup_vid_capture(pjsua_call_media *call_med) 
     914{ 
     915    pjsua_acc *acc_enc = &pjsua_var.acc[call_med->call->acc_id]; 
     916    pjmedia_port *media_port; 
     917    pjsua_vid_win *w; 
     918    pjsua_vid_win_id wid; 
     919    pj_bool_t just_created = PJ_FALSE; 
     920    pj_status_t status; 
     921 
     922    /* Retrieve stream encoding port */ 
     923    status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 
     924                                         PJMEDIA_DIR_ENCODING, 
     925                                         &media_port); 
     926    if (status != PJ_SUCCESS) 
     927        return status; 
     928 
     929    PJSUA_LOCK(); 
     930 
     931    /* Note: calling pjsua_vid_preview_get_win() even though 
     932     * create_vid_win() will automatically create the window 
     933     * if it doesn't exist, because create_vid_win() will modify 
     934     * existing window SHOW/HIDE value. 
     935     */ 
     936    wid = vid_preview_get_win(call_med->strm.v.cap_dev, PJ_FALSE); 
     937    if (wid == PJSUA_INVALID_ID) { 
     938        /* Create preview video window */ 
     939        status = create_vid_win(PJSUA_WND_TYPE_PREVIEW, 
     940                                &media_port->info.fmt, 
     941                                call_med->strm.v.rdr_dev, 
     942                                call_med->strm.v.cap_dev, 
     943                                PJSUA_HIDE_WINDOW, 
     944                                acc_enc->cfg.vid_wnd_flags, 
     945                                NULL, 
     946                                &wid); 
     947        if (status != PJ_SUCCESS) 
     948            goto on_error; 
     949 
     950        just_created = PJ_TRUE; 
     951    } 
     952 
     953    w = &pjsua_var.win[wid]; 
     954#if ENABLE_EVENT 
     955    pjmedia_event_subscribe(NULL, &call_media_on_event, 
     956                            call_med, w->vp_cap); 
     957#endif 
     958 
     959    /* Connect capturer to stream encoding (via conf) */ 
     960    status = pjsua_vid_conf_connect(w->cap_slot, 
     961                                    call_med->strm.v.strm_enc_slot, 
     962                                    NULL); 
     963    if (status != PJ_SUCCESS) 
     964        goto on_error; 
     965 
     966    /* Start capturer */ 
     967    if (just_created) { 
     968        status = pjmedia_vid_port_start(w->vp_cap); 
     969        if (status != PJ_SUCCESS) 
     970            goto on_error; 
     971    } 
     972 
     973    /* Done */ 
     974    inc_vid_win(wid); 
     975    call_med->strm.v.cap_win_id = wid; 
     976 
     977    PJSUA_UNLOCK(); 
     978 
     979    return PJ_SUCCESS; 
     980 
     981on_error: 
     982    PJSUA_UNLOCK(); 
     983    return status; 
     984} 
     985 
    898986/* Internal function: update video channel after SDP negotiation. 
    899987 * Warning: do not use temporary/flip-flop pool, e.g: inv->pool_prov, 
     
    10211109 
    10221110            /* Create stream video window */ 
     1111            PJSUA_LOCK(); 
    10231112            status = create_vid_win(PJSUA_WND_TYPE_STREAM, 
    10241113                                    &media_port->info.fmt, 
     
    10311120                                    &wid); 
    10321121            if (status != PJ_SUCCESS) { 
     1122                PJSUA_UNLOCK(); 
    10331123                pj_log_pop_indent(); 
    10341124                goto on_error; 
     
    10521142                                             &call_med->strm.v.strm_dec_slot); 
    10531143            if (status != PJ_SUCCESS) { 
     1144                PJSUA_UNLOCK(); 
    10541145                pj_log_pop_indent(); 
    10551146                goto on_error; 
     
    10601151                                            w->rend_slot, NULL); 
    10611152            if (status != PJ_SUCCESS) { 
     1153                PJSUA_UNLOCK(); 
    10621154                pj_log_pop_indent(); 
    10631155                goto on_error; 
     
    10671159            status = pjmedia_vid_port_start(w->vp_rend); 
    10681160            if (status != PJ_SUCCESS) { 
     1161                PJSUA_UNLOCK(); 
    10691162                pj_log_pop_indent(); 
    10701163                goto on_error; 
     
    10741167            inc_vid_win(wid); 
    10751168            call_med->strm.v.rdr_win_id = wid; 
     1169            PJSUA_UNLOCK(); 
    10761170            pj_log_pop_indent(); 
    10771171        } 
    10781172 
    10791173        /* Setup encoding direction */ 
    1080         if (si->dir & PJMEDIA_DIR_ENCODING && !call->local_hold) 
    1081         { 
    1082             pjsua_acc *acc_enc = &pjsua_var.acc[call_med->call->acc_id]; 
    1083             pjsua_vid_win *w; 
    1084             pjsua_vid_win_id wid; 
    1085             pj_bool_t just_created = PJ_FALSE; 
    1086  
     1174        if (si->dir & PJMEDIA_DIR_ENCODING) { 
    10871175            PJ_LOG(4,(THIS_FILE, "Setting up TX..")); 
    10881176            pj_log_push_indent(); 
     
    10921180                                                 PJMEDIA_DIR_ENCODING, 
    10931181                                                 &media_port); 
    1094             if (status != PJ_SUCCESS) { 
    1095                 pj_log_pop_indent(); 
     1182            if (status != PJ_SUCCESS) 
    10961183                goto on_error; 
    1097             } 
    1098  
    1099             /* Note: calling pjsua_vid_preview_get_win() even though 
    1100              * create_vid_win() will automatically create the window 
    1101              * if it doesn't exist, because create_vid_win() will modify 
    1102              * existing window SHOW/HIDE value. 
    1103              */ 
    1104             wid = vid_preview_get_win(call_med->strm.v.cap_dev, PJ_FALSE); 
    1105             if (wid == PJSUA_INVALID_ID) { 
    1106                 /* Create preview video window */ 
    1107                 status = create_vid_win(PJSUA_WND_TYPE_PREVIEW, 
    1108                                         &media_port->info.fmt, 
    1109                                         call_med->strm.v.rdr_dev, 
    1110                                         call_med->strm.v.cap_dev, 
    1111                                         PJSUA_HIDE_WINDOW, 
    1112                                         acc_enc->cfg.vid_wnd_flags, 
    1113                                         NULL, 
    1114                                         &wid); 
    1115                 if (status != PJ_SUCCESS) { 
    1116                 pj_log_pop_indent(); 
    1117                     return status; 
    1118                 } 
    1119                 just_created = PJ_TRUE; 
    1120             } 
    1121  
    1122             w = &pjsua_var.win[wid]; 
    1123 #if ENABLE_EVENT 
    1124             pjmedia_event_subscribe(NULL, &call_media_on_event, 
    1125                                     call_med, w->vp_cap); 
    1126 #endif 
    1127              
     1184 
    11281185            /* Register stream encoding to conf, using tmp_pool should be fine 
    11291186             * as bridge will create its own pool (using tmp_pool factory). 
     
    11311188            status = pjsua_vid_conf_add_port(tmp_pool, media_port, NULL, 
    11321189                                             &call_med->strm.v.strm_enc_slot); 
    1133             if (status != PJ_SUCCESS) { 
    1134                 pj_log_pop_indent(); 
    1135                 goto on_error; 
    1136             } 
    1137  
    1138             /* Connect capturer to stream encoding (via conf) */ 
    1139             status = pjsua_vid_conf_connect(w->cap_slot, 
    1140                                             call_med->strm.v.strm_enc_slot, 
    1141                                             NULL); 
    1142             if (status != PJ_SUCCESS) { 
    1143                 pj_log_pop_indent(); 
    1144                 goto on_error; 
    1145             } 
    1146  
    1147             /* Start capturer */ 
    1148             if (just_created && acc->cfg.vid_out_auto_transmit) { 
    1149                 status = pjmedia_vid_port_start(w->vp_cap); 
    1150                 if (status != PJ_SUCCESS) { 
    1151                     pj_log_pop_indent(); 
    1152                     goto on_error; 
    1153                 } 
    1154                 w->cap_started = PJ_TRUE; 
    1155             } 
    1156  
    1157             /* Done */ 
    1158             inc_vid_win(wid); 
    1159             call_med->strm.v.cap_win_id = wid; 
    1160             pj_log_pop_indent(); 
    1161  
    1162         } else if (si->dir & PJMEDIA_DIR_ENCODING && call->local_hold) { 
    1163             /* This is similar as above, but we are on local hold. So 
    1164              * we just get the stream encoding port and add it to the 
    1165              * video conference, in order for the stream to be able to 
    1166              * keep sending keep-alive. 
    1167              */ 
    1168             PJ_LOG(4,(THIS_FILE, "Setting up TX..")); 
    1169  
    1170             status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 
    1171                                                  PJMEDIA_DIR_ENCODING, 
    1172                                                  &media_port); 
    11731190            if (status != PJ_SUCCESS) 
    11741191                goto on_error; 
    11751192 
    1176             status = pjsua_vid_conf_add_port(tmp_pool, media_port, NULL, 
    1177                                              &call_med->strm.v.strm_enc_slot); 
    1178             if (status != PJ_SUCCESS) 
    1179                 goto on_error; 
    1180         } 
    1181  
     1193            if (!call->local_hold && acc->cfg.vid_out_auto_transmit) { 
     1194                status = setup_vid_capture(call_med); 
     1195                if (status != PJ_SUCCESS) 
     1196                    goto on_error; 
     1197            } 
     1198 
     1199            pj_log_pop_indent(); 
     1200        } 
    11821201    } 
    11831202 
     
    12241243    pjmedia_vid_stream_send_rtcp_bye(strm); 
    12251244 
     1245    PJSUA_LOCK(); 
    12261246    if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) { 
    12271247        pjsua_vid_win *w = &pjsua_var.win[call_med->strm.v.cap_win_id]; 
     
    12481268        call_med->strm.v.rdr_win_id = PJSUA_INVALID_ID; 
    12491269    } 
     1270    PJSUA_UNLOCK(); 
    12501271 
    12511272    if ((call_med->dir & PJMEDIA_DIR_ENCODING) && 
     
    21032124 
    21042125    /* == Apply the new capture device == */ 
    2105  
     2126    PJSUA_LOCK(); 
    21062127    wid = call_med->strm.v.cap_win_id; 
    21072128    w = &pjsua_var.win[wid]; 
     
    21182139        w->preview_cap_id = cap_dev; 
    21192140        call_med->strm.v.cap_dev = cap_dev; 
     2141 
     2142        PJSUA_UNLOCK(); 
    21202143        /* Yay, change capturer done! */ 
    21212144        return PJ_SUCCESS; 
     
    21272150    status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 
    21282151                                         PJMEDIA_DIR_ENCODING, &media_port); 
    2129     if (status != PJ_SUCCESS) 
     2152    if (status != PJ_SUCCESS) { 
     2153        PJSUA_UNLOCK(); 
    21302154        return status; 
     2155    } 
    21312156 
    21322157    pjmedia_event_unsubscribe(NULL, &call_media_on_event, call_med, 
     
    21362161    status = pjsua_vid_conf_disconnect(w->cap_slot, 
    21372162                                       call_med->strm.v.strm_enc_slot); 
    2138     if (status != PJ_SUCCESS) 
     2163    if (status != PJ_SUCCESS) { 
     2164        PJSUA_UNLOCK(); 
    21392165        return status; 
     2166    } 
    21402167 
    21412168 
     
    21972224    call_med->strm.v.cap_win_id = new_wid; 
    21982225    dec_vid_win(wid); 
     2226     
     2227    PJSUA_UNLOCK(); 
    21992228 
    22002229    return PJ_SUCCESS; 
     
    22172246    status = pjsua_vid_conf_connect(w->cap_slot, 
    22182247                                    call_med->strm.v.strm_enc_slot, NULL); 
    2219     if (status != PJ_SUCCESS) 
     2248    if (status != PJ_SUCCESS) { 
     2249        PJSUA_UNLOCK(); 
    22202250        return status; 
     2251    } 
    22212252 
    22222253#if ENABLE_EVENT 
     
    22252256                            call_med, w->vp_cap); 
    22262257#endif 
     2258 
     2259    PJSUA_UNLOCK(); 
    22272260 
    22282261    return status; 
     
    22592292 
    22602293    if (enable) { 
    2261         pjsua_vid_win *w; 
    2262         pjsua_vid_win_id wid; 
    2263  
    2264         wid = vid_preview_get_win(call_med->strm.v.cap_dev, PJ_FALSE); 
    2265         pj_assert(wid != PJSUA_INVALID_ID); 
    2266  
    2267         w = &pjsua_var.win[wid]; 
    2268  
    2269         if (!w->cap_started) { 
    2270             /* Start the video capture first */ 
    2271             status = pjmedia_vid_port_start(w->vp_cap); 
     2294        if (call_med->strm.v.cap_win_id == PJSUA_INVALID_ID) { 
     2295            /* Setup the video capture first */ 
     2296            status = setup_vid_capture(call_med); 
    22722297            if (status != PJ_SUCCESS) 
    22732298                return status; 
    2274             w->cap_started = PJ_TRUE; 
    22752299        } 
    22762300         
     
    22792303                                           PJMEDIA_DIR_ENCODING); 
    22802304    } else { 
     2305        pjsua_vid_win_id wid; 
     2306        pjsua_vid_win *w; 
     2307 
    22812308        /* Pause stream in encoding direction */ 
    22822309        status = pjmedia_vid_stream_pause( call_med->strm.v.stream, 
    22832310                                           PJMEDIA_DIR_ENCODING); 
     2311         
     2312        PJSUA_LOCK(); 
     2313         
     2314        wid = vid_preview_get_win(call_med->strm.v.cap_dev, PJ_FALSE); 
     2315        if (wid != PJSUA_INVALID_ID) { 
     2316            w = &pjsua_var.win[wid]; 
     2317 
     2318            /* Unsubscribe event */ 
     2319            pjmedia_event_unsubscribe(NULL, &call_media_on_event, call_med, 
     2320                                      w->vp_cap); 
     2321 
     2322            /* Disconnect from video conference */ 
     2323            pjsua_vid_conf_disconnect(w->cap_slot, 
     2324                                      call_med->strm.v.strm_enc_slot); 
     2325 
     2326            /* Decrement ref count of the video window */ 
     2327            dec_vid_win(call_med->strm.v.cap_win_id); 
     2328            call_med->strm.v.cap_win_id = PJSUA_INVALID_ID; 
     2329        } 
     2330         
     2331        PJSUA_UNLOCK(); 
    22842332    } 
    22852333 
Note: See TracChangeset for help on using the changeset viewer.