我已经创建了一个自定义分配器/演示器,可以很好地播放普通媒体文件。但是,当我使用以下代码尝试播放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()之后立即发生。这让我抓狂,因为我确信我只是忘记了一些非常非常简单的东西。
谢谢。
发布于 2009-09-25 11:07:16
您的图表应该如下所示。确保您的图表中没有任何错误过滤器。
因为您使用的是自定义分配器,所以我会在那里查找问题,并在那里设置一些断点。您粘贴的代码可能不完整,因为我没有看到您使用自定义分配器配置VMR9,也没有看到它被添加到图形中。我避免使用DVDGraphBuilder,因为我很难用我的VMR9+Allocator正确地获取它。我会更多地手动构建图表。
在我的开源项目中,我有一个自定义的分配器,以及一个DVD播放器。您可以查看它以供参考,尽管其中有许多代码噪音,因为我需要修改一些东西来实现WPF兼容性。http://wpfmediakit.codeplex.com
您看到的应该不是DRM问题。
alt text http://img29.imageshack.us/img29/7798/capturelu.jpg
发布于 2009-09-21 08:41:54
它可能是DRM保护的一种形式吗?DVD图形中的解码器通常会试图阻止您构建获取未压缩数据的图形,就像您这里所做的那样。通常,他们通过一种更干净的方法来做到这一点,例如拒绝连接到未经授权的渲染器,但这可能是由这样的原因造成的--当然有mpeg-2解码器使用故意的崩溃来防止反向工程。
G
发布于 2009-10-22 09:04:09
多亏了耶利米·莫里尔给我的代码,我成功地让回放基本上正常了。只要你不想调整播放它的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;
}https://stackoverflow.com/questions/1451925
复制相似问题