]> git.sesse.net Git - ffmpeg/blob - libavdevice/dshow.c
Merge commit 'f593628e5868e52a46de666767896c6afcebdae4'
[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 "libavformat/timefilter.h"
23
24 #include "avdevice.h"
25 #include "dshow.h"
26
27 struct dshow_ctx {
28     IGraphBuilder *graph;
29
30     char *device_name[2];
31
32     IBaseFilter *device_filter[2];
33     IPin        *device_pin[2];
34     libAVFilter *capture_filter[2];
35     libAVPin    *capture_pin[2];
36
37     HANDLE mutex;
38     HANDLE event;
39     AVPacketList *pktl;
40
41     unsigned int curbufsize;
42     unsigned int video_frame_num;
43
44     IMediaControl *control;
45
46     TimeFilter *timefilter;
47 };
48
49 static enum PixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
50 {
51     switch(biCompression) {
52     case MKTAG('U', 'Y', 'V', 'Y'):
53         return PIX_FMT_UYVY422;
54     case MKTAG('Y', 'U', 'Y', '2'):
55         return PIX_FMT_YUYV422;
56     case MKTAG('I', '4', '2', '0'):
57         return PIX_FMT_YUV420P;
58     case BI_RGB:
59         switch(biBitCount) { /* 1-8 are untested */
60             case 1:
61                 return PIX_FMT_MONOWHITE;
62             case 4:
63                 return PIX_FMT_RGB4;
64             case 8:
65                 return PIX_FMT_RGB8;
66             case 16:
67                 return PIX_FMT_RGB555;
68             case 24:
69                 return PIX_FMT_BGR24;
70             case 32:
71                 return PIX_FMT_RGB32;
72         }
73     }
74     return PIX_FMT_NONE;
75 }
76
77 static enum CodecID dshow_codecid(DWORD biCompression)
78 {
79     switch(biCompression) {
80     case MKTAG('d', 'v', 's', 'd'):
81         return CODEC_ID_DVVIDEO;
82     case MKTAG('M', 'J', 'P', 'G'):
83     case MKTAG('m', 'j', 'p', 'g'):
84         return CODEC_ID_MJPEG;
85     }
86     return CODEC_ID_NONE;
87 }
88
89 static int
90 dshow_read_close(AVFormatContext *s)
91 {
92     struct dshow_ctx *ctx = s->priv_data;
93     AVPacketList *pktl;
94
95     if (ctx->control) {
96         IMediaControl_Stop(ctx->control);
97         IMediaControl_Release(ctx->control);
98     }
99     if (ctx->graph)
100         IGraphBuilder_Release(ctx->graph);
101
102     /* FIXME remove filters from graph */
103     /* FIXME disconnect pins */
104     if (ctx->capture_pin[VideoDevice])
105         libAVPin_Release(ctx->capture_pin[VideoDevice]);
106     if (ctx->capture_pin[AudioDevice])
107         libAVPin_Release(ctx->capture_pin[AudioDevice]);
108     if (ctx->capture_filter[VideoDevice])
109         libAVFilter_Release(ctx->capture_filter[VideoDevice]);
110     if (ctx->capture_filter[AudioDevice])
111         libAVFilter_Release(ctx->capture_filter[AudioDevice]);
112
113     if (ctx->device_pin[VideoDevice])
114         IPin_Release(ctx->device_pin[VideoDevice]);
115     if (ctx->device_pin[AudioDevice])
116         IPin_Release(ctx->device_pin[AudioDevice]);
117     if (ctx->device_filter[VideoDevice])
118         IBaseFilter_Release(ctx->device_filter[VideoDevice]);
119     if (ctx->device_filter[AudioDevice])
120         IBaseFilter_Release(ctx->device_filter[AudioDevice]);
121
122     if (ctx->device_name[0])
123         av_free(ctx->device_name[0]);
124     if (ctx->device_name[1])
125         av_free(ctx->device_name[1]);
126
127     if(ctx->mutex)
128         CloseHandle(ctx->mutex);
129     if(ctx->event)
130         CloseHandle(ctx->event);
131
132     pktl = ctx->pktl;
133     while (pktl) {
134         AVPacketList *next = pktl->next;
135         av_destruct_packet(&pktl->pkt);
136         av_free(pktl);
137         pktl = next;
138     }
139
140     return 0;
141 }
142
143 static char *dup_wchar_to_utf8(wchar_t *w)
144 {
145     char *s = NULL;
146     int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
147     s = av_malloc(l);
148     if (s)
149         WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
150     return s;
151 }
152
153 static int shall_we_drop(AVFormatContext *s)
154 {
155     struct dshow_ctx *ctx = s->priv_data;
156     const uint8_t dropscore[] = {62, 75, 87, 100};
157     const int ndropscores = FF_ARRAY_ELEMS(dropscore);
158     unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer;
159
160     if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
161         av_log(s, AV_LOG_ERROR,
162               "real-time buffer %d%% full! frame dropped!\n", buffer_fullness);
163         return 1;
164     }
165
166     return 0;
167 }
168
169 static void
170 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
171 {
172     AVFormatContext *s = priv_data;
173     struct dshow_ctx *ctx = s->priv_data;
174     AVPacketList **ppktl, *pktl_next;
175
176 //    dump_videohdr(s, vdhdr);
177
178     if(shall_we_drop(s))
179         return;
180
181     WaitForSingleObject(ctx->mutex, INFINITE);
182
183     pktl_next = av_mallocz(sizeof(AVPacketList));
184     if(!pktl_next)
185         goto fail;
186
187     if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
188         av_free(pktl_next);
189         goto fail;
190     }
191
192     pktl_next->pkt.stream_index = index;
193     pktl_next->pkt.pts = time;
194     memcpy(pktl_next->pkt.data, buf, buf_size);
195
196     for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
197     *ppktl = pktl_next;
198
199     ctx->curbufsize += buf_size;
200
201     SetEvent(ctx->event);
202     ReleaseMutex(ctx->mutex);
203
204     return;
205 fail:
206     ReleaseMutex(ctx->mutex);
207     return;
208 }
209
210 static int
211 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
212                   enum dshowDeviceType devtype)
213 {
214     struct dshow_ctx *ctx = avctx->priv_data;
215     IBaseFilter *device_filter = NULL;
216     IEnumMoniker *classenum = NULL;
217     IGraphBuilder *graph = ctx->graph;
218     IEnumPins *pins = 0;
219     IMoniker *m = NULL;
220     IPin *device_pin = NULL;
221     libAVPin *capture_pin = NULL;
222     libAVFilter *capture_filter = NULL;
223     const char *device_name = ctx->device_name[devtype];
224     int ret = AVERROR(EIO);
225     IPin *pin;
226     int r, i;
227
228     const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
229                                    &CLSID_AudioInputDeviceCategory };
230     const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
231     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
232     const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
233
234     r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
235                                              (IEnumMoniker **) &classenum, 0);
236     if (r != S_OK) {
237         av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
238                devtypename);
239         goto error;
240     }
241
242     while (IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK && !device_filter) {
243         IPropertyBag *bag = NULL;
244         char *buf = NULL;
245         VARIANT var;
246
247         r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
248         if (r != S_OK)
249             goto fail1;
250
251         var.vt = VT_BSTR;
252         r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
253         if (r != S_OK)
254             goto fail1;
255
256         buf = dup_wchar_to_utf8(var.bstrVal);
257
258         if (strcmp(device_name, buf))
259             goto fail1;
260
261         IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
262
263 fail1:
264         if (buf)
265             av_free(buf);
266         if (bag)
267             IPropertyBag_Release(bag);
268         IMoniker_Release(m);
269     }
270
271     if (!device_filter) {
272         av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
273                devtypename);
274         goto error;
275     }
276     ctx->device_filter [devtype] = device_filter;
277
278     r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
279     if (r != S_OK) {
280         av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
281         goto error;
282     }
283
284     r = IBaseFilter_EnumPins(device_filter, &pins);
285     if (r != S_OK) {
286         av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
287         goto error;
288     }
289
290     i = 0;
291     while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK && !device_pin) {
292         IKsPropertySet *p = NULL;
293         IEnumMediaTypes *types;
294         PIN_INFO info = {0};
295         AM_MEDIA_TYPE *type;
296         GUID category;
297         DWORD r2;
298
299         IPin_QueryPinInfo(pin, &info);
300         IBaseFilter_Release(info.pFilter);
301
302         if (info.dir != PINDIR_OUTPUT)
303             goto next;
304         if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
305             goto next;
306         if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
307                                NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
308             goto next;
309         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
310             goto next;
311
312         if (IPin_EnumMediaTypes(pin, &types) != S_OK)
313             goto next;
314
315         IEnumMediaTypes_Reset(types);
316         while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK && !device_pin) {
317             if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
318                 device_pin = pin;
319                 goto next;
320             }
321             CoTaskMemFree(type);
322         }
323
324 next:
325         if (types)
326             IEnumMediaTypes_Release(types);
327         if (p)
328             IKsPropertySet_Release(p);
329         if (device_pin != pin)
330             IPin_Release(pin);
331     }
332
333     if (!device_pin) {
334         av_log(avctx, AV_LOG_ERROR,
335                "Could not find output pin from %s capture device.\n", devtypename);
336         goto error;
337     }
338     ctx->device_pin[devtype] = device_pin;
339
340     capture_filter = libAVFilter_Create(avctx, callback, devtype);
341     if (!capture_filter) {
342         av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
343         goto error;
344     }
345     ctx->capture_filter[devtype] = capture_filter;
346
347     r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
348                                 filter_name[devtype]);
349     if (r != S_OK) {
350         av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
351         goto error;
352     }
353
354     libAVPin_AddRef(capture_filter->pin);
355     capture_pin = capture_filter->pin;
356     ctx->capture_pin[devtype] = capture_pin;
357
358     r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
359     if (r != S_OK) {
360         av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
361         goto error;
362     }
363
364     ret = 0;
365
366 error:
367     if (pins)
368         IEnumPins_Release(pins);
369     if (classenum)
370         IEnumMoniker_Release(classenum);
371
372     return ret;
373 }
374
375 static enum CodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
376 {
377     switch (sample_fmt) {
378     case AV_SAMPLE_FMT_U8:  return CODEC_ID_PCM_U8;
379     case AV_SAMPLE_FMT_S16: return CODEC_ID_PCM_S16LE;
380     case AV_SAMPLE_FMT_S32: return CODEC_ID_PCM_S32LE;
381     default:                return CODEC_ID_NONE; /* Should never happen. */
382     }
383 }
384
385 static enum SampleFormat sample_fmt_bits_per_sample(int bits)
386 {
387     switch (bits) {
388     case 8:  return AV_SAMPLE_FMT_U8;
389     case 16: return AV_SAMPLE_FMT_S16;
390     case 32: return AV_SAMPLE_FMT_S32;
391     default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
392     }
393 }
394
395 static int
396 dshow_add_device(AVFormatContext *avctx, AVFormatParameters *ap,
397                  enum dshowDeviceType devtype)
398 {
399     struct dshow_ctx *ctx = avctx->priv_data;
400     AM_MEDIA_TYPE type;
401     AVCodecContext *codec;
402     AVStream *st;
403     int ret = AVERROR(EIO);
404
405     st = av_new_stream(avctx, devtype);
406     if (!st) {
407         ret = AVERROR(ENOMEM);
408         goto error;
409     }
410
411     ctx->capture_filter[devtype]->stream_index = st->index;
412
413     libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
414
415     codec = st->codec;
416     if (devtype == VideoDevice) {
417         BITMAPINFOHEADER *bih = NULL;
418
419         if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
420             VIDEOINFOHEADER *v = (void *) type.pbFormat;
421             bih = &v->bmiHeader;
422         } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
423             VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
424             bih = &v->bmiHeader;
425         }
426         if (!bih) {
427             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
428             goto error;
429         }
430
431         codec->time_base  = ap->time_base;
432         codec->codec_type = AVMEDIA_TYPE_VIDEO;
433         codec->width      = bih->biWidth;
434         codec->height     = bih->biHeight;
435         codec->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
436         if (codec->pix_fmt == PIX_FMT_NONE) {
437             codec->codec_id = dshow_codecid(bih->biCompression);
438             if (codec->codec_id == CODEC_ID_NONE) {
439                 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
440                                  "Please report verbose (-v 9) debug information.\n");
441                 dshow_read_close(avctx);
442                 return AVERROR_PATCHWELCOME;
443             }
444             codec->bits_per_coded_sample = bih->biBitCount;
445         } else {
446             codec->codec_id = CODEC_ID_RAWVIDEO;
447             if (bih->biCompression == BI_RGB) {
448                 codec->bits_per_coded_sample = bih->biBitCount;
449                 codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
450                 if (codec->extradata) {
451                     codec->extradata_size = 9;
452                     memcpy(codec->extradata, "BottomUp", 9);
453                 }
454             }
455         }
456     } else {
457         WAVEFORMATEX *fx = NULL;
458
459         if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
460             fx = (void *) type.pbFormat;
461         }
462         if (!fx) {
463             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
464             goto error;
465         }
466
467         codec->codec_type  = AVMEDIA_TYPE_AUDIO;
468         codec->sample_fmt  = sample_fmt_bits_per_sample(fx->wBitsPerSample);
469         codec->codec_id    = waveform_codec_id(codec->sample_fmt);
470         codec->sample_rate = fx->nSamplesPerSec;
471         codec->channels    = fx->nChannels;
472     }
473
474     av_set_pts_info(st, 64, 1, 10000000);
475
476     ret = 0;
477
478 error:
479     return ret;
480 }
481
482 static int parse_device_name(AVFormatContext *avctx)
483 {
484     struct dshow_ctx *ctx = avctx->priv_data;
485     char **device_name = ctx->device_name;
486     char *name = av_strdup(avctx->filename);
487     char *tmp = name;
488     int ret = 1;
489     char *type;
490
491     while ((type = strtok(tmp, "="))) {
492         char *token = strtok(NULL, ":");
493         tmp = NULL;
494
495         if        (!strcmp(type, "video")) {
496             device_name[0] = token;
497         } else if (!strcmp(type, "audio")) {
498             device_name[1] = token;
499         } else {
500             device_name[0] = NULL;
501             device_name[1] = NULL;
502             break;
503         }
504     }
505
506     if (!device_name[0] && !device_name[1]) {
507         ret = 0;
508     } else {
509         if (device_name[0])
510             device_name[0] = av_strdup(device_name[0]);
511         if (device_name[1])
512             device_name[1] = av_strdup(device_name[1]);
513     }
514
515     av_free(name);
516     return ret;
517 }
518
519 static int dshow_read_header(AVFormatContext *avctx, AVFormatParameters *ap)
520 {
521     struct dshow_ctx *ctx = avctx->priv_data;
522     IGraphBuilder *graph = NULL;
523     ICreateDevEnum *devenum = NULL;
524     IMediaControl *control = NULL;
525     int ret = AVERROR(EIO);
526     int r;
527
528     if (!parse_device_name(avctx)) {
529         av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
530         goto error;
531     }
532
533     CoInitialize(0);
534
535     r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
536                          &IID_IGraphBuilder, (void **) &graph);
537     if (r != S_OK) {
538         av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
539         goto error;
540     }
541     ctx->graph = graph;
542
543     r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
544                          &IID_ICreateDevEnum, (void **) &devenum);
545     if (r != S_OK) {
546         av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
547         goto error;
548     }
549
550     if (ctx->device_name[VideoDevice]) {
551         ret = dshow_open_device(avctx, devenum, VideoDevice);
552         if (ret < 0)
553             goto error;
554         ret = dshow_add_device(avctx, ap, VideoDevice);
555         if (ret < 0)
556             goto error;
557     }
558     if (ctx->device_name[AudioDevice]) {
559         ret = dshow_open_device(avctx, devenum, AudioDevice);
560         if (ret < 0)
561             goto error;
562         ret = dshow_add_device(avctx, ap, AudioDevice);
563         if (ret < 0)
564             goto error;
565     }
566
567     ctx->mutex = CreateMutex(NULL, 0, NULL);
568     if (!ctx->mutex) {
569         av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
570         goto error;
571     }
572     ctx->event = CreateEvent(NULL, 1, 0, NULL);
573     if (!ctx->event) {
574         av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
575         goto error;
576     }
577
578     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
579     if (r != S_OK) {
580         av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
581         goto error;
582     }
583     ctx->control = control;
584
585     r = IMediaControl_Run(control);
586     if (r == S_FALSE) {
587         OAFilterState pfs;
588         r = IMediaControl_GetState(control, 0, &pfs);
589     }
590     if (r != S_OK) {
591         av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
592         goto error;
593     }
594
595     ret = 0;
596
597 error:
598
599     if (ret < 0)
600         dshow_read_close(avctx);
601
602     if (devenum)
603         ICreateDevEnum_Release(devenum);
604
605     return ret;
606 }
607
608 static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
609 {
610     struct dshow_ctx *ctx = s->priv_data;
611     AVPacketList *pktl = NULL;
612
613     while (!pktl) {
614         WaitForSingleObject(ctx->mutex, INFINITE);
615         pktl = ctx->pktl;
616         if (ctx->pktl) {
617             *pkt = ctx->pktl->pkt;
618             ctx->pktl = ctx->pktl->next;
619             av_free(pktl);
620         }
621         ResetEvent(ctx->event);
622         ReleaseMutex(ctx->mutex);
623         if (!pktl) {
624             if (s->flags & AVFMT_FLAG_NONBLOCK) {
625                 return AVERROR(EAGAIN);
626             } else {
627                 WaitForSingleObject(ctx->event, INFINITE);
628             }
629         }
630     }
631
632     ctx->curbufsize -= pkt->size;
633
634     return pkt->size;
635 }
636
637 AVInputFormat ff_dshow_demuxer = {
638     "dshow",
639     NULL_IF_CONFIG_SMALL("DirectShow capture"),
640     sizeof(struct dshow_ctx),
641     NULL,
642     dshow_read_header,
643     dshow_read_packet,
644     dshow_read_close,
645     .flags = AVFMT_NOFILE,
646 };