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/pixdesc.h"
24#include "libavutil/opt.h"
25#include "libavformat/internal.h"
26#include "libavformat/riff.h"
27#include "avdevice.h"
28#include "dshow_capture.h"
29#include "libavcodec/raw.h"
30
31struct dshow_ctx {
32    const AVClass *class;
33
34    IGraphBuilder *graph;
35
36    char *device_name[2];
37    int video_device_number;
38    int audio_device_number;
39
40    int   list_options;
41    int   list_devices;
42    int   audio_buffer_size;
43
44    IBaseFilter *device_filter[2];
45    IPin        *device_pin[2];
46    libAVFilter *capture_filter[2];
47    libAVPin    *capture_pin[2];
48
49    HANDLE mutex;
50    HANDLE event[2]; /* event[0] is set by DirectShow
51                      * event[1] is set by callback() */
52    AVPacketList *pktl;
53
54    int eof;
55
56    int64_t curbufsize[2];
57    unsigned int video_frame_num;
58
59    IMediaControl *control;
60    IMediaEvent *media_event;
61
62    enum AVPixelFormat pixel_format;
63    enum AVCodecID video_codec_id;
64    char *framerate;
65
66    int requested_width;
67    int requested_height;
68    AVRational requested_framerate;
69
70    int sample_rate;
71    int sample_size;
72    int channels;
73};
74
75static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
76{
77    switch(biCompression) {
78    case BI_BITFIELDS:
79    case BI_RGB:
80        switch(biBitCount) { /* 1-8 are untested */
81            case 1:
82                return AV_PIX_FMT_MONOWHITE;
83            case 4:
84                return AV_PIX_FMT_RGB4;
85            case 8:
86                return AV_PIX_FMT_RGB8;
87            case 16:
88                return AV_PIX_FMT_RGB555;
89            case 24:
90                return AV_PIX_FMT_BGR24;
91            case 32:
92                return AV_PIX_FMT_0RGB32;
93        }
94    }
95    return avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, biCompression); // all others
96}
97
98static int
99dshow_read_close(AVFormatContext *s)
100{
101    struct dshow_ctx *ctx = s->priv_data;
102    AVPacketList *pktl;
103
104    if (ctx->control) {
105        IMediaControl_Stop(ctx->control);
106        IMediaControl_Release(ctx->control);
107    }
108
109    if (ctx->media_event)
110        IMediaEvent_Release(ctx->media_event);
111
112    if (ctx->graph) {
113        IEnumFilters *fenum;
114        int r;
115        r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
116        if (r == S_OK) {
117            IBaseFilter *f;
118            IEnumFilters_Reset(fenum);
119            while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
120                if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
121                    IEnumFilters_Reset(fenum); /* When a filter is removed,
122                                                * the list must be reset. */
123                IBaseFilter_Release(f);
124            }
125            IEnumFilters_Release(fenum);
126        }
127        IGraphBuilder_Release(ctx->graph);
128    }
129
130    if (ctx->capture_pin[VideoDevice])
131        libAVPin_Release(ctx->capture_pin[VideoDevice]);
132    if (ctx->capture_pin[AudioDevice])
133        libAVPin_Release(ctx->capture_pin[AudioDevice]);
134    if (ctx->capture_filter[VideoDevice])
135        libAVFilter_Release(ctx->capture_filter[VideoDevice]);
136    if (ctx->capture_filter[AudioDevice])
137        libAVFilter_Release(ctx->capture_filter[AudioDevice]);
138
139    if (ctx->device_pin[VideoDevice])
140        IPin_Release(ctx->device_pin[VideoDevice]);
141    if (ctx->device_pin[AudioDevice])
142        IPin_Release(ctx->device_pin[AudioDevice]);
143    if (ctx->device_filter[VideoDevice])
144        IBaseFilter_Release(ctx->device_filter[VideoDevice]);
145    if (ctx->device_filter[AudioDevice])
146        IBaseFilter_Release(ctx->device_filter[AudioDevice]);
147
148    if (ctx->device_name[0])
149        av_free(ctx->device_name[0]);
150    if (ctx->device_name[1])
151        av_free(ctx->device_name[1]);
152
153    if(ctx->mutex)
154        CloseHandle(ctx->mutex);
155    if(ctx->event[0])
156        CloseHandle(ctx->event[0]);
157    if(ctx->event[1])
158        CloseHandle(ctx->event[1]);
159
160    pktl = ctx->pktl;
161    while (pktl) {
162        AVPacketList *next = pktl->next;
163        av_destruct_packet(&pktl->pkt);
164        av_free(pktl);
165        pktl = next;
166    }
167
168    CoUninitialize();
169
170    return 0;
171}
172
173static char *dup_wchar_to_utf8(wchar_t *w)
174{
175    char *s = NULL;
176    int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
177    s = av_malloc(l);
178    if (s)
179        WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
180    return s;
181}
182
183static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
184{
185    struct dshow_ctx *ctx = s->priv_data;
186    static const uint8_t dropscore[] = {62, 75, 87, 100};
187    const int ndropscores = FF_ARRAY_ELEMS(dropscore);
188    unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
189
190    if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
191        av_log(s, AV_LOG_ERROR,
192              "real-time buffer[%s] too full (%d%% of size: %d)! frame dropped!\n", ctx->device_name[devtype], buffer_fullness, s->max_picture_buffer);
193        return 1;
194    }
195
196    return 0;
197}
198
199static void
200callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
201{
202    AVFormatContext *s = priv_data;
203    struct dshow_ctx *ctx = s->priv_data;
204    AVPacketList **ppktl, *pktl_next;
205
206//    dump_videohdr(s, vdhdr);
207
208    WaitForSingleObject(ctx->mutex, INFINITE);
209
210    if(shall_we_drop(s, index, devtype))
211        goto fail;
212
213    pktl_next = av_mallocz(sizeof(AVPacketList));
214    if(!pktl_next)
215        goto fail;
216
217    if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
218        av_free(pktl_next);
219        goto fail;
220    }
221
222    pktl_next->pkt.stream_index = index;
223    pktl_next->pkt.pts = time;
224    memcpy(pktl_next->pkt.data, buf, buf_size);
225
226    for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
227    *ppktl = pktl_next;
228    ctx->curbufsize[index] += buf_size;
229
230    SetEvent(ctx->event[1]);
231    ReleaseMutex(ctx->mutex);
232
233    return;
234fail:
235    ReleaseMutex(ctx->mutex);
236    return;
237}
238
239/**
240 * Cycle through available devices using the device enumerator devenum,
241 * retrieve the device with type specified by devtype and return the
242 * pointer to the object found in *pfilter.
243 * If pfilter is NULL, list all device names.
244 */
245static int
246dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
247                    enum dshowDeviceType devtype, IBaseFilter **pfilter)
248{
249    struct dshow_ctx *ctx = avctx->priv_data;
250    IBaseFilter *device_filter = NULL;
251    IEnumMoniker *classenum = NULL;
252    IMoniker *m = NULL;
253    const char *device_name = ctx->device_name[devtype];
254    int skip = (devtype == VideoDevice) ? ctx->video_device_number
255                                        : ctx->audio_device_number;
256    int r;
257
258    const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
259                                   &CLSID_AudioInputDeviceCategory };
260    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
261
262    r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
263                                             (IEnumMoniker **) &classenum, 0);
264    if (r != S_OK) {
265        av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
266               devtypename);
267        return AVERROR(EIO);
268    }
269
270    while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
271        IPropertyBag *bag = NULL;
272        char *buf = NULL;
273        VARIANT var;
274
275        r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
276        if (r != S_OK)
277            goto fail1;
278
279        var.vt = VT_BSTR;
280        r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
281        if (r != S_OK)
282            goto fail1;
283
284        buf = dup_wchar_to_utf8(var.bstrVal);
285
286        if (pfilter) {
287            if (strcmp(device_name, buf))
288                goto fail1;
289
290            if (!skip--)
291                IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
292        } else {
293            av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
294        }
295
296fail1:
297        if (buf)
298            av_free(buf);
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.\n",
309                   devtypename);
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 */
324static void
325dshow_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;
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        IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
346
347#if DSHOWDEBUG
348        ff_print_AM_MEDIA_TYPE(type);
349#endif
350
351        if (devtype == VideoDevice) {
352            VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
353            BITMAPINFOHEADER *bih;
354            int64_t *fr;
355#if DSHOWDEBUG
356            ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
357#endif
358            if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
359                VIDEOINFOHEADER *v = (void *) type->pbFormat;
360                fr = &v->AvgTimePerFrame;
361                bih = &v->bmiHeader;
362            } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
363                VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
364                fr = &v->AvgTimePerFrame;
365                bih = &v->bmiHeader;
366            } else {
367                goto next;
368            }
369            if (!pformat_set) {
370                enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
371                if (pix_fmt == AV_PIX_FMT_NONE) {
372                    enum AVCodecID codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
373                    AVCodec *codec = avcodec_find_decoder(codec_id);
374                    if (codec_id == AV_CODEC_ID_NONE || !codec) {
375                        av_log(avctx, AV_LOG_INFO, "  unknown compression type 0x%X", (int) bih->biCompression);
376                    } else {
377                        av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
378                    }
379                } else {
380                    av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
381                }
382                av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
383                       vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
384                       1e7 / vcaps->MaxFrameInterval,
385                       vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
386                       1e7 / vcaps->MinFrameInterval);
387                continue;
388            }
389            if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
390                if (ctx->video_codec_id != ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression))
391                    goto next;
392            }
393            if (ctx->pixel_format != AV_PIX_FMT_NONE &&
394                ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
395                goto next;
396            }
397            if (ctx->framerate) {
398                int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
399                                            /  ctx->requested_framerate.num;
400                if (framerate > vcaps->MaxFrameInterval ||
401                    framerate < vcaps->MinFrameInterval)
402                    goto next;
403                *fr = framerate;
404            }
405            if (ctx->requested_width && ctx->requested_height) {
406                if (ctx->requested_width  > vcaps->MaxOutputSize.cx ||
407                    ctx->requested_width  < vcaps->MinOutputSize.cx ||
408                    ctx->requested_height > vcaps->MaxOutputSize.cy ||
409                    ctx->requested_height < vcaps->MinOutputSize.cy)
410                    goto next;
411                bih->biWidth  = ctx->requested_width;
412                bih->biHeight = ctx->requested_height;
413            }
414        } else {
415            AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
416            WAVEFORMATEX *fx;
417#if DSHOWDEBUG
418            ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
419#endif
420            if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
421                fx = (void *) type->pbFormat;
422            } else {
423                goto next;
424            }
425            if (!pformat_set) {
426                av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
427                       acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
428                       acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
429                continue;
430            }
431            if (ctx->sample_rate) {
432                if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
433                    ctx->sample_rate < acaps->MinimumSampleFrequency)
434                    goto next;
435                fx->nSamplesPerSec = ctx->sample_rate;
436            }
437            if (ctx->sample_size) {
438                if (ctx->sample_size > acaps->MaximumBitsPerSample ||
439                    ctx->sample_size < acaps->MinimumBitsPerSample)
440                    goto next;
441                fx->wBitsPerSample = ctx->sample_size;
442            }
443            if (ctx->channels) {
444                if (ctx->channels > acaps->MaximumChannels ||
445                    ctx->channels < acaps->MinimumChannels)
446                    goto next;
447                fx->nChannels = ctx->channels;
448            }
449        }
450        if (IAMStreamConfig_SetFormat(config, type) != S_OK)
451            goto next;
452        format_set = 1;
453next:
454        if (type->pbFormat)
455            CoTaskMemFree(type->pbFormat);
456        CoTaskMemFree(type);
457    }
458end:
459    IAMStreamConfig_Release(config);
460    if (caps)
461        av_free(caps);
462    if (pformat_set)
463        *pformat_set = format_set;
464}
465
466/**
467 * Set audio device buffer size in milliseconds (which can directly impact
468 * latency, depending on the device).
469 */
470static int
471dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
472{
473    struct dshow_ctx *ctx = avctx->priv_data;
474    IAMBufferNegotiation *buffer_negotiation = NULL;
475    ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
476    IAMStreamConfig *config = NULL;
477    AM_MEDIA_TYPE *type = NULL;
478    int ret = AVERROR(EIO);
479
480    if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
481        goto end;
482    if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
483        goto end;
484    if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
485        goto end;
486
487    props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
488                   * ctx->audio_buffer_size / 1000;
489
490    if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
491        goto end;
492    if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
493        goto end;
494
495    ret = 0;
496
497end:
498    if (buffer_negotiation)
499        IAMBufferNegotiation_Release(buffer_negotiation);
500    if (type) {
501        if (type->pbFormat)
502            CoTaskMemFree(type->pbFormat);
503        CoTaskMemFree(type);
504    }
505    if (config)
506        IAMStreamConfig_Release(config);
507
508    return ret;
509}
510
511/**
512 * Cycle through available pins using the device_filter device, of type
513 * devtype, retrieve the first output pin and return the pointer to the
514 * object found in *ppin.
515 * If ppin is NULL, cycle through all pins listing audio/video capabilities.
516 */
517static int
518dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
519                 IBaseFilter *device_filter, IPin **ppin)
520{
521    struct dshow_ctx *ctx = avctx->priv_data;
522    IEnumPins *pins = 0;
523    IPin *device_pin = NULL;
524    IPin *pin;
525    int r;
526
527    const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
528    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
529
530    int set_format = (devtype == VideoDevice && (ctx->framerate ||
531                                                (ctx->requested_width && ctx->requested_height) ||
532                                                 ctx->pixel_format != AV_PIX_FMT_NONE ||
533                                                 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
534                  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
535    int format_set = 0;
536
537    r = IBaseFilter_EnumPins(device_filter, &pins);
538    if (r != S_OK) {
539        av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
540        return AVERROR(EIO);
541    }
542
543    if (!ppin) {
544        av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
545               devtypename);
546    }
547    while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
548        IKsPropertySet *p = NULL;
549        IEnumMediaTypes *types = NULL;
550        PIN_INFO info = {0};
551        AM_MEDIA_TYPE *type;
552        GUID category;
553        DWORD r2;
554
555        IPin_QueryPinInfo(pin, &info);
556        IBaseFilter_Release(info.pFilter);
557
558        if (info.dir != PINDIR_OUTPUT)
559            goto next;
560        if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
561            goto next;
562        if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
563                               NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
564            goto next;
565        if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
566            goto next;
567
568        if (!ppin) {
569            char *buf = dup_wchar_to_utf8(info.achName);
570            av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
571            av_free(buf);
572            dshow_cycle_formats(avctx, devtype, pin, NULL);
573            goto next;
574        }
575        if (set_format) {
576            dshow_cycle_formats(avctx, devtype, pin, &format_set);
577            if (!format_set) {
578                goto next;
579            }
580        }
581        if (devtype == AudioDevice && ctx->audio_buffer_size) {
582            if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
583                av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
584            }
585        }
586
587        if (IPin_EnumMediaTypes(pin, &types) != S_OK)
588            goto next;
589
590        IEnumMediaTypes_Reset(types);
591        while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
592            if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
593                device_pin = pin;
594                goto next;
595            }
596            CoTaskMemFree(type);
597        }
598
599next:
600        if (types)
601            IEnumMediaTypes_Release(types);
602        if (p)
603            IKsPropertySet_Release(p);
604        if (device_pin != pin)
605            IPin_Release(pin);
606    }
607
608    IEnumPins_Release(pins);
609
610    if (ppin) {
611        if (set_format && !format_set) {
612            av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
613            return AVERROR(EIO);
614        }
615        if (!device_pin) {
616            av_log(avctx, AV_LOG_ERROR,
617                "Could not find output pin from %s capture device.\n", devtypename);
618            return AVERROR(EIO);
619        }
620        *ppin = device_pin;
621    }
622
623    return 0;
624}
625
626/**
627 * List options for device with type devtype.
628 *
629 * @param devenum device enumerator used for accessing the device
630 */
631static int
632dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
633                          enum dshowDeviceType devtype)
634{
635    struct dshow_ctx *ctx = avctx->priv_data;
636    IBaseFilter *device_filter = NULL;
637    int r;
638
639    if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0)
640        return r;
641    ctx->device_filter[devtype] = device_filter;
642    if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0)
643        return r;
644
645    return 0;
646}
647
648static int
649dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
650                  enum dshowDeviceType devtype)
651{
652    struct dshow_ctx *ctx = avctx->priv_data;
653    IBaseFilter *device_filter = NULL;
654    IGraphBuilder *graph = ctx->graph;
655    IPin *device_pin = NULL;
656    libAVPin *capture_pin = NULL;
657    libAVFilter *capture_filter = NULL;
658    int ret = AVERROR(EIO);
659    int r;
660
661    const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
662
663    if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) {
664        ret = r;
665        goto error;
666    }
667
668    ctx->device_filter [devtype] = device_filter;
669
670    r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
671    if (r != S_OK) {
672        av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
673        goto error;
674    }
675
676    if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
677        ret = r;
678        goto error;
679    }
680    ctx->device_pin[devtype] = device_pin;
681
682    capture_filter = libAVFilter_Create(avctx, callback, devtype);
683    if (!capture_filter) {
684        av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
685        goto error;
686    }
687    ctx->capture_filter[devtype] = capture_filter;
688
689    r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
690                                filter_name[devtype]);
691    if (r != S_OK) {
692        av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
693        goto error;
694    }
695
696    libAVPin_AddRef(capture_filter->pin);
697    capture_pin = capture_filter->pin;
698    ctx->capture_pin[devtype] = capture_pin;
699
700    r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
701    if (r != S_OK) {
702        av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
703        goto error;
704    }
705
706    ret = 0;
707
708error:
709    return ret;
710}
711
712static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
713{
714    switch (sample_fmt) {
715    case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
716    case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
717    case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
718    default:                return AV_CODEC_ID_NONE; /* Should never happen. */
719    }
720}
721
722static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
723{
724    switch (bits) {
725    case 8:  return AV_SAMPLE_FMT_U8;
726    case 16: return AV_SAMPLE_FMT_S16;
727    case 32: return AV_SAMPLE_FMT_S32;
728    default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
729    }
730}
731
732static int
733dshow_add_device(AVFormatContext *avctx,
734                 enum dshowDeviceType devtype)
735{
736    struct dshow_ctx *ctx = avctx->priv_data;
737    AM_MEDIA_TYPE type;
738    AVCodecContext *codec;
739    AVStream *st;
740    int ret = AVERROR(EIO);
741
742    st = avformat_new_stream(avctx, NULL);
743    if (!st) {
744        ret = AVERROR(ENOMEM);
745        goto error;
746    }
747    st->id = devtype;
748
749    ctx->capture_filter[devtype]->stream_index = st->index;
750
751    libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
752
753    codec = st->codec;
754    if (devtype == VideoDevice) {
755        BITMAPINFOHEADER *bih = NULL;
756        AVRational time_base;
757
758        if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
759            VIDEOINFOHEADER *v = (void *) type.pbFormat;
760            time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
761            bih = &v->bmiHeader;
762        } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
763            VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
764            time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
765            bih = &v->bmiHeader;
766        }
767        if (!bih) {
768            av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
769            goto error;
770        }
771
772        codec->time_base  = time_base;
773        codec->codec_type = AVMEDIA_TYPE_VIDEO;
774        codec->width      = bih->biWidth;
775        codec->height     = bih->biHeight;
776        codec->codec_tag  = bih->biCompression;
777        codec->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
778        if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
779            av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
780            codec->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
781        }
782        if (codec->pix_fmt == AV_PIX_FMT_NONE) {
783            codec->codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
784            if (codec->codec_id == AV_CODEC_ID_NONE) {
785                av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
786                                 "Please report type 0x%X.\n", (int) bih->biCompression);
787                return AVERROR_PATCHWELCOME;
788            }
789            codec->bits_per_coded_sample = bih->biBitCount;
790        } else {
791            codec->codec_id = AV_CODEC_ID_RAWVIDEO;
792            if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
793                codec->bits_per_coded_sample = bih->biBitCount;
794                codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
795                if (codec->extradata) {
796                    codec->extradata_size = 9;
797                    memcpy(codec->extradata, "BottomUp", 9);
798                }
799            }
800        }
801    } else {
802        WAVEFORMATEX *fx = NULL;
803
804        if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
805            fx = (void *) type.pbFormat;
806        }
807        if (!fx) {
808            av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
809            goto error;
810        }
811
812        codec->codec_type  = AVMEDIA_TYPE_AUDIO;
813        codec->sample_fmt  = sample_fmt_bits_per_sample(fx->wBitsPerSample);
814        codec->codec_id    = waveform_codec_id(codec->sample_fmt);
815        codec->sample_rate = fx->nSamplesPerSec;
816        codec->channels    = fx->nChannels;
817    }
818
819    avpriv_set_pts_info(st, 64, 1, 10000000);
820
821    ret = 0;
822
823error:
824    return ret;
825}
826
827static int parse_device_name(AVFormatContext *avctx)
828{
829    struct dshow_ctx *ctx = avctx->priv_data;
830    char **device_name = ctx->device_name;
831    char *name = av_strdup(avctx->filename);
832    char *tmp = name;
833    int ret = 1;
834    char *type;
835
836    while ((type = strtok(tmp, "="))) {
837        char *token = strtok(NULL, ":");
838        tmp = NULL;
839
840        if        (!strcmp(type, "video")) {
841            device_name[0] = token;
842        } else if (!strcmp(type, "audio")) {
843            device_name[1] = token;
844        } else {
845            device_name[0] = NULL;
846            device_name[1] = NULL;
847            break;
848        }
849    }
850
851    if (!device_name[0] && !device_name[1]) {
852        ret = 0;
853    } else {
854        if (device_name[0])
855            device_name[0] = av_strdup(device_name[0]);
856        if (device_name[1])
857            device_name[1] = av_strdup(device_name[1]);
858    }
859
860    av_free(name);
861    return ret;
862}
863
864static int dshow_read_header(AVFormatContext *avctx)
865{
866    struct dshow_ctx *ctx = avctx->priv_data;
867    IGraphBuilder *graph = NULL;
868    ICreateDevEnum *devenum = NULL;
869    IMediaControl *control = NULL;
870    IMediaEvent *media_event = NULL;
871    HANDLE media_event_handle;
872    HANDLE proc;
873    int ret = AVERROR(EIO);
874    int r;
875
876    CoInitialize(0);
877
878    if (!ctx->list_devices && !parse_device_name(avctx)) {
879        av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
880        goto error;
881    }
882
883    ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
884                                                : AV_CODEC_ID_RAWVIDEO;
885    if (ctx->pixel_format != AV_PIX_FMT_NONE) {
886        if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
887            av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
888                              "video codec is not set or set to rawvideo\n");
889            ret = AVERROR(EINVAL);
890            goto error;
891        }
892    }
893    if (ctx->framerate) {
894        r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
895        if (r < 0) {
896            av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
897            goto error;
898        }
899    }
900
901    r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
902                         &IID_IGraphBuilder, (void **) &graph);
903    if (r != S_OK) {
904        av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
905        goto error;
906    }
907    ctx->graph = graph;
908
909    r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
910                         &IID_ICreateDevEnum, (void **) &devenum);
911    if (r != S_OK) {
912        av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
913        goto error;
914    }
915
916    if (ctx->list_devices) {
917        av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
918        dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
919        av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
920        dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
921        ret = AVERROR_EXIT;
922        goto error;
923    }
924    if (ctx->list_options) {
925        if (ctx->device_name[VideoDevice])
926            dshow_list_device_options(avctx, devenum, VideoDevice);
927        if (ctx->device_name[AudioDevice])
928            dshow_list_device_options(avctx, devenum, AudioDevice);
929        ret = AVERROR_EXIT;
930        goto error;
931    }
932
933    if (ctx->device_name[VideoDevice]) {
934        if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 ||
935            (r = dshow_add_device(avctx, VideoDevice)) < 0) {
936            ret = r;
937            goto error;
938        }
939    }
940    if (ctx->device_name[AudioDevice]) {
941        if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 ||
942            (r = dshow_add_device(avctx, AudioDevice)) < 0) {
943            ret = r;
944            goto error;
945        }
946    }
947    ctx->curbufsize[0] = 0;
948    ctx->curbufsize[1] = 0;
949    ctx->mutex = CreateMutex(NULL, 0, NULL);
950    if (!ctx->mutex) {
951        av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
952        goto error;
953    }
954    ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
955    if (!ctx->event[1]) {
956        av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
957        goto error;
958    }
959
960    r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
961    if (r != S_OK) {
962        av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
963        goto error;
964    }
965    ctx->control = control;
966
967    r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
968    if (r != S_OK) {
969        av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
970        goto error;
971    }
972    ctx->media_event = media_event;
973
974    r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
975    if (r != S_OK) {
976        av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
977        goto error;
978    }
979    proc = GetCurrentProcess();
980    r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
981                        0, 0, DUPLICATE_SAME_ACCESS);
982    if (!r) {
983        av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
984        goto error;
985    }
986
987    r = IMediaControl_Run(control);
988    if (r == S_FALSE) {
989        OAFilterState pfs;
990        r = IMediaControl_GetState(control, 0, &pfs);
991    }
992    if (r != S_OK) {
993        av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
994        goto error;
995    }
996
997    ret = 0;
998
999error:
1000
1001    if (devenum)
1002        ICreateDevEnum_Release(devenum);
1003
1004    if (ret < 0)
1005        dshow_read_close(avctx);
1006
1007    return ret;
1008}
1009
1010/**
1011 * Checks media events from DirectShow and returns -1 on error or EOF. Also
1012 * purges all events that might be in the event queue to stop the trigger
1013 * of event notification.
1014 */
1015static int dshow_check_event_queue(IMediaEvent *media_event)
1016{
1017    LONG_PTR p1, p2;
1018    long code;
1019    int ret = 0;
1020
1021    while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1022        if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1023            ret = -1;
1024        IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1025    }
1026
1027    return ret;
1028}
1029
1030static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
1031{
1032    struct dshow_ctx *ctx = s->priv_data;
1033    AVPacketList *pktl = NULL;
1034
1035    while (!ctx->eof && !pktl) {
1036        WaitForSingleObject(ctx->mutex, INFINITE);
1037        pktl = ctx->pktl;
1038        if (pktl) {
1039            *pkt = pktl->pkt;
1040            ctx->pktl = ctx->pktl->next;
1041            av_free(pktl);
1042            ctx->curbufsize[pkt->stream_index] -= pkt->size;
1043        }
1044        ResetEvent(ctx->event[1]);
1045        ReleaseMutex(ctx->mutex);
1046        if (!pktl) {
1047            if (dshow_check_event_queue(ctx->media_event) < 0) {
1048                ctx->eof = 1;
1049            } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1050                return AVERROR(EAGAIN);
1051            } else {
1052                WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1053            }
1054        }
1055    }
1056
1057    return ctx->eof ? AVERROR(EIO) : pkt->size;
1058}
1059
1060#define OFFSET(x) offsetof(struct dshow_ctx, x)
1061#define DEC AV_OPT_FLAG_DECODING_PARAM
1062static const AVOption options[] = {
1063    { "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 },
1064    { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1065    { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1066    { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1067    { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1068    { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1069    { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" },
1070    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" },
1071    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" },
1072    { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" },
1073    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" },
1074    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" },
1075    { "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 },
1076    { "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 },
1077    { "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 },
1078    { NULL },
1079};
1080
1081static const AVClass dshow_class = {
1082    .class_name = "dshow indev",
1083    .item_name  = av_default_item_name,
1084    .option     = options,
1085    .version    = LIBAVUTIL_VERSION_INT,
1086    .category   = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
1087};
1088
1089AVInputFormat ff_dshow_demuxer = {
1090    .name           = "dshow",
1091    .long_name      = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1092    .priv_data_size = sizeof(struct dshow_ctx),
1093    .read_header    = dshow_read_header,
1094    .read_packet    = dshow_read_packet,
1095    .read_close     = dshow_read_close,
1096    .flags          = AVFMT_NOFILE,
1097    .priv_class     = &dshow_class,
1098};
1099