C++ DirectShow DVD播放

C++ DirectShow DVD播放,c++,directx,stack-overflow,directshow,C++,Directx,Stack Overflow,Directshow,我已经创建了一个自定义分配器/演示器,可以很好地播放普通媒体文件。但是,当我使用以下代码尝试播放DVD时,它失败,出现堆栈溢出异常 vmr9_ap = new vmr9ap(); HMONITOR monitor = MonitorFromWindow(hwnd, NULL); IGraphBuilder *graph; IBaseFilter *filter; IDvdGraphBuilder *builder; CoCreateInstance(CLSID_DvdGraphB

我已经创建了一个自定义分配器/演示器,可以很好地播放普通媒体文件。但是,当我使用以下代码尝试播放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();
vmr9_ap=new vmr9ap();
HMONITOR monitor=MonitorFromWindow(hwnd,NULL);
IGraphBuilder*图;
IBaseFilter*过滤器;
IDvdGraphBuilder*生成器;
CoCreateInstance(CLSID_DvdGraphBuilder,NULL,CLSCTX_INPROC_服务器,IID_IDvdGraphBuilder,reinterpret_cast(&builder));
CoCreateInstance(::CLSID_videomixingrender9,NULL,CLSCTX_INPROC_服务器,IID_IBaseFilter,reinterpret_cast(&filter));
生成器->获取DVD接口(IID_IVMRFilterConfig9,(void**)和vmr9_配置);
vmr9_ap->初始化(g_PD3D设备、监视器、vmr9_配置);
HRESULT hr=builder->rendervdvideovolume(L“G:\\VIDEO”,AM_DVD_SWDEC|u首选,仅AM_DVD_VMR9_,&status);
生成器->GetFiltergraph(&graph);
IDvdControl2*DVD控制;
生成器->获取DVD接口(::IID_IDvdControl2,(void**)和DVD控件);
图形->查询界面(::IID\u IMediaControl,(void**)和control);
HRESULT h=控制->运行();
调用control->Run()后立即发生堆栈溢出。这让我发疯,因为我肯定我只是忘记了一些非常简单的事情


谢谢。

这可能是一种DRM保护吗?DVD图形中的解码器通常会试图阻止您构建可以访问未压缩数据的图形。通常情况下,他们是通过更干净的方法来实现的,比如拒绝连接到未经授权的渲染器,但这可能是由类似的原因造成的——当然也有mpeg-2解码器使用故意崩溃来防止反向工程


G

这可能是DRM保护的一种形式吗?DVD图形中的解码器通常会试图阻止您构建可以访问未压缩数据的图形。通常情况下,他们是通过更干净的方法来实现的,比如拒绝连接到未经授权的渲染器,但这可能是由类似的原因造成的——当然也有mpeg-2解码器使用故意崩溃来防止反向工程


你的图表应该是这样的。确保图表中没有任何错误过滤器

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

在我的开源项目中,我有一个定制的分配器,还有一个DVD播放器。您可以查看它以供参考,尽管那里有很多代码噪音,因为我需要在那里修改一些东西以实现WPF兼容性

您看到的不应该是DRM问题


您的图表应该是这样的。确保图表中没有任何错误过滤器

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

在我的开源项目中,我有一个定制的分配器,还有一个DVD播放器。您可以查看它以供参考,尽管那里有很多代码噪音,因为我需要在那里修改一些东西以实现WPF兼容性

您看到的不应该是DRM问题


多亏了杰里迈亚·莫里尔给我指出的代码,我才得以使播放基本正常。 只要您不尝试调整其播放的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;
}
extern“C”\u declspec(dllexport)LPDIRECT3DSURFACE9初始化VD(HWND-HWND)
{
共初始化(空);
IPin*DVD视频输出;
IPin*vmr9VideoIn;
HRESULT hr=S_正常;
hr=CoCreateInstance(CLSID\u FilterGraph,NULL,CLSCTX\u INPROC\u服务器,
IID_IGraphBuilder(void**)和图形);
if(图)
{
hr=CoCreateInstance(CLSID_DVDNavigator,NULL,CLSCTX_INPROC_服务器,
IID_IBaseFilter(void**)和dvdNavigator);
如果(DVD导航器)
{
hr=图形->添加过滤器(DVD导航器,L“DVD导航器”);
如果(成功(hr))
{
hr=CoCreateInstance(CLSID\u VideoMixingRenderer9,NULL,CLSCTX\u INPROC\u服务器,
IID_IBaseFilter(void**)和vmr9);
如果(vmr9)
{
hr=vmr9->QueryInterface(IID_IVMRFilterConfig9,重新解释cast(&p_fConfig));
p_Ap=新的VMR9AllocatorPresenter();
p_Dh=新设备处理器();
p_设备=p_Dh->初始化(hWnd);
p_fConfig->SetRenderingMode(VMR9Mode_Renderless);
p_fConfig->SetNumberOfStreams(1);
p_Ap->初始化(硬件驱动、p_设备、p_配置);
如果(成功(hr))
{
hr=图形->添加过滤器(vmr9,L“视频混合渲染器9”);
如果(p_fConfig)
{
dvdvnavigator->FindPin(L“Video”和dvdvvideoout);
如果(DVD视频输出)
{
hr=图形->渲染(dvd视频输出);
}