Changeset 3592


Ignore:
Timestamp:
Jun 21, 2011 9:33:01 AM (9 years ago)
Author:
ming
Message:

Re #1312: Support for refreshing video device list
Add pjmedia-videodev API: pjmedia_vid_dev_refresh() and its implementation for Windows and Linux.

Location:
pjproject/branches/projects/2.0-dev/pjmedia
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h

    r3590 r3592  
    446446 
    447447/** 
     448 * Refresh the list of video devices installed in the system. This function 
     449 * will only refresh the list of videoo device so all active video streams will 
     450 * be unaffected. After refreshing the device list, application MUST make sure 
     451 * to update all index references to video devices (i.e. all variables of type 
     452 * pjmedia_vid_dev_index) before calling any function that accepts video device 
     453 * index as its parameter. 
     454 * 
     455 * @return              PJ_SUCCESS on successful operation or the appropriate 
     456 *                      error code. 
     457 */ 
     458PJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void); 
     459 
     460 
     461/** 
    448462 * Get the number of video devices installed in the system. 
    449463 * 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h

    r3489 r3592  
    9191                                 void *user_data, 
    9292                                 pjmedia_vid_dev_stream **p_vid_strm); 
     93 
     94    /** 
     95     * Refresh the list of video devices installed in the system. 
     96     * 
     97     * @param f         The video device factory. 
     98     */ 
     99    pj_status_t (*refresh)(pjmedia_vid_dev_factory *f); 
    93100 
    94101} pjmedia_vid_dev_factory_op; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c

    r3580 r3592  
    100100static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f); 
    101101static pj_status_t cbar_factory_destroy(pjmedia_vid_dev_factory *f); 
     102static pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f);  
    102103static unsigned    cbar_factory_get_dev_count(pjmedia_vid_dev_factory *f); 
    103104static pj_status_t cbar_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
     
    137138    &cbar_factory_get_dev_info, 
    138139    &cbar_factory_default_param, 
    139     &cbar_factory_create_stream 
     140    &cbar_factory_create_stream, 
     141    &cbar_factory_refresh 
    140142}; 
    141143 
     
    226228    pj_pool_release(pool); 
    227229 
     230    return PJ_SUCCESS; 
     231} 
     232 
     233/* API: refresh the list of devices */ 
     234static pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f) 
     235{ 
     236    PJ_UNUSED_ARG(f); 
    228237    return PJ_SUCCESS; 
    229238} 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c

    r3582 r3592  
    8383    pjmedia_vid_dev_factory      base; 
    8484    pj_pool_t                   *pool; 
     85    pj_pool_t                   *dev_pool; 
    8586    pj_pool_factory             *pf; 
    8687 
     
    124125static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f); 
    125126static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f); 
     127static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f); 
    126128static unsigned    dshow_factory_get_dev_count(pjmedia_vid_dev_factory *f); 
    127129static pj_status_t dshow_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
     
    161163    &dshow_factory_get_dev_info, 
    162164    &dshow_factory_default_param, 
    163     &dshow_factory_create_stream 
     165    &dshow_factory_create_stream, 
     166    &dshow_factory_refresh 
    164167}; 
    165168 
     
    200203static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f) 
    201204{ 
     205    CoInitializeEx(NULL, COINIT_MULTITHREADED); 
     206 
     207    return dshow_factory_refresh(f); 
     208} 
     209 
     210/* API: destroy factory */ 
     211static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f) 
     212{ 
     213    struct dshow_factory *df = (struct dshow_factory*)f; 
     214    pj_pool_t *pool = df->pool; 
     215 
     216    df->pool = NULL; 
     217    if (df->dev_pool) 
     218        pj_pool_release(df->dev_pool); 
     219    if (pool) 
     220        pj_pool_release(pool); 
     221 
     222    CoUninitialize(); 
     223 
     224    return PJ_SUCCESS; 
     225} 
     226 
     227/* API: refresh the list of devices */ 
     228static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f) 
     229{ 
    202230    struct dshow_factory *df = (struct dshow_factory*)f; 
    203231    struct dshow_dev_info *ddi; 
     
    210238    ULONG fetched; 
    211239 
     240    if (df->dev_pool) { 
     241        pj_pool_release(df->dev_pool); 
     242        df->dev_pool = NULL; 
     243    } 
     244 
    212245    df->dev_count = 0; 
    213  
    214     CoInitializeEx(NULL, COINIT_MULTITHREADED); 
     246    df->dev_pool = pj_pool_create(df->pf, "dshow video", 500, 500, NULL); 
    215247 
    216248    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, 
     
    234266    dev_count += 1; 
    235267    df->dev_info = (struct dshow_dev_info*) 
    236                    pj_pool_calloc(df->pool, dev_count, 
     268                   pj_pool_calloc(df->dev_pool, dev_count, 
    237269                                  sizeof(struct dshow_dev_info)); 
    238270 
     
    305337        ddi->info.fmt_cnt = sizeof(dshow_fmts)/sizeof(dshow_fmts[0]); 
    306338        ddi->info.fmt = (pjmedia_format*) 
    307                         pj_pool_calloc(df->pool, ddi->info.fmt_cnt, 
     339                        pj_pool_calloc(df->dev_pool, ddi->info.fmt_cnt, 
    308340                                       sizeof(pjmedia_format)); 
    309341 
     
    322354//    ddi->info.caps = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW; 
    323355 
    324     PJ_LOG(4, (THIS_FILE, "DShow initialized, found %d devices:",  
     356    PJ_LOG(4, (THIS_FILE, "DShow has %d devices:",  
    325357               df->dev_count)); 
    326358    for (c = 0; c < df->dev_count; ++c) { 
     
    331363               "capture" : "render")); 
    332364    } 
    333  
    334     return PJ_SUCCESS; 
    335 } 
    336  
    337 /* API: destroy factory */ 
    338 static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f) 
    339 { 
    340     struct dshow_factory *df = (struct dshow_factory*)f; 
    341     pj_pool_t *pool = df->pool; 
    342  
    343     df->pool = NULL; 
    344     pj_pool_release(pool); 
    345  
    346     CoUninitialize(); 
    347365 
    348366    return PJ_SUCCESS; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c

    r3489 r3592  
    6161    pj_pool_factory             *pf; 
    6262    pj_pool_t                   *pool; 
     63    pj_pool_t                   *dev_pool; 
    6364    unsigned                     dev_count; 
    6465    ffmpeg_dev_info              dev_info[MAX_DEV_CNT]; 
     
    7980static pj_status_t ffmpeg_factory_init(pjmedia_vid_dev_factory *f); 
    8081static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f); 
     82static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f); 
    8183static unsigned    ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f); 
    8284static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
     
    116118    &ffmpeg_factory_get_dev_info, 
    117119    &ffmpeg_factory_default_param, 
    118     &ffmpeg_factory_create_stream 
     120    &ffmpeg_factory_create_stream, 
     121    &ffmpeg_factory_refresh 
    119122}; 
    120123 
     
    220223static pj_status_t ffmpeg_factory_init(pjmedia_vid_dev_factory *f) 
    221224{ 
     225    return ffmpeg_factory_refresh(f); 
     226} 
     227 
     228/* API: destroy factory */ 
     229static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f) 
     230{ 
     231    ffmpeg_factory *ff = (ffmpeg_factory*)f; 
     232    pj_pool_t *pool = ff->pool; 
     233 
     234    ff->dev_count = 0; 
     235    ff->pool = NULL; 
     236    if (ff->dev_pool) 
     237        pj_pool_release(ff->dev_pool); 
     238    if (pool) 
     239        pj_pool_release(pool); 
     240 
     241    return PJ_SUCCESS; 
     242} 
     243 
     244/* API: refresh the list of devices */ 
     245static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f) 
     246{ 
    222247    ffmpeg_factory *ff = (ffmpeg_factory*)f; 
    223248    AVInputFormat *p; 
     
    227252    av_log_set_level(AV_LOG_DEBUG); 
    228253 
     254    if (ff->dev_pool) { 
     255        pj_pool_release(ff->dev_pool); 
     256        ff->dev_pool = NULL; 
     257    } 
     258 
    229259    /* TODO: this should enumerate devices, now it enumerates host APIs */ 
    230260    ff->dev_count = 0; 
     261    ff->dev_pool = pj_pool_create(ff->pf, "ffmpeg_cap_dev", 500, 500, NULL); 
     262 
    231263    p = av_iformat_next(NULL); 
    232264    while (p) { 
     
    255287            info->base.fmt_cnt = 1; 
    256288            info->base.fmt = (pjmedia_format*) 
    257                              pj_pool_calloc(ff->pool, info->base.fmt_cnt, 
     289                             pj_pool_calloc(ff->dev_pool, info->base.fmt_cnt, 
    258290                                            sizeof(pjmedia_format)); 
    259291            for (i = 0; i < info->base.fmt_cnt; ++i) { 
     
    271303} 
    272304 
    273 /* API: destroy factory */ 
    274 static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f) 
    275 { 
    276     ffmpeg_factory *ff = (ffmpeg_factory*)f; 
    277  
    278     ff->dev_count = 0; 
    279  
    280     return PJ_SUCCESS; 
    281 } 
    282  
    283305/* API: get number of devices */ 
    284306static unsigned ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f) 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c

    r3590 r3592  
    186186static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f); 
    187187static pj_status_t sdl_factory_destroy(pjmedia_vid_dev_factory *f); 
     188static pj_status_t sdl_factory_refresh(pjmedia_vid_dev_factory *f); 
    188189static unsigned    sdl_factory_get_dev_count(pjmedia_vid_dev_factory *f); 
    189190static pj_status_t sdl_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
     
    227228    &sdl_factory_get_dev_info, 
    228229    &sdl_factory_default_param, 
    229     &sdl_factory_create_stream 
     230    &sdl_factory_create_stream, 
     231    &sdl_factory_refresh 
    230232}; 
    231233 
     
    354356#endif 
    355357 
     358    return PJ_SUCCESS; 
     359} 
     360 
     361/* API: refresh the list of devices */ 
     362static pj_status_t sdl_factory_refresh(pjmedia_vid_dev_factory *f) 
     363{ 
     364    PJ_UNUSED_ARG(f); 
    356365    return PJ_SUCCESS; 
    357366} 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/v4l2_dev.c

    r3580 r3592  
    8282    pjmedia_vid_dev_factory      base; 
    8383    pj_pool_t                   *pool; 
     84    pj_pool_t                   *dev_pool; 
    8485    pj_pool_factory             *pf; 
    8586 
     
    120121static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f); 
    121122static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f); 
     123static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f); 
    122124static unsigned    vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f); 
    123125static pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
     
    156158    &vid4lin_factory_get_dev_info, 
    157159    &vid4lin_factory_default_param, 
    158     &vid4lin_factory_create_stream 
     160    &vid4lin_factory_create_stream, 
     161    &vid4lin_factory_refresh 
    159162}; 
    160163 
     
    213216    pj_status_t status; 
    214217 
     218    if (f->dev_pool) { 
     219        pj_pool_release(f->dev_pool); 
     220        f->dev_pool = NULL; 
     221    } 
     222 
    215223    pj_bzero(vdi, sizeof(vdi)); 
    216224    old_count = f->dev_count; 
    217225    f->dev_count = 0; 
     226    f->dev_pool = pj_pool_create(f->pf, DRIVER_NAME, 500, 500, NULL); 
    218227 
    219228    for (i=0; i<V4L2_MAX_DEVS && f->dev_count < V4L2_MAX_DEVS; ++i) { 
    220229        int fd; 
    221230        vid4lin_dev_info *pdi; 
    222         pj_pool_t *pool = f->pool; 
     231        pj_pool_t *pool = f->dev_pool; 
    223232        pj_uint32_t fmt_cap[8]; 
    224233        int j, fmt_cnt=0; 
     
    313322    if (f->dev_count > old_count || f->dev_info == NULL) { 
    314323        f->dev_info = (vid4lin_dev_info*) 
    315                       pj_pool_calloc(f->pool, 
     324                      pj_pool_calloc(f->dev_pool, 
    316325                                     f->dev_count, 
    317326                                     sizeof(vid4lin_dev_info)); 
     
    325334/* API: init factory */ 
    326335static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f) 
     336{ 
     337    return vid4lin_factory_refresh(f); 
     338} 
     339 
     340/* API: destroy factory */ 
     341static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f) 
     342{ 
     343    vid4lin_factory *cf = (vid4lin_factory*)f; 
     344    pj_pool_t *pool = cf->pool; 
     345 
     346    if (cf->dev_pool) 
     347        pj_pool_release(cf->dev_pool); 
     348    if (cf->pool) { 
     349        cf->pool = NULL; 
     350        pj_pool_release(pool); 
     351    } 
     352 
     353    return PJ_SUCCESS; 
     354} 
     355 
     356/* API: refresh the list of devices */ 
     357static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f) 
    327358{ 
    328359    vid4lin_factory *cf = (vid4lin_factory*)f; 
     
    333364        return status; 
    334365 
    335     PJ_LOG(4, (THIS_FILE, "Video4Linux2 initialized with %d devices", 
     366    PJ_LOG(4, (THIS_FILE, "Video4Linux2 has %d devices", 
    336367               cf->dev_count)); 
    337  
    338     return PJ_SUCCESS; 
    339 } 
    340  
    341 /* API: destroy factory */ 
    342 static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f) 
    343 { 
    344     vid4lin_factory *cf = (vid4lin_factory*)f; 
    345     pj_pool_t *pool = cf->pool; 
    346  
    347     if (cf->pool) { 
    348         cf->pool = NULL; 
    349         pj_pool_release(pool); 
    350     } 
    351368 
    352369    return PJ_SUCCESS; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c

    r3579 r3592  
    211211 
    212212/* Internal: init driver */ 
    213 static pj_status_t init_driver(unsigned drv_idx) 
     213static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh) 
    214214{ 
    215215    struct driver *drv = &vid_subsys.drv[drv_idx]; 
     
    218218    pj_status_t status; 
    219219 
    220     /* Create the factory */ 
    221     f = (*drv->create)(vid_subsys.pf); 
    222     if (!f) 
    223         return PJ_EUNKNOWN; 
    224  
    225     /* Call factory->init() */ 
    226     status = f->op->init(f); 
    227     if (status != PJ_SUCCESS) { 
    228         f->op->destroy(f); 
    229         return status; 
     220    if (!refresh) { 
     221        /* Create the factory */ 
     222        f = (*drv->create)(vid_subsys.pf); 
     223        if (!f) 
     224            return PJ_EUNKNOWN; 
     225 
     226        /* Call factory->init() */ 
     227        status = f->op->init(f); 
     228        if (status != PJ_SUCCESS) { 
     229            f->op->destroy(f); 
     230            return status; 
     231        } 
     232    } else { 
     233        f = drv->f; 
    230234    } 
    231235 
     
    357361    /* Initialize each factory and build the device ID list */ 
    358362    for (i=0; i<vid_subsys.drv_cnt; ++i) { 
    359         status = init_driver(i); 
     363        status = init_driver(i, PJ_FALSE); 
    360364        if (status != PJ_SUCCESS) { 
    361365            deinit_driver(i); 
     
    377381 
    378382    vid_subsys.drv[vid_subsys.drv_cnt].create = adf; 
    379     status = init_driver(vid_subsys.drv_cnt); 
     383    status = init_driver(vid_subsys.drv_cnt, PJ_FALSE); 
    380384    if (status == PJ_SUCCESS) { 
    381385        vid_subsys.drv_cnt++; 
     
    439443 
    440444        vid_subsys.pf = NULL; 
     445    } 
     446    return PJ_SUCCESS; 
     447} 
     448 
     449/* API: Refresh the list of video devices installed in the system. */ 
     450PJ_DEF(pj_status_t) pjmedia_vid_dev_refresh(void) 
     451{ 
     452    unsigned i; 
     453     
     454    vid_subsys.dev_cnt = 0; 
     455    for (i=0; i<vid_subsys.drv_cnt; ++i) { 
     456        struct driver *drv = &vid_subsys.drv[i]; 
     457         
     458        if (drv->f && drv->f->op->refresh) { 
     459            pj_status_t status = drv->f->op->refresh(drv->f); 
     460            if (status != PJ_SUCCESS) { 
     461                PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device " 
     462                                                 "list for %s", drv->name)); 
     463            } 
     464        } 
     465        init_driver(i, PJ_TRUE); 
    441466    } 
    442467    return PJ_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.