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