dshow_capture.h
Go to the documentation of this file.
1 /*
2  * DirectShow capture interface
3  * Copyright (c) 2010 Ramiro Polla
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #ifndef AVDEVICE_DSHOW_H
23 #define AVDEVICE_DSHOW_H
24 
25 #define DSHOWDEBUG 0
26 
27 #include "avdevice.h"
28 
29 #define COBJMACROS
30 #include <windows.h>
31 #define NO_DSHOW_STRSAFE
32 #include <dshow.h>
33 #include <dvdmedia.h>
34 
35 /* EC_DEVICE_LOST is not defined in MinGW dshow headers. */
36 #ifndef EC_DEVICE_LOST
37 #define EC_DEVICE_LOST 0x1f
38 #endif
39 
40 long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src);
41 void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps);
42 void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps);
43 void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type);
44 void ff_printGUID(const GUID *g);
45 
46 #if DSHOWDEBUG
48 #define dshowdebug(...) av_log(&ff_dshow_context_class_ptr, AV_LOG_DEBUG, __VA_ARGS__)
49 #else
50 #define dshowdebug(...)
51 #endif
52 
53 static inline void nothing(void *foo)
54 {
55 }
56 
57 struct GUIDoffset {
58  const GUID *iid;
59  int offset;
60 };
61 
65 };
66 
67 #define DECLARE_QUERYINTERFACE(class, ...) \
68 long WINAPI \
69 class##_QueryInterface(class *this, const GUID *riid, void **ppvObject) \
70 { \
71  struct GUIDoffset ifaces[] = __VA_ARGS__; \
72  int i; \
73  dshowdebug(AV_STRINGIFY(class)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \
74  ff_printGUID(riid); \
75  if (!ppvObject) \
76  return E_POINTER; \
77  for (i = 0; i < sizeof(ifaces)/sizeof(ifaces[0]); i++) { \
78  if (IsEqualGUID(riid, ifaces[i].iid)) { \
79  void *obj = (void *) ((uint8_t *) this + ifaces[i].offset); \
80  class##_AddRef(this); \
81  dshowdebug("\tfound %d with offset %d\n", i, ifaces[i].offset); \
82  *ppvObject = (void *) obj; \
83  return S_OK; \
84  } \
85  } \
86  dshowdebug("\tE_NOINTERFACE\n"); \
87  *ppvObject = NULL; \
88  return E_NOINTERFACE; \
89 }
90 #define DECLARE_ADDREF(class) \
91 unsigned long WINAPI \
92 class##_AddRef(class *this) \
93 { \
94  dshowdebug(AV_STRINGIFY(class)"_AddRef(%p)\t%ld\n", this, this->ref+1); \
95  return InterlockedIncrement(&this->ref); \
96 }
97 #define DECLARE_RELEASE(class) \
98 unsigned long WINAPI \
99 class##_Release(class *this) \
100 { \
101  long ref = InterlockedDecrement(&this->ref); \
102  dshowdebug(AV_STRINGIFY(class)"_Release(%p)\t%ld\n", this, ref); \
103  if (!ref) \
104  class##_Destroy(this); \
105  return ref; \
106 }
107 
108 #define DECLARE_DESTROY(class, func) \
109 void class##_Destroy(class *this) \
110 { \
111  dshowdebug(AV_STRINGIFY(class)"_Destroy(%p)\n", this); \
112  func(this); \
113  if (this) { \
114  if (this->vtbl) \
115  CoTaskMemFree(this->vtbl); \
116  CoTaskMemFree(this); \
117  } \
118 }
119 #define DECLARE_CREATE(class, setup, ...) \
120 class *class##_Create(__VA_ARGS__) \
121 { \
122  class *this = CoTaskMemAlloc(sizeof(class)); \
123  void *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \
124  dshowdebug(AV_STRINGIFY(class)"_Create(%p)\n", this); \
125  if (!this || !vtbl) \
126  goto fail; \
127  ZeroMemory(this, sizeof(class)); \
128  ZeroMemory(vtbl, sizeof(*this->vtbl)); \
129  this->ref = 1; \
130  this->vtbl = vtbl; \
131  if (!setup) \
132  goto fail; \
133  dshowdebug("created "AV_STRINGIFY(class)" %p\n", this); \
134  return this; \
135 fail: \
136  class##_Destroy(this); \
137  dshowdebug("could not create "AV_STRINGIFY(class)"\n"); \
138  return NULL; \
139 }
140 
141 #define SETVTBL(vtbl, class, fn) \
142  do { (vtbl)->fn = (void *) class##_##fn; } while(0)
143 
144 /*****************************************************************************
145  * Forward Declarations
146  ****************************************************************************/
147 typedef struct libAVPin libAVPin;
151 typedef struct libAVFilter libAVFilter;
152 
153 /*****************************************************************************
154  * libAVPin
155  ****************************************************************************/
156 struct libAVPin {
157  IPinVtbl *vtbl;
158  long ref;
160  IPin *connectedto;
161  AM_MEDIA_TYPE type;
162  IMemInputPinVtbl *imemvtbl;
163 };
164 
165 long WINAPI libAVPin_QueryInterface (libAVPin *, const GUID *, void **);
166 unsigned long WINAPI libAVPin_AddRef (libAVPin *);
167 unsigned long WINAPI libAVPin_Release (libAVPin *);
168 long WINAPI libAVPin_Connect (libAVPin *, IPin *, const AM_MEDIA_TYPE *);
169 long WINAPI libAVPin_ReceiveConnection (libAVPin *, IPin *, const AM_MEDIA_TYPE *);
170 long WINAPI libAVPin_Disconnect (libAVPin *);
171 long WINAPI libAVPin_ConnectedTo (libAVPin *, IPin **);
172 long WINAPI libAVPin_ConnectionMediaType (libAVPin *, AM_MEDIA_TYPE *);
173 long WINAPI libAVPin_QueryPinInfo (libAVPin *, PIN_INFO *);
174 long WINAPI libAVPin_QueryDirection (libAVPin *, PIN_DIRECTION *);
175 long WINAPI libAVPin_QueryId (libAVPin *, wchar_t **);
176 long WINAPI libAVPin_QueryAccept (libAVPin *, const AM_MEDIA_TYPE *);
177 long WINAPI libAVPin_EnumMediaTypes (libAVPin *, IEnumMediaTypes **);
178 long WINAPI libAVPin_QueryInternalConnections(libAVPin *, IPin **, unsigned long *);
179 long WINAPI libAVPin_EndOfStream (libAVPin *);
180 long WINAPI libAVPin_BeginFlush (libAVPin *);
181 long WINAPI libAVPin_EndFlush (libAVPin *);
182 long WINAPI libAVPin_NewSegment (libAVPin *, REFERENCE_TIME, REFERENCE_TIME, double);
183 
184 long WINAPI libAVMemInputPin_QueryInterface (libAVMemInputPin *, const GUID *, void **);
185 unsigned long WINAPI libAVMemInputPin_AddRef (libAVMemInputPin *);
186 unsigned long WINAPI libAVMemInputPin_Release (libAVMemInputPin *);
187 long WINAPI libAVMemInputPin_GetAllocator (libAVMemInputPin *, IMemAllocator **);
188 long WINAPI libAVMemInputPin_NotifyAllocator (libAVMemInputPin *, IMemAllocator *, BOOL);
189 long WINAPI libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *, ALLOCATOR_PROPERTIES *);
190 long WINAPI libAVMemInputPin_Receive (libAVMemInputPin *, IMediaSample *);
191 long WINAPI libAVMemInputPin_ReceiveMultiple (libAVMemInputPin *, IMediaSample **, long, long *);
193 
194 void libAVPin_Destroy(libAVPin *);
196 
198 
199 /*****************************************************************************
200  * libAVEnumPins
201  ****************************************************************************/
203  IEnumPinsVtbl *vtbl;
204  long ref;
205  int pos;
208 };
209 
210 long WINAPI libAVEnumPins_QueryInterface(libAVEnumPins *, const GUID *, void **);
211 unsigned long WINAPI libAVEnumPins_AddRef (libAVEnumPins *);
212 unsigned long WINAPI libAVEnumPins_Release (libAVEnumPins *);
213 long WINAPI libAVEnumPins_Next (libAVEnumPins *, unsigned long, IPin **, unsigned long *);
214 long WINAPI libAVEnumPins_Skip (libAVEnumPins *, unsigned long);
215 long WINAPI libAVEnumPins_Reset (libAVEnumPins *);
217 
220 
221 /*****************************************************************************
222  * libAVEnumMediaTypes
223  ****************************************************************************/
225  IEnumPinsVtbl *vtbl;
226  long ref;
227  int pos;
228  AM_MEDIA_TYPE type;
229 };
230 
231 long WINAPI libAVEnumMediaTypes_QueryInterface(libAVEnumMediaTypes *, const GUID *, void **);
232 unsigned long WINAPI libAVEnumMediaTypes_AddRef (libAVEnumMediaTypes *);
233 unsigned long WINAPI libAVEnumMediaTypes_Release (libAVEnumMediaTypes *);
234 long WINAPI libAVEnumMediaTypes_Next (libAVEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *);
235 long WINAPI libAVEnumMediaTypes_Skip (libAVEnumMediaTypes *, unsigned long);
238 
241 
242 /*****************************************************************************
243  * libAVFilter
244  ****************************************************************************/
245 struct libAVFilter {
246  IBaseFilterVtbl *vtbl;
247  long ref;
248  const wchar_t *name;
250  FILTER_INFO info;
251  FILTER_STATE state;
252  IReferenceClock *clock;
254  void *priv_data;
256  int64_t start_time;
257  void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time);
258 };
259 
260 long WINAPI libAVFilter_QueryInterface (libAVFilter *, const GUID *, void **);
261 unsigned long WINAPI libAVFilter_AddRef (libAVFilter *);
262 unsigned long WINAPI libAVFilter_Release (libAVFilter *);
263 long WINAPI libAVFilter_GetClassID (libAVFilter *, CLSID *);
264 long WINAPI libAVFilter_Stop (libAVFilter *);
265 long WINAPI libAVFilter_Pause (libAVFilter *);
266 long WINAPI libAVFilter_Run (libAVFilter *, REFERENCE_TIME);
267 long WINAPI libAVFilter_GetState (libAVFilter *, DWORD, FILTER_STATE *);
268 long WINAPI libAVFilter_SetSyncSource (libAVFilter *, IReferenceClock *);
269 long WINAPI libAVFilter_GetSyncSource (libAVFilter *, IReferenceClock **);
270 long WINAPI libAVFilter_EnumPins (libAVFilter *, IEnumPins **);
271 long WINAPI libAVFilter_FindPin (libAVFilter *, const wchar_t *, IPin **);
272 long WINAPI libAVFilter_QueryFilterInfo(libAVFilter *, FILTER_INFO *);
273 long WINAPI libAVFilter_JoinFilterGraph(libAVFilter *, IFilterGraph *, const wchar_t *);
274 long WINAPI libAVFilter_QueryVendorInfo(libAVFilter *, wchar_t **);
275 
277 libAVFilter *libAVFilter_Create (void *, void *, enum dshowDeviceType);
278 
279 #endif /* AVDEVICE_DSHOW_H */
void libAVEnumPins_Destroy(libAVEnumPins *)
void libAVEnumMediaTypes_Destroy(libAVEnumMediaTypes *)
void libAVMemInputPin_Destroy(libAVMemInputPin *)
Definition: dshow_pin.c:357
long WINAPI libAVMemInputPin_GetAllocator(libAVMemInputPin *, IMemAllocator **)
Definition: dshow_pin.c:281
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
Definition: dshow.c:200
libAVPin * libAVPin_Create(libAVFilter *filter)
long WINAPI libAVFilter_Pause(libAVFilter *)
Definition: dshow_filter.c:44
void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:85
long WINAPI libAVPin_EndFlush(libAVPin *)
Definition: dshow_pin.c:189
long WINAPI libAVMemInputPin_ReceiveMultiple(libAVMemInputPin *, IMediaSample **, long, long *)
Definition: dshow_pin.c:336
long WINAPI libAVMemInputPin_NotifyAllocator(libAVMemInputPin *, IMemAllocator *, BOOL)
Definition: dshow_pin.c:287
unsigned long WINAPI libAVPin_Release(libAVPin *)
dshowDeviceType
Definition: dshow_capture.h:62
long WINAPI libAVEnumMediaTypes_Skip(libAVEnumMediaTypes *, unsigned long)
long WINAPI libAVFilter_EnumPins(libAVFilter *, IEnumPins **)
Definition: dshow_filter.c:96
long WINAPI libAVFilter_Stop(libAVFilter *)
Definition: dshow_filter.c:37
long WINAPI libAVPin_ReceiveConnection(libAVPin *, IPin *, const AM_MEDIA_TYPE *)
Definition: dshow_pin.c:40
long WINAPI libAVMemInputPin_Receive(libAVMemInputPin *, IMediaSample *)
Definition: dshow_pin.c:301
unsigned long WINAPI libAVEnumMediaTypes_Release(libAVEnumMediaTypes *)
long WINAPI libAVPin_QueryPinInfo(libAVPin *, PIN_INFO *)
Definition: dshow_pin.c:108
long WINAPI libAVPin_EndOfStream(libAVPin *)
Definition: dshow_pin.c:175
long WINAPI libAVPin_QueryId(libAVPin *, wchar_t **)
Definition: dshow_pin.c:134
long WINAPI libAVPin_NewSegment(libAVPin *, REFERENCE_TIME, REFERENCE_TIME, double)
Definition: dshow_pin.c:196
long WINAPI libAVEnumPins_Reset(libAVEnumPins *)
IReferenceClock * clock
long WINAPI libAVFilter_SetSyncSource(libAVFilter *, IReferenceClock *)
Definition: dshow_filter.c:68
void libAVPin_Destroy(libAVPin *)
long WINAPI libAVEnumMediaTypes_Next(libAVEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *)
long WINAPI libAVMemInputPin_ReceiveCanBlock(libAVMemInputPin *)
Definition: dshow_pin.c:349
uint8_t
static void foo(struct pullup_context *c)
Definition: pullup.c:570
long WINAPI libAVPin_EnumMediaTypes(libAVPin *, IEnumMediaTypes **)
Definition: dshow_pin.c:152
long WINAPI libAVFilter_QueryInterface(libAVFilter *, const GUID *, void **)
libAVFilter * libAVFilter_Create(void *, void *, enum dshowDeviceType)
long WINAPI libAVPin_Connect(libAVPin *, IPin *, const AM_MEDIA_TYPE *)
long WINAPI libAVEnumMediaTypes_Clone(libAVEnumMediaTypes *, libAVEnumMediaTypes **)
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
long WINAPI libAVPin_QueryInternalConnections(libAVPin *, IPin **, unsigned long *)
Definition: dshow_pin.c:168
const wchar_t * name
unsigned long WINAPI libAVEnumMediaTypes_AddRef(libAVEnumMediaTypes *)
Main libavdevice API header.
long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src)
Definition: dshow_common.c:24
unsigned long WINAPI libAVEnumPins_AddRef(libAVEnumPins *)
long WINAPI libAVPin_BeginFlush(libAVPin *)
Definition: dshow_pin.c:182
AM_MEDIA_TYPE type
long WINAPI libAVEnumPins_QueryInterface(libAVEnumPins *, const GUID *, void **)
long WINAPI libAVFilter_FindPin(libAVFilter *, const wchar_t *, IPin **)
Definition: dshow_filter.c:111
unsigned long WINAPI libAVPin_AddRef(libAVPin *)
long WINAPI libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *, ALLOCATOR_PROPERTIES *)
Definition: dshow_pin.c:294
void * priv_data
FFT buffer for g
Definition: stft_peak.m:17
long WINAPI libAVEnumPins_Next(libAVEnumPins *, unsigned long, IPin **, unsigned long *)
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:115
unsigned long WINAPI libAVMemInputPin_AddRef(libAVMemInputPin *)
Definition: dshow_pin.c:267
libAVPin * pin
long WINAPI libAVPin_ConnectedTo(libAVPin *, IPin **)
Definition: dshow_pin.c:82
FILTER_STATE state
const AVClass * ff_dshow_context_class_ptr
Definition: dshow_common.c:60
long WINAPI libAVFilter_GetSyncSource(libAVFilter *, IReferenceClock **)
Definition: dshow_filter.c:83
long WINAPI libAVFilter_JoinFilterGraph(libAVFilter *, IFilterGraph *, const wchar_t *)
Definition: dshow_filter.c:142
long WINAPI libAVMemInputPin_QueryInterface(libAVMemInputPin *, const GUID *, void **)
Definition: dshow_pin.c:259
AVS_Value src
Definition: avisynth_c.h:523
IPin * connectedto
IBaseFilterVtbl * vtbl
typedef void(RENAME(mix_any_func_type))
long WINAPI libAVFilter_QueryFilterInfo(libAVFilter *, FILTER_INFO *)
Definition: dshow_filter.c:129
void ff_printGUID(const GUID *g)
Definition: dshow_common.c:42
unsigned long WINAPI libAVMemInputPin_Release(libAVMemInputPin *)
Definition: dshow_pin.c:274
libAVPin * pin
IPinVtbl * vtbl
void * buf
Definition: avisynth_c.h:594
unsigned long WINAPI libAVFilter_AddRef(libAVFilter *)
Describe the class of an AVClass context structure.
Definition: log.h:50
int index
Definition: gxfenc.c:89
AM_MEDIA_TYPE type
IEnumPinsVtbl * vtbl
const GUID * iid
Definition: dshow_capture.h:58
uint32_t DWORD
#define type
static void nothing(void *foo)
Definition: dshow_capture.h:53
libAVEnumPins * libAVEnumPins_Create(libAVPin *pin, libAVFilter *filter)
IEnumPinsVtbl * vtbl
long WINAPI libAVPin_Disconnect(libAVPin *)
Definition: dshow_pin.c:68
long WINAPI libAVPin_QueryAccept(libAVPin *, const AM_MEDIA_TYPE *)
Definition: dshow_pin.c:146
int64_t start_time
IMemInputPinVtbl * imemvtbl
long WINAPI libAVPin_QueryInterface(libAVPin *, const GUID *, void **)
long WINAPI libAVPin_QueryDirection(libAVPin *, PIN_DIRECTION *)
Definition: dshow_pin.c:125
unsigned long WINAPI libAVFilter_Release(libAVFilter *)
long WINAPI libAVFilter_Run(libAVFilter *, REFERENCE_TIME)
Definition: dshow_filter.c:51
long WINAPI libAVEnumMediaTypes_Reset(libAVEnumMediaTypes *)
long WINAPI libAVPin_ConnectionMediaType(libAVPin *, AM_MEDIA_TYPE *)
Definition: dshow_pin.c:96
uint32_t BOOL
long WINAPI libAVEnumPins_Skip(libAVEnumPins *, unsigned long)
half analysis window size pin
libAVFilter * filter
unsigned long WINAPI libAVEnumPins_Release(libAVEnumPins *)
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
libAVEnumMediaTypes * libAVEnumMediaTypes_Create(const AM_MEDIA_TYPE *type)
long WINAPI libAVFilter_GetState(libAVFilter *, DWORD, FILTER_STATE *)
Definition: dshow_filter.c:59
void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type)
Definition: dshow_common.c:134
long WINAPI libAVFilter_GetClassID(libAVFilter *, CLSID *)
struct libAVMemInputPin libAVMemInputPin
FILTER_INFO info
void libAVFilter_Destroy(libAVFilter *)
libAVFilter * filter
long WINAPI libAVFilter_QueryVendorInfo(libAVFilter *, wchar_t **)
Definition: dshow_filter.c:154
long WINAPI libAVEnumMediaTypes_QueryInterface(libAVEnumMediaTypes *, const GUID *, void **)
long WINAPI libAVEnumPins_Clone(libAVEnumPins *, libAVEnumPins **)