【问题标题】:DirectShow DVD playbackDirectShow DVD 播放
【发布时间】:2009-09-20 20:18:56
【问题描述】:

我创建了一个自定义分配器/演示器,可以正常播放普通媒体文件。但是,当我使用以下代码尝试播放 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() 后立即发生堆栈溢出。这让我发疯了,因为我确定我只是忘记了一些非常简单的事情。

谢谢。

【问题讨论】:

    标签: c++ directx stack-overflow directshow


    【解决方案1】:

    您的图表应如下所示。确保您的图表中没有任何错误的过滤器。

    因为您使用的是自定义分配器,所以我会在那里寻找问题并在那里设置一些断点。您粘贴的代码可能不完整,因为我没有看到您使用自定义分配器配置 VMR9,也没有看到它被添加到图表中。我避免使用 DVDGraphBuilder,因为我很难用我的 VMR9+Allocator 正确地获得 RenderVolume。我会更手动地构建图表。

    我的开源项目中有一个自定义分配器,还有一个 DVD 播放器。您可以查看它以供参考,尽管由于我需要在其中破解一些东西以实现 WPF 兼容性,因此其中存在很多代码噪音。 http://wpfmediakit.codeplex.com

    您所看到的不应是 DRM 问题。

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

    【讨论】:

    • 感谢您的链接。很有帮助。 :) 我刚刚发布了我最终得到的代码。虽然播放仍然无法使用附加的调试器......我同意它看起来不像 DRM。可能是一种反逆向工程策略。 Google 似乎就是这么想的。
    【解决方案2】:

    这可能是一种 DRM 保护形式吗? DVD 图表中的解码器通常会尝试阻止您构建可以访问未压缩数据的图表,就像您在此处所做的那样。通常他们通过更简洁的方法来做到这一点,例如拒绝连接到未经授权的渲染器,但这可能是由类似的东西引起的——当然有 mpeg-2 解码器使用故意崩溃来防止逆向工程。

    G

    【讨论】:

      【解决方案3】:

      感谢 Jeremiah Morrill 向我指出的代码,我设法让播放大部分工作正常。 只要您不尝试调整播放它的 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;
      }
      

      【讨论】:

      • 对我来说,使用 sdk 中的 dvd 示例应用程序,dvd 播放在调试模式下工作,它只是真的像素化和生涩。
      猜你喜欢
      • 2016-06-26
      • 1970-01-01
      • 2010-10-26
      • 2011-03-17
      • 1970-01-01
      • 2011-03-08
      • 2012-04-01
      • 2011-02-01
      • 2011-04-14
      相关资源
      最近更新 更多