2015-03-13 20 views
0

我最近开始尝试使用BlackMagic SDK的DirectShow示例。 我做了我的第一个应用程序,但在阅读卡的可用视频模式(DeckLink Studio 4K)时遇到了一些奇怪的行为。 旁注:同样的行为发生在Windows 7教授& HP x64和Win 8.1 Pro x64。Blackmagic DirectShow Framerate - 为什么我没有获取我的拍摄设备所能支持的所有视频模式?

我的问题是,我没有得到像25p,29.97p和30p视频模式。 尽管捕捉设备能够支持它们,但它们甚至可以与Blackmagic Media Express完美配合。

HRESULT CDecklinkCaptureDlg::PopulateVideoControl() 
{ 
HRESULT hr = S_OK; 
if (m_pVideoCapture) 
{ 
    int count = m_videoFormatCtrl.GetCount(); 
    if (count) 
    { 
     for (int item=0; item<count; ++item) 
     { 
      DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); 
     } 
     m_videoFormatCtrl.ResetContent(); 
    } 

    CComPtr<IAMStreamConfig> pISC = NULL; 
    hr = CDSUtils::FindPinInterface(m_pVideoCapture, &MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast<void**>(&pISC)); 
    if (SUCCEEDED(hr)) 
    { 
     int count, size; 
     hr = pISC->GetNumberOfCapabilities(&count, &size); 
     if (SUCCEEDED(hr)) 
     { 
      if (sizeof(VIDEO_STREAM_CONFIG_CAPS) == size) 
      { 
       AM_MEDIA_TYPE* pmt = NULL; 
       VIDEO_STREAM_CONFIG_CAPS vscc; 
       VIDEOINFOHEADER* pvih = NULL; 

       for (int index=0; index<count; ++index) 
       { 
        hr = pISC->GetStreamCaps(index, &pmt, reinterpret_cast<BYTE*>(&vscc)); 
        if (SUCCEEDED(hr)) 
        { 
         TCHAR  buffer[128]; 
         float  frameRate; 
         char*  pixelFormatString; 

         ZeroMemory(buffer, sizeof(buffer)); 

         pvih = (VIDEOINFOHEADER*)pmt->pbFormat; 
         // 
         if (pvih->bmiHeader.biBitCount == 16) 
          pixelFormatString = TEXT("8 bit 4:2:2 YUV"); 
         else if (pvih->bmiHeader.biBitCount == 20) 
          pixelFormatString = TEXT("10 bit 4:2:2 YUV"); 
         else if (pvih->bmiHeader.biBitCount == 30) 
          pixelFormatString = TEXT("10 bit 4:4:4 RGB"); 
         else 
          pixelFormatString = TEXT("");   


         if (486 == pvih->bmiHeader.biHeight) 
         { 
          if (417083 == pvih->AvgTimePerFrame) 
          { 
           StringCbPrintf(buffer, sizeof(buffer), TEXT("NTSC - %s (3:2 pulldown removal)"), pixelFormatString); 
          } 
          else 
          { 
           StringCbPrintf(buffer, sizeof(buffer), TEXT("NTSC - %s"), pixelFormatString); 
          } 
         } 
         else if (576 == pvih->bmiHeader.biHeight) 
         { 
          StringCbPrintf(buffer, sizeof(buffer), TEXT("PAL - %s"), pixelFormatString); 
         } 
         else 
         { 
          frameRate = (float)UNITS/pvih->AvgTimePerFrame; 

          if (720 == pvih->bmiHeader.biHeight) 
          { 
           // 720p 
           if ((frameRate - (int)frameRate) > 0.01) 
           { 
            StringCbPrintf(buffer, sizeof(buffer), TEXT("HD 720p %.2f - %s"), frameRate, pixelFormatString); 
           } 
           else 
           { 
            StringCbPrintf(buffer, sizeof(buffer), TEXT("HD 720p %.0f - %s"), frameRate, pixelFormatString); 
           } 
          } 
          else if (1080 == pvih->bmiHeader.biHeight) 
          { 
           if ((frameRate < 25) || (frameRate >= 50.0))  // 1080p23, 1080p24, 1080p50, 1080p5994, 1080p60 
           { 
            // Progressive 1080 
            if ((frameRate - (int)frameRate) > 0.01) 
            { 
             StringCbPrintf(buffer, sizeof(buffer), TEXT("HD 1080p %.2f - %s"), frameRate, pixelFormatString); 
            } 
            else 
            { 
             StringCbPrintf(buffer, sizeof(buffer), TEXT("HD 1080p %.0f - %s"), frameRate, pixelFormatString); 
            } 
           } 
           else 
           { 
            // Interlaced 1080 
            if ((frameRate - (int)frameRate) > 0.01) 
            { 
             StringCbPrintf(buffer, sizeof(buffer), TEXT("HD 1080i %.2f - %s"), frameRate*2.0f, pixelFormatString); 
            } 
            else 
            { 
             StringCbPrintf(buffer, sizeof(buffer), TEXT("HD 1080i %.0f - %s"), frameRate*2.0f, pixelFormatString); 
            } 
           } 
          } 
          else if (1556 == pvih->bmiHeader.biHeight) 
          { 
           if ((frameRate - (int)frameRate) > 0.01) 
           { 
            StringCbPrintf(buffer, sizeof(buffer), TEXT("2K 1556p %.2f - %s"), frameRate, pixelFormatString); 
           } 
           else 
           { 
            StringCbPrintf(buffer, sizeof(buffer), TEXT("2K 1556p %.0f - %s"), frameRate, pixelFormatString); 
           } 
          } 
         } 

         // If the display mode was recognized, add it to the listbox UI 
         if (buffer[0] != 0) 
         { 
          // add the item description to combo box 
          int n = m_videoFormatCtrl.AddString(buffer); 
          // store media type pointer in item's data section 
          m_videoFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); 

          // set default format 
          if ((pvih->AvgTimePerFrame == m_vihDefault.AvgTimePerFrame) && 
           (pvih->bmiHeader.biWidth == m_vihDefault.bmiHeader.biWidth) && 
           (pvih->bmiHeader.biHeight == m_vihDefault.bmiHeader.biHeight) && 
           (pvih->bmiHeader.biBitCount == m_vihDefault.bmiHeader.biBitCount)) 
          { 
           m_videoFormatCtrl.SetCurSel(n); 
           pISC->SetFormat(pmt); 
          } 
         } 
         else 
         { 
          DeleteMediaType(pmt); 
         } 
        } 
       } 
      } 
      else 
      { 
       m_videoFormatCtrl.AddString(TEXT("ERROR: Unable to retrieve video formats")); 
      } 
     } 
    } 

    // as the device is being changed, update the IDecklinkInputStatus interface 
    { 
     CAutoLock lock(&m_csInputStatusLock); // prevent thread from using this interface while it is changed 

     m_pIDecklinkStatus = m_pVideoCapture; 
     if (m_pIDecklinkStatus) 
     { 
      m_pIDecklinkStatus->RegisterVideoStatusChangeEvent((unsigned long)m_hInputStatusChangeEvent); 
     } 
    } 
} 
else 
{ 
    hr = E_POINTER; 
} 

return hr; 
} 

现在当然我试图改变这样的: “如果((帧率< 25)||(帧率> = 50.0))”

到 “如果((帧率< 30)| |(frameRate> = 50.0))“

但是,只是将1080 50i/59,94i/60i重命名为25p/29.97p/30p。 我不给我使用30p的能力,它只是改名为30p,但仍然捕获60i。

也许有人更有经验可以找出问题。我认为这与DirectShow interpresing有关,即59.94i作为29.97的帧率,因此它不能填充该帧率两次。

在此先感谢(和抱歉任何拼错 - >来自德国), 马尔科

回答

2

的Blackmagic提供了SDK作为主要的API,然后他们的DirectShow过滤器都是建立在这个SDK之上。也就是说,DirectShow过滤器提供了SDK功能的一个子集,特别是您可以看到隔行/逐行媒体类型重叠的问题(它们的过滤器在交付真正交错的媒体类型的视频馈送时不会执行隔行扫描,或者通过字段),你基本上只限于过滤器可用的内容。

+0

感谢您的澄清,我会使用API​​,但是我发现它确实很难(特别是编程技能有限)来构建一个简单的软件,允许记录到文件并截取屏幕截图。在这种情况下,DirectShow Capture/record样例非常棒。 – 2015-03-14 18:23:44

+0

是否有任何使用内置录像机的“本机”API的示例。 我想要一个全屏应用程序(Media Express不支持预览窗口的全屏显示)和记录器和屏幕截图功能。 截图不会是问题,因为我可以实现整个屏幕的简单捕获 – 2015-03-14 21:52:53

+0

有问题的部分是体面的视频编码器(通常是H.264编码器,反过来) - 它们通常不是免费的,所以它们不可用的盒子。通常需要第三方视频编码器或使用Windows Media或M-JPEG编码器。那么选择编码器就意味着容器(文件)格式。我看到你正在使用股票视频过滤器,因为它很容易使用。我建议[WM ASF Writer](https://msdn.microsoft.com/en-us/library/windows/desktop/dd318239%28)过滤器作为最容易记录的文件,尽管它需要一些棘手的设置。 – 2015-03-15 18:21:25

相关问题