Bug fix of wrong mp4, m4a duration
[platform/upstream/ffmpeg.git] / libavdevice / dshow.c
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 #include "dshow_capture.h"
23 #include "libavutil/parseutils.h"
24 #include "libavutil/pixdesc.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/mem.h"
27 #include "libavformat/internal.h"
28 #include "libavformat/riff.h"
29 #include "avdevice.h"
30 #include "libavcodec/raw.h"
31 #include "objidl.h"
32 #include "shlwapi.h"
33 // NB: technically, we should include dxva.h and use
34 // DXVA_ExtendedFormat, but that type is not defined in
35 // the MinGW headers. The DXVA2_ExtendedFormat and the
36 // contents of its fields is identical to
37 // DXVA_ExtendedFormat (see https://docs.microsoft.com/en-us/windows/win32/medfound/extended-color-information#color-space-in-media-types)
38 // and is provided by MinGW as well, so we use that
39 // instead. NB also that per the Microsoft docs, the
40 // lowest 8 bits of the structure, i.e. the SampleFormat
41 // field, contain AMCONTROL_xxx flags instead of sample
42 // format information, and should thus not be used.
43 // NB further that various values in the structure's
44 // fields (e.g. BT.2020 color space) are not provided
45 // for either of the DXVA structs, but are provided in
46 // the flags of the corresponding fields of Media Foundation.
47 // These may be provided by DirectShow devices (e.g. LAVFilters
48 // does so). So we use those values here too (the equivalence is
49 // indicated by Microsoft example code: https://docs.microsoft.com/en-us/windows/win32/api/dxva2api/ns-dxva2api-dxva2_videodesc)
50 #include "d3d9types.h"
51 #include "dxva2api.h"
52
53 #ifndef AMCONTROL_COLORINFO_PRESENT
54 // not defined in some versions of MinGW's dvdmedia.h
55 #   define AMCONTROL_COLORINFO_PRESENT 0x00000080 // if set, indicates DXVA color info is present in the upper (24) bits of the dwControlFlags
56 #endif
57
58
59 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
60 {
61     switch(biCompression) {
62     case BI_BITFIELDS:
63     case BI_RGB:
64         switch(biBitCount) { /* 1-8 are untested */
65             case 1:
66                 return AV_PIX_FMT_MONOWHITE;
67             case 4:
68                 return AV_PIX_FMT_RGB4;
69             case 8:
70                 return AV_PIX_FMT_RGB8;
71             case 16:
72                 return AV_PIX_FMT_RGB555;
73             case 24:
74                 return AV_PIX_FMT_BGR24;
75             case 32:
76                 return AV_PIX_FMT_0RGB32;
77         }
78     }
79     return avpriv_pix_fmt_find(PIX_FMT_LIST_RAW, biCompression); // all others
80 }
81
82 static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
83 {
84     switch (fmt_info->NominalRange)
85     {
86     case DXVA2_NominalRange_Unknown:
87         return AVCOL_RANGE_UNSPECIFIED;
88     case DXVA2_NominalRange_Normal: // equal to DXVA2_NominalRange_0_255
89         return AVCOL_RANGE_JPEG;
90     case DXVA2_NominalRange_Wide:   // equal to DXVA2_NominalRange_16_235
91         return AVCOL_RANGE_MPEG;
92     case DXVA2_NominalRange_48_208:
93         // not an ffmpeg color range
94         return AVCOL_RANGE_UNSPECIFIED;
95
96     // values from MediaFoundation SDK (mfobjects.h)
97     case 4:     // MFNominalRange_64_127
98         // not an ffmpeg color range
99         return AVCOL_RANGE_UNSPECIFIED;
100
101     default:
102         return AVCOL_RANGE_UNSPECIFIED;
103     }
104 }
105
106 static enum AVColorSpace dshow_color_space(DXVA2_ExtendedFormat *fmt_info)
107 {
108     switch (fmt_info->VideoTransferMatrix)
109     {
110     case DXVA2_VideoTransferMatrix_BT709:
111         return AVCOL_SPC_BT709;
112     case DXVA2_VideoTransferMatrix_BT601:
113         return AVCOL_SPC_BT470BG;
114     case DXVA2_VideoTransferMatrix_SMPTE240M:
115         return AVCOL_SPC_SMPTE240M;
116
117     // values from MediaFoundation SDK (mfobjects.h)
118     case 4:     // MFVideoTransferMatrix_BT2020_10
119     case 5:     // MFVideoTransferMatrix_BT2020_12
120         if (fmt_info->VideoTransferFunction == 12)  // MFVideoTransFunc_2020_const
121             return AVCOL_SPC_BT2020_CL;
122         else
123             return AVCOL_SPC_BT2020_NCL;
124
125     default:
126         return AVCOL_SPC_UNSPECIFIED;
127     }
128 }
129
130 static enum AVColorPrimaries dshow_color_primaries(DXVA2_ExtendedFormat *fmt_info)
131 {
132     switch (fmt_info->VideoPrimaries)
133     {
134     case DXVA2_VideoPrimaries_Unknown:
135         return AVCOL_PRI_UNSPECIFIED;
136     case DXVA2_VideoPrimaries_reserved:
137         return AVCOL_PRI_RESERVED;
138     case DXVA2_VideoPrimaries_BT709:
139         return AVCOL_PRI_BT709;
140     case DXVA2_VideoPrimaries_BT470_2_SysM:
141         return AVCOL_PRI_BT470M;
142     case DXVA2_VideoPrimaries_BT470_2_SysBG:
143     case DXVA2_VideoPrimaries_EBU3213:   // this is PAL
144         return AVCOL_PRI_BT470BG;
145     case DXVA2_VideoPrimaries_SMPTE170M:
146     case DXVA2_VideoPrimaries_SMPTE_C:
147         return AVCOL_PRI_SMPTE170M;
148     case DXVA2_VideoPrimaries_SMPTE240M:
149         return AVCOL_PRI_SMPTE240M;
150
151     // values from MediaFoundation SDK (mfobjects.h)
152     case 9:     // MFVideoPrimaries_BT2020
153         return AVCOL_PRI_BT2020;
154     case 10:    // MFVideoPrimaries_XYZ
155         return AVCOL_PRI_SMPTE428;
156     case 11:    // MFVideoPrimaries_DCI_P3
157         return AVCOL_PRI_SMPTE431;
158     case 12:    // MFVideoPrimaries_ACES (Academy Color Encoding System)
159         // not an FFmpeg color primary
160         return AVCOL_PRI_UNSPECIFIED;
161
162     default:
163         return AVCOL_PRI_UNSPECIFIED;
164     }
165 }
166
167 static enum AVColorTransferCharacteristic dshow_color_trc(DXVA2_ExtendedFormat *fmt_info)
168 {
169     switch (fmt_info->VideoTransferFunction)
170     {
171     case DXVA2_VideoTransFunc_Unknown:
172         return AVCOL_TRC_UNSPECIFIED;
173     case DXVA2_VideoTransFunc_10:
174         return AVCOL_TRC_LINEAR;
175     case DXVA2_VideoTransFunc_18:
176         // not an FFmpeg transfer characteristic
177         return AVCOL_TRC_UNSPECIFIED;
178     case DXVA2_VideoTransFunc_20:
179         // not an FFmpeg transfer characteristic
180         return AVCOL_TRC_UNSPECIFIED;
181     case DXVA2_VideoTransFunc_22:
182         return AVCOL_TRC_GAMMA22;
183     case DXVA2_VideoTransFunc_709:
184         return AVCOL_TRC_BT709;
185     case DXVA2_VideoTransFunc_240M:
186         return AVCOL_TRC_SMPTE240M;
187     case DXVA2_VideoTransFunc_sRGB:
188         return AVCOL_TRC_IEC61966_2_1;
189     case DXVA2_VideoTransFunc_28:
190         return AVCOL_TRC_GAMMA28;
191
192     // values from MediaFoundation SDK (mfobjects.h)
193     case 9:     // MFVideoTransFunc_Log_100
194         return AVCOL_TRC_LOG;
195     case 10:    // MFVideoTransFunc_Log_316
196         return AVCOL_TRC_LOG_SQRT;
197     case 11:    // MFVideoTransFunc_709_sym
198         // not an FFmpeg transfer characteristic
199         return AVCOL_TRC_UNSPECIFIED;
200     case 12:    // MFVideoTransFunc_2020_const
201     case 13:    // MFVideoTransFunc_2020
202         if (fmt_info->VideoTransferMatrix == 5) // MFVideoTransferMatrix_BT2020_12
203             return AVCOL_TRC_BT2020_12;
204         else
205             return AVCOL_TRC_BT2020_10;
206     case 14:    // MFVideoTransFunc_26
207         // not an FFmpeg transfer characteristic
208         return AVCOL_TRC_UNSPECIFIED;
209     case 15:    // MFVideoTransFunc_2084
210         return AVCOL_TRC_SMPTEST2084;
211     case 16:    // MFVideoTransFunc_HLG
212         return AVCOL_TRC_ARIB_STD_B67;
213     case 17:    // MFVideoTransFunc_10_rel
214         // not an FFmpeg transfer characteristic? Undocumented also by MS
215         return AVCOL_TRC_UNSPECIFIED;
216
217     default:
218         return AVCOL_TRC_UNSPECIFIED;
219     }
220 }
221
222 static enum AVChromaLocation dshow_chroma_loc(DXVA2_ExtendedFormat *fmt_info)
223 {
224     if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_Cosited)       // that is: (DXVA2_VideoChromaSubsampling_Horizontally_Cosited | DXVA2_VideoChromaSubsampling_Vertically_Cosited | DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes)
225         return AVCHROMA_LOC_TOPLEFT;
226     else if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_MPEG1)    // that is: DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes
227         return AVCHROMA_LOC_CENTER;
228     else if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_MPEG2)    // that is: (DXVA2_VideoChromaSubsampling_Horizontally_Cosited | DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes)
229         return AVCHROMA_LOC_LEFT;
230     else if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_DV_PAL)   // that is: (DXVA2_VideoChromaSubsampling_Horizontally_Cosited | DXVA2_VideoChromaSubsampling_Vertically_Cosited)
231         return AVCHROMA_LOC_TOPLEFT;
232     else
233         // unknown
234         return AVCHROMA_LOC_UNSPECIFIED;
235 }
236
237 static int
238 dshow_read_close(AVFormatContext *s)
239 {
240     struct dshow_ctx *ctx = s->priv_data;
241     PacketListEntry *pktl;
242
243     if (ctx->control) {
244         IMediaControl_Stop(ctx->control);
245         IMediaControl_Release(ctx->control);
246     }
247
248     if (ctx->media_event)
249         IMediaEvent_Release(ctx->media_event);
250
251     if (ctx->graph) {
252         IEnumFilters *fenum;
253         int r;
254         r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
255         if (r == S_OK) {
256             IBaseFilter *f;
257             IEnumFilters_Reset(fenum);
258             while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
259                 if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
260                     IEnumFilters_Reset(fenum); /* When a filter is removed,
261                                                 * the list must be reset. */
262                 IBaseFilter_Release(f);
263             }
264             IEnumFilters_Release(fenum);
265         }
266         IGraphBuilder_Release(ctx->graph);
267     }
268
269     if (ctx->capture_pin[VideoDevice])
270         ff_dshow_pin_Release(ctx->capture_pin[VideoDevice]);
271     if (ctx->capture_pin[AudioDevice])
272         ff_dshow_pin_Release(ctx->capture_pin[AudioDevice]);
273     if (ctx->capture_filter[VideoDevice])
274         ff_dshow_filter_Release(ctx->capture_filter[VideoDevice]);
275     if (ctx->capture_filter[AudioDevice])
276         ff_dshow_filter_Release(ctx->capture_filter[AudioDevice]);
277
278     if (ctx->device_pin[VideoDevice])
279         IPin_Release(ctx->device_pin[VideoDevice]);
280     if (ctx->device_pin[AudioDevice])
281         IPin_Release(ctx->device_pin[AudioDevice]);
282     if (ctx->device_filter[VideoDevice])
283         IBaseFilter_Release(ctx->device_filter[VideoDevice]);
284     if (ctx->device_filter[AudioDevice])
285         IBaseFilter_Release(ctx->device_filter[AudioDevice]);
286
287     av_freep(&ctx->device_name[0]);
288     av_freep(&ctx->device_name[1]);
289     av_freep(&ctx->device_unique_name[0]);
290     av_freep(&ctx->device_unique_name[1]);
291
292     if(ctx->mutex)
293         CloseHandle(ctx->mutex);
294     if(ctx->event[0])
295         CloseHandle(ctx->event[0]);
296     if(ctx->event[1])
297         CloseHandle(ctx->event[1]);
298
299     pktl = ctx->pktl;
300     while (pktl) {
301         PacketListEntry *next = pktl->next;
302         av_packet_unref(&pktl->pkt);
303         av_free(pktl);
304         pktl = next;
305     }
306
307     CoUninitialize();
308
309     return 0;
310 }
311
312 static char *dup_wchar_to_utf8(wchar_t *w)
313 {
314     char *s = NULL;
315     int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
316     s = av_malloc(l);
317     if (s)
318         WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
319     return s;
320 }
321
322 static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
323 {
324     struct dshow_ctx *ctx = s->priv_data;
325     static const uint8_t dropscore[] = {62, 75, 87, 100};
326     const int ndropscores = FF_ARRAY_ELEMS(dropscore);
327     unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
328     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
329
330     if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
331         av_log(s, AV_LOG_ERROR,
332               "real-time buffer [%s] [%s input] too full or near too full (%d%% of size: %d [rtbufsize parameter])! frame dropped!\n",
333               ctx->device_name[devtype], devtypename, buffer_fullness, s->max_picture_buffer);
334         return 1;
335     }
336
337     return 0;
338 }
339
340 static void
341 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
342 {
343     AVFormatContext *s = priv_data;
344     struct dshow_ctx *ctx = s->priv_data;
345     PacketListEntry **ppktl, *pktl_next;
346
347 //    dump_videohdr(s, vdhdr);
348
349     WaitForSingleObject(ctx->mutex, INFINITE);
350
351     if(shall_we_drop(s, index, devtype))
352         goto fail;
353
354     pktl_next = av_mallocz(sizeof(*pktl_next));
355     if(!pktl_next)
356         goto fail;
357
358     if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
359         av_free(pktl_next);
360         goto fail;
361     }
362
363     pktl_next->pkt.stream_index = index;
364     pktl_next->pkt.pts = time;
365     memcpy(pktl_next->pkt.data, buf, buf_size);
366
367     for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
368     *ppktl = pktl_next;
369     ctx->curbufsize[index] += buf_size;
370
371     SetEvent(ctx->event[1]);
372     ReleaseMutex(ctx->mutex);
373
374     return;
375 fail:
376     ReleaseMutex(ctx->mutex);
377     return;
378 }
379
380 static void
381 dshow_get_device_media_types(AVFormatContext *avctx, enum dshowDeviceType devtype,
382                                          enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter,
383                                          enum AVMediaType **media_types, int *nb_media_types)
384 {
385     IEnumPins *pins = 0;
386     IPin *pin;
387     int has_audio = 0, has_video = 0;
388
389     if (IBaseFilter_EnumPins(device_filter, &pins) != S_OK)
390         return;
391
392     while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
393         IKsPropertySet *p = NULL;
394         PIN_INFO info = { 0 };
395         GUID category;
396         DWORD r2;
397         IEnumMediaTypes *types = NULL;
398         AM_MEDIA_TYPE *type;
399
400         if (IPin_QueryPinInfo(pin, &info) != S_OK)
401             goto next;
402         IBaseFilter_Release(info.pFilter);
403
404         if (info.dir != PINDIR_OUTPUT)
405             goto next;
406         if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
407             goto next;
408         if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
409                                NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
410             goto next;
411         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
412             goto next;
413
414         if (IPin_EnumMediaTypes(pin, &types) != S_OK)
415             goto next;
416
417         // enumerate media types exposed by pin
418         // NB: don't know if a pin can expose both audio and video, check 'm all to be safe
419         IEnumMediaTypes_Reset(types);
420         while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
421             if (IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) {
422                 has_video = 1;
423             } else if (IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) {
424                 has_audio = 1;
425             }
426             CoTaskMemFree(type);
427         }
428
429     next:
430         if (types)
431             IEnumMediaTypes_Release(types);
432         if (p)
433             IKsPropertySet_Release(p);
434         if (pin)
435             IPin_Release(pin);
436     }
437
438     IEnumPins_Release(pins);
439
440     if (has_audio || has_video) {
441         int nb_types = has_audio + has_video;
442         *media_types = av_malloc_array(nb_types, sizeof(enum AVMediaType));
443         if (*media_types) {
444             if (has_audio)
445                 (*media_types)[0] = AVMEDIA_TYPE_AUDIO;
446             if (has_video)
447                 (*media_types)[0 + has_audio] = AVMEDIA_TYPE_VIDEO;
448             *nb_media_types = nb_types;
449         }
450     }
451 }
452
453 /**
454  * Cycle through available devices using the device enumerator devenum,
455  * retrieve the device with type specified by devtype and return the
456  * pointer to the object found in *pfilter.
457  * If pfilter is NULL, list all device names.
458  * If device_list is not NULL, populate it with found devices instead of
459  * outputting device names to log
460  */
461 static int
462 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
463                     enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype,
464                     IBaseFilter **pfilter, char **device_unique_name,
465                     AVDeviceInfoList **device_list)
466 {
467     struct dshow_ctx *ctx = avctx->priv_data;
468     IBaseFilter *device_filter = NULL;
469     IEnumMoniker *classenum = NULL;
470     IMoniker *m = NULL;
471     const char *device_name = ctx->device_name[devtype];
472     int skip = (devtype == VideoDevice) ? ctx->video_device_number
473                                         : ctx->audio_device_number;
474     int r;
475
476     const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
477                                    &CLSID_AudioInputDeviceCategory };
478     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
479     const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
480
481     r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype],
482                                              (IEnumMoniker **) &classenum, 0);
483     if (r != S_OK) {
484         av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n",
485                devtypename);
486         return AVERROR(EIO);
487     }
488
489     while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
490         IPropertyBag *bag = NULL;
491         char *friendly_name = NULL;
492         char *unique_name = NULL;
493         VARIANT var;
494         IBindCtx *bind_ctx = NULL;
495         LPOLESTR olestr = NULL;
496         LPMALLOC co_malloc = NULL;
497         AVDeviceInfo *device = NULL;
498         enum AVMediaType *media_types = NULL;
499         int nb_media_types = 0;
500         int i;
501
502         r = CoGetMalloc(1, &co_malloc);
503         if (r != S_OK)
504             goto fail;
505         r = CreateBindCtx(0, &bind_ctx);
506         if (r != S_OK)
507             goto fail;
508         /* GetDisplayname works for both video and audio, DevicePath doesn't */
509         r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr);
510         if (r != S_OK)
511             goto fail;
512         unique_name = dup_wchar_to_utf8(olestr);
513         /* replace ':' with '_' since we use : to delineate between sources */
514         for (i = 0; i < strlen(unique_name); i++) {
515             if (unique_name[i] == ':')
516                 unique_name[i] = '_';
517         }
518
519         r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
520         if (r != S_OK)
521             goto fail;
522
523         var.vt = VT_BSTR;
524         r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
525         if (r != S_OK)
526             goto fail;
527         friendly_name = dup_wchar_to_utf8(var.bstrVal);
528
529         if (pfilter) {
530             if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name))
531                 goto fail;
532
533             if (!skip--) {
534                 r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
535                 if (r != S_OK) {
536                     av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name);
537                     goto fail;
538                 }
539                 *device_unique_name = unique_name;
540                 unique_name = NULL;
541                 // success, loop will end now
542             }
543         } else {
544             // get media types exposed by pins of device
545             if (IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void* ) &device_filter) == S_OK) {
546                 dshow_get_device_media_types(avctx, devtype, sourcetype, device_filter, &media_types, &nb_media_types);
547                 IBaseFilter_Release(device_filter);
548                 device_filter = NULL;
549             }
550             if (device_list) {
551                 device = av_mallocz(sizeof(AVDeviceInfo));
552                 if (!device)
553                     goto fail;
554
555                 device->device_name = av_strdup(unique_name);
556                 device->device_description = av_strdup(friendly_name);
557                 if (!device->device_name || !device->device_description)
558                     goto fail;
559
560                 // make space in device_list for this new device
561                 if (av_reallocp_array(&(*device_list)->devices,
562                                      (*device_list)->nb_devices + 1,
563                                      sizeof(*(*device_list)->devices)) < 0)
564                     goto fail;
565
566                 // attach media_types to device
567                 device->nb_media_types = nb_media_types;
568                 device->media_types = media_types;
569                 nb_media_types = 0;
570                 media_types = NULL;
571
572                 // store device in list
573                 (*device_list)->devices[(*device_list)->nb_devices] = device;
574                 (*device_list)->nb_devices++;
575                 device = NULL;  // copied into array, make sure not freed below
576             }
577             else {
578                 av_log(avctx, AV_LOG_INFO, "\"%s\"", friendly_name);
579                 if (nb_media_types > 0) {
580                     const char* media_type = av_get_media_type_string(media_types[0]);
581                     av_log(avctx, AV_LOG_INFO, " (%s", media_type ? media_type : "unknown");
582                     for (int i = 1; i < nb_media_types; ++i) {
583                         media_type = av_get_media_type_string(media_types[i]);
584                         av_log(avctx, AV_LOG_INFO, ", %s", media_type ? media_type : "unknown");
585                     }
586                     av_log(avctx, AV_LOG_INFO, ")");
587                 } else {
588                     av_log(avctx, AV_LOG_INFO, " (none)");
589                 }
590                 av_log(avctx, AV_LOG_INFO, "\n");
591                 av_log(avctx, AV_LOG_INFO, "  Alternative name \"%s\"\n", unique_name);
592             }
593         }
594
595     fail:
596         av_freep(&media_types);
597         if (device) {
598             av_freep(&device->device_name);
599             av_freep(&device->device_description);
600             // NB: no need to av_freep(&device->media_types), its only moved to device once nothing can fail anymore
601             av_free(device);
602         }
603         if (olestr && co_malloc)
604             IMalloc_Free(co_malloc, olestr);
605         if (bind_ctx)
606             IBindCtx_Release(bind_ctx);
607         av_freep(&friendly_name);
608         av_freep(&unique_name);
609         if (bag)
610             IPropertyBag_Release(bag);
611         IMoniker_Release(m);
612     }
613
614     IEnumMoniker_Release(classenum);
615
616     if (pfilter) {
617         if (!device_filter) {
618             av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
619                    devtypename, device_name, sourcetypename);
620             return AVERROR(EIO);
621         }
622         *pfilter = device_filter;
623     }
624
625     return 0;
626 }
627
628 static int dshow_get_device_list(AVFormatContext *avctx, AVDeviceInfoList *device_list)
629 {
630     ICreateDevEnum *devenum = NULL;
631     int r;
632     int ret = AVERROR(EIO);
633
634     if (!device_list)
635         return AVERROR(EINVAL);
636
637     CoInitialize(0);
638
639     r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
640         &IID_ICreateDevEnum, (void**)&devenum);
641     if (r != S_OK) {
642         av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
643         goto error;
644     }
645
646     ret = dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL, NULL, &device_list);
647     if (ret < S_OK)
648         goto error;
649     ret = dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL, NULL, &device_list);
650
651 error:
652     if (devenum)
653         ICreateDevEnum_Release(devenum);
654
655     CoUninitialize();
656
657     return ret;
658 }
659
660 static int dshow_should_set_format(AVFormatContext *avctx, enum dshowDeviceType devtype)
661 {
662     struct dshow_ctx *ctx = avctx->priv_data;
663
664     return (devtype == VideoDevice && (ctx->framerate ||
665                                       (ctx->requested_width && ctx->requested_height) ||
666                                        ctx->pixel_format != AV_PIX_FMT_NONE ||
667                                        ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
668         || (devtype == AudioDevice && (ctx->channels || ctx->sample_size || ctx->sample_rate));
669 }
670
671
672 struct dshow_format_info {
673     enum dshowDeviceType devtype;
674     // video
675     int64_t framerate;
676     enum AVPixelFormat pix_fmt;
677     enum AVCodecID codec_id;
678     enum AVColorRange col_range;
679     enum AVColorSpace col_space;
680     enum AVColorPrimaries col_prim;
681     enum AVColorTransferCharacteristic col_trc;
682     enum AVChromaLocation chroma_loc;
683     int width;
684     int height;
685     // audio
686     int sample_rate;
687     int sample_size;
688     int channels;
689 };
690
691 // user must av_free the returned pointer
692 static struct dshow_format_info *dshow_get_format_info(AM_MEDIA_TYPE *type)
693 {
694     struct dshow_format_info *fmt_info = NULL;
695     BITMAPINFOHEADER *bih;
696     DXVA2_ExtendedFormat *extended_format_info = NULL;
697     WAVEFORMATEX *fx;
698     enum dshowDeviceType devtype;
699     int64_t framerate;
700
701     if (!type)
702         return NULL;
703
704     if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
705         VIDEOINFOHEADER *v = (void *) type->pbFormat;
706         framerate = v->AvgTimePerFrame;
707         bih       = &v->bmiHeader;
708         devtype   = VideoDevice;
709     } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
710         VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
711         devtype   = VideoDevice;
712         framerate = v->AvgTimePerFrame;
713         bih       = &v->bmiHeader;
714         if (v->dwControlFlags & AMCONTROL_COLORINFO_PRESENT)
715             extended_format_info = (DXVA2_ExtendedFormat *) &v->dwControlFlags;
716     } else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
717         fx = (void *) type->pbFormat;
718         devtype = AudioDevice;
719     } else {
720         return NULL;
721     }
722
723     fmt_info = av_mallocz(sizeof(struct dshow_format_info));
724     if (!fmt_info)
725         return NULL;
726     // initialize fields where unset is not zero
727     fmt_info->pix_fmt = AV_PIX_FMT_NONE;
728     fmt_info->col_space = AVCOL_SPC_UNSPECIFIED;
729     fmt_info->col_prim = AVCOL_PRI_UNSPECIFIED;
730     fmt_info->col_trc = AVCOL_TRC_UNSPECIFIED;
731     // now get info about format
732     fmt_info->devtype = devtype;
733     if (devtype == VideoDevice) {
734         fmt_info->width = bih->biWidth;
735         fmt_info->height = bih->biHeight;
736         fmt_info->framerate = framerate;
737         fmt_info->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
738         if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
739             const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
740             fmt_info->codec_id = av_codec_get_id(tags, bih->biCompression);
741         }
742         else
743             fmt_info->codec_id = AV_CODEC_ID_RAWVIDEO;
744
745         if (extended_format_info) {
746             fmt_info->col_range = dshow_color_range(extended_format_info);
747             fmt_info->col_space = dshow_color_space(extended_format_info);
748             fmt_info->col_prim = dshow_color_primaries(extended_format_info);
749             fmt_info->col_trc = dshow_color_trc(extended_format_info);
750             fmt_info->chroma_loc = dshow_chroma_loc(extended_format_info);
751         }
752     } else {
753         fmt_info->sample_rate = fx->nSamplesPerSec;
754         fmt_info->sample_size = fx->wBitsPerSample;
755         fmt_info->channels = fx->nChannels;
756     }
757
758     return fmt_info;
759 }
760
761 static void dshow_get_default_format(IPin *pin, IAMStreamConfig *config, enum dshowDeviceType devtype, AM_MEDIA_TYPE **type)
762 {
763     HRESULT hr;
764
765     if ((hr = IAMStreamConfig_GetFormat(config, type)) != S_OK) {
766         if (hr == E_NOTIMPL || !IsEqualGUID(&(*type)->majortype, devtype == VideoDevice ? &MEDIATYPE_Video : &MEDIATYPE_Audio)) {
767             // default not available or of wrong type,
768             // fall back to iterating exposed formats
769             // until one of the right type is found
770             IEnumMediaTypes* types = NULL;
771             if (IPin_EnumMediaTypes(pin, &types) != S_OK)
772                 return;
773             IEnumMediaTypes_Reset(types);
774             while (IEnumMediaTypes_Next(types, 1, type, NULL) == S_OK) {
775                 if (IsEqualGUID(&(*type)->majortype, devtype == VideoDevice ? &MEDIATYPE_Video : &MEDIATYPE_Audio)) {
776                     break;
777                 }
778                 CoTaskMemFree(*type);
779                 *type = NULL;
780             }
781             IEnumMediaTypes_Release(types);
782         }
783     }
784 }
785
786 /**
787  * Cycle through available formats available from the specified pin,
788  * try to set parameters specified through AVOptions, or the pin's
789  * default format if no such parameters were set. If successful,
790  * return 1 in *pformat_set.
791  * If pformat_set is NULL, list all pin capabilities.
792  */
793 static void
794 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
795                     IPin *pin, int *pformat_set)
796 {
797     struct dshow_ctx *ctx = avctx->priv_data;
798     IAMStreamConfig *config = NULL;
799     AM_MEDIA_TYPE *type = NULL;
800     AM_MEDIA_TYPE *previous_match_type = NULL;
801     int format_set = 0;
802     void *caps = NULL;
803     int i, n, size, r;
804     int wait_for_better = 0;
805     int use_default;
806
807     // format parameters requested by user
808     // if none are requested by user, the values will below be set to
809     // those of the default format
810     // video
811     enum AVCodecID requested_video_codec_id   = ctx->video_codec_id;
812     enum AVPixelFormat requested_pixel_format = ctx->pixel_format;
813     int64_t requested_framerate               = ctx->framerate ? ((int64_t)ctx->requested_framerate.den * 10000000)
814                                                                     / ctx->requested_framerate.num : 0;
815     int requested_width                       = ctx->requested_width;
816     int requested_height                      = ctx->requested_height;
817     // audio
818     int requested_sample_rate                 = ctx->sample_rate;
819     int requested_sample_size                 = ctx->sample_size;
820     int requested_channels                    = ctx->channels;
821
822     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
823         return;
824     if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
825         goto end;
826
827     caps = av_malloc(size);
828     if (!caps)
829         goto end;
830
831     /**
832      * If we should open the device with the default format,
833      * then:
834      * 1. check what the format of the default device is, and
835      * 2. below we iterate all formats till we find a matching
836      *    one, with most info exposed (see comment below).
837      */
838     use_default = !dshow_should_set_format(avctx, devtype);
839     if (use_default && pformat_set)
840     {
841         // get default
842         dshow_get_default_format(pin, config, devtype, &type);
843         if (!type)
844             // this pin does not expose any formats of the expected type
845             goto end;
846
847         if (type) {
848             // interrogate default format, so we know what to search for below
849             struct dshow_format_info *fmt_info = dshow_get_format_info(type);
850             if (fmt_info) {
851                 if (fmt_info->devtype == VideoDevice) {
852                     requested_video_codec_id = fmt_info->codec_id;
853                     requested_pixel_format   = fmt_info->pix_fmt;
854                     requested_framerate      = fmt_info->framerate;
855                     requested_width          = fmt_info->width;
856                     requested_height         = fmt_info->height;
857                 } else {
858                     requested_sample_rate = fmt_info->sample_rate;
859                     requested_sample_size = fmt_info->sample_size;
860                     requested_channels    = fmt_info->channels;
861                 }
862                 av_free(fmt_info);  // free but don't set to NULL to enable below check
863             }
864
865             if (type && type->pbFormat)
866                 CoTaskMemFree(type->pbFormat);
867             CoTaskMemFree(type);
868             type = NULL;
869             if (!fmt_info)
870                 // default format somehow invalid, can't continue with this pin
871                 goto end;
872             fmt_info = NULL;
873         }
874     }
875
876     // NB: some devices (e.g. Logitech C920) expose each video format twice:
877     // both a format containing a VIDEOINFOHEADER and a format containing
878     // a VIDEOINFOHEADER2. We want, if possible, to select a format with a
879     // VIDEOINFOHEADER2, as this potentially provides more info about the
880     // format. So, if in the iteration below we have found a matching format,
881     // but it is a VIDEOINFOHEADER, keep looking for a matching format that
882     // exposes contains a VIDEOINFOHEADER2. Fall back to the VIDEOINFOHEADER
883     // format if no corresponding VIDEOINFOHEADER2 is found when we finish
884     // iterating.
885     for (i = 0; i < n && !format_set; i++) {
886         struct dshow_format_info *fmt_info = NULL;
887         r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
888         if (r != S_OK)
889             goto next;
890 #if DSHOWDEBUG
891         ff_print_AM_MEDIA_TYPE(type);
892 #endif
893
894         fmt_info = dshow_get_format_info(type);
895         if (!fmt_info)
896             goto next;
897
898         if (devtype == VideoDevice) {
899             VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
900             BITMAPINFOHEADER *bih;
901             int64_t *fr;
902 #if DSHOWDEBUG
903             ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
904 #endif
905
906             if (fmt_info->devtype != VideoDevice)
907                 goto next;
908
909             if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
910                 VIDEOINFOHEADER *v = (void *) type->pbFormat;
911                 fr  = &v->AvgTimePerFrame;
912                 bih = &v->bmiHeader;
913                 wait_for_better = 1;
914             } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
915                 VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
916                 fr  = &v->AvgTimePerFrame;
917                 bih = &v->bmiHeader;
918                 wait_for_better = 0;
919             }
920
921             if (!pformat_set) {
922                 const char *chroma = av_chroma_location_name(fmt_info->chroma_loc);
923                 if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
924                     const AVCodec *codec = avcodec_find_decoder(fmt_info->codec_id);
925                     if (fmt_info->codec_id == AV_CODEC_ID_NONE || !codec) {
926                         av_log(avctx, AV_LOG_INFO, "  unknown compression type 0x%X", (int) bih->biCompression);
927                     } else {
928                         av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
929                     }
930                 } else {
931                     av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(fmt_info->pix_fmt));
932                 }
933                 av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g",
934                        vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
935                        1e7 / vcaps->MaxFrameInterval,
936                        vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
937                        1e7 / vcaps->MinFrameInterval);
938
939                 if (fmt_info->col_range != AVCOL_RANGE_UNSPECIFIED ||
940                     fmt_info->col_space != AVCOL_SPC_UNSPECIFIED ||
941                     fmt_info->col_prim != AVCOL_PRI_UNSPECIFIED ||
942                     fmt_info->col_trc != AVCOL_TRC_UNSPECIFIED) {
943                     const char *range = av_color_range_name(fmt_info->col_range);
944                     const char *space = av_color_space_name(fmt_info->col_space);
945                     const char *prim = av_color_primaries_name(fmt_info->col_prim);
946                     const char *trc = av_color_transfer_name(fmt_info->col_trc);
947                     av_log(avctx, AV_LOG_INFO, " (%s, %s/%s/%s",
948                         range ? range : "unknown",
949                         space ? space : "unknown",
950                         prim  ? prim  : "unknown",
951                         trc   ? trc   : "unknown");
952                     if (fmt_info->chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
953                         av_log(avctx, AV_LOG_INFO, ", %s", chroma ? chroma : "unknown");
954                     av_log(avctx, AV_LOG_INFO, ")");
955                 }
956                 else if (fmt_info->chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
957                     av_log(avctx, AV_LOG_INFO, "(%s)", chroma ? chroma : "unknown");
958
959                 av_log(avctx, AV_LOG_INFO, "\n");
960                 goto next;
961             }
962             if (requested_video_codec_id != AV_CODEC_ID_RAWVIDEO) {
963                 if (requested_video_codec_id != fmt_info->codec_id)
964                     goto next;
965             }
966             if (requested_pixel_format != AV_PIX_FMT_NONE &&
967                 requested_pixel_format != fmt_info->pix_fmt) {
968                 goto next;
969             }
970             if (requested_framerate) {
971                 if (requested_framerate > vcaps->MaxFrameInterval ||
972                     requested_framerate < vcaps->MinFrameInterval)
973                     goto next;
974                 *fr = requested_framerate;
975             }
976             if (requested_width && requested_height) {
977                 if (requested_width  > vcaps->MaxOutputSize.cx ||
978                     requested_width  < vcaps->MinOutputSize.cx ||
979                     requested_height > vcaps->MaxOutputSize.cy ||
980                     requested_height < vcaps->MinOutputSize.cy)
981                     goto next;
982                 bih->biWidth  = requested_width;
983                 bih->biHeight = requested_height;
984             }
985         } else {
986             WAVEFORMATEX *fx;
987             AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
988 #if DSHOWDEBUG
989             ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
990 #endif
991             if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
992                 fx = (void *) type->pbFormat;
993             } else {
994                 goto next;
995             }
996             if (!pformat_set) {
997                 av_log(
998                     avctx,
999                     AV_LOG_INFO,
1000                     "  ch=%2u, bits=%2u, rate=%6lu\n",
1001                     fx->nChannels, fx->wBitsPerSample, fx->nSamplesPerSec
1002                 );
1003                 continue;
1004             }
1005             if (
1006                 (requested_sample_rate && requested_sample_rate != fx->nSamplesPerSec) ||
1007                 (requested_sample_size && requested_sample_size != fx->wBitsPerSample) ||
1008                 (requested_channels    && requested_channels    != fx->nChannels     )
1009             ) {
1010                 goto next;
1011             }
1012         }
1013
1014         // found a matching format. Either apply or store
1015         // for safekeeping if we might maybe find a better
1016         // format with more info attached to it (see comment
1017         // above loop)
1018         if (!wait_for_better) {
1019             if (IAMStreamConfig_SetFormat(config, type) != S_OK)
1020                 goto next;
1021             format_set = 1;
1022         }
1023         else if (!previous_match_type) {
1024             // store this matching format for possible later use.
1025             // If we have already found a matching format, ignore it
1026             previous_match_type = type;
1027             type = NULL;
1028         }
1029 next:
1030         av_freep(&fmt_info);
1031         if (type && type->pbFormat)
1032             CoTaskMemFree(type->pbFormat);
1033         CoTaskMemFree(type);
1034         type = NULL;
1035     }
1036
1037     // set the pin's format, if wanted
1038     if (pformat_set && !format_set) {
1039         if (previous_match_type) {
1040             // previously found a matching VIDEOINFOHEADER format and stored
1041             // it for safe keeping. Searching further for a matching
1042             // VIDEOINFOHEADER2 format yielded nothing. So set the pin's
1043             // format based on the VIDEOINFOHEADER format.
1044             // NB: this never applies to an audio format because
1045             // previous_match_type always NULL in that case
1046             if (IAMStreamConfig_SetFormat(config, previous_match_type) == S_OK)
1047                 format_set = 1;
1048         }
1049         else if (use_default) {
1050             // default format returned by device apparently was not contained
1051             // in the capabilities of any of the formats returned by the device
1052             // (sic?). Fall back to directly setting the default format
1053             dshow_get_default_format(pin, config, devtype, &type);
1054             if (IAMStreamConfig_SetFormat(config, type) == S_OK)
1055                 format_set = 1;
1056             if (type && type->pbFormat)
1057                 CoTaskMemFree(type->pbFormat);
1058             CoTaskMemFree(type);
1059             type = NULL;
1060         }
1061     }
1062
1063 end:
1064     if (previous_match_type && previous_match_type->pbFormat)
1065         CoTaskMemFree(previous_match_type->pbFormat);
1066     CoTaskMemFree(previous_match_type);
1067     IAMStreamConfig_Release(config);
1068     av_free(caps);
1069     if (pformat_set)
1070         *pformat_set = format_set;
1071 }
1072
1073 /**
1074  * Set audio device buffer size in milliseconds (which can directly impact
1075  * latency, depending on the device).
1076  */
1077 static int
1078 dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
1079 {
1080     struct dshow_ctx *ctx = avctx->priv_data;
1081     IAMBufferNegotiation *buffer_negotiation = NULL;
1082     ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
1083     IAMStreamConfig *config = NULL;
1084     AM_MEDIA_TYPE *type = NULL;
1085     int ret = AVERROR(EIO);
1086
1087     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
1088         goto end;
1089     if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
1090         goto end;
1091     if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
1092         goto end;
1093
1094     props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
1095                    * ctx->audio_buffer_size / 1000;
1096
1097     if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
1098         goto end;
1099     if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
1100         goto end;
1101
1102     ret = 0;
1103
1104 end:
1105     if (buffer_negotiation)
1106         IAMBufferNegotiation_Release(buffer_negotiation);
1107     if (type) {
1108         if (type->pbFormat)
1109             CoTaskMemFree(type->pbFormat);
1110         CoTaskMemFree(type);
1111     }
1112     if (config)
1113         IAMStreamConfig_Release(config);
1114
1115     return ret;
1116 }
1117
1118 /**
1119  * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
1120  */
1121 void
1122 ff_dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx) {
1123     ISpecifyPropertyPages *property_pages = NULL;
1124     IUnknown *device_filter_iunknown = NULL;
1125     HRESULT hr;
1126     FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
1127     CAUUID ca_guid = {0};
1128
1129     hr  = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
1130     if (hr != S_OK) {
1131         av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
1132         goto end;
1133     }
1134     hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
1135     if (hr != S_OK) {
1136         goto fail;
1137     }
1138     hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
1139     if (hr != S_OK) {
1140         goto fail;
1141     }
1142     hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
1143     if (hr != S_OK) {
1144         goto fail;
1145     }
1146     hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
1147         ca_guid.pElems, 0, 0, NULL);
1148     if (hr != S_OK) {
1149         goto fail;
1150     }
1151     goto end;
1152 fail:
1153     av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
1154 end:
1155     if (property_pages)
1156         ISpecifyPropertyPages_Release(property_pages);
1157     if (device_filter_iunknown)
1158         IUnknown_Release(device_filter_iunknown);
1159     if (filter_info.pGraph)
1160         IFilterGraph_Release(filter_info.pGraph);
1161     if (ca_guid.pElems)
1162         CoTaskMemFree(ca_guid.pElems);
1163 }
1164
1165 /**
1166  * Cycle through available pins using the device_filter device, of type
1167  * devtype, retrieve the first output pin and return the pointer to the
1168  * object found in *ppin.
1169  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
1170  */
1171 static int
1172 dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
1173                  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
1174 {
1175     struct dshow_ctx *ctx = avctx->priv_data;
1176     IEnumPins *pins = 0;
1177     IPin *device_pin = NULL;
1178     IPin *pin;
1179     int r;
1180
1181     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
1182     const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
1183
1184     int set_format = dshow_should_set_format(avctx, devtype);
1185     int format_set = 0;
1186     int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
1187
1188     if (should_show_properties)
1189         ff_dshow_show_filter_properties(device_filter, avctx);
1190
1191     r = IBaseFilter_EnumPins(device_filter, &pins);
1192     if (r != S_OK) {
1193         av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
1194         return AVERROR(EIO);
1195     }
1196
1197     if (!ppin) {
1198         av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
1199                devtypename, sourcetypename);
1200     }
1201
1202     while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
1203         IKsPropertySet *p = NULL;
1204         PIN_INFO info = {0};
1205         GUID category;
1206         DWORD r2;
1207         char *name_buf = NULL;
1208         wchar_t *pin_id = NULL;
1209         char *pin_buf = NULL;
1210         char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
1211
1212         IPin_QueryPinInfo(pin, &info);
1213         IBaseFilter_Release(info.pFilter);
1214
1215         if (info.dir != PINDIR_OUTPUT)
1216             goto next;
1217         if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
1218             goto next;
1219         if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
1220                                NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
1221             goto next;
1222         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
1223             goto next;
1224         name_buf = dup_wchar_to_utf8(info.achName);
1225
1226         r = IPin_QueryId(pin, &pin_id);
1227         if (r != S_OK) {
1228             av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
1229             return AVERROR(EIO);
1230         }
1231         pin_buf = dup_wchar_to_utf8(pin_id);
1232
1233         if (!ppin) {
1234             av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
1235             dshow_cycle_formats(avctx, devtype, pin, NULL);
1236             goto next;
1237         }
1238
1239         if (desired_pin_name) {
1240             if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
1241                 av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
1242                     name_buf, pin_buf, desired_pin_name);
1243                 goto next;
1244             }
1245         }
1246
1247         // will either try to find format matching options supplied by user
1248         // or try to open default format. Successful if returns with format_set==1
1249         dshow_cycle_formats(avctx, devtype, pin, &format_set);
1250         if (!format_set) {
1251             goto next;
1252         }
1253
1254         if (devtype == AudioDevice && ctx->audio_buffer_size) {
1255             if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
1256                 av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
1257             }
1258         }
1259
1260         if (format_set) {
1261             device_pin = pin;
1262             av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
1263         }
1264 next:
1265         if (p)
1266             IKsPropertySet_Release(p);
1267         if (device_pin != pin)
1268             IPin_Release(pin);
1269         av_free(name_buf);
1270         av_free(pin_buf);
1271         if (pin_id)
1272             CoTaskMemFree(pin_id);
1273     }
1274
1275     IEnumPins_Release(pins);
1276
1277     if (ppin) {
1278         if (set_format && !format_set) {
1279             av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
1280             return AVERROR(EIO);
1281         }
1282         if (!device_pin) {
1283             av_log(avctx, AV_LOG_ERROR,
1284                 "Could not find output pin from %s capture device.\n", devtypename);
1285             return AVERROR(EIO);
1286         }
1287         *ppin = device_pin;
1288     }
1289
1290     return 0;
1291 }
1292
1293 /**
1294  * List options for device with type devtype, source filter type sourcetype
1295  *
1296  * @param devenum device enumerator used for accessing the device
1297  */
1298 static int
1299 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
1300                           enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
1301 {
1302     struct dshow_ctx *ctx = avctx->priv_data;
1303     IBaseFilter *device_filter = NULL;
1304     char *device_unique_name = NULL;
1305     int r;
1306
1307     if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name, NULL)) < 0)
1308         return r;
1309     ctx->device_filter[devtype] = device_filter;
1310     ctx->device_unique_name[devtype] = device_unique_name;
1311     if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
1312         return r;
1313     return 0;
1314 }
1315
1316 static int
1317 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
1318                   enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
1319 {
1320     struct dshow_ctx *ctx = avctx->priv_data;
1321     IBaseFilter *device_filter = NULL;
1322     char *device_filter_unique_name = NULL;
1323     IGraphBuilder *graph = ctx->graph;
1324     IPin *device_pin = NULL;
1325     DShowPin *capture_pin = NULL;
1326     DShowFilter *capture_filter = NULL;
1327     ICaptureGraphBuilder2 *graph_builder2 = NULL;
1328     int ret = AVERROR(EIO);
1329     int r;
1330     IStream *ifile_stream = NULL;
1331     IStream *ofile_stream = NULL;
1332     IPersistStream *pers_stream = NULL;
1333     enum dshowDeviceType otherDevType = (devtype == VideoDevice) ? AudioDevice : VideoDevice;
1334
1335     const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
1336
1337
1338     if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
1339             ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
1340         HRESULT hr;
1341         char *filename = NULL;
1342
1343         if (sourcetype == AudioSourceDevice)
1344             filename = ctx->audio_filter_load_file;
1345         else
1346             filename = ctx->video_filter_load_file;
1347
1348         hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
1349         if (S_OK != hr) {
1350             av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
1351             goto error;
1352         }
1353
1354         hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
1355         if (hr != S_OK) {
1356             av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
1357             goto error;
1358         }
1359
1360         if (sourcetype == AudioSourceDevice)
1361             av_log(avctx, AV_LOG_INFO, "Audio-");
1362         else
1363             av_log(avctx, AV_LOG_INFO, "Video-");
1364         av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
1365     } else {
1366
1367         if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_filter_unique_name, NULL)) < 0) {
1368             ret = r;
1369             goto error;
1370         }
1371     }
1372         if (ctx->device_filter[otherDevType]) {
1373         // avoid adding add two instances of the same device to the graph, one for video, one for audio
1374         // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK)
1375         if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) {
1376           av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name);
1377           IBaseFilter_Release(device_filter);
1378           device_filter = ctx->device_filter[otherDevType];
1379           IBaseFilter_AddRef(ctx->device_filter[otherDevType]);
1380         } else {
1381             av_log(avctx, AV_LOG_DEBUG, "not reusing previous graph capture filter %s != %s\n", device_filter_unique_name, ctx->device_unique_name[otherDevType]);
1382         }
1383     }
1384
1385     ctx->device_filter [devtype] = device_filter;
1386     ctx->device_unique_name [devtype] = device_filter_unique_name;
1387
1388     r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
1389     if (r != S_OK) {
1390         av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
1391         goto error;
1392     }
1393
1394     if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
1395         ret = r;
1396         goto error;
1397     }
1398
1399     ctx->device_pin[devtype] = device_pin;
1400
1401     capture_filter = ff_dshow_filter_Create(avctx, callback, devtype);
1402     if (!capture_filter) {
1403         av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
1404         goto error;
1405     }
1406     ctx->capture_filter[devtype] = capture_filter;
1407
1408     if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
1409             ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
1410
1411         HRESULT hr;
1412         char *filename = NULL;
1413
1414         if (sourcetype == AudioSourceDevice)
1415             filename = ctx->audio_filter_save_file;
1416         else
1417             filename = ctx->video_filter_save_file;
1418
1419         hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
1420         if (S_OK != hr) {
1421             av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
1422             goto error;
1423         }
1424
1425         hr  = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
1426         if (hr != S_OK) {
1427             av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
1428             goto error;
1429         }
1430
1431         hr = OleSaveToStream(pers_stream, ofile_stream);
1432         if (hr != S_OK) {
1433             av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
1434             goto error;
1435         }
1436
1437         hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
1438         if (S_OK != hr) {
1439             av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
1440             goto error;
1441         }
1442
1443         if (sourcetype == AudioSourceDevice)
1444             av_log(avctx, AV_LOG_INFO, "Audio-");
1445         else
1446             av_log(avctx, AV_LOG_INFO, "Video-");
1447         av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
1448     }
1449
1450     r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
1451                                 filter_name[devtype]);
1452     if (r != S_OK) {
1453         av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
1454         goto error;
1455     }
1456
1457     ff_dshow_pin_AddRef(capture_filter->pin);
1458     capture_pin = capture_filter->pin;
1459     ctx->capture_pin[devtype] = capture_pin;
1460
1461     r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
1462                          &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
1463     if (r != S_OK) {
1464         av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
1465         goto error;
1466     }
1467     ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
1468     if (r != S_OK) {
1469         av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
1470         goto error;
1471     }
1472
1473     r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
1474         (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
1475
1476     if (r != S_OK) {
1477         av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
1478         goto error;
1479     }
1480
1481     r = ff_dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
1482
1483     if (r != S_OK) {
1484         av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
1485         goto error;
1486     }
1487
1488     ret = 0;
1489
1490 error:
1491     if (graph_builder2 != NULL)
1492         ICaptureGraphBuilder2_Release(graph_builder2);
1493
1494     if (pers_stream)
1495         IPersistStream_Release(pers_stream);
1496
1497     if (ifile_stream)
1498         IStream_Release(ifile_stream);
1499
1500     if (ofile_stream)
1501         IStream_Release(ofile_stream);
1502
1503     return ret;
1504 }
1505
1506 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
1507 {
1508     switch (sample_fmt) {
1509     case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
1510     case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
1511     case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
1512     default:                return AV_CODEC_ID_NONE; /* Should never happen. */
1513     }
1514 }
1515
1516 static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
1517 {
1518     switch (bits) {
1519     case 8:  return AV_SAMPLE_FMT_U8;
1520     case 16: return AV_SAMPLE_FMT_S16;
1521     case 32: return AV_SAMPLE_FMT_S32;
1522     default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
1523     }
1524 }
1525
1526 static int
1527 dshow_add_device(AVFormatContext *avctx,
1528                  enum dshowDeviceType devtype)
1529 {
1530     struct dshow_ctx *ctx = avctx->priv_data;
1531     AM_MEDIA_TYPE type;
1532     AVCodecParameters *par;
1533     AVStream *st;
1534     struct dshow_format_info *fmt_info = NULL;
1535     int ret = AVERROR(EIO);
1536
1537     type.pbFormat = NULL;
1538
1539     st = avformat_new_stream(avctx, NULL);
1540     if (!st) {
1541         ret = AVERROR(ENOMEM);
1542         goto error;
1543     }
1544     st->id = devtype;
1545
1546     ctx->capture_filter[devtype]->stream_index = st->index;
1547
1548     ff_dshow_pin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
1549     fmt_info = dshow_get_format_info(&type);
1550     if (!fmt_info) {
1551         ret = AVERROR(EIO);
1552         goto error;
1553     }
1554
1555     par = st->codecpar;
1556     if (devtype == VideoDevice) {
1557         BITMAPINFOHEADER *bih = NULL;
1558         AVRational time_base;
1559
1560         if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
1561             VIDEOINFOHEADER *v = (void *) type.pbFormat;
1562             time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
1563             bih = &v->bmiHeader;
1564         } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
1565             VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
1566             time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
1567             bih = &v->bmiHeader;
1568         }
1569         if (!bih) {
1570             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1571             goto error;
1572         }
1573
1574         st->avg_frame_rate = av_inv_q(time_base);
1575         st->r_frame_rate = av_inv_q(time_base);
1576
1577         par->codec_type = AVMEDIA_TYPE_VIDEO;
1578         par->width      = fmt_info->width;
1579         par->height     = fmt_info->height;
1580         par->codec_tag  = bih->biCompression;
1581         par->format     = fmt_info->pix_fmt;
1582         if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
1583             av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
1584             par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
1585         }
1586         par->color_range = fmt_info->col_range;
1587         par->color_space = fmt_info->col_space;
1588         par->color_primaries = fmt_info->col_prim;
1589         par->color_trc = fmt_info->col_trc;
1590         par->chroma_location = fmt_info->chroma_loc;
1591         par->codec_id = fmt_info->codec_id;
1592         if (par->codec_id == AV_CODEC_ID_RAWVIDEO) {
1593             if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
1594                 par->bits_per_coded_sample = bih->biBitCount;
1595                 if (par->height < 0) {
1596                     par->height *= -1;
1597                 } else {
1598                     par->extradata = av_malloc(9 + AV_INPUT_BUFFER_PADDING_SIZE);
1599                     if (par->extradata) {
1600                         par->extradata_size = 9;
1601                         memcpy(par->extradata, "BottomUp", 9);
1602                     }
1603                 }
1604             }
1605         } else {
1606             if (par->codec_id == AV_CODEC_ID_NONE) {
1607                 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
1608                                  "Please report type 0x%X.\n", (int) bih->biCompression);
1609                 ret = AVERROR_PATCHWELCOME;
1610                 goto error;
1611             }
1612             par->bits_per_coded_sample = bih->biBitCount;
1613         }
1614     } else {
1615         if (!IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
1616             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1617             goto error;
1618         }
1619
1620         par->codec_type  = AVMEDIA_TYPE_AUDIO;
1621         par->format      = sample_fmt_bits_per_sample(fmt_info->sample_size);
1622         par->codec_id    = waveform_codec_id(par->format);
1623         par->sample_rate = fmt_info->sample_rate;
1624         par->ch_layout.nb_channels = fmt_info->channels;
1625     }
1626
1627     avpriv_set_pts_info(st, 64, 1, 10000000);
1628
1629     ret = 0;
1630
1631 error:
1632     av_freep(&fmt_info);
1633     if (type.pbFormat)
1634         CoTaskMemFree(type.pbFormat);
1635     return ret;
1636 }
1637
1638 static int parse_device_name(AVFormatContext *avctx)
1639 {
1640     struct dshow_ctx *ctx = avctx->priv_data;
1641     char **device_name = ctx->device_name;
1642     char *name = av_strdup(avctx->url);
1643     char *tmp = name;
1644     int ret = 1;
1645     char *type;
1646
1647     while ((type = strtok(tmp, "="))) {
1648         char *token = strtok(NULL, ":");
1649         tmp = NULL;
1650
1651         if        (!strcmp(type, "video")) {
1652             device_name[0] = token;
1653         } else if (!strcmp(type, "audio")) {
1654             device_name[1] = token;
1655         } else {
1656             device_name[0] = NULL;
1657             device_name[1] = NULL;
1658             break;
1659         }
1660     }
1661
1662     if (!device_name[0] && !device_name[1]) {
1663         ret = 0;
1664     } else {
1665         if (device_name[0])
1666             device_name[0] = av_strdup(device_name[0]);
1667         if (device_name[1])
1668             device_name[1] = av_strdup(device_name[1]);
1669     }
1670
1671     av_free(name);
1672     return ret;
1673 }
1674
1675 static int dshow_read_header(AVFormatContext *avctx)
1676 {
1677     struct dshow_ctx *ctx = avctx->priv_data;
1678     IGraphBuilder *graph = NULL;
1679     ICreateDevEnum *devenum = NULL;
1680     IMediaControl *control = NULL;
1681     IMediaEvent *media_event = NULL;
1682     HANDLE media_event_handle;
1683     HANDLE proc;
1684     int ret = AVERROR(EIO);
1685     int r;
1686
1687     CoInitialize(0);
1688
1689     if (!ctx->list_devices && !parse_device_name(avctx)) {
1690         av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
1691         goto error;
1692     }
1693
1694     ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
1695                                                 : AV_CODEC_ID_RAWVIDEO;
1696     if (ctx->pixel_format != AV_PIX_FMT_NONE) {
1697         if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
1698             av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
1699                               "video codec is not set or set to rawvideo\n");
1700             ret = AVERROR(EINVAL);
1701             goto error;
1702         }
1703     }
1704     if (ctx->framerate) {
1705         r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
1706         if (r < 0) {
1707             av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
1708             goto error;
1709         }
1710     }
1711
1712     r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1713                          &IID_IGraphBuilder, (void **) &graph);
1714     if (r != S_OK) {
1715         av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
1716         goto error;
1717     }
1718     ctx->graph = graph;
1719
1720     r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
1721                          &IID_ICreateDevEnum, (void **) &devenum);
1722     if (r != S_OK) {
1723         av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
1724         goto error;
1725     }
1726
1727     if (ctx->list_devices) {
1728         dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL, NULL, NULL);
1729         dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL, NULL, NULL);
1730         ret = AVERROR_EXIT;
1731         goto error;
1732     }
1733     if (ctx->list_options) {
1734         if (ctx->device_name[VideoDevice])
1735             if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
1736                 ret = r;
1737                 goto error;
1738             }
1739         if (ctx->device_name[AudioDevice]) {
1740             if (dshow_list_device_options(avctx, devenum, AudioDevice, AudioSourceDevice)) {
1741                 /* show audio options from combined video+audio sources as fallback */
1742                 if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
1743                     ret = r;
1744                     goto error;
1745                 }
1746             }
1747         }
1748         // don't exit yet, allow it to list crossbar options in dshow_open_device
1749     }
1750     if (ctx->device_name[VideoDevice]) {
1751         if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
1752             (r = dshow_add_device(avctx, VideoDevice)) < 0) {
1753             ret = r;
1754             goto error;
1755         }
1756     }
1757     if (ctx->device_name[AudioDevice]) {
1758         if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
1759             (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1760             av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
1761             /* see if there's a video source with an audio pin with the given audio name */
1762             if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
1763                 (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1764                 ret = r;
1765                 goto error;
1766             }
1767         }
1768     }
1769     if (ctx->list_options) {
1770         /* allow it to list crossbar options in dshow_open_device */
1771         ret = AVERROR_EXIT;
1772         goto error;
1773     }
1774     ctx->curbufsize[0] = 0;
1775     ctx->curbufsize[1] = 0;
1776     ctx->mutex = CreateMutex(NULL, 0, NULL);
1777     if (!ctx->mutex) {
1778         av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
1779         goto error;
1780     }
1781     ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
1782     if (!ctx->event[1]) {
1783         av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
1784         goto error;
1785     }
1786
1787     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
1788     if (r != S_OK) {
1789         av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
1790         goto error;
1791     }
1792     ctx->control = control;
1793
1794     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
1795     if (r != S_OK) {
1796         av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
1797         goto error;
1798     }
1799     ctx->media_event = media_event;
1800
1801     r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
1802     if (r != S_OK) {
1803         av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
1804         goto error;
1805     }
1806     proc = GetCurrentProcess();
1807     r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
1808                         0, 0, DUPLICATE_SAME_ACCESS);
1809     if (!r) {
1810         av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
1811         goto error;
1812     }
1813
1814     r = IMediaControl_Run(control);
1815     if (r == S_FALSE) {
1816         OAFilterState pfs;
1817         r = IMediaControl_GetState(control, 0, &pfs);
1818     }
1819     if (r != S_OK) {
1820         av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
1821         goto error;
1822     }
1823
1824     ret = 0;
1825
1826 error:
1827
1828     if (devenum)
1829         ICreateDevEnum_Release(devenum);
1830
1831     if (ret < 0)
1832         dshow_read_close(avctx);
1833
1834     return ret;
1835 }
1836
1837 /**
1838  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1839  * purges all events that might be in the event queue to stop the trigger
1840  * of event notification.
1841  */
1842 static int dshow_check_event_queue(IMediaEvent *media_event)
1843 {
1844     LONG_PTR p1, p2;
1845     long code;
1846     int ret = 0;
1847
1848     while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1849         if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1850             ret = -1;
1851         IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1852     }
1853
1854     return ret;
1855 }
1856
1857 static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
1858 {
1859     struct dshow_ctx *ctx = s->priv_data;
1860     PacketListEntry *pktl = NULL;
1861
1862     while (!ctx->eof && !pktl) {
1863         WaitForSingleObject(ctx->mutex, INFINITE);
1864         pktl = ctx->pktl;
1865         if (pktl) {
1866             *pkt = pktl->pkt;
1867             ctx->pktl = ctx->pktl->next;
1868             av_free(pktl);
1869             ctx->curbufsize[pkt->stream_index] -= pkt->size;
1870         }
1871         ResetEvent(ctx->event[1]);
1872         ReleaseMutex(ctx->mutex);
1873         if (!pktl) {
1874             if (dshow_check_event_queue(ctx->media_event) < 0) {
1875                 ctx->eof = 1;
1876             } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1877                 return AVERROR(EAGAIN);
1878             } else {
1879                 WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1880             }
1881         }
1882     }
1883
1884     return ctx->eof ? AVERROR(EIO) : pkt->size;
1885 }
1886
1887 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1888 #define DEC AV_OPT_FLAG_DECODING_PARAM
1889 static const AVOption options[] = {
1890     { "video_size", "set video size given a string such as 640x480 or hd720.", OFFSET(requested_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },
1891     { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1892     { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1893     { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1894     { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1895     { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1896     { "audio_buffer_size", "set audio device buffer latency size in milliseconds (default is the device's default)", OFFSET(audio_buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1897     { "list_devices", "list available devices",                      OFFSET(list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1898     { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1899     { "video_device_number", "set video device number for devices with same name (starts at 0)", OFFSET(video_device_number), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1900     { "audio_device_number", "set audio device number for devices with same name (starts at 0)", OFFSET(audio_device_number), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1901     { "video_pin_name", "select video capture pin by name", OFFSET(video_pin_name),AV_OPT_TYPE_STRING, {.str = NULL},  0, 0, AV_OPT_FLAG_ENCODING_PARAM },
1902     { "audio_pin_name", "select audio capture pin by name", OFFSET(audio_pin_name),AV_OPT_TYPE_STRING, {.str = NULL},  0, 0, AV_OPT_FLAG_ENCODING_PARAM },
1903     { "crossbar_video_input_pin_number", "set video input pin number for crossbar device", OFFSET(crossbar_video_input_pin_number), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC },
1904     { "crossbar_audio_input_pin_number", "set audio input pin number for crossbar device", OFFSET(crossbar_audio_input_pin_number), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC },
1905     { "show_video_device_dialog",              "display property dialog for video capture device",                            OFFSET(show_video_device_dialog),              AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1906     { "show_audio_device_dialog",              "display property dialog for audio capture device",                            OFFSET(show_audio_device_dialog),              AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1907     { "show_video_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter on video device", OFFSET(show_video_crossbar_connection_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1908     { "show_audio_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter on audio device", OFFSET(show_audio_crossbar_connection_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1909     { "show_analog_tv_tuner_dialog",           "display property dialog for analog tuner filter",                             OFFSET(show_analog_tv_tuner_dialog),           AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1910     { "show_analog_tv_tuner_audio_dialog",     "display property dialog for analog tuner audio filter",                       OFFSET(show_analog_tv_tuner_audio_dialog),     AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1911     { "audio_device_load", "load audio capture filter device (and properties) from file", OFFSET(audio_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1912     { "audio_device_save", "save audio capture filter device (and properties) to file", OFFSET(audio_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1913     { "video_device_load", "load video capture filter device (and properties) from file", OFFSET(video_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1914     { "video_device_save", "save video capture filter device (and properties) to file", OFFSET(video_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1915     { "use_video_device_timestamps", "use device instead of wallclock timestamps for video frames", OFFSET(use_video_device_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
1916     { NULL },
1917 };
1918
1919 static const AVClass dshow_class = {
1920     .class_name = "dshow indev",
1921     .item_name  = av_default_item_name,
1922     .option     = options,
1923     .version    = LIBAVUTIL_VERSION_INT,
1924     .category   = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
1925 };
1926
1927 const AVInputFormat ff_dshow_demuxer = {
1928     .name           = "dshow",
1929     .long_name      = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1930     .priv_data_size = sizeof(struct dshow_ctx),
1931     .read_header    = dshow_read_header,
1932     .read_packet    = dshow_read_packet,
1933     .read_close     = dshow_read_close,
1934     .get_device_list= dshow_get_device_list,
1935     .flags          = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
1936     .priv_class     = &dshow_class,
1937 };