Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. #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"
  37.  
  38. /* EC_DEVICE_LOST is not defined in MinGW dshow headers. */
  39. #ifndef EC_DEVICE_LOST
  40. #define EC_DEVICE_LOST 0x1f
  41. #endif
  42.  
  43. long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src);
  44. void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps);
  45. void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps);
  46. void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type);
  47. void ff_printGUID(const GUID *g);
  48.  
  49. extern const AVClass *ff_dshow_context_class_ptr;
  50. #define dshowdebug(...) ff_dlog(&ff_dshow_context_class_ptr, __VA_ARGS__)
  51.  
  52. static inline void nothing(void *foo)
  53. {
  54. }
  55.  
  56. struct GUIDoffset {
  57.     const GUID *iid;
  58.     int offset;
  59. };
  60.  
  61. enum dshowDeviceType {
  62.     VideoDevice = 0,
  63.     AudioDevice = 1,
  64. };
  65.  
  66. enum dshowSourceFilterType {
  67.     VideoSourceDevice = 0,
  68.     AudioSourceDevice = 1,
  69. };
  70.  
  71. #define DECLARE_QUERYINTERFACE(class, ...)                                   \
  72. long WINAPI                                                                  \
  73. class##_QueryInterface(class *this, const GUID *riid, void **ppvObject)      \
  74. {                                                                            \
  75.     struct GUIDoffset ifaces[] = __VA_ARGS__;                                \
  76.     int i;                                                                   \
  77.     dshowdebug(AV_STRINGIFY(class)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \
  78.     ff_printGUID(riid);                                                      \
  79.     if (!ppvObject)                                                          \
  80.         return E_POINTER;                                                    \
  81.     for (i = 0; i < sizeof(ifaces)/sizeof(ifaces[0]); i++) {                 \
  82.         if (IsEqualGUID(riid, ifaces[i].iid)) {                              \
  83.             void *obj = (void *) ((uint8_t *) this + ifaces[i].offset);      \
  84.             class##_AddRef(this);                                            \
  85.             dshowdebug("\tfound %d with offset %d\n", i, ifaces[i].offset);  \
  86.             *ppvObject = (void *) obj;                                       \
  87.             return S_OK;                                                     \
  88.         }                                                                    \
  89.     }                                                                        \
  90.     dshowdebug("\tE_NOINTERFACE\n");                                         \
  91.     *ppvObject = NULL;                                                       \
  92.     return E_NOINTERFACE;                                                    \
  93. }
  94. #define DECLARE_ADDREF(class)                                                \
  95. unsigned long WINAPI                                                         \
  96. class##_AddRef(class *this)                                                  \
  97. {                                                                            \
  98.     dshowdebug(AV_STRINGIFY(class)"_AddRef(%p)\t%ld\n", this, this->ref+1);  \
  99.     return InterlockedIncrement(&this->ref);                                 \
  100. }
  101. #define DECLARE_RELEASE(class)                                               \
  102. unsigned long WINAPI                                                         \
  103. class##_Release(class *this)                                                 \
  104. {                                                                            \
  105.     long ref = InterlockedDecrement(&this->ref);                             \
  106.     dshowdebug(AV_STRINGIFY(class)"_Release(%p)\t%ld\n", this, ref);         \
  107.     if (!ref)                                                                \
  108.         class##_Destroy(this);                                               \
  109.     return ref;                                                              \
  110. }
  111.  
  112. #define DECLARE_DESTROY(class, func)                                         \
  113. void class##_Destroy(class *this)                                            \
  114. {                                                                            \
  115.     dshowdebug(AV_STRINGIFY(class)"_Destroy(%p)\n", this);                   \
  116.     func(this);                                                              \
  117.     if (this) {                                                              \
  118.         if (this->vtbl)                                                      \
  119.             CoTaskMemFree(this->vtbl);                                       \
  120.         CoTaskMemFree(this);                                                 \
  121.     }                                                                        \
  122. }
  123. #define DECLARE_CREATE(class, setup, ...)                                    \
  124. class *class##_Create(__VA_ARGS__)                                           \
  125. {                                                                            \
  126.     class *this = CoTaskMemAlloc(sizeof(class));                             \
  127.     void  *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl));                       \
  128.     dshowdebug(AV_STRINGIFY(class)"_Create(%p)\n", this);                    \
  129.     if (!this || !vtbl)                                                      \
  130.         goto fail;                                                           \
  131.     ZeroMemory(this, sizeof(class));                                         \
  132.     ZeroMemory(vtbl, sizeof(*this->vtbl));                                   \
  133.     this->ref  = 1;                                                          \
  134.     this->vtbl = vtbl;                                                       \
  135.     if (!setup)                                                              \
  136.         goto fail;                                                           \
  137.     dshowdebug("created "AV_STRINGIFY(class)" %p\n", this);                  \
  138.     return this;                                                             \
  139. fail:                                                                        \
  140.     class##_Destroy(this);                                                   \
  141.     dshowdebug("could not create "AV_STRINGIFY(class)"\n");                  \
  142.     return NULL;                                                             \
  143. }
  144.  
  145. #define SETVTBL(vtbl, class, fn) \
  146.     do { (vtbl)->fn = (void *) class##_##fn; } while(0)
  147.  
  148. /*****************************************************************************
  149.  * Forward Declarations
  150.  ****************************************************************************/
  151. typedef struct libAVPin libAVPin;
  152. typedef struct libAVMemInputPin libAVMemInputPin;
  153. typedef struct libAVEnumPins libAVEnumPins;
  154. typedef struct libAVEnumMediaTypes libAVEnumMediaTypes;
  155. typedef struct libAVFilter libAVFilter;
  156.  
  157. /*****************************************************************************
  158.  * libAVPin
  159.  ****************************************************************************/
  160. struct libAVPin {
  161.     IPinVtbl *vtbl;
  162.     long ref;
  163.     libAVFilter *filter;
  164.     IPin *connectedto;
  165.     AM_MEDIA_TYPE type;
  166.     IMemInputPinVtbl *imemvtbl;
  167. };
  168.  
  169. long          WINAPI libAVPin_QueryInterface          (libAVPin *, const GUID *, void **);
  170. unsigned long WINAPI libAVPin_AddRef                  (libAVPin *);
  171. unsigned long WINAPI libAVPin_Release                 (libAVPin *);
  172. long          WINAPI libAVPin_Connect                 (libAVPin *, IPin *, const AM_MEDIA_TYPE *);
  173. long          WINAPI libAVPin_ReceiveConnection       (libAVPin *, IPin *, const AM_MEDIA_TYPE *);
  174. long          WINAPI libAVPin_Disconnect              (libAVPin *);
  175. long          WINAPI libAVPin_ConnectedTo             (libAVPin *, IPin **);
  176. long          WINAPI libAVPin_ConnectionMediaType     (libAVPin *, AM_MEDIA_TYPE *);
  177. long          WINAPI libAVPin_QueryPinInfo            (libAVPin *, PIN_INFO *);
  178. long          WINAPI libAVPin_QueryDirection          (libAVPin *, PIN_DIRECTION *);
  179. long          WINAPI libAVPin_QueryId                 (libAVPin *, wchar_t **);
  180. long          WINAPI libAVPin_QueryAccept             (libAVPin *, const AM_MEDIA_TYPE *);
  181. long          WINAPI libAVPin_EnumMediaTypes          (libAVPin *, IEnumMediaTypes **);
  182. long          WINAPI libAVPin_QueryInternalConnections(libAVPin *, IPin **, unsigned long *);
  183. long          WINAPI libAVPin_EndOfStream             (libAVPin *);
  184. long          WINAPI libAVPin_BeginFlush              (libAVPin *);
  185. long          WINAPI libAVPin_EndFlush                (libAVPin *);
  186. long          WINAPI libAVPin_NewSegment              (libAVPin *, REFERENCE_TIME, REFERENCE_TIME, double);
  187.  
  188. long          WINAPI libAVMemInputPin_QueryInterface          (libAVMemInputPin *, const GUID *, void **);
  189. unsigned long WINAPI libAVMemInputPin_AddRef                  (libAVMemInputPin *);
  190. unsigned long WINAPI libAVMemInputPin_Release                 (libAVMemInputPin *);
  191. long          WINAPI libAVMemInputPin_GetAllocator            (libAVMemInputPin *, IMemAllocator **);
  192. long          WINAPI libAVMemInputPin_NotifyAllocator         (libAVMemInputPin *, IMemAllocator *, BOOL);
  193. long          WINAPI libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *, ALLOCATOR_PROPERTIES *);
  194. long          WINAPI libAVMemInputPin_Receive                 (libAVMemInputPin *, IMediaSample *);
  195. long          WINAPI libAVMemInputPin_ReceiveMultiple         (libAVMemInputPin *, IMediaSample **, long, long *);
  196. long          WINAPI libAVMemInputPin_ReceiveCanBlock         (libAVMemInputPin *);
  197.  
  198. void                 libAVPin_Destroy(libAVPin *);
  199. libAVPin            *libAVPin_Create (libAVFilter *filter);
  200.  
  201. void                 libAVMemInputPin_Destroy(libAVMemInputPin *);
  202.  
  203. /*****************************************************************************
  204.  * libAVEnumPins
  205.  ****************************************************************************/
  206. struct libAVEnumPins {
  207.     IEnumPinsVtbl *vtbl;
  208.     long ref;
  209.     int pos;
  210.     libAVPin *pin;
  211.     libAVFilter *filter;
  212. };
  213.  
  214. long          WINAPI libAVEnumPins_QueryInterface(libAVEnumPins *, const GUID *, void **);
  215. unsigned long WINAPI libAVEnumPins_AddRef        (libAVEnumPins *);
  216. unsigned long WINAPI libAVEnumPins_Release       (libAVEnumPins *);
  217. long          WINAPI libAVEnumPins_Next          (libAVEnumPins *, unsigned long, IPin **, unsigned long *);
  218. long          WINAPI libAVEnumPins_Skip          (libAVEnumPins *, unsigned long);
  219. long          WINAPI libAVEnumPins_Reset         (libAVEnumPins *);
  220. long          WINAPI libAVEnumPins_Clone         (libAVEnumPins *, libAVEnumPins **);
  221.  
  222. void                 libAVEnumPins_Destroy(libAVEnumPins *);
  223. libAVEnumPins       *libAVEnumPins_Create (libAVPin *pin, libAVFilter *filter);
  224.  
  225. /*****************************************************************************
  226.  * libAVEnumMediaTypes
  227.  ****************************************************************************/
  228. struct libAVEnumMediaTypes {
  229.     IEnumMediaTypesVtbl *vtbl;
  230.     long ref;
  231.     int pos;
  232.     AM_MEDIA_TYPE type;
  233. };
  234.  
  235. long          WINAPI libAVEnumMediaTypes_QueryInterface(libAVEnumMediaTypes *, const GUID *, void **);
  236. unsigned long WINAPI libAVEnumMediaTypes_AddRef        (libAVEnumMediaTypes *);
  237. unsigned long WINAPI libAVEnumMediaTypes_Release       (libAVEnumMediaTypes *);
  238. long          WINAPI libAVEnumMediaTypes_Next          (libAVEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *);
  239. long          WINAPI libAVEnumMediaTypes_Skip          (libAVEnumMediaTypes *, unsigned long);
  240. long          WINAPI libAVEnumMediaTypes_Reset         (libAVEnumMediaTypes *);
  241. long          WINAPI libAVEnumMediaTypes_Clone         (libAVEnumMediaTypes *, libAVEnumMediaTypes **);
  242.  
  243. void                 libAVEnumMediaTypes_Destroy(libAVEnumMediaTypes *);
  244. libAVEnumMediaTypes *libAVEnumMediaTypes_Create(const AM_MEDIA_TYPE *type);
  245.  
  246. /*****************************************************************************
  247.  * libAVFilter
  248.  ****************************************************************************/
  249. struct libAVFilter {
  250.     IBaseFilterVtbl *vtbl;
  251.     long ref;
  252.     const wchar_t *name;
  253.     libAVPin *pin;
  254.     FILTER_INFO info;
  255.     FILTER_STATE state;
  256.     IReferenceClock *clock;
  257.     enum dshowDeviceType type;
  258.     void *priv_data;
  259.     int stream_index;
  260.     int64_t start_time;
  261.     void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType type);
  262. };
  263.  
  264. long          WINAPI libAVFilter_QueryInterface (libAVFilter *, const GUID *, void **);
  265. unsigned long WINAPI libAVFilter_AddRef         (libAVFilter *);
  266. unsigned long WINAPI libAVFilter_Release        (libAVFilter *);
  267. long          WINAPI libAVFilter_GetClassID     (libAVFilter *, CLSID *);
  268. long          WINAPI libAVFilter_Stop           (libAVFilter *);
  269. long          WINAPI libAVFilter_Pause          (libAVFilter *);
  270. long          WINAPI libAVFilter_Run            (libAVFilter *, REFERENCE_TIME);
  271. long          WINAPI libAVFilter_GetState       (libAVFilter *, DWORD, FILTER_STATE *);
  272. long          WINAPI libAVFilter_SetSyncSource  (libAVFilter *, IReferenceClock *);
  273. long          WINAPI libAVFilter_GetSyncSource  (libAVFilter *, IReferenceClock **);
  274. long          WINAPI libAVFilter_EnumPins       (libAVFilter *, IEnumPins **);
  275. long          WINAPI libAVFilter_FindPin        (libAVFilter *, const wchar_t *, IPin **);
  276. long          WINAPI libAVFilter_QueryFilterInfo(libAVFilter *, FILTER_INFO *);
  277. long          WINAPI libAVFilter_JoinFilterGraph(libAVFilter *, IFilterGraph *, const wchar_t *);
  278. long          WINAPI libAVFilter_QueryVendorInfo(libAVFilter *, wchar_t **);
  279.  
  280. void                 libAVFilter_Destroy(libAVFilter *);
  281. libAVFilter         *libAVFilter_Create (void *, void *, enum dshowDeviceType);
  282.  
  283. /*****************************************************************************
  284.  * dshow_ctx
  285.  ****************************************************************************/
  286. struct dshow_ctx {
  287.     const AVClass *class;
  288.  
  289.     IGraphBuilder *graph;
  290.  
  291.     char *device_name[2];
  292.     int video_device_number;
  293.     int audio_device_number;
  294.  
  295.     int   list_options;
  296.     int   list_devices;
  297.     int   audio_buffer_size;
  298.     int   crossbar_video_input_pin_number;
  299.     int   crossbar_audio_input_pin_number;
  300.     char *video_pin_name;
  301.     char *audio_pin_name;
  302.     int   show_video_device_dialog;
  303.     int   show_audio_device_dialog;
  304.     int   show_video_crossbar_connection_dialog;
  305.     int   show_audio_crossbar_connection_dialog;
  306.     int   show_analog_tv_tuner_dialog;
  307.     int   show_analog_tv_tuner_audio_dialog;
  308.     char *audio_filter_load_file;
  309.     char *audio_filter_save_file;
  310.     char *video_filter_load_file;
  311.     char *video_filter_save_file;
  312.  
  313.     IBaseFilter *device_filter[2];
  314.     IPin        *device_pin[2];
  315.     libAVFilter *capture_filter[2];
  316.     libAVPin    *capture_pin[2];
  317.  
  318.     HANDLE mutex;
  319.     HANDLE event[2]; /* event[0] is set by DirectShow
  320.                       * event[1] is set by callback() */
  321.     AVPacketList *pktl;
  322.  
  323.     int eof;
  324.  
  325.     int64_t curbufsize[2];
  326.     unsigned int video_frame_num;
  327.  
  328.     IMediaControl *control;
  329.     IMediaEvent *media_event;
  330.  
  331.     enum AVPixelFormat pixel_format;
  332.     enum AVCodecID video_codec_id;
  333.     char *framerate;
  334.  
  335.     int requested_width;
  336.     int requested_height;
  337.     AVRational requested_framerate;
  338.  
  339.     int sample_rate;
  340.     int sample_size;
  341.     int channels;
  342. };
  343.  
  344. /*****************************************************************************
  345.  * CrossBar
  346.  ****************************************************************************/
  347. HRESULT dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2,
  348.     IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx);
  349.  
  350. void dshow_show_filter_properties(IBaseFilter *pFilter, AVFormatContext *avctx);
  351.  
  352. #endif /* AVDEVICE_DSHOW_H */
  353.