1 /*
2  *  Copyright (c) 2011 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 #ifndef MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_HELP_FUNCTIONS_DS_H_
12 #define MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_HELP_FUNCTIONS_DS_H_
13 
14 #include <dshow.h>
15 
16 #include <type_traits>
17 #include <utility>
18 
19 #include "api/scoped_refptr.h"
20 #include "rtc_base/ref_counter.h"
21 
22 DEFINE_GUID(MEDIASUBTYPE_I420,
23             0x30323449,
24             0x0000,
25             0x0010,
26             0x80,
27             0x00,
28             0x00,
29             0xAA,
30             0x00,
31             0x38,
32             0x9B,
33             0x71);
34 DEFINE_GUID(MEDIASUBTYPE_HDYC,
35             0x43594448,
36             0x0000,
37             0x0010,
38             0x80,
39             0x00,
40             0x00,
41             0xAA,
42             0x00,
43             0x38,
44             0x9B,
45             0x71);
46 
47 #define RELEASE_AND_CLEAR(p) \
48   if (p) {                   \
49     (p)->Release();          \
50     (p) = NULL;              \
51   }
52 
53 namespace webrtc {
54 namespace videocapturemodule {
55 LONGLONG GetMaxOfFrameArray(LONGLONG* maxFps, long size);
56 
57 IPin* GetInputPin(IBaseFilter* filter);
58 IPin* GetOutputPin(IBaseFilter* filter, REFGUID Category);
59 BOOL PinMatchesCategory(IPin* pPin, REFGUID Category);
60 void ResetMediaType(AM_MEDIA_TYPE* media_type);
61 void FreeMediaType(AM_MEDIA_TYPE* media_type);
62 HRESULT CopyMediaType(AM_MEDIA_TYPE* target, const AM_MEDIA_TYPE* source);
63 
64 // Helper function to make using scoped_refptr with COM interface pointers
65 // a little less awkward. rtc::scoped_refptr doesn't support the & operator
66 // or a way to receive values via an out ptr.
67 // The function is intentionally not called QueryInterface to make things less
68 // confusing for the compiler to figure out what the caller wants to do when
69 // called from within the context of a class that also implements COM
70 // interfaces.
71 template <class T>
GetComInterface(IUnknown * object,rtc::scoped_refptr<T> * ptr)72 HRESULT GetComInterface(IUnknown* object, rtc::scoped_refptr<T>* ptr) {
73   // This helper function is not meant to magically free ptr. If we do that
74   // we add code bloat to most places where it's not needed and make the code
75   // less readable since it's not clear at the call site that the pointer
76   // would get freed even inf QI() fails.
77   RTC_DCHECK(!ptr->get());
78   void* new_ptr = nullptr;
79   HRESULT hr = object->QueryInterface(__uuidof(T), &new_ptr);
80   if (SUCCEEDED(hr))
81     ptr->swap(reinterpret_cast<T**>(&new_ptr));
82   return hr;
83 }
84 
85 // Provides a reference count implementation for COM (IUnknown derived) classes.
86 // The implementation uses atomics for managing the ref count.
87 template <class T>
88 class ComRefCount : public T {
89  public:
ComRefCount()90   ComRefCount() {}
91 
92   template <class P0>
ComRefCount(P0 && p0)93   explicit ComRefCount(P0&& p0) : T(std::forward<P0>(p0)) {}
94 
STDMETHOD_(ULONG,AddRef)95   STDMETHOD_(ULONG, AddRef)() override {
96     ref_count_.IncRef();
97     return 1;
98   }
99 
STDMETHOD_(ULONG,Release)100   STDMETHOD_(ULONG, Release)() override {
101     const auto status = ref_count_.DecRef();
102     if (status == rtc::RefCountReleaseStatus::kDroppedLastRef) {
103       delete this;
104       return 0;
105     }
106     return 1;
107   }
108 
109  protected:
~ComRefCount()110   ~ComRefCount() {}
111 
112  private:
113   webrtc::webrtc_impl::RefCounter ref_count_{0};
114 };
115 
116 }  // namespace videocapturemodule
117 }  // namespace webrtc
118 #endif  // MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_HELP_FUNCTIONS_DS_H_
119