FFmpeg  4.4
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_CAPTURE_H
23 #define AVDEVICE_DSHOW_CAPTURE_H
24 
25 #define DSHOWDEBUG 0
26 
27 #include "avdevice.h"
28 
29 #define COBJMACROS
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
32 #define NO_DSHOW_STRSAFE
33 #include <dshow.h>
34 #include <dvdmedia.h>
35 
36 #include "libavcodec/internal.h"
38 
39 /* EC_DEVICE_LOST is not defined in MinGW dshow headers. */
40 #ifndef EC_DEVICE_LOST
41 #define EC_DEVICE_LOST 0x1f
42 #endif
43 
44 long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src);
45 void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps);
46 void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps);
47 void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type);
48 void ff_printGUID(const GUID *g);
49 
51 #define dshowdebug(...) ff_dlog(&ff_dshow_context_class_ptr, __VA_ARGS__)
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 
70 };
71 
72 #define DECLARE_QUERYINTERFACE(prefix, class, ...) \
73 long \
74 ff_dshow_##prefix##_QueryInterface(class *this, const GUID *riid, void **ppvObject) \
75 { \
76  struct GUIDoffset ifaces[] = __VA_ARGS__; \
77  int i; \
78  dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \
79  ff_printGUID(riid); \
80  if (!ppvObject) \
81  return E_POINTER; \
82  for (i = 0; i < sizeof(ifaces)/sizeof(ifaces[0]); i++) { \
83  if (IsEqualGUID(riid, ifaces[i].iid)) { \
84  void *obj = (void *) ((uint8_t *) this + ifaces[i].offset); \
85  ff_dshow_##prefix##_AddRef(this); \
86  dshowdebug("\tfound %d with offset %d\n", i, ifaces[i].offset); \
87  *ppvObject = (void *) obj; \
88  return S_OK; \
89  } \
90  } \
91  dshowdebug("\tE_NOINTERFACE\n"); \
92  *ppvObject = NULL; \
93  return E_NOINTERFACE; \
94 }
95 #define DECLARE_ADDREF(prefix, class) \
96 unsigned long \
97 ff_dshow_##prefix##_AddRef(class *this) \
98 { \
99  dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_AddRef(%p)\t%ld\n", this, this->ref+1); \
100  return InterlockedIncrement(&this->ref); \
101 }
102 #define DECLARE_RELEASE(prefix, class) \
103 unsigned long \
104 ff_dshow_##prefix##_Release(class *this) \
105 { \
106  long ref = InterlockedDecrement(&this->ref); \
107  dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Release(%p)\t%ld\n", this, ref); \
108  if (!ref) \
109  ff_dshow_##prefix##_Destroy(this); \
110  return ref; \
111 }
112 
113 #define DECLARE_DESTROY(prefix, class, func) \
114 void ff_dshow_##prefix##_Destroy(class *this) \
115 { \
116  dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Destroy(%p)\n", this); \
117  func(this); \
118  if (this) { \
119  if (this->vtbl) \
120  CoTaskMemFree(this->vtbl); \
121  CoTaskMemFree(this); \
122  } \
123 }
124 #define DECLARE_CREATE(prefix, class, setup, ...) \
125 class *ff_dshow_##prefix##_Create(__VA_ARGS__) \
126 { \
127  class *this = CoTaskMemAlloc(sizeof(class)); \
128  void *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \
129  dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Create(%p)\n", this); \
130  if (!this || !vtbl) \
131  goto fail; \
132  ZeroMemory(this, sizeof(class)); \
133  ZeroMemory(vtbl, sizeof(*this->vtbl)); \
134  this->ref = 1; \
135  this->vtbl = vtbl; \
136  if (!setup) \
137  goto fail; \
138  dshowdebug("created ff_dshow_"AV_STRINGIFY(prefix)" %p\n", this); \
139  return this; \
140 fail: \
141  ff_dshow_##prefix##_Destroy(this); \
142  dshowdebug("could not create ff_dshow_"AV_STRINGIFY(prefix)"\n"); \
143  return NULL; \
144 }
145 
146 #define SETVTBL(vtbl, prefix, fn) \
147  do { (vtbl)->fn = (void *) ff_dshow_##prefix##_##fn; } while(0)
148 
149 /*****************************************************************************
150  * Forward Declarations
151  ****************************************************************************/
152 typedef struct DShowPin DShowPin;
153 typedef struct DShowMemInputPin DShowMemInputPin;
154 typedef struct DShowEnumPins DShowEnumPins;
156 typedef struct DShowFilter DShowFilter;
157 
158 /*****************************************************************************
159  * DShowPin
160  ****************************************************************************/
161 struct DShowPin {
162  IPinVtbl *vtbl;
163  long ref;
165  IPin *connectedto;
166  AM_MEDIA_TYPE type;
167  IMemInputPinVtbl *imemvtbl;
168 };
169 
170 long ff_dshow_pin_QueryInterface (DShowPin *, const GUID *, void **);
171 unsigned long ff_dshow_pin_AddRef (DShowPin *);
172 unsigned long ff_dshow_pin_Release (DShowPin *);
173 long ff_dshow_pin_Connect (DShowPin *, IPin *, const AM_MEDIA_TYPE *);
174 long ff_dshow_pin_ReceiveConnection (DShowPin *, IPin *, const AM_MEDIA_TYPE *);
176 long ff_dshow_pin_ConnectedTo (DShowPin *, IPin **);
177 long ff_dshow_pin_ConnectionMediaType (DShowPin *, AM_MEDIA_TYPE *);
178 long ff_dshow_pin_QueryPinInfo (DShowPin *, PIN_INFO *);
179 long ff_dshow_pin_QueryDirection (DShowPin *, PIN_DIRECTION *);
180 long ff_dshow_pin_QueryId (DShowPin *, wchar_t **);
181 long ff_dshow_pin_QueryAccept (DShowPin *, const AM_MEDIA_TYPE *);
182 long ff_dshow_pin_EnumMediaTypes (DShowPin *, IEnumMediaTypes **);
183 long ff_dshow_pin_QueryInternalConnections(DShowPin *, IPin **, unsigned long *);
187 long ff_dshow_pin_NewSegment (DShowPin *, REFERENCE_TIME, REFERENCE_TIME, double);
188 
189 long ff_dshow_meminputpin_QueryInterface (DShowMemInputPin *, const GUID *, void **);
192 long ff_dshow_meminputpin_GetAllocator (DShowMemInputPin *, IMemAllocator **);
193 long ff_dshow_meminputpin_NotifyAllocator (DShowMemInputPin *, IMemAllocator *, BOOL);
195 long ff_dshow_meminputpin_Receive (DShowMemInputPin *, IMediaSample *);
196 long ff_dshow_meminputpin_ReceiveMultiple (DShowMemInputPin *, IMediaSample **, long, long *);
198 
201 
203 
204 /*****************************************************************************
205  * DShowEnumPins
206  ****************************************************************************/
208  IEnumPinsVtbl *vtbl;
209  long ref;
210  int pos;
213 };
214 
215 long ff_dshow_enumpins_QueryInterface(DShowEnumPins *, const GUID *, void **);
218 long ff_dshow_enumpins_Next (DShowEnumPins *, unsigned long, IPin **, unsigned long *);
219 long ff_dshow_enumpins_Skip (DShowEnumPins *, unsigned long);
222 
225 
226 /*****************************************************************************
227  * DShowEnumMediaTypes
228  ****************************************************************************/
230  IEnumMediaTypesVtbl *vtbl;
231  long ref;
232  int pos;
233  AM_MEDIA_TYPE type;
234 };
235 
239 long ff_dshow_enummediatypes_Next (DShowEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *);
240 long ff_dshow_enummediatypes_Skip (DShowEnumMediaTypes *, unsigned long);
243 
246 
247 /*****************************************************************************
248  * DShowFilter
249  ****************************************************************************/
250 struct DShowFilter {
251  IBaseFilterVtbl *vtbl;
252  long ref;
253  const wchar_t *name;
255  FILTER_INFO info;
256  FILTER_STATE state;
257  IReferenceClock *clock;
258  enum dshowDeviceType type;
259  void *priv_data;
261  int64_t start_time;
262  void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType type);
263 };
264 
265 long ff_dshow_filter_QueryInterface (DShowFilter *, const GUID *, void **);
271 long ff_dshow_filter_Run (DShowFilter *, REFERENCE_TIME);
272 long ff_dshow_filter_GetState (DShowFilter *, DWORD, FILTER_STATE *);
273 long ff_dshow_filter_SetSyncSource (DShowFilter *, IReferenceClock *);
274 long ff_dshow_filter_GetSyncSource (DShowFilter *, IReferenceClock **);
275 long ff_dshow_filter_EnumPins (DShowFilter *, IEnumPins **);
276 long ff_dshow_filter_FindPin (DShowFilter *, const wchar_t *, IPin **);
277 long ff_dshow_filter_QueryFilterInfo(DShowFilter *, FILTER_INFO *);
278 long ff_dshow_filter_JoinFilterGraph(DShowFilter *, IFilterGraph *, const wchar_t *);
279 long ff_dshow_filter_QueryVendorInfo(DShowFilter *, wchar_t **);
280 
283 
284 /*****************************************************************************
285  * dshow_ctx
286  ****************************************************************************/
287 struct dshow_ctx {
288  const AVClass *class;
289 
290  IGraphBuilder *graph;
291 
292  char *device_name[2];
294 
297 
315 
316  IBaseFilter *device_filter[2];
317  IPin *device_pin[2];
320 
321  HANDLE mutex;
322  HANDLE event[2]; /* event[0] is set by DirectShow
323  * event[1] is set by callback() */
325 
326  int eof;
327 
328  int64_t curbufsize[2];
329  unsigned int video_frame_num;
330 
331  IMediaControl *control;
332  IMediaEvent *media_event;
333 
336  char *framerate;
337 
341 
344  int channels;
345 };
346 
347 /*****************************************************************************
348  * CrossBar
349  ****************************************************************************/
350 HRESULT ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2,
351  IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx);
352 
353 void ff_dshow_show_filter_properties(IBaseFilter *pFilter, AVFormatContext *avctx);
354 
355 #endif /* AVDEVICE_DSHOW_CAPTURE_H */
uint8_t
Main libavdevice API header.
static av_always_inline void filter(int16_t *output, ptrdiff_t out_stride, const int16_t *low, ptrdiff_t low_stride, const int16_t *high, ptrdiff_t high_stride, int len, int clip)
Definition: cfhddsp.c:27
DShowEnumMediaTypes * ff_dshow_enummediatypes_Create(const AM_MEDIA_TYPE *type)
long ff_dshow_filter_JoinFilterGraph(DShowFilter *, IFilterGraph *, const wchar_t *)
Definition: dshow_filter.c:131
unsigned long ff_dshow_enummediatypes_AddRef(DShowEnumMediaTypes *)
long ff_dshow_enumpins_QueryInterface(DShowEnumPins *, const GUID *, void **)
unsigned long ff_dshow_pin_AddRef(DShowPin *)
unsigned long ff_dshow_pin_Release(DShowPin *)
void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:85
unsigned long ff_dshow_enumpins_Release(DShowEnumPins *)
dshowDeviceType
Definition: dshow_capture.h:62
@ AudioDevice
Definition: dshow_capture.h:64
@ VideoDevice
Definition: dshow_capture.h:63
long ff_dshow_filter_QueryFilterInfo(DShowFilter *, FILTER_INFO *)
Definition: dshow_filter.c:119
long ff_dshow_enummediatypes_Next(DShowEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *)
long ff_dshow_filter_GetSyncSource(DShowFilter *, IReferenceClock **)
Definition: dshow_filter.c:76
long ff_dshow_pin_QueryId(DShowPin *, wchar_t **)
Definition: dshow_pin.c:126
const AVClass * ff_dshow_context_class_ptr
Definition: dshow_common.c:60
long ff_dshow_filter_Run(DShowFilter *, REFERENCE_TIME)
Definition: dshow_filter.c:47
long ff_dshow_enummediatypes_Skip(DShowEnumMediaTypes *, unsigned long)
void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type)
Definition: dshow_common.c:134
void ff_dshow_show_filter_properties(IBaseFilter *pFilter, AVFormatContext *avctx)
Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
Definition: dshow.c:513
long ff_dshow_meminputpin_GetAllocator(DShowMemInputPin *, IMemAllocator **)
Definition: dshow_pin.c:272
void ff_dshow_enummediatypes_Destroy(DShowEnumMediaTypes *)
void ff_dshow_pin_Destroy(DShowPin *)
long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src)
Definition: dshow_common.c:24
long ff_dshow_pin_NewSegment(DShowPin *, REFERENCE_TIME, REFERENCE_TIME, double)
Definition: dshow_pin.c:181
void ff_dshow_enumpins_Destroy(DShowEnumPins *)
long ff_dshow_meminputpin_GetAllocatorRequirements(DShowMemInputPin *, ALLOCATOR_PROPERTIES *)
Definition: dshow_pin.c:283
long ff_dshow_filter_SetSyncSource(DShowFilter *, IReferenceClock *)
Definition: dshow_filter.c:62
long ff_dshow_filter_EnumPins(DShowFilter *, IEnumPins **)
Definition: dshow_filter.c:88
long ff_dshow_pin_EndOfStream(DShowPin *)
Definition: dshow_pin.c:163
long ff_dshow_filter_QueryVendorInfo(DShowFilter *, wchar_t **)
Definition: dshow_filter.c:142
long ff_dshow_enummediatypes_QueryInterface(DShowEnumMediaTypes *, const GUID *, void **)
long ff_dshow_filter_QueryInterface(DShowFilter *, const GUID *, void **)
long ff_dshow_filter_GetState(DShowFilter *, DWORD, FILTER_STATE *)
Definition: dshow_filter.c:54
long ff_dshow_pin_BeginFlush(DShowPin *)
Definition: dshow_pin.c:169
long ff_dshow_enummediatypes_Reset(DShowEnumMediaTypes *)
unsigned long ff_dshow_filter_AddRef(DShowFilter *)
long ff_dshow_enumpins_Reset(DShowEnumPins *)
HRESULT ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx)
Given a fully constructed graph, check if there is a cross bar filter, and configure its pins if so.
long ff_dshow_enumpins_Clone(DShowEnumPins *, DShowEnumPins **)
DShowFilter * ff_dshow_filter_Create(void *, void *, enum dshowDeviceType)
long ff_dshow_pin_QueryPinInfo(DShowPin *, PIN_INFO *)
Definition: dshow_pin.c:102
long ff_dshow_pin_EndFlush(DShowPin *)
Definition: dshow_pin.c:175
unsigned long ff_dshow_enummediatypes_Release(DShowEnumMediaTypes *)
long ff_dshow_filter_FindPin(DShowFilter *, const wchar_t *, IPin **)
Definition: dshow_filter.c:102
unsigned long ff_dshow_meminputpin_Release(DShowMemInputPin *)
Definition: dshow_pin.c:266
unsigned long ff_dshow_meminputpin_AddRef(DShowMemInputPin *)
Definition: dshow_pin.c:260
DShowPin * ff_dshow_pin_Create(DShowFilter *filter)
long ff_dshow_pin_QueryInternalConnections(DShowPin *, IPin **, unsigned long *)
Definition: dshow_pin.c:157
struct DShowMemInputPin DShowMemInputPin
long ff_dshow_meminputpin_Receive(DShowMemInputPin *, IMediaSample *)
Definition: dshow_pin.c:289
long ff_dshow_pin_QueryAccept(DShowPin *, const AM_MEDIA_TYPE *)
Definition: dshow_pin.c:137
dshowSourceFilterType
Definition: dshow_capture.h:67
@ AudioSourceDevice
Definition: dshow_capture.h:69
@ VideoSourceDevice
Definition: dshow_capture.h:68
long ff_dshow_pin_EnumMediaTypes(DShowPin *, IEnumMediaTypes **)
Definition: dshow_pin.c:142
long ff_dshow_filter_Pause(DShowFilter *)
Definition: dshow_filter.c:41
DShowEnumPins * ff_dshow_enumpins_Create(DShowPin *pin, DShowFilter *filter)
long ff_dshow_filter_Stop(DShowFilter *)
Definition: dshow_filter.c:35
long ff_dshow_enummediatypes_Clone(DShowEnumMediaTypes *, DShowEnumMediaTypes **)
long ff_dshow_pin_ConnectionMediaType(DShowPin *, AM_MEDIA_TYPE *)
Definition: dshow_pin.c:91
long ff_dshow_pin_ConnectedTo(DShowPin *, IPin **)
Definition: dshow_pin.c:78
long ff_dshow_enumpins_Skip(DShowEnumPins *, unsigned long)
static void nothing(void *foo)
Definition: dshow_capture.h:53
long ff_dshow_pin_Disconnect(DShowPin *)
Definition: dshow_pin.c:65
unsigned long ff_dshow_filter_Release(DShowFilter *)
long ff_dshow_meminputpin_ReceiveMultiple(DShowMemInputPin *, IMediaSample **, long, long *)
Definition: dshow_pin.c:345
long ff_dshow_enumpins_Next(DShowEnumPins *, unsigned long, IPin **, unsigned long *)
void ff_dshow_filter_Destroy(DShowFilter *)
unsigned long ff_dshow_enumpins_AddRef(DShowEnumPins *)
long ff_dshow_pin_Connect(DShowPin *, IPin *, const AM_MEDIA_TYPE *)
long ff_dshow_pin_QueryInterface(DShowPin *, const GUID *, void **)
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:115
void ff_dshow_meminputpin_Destroy(DShowMemInputPin *)
Definition: dshow_pin.c:364
long ff_dshow_filter_GetClassID(DShowFilter *, CLSID *)
void ff_printGUID(const GUID *g)
Definition: dshow_common.c:42
long ff_dshow_meminputpin_QueryInterface(DShowMemInputPin *, const GUID *, void **)
Definition: dshow_pin.c:253
long ff_dshow_meminputpin_ReceiveCanBlock(DShowMemInputPin *)
Definition: dshow_pin.c:357
long ff_dshow_pin_QueryDirection(DShowPin *, PIN_DIRECTION *)
Definition: dshow_pin.c:118
long ff_dshow_pin_ReceiveConnection(DShowPin *, IPin *, const AM_MEDIA_TYPE *)
Definition: dshow_pin.c:38
long ff_dshow_meminputpin_NotifyAllocator(DShowMemInputPin *, IMemAllocator *, BOOL)
Definition: dshow_pin.c:277
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
int index
Definition: gxfenc.c:89
cl_device_type type
common internal api header.
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
typedef void(RENAME(mix_any_func_type))
Describe the class of an AVClass context structure.
Definition: log.h:67
Format I/O context.
Definition: avformat.h:1232
Rational number (pair of numerator and denominator).
Definition: rational.h:58
IEnumMediaTypesVtbl * vtbl
AM_MEDIA_TYPE type
DShowPin * pin
DShowFilter * filter
IEnumPinsVtbl * vtbl
IBaseFilterVtbl * vtbl
void(* callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType type)
const wchar_t * name
int64_t start_time
FILTER_STATE state
enum dshowDeviceType type
IReferenceClock * clock
DShowPin * pin
void * priv_data
FILTER_INFO info
DShowFilter * filter
IPin * connectedto
IPinVtbl * vtbl
AM_MEDIA_TYPE type
IMemInputPinVtbl * imemvtbl
const GUID * iid
Definition: dshow_capture.h:58
IMediaEvent * media_event
int show_video_device_dialog
IMediaControl * control
char * audio_filter_save_file
char * device_name[2]
PacketList * pktl
int crossbar_audio_input_pin_number
int list_options
int show_analog_tv_tuner_audio_dialog
int requested_width
int audio_device_number
int64_t curbufsize[2]
int show_analog_tv_tuner_dialog
char * audio_filter_load_file
IGraphBuilder * graph
int show_video_crossbar_connection_dialog
AVRational requested_framerate
int show_audio_device_dialog
int show_audio_crossbar_connection_dialog
char * video_pin_name
char * video_filter_load_file
int list_devices
char * video_filter_save_file
int crossbar_video_input_pin_number
int audio_buffer_size
DShowPin * capture_pin[2]
enum AVCodecID video_codec_id
char * framerate
char * device_unique_name[2]
enum AVPixelFormat pixel_format
int video_device_number
IPin * device_pin[2]
unsigned int video_frame_num
char * audio_pin_name
int requested_height
IBaseFilter * device_filter[2]
HANDLE mutex
DShowFilter * capture_filter[2]
#define src
Definition: vp8dsp.c:255
const char * g
Definition: vf_curves.c:117