Changeset 3654


Ignore:
Timestamp:
Jul 15, 2011 6:42:11 AM (8 years ago)
Author:
ming
Message:

Fixed #1281:
Video device should now be able to open the device when provided with the default param.
Tested video device: dshow capture, qt, iOS, SDL

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c

    r3651 r3654  
    228228} 
    229229 
     230static HRESULT get_cap_device(struct dshow_factory *df, 
     231                              unsigned id, 
     232                              IBaseFilter **filter) 
     233{ 
     234    IBindCtx *pbc; 
     235    HRESULT hr; 
     236 
     237    hr = CreateBindCtx(0, &pbc); 
     238    if (SUCCEEDED (hr)) { 
     239        IMoniker *moniker; 
     240        DWORD pchEaten; 
     241 
     242        hr = MkParseDisplayName(pbc, df->dev_info[id].display_name, 
     243                                &pchEaten, &moniker); 
     244        if (SUCCEEDED(hr)) { 
     245            hr = IMoniker_BindToObject(moniker, pbc, NULL, 
     246                                       &IID_IBaseFilter, 
     247                                       (LPVOID *)filter); 
     248            IMoniker_Release(moniker); 
     249        } 
     250        IBindCtx_Release(pbc); 
     251    } 
     252 
     253    return hr; 
     254} 
     255 
     256static void enum_dev_cap(IBaseFilter *filter, 
     257                         pjmedia_dir dir, 
     258                         const GUID *dshow_format, 
     259                         AM_MEDIA_TYPE **pMediatype, 
     260                         IPin **pSrcpin, 
     261                         pj_bool_t *sup_fmt) 
     262{ 
     263    IEnumPins *pEnum; 
     264    AM_MEDIA_TYPE *mediatype = NULL; 
     265    HRESULT hr; 
     266 
     267    if (pSrcpin) 
     268        *pSrcpin = NULL; 
     269    hr = IBaseFilter_EnumPins(filter, &pEnum); 
     270    if (SUCCEEDED(hr)) { 
     271        /* Loop through all the pins. */ 
     272        IPin *pPin = NULL; 
     273 
     274        while (IEnumPins_Next(pEnum, 1, &pPin, NULL) == S_OK) { 
     275            PIN_DIRECTION pindirtmp; 
     276 
     277            hr = IPin_QueryDirection(pPin, &pindirtmp); 
     278            if (hr != S_OK || pindirtmp != PINDIR_OUTPUT) { 
     279                if (SUCCEEDED(hr)) 
     280                    IPin_Release(pPin); 
     281                continue; 
     282            } 
     283 
     284            if (dir == PJMEDIA_DIR_CAPTURE) { 
     285                IAMStreamConfig *streamcaps; 
     286 
     287                hr = IPin_QueryInterface(pPin, &IID_IAMStreamConfig, 
     288                                         (LPVOID *)&streamcaps); 
     289                if (SUCCEEDED(hr)) { 
     290                    VIDEO_STREAM_CONFIG_CAPS vscc; 
     291                    int i, isize, icount; 
     292 
     293                    IAMStreamConfig_GetNumberOfCapabilities(streamcaps, 
     294                                                            &icount, &isize); 
     295 
     296                    for (i = 0; i < icount; i++) { 
     297                        unsigned j, nformat; 
     298                        RPC_STATUS rpcstatus, rpcstatus2; 
     299 
     300                        hr = IAMStreamConfig_GetStreamCaps(streamcaps, i, 
     301                                                           &mediatype, 
     302                                                           (BYTE *)&vscc); 
     303                        if (FAILED (hr)) 
     304                            continue; 
     305 
     306                        nformat = (dshow_format? 1: 
     307                                   sizeof(dshow_fmts)/sizeof(dshow_fmts[0])); 
     308                        for (j = 0; j < nformat; j++) { 
     309                            if (!dshow_format || j > 0) 
     310                                dshow_format = dshow_fmts[j].dshow_format; 
     311                            if (UuidCompare(&mediatype->subtype,  
     312                                            (UUID*)dshow_format, 
     313                                            &rpcstatus) == 0 &&  
     314                                rpcstatus == RPC_S_OK && 
     315                                UuidCompare(&mediatype->formattype, 
     316                                            (UUID*)&FORMAT_VideoInfo, 
     317                                            &rpcstatus2) == 0 && 
     318                                rpcstatus2 == RPC_S_OK) 
     319                            { 
     320                                if (sup_fmt) 
     321                                    sup_fmt[j] = PJ_TRUE; 
     322                                if (pSrcpin) { 
     323                                    *pSrcpin = pPin; 
     324                                    *pMediatype = mediatype; 
     325                                } 
     326                            } 
     327                        } 
     328                        if (pSrcpin && *pSrcpin) 
     329                            break; 
     330                    } 
     331                    IAMStreamConfig_Release(streamcaps); 
     332                } 
     333            } else { 
     334                *pSrcpin = pPin; 
     335            } 
     336            if (pSrcpin && *pSrcpin) 
     337                break; 
     338            IPin_Release(pPin); 
     339        } 
     340        IEnumPins_Release(pEnum); 
     341    } 
     342} 
     343 
    230344/* API: refresh the list of devices */ 
    231345static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f) 
     
    287401                if (SUCCEEDED(hr) && var_name.bstrVal) { 
    288402                    WCHAR *wszDisplayName = NULL; 
     403                    IBaseFilter *filter; 
    289404 
    290405                    ddi = &df->dev_info[df->dev_count++]; 
     
    311426                    /* Set the device capabilities here */ 
    312427                    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT; 
    313                     // TODO: Query the default width, height, fps, and 
    314                     // supported formats 
     428 
     429                    hr = get_cap_device(df, df->dev_count-1, &filter); 
     430                    if (SUCCEEDED(hr)) { 
     431                        unsigned j; 
     432                        pj_bool_t sup_fmt[sizeof(dshow_fmts)/sizeof(dshow_fmts[0])]; 
     433 
     434                        pj_bzero(sup_fmt, sizeof(sup_fmt)); 
     435                        enum_dev_cap(filter, ddi->info.dir, NULL, NULL, NULL, sup_fmt); 
     436 
     437                        ddi->info.fmt_cnt = 0; 
     438                        ddi->info.fmt = (pjmedia_format*) 
     439                                        pj_pool_calloc(df->dev_pool, 
     440                                                       sizeof(dshow_fmts)/ 
     441                                                       sizeof(dshow_fmts[0]), 
     442                                                       sizeof(pjmedia_format)); 
     443 
     444                        for (j = 0; 
     445                             j < sizeof(dshow_fmts)/sizeof(dshow_fmts[0]); 
     446                             j++) 
     447                        { 
     448                            if (!sup_fmt[j]) 
     449                                continue; 
     450                            pjmedia_format_init_video( 
     451                                &ddi->info.fmt[ddi->info.fmt_cnt++], 
     452                                dshow_fmts[j].pjmedia_format,  
     453                                DEFAULT_WIDTH, DEFAULT_HEIGHT,  
     454                                DEFAULT_FPS, 1); 
     455                        } 
     456                    } 
    315457                } 
    316458                VariantClear(&var_name); 
     
    336478    ddi->info.has_callback = PJ_FALSE; 
    337479    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT; 
    338  
    339     for (c = 0; c < df->dev_count; c++) { 
    340         unsigned i; 
    341  
    342         ddi = &df->dev_info[c]; 
    343         ddi->info.fmt_cnt = sizeof(dshow_fmts)/sizeof(dshow_fmts[0]); 
    344         ddi->info.fmt = (pjmedia_format*) 
    345                         pj_pool_calloc(df->dev_pool, ddi->info.fmt_cnt, 
    346                                        sizeof(pjmedia_format)); 
    347  
    348         for (i = 0; i < ddi->info.fmt_cnt; i++) { 
    349             pjmedia_format *fmt = &ddi->info.fmt[i]; 
    350  
    351             if (ddi->info.dir == PJMEDIA_DIR_RENDER && i > 0) 
    352                 break; 
    353             pjmedia_format_init_video(fmt, dshow_fmts[i].pjmedia_format,  
    354                                       DEFAULT_WIDTH, DEFAULT_HEIGHT,  
    355                                       DEFAULT_FPS, 1); 
    356         } 
    357     } 
     480//    TODO: 
     481//    ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW; 
     482 
     483    ddi->info.fmt_cnt = 1; 
     484    ddi->info.fmt = PJ_POOL_ZALLOC_T(df->dev_pool, pjmedia_format); 
     485    pjmedia_format_init_video(&ddi->info.fmt[0], dshow_fmts[0].pjmedia_format,  
     486                              DEFAULT_WIDTH, DEFAULT_HEIGHT,  
     487                              DEFAULT_FPS, 1); 
    358488#endif 
    359  
    360  
    361 //    TODO: 
    362 //    ddi->info.caps = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW; 
    363489 
    364490    PJ_LOG(4, (THIS_FILE, "DShow has %d devices:",  
     
    533659 
    534660    if (dir == PJMEDIA_DIR_CAPTURE) { 
    535         IBindCtx *pbc; 
    536  
    537         hr = CreateBindCtx(0, &pbc); 
    538         if (SUCCEEDED (hr)) { 
    539             IMoniker *moniker; 
    540             DWORD pchEaten; 
    541  
    542             hr = MkParseDisplayName(pbc,  
    543                                     df->dev_info[id].display_name, 
    544                                     &pchEaten, &moniker); 
    545             if (SUCCEEDED(hr)) { 
    546                 hr = IMoniker_BindToObject(moniker, pbc, NULL, 
    547                                            &IID_IBaseFilter, 
    548                                            (LPVOID *)&graph->source_filter); 
    549                 IMoniker_Release(moniker); 
    550             } 
    551             IBindCtx_Release(pbc); 
    552         } 
    553         if (FAILED(hr)) { 
     661        hr = get_cap_device(df, id, &graph->source_filter); 
     662        if (FAILED(hr)) { 
    554663            goto on_error; 
    555664        } 
     
    595704    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE); 
    596705 
    597     IBaseFilter_EnumPins(graph->source_filter, &pEnum); 
    598     if (SUCCEEDED(hr)) { 
    599         // Loop through all the pins 
    600         IPin *pPin = NULL; 
    601  
    602         while (IEnumPins_Next(pEnum, 1, &pPin, NULL) == S_OK) { 
    603             PIN_DIRECTION pindirtmp; 
    604             const GUID *dshow_format; 
    605                  
    606             dshow_format = get_dshow_format_info(strm->param.fmt.id)-> 
    607                                                  dshow_format; 
    608  
    609             hr = IPin_QueryDirection(pPin, &pindirtmp); 
    610             if (hr != S_OK || pindirtmp != PINDIR_OUTPUT) { 
    611                 if (SUCCEEDED(hr)) 
    612                     IPin_Release(pPin); 
    613                 continue; 
    614             } 
    615  
    616             if (dir == PJMEDIA_DIR_CAPTURE) { 
    617                 IAMStreamConfig *streamcaps; 
    618  
    619                 hr = IPin_QueryInterface(pPin, &IID_IAMStreamConfig, 
    620                                          (LPVOID *)&streamcaps); 
    621                 if (SUCCEEDED(hr)) { 
    622                     VIDEO_STREAM_CONFIG_CAPS vscc; 
    623                     int i, isize, icount; 
    624  
    625                     IAMStreamConfig_GetNumberOfCapabilities(streamcaps, 
    626                                                             &icount, &isize); 
    627  
    628                     for (i = 0; i < icount; i++) { 
    629                         RPC_STATUS rpcstatus, rpcstatus2; 
    630  
    631                         hr = IAMStreamConfig_GetStreamCaps(streamcaps, i, 
    632                                                            &mediatype, 
    633                                                            (BYTE *)&vscc); 
    634                         if (FAILED (hr)) 
    635                             continue; 
    636  
    637                         if (UuidCompare(&mediatype->subtype,  
    638                                         (UUID*)dshow_format, 
    639                                         &rpcstatus) == 0 &&  
    640                             rpcstatus == RPC_S_OK && 
    641                             UuidCompare(&mediatype->formattype, 
    642                                         (UUID*)&FORMAT_VideoInfo, 
    643                                         &rpcstatus2) == 0 && 
    644                             rpcstatus2 == RPC_S_OK) 
    645                         { 
    646                             srcpin = pPin; 
    647                             graph->mediatype = mediatype; 
    648                             break; 
    649                         } 
    650                     } 
    651                     IAMStreamConfig_Release(streamcaps); 
    652                 } 
    653             } else { 
    654                 srcpin = pPin; 
    655                 mediatype = graph->mediatype = &mtype; 
    656  
    657                 memset (mediatype, 0, sizeof(AM_MEDIA_TYPE)); 
    658                 mediatype->majortype = MEDIATYPE_Video; 
    659                 mediatype->subtype = *dshow_format; 
    660                 mediatype->bFixedSizeSamples = TRUE; 
    661                 mediatype->bTemporalCompression = FALSE; 
    662  
    663                 vi = (VIDEOINFOHEADER *) 
    664                      CoTaskMemAlloc(sizeof(VIDEOINFOHEADER)); 
    665                 memset (vi, 0, sizeof(VIDEOINFOHEADER)); 
    666                 mediatype->formattype = FORMAT_VideoInfo; 
    667                 mediatype->cbFormat = sizeof(VIDEOINFOHEADER); 
    668                 mediatype->pbFormat = (BYTE *)vi; 
    669  
    670                 vi->rcSource.bottom = vfd->size.h; 
    671                 vi->rcSource.right = vfd->size.w; 
    672                 vi->rcTarget.bottom = vfd->size.h; 
    673                 vi->rcTarget.right = vfd->size.w; 
    674  
    675                 vi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    676                 vi->bmiHeader.biPlanes = 1; 
    677                 vi->bmiHeader.biBitCount = vfi->bpp; 
    678                 vi->bmiHeader.biCompression = strm->param.fmt.id; 
    679             } 
    680             if (srcpin) 
    681                 break; 
    682             IPin_Release(pPin); 
    683         } 
    684         IEnumPins_Release(pEnum); 
     706    enum_dev_cap(graph->source_filter, dir, 
     707                 get_dshow_format_info(strm->param.fmt.id)->dshow_format, 
     708                 &mediatype, &srcpin, NULL); 
     709    graph->mediatype = mediatype; 
     710 
     711    if (srcpin && dir == PJMEDIA_DIR_RENDER) { 
     712        mediatype = graph->mediatype = &mtype; 
     713 
     714        memset (mediatype, 0, sizeof(AM_MEDIA_TYPE)); 
     715        mediatype->majortype = MEDIATYPE_Video; 
     716        mediatype->subtype = *(get_dshow_format_info(strm->param.fmt.id)-> 
     717                               dshow_format); 
     718        mediatype->bFixedSizeSamples = TRUE; 
     719        mediatype->bTemporalCompression = FALSE; 
     720 
     721        vi = (VIDEOINFOHEADER *) 
     722            CoTaskMemAlloc(sizeof(VIDEOINFOHEADER)); 
     723        memset (vi, 0, sizeof(VIDEOINFOHEADER)); 
     724        mediatype->formattype = FORMAT_VideoInfo; 
     725        mediatype->cbFormat = sizeof(VIDEOINFOHEADER); 
     726        mediatype->pbFormat = (BYTE *)vi; 
     727 
     728        vi->rcSource.bottom = vfd->size.h; 
     729        vi->rcSource.right = vfd->size.w; 
     730        vi->rcTarget.bottom = vfd->size.h; 
     731        vi->rcTarget.right = vfd->size.w; 
     732 
     733        vi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
     734        vi->bmiHeader.biPlanes = 1; 
     735        vi->bmiHeader.biBitCount = vfi->bpp; 
     736        vi->bmiHeader.biCompression = strm->param.fmt.id; 
    685737    } 
    686738 
Note: See TracChangeset for help on using the changeset viewer.