Не удается найти пин-код в фильтре DirectShow по имени / идентификатору, несмотря на то, что это идентификатор, возвращаемый QueryPinInfo
У меня странная проблема при разработке приложения DirectShow. Я использую Delphi 6 с библиотекой компонентов DSPACK DirectShow. Один из экземпляров IBaseFilter, похоже, не распознает принадлежащий ему вывод, когда я пытаюсь найти вывод в фильтре, используя его свойство TPinInfo.achName (_PinInfo). (Обратите внимание, что в этом случае именно IBaseFilter, созданный компонентом TSampleGrabber, демонстрирует это странное поведение).
Последовательность событий, инкапсулированная в следующем примере кода:
- Найдите первый доступный входной контакт в экземпляре IBaseFilter. В приведенном ниже коде это пин, переданный в testPinInfo().
- Выполните QueryPinInfo() на возвращенном выводе, чтобы получить эту информацию. В возвращенной информации ах-имя пина отображается как "Вход".
- Попробуйте найти пин-код "Input" в том же экземпляре IBaseFilter, используя IBaseFilter.findPin().
- Верните NIL, указывая, что не удалось найти пин-код с таким именем. Это, на мой взгляд, действительно странное условие (ошибка).
Кто-нибудь знает, какие условия могут вызвать этот сценарий? Я не думаю, что это проблема повреждения памяти, потому что структуры данных выглядят хорошо, когда я проверяю их в отладчике. Возможно ли, что некоторые реализации IBaseFilter пренебрегают для правильной реализации метода FindPin()?
Вот код ниже:
procedure testPinInfo(intfInputPin: IPin);
var
intfTestPin: IPin;
pinInfo_input: TPinInfo;
begin
intfTestPin := nil;
// Get the pin information.
ZeroMemory(@pinInfo_input, SizeOf(pinInfo_input));
intfInputPin.QueryPinInfo(pinInfo_input);
// Now immediately turn around and try to find the pin in the filter that
// owns it, using the name found in pinInfo_input
pinInfo_input.pFilter.FindPin(pinInfo_input.achName, intfTestPin);
// >>> intfTestPin is NIL (unassigned). This is an error.
end;
3 ответа
Не использовать FindPin
У вас всегда есть лучшие способы сделать это. Ищите неподключенный штифт нужного направления с интересующим вас типом носителя. Если вы ищете специально для предварительного просмотра / захвата булавки, у вас всегда есть возможность использовать IKsPropertySet
Интерфейс для однозначного определения необходимых контактов.
У меня была похожая проблема, поэтому я сделал свою собственную версию FindPin:
HRESULT GraphControl::FindPinByName(IBaseFilter* pFilter,LPCWSTR pName,IPin** ppPin)
{
HRESULT hr = E_FAIL;
IEnumPins* pEnum = NULL;
IPin* pPin = NULL;
DWORD pFetched = 0;
PIN_INFO pinInfo = {0};
// Create a pin enumerator
if(FAILED(pFilter->EnumPins(&pEnum)))
return E_FAIL;
// Get the first instance
hr = pEnum->Next(1,&pPin,&pFetched);
while( hr == S_OK )
{
pPin->QueryPinInfo(&pinInfo);
// Compare the names
if (wcscmp(pName,pinInfo.achName) == 0 )
{
// pin names match so use this one and exit
*ppPin = pPin;
break;
}
SAFE_RELEASE(pinInfo.pFilter);
SAFE_RELEASE(pPin);
hr = pEnum->Next(1,&pPin,&pFetched);
}
SAFE_RELEASE(pinInfo.pFilter);
SAFE_RELEASE(pEnum);
// if the pPin address is null we didnt find a pin with the wanted name
if(&*pPin == NULL)
hr = VFW_E_NOT_FOUND;
return hr;
}
Для FindPin вам нужен соответствующий Id, проверьте QueryId(). Для ввода это обычно "В".