Не хотел опять лезть с дурацкими вопросами, но как обычно
Имею массив сплиттеров GUID | Name
. Их надо в цикле перебрать и взять первый успешно подключенный. Подключение первого в списке проходит успешно. Но пин для подключения видео-декодера у него отсутствует. Это значит, что сплиттер не смог правильно распознать контейнер. Для сплиттеров это обычная ситуация. Пока не подключишь сплиттер - не узнаешь. По-этому, собственно, и нужен перебор. В таком случае надо отключить текущий сплиттер и перейти к следующему.
Но проблема в том, что следующие сплиттеры при попытке подключения будут выдавать ошибку VFW_E_CANNOT_CONNECT
. Даже если их не перебирать, а просто подключить / отключить / подключить один и тот же сплиттер - будет та же ошибка.
private int FindAndConnectMediaSplitter_Manual(IEnumerable<FilterItem> splitters, IPin sourcePinOut)
{
foreach (FilterItem item in splitters)
{
int errorCode = CreateDirectShowFilter(item.GetGuid(), out IBaseFilter filter);
if (errorCode != S_OK)
{
System.Diagnostics.Debug.WriteLine($"Loading {item.DisplayName}: {ErrorCodeToString(errorCode)}");
continue;
}
System.Diagnostics.Debug.WriteLine($"Loading {item.DisplayName}: S_OK");
graphBuilder.AddFilter(filter, item.DisplayName);
FindPin(filter, 0, PinDirection.Input, out IPin pinIn);
errorCode = graphBuilder.Connect(sourcePinOut, pinIn);
if (errorCode != S_OK)
{
System.Diagnostics.Debug.WriteLine($"Connecting {item.DisplayName}: {ErrorCodeToString(errorCode)}");
graphBuilder.RemoveFilter(filter);
Marshal.ReleaseComObject(filter);
continue;
}
System.Diagnostics.Debug.WriteLine($"Connecting {item.DisplayName}: S_OK");
FindPin(filter, "ideo", PinDirection.Output, out IPin splitterPinOut);
if (splitterPinOut == null)
{
System.Diagnostics.Debug.WriteLine("Video output pin not found! Skipping this bad bad filter.");
graphBuilder.Disconnect(pinIn);
graphBuilder.RemoveFilter(filter);
Marshal.ReleaseComObject(filter);
continue;
}
mediaSplitter = filter;
return errorCode;
}
System.Diagnostics.Debug.WriteLine("No one valid media splitter found!");
return S_FALSE;
}
На Delphi такой алгоритм работает.
Если коротко, то проблема в следующем:
errorCode = graphBuilder.Connect(sourcePinOut, pinIn); //S_OK
errorCode = graphBuilder.Disconnect(pinIn); //S_OK
errorCode = graphBuilder.Connect(sourcePinOut, pinIn); //VFW_E_CANNOT_CONNECT