我正在将一个DirectShow图形集成到一个现有应用程序中,但遇到了一些奇怪的问题。
首先需要说明以下几点:
1. 该图的目的是从具有公开DirectShow接口的FrameGrabber中获取原始视频。该图通过VMR9直接将视频显示出来,并通过ISampleGrabber(DirectShow示例)将原始帧暴露给一些算法。 2. 该图已经在单独的项目中构建并成功运行。视频正常显示,一切都很顺利。
现在的问题是当我将其集成到现有代码中时出现了问题。在初始化应用程序时,我首先创建并启动图形,以无窗口模式运行VMR9。稍后在初始化时,我通过_beginthreadex创建了一些工作线程。只有当构建并运行图形时,调用_beginthreadex才会返回12(内存不足)错误码。
显然,答案是我没有足够的内存或其他资源。然而,在线程尝试启动的时候,我使用了2GB系统内存的约420MB。线程堆栈大小已明确设置为1MB。因此,就我所知,我没有内存不足的问题。此外,运行的应用程序中共有15个线程,因此我没有创建过多的线程。
是否有人遇到过DirectShow的类似问题?我正在寻找任何输入,我们一直在尝试调试这个问题,但没有成功。
如果需要,我会发布您需要的任何代码,就像大多数DirectShow图形一样,代码很长。
编辑:
如所请求。我不确定DirectShow代码的哪个部分导致线程无法启动。但是,如果我只构建而不运行该图,则线程可以正常工作。因此,我猜测故障发生在运行调用之后。我的运行图形代码如下:
SetVMRSize函数只是将VMR调整为其父窗口的大小:
首先需要说明以下几点:
1. 该图的目的是从具有公开DirectShow接口的FrameGrabber中获取原始视频。该图通过VMR9直接将视频显示出来,并通过ISampleGrabber(DirectShow示例)将原始帧暴露给一些算法。 2. 该图已经在单独的项目中构建并成功运行。视频正常显示,一切都很顺利。
现在的问题是当我将其集成到现有代码中时出现了问题。在初始化应用程序时,我首先创建并启动图形,以无窗口模式运行VMR9。稍后在初始化时,我通过_beginthreadex创建了一些工作线程。只有当构建并运行图形时,调用_beginthreadex才会返回12(内存不足)错误码。
显然,答案是我没有足够的内存或其他资源。然而,在线程尝试启动的时候,我使用了2GB系统内存的约420MB。线程堆栈大小已明确设置为1MB。因此,就我所知,我没有内存不足的问题。此外,运行的应用程序中共有15个线程,因此我没有创建过多的线程。
是否有人遇到过DirectShow的类似问题?我正在寻找任何输入,我们一直在尝试调试这个问题,但没有成功。
如果需要,我会发布您需要的任何代码,就像大多数DirectShow图形一样,代码很长。
编辑:
如所请求。我不确定DirectShow代码的哪个部分导致线程无法启动。但是,如果我只构建而不运行该图,则线程可以正常工作。因此,我猜测故障发生在运行调用之后。我的运行图形代码如下:
if (CurrentState != Stopped)
return WrongState;
HRESULT hr;
printf("Attempting to run graph... ");
Timer->Start();
hr = pMediaControl->Run();
if (FAILED(hr))
{
OAFilterState State;
hr = pMediaControl->GetState(1000, &State);
if ((SUCCEEDED(hr) && State != State_Running) || FAILED(hr))
{
return FailedToStartGraph;
}
}
CurrentState = Streaming;
SetVMRSize();
Timer->Stop();
RunTime->Start();
FrameRate->Reset();
return NoError;
SetVMRSize函数只是将VMR调整为其父窗口的大小:
void KontronGraph::SetVMRSize()
{
if (CurrentState == Disconnected || VideoMode != ParentWindow)
return;
long lWidth, lHeight;
HRESULT hr = pWindowController->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL);
if (SUCCEEDED(hr))
{
RECT rcSrc, rcDest;
// Set the source rectangle.
rcSrc.left = 0;
rcSrc.right = lWidth;
rcSrc.top = 0;
rcSrc.bottom = lHeight;
// Get the window client area.
GetClientRect(MyHwnd, &rcDest);
// Set the destination rectangle.
rcDest.right = rcDest.right - rcDest.left;
rcDest.bottom = rcDest.bottom - rcDest.top;
rcDest.left = 0;
rcDest.top = 0;
// Set the video position.
hr = pWindowController->SetVideoPosition(&rcSrc, &rcDest);
}
}
需要注意的是,pWindowController是IVMRWindowlessControl9
,而pMediaControl是IMediaControl
。
编辑2
使用CreateThread测试代码,而非__beginthreadex。在尝试启动线程后,GetLastError()返回:
8:没有足够的存储空间来处理此命令。
创建线程的代码如下:
HANDLE worker_thread = CreateThread(0,
Thread_Stack_Size, worker_thread_op, thread_param, 0, 0);
CreateThread的一些参数:
Thread_Stack_Size = 1024 * 1024;
typedef DWORD (WINAPI *worker_thread_op_type)(LPVOID params);