/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include // Must come before the help_functions_ds.h include so // that DEFINE_GUID() entries will be defined in this // object file. #include #include "modules/video_capture/windows/help_functions_ds.h" #include "rtc_base/logging.h" namespace webrtc { namespace videocapturemodule { // This returns minimum :), which will give max frame rate... LONGLONG GetMaxOfFrameArray(LONGLONG* maxFps, long size) { LONGLONG maxFPS = maxFps[0]; for (int i = 0; i < size; i++) { if (maxFPS > maxFps[i]) maxFPS = maxFps[i]; } return maxFPS; } IPin* GetInputPin(IBaseFilter* filter) { HRESULT hr; IPin* pin = NULL; IEnumPins* pPinEnum = NULL; filter->EnumPins(&pPinEnum); if (pPinEnum == NULL) { return NULL; } // get first unconnected pin hr = pPinEnum->Reset(); // set to first pin while (S_OK == pPinEnum->Next(1, &pin, NULL)) { PIN_DIRECTION pPinDir; pin->QueryDirection(&pPinDir); if (PINDIR_INPUT == pPinDir) // This is an input pin { IPin* tempPin = NULL; if (S_OK != pin->ConnectedTo(&tempPin)) // The pint is not connected { pPinEnum->Release(); return pin; } } pin->Release(); } pPinEnum->Release(); return NULL; } IPin* GetOutputPin(IBaseFilter* filter, REFGUID Category) { HRESULT hr; IPin* pin = NULL; IEnumPins* pPinEnum = NULL; filter->EnumPins(&pPinEnum); if (pPinEnum == NULL) { return NULL; } // get first unconnected pin hr = pPinEnum->Reset(); // set to first pin while (S_OK == pPinEnum->Next(1, &pin, NULL)) { PIN_DIRECTION pPinDir; pin->QueryDirection(&pPinDir); if (PINDIR_OUTPUT == pPinDir) // This is an output pin { if (Category == GUID_NULL || PinMatchesCategory(pin, Category)) { pPinEnum->Release(); return pin; } } pin->Release(); pin = NULL; } pPinEnum->Release(); return NULL; } BOOL PinMatchesCategory(IPin* pPin, REFGUID Category) { BOOL bFound = FALSE; IKsPropertySet* pKs = NULL; HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs)); if (SUCCEEDED(hr)) { GUID PinCategory; DWORD cbReturned; hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, &PinCategory, sizeof(GUID), &cbReturned); if (SUCCEEDED(hr) && (cbReturned == sizeof(GUID))) { bFound = (PinCategory == Category); } pKs->Release(); } return bFound; } void ResetMediaType(AM_MEDIA_TYPE* media_type) { if (!media_type) return; if (media_type->cbFormat != 0) { CoTaskMemFree(media_type->pbFormat); media_type->cbFormat = 0; media_type->pbFormat = nullptr; } if (media_type->pUnk) { media_type->pUnk->Release(); media_type->pUnk = nullptr; } } void FreeMediaType(AM_MEDIA_TYPE* media_type) { if (!media_type) return; ResetMediaType(media_type); CoTaskMemFree(media_type); } HRESULT CopyMediaType(AM_MEDIA_TYPE* target, const AM_MEDIA_TYPE* source) { RTC_DCHECK_NE(source, target); *target = *source; if (source->cbFormat != 0) { RTC_DCHECK(source->pbFormat); target->pbFormat = reinterpret_cast(CoTaskMemAlloc(source->cbFormat)); if (target->pbFormat == nullptr) { target->cbFormat = 0; return E_OUTOFMEMORY; } else { CopyMemory(target->pbFormat, source->pbFormat, target->cbFormat); } } if (target->pUnk != nullptr) target->pUnk->AddRef(); return S_OK; } wchar_t* DuplicateWideString(const wchar_t* str) { size_t len = lstrlenW(str); wchar_t* ret = reinterpret_cast(CoTaskMemAlloc((len + 1) * sizeof(wchar_t))); lstrcpyW(ret, str); return ret; } } // namespace videocapturemodule } // namespace webrtc