【问题标题】:How to set amcap's default color space to YUY2?如何将amcap的默认色彩空间设置为YUY2?
【发布时间】:2009-05-22 10:49:31
【问题描述】:

AMcap 是一款用于捕捉视频或从网络摄像头预览的应用。它的源代码以 Microsoft Windows SDK 作为示例。

我想(绕过amcap代码中的以下用户交互过程或说想)将其设置为默认值:

Ampcap 菜单

  Options

    Video Capture Pin ...

        Color Space/Compression: YUY2

        Output size: 1600x1200

我有一个兼容的网络摄像头,可以在 AMcap 应用中手动更改为 YUY2 和 1600x1200。

默认是:

    Color Space/Compression: MJPG

    Output size: 160x120

我试图在整个项目中找到'YUY2'字符串,但我找不到它,所以我可以对其进行硬编码。好像是动态创建然后操作的;参考:在文件 amcap.cpp 附近的第 3395 行。

【问题讨论】:

    标签: .net c++ visual-c++ webcam winapi


    【解决方案1】:

    我有一些代码使用 IID_IAMStreamConfig 接口来设置相机图像大小。我没有使用它来设置图像格式,但我添加了我认为可以完成这项工作的代码。然而,它未经测试。

                // get the number of formats and make sure the strutucre size matches
                int count;
                int size;
                VIDEO_STREAM_CONFIG_CAPS caps;
                pSC->GetNumberOfCapabilities(&count, &size);
                if( sizeof(caps) != size )
                {
                    // Error
                }
    
                AM_MEDIA_TYPE* mt_p = NULL;
                hr = pSC->GetStreamCaps(0, &mt_p, (BYTE*)&caps);
                if (hr != S_OK)
                {
                    // Error
                }
    
                if ((mt_p->majortype != MEDIATYPE_Video) || (mt_p->formattype != FORMAT_VideoInfo))
                {
                    // Error
                }
    
                VIDEOINFOHEADER* video_info_header_p = (VIDEOINFOHEADER *)mt_p->pbFormat;
                video_info_header_p->bmiHeader.biWidth = 1600;
                video_info_header_p->bmiHeader.biHeight = 1200;
                // Code to change video format 
                // I think 16 is the right value for biBitCount, but I am not sure!!!!
                video_info_header_p->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','2');
                video_info_header_p->bmiHeader.biBitCount = 16;
    
                hr = pSC->SetFormat(mt_p);
                if (hr != S_OK)
                {
                    // Error
                }
    
                if (mt_p->cbFormat != 0)
                {
                    CoTaskMemFree((PVOID)mt_p->pbFormat);
                    mt_p->cbFormat = 0;
                    mt_p->pbFormat = NULL;
                }
                if (mt_p->pUnk != NULL)
                {
                    // Unecessary because pUnk should not be used, but safest.
                    mt_p->pUnk->Release();
                    mt_p->pUnk = NULL;
                }
    

    您应该将代码放在 amcap 中的以下块之后:

        if(hr != NOERROR)
            hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
                &MEDIATYPE_Video, gcap.pVCap,
                IID_IAMStreamConfig, (void **)&pSC);
    

    同样,这是未经测试的代码,但您可以尝试一下,希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      嘿@Dani van der Meer:感谢您的指点……我做到了: 在函数 BOOL InitCapFilters()

      之后

       if(hr != NOERROR)
      {
      
          hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
                                            &MEDIATYPE_Video, gcap.pVCap,
                                            IID_IAMStreamConfig, (void **)&gcap.pVSC);
      
          if(hr != NOERROR)
          {
              // this means we can't set frame rate (non-DV only)
              ErrMsg(TEXT("Error %x: Cannot find VCapture:IAMStreamConfig"), hr);
          }
      }
      
      gcap.fCapAudioIsRelevant = TRUE;
      

      粘贴:

      CMediaType *pmt;
      // default capture format
      if(gcap.pVSC && gcap.pVSC->GetFormat((AM_MEDIA_TYPE**)&pmt) == S_OK)
      {
          // DV capture does not use a VIDEOINFOHEADER
          if(pmt->formattype == FORMAT_VideoInfo)
          {
           pmt->SetType(&MEDIATYPE_Video);
           pmt->SetFormatType(&FORMAT_VideoInfo);
           pmt->SetSubtype(&MEDIASUBTYPE_YUY2);
           pmt->SetTemporalCompression(FALSE);
      
           VIDEOINFOHEADER* lpvihin = (VIDEOINFOHEADER*) pmt->pbFormat;
      
              {
      
                   //DWORD fccYUY2 =  'YUY2' ;
                   //lpvihin->bmiHeader.biCompression  =fccYUY2;
                  //'YUY2';// MAKEFOURCC('Y','U','Y','2');
                  //lpvihin->bmiHeader.biBitCount = 16; 
                  lpvihin->bmiHeader.biWidth =  1600;// 960; //1600;
                  lpvihin->bmiHeader.biHeight =  1200;//  720; //1200;
                  lpvihin->bmiHeader.biSizeImage =   1600*1200*3; 
      
                  hr = gcap.pVSC->SetFormat(pmt);
      
                  ResizeWindow(HEADER(pmt->pbFormat)->biWidth,
                           ABS(HEADER(pmt->pbFormat)->biHeight));
              }
          }
          if(pmt->majortype != MEDIATYPE_Video)
          {
              // This capture filter captures something other that pure video.
              // Maybe it's DV or something?  Anyway, chances are we shouldn't
              // allow capturing audio separately, since our video capture
              // filter may have audio combined in it already!
              gcap.fCapAudioIsRelevant = FALSE;
              gcap.fCapAudio = FALSE;
          }
          DeleteMediaType(pmt);
      }
      

      非常感谢

      【讨论】:

      • 好的。很高兴知道这行得通。 DirectShow API 的文档记录很差,有时您只需要进行一些试验和错误...
      猜你喜欢
      • 1970-01-01
      • 2019-09-24
      • 2013-01-19
      • 2011-02-21
      • 1970-01-01
      • 2014-03-04
      • 2018-02-11
      • 2021-01-26
      相关资源
      最近更新 更多