У меня возникают некоторые странные проблемы при интеграции графа DirectShow в существующее приложение.
Несколько вещей, которые нужно охватить в первую очередь:
- Цель графика - получить необработанное видео изFrameGrabber с открытым интерфейсом DirectShow.График дает право видео отображать через VMR9, а также предоставляет необработанные кадры некоторым алгоритмам через ISampleGrabber (Примеры DirectShow).
- График был построен и успешно выполнен в отдельном проекте.Видео отображается нормально, и все хорошо.
Теперь возникает проблема, когда я интегрирую это в существующий код.После инициализации приложения я сначала создаю и запускаю график, запускающий VMR9 в режиме без окон.Позже в процессе инициализации я создаю пару рабочих потоков через _beginthreadex.Вызовы _beginthreadex завершаются неудачно с кодом возврата 12 (Недостаточно памяти), когда и ТОЛЬКО тогда, когда график построен и запущен.
Теперь очевидный ответ: у меня недостаточно памяти или, возможно, какой-то другой ресурс.Однако в тот момент, когда потоки пытаются запустить, я использую ~ 420 МБ системной памяти объемом 2 ГБ.Размер стека потока был явно установлен равным 1 МБ.Так что я не без памяти, насколько я могу судить.Кроме того, в запущенном приложении 15 потоков, поэтому я не создаю абсурдную сумму.
Кто-нибудь сталкивался с подобной проблемой DirectShow?Я вообще ищу какие-либо входные данные, мы пытались отладить эту проблему уже довольно давно и не увенчались успехом.
Я буду публиковать любой код, который вам требуется, как в большинстве графиков DirectShow, кодявляется длинным.
Редактировать
По запросу.Я не уверен, какая часть кода DirectShow приводит к сбою потоков.Однако, если я только строю, но не запускаю график, потоки работают нормально.Так что я бы догадался, что сбой происходит после вызова run.Мой код для запуска графика выглядит следующим образом:
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
и pMediaControlis IMediaControl
Edit 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);