]> git.sesse.net Git - ffmpeg/blob - libavdevice/dshow.c
dshow: save opened device reference so it may be properly closed
[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 "libavutil/parseutils.h"
23 #include "libavutil/opt.h"
24
25 #include "avdevice.h"
26 #include "dshow.h"
27
28 struct dshow_ctx {
29     const AVClass *class;
30
31     IGraphBuilder *graph;
32
33     char *device_name[2];
34     int video_device_number;
35     int audio_device_number;
36
37     int   list_options;
38     int   list_devices;
39
40     IBaseFilter *device_filter[2];
41     IPin        *device_pin[2];
42     libAVFilter *capture_filter[2];
43     libAVPin    *capture_pin[2];
44
45     HANDLE mutex;
46     HANDLE event;
47     AVPacketList *pktl;
48
49     unsigned int curbufsize;
50     unsigned int video_frame_num;
51
52     IMediaControl *control;
53
54     char *video_size;
55     char *framerate;
56
57     int requested_width;
58     int requested_height;
59     AVRational requested_framerate;
60
61     int sample_rate;
62     int sample_size;
63     int channels;
64 };
65
66 static enum PixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
67 {
68     switch(biCompression) {
69     case MKTAG('U', 'Y', 'V', 'Y'):
70         return PIX_FMT_UYVY422;
71     case MKTAG('Y', 'U', 'Y', '2'):
72         return PIX_FMT_YUYV422;
73     case MKTAG('I', '4', '2', '0'):
74         return PIX_FMT_YUV420P;
75     case BI_RGB:
76         switch(biBitCount) { /* 1-8 are untested */
77             case 1:
78                 return PIX_FMT_MONOWHITE;
79             case 4:
80                 return PIX_FMT_RGB4;
81             case 8:
82                 return PIX_FMT_RGB8;
83             case 16:
84                 return PIX_FMT_RGB555;
85             case 24:
86                 return PIX_FMT_BGR24;
87             case 32:
88                 return PIX_FMT_RGB32;
89         }
90     }
91     return PIX_FMT_NONE;
92 }
93
94 static enum CodecID dshow_codecid(DWORD biCompression)
95 {
96     switch(biCompression) {
97     case MKTAG('d', 'v', 's', 'd'):
98         return CODEC_ID_DVVIDEO;
99     case MKTAG('M', 'J', 'P', 'G'):
100     case MKTAG('m', 'j', 'p', 'g'):
101         return CODEC_ID_MJPEG;
102     }
103     return CODEC_ID_NONE;
104 }
105
106 static int
107 dshow_read_close(AVFormatContext *s)
108 {
109     struct dshow_ctx *ctx = s->priv_data;
110     AVPacketList *pktl;
111
112     if (ctx->control) {
113         IMediaControl_Stop(ctx->control);
114         IMediaControl_Release(ctx->control);
115     }
116
117     if (ctx->graph) {
118         IEnumFilters *fenum;
119         int r;
120         r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
121         if (r == S_OK) {
122             IBaseFilter *f;
123             IEnumFilters_Reset(fenum);
124             while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
125                 if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
126                     IEnumFilters_Reset(fenum); /* When a filter is removed,
127                                                 * the list must be reset. */
128                 IBaseFilter_Release(f);
129             }
130             IEnumFilters_Release(fenum);
131         }
132         IGraphBuilder_Release(ctx->graph);
133     }
134
135     if (ctx->capture_pin[VideoDevice])
136         libAVPin_Release(ctx->capture_pin[VideoDevice]);
137     if (ctx->capture_pin[AudioDevice])
138         libAVPin_Release(ctx->capture_pin[AudioDevice]);
139     if (ctx->capture_filter[VideoDevice])
140         libAVFilter_Release(ctx->capture_filter[VideoDevice]);
141     if (ctx->capture_filter[AudioDevice])
142         libAVFilter_Release(ctx->capture_filter[AudioDevice]);
143
144     if (ctx->device_pin[VideoDevice])
145         IPin_Release(ctx->device_pin[VideoDevice]);
146     if (ctx->device_pin[AudioDevice])
147         IPin_Release(ctx->device_pin[AudioDevice]);
148     if (ctx->device_filter[VideoDevice])
149         IBaseFilter_Release(ctx->device_filter[VideoDevice]);
150     if (ctx->device_filter[AudioDevice])
151         IBaseFilter_Release(ctx->device_filter[AudioDevice]);
152
153     if (ctx->device_name[0])
154         av_free(ctx->device_name[0]);
155     if (ctx->device_name[1])
156         av_free(ctx->device_name[1]);
157
158     if(ctx->mutex)
159         CloseHandle(ctx->mutex);
160     if(ctx->event)
161         CloseHandle(ctx->event);
162
163     pktl = ctx->pktl;
164     while (pktl) {
165         AVPacketList *next = pktl->next;
166         av_destruct_packet(&pktl->pkt);
167         av_free(pktl);
168         pktl = next;
169     }
170
171     return 0;
172 }
173
174 static char *dup_wchar_to_utf8(wchar_t *w)
175 {
176     char *s = NULL;
177     int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
178     s = av_malloc(l);
179     if (s)
180         WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
181     return s;
182 }
183
184 static int shall_we_drop(AVFormatContext *s)
185 {
186     struct dshow_ctx *ctx = s->priv_data;
187     const uint8_t dropscore[] = {62, 75, 87, 100};
188     const int ndropscores = FF_ARRAY_ELEMS(dropscore);
189     unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer;
190
191     if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
192         av_log(s, AV_LOG_ERROR,
193               "real-time buffer %d%% full! frame dropped!\n", buffer_fullness);
194         return 1;
195     }
196
197     return 0;
198 }
199
200 static void
201 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
202 {
203     AVFormatContext *s = priv_data;
204     struct dshow_ctx *ctx = s->priv_data;
205     AVPacketList **ppktl, *pktl_next;
206
207 //    dump_videohdr(s, vdhdr);
208
209     if(shall_we_drop(s))
210         return;
211
212     WaitForSingleObject(ctx->mutex, INFINITE);
213
214     pktl_next = av_mallocz(sizeof(AVPacketList));
215     if(!pktl_next)
216         goto fail;
217
218     if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
219         av_free(pktl_next);
220         goto fail;
221     }
222
223     pktl_next->pkt.stream_index = index;
224     pktl_next->pkt.pts = time;
225     memcpy(pktl_next->pkt.data, buf, buf_size);
226
227     for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
228     *ppktl = pktl_next;
229
230     ctx->curbufsize += buf_size;
231
232     SetEvent(ctx->event);
233     ReleaseMutex(ctx->mutex);
234
235     return;
236 fail:
237     ReleaseMutex(ctx->mutex);
238     return;
239 }
240
241 /**
242  * Cycle through available devices using the device enumerator devenum,
243  * retrieve the device with type specified by devtype and return the
244  * pointer to the object found in *pfilter.
245  * If pfilter is NULL, list all device names.
246  */
247 static int
248 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
249                     enum dshowDeviceType devtype, IBaseFilter **pfilter)
250 {
251     struct dshow_ctx *ctx = avctx->priv_data;
252     IBaseFilter *device_filter = NULL;
253     IEnumMoniker *classenum = NULL;
254     IMoniker *m = NULL;
255     const char *device_name = ctx->device_name[devtype];
256     int skip = (devtype == VideoDevice) ? ctx->video_device_number
257                                         : ctx->audio_device_number;
258     int r;
259
260     const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
261                                    &CLSID_AudioInputDeviceCategory };
262     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
263
264     r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
265                                              (IEnumMoniker **) &classenum, 0);
266     if (r != S_OK) {
267         av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
268                devtypename);
269         return AVERROR(EIO);
270     }
271
272     while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
273         IPropertyBag *bag = NULL;
274         char *buf = NULL;
275         VARIANT var;
276
277         r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
278         if (r != S_OK)
279             goto fail1;
280
281         var.vt = VT_BSTR;
282         r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
283         if (r != S_OK)
284             goto fail1;
285
286         buf = dup_wchar_to_utf8(var.bstrVal);
287
288         if (pfilter) {
289             if (strcmp(device_name, buf))
290                 goto fail1;
291
292             if (!skip--)
293                 IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
294         } else {
295             av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
296         }
297
298 fail1:
299         if (buf)
300             av_free(buf);
301         if (bag)
302             IPropertyBag_Release(bag);
303         IMoniker_Release(m);
304     }
305
306     IEnumMoniker_Release(classenum);
307
308     if (pfilter) {
309         if (!device_filter) {
310             av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
311                    devtypename);
312             return AVERROR(EIO);
313         }
314         *pfilter = device_filter;
315     }
316
317     return 0;
318 }
319
320 /**
321  * Cycle through available formats using the specified pin,
322  * try to set parameters specified through AVOptions and if successful
323  * return 1 in *pformat_set.
324  * If pformat_set is NULL, list all pin capabilities.
325  */
326 static void
327 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
328                     IPin *pin, int *pformat_set)
329 {
330     struct dshow_ctx *ctx = avctx->priv_data;
331     IAMStreamConfig *config = NULL;
332     AM_MEDIA_TYPE *type = NULL;
333     int format_set = 0;
334     void *caps = NULL;
335     int i, n, size;
336
337     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
338         return;
339     if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
340         goto end;
341
342     caps = av_malloc(size);
343     if (!caps)
344         goto end;
345
346     for (i = 0; i < n && !format_set; i++) {
347         IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
348
349 #if DSHOWDEBUG
350         ff_print_AM_MEDIA_TYPE(type);
351 #endif
352
353         if (devtype == VideoDevice) {
354             VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
355             BITMAPINFOHEADER *bih;
356             int64_t *fr;
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                 av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
373                        vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
374                        1e7 / vcaps->MinFrameInterval,
375                        vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
376                        1e7 / vcaps->MaxFrameInterval);
377                 continue;
378             }
379             if (ctx->framerate) {
380                 int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
381                                             /  ctx->requested_framerate.num;
382                 if (framerate > vcaps->MaxFrameInterval ||
383                     framerate < vcaps->MinFrameInterval)
384                     goto next;
385                 *fr = framerate;
386             }
387             if (ctx->video_size) {
388                 if (ctx->requested_width  > vcaps->MaxOutputSize.cx ||
389                     ctx->requested_width  < vcaps->MinOutputSize.cx ||
390                     ctx->requested_height > vcaps->MaxOutputSize.cy ||
391                     ctx->requested_height < vcaps->MinOutputSize.cy)
392                     goto next;
393                 bih->biWidth  = ctx->requested_width;
394                 bih->biHeight = ctx->requested_height;
395             }
396         } else {
397             AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
398             WAVEFORMATEX *fx;
399 #if DSHOWDEBUG
400             ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
401 #endif
402             if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
403                 fx = (void *) type->pbFormat;
404             } else {
405                 goto next;
406             }
407             if (!pformat_set) {
408                 av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
409                        acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
410                        acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
411                 continue;
412             }
413             if (ctx->sample_rate) {
414                 if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
415                     ctx->sample_rate < acaps->MinimumSampleFrequency)
416                     goto next;
417                 fx->nSamplesPerSec = ctx->sample_rate;
418             }
419             if (ctx->sample_size) {
420                 if (ctx->sample_size > acaps->MaximumBitsPerSample ||
421                     ctx->sample_size < acaps->MinimumBitsPerSample)
422                     goto next;
423                 fx->wBitsPerSample = ctx->sample_size;
424             }
425             if (ctx->channels) {
426                 if (ctx->channels > acaps->MaximumChannels ||
427                     ctx->channels < acaps->MinimumChannels)
428                     goto next;
429                 fx->nChannels = ctx->channels;
430             }
431         }
432         if (IAMStreamConfig_SetFormat(config, type) != S_OK)
433             goto next;
434         format_set = 1;
435 next:
436         if (type->pbFormat)
437             CoTaskMemFree(type->pbFormat);
438         CoTaskMemFree(type);
439     }
440 end:
441     IAMStreamConfig_Release(config);
442     if (caps)
443         av_free(caps);
444     if (pformat_set)
445         *pformat_set = format_set;
446 }
447
448 /**
449  * Cycle through available pins using the device_filter device, of type
450  * devtype, retrieve the first output pin and return the pointer to the
451  * object found in *ppin.
452  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
453  */
454 static int
455 dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
456                  IBaseFilter *device_filter, IPin **ppin)
457 {
458     struct dshow_ctx *ctx = avctx->priv_data;
459     IEnumPins *pins = 0;
460     IPin *device_pin = NULL;
461     IPin *pin;
462     int r;
463
464     const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
465     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
466
467     int set_format = (devtype == VideoDevice && (ctx->video_size || ctx->framerate))
468                   || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
469     int format_set = 0;
470
471     r = IBaseFilter_EnumPins(device_filter, &pins);
472     if (r != S_OK) {
473         av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
474         return AVERROR(EIO);
475     }
476
477     if (!ppin) {
478         av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
479                devtypename);
480     }
481     while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
482         IKsPropertySet *p = NULL;
483         IEnumMediaTypes *types = NULL;
484         PIN_INFO info = {0};
485         AM_MEDIA_TYPE *type;
486         GUID category;
487         DWORD r2;
488
489         IPin_QueryPinInfo(pin, &info);
490         IBaseFilter_Release(info.pFilter);
491
492         if (info.dir != PINDIR_OUTPUT)
493             goto next;
494         if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
495             goto next;
496         if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
497                                NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
498             goto next;
499         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
500             goto next;
501
502         if (!ppin) {
503             char *buf = dup_wchar_to_utf8(info.achName);
504             av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
505             av_free(buf);
506             dshow_cycle_formats(avctx, devtype, pin, NULL);
507             goto next;
508         }
509         if (set_format) {
510             dshow_cycle_formats(avctx, devtype, pin, &format_set);
511             if (!format_set) {
512                 goto next;
513             }
514         }
515
516         if (IPin_EnumMediaTypes(pin, &types) != S_OK)
517             goto next;
518
519         IEnumMediaTypes_Reset(types);
520         while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
521             if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
522                 device_pin = pin;
523                 goto next;
524             }
525             CoTaskMemFree(type);
526         }
527
528 next:
529         if (types)
530             IEnumMediaTypes_Release(types);
531         if (p)
532             IKsPropertySet_Release(p);
533         if (device_pin != pin)
534             IPin_Release(pin);
535     }
536
537     IEnumPins_Release(pins);
538
539     if (ppin) {
540         if (set_format && !format_set) {
541             av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
542             return AVERROR(EIO);
543         }
544         if (!device_pin) {
545             av_log(avctx, AV_LOG_ERROR,
546                 "Could not find output pin from %s capture device.\n", devtypename);
547             return AVERROR(EIO);
548         }
549         *ppin = device_pin;
550     }
551
552     return 0;
553 }
554
555 /**
556  * List options for device with type devtype.
557  *
558  * @param devenum device enumerator used for accessing the device
559  */
560 static int
561 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
562                           enum dshowDeviceType devtype)
563 {
564     struct dshow_ctx *ctx = avctx->priv_data;
565     IBaseFilter *device_filter = NULL;
566     int r;
567
568     if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0)
569         return r;
570     ctx->device_filter[devtype] = device_filter;
571     if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0)
572         return r;
573
574     return 0;
575 }
576
577 static int
578 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
579                   enum dshowDeviceType devtype)
580 {
581     struct dshow_ctx *ctx = avctx->priv_data;
582     IBaseFilter *device_filter = NULL;
583     IGraphBuilder *graph = ctx->graph;
584     IPin *device_pin = NULL;
585     libAVPin *capture_pin = NULL;
586     libAVFilter *capture_filter = NULL;
587     int ret = AVERROR(EIO);
588     int r;
589
590     const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
591
592     if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) {
593         ret = r;
594         goto error;
595     }
596
597     ctx->device_filter [devtype] = device_filter;
598
599     r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
600     if (r != S_OK) {
601         av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
602         goto error;
603     }
604
605     if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
606         ret = r;
607         goto error;
608     }
609     ctx->device_pin[devtype] = device_pin;
610
611     capture_filter = libAVFilter_Create(avctx, callback, devtype);
612     if (!capture_filter) {
613         av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
614         goto error;
615     }
616     ctx->capture_filter[devtype] = capture_filter;
617
618     r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
619                                 filter_name[devtype]);
620     if (r != S_OK) {
621         av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
622         goto error;
623     }
624
625     libAVPin_AddRef(capture_filter->pin);
626     capture_pin = capture_filter->pin;
627     ctx->capture_pin[devtype] = capture_pin;
628
629     r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
630     if (r != S_OK) {
631         av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
632         goto error;
633     }
634
635     ret = 0;
636
637 error:
638     return ret;
639 }
640
641 static enum CodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
642 {
643     switch (sample_fmt) {
644     case AV_SAMPLE_FMT_U8:  return CODEC_ID_PCM_U8;
645     case AV_SAMPLE_FMT_S16: return CODEC_ID_PCM_S16LE;
646     case AV_SAMPLE_FMT_S32: return CODEC_ID_PCM_S32LE;
647     default:                return CODEC_ID_NONE; /* Should never happen. */
648     }
649 }
650
651 static enum SampleFormat sample_fmt_bits_per_sample(int bits)
652 {
653     switch (bits) {
654     case 8:  return AV_SAMPLE_FMT_U8;
655     case 16: return AV_SAMPLE_FMT_S16;
656     case 32: return AV_SAMPLE_FMT_S32;
657     default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
658     }
659 }
660
661 static int
662 dshow_add_device(AVFormatContext *avctx, AVFormatParameters *ap,
663                  enum dshowDeviceType devtype)
664 {
665     struct dshow_ctx *ctx = avctx->priv_data;
666     AM_MEDIA_TYPE type;
667     AVCodecContext *codec;
668     AVStream *st;
669     int ret = AVERROR(EIO);
670
671     st = avformat_new_stream(avctx, NULL);
672     if (!st) {
673         ret = AVERROR(ENOMEM);
674         goto error;
675     }
676     st->id = devtype;
677
678     ctx->capture_filter[devtype]->stream_index = st->index;
679
680     libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
681
682     codec = st->codec;
683     if (devtype == VideoDevice) {
684         BITMAPINFOHEADER *bih = NULL;
685
686         if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
687             VIDEOINFOHEADER *v = (void *) type.pbFormat;
688             bih = &v->bmiHeader;
689         } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
690             VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
691             bih = &v->bmiHeader;
692         }
693         if (!bih) {
694             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
695             goto error;
696         }
697
698         codec->time_base  = ap->time_base;
699         codec->codec_type = AVMEDIA_TYPE_VIDEO;
700         codec->width      = bih->biWidth;
701         codec->height     = bih->biHeight;
702         codec->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
703         if (codec->pix_fmt == PIX_FMT_NONE) {
704             codec->codec_id = dshow_codecid(bih->biCompression);
705             if (codec->codec_id == CODEC_ID_NONE) {
706                 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
707                                  "Please report verbose (-v 9) debug information.\n");
708                 dshow_read_close(avctx);
709                 return AVERROR_PATCHWELCOME;
710             }
711             codec->bits_per_coded_sample = bih->biBitCount;
712         } else {
713             codec->codec_id = CODEC_ID_RAWVIDEO;
714             if (bih->biCompression == BI_RGB) {
715                 codec->bits_per_coded_sample = bih->biBitCount;
716                 codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
717                 if (codec->extradata) {
718                     codec->extradata_size = 9;
719                     memcpy(codec->extradata, "BottomUp", 9);
720                 }
721             }
722         }
723     } else {
724         WAVEFORMATEX *fx = NULL;
725
726         if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
727             fx = (void *) type.pbFormat;
728         }
729         if (!fx) {
730             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
731             goto error;
732         }
733
734         codec->codec_type  = AVMEDIA_TYPE_AUDIO;
735         codec->sample_fmt  = sample_fmt_bits_per_sample(fx->wBitsPerSample);
736         codec->codec_id    = waveform_codec_id(codec->sample_fmt);
737         codec->sample_rate = fx->nSamplesPerSec;
738         codec->channels    = fx->nChannels;
739     }
740
741     av_set_pts_info(st, 64, 1, 10000000);
742
743     ret = 0;
744
745 error:
746     return ret;
747 }
748
749 static int parse_device_name(AVFormatContext *avctx)
750 {
751     struct dshow_ctx *ctx = avctx->priv_data;
752     char **device_name = ctx->device_name;
753     char *name = av_strdup(avctx->filename);
754     char *tmp = name;
755     int ret = 1;
756     char *type;
757
758     while ((type = strtok(tmp, "="))) {
759         char *token = strtok(NULL, ":");
760         tmp = NULL;
761
762         if        (!strcmp(type, "video")) {
763             device_name[0] = token;
764         } else if (!strcmp(type, "audio")) {
765             device_name[1] = token;
766         } else {
767             device_name[0] = NULL;
768             device_name[1] = NULL;
769             break;
770         }
771     }
772
773     if (!device_name[0] && !device_name[1]) {
774         ret = 0;
775     } else {
776         if (device_name[0])
777             device_name[0] = av_strdup(device_name[0]);
778         if (device_name[1])
779             device_name[1] = av_strdup(device_name[1]);
780     }
781
782     av_free(name);
783     return ret;
784 }
785
786 static int dshow_read_header(AVFormatContext *avctx, AVFormatParameters *ap)
787 {
788     struct dshow_ctx *ctx = avctx->priv_data;
789     IGraphBuilder *graph = NULL;
790     ICreateDevEnum *devenum = NULL;
791     IMediaControl *control = NULL;
792     int ret = AVERROR(EIO);
793     int r;
794
795     if (!ctx->list_devices && !parse_device_name(avctx)) {
796         av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
797         goto error;
798     }
799
800     if (ctx->video_size) {
801         r = av_parse_video_size(&ctx->requested_width, &ctx->requested_height, ctx->video_size);
802         if (r < 0) {
803             av_log(avctx, AV_LOG_ERROR, "Could not parse video size '%s'.\n", ctx->video_size);
804             goto error;
805         }
806     }
807     if (ctx->framerate) {
808         r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
809         if (r < 0) {
810             av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
811             goto error;
812         }
813     }
814
815     CoInitialize(0);
816
817     r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
818                          &IID_IGraphBuilder, (void **) &graph);
819     if (r != S_OK) {
820         av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
821         goto error;
822     }
823     ctx->graph = graph;
824
825     r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
826                          &IID_ICreateDevEnum, (void **) &devenum);
827     if (r != S_OK) {
828         av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
829         goto error;
830     }
831
832     if (ctx->list_devices) {
833         av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
834         dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
835         av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
836         dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
837         ret = AVERROR_EXIT;
838         goto error;
839     }
840     if (ctx->list_options) {
841         if (ctx->device_name[VideoDevice])
842             dshow_list_device_options(avctx, devenum, VideoDevice);
843         if (ctx->device_name[AudioDevice])
844             dshow_list_device_options(avctx, devenum, AudioDevice);
845         ret = AVERROR_EXIT;
846         goto error;
847     }
848
849     if (ctx->device_name[VideoDevice]) {
850         ret = dshow_open_device(avctx, devenum, VideoDevice);
851         if (ret < 0)
852             goto error;
853         ret = dshow_add_device(avctx, ap, VideoDevice);
854         if (ret < 0)
855             goto error;
856     }
857     if (ctx->device_name[AudioDevice]) {
858         ret = dshow_open_device(avctx, devenum, AudioDevice);
859         if (ret < 0)
860             goto error;
861         ret = dshow_add_device(avctx, ap, AudioDevice);
862         if (ret < 0)
863             goto error;
864     }
865
866     ctx->mutex = CreateMutex(NULL, 0, NULL);
867     if (!ctx->mutex) {
868         av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
869         goto error;
870     }
871     ctx->event = CreateEvent(NULL, 1, 0, NULL);
872     if (!ctx->event) {
873         av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
874         goto error;
875     }
876
877     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
878     if (r != S_OK) {
879         av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
880         goto error;
881     }
882     ctx->control = control;
883
884     r = IMediaControl_Run(control);
885     if (r == S_FALSE) {
886         OAFilterState pfs;
887         r = IMediaControl_GetState(control, 0, &pfs);
888     }
889     if (r != S_OK) {
890         av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
891         goto error;
892     }
893
894     ret = 0;
895
896 error:
897
898     if (ret < 0)
899         dshow_read_close(avctx);
900
901     if (devenum)
902         ICreateDevEnum_Release(devenum);
903
904     return ret;
905 }
906
907 static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
908 {
909     struct dshow_ctx *ctx = s->priv_data;
910     AVPacketList *pktl = NULL;
911
912     while (!pktl) {
913         WaitForSingleObject(ctx->mutex, INFINITE);
914         pktl = ctx->pktl;
915         if (ctx->pktl) {
916             *pkt = ctx->pktl->pkt;
917             ctx->pktl = ctx->pktl->next;
918             av_free(pktl);
919         }
920         ResetEvent(ctx->event);
921         ReleaseMutex(ctx->mutex);
922         if (!pktl) {
923             if (s->flags & AVFMT_FLAG_NONBLOCK) {
924                 return AVERROR(EAGAIN);
925             } else {
926                 WaitForSingleObject(ctx->event, INFINITE);
927             }
928         }
929     }
930
931     ctx->curbufsize -= pkt->size;
932
933     return pkt->size;
934 }
935
936 #define OFFSET(x) offsetof(struct dshow_ctx, x)
937 #define DEC AV_OPT_FLAG_DECODING_PARAM
938 static const AVOption options[] = {
939     { "video_size", "set video size given a string such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
940     { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
941     { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
942     { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 16, DEC },
943     { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
944     { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.dbl=0}, 0, 1, DEC, "list_devices" },
945     { "true", "", 0, AV_OPT_TYPE_CONST, {.dbl=1}, 0, 0, DEC, "list_devices" },
946     { "false", "", 0, AV_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_devices" },
947     { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.dbl=0}, 0, 1, DEC, "list_options" },
948     { "true", "", 0, AV_OPT_TYPE_CONST, {.dbl=1}, 0, 0, DEC, "list_options" },
949     { "false", "", 0, AV_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_options" },
950     { "video_device_number", "set video device number for devices with same name (starts at 0)", OFFSET(video_device_number), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
951     { "audio_device_number", "set audio device number for devices with same name (starts at 0)", OFFSET(audio_device_number), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
952     { NULL },
953 };
954
955 static const AVClass dshow_class = {
956     .class_name = "DirectShow indev",
957     .item_name  = av_default_item_name,
958     .option     = options,
959     .version    = LIBAVUTIL_VERSION_INT,
960 };
961
962 AVInputFormat ff_dshow_demuxer = {
963     "dshow",
964     NULL_IF_CONFIG_SMALL("DirectShow capture"),
965     sizeof(struct dshow_ctx),
966     NULL,
967     dshow_read_header,
968     dshow_read_packet,
969     dshow_read_close,
970     .flags = AVFMT_NOFILE,
971     .priv_class = &dshow_class,
972 };