FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dshow.c
Go to the documentation of this file.
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];
39 
43 
44  IBaseFilter *device_filter[2];
45  IPin *device_pin[2];
48 
50  HANDLE event[2]; /* event[0] is set by DirectShow
51  * event[1] is set by callback() */
53 
54  int eof;
55 
56  int64_t curbufsize;
57  unsigned int video_frame_num;
58 
59  IMediaControl *control;
60  IMediaEvent *media_event;
61 
64  char *framerate;
65 
69 
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
100 {
101  struct dshow_ctx *ctx = s->priv_data;
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])
132  if (ctx->capture_pin[AudioDevice])
134  if (ctx->capture_filter[VideoDevice])
136  if (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 
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
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
350 #endif
351 
352  if (devtype == VideoDevice) {
353  VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
354  BITMAPINFOHEADER *bih;
355  int64_t *fr;
356 #if DSHOWDEBUG
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
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
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
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 ||
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, &AMPROPSETID_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) {
718  default: return AV_CODEC_ID_NONE; /* Should never happen. */
719  }
720 }
721 
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
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;
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 {
791  if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
792  codec->bits_per_coded_sample = bih->biBitCount;
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 
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 
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 
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
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) {
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 
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 
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 };