- Timestamp:
- Jul 15, 2011 6:42:11 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c
r3651 r3654 228 228 } 229 229 230 static 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 256 static 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 230 344 /* API: refresh the list of devices */ 231 345 static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f) … … 287 401 if (SUCCEEDED(hr) && var_name.bstrVal) { 288 402 WCHAR *wszDisplayName = NULL; 403 IBaseFilter *filter; 289 404 290 405 ddi = &df->dev_info[df->dev_count++]; … … 311 426 /* Set the device capabilities here */ 312 427 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 } 315 457 } 316 458 VariantClear(&var_name); … … 336 478 ddi->info.has_callback = PJ_FALSE; 337 479 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); 358 488 #endif 359 360 361 // TODO:362 // ddi->info.caps = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;363 489 364 490 PJ_LOG(4, (THIS_FILE, "DShow has %d devices:", … … 533 659 534 660 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)) { 554 663 goto on_error; 555 664 } … … 595 704 vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE); 596 705 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; 685 737 } 686 738
Note: See TracChangeset
for help on using the changeset viewer.