2009-09-20 64 views
1

我已經創建了一個自定義分配器/演示者,可以正常播放媒體文件。但是,當我使用以下代碼嘗試播放DVD時,它會因堆棧溢出異常而失敗。DirectShow DVD播放

vmr9_ap = new vmr9ap(); 

HMONITOR monitor = MonitorFromWindow(hwnd, NULL); 

IGraphBuilder *graph; 
IBaseFilter *filter; 

IDvdGraphBuilder *builder; 

CoCreateInstance(CLSID_DvdGraphBuilder, NULL, CLSCTX_INPROC_SERVER, IID_IDvdGraphBuilder, reinterpret_cast<void**>(&builder)); 

CoCreateInstance(::CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<void**>(&filter)); 


builder->GetDvdInterface(IID_IVMRFilterConfig9, (void**)&vmr9_config); 

vmr9_ap->Initialize(g_pd3dDevice, monitor, vmr9_config); 

HRESULT hr = builder->RenderDvdVideoVolume(L"G:\\VIDEO_TS", AM_DVD_SWDEC_PREFER | AM_DVD_VMR9_ONLY, &status); 

builder->GetFiltergraph(&graph); 

IDvdControl2 *dvdControl; 

builder->GetDvdInterface(::IID_IDvdControl2, (void**)&dvdControl); 

graph->QueryInterface(::IID_IMediaControl, (void**)&control); 

HRESULT h = control->Run(); 

調用control-> Run()後立即發生堆棧溢出。這讓我瘋狂,因爲我確信我只是忘記了一些非常簡單的事情。

謝謝。

回答

1

你的圖應該看起來像這樣。確保圖中沒有任何錯誤的過濾器。

因爲你使用的是自定義分配器,所以我會在那裏尋找問題並在那裏設置一些斷點。您粘貼的代碼可能不完整,因爲我沒有看到您使用自定義分配器配置了VMR9,也沒有看到它被添加到圖中。我避免使用DVDGraphBuilder,因爲我用VMR9 + Allocator正確地獲取RenderVolume的時間太困難了。我會更手動地構建圖表。

我有一個自定義分配器在我的開源項目中,沿w/a DVD播放器。你可以檢查一下,以供參考,雖然有很多代碼噪聲在那裏,因爲我需要破解WPF兼容性的一些東西。 http://wpfmediakit.codeplex.com

你所看到的不應該是DRM問題。

alt text http://img29.imageshack.us/img29/7798/capturelu.jpg

+0

感謝您的鏈接。很有幫助。 :)我剛剛發佈了代碼,我結束了。 雖然回放仍然無法與附加的調試器一起工作......我同意它看起來不像DRM。可能是一種反向工程策略。這就是Google似乎認爲的。 – Alex 2009-10-22 01:06:24

0

它可能是DRM保護的一種形式嗎? DVD圖形中的解碼器通常會試圖阻止您構建可訪問未壓縮數據的圖形,就像您在此處所做的那樣。通常他們通過更簡潔的方法來做到這一點,比如拒絕連接未經授權的渲染器,但這可能是由於類似的原因造成的 - 當然有些MPEG-2解碼器會使用故意的崩潰來防止逆向工程。

G

0

由於代碼耶利米莫里爾向我指出,我設法播放大部分的工作。 它工作正常,只要你不嘗試調整它所播放的D3DImage的大小。我想,魔鬼的細節。

感謝所有的答案。根據谷歌的說法,DVD播放不適用於附加的調試器,它不是DRM,而是一種反向工程措施。可能對我使用的DVD編解碼器也很特別。

extern "C" __declspec(dllexport) LPDIRECT3DSURFACE9 InitializeDvd(HWND hWnd) 
{ 
    CoInitialize(NULL); 

    IPin *dvdVideoOut; 
    IPin *vmr9VideoIn; 

    HRESULT hr = S_OK; 

    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
      IID_IGraphBuilder, (void **)&graph); 

    if(graph) 
    { 
     hr = CoCreateInstance(CLSID_DVDNavigator, NULL, CLSCTX_INPROC_SERVER, 
       IID_IBaseFilter, (void **)&dvdNavigator); 

     if(dvdNavigator) 
     { 
      hr = graph->AddFilter(dvdNavigator, L"DVD Navigator"); 

      if(SUCCEEDED(hr)) 
      { 
       hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, 
         IID_IBaseFilter, (void **)&vmr9); 

       if(vmr9) 
       { 
        hr = vmr9->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&p_fConfig)); 

        p_Ap = new VMR9AllocatorPresenter(); 
        p_Dh = new DeviceHandler(); 
        p_device = p_Dh->Initialize(hWnd); 
        p_fConfig->SetRenderingMode(VMR9Mode_Renderless); 
        p_fConfig->SetNumberOfStreams(1); 

        p_Ap->Initialize(hWnd, p_device, p_fConfig); 

        if(SUCCEEDED(hr)) 
        { 
         hr = graph->AddFilter(vmr9, L"Video Mixing Renderer 9"); 

         if(p_fConfig) 
         { 
          dvdNavigator->FindPin(L"Video", &dvdVideoOut); 
          if(dvdVideoOut) 
          { 
           hr = graph->Render(dvdVideoOut); 
          } 
          hr = graph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&control)); 

          if(control) 
          { 
           control->Run(); 
          } 
         } 
        } 
       } 
      } 
     } 
    } 

    return p_Dh->g_surface9; 
} 
+0

對於我與從DVD的DVD樣品應用程序,DVD播放工作在調試模式,它只是真正像素化和生澀。 – rogerdpack 2011-04-21 06:48:39