FFmpeg  4.4.6
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  dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Create(%p)\n", this); \
129  if (!this) \
130  goto fail; \
131  ZeroMemory(this, sizeof(class)); \
132  this->vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \
133  if (!this->vtbl) \
134  goto fail; \
135  ZeroMemory(this->vtbl, sizeof(*this->vtbl)); \
136  this->ref = 1; \
137  if (!setup) \
138  goto fail; \
139  dshowdebug("created ff_dshow_"AV_STRINGIFY(prefix)" %p\n", this); \
140  return this; \
141 fail: \
142  ff_dshow_##prefix##_Destroy(this); \
143  dshowdebug("could not create ff_dshow_"AV_STRINGIFY(prefix)"\n"); \
144  return NULL; \
145 }
146 
147 #define SETVTBL(vtbl, prefix, fn) \
148  do { (vtbl)->fn = (void *) ff_dshow_##prefix##_##fn; } while(0)
149 
150 /*****************************************************************************
151  * Forward Declarations
152  ****************************************************************************/
153 typedef struct DShowPin DShowPin;
154 typedef struct DShowMemInputPin DShowMemInputPin;
155 typedef struct DShowEnumPins DShowEnumPins;
157 typedef struct DShowFilter DShowFilter;
158 
159 /*****************************************************************************
160  * DShowPin
161  ****************************************************************************/
162 struct DShowPin {
163  IPinVtbl *vtbl;
164  long ref;
166  IPin *connectedto;
167  AM_MEDIA_TYPE type;
168  IMemInputPinVtbl *imemvtbl;
169 };
170 
171 long ff_dshow_pin_QueryInterface (DShowPin *, const GUID *, void **);
172 unsigned long ff_dshow_pin_AddRef (DShowPin *);
173 unsigned long ff_dshow_pin_Release (DShowPin *);
174 long ff_dshow_pin_Connect (DShowPin *, IPin *, const AM_MEDIA_TYPE *);
175 long ff_dshow_pin_ReceiveConnection (DShowPin *, IPin *, const AM_MEDIA_TYPE *);
177 long ff_dshow_pin_ConnectedTo (DShowPin *, IPin **);
178 long ff_dshow_pin_ConnectionMediaType (DShowPin *, AM_MEDIA_TYPE *);
179 long ff_dshow_pin_QueryPinInfo (DShowPin *, PIN_INFO *);
180 long ff_dshow_pin_QueryDirection (DShowPin *, PIN_DIRECTION *);
181 long ff_dshow_pin_QueryId (DShowPin *, wchar_t **);
182 long ff_dshow_pin_QueryAccept (DShowPin *, const AM_MEDIA_TYPE *);
183 long ff_dshow_pin_EnumMediaTypes (DShowPin *, IEnumMediaTypes **);
184 long ff_dshow_pin_QueryInternalConnections(DShowPin *, IPin **, unsigned long *);
188 long ff_dshow_pin_NewSegment (DShowPin *, REFERENCE_TIME, REFERENCE_TIME, double);
189 
190 long ff_dshow_meminputpin_QueryInterface (DShowMemInputPin *, const GUID *, void **);
193 long ff_dshow_meminputpin_GetAllocator (DShowMemInputPin *, IMemAllocator **);
194 long ff_dshow_meminputpin_NotifyAllocator (DShowMemInputPin *, IMemAllocator *, BOOL);
196 long ff_dshow_meminputpin_Receive (DShowMemInputPin *, IMediaSample *);
197 long ff_dshow_meminputpin_ReceiveMultiple (DShowMemInputPin *, IMediaSample **, long, long *);
199 
202 
204 
205 /*****************************************************************************
206  * DShowEnumPins
207  ****************************************************************************/
209  IEnumPinsVtbl *vtbl;
210  long ref;
211  int pos;
214 };
215 
216 long ff_dshow_enumpins_QueryInterface(DShowEnumPins *, const GUID *, void **);
219 long ff_dshow_enumpins_Next (DShowEnumPins *, unsigned long, IPin **, unsigned long *);
220 long ff_dshow_enumpins_Skip (DShowEnumPins *, unsigned long);
223 
226 
227 /*****************************************************************************
228  * DShowEnumMediaTypes
229  ****************************************************************************/
231  IEnumMediaTypesVtbl *vtbl;
232  long ref;
233  int pos;
234  AM_MEDIA_TYPE type;
235 };
236 
240 long ff_dshow_enummediatypes_Next (DShowEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *);
241 long ff_dshow_enummediatypes_Skip (DShowEnumMediaTypes *, unsigned long);
244 
247 
248 /*****************************************************************************
249  * DShowFilter
250  ****************************************************************************/
251 struct DShowFilter {
252  IBaseFilterVtbl *vtbl;
253  long ref;
254  const wchar_t *name;
256  FILTER_INFO info;
257  FILTER_STATE state;
258  IReferenceClock *clock;
259  enum dshowDeviceType type;
260  void *priv_data;
263  void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType type);
264 };
265 
266 long ff_dshow_filter_QueryInterface (DShowFilter *, const GUID *, void **);
272 long ff_dshow_filter_Run (DShowFilter *, REFERENCE_TIME);
273 long ff_dshow_filter_GetState (DShowFilter *, DWORD, FILTER_STATE *);
274 long ff_dshow_filter_SetSyncSource (DShowFilter *, IReferenceClock *);
275 long ff_dshow_filter_GetSyncSource (DShowFilter *, IReferenceClock **);
276 long ff_dshow_filter_EnumPins (DShowFilter *, IEnumPins **);
277 long ff_dshow_filter_FindPin (DShowFilter *, const wchar_t *, IPin **);
278 long ff_dshow_filter_QueryFilterInfo(DShowFilter *, FILTER_INFO *);
279 long ff_dshow_filter_JoinFilterGraph(DShowFilter *, IFilterGraph *, const wchar_t *);
280 long ff_dshow_filter_QueryVendorInfo(DShowFilter *, wchar_t **);
281 
284 
285 /*****************************************************************************
286  * dshow_ctx
287  ****************************************************************************/
288 struct dshow_ctx {
289  const AVClass *class;
290 
291  IGraphBuilder *graph;
292 
293  char *device_name[2];
295 
298 
316 
317  IBaseFilter *device_filter[2];
318  IPin *device_pin[2];
321 
322  HANDLE mutex;
323  HANDLE event[2]; /* event[0] is set by DirectShow
324  * event[1] is set by callback() */
326 
327  int eof;
328 
330  unsigned int video_frame_num;
331 
332  IMediaControl *control;
333  IMediaEvent *media_event;
334 
337  char *framerate;
338 
342 
345  int channels;
346 };
347 
348 /*****************************************************************************
349  * CrossBar
350  ****************************************************************************/
351 HRESULT ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2,
352  IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx);
353 
354 void ff_dshow_show_filter_properties(IBaseFilter *pFilter, AVFormatContext *avctx);
355 
356 #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
long long int64_t
Definition: coverity.c:34
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