diff options
author | Ramiro Polla <ramiro.polla@gmail.com> | 2011-05-21 14:24:50 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-05-21 17:23:14 +0200 |
commit | 95eb2e3a3819e8b6d87940bfa41bf1ea3ae68f5a (patch) | |
tree | a6b05f2a93b4fadf6790d032d8830906150e3e3d /libavdevice/dshow.h | |
parent | f8c49d02b0f17c3011712ec4638ec4c6c76e7831 (diff) | |
download | ffmpeg-streaming-95eb2e3a3819e8b6d87940bfa41bf1ea3ae68f5a.zip ffmpeg-streaming-95eb2e3a3819e8b6d87940bfa41bf1ea3ae68f5a.tar.gz |
DirectShow capture support
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavdevice/dshow.h')
-rw-r--r-- | libavdevice/dshow.h | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/libavdevice/dshow.h b/libavdevice/dshow.h new file mode 100644 index 0000000..c991c02 --- /dev/null +++ b/libavdevice/dshow.h @@ -0,0 +1,266 @@ +/* + * DirectShow capture interface + * Copyright (c) 2010 Ramiro Polla + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define DSHOWDEBUG 0 + +#include "libavformat/avformat.h" + +#define COBJMACROS +#include <windows.h> +#include <dshow.h> +#include <dvdmedia.h> + +long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src); +void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type); +void ff_printGUID(const GUID *g); + +#if DSHOWDEBUG +extern const AVClass *ff_dshow_context_class_ptr; +#define dshowdebug(...) av_log(&ff_dshow_context_class_ptr, AV_LOG_DEBUG, __VA_ARGS__) +#else +#define dshowdebug(...) +#endif + +static inline void nothing(void *foo) +{ +} + +struct GUIDoffset { + const GUID *iid; + int offset; +}; + +enum dshowDeviceType { + VideoDevice = 0, + AudioDevice = 1, +}; + +#define DECLARE_QUERYINTERFACE(class, ...) \ +long WINAPI \ +class##_QueryInterface(class *this, const GUID *riid, void **ppvObject) \ +{ \ + struct GUIDoffset ifaces[] = __VA_ARGS__; \ + int i; \ + dshowdebug(AV_STRINGIFY(class)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \ + ff_printGUID(riid); \ + if (!ppvObject) \ + return E_POINTER; \ + for (i = 0; i < sizeof(ifaces)/sizeof(ifaces[0]); i++) { \ + if (IsEqualGUID(riid, ifaces[i].iid)) { \ + void *obj = (void *) ((uint8_t *) this + ifaces[i].offset); \ + class##_AddRef(this); \ + dshowdebug("\tfound %d with offset %d\n", i, ifaces[i].offset); \ + *ppvObject = (void *) obj; \ + return S_OK; \ + } \ + } \ + dshowdebug("\tE_NOINTERFACE\n"); \ + *ppvObject = NULL; \ + return E_NOINTERFACE; \ +} +#define DECLARE_ADDREF(class) \ +unsigned long WINAPI \ +class##_AddRef(class *this) \ +{ \ + dshowdebug(AV_STRINGIFY(class)"_AddRef(%p)\t%ld\n", this, this->ref+1); \ + return InterlockedIncrement(&this->ref); \ +} +#define DECLARE_RELEASE(class) \ +unsigned long WINAPI \ +class##_Release(class *this) \ +{ \ + long ref = InterlockedDecrement(&this->ref); \ + dshowdebug(AV_STRINGIFY(class)"_Release(%p)\t%ld\n", this, ref); \ + if (!ref) \ + class##_Destroy(this); \ + return ref; \ +} + +#define DECLARE_DESTROY(class, func) \ +void class##_Destroy(class *this) \ +{ \ + dshowdebug(AV_STRINGIFY(class)"_Destroy(%p)\n", this); \ + func(this); \ + if (this) { \ + if (this->vtbl) \ + CoTaskMemFree(this->vtbl); \ + CoTaskMemFree(this); \ + } \ +} +#define DECLARE_CREATE(class, setup, ...) \ +class *class##_Create(__VA_ARGS__) \ +{ \ + class *this = CoTaskMemAlloc(sizeof(class)); \ + void *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \ + dshowdebug(AV_STRINGIFY(class)"_Create(%p)\n", this); \ + if (!this || !vtbl) \ + goto fail; \ + ZeroMemory(this, sizeof(class)); \ + ZeroMemory(vtbl, sizeof(*this->vtbl)); \ + this->ref = 1; \ + this->vtbl = vtbl; \ + if (!setup) \ + goto fail; \ + dshowdebug("created "AV_STRINGIFY(class)" %p\n", this); \ + return this; \ +fail: \ + class##_Destroy(this); \ + dshowdebug("could not create "AV_STRINGIFY(class)"\n"); \ + return NULL; \ +} + +#define SETVTBL(vtbl, class, fn) \ + do { (vtbl)->fn = (void *) class##_##fn; } while(0) + +/***************************************************************************** + * Forward Declarations + ****************************************************************************/ +typedef struct libAVPin libAVPin; +typedef struct libAVMemInputPin libAVMemInputPin; +typedef struct libAVEnumPins libAVEnumPins; +typedef struct libAVEnumMediaTypes libAVEnumMediaTypes; +typedef struct libAVFilter libAVFilter; + +/***************************************************************************** + * libAVPin + ****************************************************************************/ +struct libAVPin { + IPinVtbl *vtbl; + long ref; + libAVFilter *filter; + IPin *connectedto; + AM_MEDIA_TYPE type; + IMemInputPinVtbl *imemvtbl; +}; + +long WINAPI libAVPin_QueryInterface (libAVPin *, const GUID *, void **); +unsigned long WINAPI libAVPin_AddRef (libAVPin *); +unsigned long WINAPI libAVPin_Release (libAVPin *); +long WINAPI libAVPin_Connect (libAVPin *, IPin *, const AM_MEDIA_TYPE *); +long WINAPI libAVPin_ReceiveConnection (libAVPin *, IPin *, const AM_MEDIA_TYPE *); +long WINAPI libAVPin_Disconnect (libAVPin *); +long WINAPI libAVPin_ConnectedTo (libAVPin *, IPin **); +long WINAPI libAVPin_ConnectionMediaType (libAVPin *, AM_MEDIA_TYPE *); +long WINAPI libAVPin_QueryPinInfo (libAVPin *, PIN_INFO *); +long WINAPI libAVPin_QueryDirection (libAVPin *, PIN_DIRECTION *); +long WINAPI libAVPin_QueryId (libAVPin *, wchar_t **); +long WINAPI libAVPin_QueryAccept (libAVPin *, const AM_MEDIA_TYPE *); +long WINAPI libAVPin_EnumMediaTypes (libAVPin *, IEnumMediaTypes **); +long WINAPI libAVPin_QueryInternalConnections(libAVPin *, IPin **, unsigned long *); +long WINAPI libAVPin_EndOfStream (libAVPin *); +long WINAPI libAVPin_BeginFlush (libAVPin *); +long WINAPI libAVPin_EndFlush (libAVPin *); +long WINAPI libAVPin_NewSegment (libAVPin *, REFERENCE_TIME, REFERENCE_TIME, double); + +long WINAPI libAVMemInputPin_QueryInterface (libAVMemInputPin *, const GUID *, void **); +unsigned long WINAPI libAVMemInputPin_AddRef (libAVMemInputPin *); +unsigned long WINAPI libAVMemInputPin_Release (libAVMemInputPin *); +long WINAPI libAVMemInputPin_GetAllocator (libAVMemInputPin *, IMemAllocator **); +long WINAPI libAVMemInputPin_NotifyAllocator (libAVMemInputPin *, IMemAllocator *, WINBOOL); +long WINAPI libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *, ALLOCATOR_PROPERTIES *); +long WINAPI libAVMemInputPin_Receive (libAVMemInputPin *, IMediaSample *); +long WINAPI libAVMemInputPin_ReceiveMultiple (libAVMemInputPin *, IMediaSample **, long, long *); +long WINAPI libAVMemInputPin_ReceiveCanBlock (libAVMemInputPin *); + +void libAVPin_Destroy(libAVPin *); +libAVPin *libAVPin_Create (libAVFilter *filter); + +void libAVMemInputPin_Destroy(libAVMemInputPin *); + +/***************************************************************************** + * libAVEnumPins + ****************************************************************************/ +struct libAVEnumPins { + IEnumPinsVtbl *vtbl; + long ref; + int pos; + libAVPin *pin; + libAVFilter *filter; +}; + +long WINAPI libAVEnumPins_QueryInterface(libAVEnumPins *, const GUID *, void **); +unsigned long WINAPI libAVEnumPins_AddRef (libAVEnumPins *); +unsigned long WINAPI libAVEnumPins_Release (libAVEnumPins *); +long WINAPI libAVEnumPins_Next (libAVEnumPins *, unsigned long, IPin **, unsigned long *); +long WINAPI libAVEnumPins_Skip (libAVEnumPins *, unsigned long); +long WINAPI libAVEnumPins_Reset (libAVEnumPins *); +long WINAPI libAVEnumPins_Clone (libAVEnumPins *, libAVEnumPins **); + +void libAVEnumPins_Destroy(libAVEnumPins *); +libAVEnumPins *libAVEnumPins_Create (libAVPin *pin, libAVFilter *filter); + +/***************************************************************************** + * libAVEnumMediaTypes + ****************************************************************************/ +struct libAVEnumMediaTypes { + IEnumPinsVtbl *vtbl; + long ref; + int pos; + AM_MEDIA_TYPE type; +}; + +long WINAPI libAVEnumMediaTypes_QueryInterface(libAVEnumMediaTypes *, const GUID *, void **); +unsigned long WINAPI libAVEnumMediaTypes_AddRef (libAVEnumMediaTypes *); +unsigned long WINAPI libAVEnumMediaTypes_Release (libAVEnumMediaTypes *); +long WINAPI libAVEnumMediaTypes_Next (libAVEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *); +long WINAPI libAVEnumMediaTypes_Skip (libAVEnumMediaTypes *, unsigned long); +long WINAPI libAVEnumMediaTypes_Reset (libAVEnumMediaTypes *); +long WINAPI libAVEnumMediaTypes_Clone (libAVEnumMediaTypes *, libAVEnumMediaTypes **); + +void libAVEnumMediaTypes_Destroy(libAVEnumMediaTypes *); +libAVEnumMediaTypes *libAVEnumMediaTypes_Create(const AM_MEDIA_TYPE *type); + +/***************************************************************************** + * libAVFilter + ****************************************************************************/ +struct libAVFilter { + IBaseFilterVtbl *vtbl; + long ref; + const wchar_t *name; + libAVPin *pin; + FILTER_INFO info; + FILTER_STATE state; + IReferenceClock *clock; + enum dshowDeviceType type; + void *priv_data; + int stream_index; + int64_t start_time; + void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time); +}; + +long WINAPI libAVFilter_QueryInterface (libAVFilter *, const GUID *, void **); +unsigned long WINAPI libAVFilter_AddRef (libAVFilter *); +unsigned long WINAPI libAVFilter_Release (libAVFilter *); +long WINAPI libAVFilter_GetClassID (libAVFilter *, CLSID *); +long WINAPI libAVFilter_Stop (libAVFilter *); +long WINAPI libAVFilter_Pause (libAVFilter *); +long WINAPI libAVFilter_Run (libAVFilter *, REFERENCE_TIME); +long WINAPI libAVFilter_GetState (libAVFilter *, DWORD, FILTER_STATE *); +long WINAPI libAVFilter_SetSyncSource (libAVFilter *, IReferenceClock *); +long WINAPI libAVFilter_GetSyncSource (libAVFilter *, IReferenceClock **); +long WINAPI libAVFilter_EnumPins (libAVFilter *, IEnumPins **); +long WINAPI libAVFilter_FindPin (libAVFilter *, const wchar_t *, IPin **); +long WINAPI libAVFilter_QueryFilterInfo(libAVFilter *, FILTER_INFO *); +long WINAPI libAVFilter_JoinFilterGraph(libAVFilter *, IFilterGraph *, const wchar_t *); +long WINAPI libAVFilter_QueryVendorInfo(libAVFilter *, wchar_t **); + +void libAVFilter_Destroy(libAVFilter *); +libAVFilter *libAVFilter_Create (void *, void *, enum dshowDeviceType); |