Changeset 3758 for pjproject/trunk


Ignore:
Timestamp:
Sep 20, 2011 10:07:55 AM (13 years ago)
Author:
bennylp
Message:

Related to preview (re #1340): handle problems with starting or stopping preview during a call

Location:
pjproject/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev.h

    r3756 r3758  
    221221    pjmedia_dir dir; 
    222222 
    223     /** Specify whether the device supports callback */ 
     223    /** 
     224     * Specify whether the device supports callback. Devices that implement 
     225     * "active interface" will actively call the callbacks to give or ask for 
     226     * video frames. If the device doesn't support callback, application 
     227     * must actively request or give video frames from/to the device by using 
     228     * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame(). 
     229     */ 
    224230    pj_bool_t has_callback; 
    225231 
     
    642648 
    643649/** 
     650 * Query whether the stream has been started. 
     651 * 
     652 * @param strm      The video stream 
     653 * 
     654 * @return          PJ_TRUE if the video stream has been started. 
     655 */ 
     656PJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm); 
     657 
     658 
     659/** 
    644660 * Get the event publisher object for the video stream. Caller typically use 
    645661 * the returned object to subscribe or unsubscribe events from the video 
     
    653669pjmedia_vid_dev_stream_get_event_publisher(pjmedia_vid_dev_stream *strm); 
    654670 
    655 /* Get/put frame API for passive stream */ 
     671 
     672/** 
     673 * Request one frame from the stream. Application needs to call this function 
     674 * periodically only if the stream doesn't support "active interface", i.e. 
     675 * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE. 
     676 * 
     677 * @param strm      The video stream. 
     678 * @param frame     The video frame to be filled by the device. 
     679 * 
     680 * @return          PJ_SUCCESS on successful operation or the appropriate 
     681 *                  error code. 
     682 */ 
    656683PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame( 
    657684                                            pjmedia_vid_dev_stream *strm, 
    658685                                            pjmedia_frame *frame); 
    659686 
     687/** 
     688 * Put one frame to the stream. Application needs to call this function 
     689 * periodically only if the stream doesn't support "active interface", i.e. 
     690 * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE. 
     691 * 
     692 * @param strm      The video stream. 
     693 * @param frame     The video frame to put to the device. 
     694 * 
     695 * @return          PJ_SUCCESS on successful operation or the appropriate 
     696 *                  error code. 
     697 */ 
    660698PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame( 
    661699                                            pjmedia_vid_dev_stream *strm, 
  • pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev_imp.h

    r3715 r3758  
    182182        /** Driver index */ 
    183183        unsigned drv_idx; 
     184 
     185        /** Has it been started? */ 
     186        pj_bool_t is_running; 
    184187    } sys; 
    185188 
  • pjproject/trunk/pjmedia/include/pjmedia/vid_port.h

    r3715 r3758  
    214214 
    215215/** 
     216 * Query whether the video port has been started. 
     217 * 
     218 * @param vid_port      The video port. 
     219 * 
     220 * @return              PJ_TRUE if the video port has been started. 
     221 */ 
     222PJ_DECL(pj_bool_t) pjmedia_vid_port_is_running(pjmedia_vid_port *vid_port); 
     223 
     224/** 
    216225 * Stop the video port. 
    217226 * 
  • pjproject/trunk/pjmedia/src/pjmedia-videodev/videodev.c

    r3756 r3758  
    782782PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm) 
    783783{ 
    784     return strm->op->start(strm); 
     784    pj_status_t status = strm->op->start(strm); 
     785    if (status == PJ_SUCCESS) 
     786        strm->sys.is_running = PJ_TRUE; 
     787    return status; 
     788} 
     789 
     790/* API: has it been started? */ 
     791PJ_DEF(pj_bool_t) 
     792pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm) 
     793{ 
     794    return strm->sys.is_running; 
    785795} 
    786796 
     
    804814PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm) 
    805815{ 
     816    strm->sys.is_running = PJ_FALSE; 
    806817    return strm->op->stop(strm); 
    807818} 
     
    811822                                                pjmedia_vid_dev_stream *strm) 
    812823{ 
     824    strm->sys.is_running = PJ_FALSE; 
    813825    return strm->op->destroy(strm); 
    814826} 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_port.c

    r3723 r3758  
    478478    pjmedia_vid_port_stop(vp); 
    479479    return status; 
     480} 
     481 
     482PJ_DEF(pj_bool_t) pjmedia_vid_port_is_running(pjmedia_vid_port *vp) 
     483{ 
     484    return pjmedia_vid_dev_stream_is_running(vp->strm); 
    480485} 
    481486 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r3756 r3758  
    325325    pjmedia_port                *tee;           /**< Video tee          */ 
    326326    pjmedia_vid_dev_index        preview_cap_id;/**< Capture dev id     */ 
     327    pj_bool_t                    preview_running;/**< Preview is started*/ 
    327328    pj_bool_t                    is_native;     /**< Preview is by dev  */ 
    328329} pjsua_vid_win; 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c

    r3756 r3758  
    324324 */ 
    325325 
    326 /* 
    327  * Get the preview window handle associated with the capture device, if any. 
    328  */ 
    329 PJ_DEF(pjsua_vid_win_id) pjsua_vid_preview_get_win(pjmedia_vid_dev_index id) 
     326static pjsua_vid_win_id vid_preview_get_win(pjmedia_vid_dev_index id, 
     327                                            pj_bool_t running_only) 
    330328{ 
    331329    pjsua_vid_win_id wid = PJSUA_INVALID_ID; 
     
    348346        } 
    349347    } 
     348 
     349    if (wid != PJSUA_INVALID_ID && running_only) { 
     350        pjsua_vid_win *w = &pjsua_var.win[wid]; 
     351        wid = w->preview_running ? wid : PJSUA_INVALID_ID; 
     352    } 
     353 
    350354    PJSUA_UNLOCK(); 
    351355 
    352356    return wid; 
     357} 
     358 
     359/* 
     360 * NOTE: internal function don't use this!!! Use vid_preview_get_win() 
     361 *       instead. This is because this function will only return window ID 
     362 *       if preview is currently running. 
     363 */ 
     364PJ_DEF(pjsua_vid_win_id) pjsua_vid_preview_get_win(pjmedia_vid_dev_index id) 
     365{ 
     366    return vid_preview_get_win(id, PJ_TRUE); 
    353367} 
    354368 
     
    394408    /* If type is preview, check if it exists already */ 
    395409    if (type == PJSUA_WND_TYPE_PREVIEW) { 
    396         wid = pjsua_vid_preview_get_win(cap_id); 
     410        wid = vid_preview_get_win(cap_id, PJ_FALSE); 
    397411        if (wid != PJSUA_INVALID_ID) { 
    398412            /* Yes, it exists */ 
     
    421435            /* Done */ 
    422436            *id = wid; 
    423             PJ_LOG(4,(THIS_FILE, "Window already exist: %d", wid)); 
    424437            pj_log_pop_indent(); 
    425             return PJ_SUCCESS; 
     438 
     439            return status; 
    426440        } 
    427441    } 
     
    826840            } 
    827841 
    828             wid = pjsua_vid_preview_get_win(call_med->strm.v.cap_dev); 
     842            /* Note: calling pjsua_vid_preview_get_win() even though 
     843             * create_vid_win() will automatically create the window 
     844             * if it doesn't exist, because create_vid_win() will modify 
     845             * existing window SHOW/HIDE value. 
     846             */ 
     847            wid = vid_preview_get_win(call_med->strm.v.cap_dev, PJ_FALSE); 
    829848            if (wid == PJSUA_INVALID_ID) { 
    830849                /* Create preview video window */ 
     
    10431062 
    10441063    w = &pjsua_var.win[wid]; 
     1064    if (w->preview_running) { 
     1065        PJSUA_UNLOCK(); 
     1066        pj_log_pop_indent(); 
     1067        return PJ_SUCCESS; 
     1068    } 
    10451069 
    10461070    /* Start renderer, unless it's native preview */ 
    1047     if (!w->is_native) { 
     1071    if (w->is_native && !pjmedia_vid_port_is_running(w->vp_cap)) { 
     1072        pjmedia_vid_dev_stream *cap_dev; 
     1073        pj_bool_t enabled = PJ_TRUE; 
     1074 
     1075        cap_dev = pjmedia_vid_port_get_stream(w->vp_cap); 
     1076        status = pjmedia_vid_dev_stream_set_cap( 
     1077                        cap_dev, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW, 
     1078                        &enabled); 
     1079        if (status != PJ_SUCCESS) { 
     1080            PJ_PERROR(1,(THIS_FILE, status, 
     1081                         "Error activating native preview, falling back " 
     1082                         "to software preview..")); 
     1083            w->is_native = PJ_FALSE; 
     1084        } 
     1085    } 
     1086 
     1087    if (!w->is_native && !pjmedia_vid_port_is_running(w->vp_rend)) { 
    10481088        status = pjmedia_vid_port_start(w->vp_rend); 
    10491089        if (status != PJ_SUCCESS) { 
     
    10551095 
    10561096    /* Start capturer */ 
    1057     status = pjmedia_vid_port_start(w->vp_cap); 
    1058     if (status != PJ_SUCCESS) { 
    1059         PJSUA_UNLOCK(); 
    1060         pj_log_pop_indent(); 
    1061         return status; 
     1097    if (!pjmedia_vid_port_is_running(w->vp_cap)) { 
     1098        status = pjmedia_vid_port_start(w->vp_cap); 
     1099        if (status != PJ_SUCCESS) { 
     1100            PJSUA_UNLOCK(); 
     1101            pj_log_pop_indent(); 
     1102            return status; 
     1103        } 
    10621104    } 
    10631105 
    10641106    inc_vid_win(wid); 
     1107    w->preview_running = PJ_TRUE; 
    10651108 
    10661109    PJSUA_UNLOCK(); 
     
    10751118{ 
    10761119    pjsua_vid_win_id wid = PJSUA_INVALID_ID; 
    1077  
    1078     PJ_LOG(4,(THIS_FILE, "Stopping preview for cap_dev=%d", id)); 
    1079     pj_log_push_indent(); 
     1120    pjsua_vid_win *w; 
     1121    pj_status_t status; 
    10801122 
    10811123    PJSUA_LOCK(); 
     
    10871129    } 
    10881130 
    1089     dec_vid_win(wid); 
     1131    PJ_LOG(4,(THIS_FILE, "Stopping preview for cap_dev=%d", id)); 
     1132    pj_log_push_indent(); 
     1133 
     1134    w = &pjsua_var.win[wid]; 
     1135    if (w->preview_running) { 
     1136        if (w->is_native) { 
     1137            pjmedia_vid_dev_stream *cap_dev; 
     1138            pj_bool_t enabled = PJ_FALSE; 
     1139 
     1140            cap_dev = pjmedia_vid_port_get_stream(w->vp_cap); 
     1141            status = pjmedia_vid_dev_stream_set_cap( 
     1142                            cap_dev, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW, 
     1143                            &enabled); 
     1144        } else { 
     1145            status = pjmedia_vid_port_stop(w->vp_rend); 
     1146        } 
     1147 
     1148        if (status != PJ_SUCCESS) { 
     1149            PJ_PERROR(1,(THIS_FILE, status, "Error stopping %spreview", 
     1150                         (w->is_native ? "native " : ""))); 
     1151            PJSUA_UNLOCK(); 
     1152            pj_log_pop_indent(); 
     1153            return status; 
     1154        } 
     1155 
     1156        dec_vid_win(wid); 
     1157        w->preview_running = PJ_FALSE; 
     1158    } 
    10901159 
    10911160    PJSUA_UNLOCK(); 
     
    16741743    /* = Attach stream port to the new capture device = */ 
    16751744 
    1676     new_wid = pjsua_vid_preview_get_win(cap_dev); 
     1745    /* Note: calling pjsua_vid_preview_get_win() even though 
     1746     * create_vid_win() will automatically create the window 
     1747     * if it doesn't exist, because create_vid_win() will modify 
     1748     * existing window SHOW/HIDE value. 
     1749     */ 
     1750    new_wid = vid_preview_get_win(cap_dev, PJ_FALSE); 
    16771751    if (new_wid == PJSUA_INVALID_ID) { 
    16781752        /* Create preview video window */ 
Note: See TracChangeset for help on using the changeset viewer.