Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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
 
31
struct 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;
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
 
75
static 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_RGB32;
93
        }
94
    }
95
    return avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, biCompression); // all others
96
}
97
 
98
static int
99
dshow_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
 
173
static 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
 
183
static int shall_we_drop(AVFormatContext *s)
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*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 %d%% full! frame dropped!\n", buffer_fullness);
193
        return 1;
194
    }
195
 
196
    return 0;
197
}
198
 
199
static void
200
callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
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))
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
 
229
    ctx->curbufsize += buf_size;
230
 
231
    SetEvent(ctx->event[1]);
232
    ReleaseMutex(ctx->mutex);
233
 
234
    return;
235
fail:
236
    ReleaseMutex(ctx->mutex);
237
    return;
238
}
239
 
240
/**
241
 * Cycle through available devices using the device enumerator devenum,
242
 * retrieve the device with type specified by devtype and return the
243
 * pointer to the object found in *pfilter.
244
 * If pfilter is NULL, list all device names.
245
 */
246
static int
247
dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
248
                    enum dshowDeviceType devtype, IBaseFilter **pfilter)
249
{
250
    struct dshow_ctx *ctx = avctx->priv_data;
251
    IBaseFilter *device_filter = NULL;
252
    IEnumMoniker *classenum = NULL;
253
    IMoniker *m = NULL;
254
    const char *device_name = ctx->device_name[devtype];
255
    int skip = (devtype == VideoDevice) ? ctx->video_device_number
256
                                        : ctx->audio_device_number;
257
    int r;
258
 
259
    const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
260
                                   &CLSID_AudioInputDeviceCategory };
261
    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
262
 
263
    r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
264
                                             (IEnumMoniker **) &classenum, 0);
265
    if (r != S_OK) {
266
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
267
               devtypename);
268
        return AVERROR(EIO);
269
    }
270
 
271
    while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
272
        IPropertyBag *bag = NULL;
273
        char *buf = NULL;
274
        VARIANT var;
275
 
276
        r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
277
        if (r != S_OK)
278
            goto fail1;
279
 
280
        var.vt = VT_BSTR;
281
        r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
282
        if (r != S_OK)
283
            goto fail1;
284
 
285
        buf = dup_wchar_to_utf8(var.bstrVal);
286
 
287
        if (pfilter) {
288
            if (strcmp(device_name, buf))
289
                goto fail1;
290
 
291
            if (!skip--)
292
                IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
293
        } else {
294
            av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
295
        }
296
 
297
fail1:
298
        if (buf)
299
            av_free(buf);
300
        if (bag)
301
            IPropertyBag_Release(bag);
302
        IMoniker_Release(m);
303
    }
304
 
305
    IEnumMoniker_Release(classenum);
306
 
307
    if (pfilter) {
308
        if (!device_filter) {
309
            av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
310
                   devtypename);
311
            return AVERROR(EIO);
312
        }
313
        *pfilter = device_filter;
314
    }
315
 
316
    return 0;
317
}
318
 
319
/**
320
 * Cycle through available formats using the specified pin,
321
 * try to set parameters specified through AVOptions and if successful
322
 * return 1 in *pformat_set.
323
 * If pformat_set is NULL, list all pin capabilities.
324
 */
325
static void
326
dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
327
                    IPin *pin, int *pformat_set)
328
{
329
    struct dshow_ctx *ctx = avctx->priv_data;
330
    IAMStreamConfig *config = NULL;
331
    AM_MEDIA_TYPE *type = NULL;
332
    int format_set = 0;
333
    void *caps = NULL;
334
    int i, n, size;
335
 
336
    if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
337
        return;
338
    if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
339
        goto end;
340
 
341
    caps = av_malloc(size);
342
    if (!caps)
343
        goto end;
344
 
345
    for (i = 0; i < n && !format_set; i++) {
346
        IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
347
 
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
#if DSHOWDEBUG
357
            ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
358
#endif
359
            if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
360
                VIDEOINFOHEADER *v = (void *) type->pbFormat;
361
                fr = &v->AvgTimePerFrame;
362
                bih = &v->bmiHeader;
363
            } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
364
                VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
365
                fr = &v->AvgTimePerFrame;
366
                bih = &v->bmiHeader;
367
            } else {
368
                goto next;
369
            }
370
            if (!pformat_set) {
371
                enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
372
                if (pix_fmt == AV_PIX_FMT_NONE) {
373
                    enum AVCodecID codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
374
                    AVCodec *codec = avcodec_find_decoder(codec_id);
375
                    if (codec_id == AV_CODEC_ID_NONE || !codec) {
376
                        av_log(avctx, AV_LOG_INFO, "  unknown compression type 0x%X", (int) bih->biCompression);
377
                    } else {
378
                        av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
379
                    }
380
                } else {
381
                    av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
382
                }
383
                av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
384
                       vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
385
                       1e7 / vcaps->MaxFrameInterval,
386
                       vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
387
                       1e7 / vcaps->MinFrameInterval);
388
                continue;
389
            }
390
            if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
391
                if (ctx->video_codec_id != ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression))
392
                    goto next;
393
            }
394
            if (ctx->pixel_format != AV_PIX_FMT_NONE &&
395
                ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
396
                goto next;
397
            }
398
            if (ctx->framerate) {
399
                int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
400
                                            /  ctx->requested_framerate.num;
401
                if (framerate > vcaps->MaxFrameInterval ||
402
                    framerate < vcaps->MinFrameInterval)
403
                    goto next;
404
                *fr = framerate;
405
            }
406
            if (ctx->requested_width && ctx->requested_height) {
407
                if (ctx->requested_width  > vcaps->MaxOutputSize.cx ||
408
                    ctx->requested_width  < vcaps->MinOutputSize.cx ||
409
                    ctx->requested_height > vcaps->MaxOutputSize.cy ||
410
                    ctx->requested_height < vcaps->MinOutputSize.cy)
411
                    goto next;
412
                bih->biWidth  = ctx->requested_width;
413
                bih->biHeight = ctx->requested_height;
414
            }
415
        } else {
416
            AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
417
            WAVEFORMATEX *fx;
418
#if DSHOWDEBUG
419
            ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
420
#endif
421
            if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
422
                fx = (void *) type->pbFormat;
423
            } else {
424
                goto next;
425
            }
426
            if (!pformat_set) {
427
                av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
428
                       acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
429
                       acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
430
                continue;
431
            }
432
            if (ctx->sample_rate) {
433
                if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
434
                    ctx->sample_rate < acaps->MinimumSampleFrequency)
435
                    goto next;
436
                fx->nSamplesPerSec = ctx->sample_rate;
437
            }
438
            if (ctx->sample_size) {
439
                if (ctx->sample_size > acaps->MaximumBitsPerSample ||
440
                    ctx->sample_size < acaps->MinimumBitsPerSample)
441
                    goto next;
442
                fx->wBitsPerSample = ctx->sample_size;
443
            }
444
            if (ctx->channels) {
445
                if (ctx->channels > acaps->MaximumChannels ||
446
                    ctx->channels < acaps->MinimumChannels)
447
                    goto next;
448
                fx->nChannels = ctx->channels;
449
            }
450
        }
451
        if (IAMStreamConfig_SetFormat(config, type) != S_OK)
452
            goto next;
453
        format_set = 1;
454
next:
455
        if (type->pbFormat)
456
            CoTaskMemFree(type->pbFormat);
457
        CoTaskMemFree(type);
458
    }
459
end:
460
    IAMStreamConfig_Release(config);
461
    if (caps)
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
 * Cycle through available pins using the device_filter device, of type
514
 * devtype, retrieve the first output pin and return the pointer to the
515
 * object found in *ppin.
516
 * If ppin is NULL, cycle through all pins listing audio/video capabilities.
517
 */
518
static int
519
dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
520
                 IBaseFilter *device_filter, IPin **ppin)
521
{
522
    struct dshow_ctx *ctx = avctx->priv_data;
523
    IEnumPins *pins = 0;
524
    IPin *device_pin = NULL;
525
    IPin *pin;
526
    int r;
527
 
528
    const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
529
    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
530
 
531
    int set_format = (devtype == VideoDevice && (ctx->framerate ||
532
                                                (ctx->requested_width && ctx->requested_height) ||
533
                                                 ctx->pixel_format != AV_PIX_FMT_NONE ||
534
                                                 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
535
                  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
536
    int format_set = 0;
537
 
538
    r = IBaseFilter_EnumPins(device_filter, &pins);
539
    if (r != S_OK) {
540
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
541
        return AVERROR(EIO);
542
    }
543
 
544
    if (!ppin) {
545
        av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
546
               devtypename);
547
    }
548
    while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
549
        IKsPropertySet *p = NULL;
550
        IEnumMediaTypes *types = NULL;
551
        PIN_INFO info = {0};
552
        AM_MEDIA_TYPE *type;
553
        GUID category;
554
        DWORD r2;
555
 
556
        IPin_QueryPinInfo(pin, &info);
557
        IBaseFilter_Release(info.pFilter);
558
 
559
        if (info.dir != PINDIR_OUTPUT)
560
            goto next;
561
        if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
562
            goto next;
563
        if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
564
                               NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
565
            goto next;
566
        if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
567
            goto next;
568
 
569
        if (!ppin) {
570
            char *buf = dup_wchar_to_utf8(info.achName);
571
            av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
572
            av_free(buf);
573
            dshow_cycle_formats(avctx, devtype, pin, NULL);
574
            goto next;
575
        }
576
        if (set_format) {
577
            dshow_cycle_formats(avctx, devtype, pin, &format_set);
578
            if (!format_set) {
579
                goto next;
580
            }
581
        }
582
        if (devtype == AudioDevice && ctx->audio_buffer_size) {
583
            if (dshow_set_audio_buffer_size(avctx, pin) < 0)
584
                goto next;
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
 
599
next:
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
 */
631
static int
632
dshow_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
 
648
static int
649
dshow_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
 
708
error:
709
    return ret;
710
}
711
 
712
static 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
 
722
static 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
 
732
static int
733
dshow_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->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
777
        if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
778
            av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
779
            codec->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
780
        }
781
        if (codec->pix_fmt == AV_PIX_FMT_NONE) {
782
            codec->codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
783
            if (codec->codec_id == AV_CODEC_ID_NONE) {
784
                av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
785
                                 "Please report type 0x%X.\n", (int) bih->biCompression);
786
                return AVERROR_PATCHWELCOME;
787
            }
788
            codec->bits_per_coded_sample = bih->biBitCount;
789
        } else {
790
            codec->codec_id = AV_CODEC_ID_RAWVIDEO;
791
            if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
792
                codec->bits_per_coded_sample = bih->biBitCount;
793
                codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
794
                if (codec->extradata) {
795
                    codec->extradata_size = 9;
796
                    memcpy(codec->extradata, "BottomUp", 9);
797
                }
798
            }
799
        }
800
    } else {
801
        WAVEFORMATEX *fx = NULL;
802
 
803
        if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
804
            fx = (void *) type.pbFormat;
805
        }
806
        if (!fx) {
807
            av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
808
            goto error;
809
        }
810
 
811
        codec->codec_type  = AVMEDIA_TYPE_AUDIO;
812
        codec->sample_fmt  = sample_fmt_bits_per_sample(fx->wBitsPerSample);
813
        codec->codec_id    = waveform_codec_id(codec->sample_fmt);
814
        codec->sample_rate = fx->nSamplesPerSec;
815
        codec->channels    = fx->nChannels;
816
    }
817
 
818
    avpriv_set_pts_info(st, 64, 1, 10000000);
819
 
820
    ret = 0;
821
 
822
error:
823
    return ret;
824
}
825
 
826
static int parse_device_name(AVFormatContext *avctx)
827
{
828
    struct dshow_ctx *ctx = avctx->priv_data;
829
    char **device_name = ctx->device_name;
830
    char *name = av_strdup(avctx->filename);
831
    char *tmp = name;
832
    int ret = 1;
833
    char *type;
834
 
835
    while ((type = strtok(tmp, "="))) {
836
        char *token = strtok(NULL, ":");
837
        tmp = NULL;
838
 
839
        if        (!strcmp(type, "video")) {
840
            device_name[0] = token;
841
        } else if (!strcmp(type, "audio")) {
842
            device_name[1] = token;
843
        } else {
844
            device_name[0] = NULL;
845
            device_name[1] = NULL;
846
            break;
847
        }
848
    }
849
 
850
    if (!device_name[0] && !device_name[1]) {
851
        ret = 0;
852
    } else {
853
        if (device_name[0])
854
            device_name[0] = av_strdup(device_name[0]);
855
        if (device_name[1])
856
            device_name[1] = av_strdup(device_name[1]);
857
    }
858
 
859
    av_free(name);
860
    return ret;
861
}
862
 
863
static int dshow_read_header(AVFormatContext *avctx)
864
{
865
    struct dshow_ctx *ctx = avctx->priv_data;
866
    IGraphBuilder *graph = NULL;
867
    ICreateDevEnum *devenum = NULL;
868
    IMediaControl *control = NULL;
869
    IMediaEvent *media_event = NULL;
870
    HANDLE media_event_handle;
871
    HANDLE proc;
872
    int ret = AVERROR(EIO);
873
    int r;
874
 
875
    CoInitialize(0);
876
 
877
    if (!ctx->list_devices && !parse_device_name(avctx)) {
878
        av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
879
        goto error;
880
    }
881
 
882
    ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
883
                                                : AV_CODEC_ID_RAWVIDEO;
884
    if (ctx->pixel_format != AV_PIX_FMT_NONE) {
885
        if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
886
            av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
887
                              "video codec is not set or set to rawvideo\n");
888
            ret = AVERROR(EINVAL);
889
            goto error;
890
        }
891
    }
892
    if (ctx->framerate) {
893
        r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
894
        if (r < 0) {
895
            av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
896
            goto error;
897
        }
898
    }
899
 
900
    r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
901
                         &IID_IGraphBuilder, (void **) &graph);
902
    if (r != S_OK) {
903
        av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
904
        goto error;
905
    }
906
    ctx->graph = graph;
907
 
908
    r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
909
                         &IID_ICreateDevEnum, (void **) &devenum);
910
    if (r != S_OK) {
911
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
912
        goto error;
913
    }
914
 
915
    if (ctx->list_devices) {
916
        av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
917
        dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
918
        av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
919
        dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
920
        ret = AVERROR_EXIT;
921
        goto error;
922
    }
923
    if (ctx->list_options) {
924
        if (ctx->device_name[VideoDevice])
925
            dshow_list_device_options(avctx, devenum, VideoDevice);
926
        if (ctx->device_name[AudioDevice])
927
            dshow_list_device_options(avctx, devenum, AudioDevice);
928
        ret = AVERROR_EXIT;
929
        goto error;
930
    }
931
 
932
    if (ctx->device_name[VideoDevice]) {
933
        if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 ||
934
            (r = dshow_add_device(avctx, VideoDevice)) < 0) {
935
            ret = r;
936
            goto error;
937
        }
938
    }
939
    if (ctx->device_name[AudioDevice]) {
940
        if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 ||
941
            (r = dshow_add_device(avctx, AudioDevice)) < 0) {
942
            ret = r;
943
            goto error;
944
        }
945
    }
946
 
947
    ctx->mutex = CreateMutex(NULL, 0, NULL);
948
    if (!ctx->mutex) {
949
        av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
950
        goto error;
951
    }
952
    ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
953
    if (!ctx->event[1]) {
954
        av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
955
        goto error;
956
    }
957
 
958
    r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
959
    if (r != S_OK) {
960
        av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
961
        goto error;
962
    }
963
    ctx->control = control;
964
 
965
    r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
966
    if (r != S_OK) {
967
        av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
968
        goto error;
969
    }
970
    ctx->media_event = media_event;
971
 
972
    r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
973
    if (r != S_OK) {
974
        av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
975
        goto error;
976
    }
977
    proc = GetCurrentProcess();
978
    r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
979
                        0, 0, DUPLICATE_SAME_ACCESS);
980
    if (!r) {
981
        av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
982
        goto error;
983
    }
984
 
985
    r = IMediaControl_Run(control);
986
    if (r == S_FALSE) {
987
        OAFilterState pfs;
988
        r = IMediaControl_GetState(control, 0, &pfs);
989
    }
990
    if (r != S_OK) {
991
        av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
992
        goto error;
993
    }
994
 
995
    ret = 0;
996
 
997
error:
998
 
999
    if (devenum)
1000
        ICreateDevEnum_Release(devenum);
1001
 
1002
    if (ret < 0)
1003
        dshow_read_close(avctx);
1004
 
1005
    return ret;
1006
}
1007
 
1008
/**
1009
 * Checks media events from DirectShow and returns -1 on error or EOF. Also
1010
 * purges all events that might be in the event queue to stop the trigger
1011
 * of event notification.
1012
 */
1013
static int dshow_check_event_queue(IMediaEvent *media_event)
1014
{
1015
    LONG_PTR p1, p2;
1016
    long code;
1017
    int ret = 0;
1018
 
1019
    while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1020
        if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1021
            ret = -1;
1022
        IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1023
    }
1024
 
1025
    return ret;
1026
}
1027
 
1028
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
1029
{
1030
    struct dshow_ctx *ctx = s->priv_data;
1031
    AVPacketList *pktl = NULL;
1032
 
1033
    while (!ctx->eof && !pktl) {
1034
        WaitForSingleObject(ctx->mutex, INFINITE);
1035
        pktl = ctx->pktl;
1036
        if (pktl) {
1037
            *pkt = pktl->pkt;
1038
            ctx->pktl = ctx->pktl->next;
1039
            av_free(pktl);
1040
            ctx->curbufsize -= pkt->size;
1041
        }
1042
        ResetEvent(ctx->event[1]);
1043
        ReleaseMutex(ctx->mutex);
1044
        if (!pktl) {
1045
            if (dshow_check_event_queue(ctx->media_event) < 0) {
1046
                ctx->eof = 1;
1047
            } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1048
                return AVERROR(EAGAIN);
1049
            } else {
1050
                WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1051
            }
1052
        }
1053
    }
1054
 
1055
    return ctx->eof ? AVERROR(EIO) : pkt->size;
1056
}
1057
 
1058
#define OFFSET(x) offsetof(struct dshow_ctx, x)
1059
#define DEC AV_OPT_FLAG_DECODING_PARAM
1060
static const AVOption options[] = {
1061
    { "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 },
1062
    { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1, DEC },
1063
    { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1064
    { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1065
    { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1066
    { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1067
    { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" },
1068
    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" },
1069
    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" },
1070
    { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" },
1071
    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" },
1072
    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" },
1073
    { "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 },
1074
    { "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 },
1075
    { "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 },
1076
    { NULL },
1077
};
1078
 
1079
static const AVClass dshow_class = {
1080
    .class_name = "dshow indev",
1081
    .item_name  = av_default_item_name,
1082
    .option     = options,
1083
    .version    = LIBAVUTIL_VERSION_INT,
1084
};
1085
 
1086
AVInputFormat ff_dshow_demuxer = {
1087
    .name           = "dshow",
1088
    .long_name      = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1089
    .priv_data_size = sizeof(struct dshow_ctx),
1090
    .read_header    = dshow_read_header,
1091
    .read_packet    = dshow_read_packet,
1092
    .read_close     = dshow_read_close,
1093
    .flags          = AVFMT_NOFILE,
1094
    .priv_class     = &dshow_class,
1095
};