1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <initguid.h>  // Must come before the help_functions_ds.h include so
12                        // that DEFINE_GUID() entries will be defined in this
13                        // object file.
14 
15 #include <cguid.h>
16 
17 #include "modules/video_capture/windows/help_functions_ds.h"
18 #include "rtc_base/logging.h"
19 
20 namespace webrtc {
21 namespace videocapturemodule {
22 // This returns minimum :), which will give max frame rate...
GetMaxOfFrameArray(LONGLONG * maxFps,long size)23 LONGLONG GetMaxOfFrameArray(LONGLONG* maxFps, long size) {
24   LONGLONG maxFPS = maxFps[0];
25   for (int i = 0; i < size; i++) {
26     if (maxFPS > maxFps[i])
27       maxFPS = maxFps[i];
28   }
29   return maxFPS;
30 }
31 
GetInputPin(IBaseFilter * filter)32 IPin* GetInputPin(IBaseFilter* filter) {
33   HRESULT hr;
34   IPin* pin = NULL;
35   IEnumPins* pPinEnum = NULL;
36   filter->EnumPins(&pPinEnum);
37   if (pPinEnum == NULL) {
38     return NULL;
39   }
40 
41   // get first unconnected pin
42   hr = pPinEnum->Reset();  // set to first pin
43 
44   while (S_OK == pPinEnum->Next(1, &pin, NULL)) {
45     PIN_DIRECTION pPinDir;
46     pin->QueryDirection(&pPinDir);
47     if (PINDIR_INPUT == pPinDir)  // This is an input pin
48     {
49       IPin* tempPin = NULL;
50       if (S_OK != pin->ConnectedTo(&tempPin))  // The pint is not connected
51       {
52         pPinEnum->Release();
53         return pin;
54       }
55     }
56     pin->Release();
57   }
58   pPinEnum->Release();
59   return NULL;
60 }
61 
GetOutputPin(IBaseFilter * filter,REFGUID Category)62 IPin* GetOutputPin(IBaseFilter* filter, REFGUID Category) {
63   HRESULT hr;
64   IPin* pin = NULL;
65   IEnumPins* pPinEnum = NULL;
66   filter->EnumPins(&pPinEnum);
67   if (pPinEnum == NULL) {
68     return NULL;
69   }
70   // get first unconnected pin
71   hr = pPinEnum->Reset();  // set to first pin
72   while (S_OK == pPinEnum->Next(1, &pin, NULL)) {
73     PIN_DIRECTION pPinDir;
74     pin->QueryDirection(&pPinDir);
75     if (PINDIR_OUTPUT == pPinDir)  // This is an output pin
76     {
77       if (Category == GUID_NULL || PinMatchesCategory(pin, Category)) {
78         pPinEnum->Release();
79         return pin;
80       }
81     }
82     pin->Release();
83     pin = NULL;
84   }
85   pPinEnum->Release();
86   return NULL;
87 }
88 
PinMatchesCategory(IPin * pPin,REFGUID Category)89 BOOL PinMatchesCategory(IPin* pPin, REFGUID Category) {
90   BOOL bFound = FALSE;
91   IKsPropertySet* pKs = NULL;
92   HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs));
93   if (SUCCEEDED(hr)) {
94     GUID PinCategory;
95     DWORD cbReturned;
96     hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
97                   &PinCategory, sizeof(GUID), &cbReturned);
98     if (SUCCEEDED(hr) && (cbReturned == sizeof(GUID))) {
99       bFound = (PinCategory == Category);
100     }
101     pKs->Release();
102   }
103   return bFound;
104 }
105 
ResetMediaType(AM_MEDIA_TYPE * media_type)106 void ResetMediaType(AM_MEDIA_TYPE* media_type) {
107   if (!media_type)
108     return;
109   if (media_type->cbFormat != 0) {
110     CoTaskMemFree(media_type->pbFormat);
111     media_type->cbFormat = 0;
112     media_type->pbFormat = nullptr;
113   }
114   if (media_type->pUnk) {
115     media_type->pUnk->Release();
116     media_type->pUnk = nullptr;
117   }
118 }
119 
FreeMediaType(AM_MEDIA_TYPE * media_type)120 void FreeMediaType(AM_MEDIA_TYPE* media_type) {
121   if (!media_type)
122     return;
123   ResetMediaType(media_type);
124   CoTaskMemFree(media_type);
125 }
126 
CopyMediaType(AM_MEDIA_TYPE * target,const AM_MEDIA_TYPE * source)127 HRESULT CopyMediaType(AM_MEDIA_TYPE* target, const AM_MEDIA_TYPE* source) {
128   RTC_DCHECK_NE(source, target);
129   *target = *source;
130   if (source->cbFormat != 0) {
131     RTC_DCHECK(source->pbFormat);
132     target->pbFormat =
133         reinterpret_cast<BYTE*>(CoTaskMemAlloc(source->cbFormat));
134     if (target->pbFormat == nullptr) {
135       target->cbFormat = 0;
136       return E_OUTOFMEMORY;
137     } else {
138       CopyMemory(target->pbFormat, source->pbFormat, target->cbFormat);
139     }
140   }
141 
142   if (target->pUnk != nullptr)
143     target->pUnk->AddRef();
144 
145   return S_OK;
146 }
147 
DuplicateWideString(const wchar_t * str)148 wchar_t* DuplicateWideString(const wchar_t* str) {
149   size_t len = lstrlenW(str);
150   wchar_t* ret =
151       reinterpret_cast<LPWSTR>(CoTaskMemAlloc((len + 1) * sizeof(wchar_t)));
152   lstrcpyW(ret, str);
153   return ret;
154 }
155 
156 }  // namespace videocapturemodule
157 }  // namespace webrtc
158