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