]> git.sesse.net Git - ffmpeg/blob - libavdevice/dshow.c
dshow: don't add two instances of same device to graphs
[ffmpeg] / 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 "libavformat/internal.h"
27 #include "libavformat/riff.h"
28 #include "avdevice.h"
29 #include "libavcodec/raw.h"
30 #include "objidl.h"
31 #include "shlwapi.h"
32
33
34 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
35 {
36     switch(biCompression) {
37     case BI_BITFIELDS:
38     case BI_RGB:
39         switch(biBitCount) { /* 1-8 are untested */
40             case 1:
41                 return AV_PIX_FMT_MONOWHITE;
42             case 4:
43                 return AV_PIX_FMT_RGB4;
44             case 8:
45                 return AV_PIX_FMT_RGB8;
46             case 16:
47                 return AV_PIX_FMT_RGB555;
48             case 24:
49                 return AV_PIX_FMT_BGR24;
50             case 32:
51                 return AV_PIX_FMT_0RGB32;
52         }
53     }
54     return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression); // all others
55 }
56
57 static int
58 dshow_read_close(AVFormatContext *s)
59 {
60     struct dshow_ctx *ctx = s->priv_data;
61     AVPacketList *pktl;
62
63     if (ctx->control) {
64         IMediaControl_Stop(ctx->control);
65         IMediaControl_Release(ctx->control);
66     }
67
68     if (ctx->media_event)
69         IMediaEvent_Release(ctx->media_event);
70
71     if (ctx->graph) {
72         IEnumFilters *fenum;
73         int r;
74         r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
75         if (r == S_OK) {
76             IBaseFilter *f;
77             IEnumFilters_Reset(fenum);
78             while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
79                 if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
80                     IEnumFilters_Reset(fenum); /* When a filter is removed,
81                                                 * the list must be reset. */
82                 IBaseFilter_Release(f);
83             }
84             IEnumFilters_Release(fenum);
85         }
86         IGraphBuilder_Release(ctx->graph);
87     }
88
89     if (ctx->capture_pin[VideoDevice])
90         libAVPin_Release(ctx->capture_pin[VideoDevice]);
91     if (ctx->capture_pin[AudioDevice])
92         libAVPin_Release(ctx->capture_pin[AudioDevice]);
93     if (ctx->capture_filter[VideoDevice])
94         libAVFilter_Release(ctx->capture_filter[VideoDevice]);
95     if (ctx->capture_filter[AudioDevice])
96         libAVFilter_Release(ctx->capture_filter[AudioDevice]);
97
98     if (ctx->device_pin[VideoDevice])
99         IPin_Release(ctx->device_pin[VideoDevice]);
100     if (ctx->device_pin[AudioDevice])
101         IPin_Release(ctx->device_pin[AudioDevice]);
102     if (ctx->device_filter[VideoDevice])
103         IBaseFilter_Release(ctx->device_filter[VideoDevice]);
104     if (ctx->device_filter[AudioDevice])
105         IBaseFilter_Release(ctx->device_filter[AudioDevice]);
106
107     if (ctx->device_name[0])
108         av_freep(&ctx->device_name[0]);
109     if (ctx->device_name[1])
110         av_freep(&ctx->device_name[1]);
111     if (ctx->device_unique_name[0])
112         av_freep(&ctx->device_unique_name[0]);
113     if (ctx->device_unique_name[1])
114         av_freep(&ctx->device_unique_name[1]);
115
116     if(ctx->mutex)
117         CloseHandle(ctx->mutex);
118     if(ctx->event[0])
119         CloseHandle(ctx->event[0]);
120     if(ctx->event[1])
121         CloseHandle(ctx->event[1]);
122
123     pktl = ctx->pktl;
124     while (pktl) {
125         AVPacketList *next = pktl->next;
126         av_packet_unref(&pktl->pkt);
127         av_free(pktl);
128         pktl = next;
129     }
130
131     CoUninitialize();
132
133     return 0;
134 }
135
136 static char *dup_wchar_to_utf8(wchar_t *w)
137 {
138     char *s = NULL;
139     int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
140     s = av_malloc(l);
141     if (s)
142         WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
143     return s;
144 }
145
146 static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
147 {
148     struct dshow_ctx *ctx = s->priv_data;
149     static const uint8_t dropscore[] = {62, 75, 87, 100};
150     const int ndropscores = FF_ARRAY_ELEMS(dropscore);
151     unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
152     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
153
154     if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
155         av_log(s, AV_LOG_ERROR,
156               "real-time buffer [%s] [%s input] too full or near too full (%d%% of size: %d [rtbufsize parameter])! frame dropped!\n",
157               ctx->device_name[devtype], devtypename, buffer_fullness, s->max_picture_buffer);
158         return 1;
159     }
160
161     return 0;
162 }
163
164 static void
165 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
166 {
167     AVFormatContext *s = priv_data;
168     struct dshow_ctx *ctx = s->priv_data;
169     AVPacketList **ppktl, *pktl_next;
170
171 //    dump_videohdr(s, vdhdr);
172
173     WaitForSingleObject(ctx->mutex, INFINITE);
174
175     if(shall_we_drop(s, index, devtype))
176         goto fail;
177
178     pktl_next = av_mallocz(sizeof(AVPacketList));
179     if(!pktl_next)
180         goto fail;
181
182     if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
183         av_free(pktl_next);
184         goto fail;
185     }
186
187     pktl_next->pkt.stream_index = index;
188     pktl_next->pkt.pts = time;
189     memcpy(pktl_next->pkt.data, buf, buf_size);
190
191     for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
192     *ppktl = pktl_next;
193     ctx->curbufsize[index] += buf_size;
194
195     SetEvent(ctx->event[1]);
196     ReleaseMutex(ctx->mutex);
197
198     return;
199 fail:
200     ReleaseMutex(ctx->mutex);
201     return;
202 }
203
204 /**
205  * Cycle through available devices using the device enumerator devenum,
206  * retrieve the device with type specified by devtype and return the
207  * pointer to the object found in *pfilter.
208  * If pfilter is NULL, list all device names.
209  */
210 static int
211 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
212                     enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype,
213                     IBaseFilter **pfilter, char **device_unique_name)
214 {
215     struct dshow_ctx *ctx = avctx->priv_data;
216     IBaseFilter *device_filter = NULL;
217     IEnumMoniker *classenum = NULL;
218     IMoniker *m = NULL;
219     const char *device_name = ctx->device_name[devtype];
220     int skip = (devtype == VideoDevice) ? ctx->video_device_number
221                                         : ctx->audio_device_number;
222     int r;
223
224     const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
225                                    &CLSID_AudioInputDeviceCategory };
226     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
227     const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
228
229     r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype],
230                                              (IEnumMoniker **) &classenum, 0);
231     if (r != S_OK) {
232         av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n",
233                devtypename);
234         return AVERROR(EIO);
235     }
236
237     while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
238         IPropertyBag *bag = NULL;
239         char *friendly_name = NULL;
240         char *unique_name = NULL;
241         VARIANT var;
242         IBindCtx *bind_ctx = NULL;
243         LPOLESTR olestr = NULL;
244         LPMALLOC co_malloc = NULL;
245         int i;
246
247         r = CoGetMalloc(1, &co_malloc);
248         if (r != S_OK)
249             goto fail1;
250         r = CreateBindCtx(0, &bind_ctx);
251         if (r != S_OK)
252             goto fail1;
253         /* GetDisplayname works for both video and audio, DevicePath doesn't */
254         r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr);
255         if (r != S_OK)
256             goto fail1;
257         unique_name = dup_wchar_to_utf8(olestr);
258         /* replace ':' with '_' since we use : to delineate between sources */
259         for (i = 0; i < strlen(unique_name); i++) {
260             if (unique_name[i] == ':')
261                 unique_name[i] = '_';
262         }
263
264         r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
265         if (r != S_OK)
266             goto fail1;
267
268         var.vt = VT_BSTR;
269         r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
270         if (r != S_OK)
271             goto fail1;
272         friendly_name = dup_wchar_to_utf8(var.bstrVal);
273
274         if (pfilter) {
275             if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name))
276                 goto fail1;
277
278             if (!skip--) {
279                 r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
280                 if (r != S_OK) {
281                     av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name);
282                     goto fail1;
283                 }
284                 *device_unique_name = unique_name;
285                 // success, loop will end now
286             }
287         } else {
288             av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
289             av_log(avctx, AV_LOG_INFO, "    Alternative name \"%s\"\n", unique_name);
290             av_free(unique_name);
291         }
292
293 fail1:
294         if (olestr && co_malloc)
295             IMalloc_Free(co_malloc, olestr);
296         if (bind_ctx)
297             IBindCtx_Release(bind_ctx);
298         av_free(friendly_name);
299         if (bag)
300             IPropertyBag_Release(bag);
301         IMoniker_Release(m);
302     }
303
304     IEnumMoniker_Release(classenum);
305
306     if (pfilter) {
307         if (!device_filter) {
308             av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
309                    devtypename, device_name, sourcetypename);
310             return AVERROR(EIO);
311         }
312         *pfilter = device_filter;
313     }
314
315     return 0;
316 }
317
318 /**
319  * Cycle through available formats using the specified pin,
320  * try to set parameters specified through AVOptions and if successful
321  * return 1 in *pformat_set.
322  * If pformat_set is NULL, list all pin capabilities.
323  */
324 static void
325 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
326                     IPin *pin, int *pformat_set)
327 {
328     struct dshow_ctx *ctx = avctx->priv_data;
329     IAMStreamConfig *config = NULL;
330     AM_MEDIA_TYPE *type = NULL;
331     int format_set = 0;
332     void *caps = NULL;
333     int i, n, size, r;
334
335     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
336         return;
337     if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
338         goto end;
339
340     caps = av_malloc(size);
341     if (!caps)
342         goto end;
343
344     for (i = 0; i < n && !format_set; i++) {
345         r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
346         if (r != S_OK)
347             goto next;
348 #if DSHOWDEBUG
349         ff_print_AM_MEDIA_TYPE(type);
350 #endif
351
352         if (devtype == VideoDevice) {
353             VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
354             BITMAPINFOHEADER *bih;
355             int64_t *fr;
356             const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
357 #if DSHOWDEBUG
358             ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
359 #endif
360             if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
361                 VIDEOINFOHEADER *v = (void *) type->pbFormat;
362                 fr = &v->AvgTimePerFrame;
363                 bih = &v->bmiHeader;
364             } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
365                 VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
366                 fr = &v->AvgTimePerFrame;
367                 bih = &v->bmiHeader;
368             } else {
369                 goto next;
370             }
371             if (!pformat_set) {
372                 enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
373                 if (pix_fmt == AV_PIX_FMT_NONE) {
374                     enum AVCodecID codec_id = av_codec_get_id(tags, bih->biCompression);
375                     AVCodec *codec = avcodec_find_decoder(codec_id);
376                     if (codec_id == AV_CODEC_ID_NONE || !codec) {
377                         av_log(avctx, AV_LOG_INFO, "  unknown compression type 0x%X", (int) bih->biCompression);
378                     } else {
379                         av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
380                     }
381                 } else {
382                     av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
383                 }
384                 av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
385                        vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
386                        1e7 / vcaps->MaxFrameInterval,
387                        vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
388                        1e7 / vcaps->MinFrameInterval);
389                 continue;
390             }
391             if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
392                 if (ctx->video_codec_id != av_codec_get_id(tags, bih->biCompression))
393                     goto next;
394             }
395             if (ctx->pixel_format != AV_PIX_FMT_NONE &&
396                 ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
397                 goto next;
398             }
399             if (ctx->framerate) {
400                 int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
401                                             /  ctx->requested_framerate.num;
402                 if (framerate > vcaps->MaxFrameInterval ||
403                     framerate < vcaps->MinFrameInterval)
404                     goto next;
405                 *fr = framerate;
406             }
407             if (ctx->requested_width && ctx->requested_height) {
408                 if (ctx->requested_width  > vcaps->MaxOutputSize.cx ||
409                     ctx->requested_width  < vcaps->MinOutputSize.cx ||
410                     ctx->requested_height > vcaps->MaxOutputSize.cy ||
411                     ctx->requested_height < vcaps->MinOutputSize.cy)
412                     goto next;
413                 bih->biWidth  = ctx->requested_width;
414                 bih->biHeight = ctx->requested_height;
415             }
416         } else {
417             AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
418             WAVEFORMATEX *fx;
419 #if DSHOWDEBUG
420             ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
421 #endif
422             if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
423                 fx = (void *) type->pbFormat;
424             } else {
425                 goto next;
426             }
427             if (!pformat_set) {
428                 av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
429                        acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
430                        acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
431                 continue;
432             }
433             if (ctx->sample_rate) {
434                 if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
435                     ctx->sample_rate < acaps->MinimumSampleFrequency)
436                     goto next;
437                 fx->nSamplesPerSec = ctx->sample_rate;
438             }
439             if (ctx->sample_size) {
440                 if (ctx->sample_size > acaps->MaximumBitsPerSample ||
441                     ctx->sample_size < acaps->MinimumBitsPerSample)
442                     goto next;
443                 fx->wBitsPerSample = ctx->sample_size;
444             }
445             if (ctx->channels) {
446                 if (ctx->channels > acaps->MaximumChannels ||
447                     ctx->channels < acaps->MinimumChannels)
448                     goto next;
449                 fx->nChannels = ctx->channels;
450             }
451         }
452         if (IAMStreamConfig_SetFormat(config, type) != S_OK)
453             goto next;
454         format_set = 1;
455 next:
456         if (type->pbFormat)
457             CoTaskMemFree(type->pbFormat);
458         CoTaskMemFree(type);
459     }
460 end:
461     IAMStreamConfig_Release(config);
462     av_free(caps);
463     if (pformat_set)
464         *pformat_set = format_set;
465 }
466
467 /**
468  * Set audio device buffer size in milliseconds (which can directly impact
469  * latency, depending on the device).
470  */
471 static int
472 dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
473 {
474     struct dshow_ctx *ctx = avctx->priv_data;
475     IAMBufferNegotiation *buffer_negotiation = NULL;
476     ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
477     IAMStreamConfig *config = NULL;
478     AM_MEDIA_TYPE *type = NULL;
479     int ret = AVERROR(EIO);
480
481     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
482         goto end;
483     if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
484         goto end;
485     if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
486         goto end;
487
488     props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
489                    * ctx->audio_buffer_size / 1000;
490
491     if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
492         goto end;
493     if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
494         goto end;
495
496     ret = 0;
497
498 end:
499     if (buffer_negotiation)
500         IAMBufferNegotiation_Release(buffer_negotiation);
501     if (type) {
502         if (type->pbFormat)
503             CoTaskMemFree(type->pbFormat);
504         CoTaskMemFree(type);
505     }
506     if (config)
507         IAMStreamConfig_Release(config);
508
509     return ret;
510 }
511
512 /**
513  * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
514  */
515 void
516 dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx) {
517     ISpecifyPropertyPages *property_pages = NULL;
518     IUnknown *device_filter_iunknown = NULL;
519     HRESULT hr;
520     FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
521     CAUUID ca_guid = {0};
522
523     hr  = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
524     if (hr != S_OK) {
525         av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
526         goto end;
527     }
528     hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
529     if (hr != S_OK) {
530         goto fail;
531     }
532     hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
533     if (hr != S_OK) {
534         goto fail;
535     }
536     hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
537     if (hr != S_OK) {
538         goto fail;
539     }
540     hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
541         ca_guid.pElems, 0, 0, NULL);
542     if (hr != S_OK) {
543         goto fail;
544     }
545     goto end;
546 fail:
547     av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
548 end:
549     if (property_pages)
550         ISpecifyPropertyPages_Release(property_pages);
551     if (device_filter_iunknown)
552         IUnknown_Release(device_filter_iunknown);
553     if (filter_info.pGraph)
554         IFilterGraph_Release(filter_info.pGraph);
555     if (ca_guid.pElems)
556         CoTaskMemFree(ca_guid.pElems);
557 }
558
559 /**
560  * Cycle through available pins using the device_filter device, of type
561  * devtype, retrieve the first output pin and return the pointer to the
562  * object found in *ppin.
563  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
564  */
565 static int
566 dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
567                  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
568 {
569     struct dshow_ctx *ctx = avctx->priv_data;
570     IEnumPins *pins = 0;
571     IPin *device_pin = NULL;
572     IPin *pin;
573     int r;
574
575     const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
576     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
577     const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
578
579     int set_format = (devtype == VideoDevice && (ctx->framerate ||
580                                                 (ctx->requested_width && ctx->requested_height) ||
581                                                  ctx->pixel_format != AV_PIX_FMT_NONE ||
582                                                  ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
583                   || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
584     int format_set = 0;
585     int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
586
587     if (should_show_properties)
588         dshow_show_filter_properties(device_filter, avctx);
589
590     r = IBaseFilter_EnumPins(device_filter, &pins);
591     if (r != S_OK) {
592         av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
593         return AVERROR(EIO);
594     }
595
596     if (!ppin) {
597         av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
598                devtypename, sourcetypename);
599     }
600
601     while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
602         IKsPropertySet *p = NULL;
603         IEnumMediaTypes *types = NULL;
604         PIN_INFO info = {0};
605         AM_MEDIA_TYPE *type;
606         GUID category;
607         DWORD r2;
608         char *name_buf = NULL;
609         wchar_t *pin_id = NULL;
610         char *pin_buf = NULL;
611         char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
612
613         IPin_QueryPinInfo(pin, &info);
614         IBaseFilter_Release(info.pFilter);
615
616         if (info.dir != PINDIR_OUTPUT)
617             goto next;
618         if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
619             goto next;
620         if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
621                                NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
622             goto next;
623         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
624             goto next;
625         name_buf = dup_wchar_to_utf8(info.achName);
626
627         r = IPin_QueryId(pin, &pin_id);
628         if (r != S_OK) {
629             av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
630             return AVERROR(EIO);
631         }
632         pin_buf = dup_wchar_to_utf8(pin_id);
633
634         if (!ppin) {
635             av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
636             dshow_cycle_formats(avctx, devtype, pin, NULL);
637             goto next;
638         }
639
640         if (desired_pin_name) {
641             if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
642                 av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
643                     name_buf, pin_buf, desired_pin_name);
644                 goto next;
645             }
646         }
647
648         if (set_format) {
649             dshow_cycle_formats(avctx, devtype, pin, &format_set);
650             if (!format_set) {
651                 goto next;
652             }
653         }
654         if (devtype == AudioDevice && ctx->audio_buffer_size) {
655             if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
656                 av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
657             }
658         }
659
660         if (IPin_EnumMediaTypes(pin, &types) != S_OK)
661             goto next;
662
663         IEnumMediaTypes_Reset(types);
664         /* in case format_set was not called, just verify the majortype */
665         while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
666             if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
667                 device_pin = pin;
668                 av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
669                 goto next;
670             }
671             CoTaskMemFree(type);
672         }
673
674 next:
675         if (types)
676             IEnumMediaTypes_Release(types);
677         if (p)
678             IKsPropertySet_Release(p);
679         if (device_pin != pin)
680             IPin_Release(pin);
681         av_free(name_buf);
682         av_free(pin_buf);
683         if (pin_id)
684             CoTaskMemFree(pin_id);
685     }
686
687     IEnumPins_Release(pins);
688
689     if (ppin) {
690         if (set_format && !format_set) {
691             av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
692             return AVERROR(EIO);
693         }
694         if (!device_pin) {
695             av_log(avctx, AV_LOG_ERROR,
696                 "Could not find output pin from %s capture device.\n", devtypename);
697             return AVERROR(EIO);
698         }
699         *ppin = device_pin;
700     }
701
702     return 0;
703 }
704
705 /**
706  * List options for device with type devtype, source filter type sourcetype
707  *
708  * @param devenum device enumerator used for accessing the device
709  */
710 static int
711 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
712                           enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
713 {
714     struct dshow_ctx *ctx = avctx->priv_data;
715     IBaseFilter *device_filter = NULL;
716     char *device_unique_name = NULL;
717     int r;
718
719     if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name)) < 0)
720         return r;
721     ctx->device_filter[devtype] = device_filter;
722     if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
723         return r;
724     av_freep(&device_unique_name);
725     return 0;
726 }
727
728 static int
729 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
730                   enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
731 {
732     struct dshow_ctx *ctx = avctx->priv_data;
733     IBaseFilter *device_filter = NULL;
734     char *device_filter_unique_name = NULL;
735     IGraphBuilder *graph = ctx->graph;
736     IPin *device_pin = NULL;
737     libAVPin *capture_pin = NULL;
738     libAVFilter *capture_filter = NULL;
739     ICaptureGraphBuilder2 *graph_builder2 = NULL;
740     int ret = AVERROR(EIO);
741     int r;
742     IStream *ifile_stream = NULL;
743     IStream *ofile_stream = NULL;
744     IPersistStream *pers_stream = NULL;
745     enum dshowDeviceType otherDevType = (devtype == VideoDevice) ? AudioDevice : VideoDevice;
746
747     const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
748
749
750     if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
751             ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
752         HRESULT hr;
753         char *filename = NULL;
754
755         if (sourcetype == AudioSourceDevice)
756             filename = ctx->audio_filter_load_file;
757         else
758             filename = ctx->video_filter_load_file;
759
760         hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
761         if (S_OK != hr) {
762             av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
763             goto error;
764         }
765
766         hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
767         if (hr != S_OK) {
768             av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
769             goto error;
770         }
771
772         if (sourcetype == AudioSourceDevice)
773             av_log(avctx, AV_LOG_INFO, "Audio-");
774         else
775             av_log(avctx, AV_LOG_INFO, "Video-");
776         av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
777     } else {
778
779         if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_filter_unique_name)) < 0) {
780             ret = r;
781             goto error;
782         }
783     }
784         if (ctx->device_filter[otherDevType]) {
785         // avoid adding add two instances of the same device to the graph, one for video, one for audio
786         // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK)
787         if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) {
788           av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name);
789           IBaseFilter_Release(device_filter);
790           device_filter = ctx->device_filter[otherDevType];
791           IBaseFilter_AddRef(ctx->device_filter[otherDevType]);
792         } else {
793             av_log(avctx, AV_LOG_DEBUG, "not reusing previous graph capture filter %s != %s\n", device_filter_unique_name, ctx->device_unique_name[otherDevType]);
794         }
795     }
796
797     ctx->device_filter [devtype] = device_filter;
798     ctx->device_unique_name [devtype] = device_filter_unique_name;
799
800     r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
801     if (r != S_OK) {
802         av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
803         goto error;
804     }
805
806     if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
807         ret = r;
808         goto error;
809     }
810
811     ctx->device_pin[devtype] = device_pin;
812
813     capture_filter = libAVFilter_Create(avctx, callback, devtype);
814     if (!capture_filter) {
815         av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
816         goto error;
817     }
818     ctx->capture_filter[devtype] = capture_filter;
819
820     if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
821             ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
822
823         HRESULT hr;
824         char *filename = NULL;
825
826         if (sourcetype == AudioSourceDevice)
827             filename = ctx->audio_filter_save_file;
828         else
829             filename = ctx->video_filter_save_file;
830
831         hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
832         if (S_OK != hr) {
833             av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
834             goto error;
835         }
836
837         hr  = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
838         if (hr != S_OK) {
839             av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
840             goto error;
841         }
842
843         hr = OleSaveToStream(pers_stream, ofile_stream);
844         if (hr != S_OK) {
845             av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
846             goto error;
847         }
848
849         hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
850         if (S_OK != hr) {
851             av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
852             goto error;
853         }
854
855         if (sourcetype == AudioSourceDevice)
856             av_log(avctx, AV_LOG_INFO, "Audio-");
857         else
858             av_log(avctx, AV_LOG_INFO, "Video-");
859         av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
860     }
861
862     r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
863                                 filter_name[devtype]);
864     if (r != S_OK) {
865         av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
866         goto error;
867     }
868
869     libAVPin_AddRef(capture_filter->pin);
870     capture_pin = capture_filter->pin;
871     ctx->capture_pin[devtype] = capture_pin;
872
873     r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
874                          &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
875     if (r != S_OK) {
876         av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
877         goto error;
878     }
879     ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
880     if (r != S_OK) {
881         av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
882         goto error;
883     }
884
885     r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
886         (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
887
888     if (r != S_OK) {
889         av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
890         goto error;
891     }
892
893     r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
894
895     if (r != S_OK) {
896         av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
897         goto error;
898     }
899
900     ret = 0;
901
902 error:
903     if (graph_builder2 != NULL)
904         ICaptureGraphBuilder2_Release(graph_builder2);
905
906     if (pers_stream)
907         IPersistStream_Release(pers_stream);
908
909     if (ifile_stream)
910         IStream_Release(ifile_stream);
911
912     if (ofile_stream)
913         IStream_Release(ofile_stream);
914
915     return ret;
916 }
917
918 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
919 {
920     switch (sample_fmt) {
921     case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
922     case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
923     case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
924     default:                return AV_CODEC_ID_NONE; /* Should never happen. */
925     }
926 }
927
928 static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
929 {
930     switch (bits) {
931     case 8:  return AV_SAMPLE_FMT_U8;
932     case 16: return AV_SAMPLE_FMT_S16;
933     case 32: return AV_SAMPLE_FMT_S32;
934     default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
935     }
936 }
937
938 static int
939 dshow_add_device(AVFormatContext *avctx,
940                  enum dshowDeviceType devtype)
941 {
942     struct dshow_ctx *ctx = avctx->priv_data;
943     AM_MEDIA_TYPE type;
944     AVCodecParameters *par;
945     AVStream *st;
946     int ret = AVERROR(EIO);
947
948     st = avformat_new_stream(avctx, NULL);
949     if (!st) {
950         ret = AVERROR(ENOMEM);
951         goto error;
952     }
953     st->id = devtype;
954
955     ctx->capture_filter[devtype]->stream_index = st->index;
956
957     libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
958
959     par = st->codecpar;
960     if (devtype == VideoDevice) {
961         BITMAPINFOHEADER *bih = NULL;
962         AVRational time_base;
963
964         if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
965             VIDEOINFOHEADER *v = (void *) type.pbFormat;
966             time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
967             bih = &v->bmiHeader;
968         } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
969             VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
970             time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
971             bih = &v->bmiHeader;
972         }
973         if (!bih) {
974             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
975             goto error;
976         }
977
978         st->avg_frame_rate = av_inv_q(time_base);
979         st->r_frame_rate = av_inv_q(time_base);
980
981         par->codec_type = AVMEDIA_TYPE_VIDEO;
982         par->width      = bih->biWidth;
983         par->height     = bih->biHeight;
984         par->codec_tag  = bih->biCompression;
985         par->format     = dshow_pixfmt(bih->biCompression, bih->biBitCount);
986         if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
987             av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
988             par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
989         }
990         if (par->format == AV_PIX_FMT_NONE) {
991             const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
992             par->codec_id = av_codec_get_id(tags, bih->biCompression);
993             if (par->codec_id == AV_CODEC_ID_NONE) {
994                 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
995                                  "Please report type 0x%X.\n", (int) bih->biCompression);
996                 return AVERROR_PATCHWELCOME;
997             }
998             par->bits_per_coded_sample = bih->biBitCount;
999         } else {
1000             par->codec_id = AV_CODEC_ID_RAWVIDEO;
1001             if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
1002                 par->bits_per_coded_sample = bih->biBitCount;
1003                 par->extradata = av_malloc(9 + AV_INPUT_BUFFER_PADDING_SIZE);
1004                 if (par->extradata) {
1005                     par->extradata_size = 9;
1006                     memcpy(par->extradata, "BottomUp", 9);
1007                 }
1008             }
1009         }
1010     } else {
1011         WAVEFORMATEX *fx = NULL;
1012
1013         if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
1014             fx = (void *) type.pbFormat;
1015         }
1016         if (!fx) {
1017             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1018             goto error;
1019         }
1020
1021         par->codec_type  = AVMEDIA_TYPE_AUDIO;
1022         par->format      = sample_fmt_bits_per_sample(fx->wBitsPerSample);
1023         par->codec_id    = waveform_codec_id(par->format);
1024         par->sample_rate = fx->nSamplesPerSec;
1025         par->channels    = fx->nChannels;
1026     }
1027
1028     avpriv_set_pts_info(st, 64, 1, 10000000);
1029
1030     ret = 0;
1031
1032 error:
1033     return ret;
1034 }
1035
1036 static int parse_device_name(AVFormatContext *avctx)
1037 {
1038     struct dshow_ctx *ctx = avctx->priv_data;
1039     char **device_name = ctx->device_name;
1040     char *name = av_strdup(avctx->filename);
1041     char *tmp = name;
1042     int ret = 1;
1043     char *type;
1044
1045     while ((type = strtok(tmp, "="))) {
1046         char *token = strtok(NULL, ":");
1047         tmp = NULL;
1048
1049         if        (!strcmp(type, "video")) {
1050             device_name[0] = token;
1051         } else if (!strcmp(type, "audio")) {
1052             device_name[1] = token;
1053         } else {
1054             device_name[0] = NULL;
1055             device_name[1] = NULL;
1056             break;
1057         }
1058     }
1059
1060     if (!device_name[0] && !device_name[1]) {
1061         ret = 0;
1062     } else {
1063         if (device_name[0])
1064             device_name[0] = av_strdup(device_name[0]);
1065         if (device_name[1])
1066             device_name[1] = av_strdup(device_name[1]);
1067     }
1068
1069     av_free(name);
1070     return ret;
1071 }
1072
1073 static int dshow_read_header(AVFormatContext *avctx)
1074 {
1075     struct dshow_ctx *ctx = avctx->priv_data;
1076     IGraphBuilder *graph = NULL;
1077     ICreateDevEnum *devenum = NULL;
1078     IMediaControl *control = NULL;
1079     IMediaEvent *media_event = NULL;
1080     HANDLE media_event_handle;
1081     HANDLE proc;
1082     int ret = AVERROR(EIO);
1083     int r;
1084
1085     CoInitialize(0);
1086
1087     if (!ctx->list_devices && !parse_device_name(avctx)) {
1088         av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
1089         goto error;
1090     }
1091
1092     ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
1093                                                 : AV_CODEC_ID_RAWVIDEO;
1094     if (ctx->pixel_format != AV_PIX_FMT_NONE) {
1095         if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
1096             av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
1097                               "video codec is not set or set to rawvideo\n");
1098             ret = AVERROR(EINVAL);
1099             goto error;
1100         }
1101     }
1102     if (ctx->framerate) {
1103         r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
1104         if (r < 0) {
1105             av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
1106             goto error;
1107         }
1108     }
1109
1110     r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1111                          &IID_IGraphBuilder, (void **) &graph);
1112     if (r != S_OK) {
1113         av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
1114         goto error;
1115     }
1116     ctx->graph = graph;
1117
1118     r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
1119                          &IID_ICreateDevEnum, (void **) &devenum);
1120     if (r != S_OK) {
1121         av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
1122         goto error;
1123     }
1124
1125     if (ctx->list_devices) {
1126         av_log(avctx, AV_LOG_INFO, "DirectShow video devices (some may be both video and audio devices)\n");
1127         dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL, NULL);
1128         av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
1129         dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL, NULL);
1130         ret = AVERROR_EXIT;
1131         goto error;
1132     }
1133     if (ctx->list_options) {
1134         if (ctx->device_name[VideoDevice])
1135             if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
1136                 ret = r;
1137                 goto error;
1138             }
1139         if (ctx->device_name[AudioDevice]) {
1140             if (dshow_list_device_options(avctx, devenum, AudioDevice, AudioSourceDevice)) {
1141                 /* show audio options from combined video+audio sources as fallback */
1142                 if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
1143                     ret = r;
1144                     goto error;
1145                 }
1146             }
1147         }
1148     }
1149     if (ctx->device_name[VideoDevice]) {
1150         if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
1151             (r = dshow_add_device(avctx, VideoDevice)) < 0) {
1152             ret = r;
1153             goto error;
1154         }
1155     }
1156     if (ctx->device_name[AudioDevice]) {
1157         if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
1158             (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1159             av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
1160             /* see if there's a video source with an audio pin with the given audio name */
1161             if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
1162                 (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1163                 ret = r;
1164                 goto error;
1165             }
1166         }
1167     }
1168     if (ctx->list_options) {
1169         /* allow it to list crossbar options in dshow_open_device */
1170         ret = AVERROR_EXIT;
1171         goto error;
1172     }
1173     ctx->curbufsize[0] = 0;
1174     ctx->curbufsize[1] = 0;
1175     ctx->mutex = CreateMutex(NULL, 0, NULL);
1176     if (!ctx->mutex) {
1177         av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
1178         goto error;
1179     }
1180     ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
1181     if (!ctx->event[1]) {
1182         av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
1183         goto error;
1184     }
1185
1186     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
1187     if (r != S_OK) {
1188         av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
1189         goto error;
1190     }
1191     ctx->control = control;
1192
1193     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
1194     if (r != S_OK) {
1195         av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
1196         goto error;
1197     }
1198     ctx->media_event = media_event;
1199
1200     r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
1201     if (r != S_OK) {
1202         av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
1203         goto error;
1204     }
1205     proc = GetCurrentProcess();
1206     r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
1207                         0, 0, DUPLICATE_SAME_ACCESS);
1208     if (!r) {
1209         av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
1210         goto error;
1211     }
1212
1213     r = IMediaControl_Run(control);
1214     if (r == S_FALSE) {
1215         OAFilterState pfs;
1216         r = IMediaControl_GetState(control, 0, &pfs);
1217     }
1218     if (r != S_OK) {
1219         av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
1220         goto error;
1221     }
1222
1223     ret = 0;
1224
1225 error:
1226
1227     if (devenum)
1228         ICreateDevEnum_Release(devenum);
1229
1230     if (ret < 0)
1231         dshow_read_close(avctx);
1232
1233     return ret;
1234 }
1235
1236 /**
1237  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1238  * purges all events that might be in the event queue to stop the trigger
1239  * of event notification.
1240  */
1241 static int dshow_check_event_queue(IMediaEvent *media_event)
1242 {
1243     LONG_PTR p1, p2;
1244     long code;
1245     int ret = 0;
1246
1247     while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1248         if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1249             ret = -1;
1250         IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1251     }
1252
1253     return ret;
1254 }
1255
1256 static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
1257 {
1258     struct dshow_ctx *ctx = s->priv_data;
1259     AVPacketList *pktl = NULL;
1260
1261     while (!ctx->eof && !pktl) {
1262         WaitForSingleObject(ctx->mutex, INFINITE);
1263         pktl = ctx->pktl;
1264         if (pktl) {
1265             *pkt = pktl->pkt;
1266             ctx->pktl = ctx->pktl->next;
1267             av_free(pktl);
1268             ctx->curbufsize[pkt->stream_index] -= pkt->size;
1269         }
1270         ResetEvent(ctx->event[1]);
1271         ReleaseMutex(ctx->mutex);
1272         if (!pktl) {
1273             if (dshow_check_event_queue(ctx->media_event) < 0) {
1274                 ctx->eof = 1;
1275             } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1276                 return AVERROR(EAGAIN);
1277             } else {
1278                 WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1279             }
1280         }
1281     }
1282
1283     return ctx->eof ? AVERROR(EIO) : pkt->size;
1284 }
1285
1286 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1287 #define DEC AV_OPT_FLAG_DECODING_PARAM
1288 static const AVOption options[] = {
1289     { "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 },
1290     { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1291     { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1292     { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1293     { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1294     { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1295     { "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 },
1296     { "list_devices", "list available devices",                      OFFSET(list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1297     { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1298     { "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 },
1299     { "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 },
1300     { "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 },
1301     { "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 },
1302     { "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 },
1303     { "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 },
1304     { "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 },
1305     { "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 },
1306     { "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 },
1307     { "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 },
1308     { "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 },
1309     { "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 },
1310     { "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 },
1311     { "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 },
1312     { "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 },
1313     { "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 },
1314     { NULL },
1315 };
1316
1317 static const AVClass dshow_class = {
1318     .class_name = "dshow indev",
1319     .item_name  = av_default_item_name,
1320     .option     = options,
1321     .version    = LIBAVUTIL_VERSION_INT,
1322     .category   = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
1323 };
1324
1325 AVInputFormat ff_dshow_demuxer = {
1326     .name           = "dshow",
1327     .long_name      = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1328     .priv_data_size = sizeof(struct dshow_ctx),
1329     .read_header    = dshow_read_header,
1330     .read_packet    = dshow_read_packet,
1331     .read_close     = dshow_read_close,
1332     .flags          = AVFMT_NOFILE,
1333     .priv_class     = &dshow_class,
1334 };