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(avpriv_get_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  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
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 = av_codec_get_id(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 != av_codec_get_id(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  av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
585  }
586  }
587 
588  if (IPin_EnumMediaTypes(pin, &types) != S_OK)
589  goto next;
590 
591  IEnumMediaTypes_Reset(types);
592  while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
593  if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
594  device_pin = pin;
595  goto next;
596  }
597  CoTaskMemFree(type);
598  }
599 
600 next:
601  if (types)
602  IEnumMediaTypes_Release(types);
603  if (p)
604  IKsPropertySet_Release(p);
605  if (device_pin != pin)
606  IPin_Release(pin);
607  }
608 
609  IEnumPins_Release(pins);
610 
611  if (ppin) {
612  if (set_format && !format_set) {
613  av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
614  return AVERROR(EIO);
615  }
616  if (!device_pin) {
617  av_log(avctx, AV_LOG_ERROR,
618  "Could not find output pin from %s capture device.\n", devtypename);
619  return AVERROR(EIO);
620  }
621  *ppin = device_pin;
622  }
623 
624  return 0;
625 }
626 
627 /**
628  * List options for device with type devtype.
629  *
630  * @param devenum device enumerator used for accessing the device
631  */
632 static int
633 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
634  enum dshowDeviceType devtype)
635 {
636  struct dshow_ctx *ctx = avctx->priv_data;
637  IBaseFilter *device_filter = NULL;
638  int r;
639 
640  if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0)
641  return r;
642  ctx->device_filter[devtype] = device_filter;
643  if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0)
644  return r;
645 
646  return 0;
647 }
648 
649 static int
650 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
651  enum dshowDeviceType devtype)
652 {
653  struct dshow_ctx *ctx = avctx->priv_data;
654  IBaseFilter *device_filter = NULL;
655  IGraphBuilder *graph = ctx->graph;
656  IPin *device_pin = NULL;
657  libAVPin *capture_pin = NULL;
658  libAVFilter *capture_filter = NULL;
659  int ret = AVERROR(EIO);
660  int r;
661 
662  const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
663 
664  if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) {
665  ret = r;
666  goto error;
667  }
668 
669  ctx->device_filter [devtype] = device_filter;
670 
671  r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
672  if (r != S_OK) {
673  av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
674  goto error;
675  }
676 
677  if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
678  ret = r;
679  goto error;
680  }
681  ctx->device_pin[devtype] = device_pin;
682 
683  capture_filter = libAVFilter_Create(avctx, callback, devtype);
684  if (!capture_filter) {
685  av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
686  goto error;
687  }
688  ctx->capture_filter[devtype] = capture_filter;
689 
690  r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
691  filter_name[devtype]);
692  if (r != S_OK) {
693  av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
694  goto error;
695  }
696 
697  libAVPin_AddRef(capture_filter->pin);
698  capture_pin = capture_filter->pin;
699  ctx->capture_pin[devtype] = capture_pin;
700 
701  r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
702  if (r != S_OK) {
703  av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
704  goto error;
705  }
706 
707  ret = 0;
708 
709 error:
710  return ret;
711 }
712 
713 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
714 {
715  switch (sample_fmt) {
719  default: return AV_CODEC_ID_NONE; /* Should never happen. */
720  }
721 }
722 
724 {
725  switch (bits) {
726  case 8: return AV_SAMPLE_FMT_U8;
727  case 16: return AV_SAMPLE_FMT_S16;
728  case 32: return AV_SAMPLE_FMT_S32;
729  default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
730  }
731 }
732 
733 static int
735  enum dshowDeviceType devtype)
736 {
737  struct dshow_ctx *ctx = avctx->priv_data;
738  AM_MEDIA_TYPE type;
739  AVCodecContext *codec;
740  AVStream *st;
741  int ret = AVERROR(EIO);
742 
743  st = avformat_new_stream(avctx, NULL);
744  if (!st) {
745  ret = AVERROR(ENOMEM);
746  goto error;
747  }
748  st->id = devtype;
749 
750  ctx->capture_filter[devtype]->stream_index = st->index;
751 
752  libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
753 
754  codec = st->codec;
755  if (devtype == VideoDevice) {
756  BITMAPINFOHEADER *bih = NULL;
757  AVRational time_base;
758 
759  if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
760  VIDEOINFOHEADER *v = (void *) type.pbFormat;
761  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
762  bih = &v->bmiHeader;
763  } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
764  VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
765  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
766  bih = &v->bmiHeader;
767  }
768  if (!bih) {
769  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
770  goto error;
771  }
772 
773  codec->time_base = time_base;
775  codec->width = bih->biWidth;
776  codec->height = bih->biHeight;
777  codec->codec_tag = bih->biCompression;
778  codec->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
779  if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
780  av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
781  codec->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
782  }
783  if (codec->pix_fmt == AV_PIX_FMT_NONE) {
784  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
785  codec->codec_id = av_codec_get_id(tags, bih->biCompression);
786  if (codec->codec_id == AV_CODEC_ID_NONE) {
787  av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
788  "Please report type 0x%X.\n", (int) bih->biCompression);
789  return AVERROR_PATCHWELCOME;
790  }
791  codec->bits_per_coded_sample = bih->biBitCount;
792  } else {
794  if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
795  codec->bits_per_coded_sample = bih->biBitCount;
797  if (codec->extradata) {
798  codec->extradata_size = 9;
799  memcpy(codec->extradata, "BottomUp", 9);
800  }
801  }
802  }
803  } else {
804  WAVEFORMATEX *fx = NULL;
805 
806  if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
807  fx = (void *) type.pbFormat;
808  }
809  if (!fx) {
810  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
811  goto error;
812  }
813 
815  codec->sample_fmt = sample_fmt_bits_per_sample(fx->wBitsPerSample);
816  codec->codec_id = waveform_codec_id(codec->sample_fmt);
817  codec->sample_rate = fx->nSamplesPerSec;
818  codec->channels = fx->nChannels;
819  }
820 
821  avpriv_set_pts_info(st, 64, 1, 10000000);
822 
823  ret = 0;
824 
825 error:
826  return ret;
827 }
828 
830 {
831  struct dshow_ctx *ctx = avctx->priv_data;
832  char **device_name = ctx->device_name;
833  char *name = av_strdup(avctx->filename);
834  char *tmp = name;
835  int ret = 1;
836  char *type;
837 
838  while ((type = strtok(tmp, "="))) {
839  char *token = strtok(NULL, ":");
840  tmp = NULL;
841 
842  if (!strcmp(type, "video")) {
843  device_name[0] = token;
844  } else if (!strcmp(type, "audio")) {
845  device_name[1] = token;
846  } else {
847  device_name[0] = NULL;
848  device_name[1] = NULL;
849  break;
850  }
851  }
852 
853  if (!device_name[0] && !device_name[1]) {
854  ret = 0;
855  } else {
856  if (device_name[0])
857  device_name[0] = av_strdup(device_name[0]);
858  if (device_name[1])
859  device_name[1] = av_strdup(device_name[1]);
860  }
861 
862  av_free(name);
863  return ret;
864 }
865 
867 {
868  struct dshow_ctx *ctx = avctx->priv_data;
869  IGraphBuilder *graph = NULL;
870  ICreateDevEnum *devenum = NULL;
871  IMediaControl *control = NULL;
872  IMediaEvent *media_event = NULL;
873  HANDLE media_event_handle;
874  HANDLE proc;
875  int ret = AVERROR(EIO);
876  int r;
877 
878  CoInitialize(0);
879 
880  if (!ctx->list_devices && !parse_device_name(avctx)) {
881  av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
882  goto error;
883  }
884 
885  ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
887  if (ctx->pixel_format != AV_PIX_FMT_NONE) {
888  if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
889  av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
890  "video codec is not set or set to rawvideo\n");
891  ret = AVERROR(EINVAL);
892  goto error;
893  }
894  }
895  if (ctx->framerate) {
897  if (r < 0) {
898  av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
899  goto error;
900  }
901  }
902 
903  r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
904  &IID_IGraphBuilder, (void **) &graph);
905  if (r != S_OK) {
906  av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
907  goto error;
908  }
909  ctx->graph = graph;
910 
911  r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
912  &IID_ICreateDevEnum, (void **) &devenum);
913  if (r != S_OK) {
914  av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
915  goto error;
916  }
917 
918  if (ctx->list_devices) {
919  av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
920  dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
921  av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
922  dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
923  ret = AVERROR_EXIT;
924  goto error;
925  }
926  if (ctx->list_options) {
927  if (ctx->device_name[VideoDevice])
928  dshow_list_device_options(avctx, devenum, VideoDevice);
929  if (ctx->device_name[AudioDevice])
930  dshow_list_device_options(avctx, devenum, AudioDevice);
931  ret = AVERROR_EXIT;
932  goto error;
933  }
934 
935  if (ctx->device_name[VideoDevice]) {
936  if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 ||
937  (r = dshow_add_device(avctx, VideoDevice)) < 0) {
938  ret = r;
939  goto error;
940  }
941  }
942  if (ctx->device_name[AudioDevice]) {
943  if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 ||
944  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
945  ret = r;
946  goto error;
947  }
948  }
949  ctx->curbufsize[0] = 0;
950  ctx->curbufsize[1] = 0;
951  ctx->mutex = CreateMutex(NULL, 0, NULL);
952  if (!ctx->mutex) {
953  av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
954  goto error;
955  }
956  ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
957  if (!ctx->event[1]) {
958  av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
959  goto error;
960  }
961 
962  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
963  if (r != S_OK) {
964  av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
965  goto error;
966  }
967  ctx->control = control;
968 
969  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
970  if (r != S_OK) {
971  av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
972  goto error;
973  }
974  ctx->media_event = media_event;
975 
976  r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
977  if (r != S_OK) {
978  av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
979  goto error;
980  }
981  proc = GetCurrentProcess();
982  r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
983  0, 0, DUPLICATE_SAME_ACCESS);
984  if (!r) {
985  av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
986  goto error;
987  }
988 
989  r = IMediaControl_Run(control);
990  if (r == S_FALSE) {
991  OAFilterState pfs;
992  r = IMediaControl_GetState(control, 0, &pfs);
993  }
994  if (r != S_OK) {
995  av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
996  goto error;
997  }
998 
999  ret = 0;
1000 
1001 error:
1002 
1003  if (devenum)
1004  ICreateDevEnum_Release(devenum);
1005 
1006  if (ret < 0)
1007  dshow_read_close(avctx);
1008 
1009  return ret;
1010 }
1011 
1012 /**
1013  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1014  * purges all events that might be in the event queue to stop the trigger
1015  * of event notification.
1016  */
1017 static int dshow_check_event_queue(IMediaEvent *media_event)
1018 {
1019  LONG_PTR p1, p2;
1020  long code;
1021  int ret = 0;
1022 
1023  while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1024  if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1025  ret = -1;
1026  IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1027  }
1028 
1029  return ret;
1030 }
1031 
1033 {
1034  struct dshow_ctx *ctx = s->priv_data;
1035  AVPacketList *pktl = NULL;
1036 
1037  while (!ctx->eof && !pktl) {
1038  WaitForSingleObject(ctx->mutex, INFINITE);
1039  pktl = ctx->pktl;
1040  if (pktl) {
1041  *pkt = pktl->pkt;
1042  ctx->pktl = ctx->pktl->next;
1043  av_free(pktl);
1044  ctx->curbufsize[pkt->stream_index] -= pkt->size;
1045  }
1046  ResetEvent(ctx->event[1]);
1047  ReleaseMutex(ctx->mutex);
1048  if (!pktl) {
1049  if (dshow_check_event_queue(ctx->media_event) < 0) {
1050  ctx->eof = 1;
1051  } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1052  return AVERROR(EAGAIN);
1053  } else {
1054  WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1055  }
1056  }
1057  }
1058 
1059  return ctx->eof ? AVERROR(EIO) : pkt->size;
1060 }
1061 
1062 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1063 #define DEC AV_OPT_FLAG_DECODING_PARAM
1064 static const AVOption options[] = {
1065  { "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 },
1066  { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1067  { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1068  { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1069  { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1070  { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1071  { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" },
1072  { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" },
1073  { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" },
1074  { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" },
1075  { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" },
1076  { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" },
1077  { "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 },
1078  { "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 },
1079  { "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 },
1080  { NULL },
1081 };
1082 
1083 static const AVClass dshow_class = {
1084  .class_name = "dshow indev",
1085  .item_name = av_default_item_name,
1086  .option = options,
1087  .version = LIBAVUTIL_VERSION_INT,
1089 };
1090 
1092  .name = "dshow",
1093  .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1094  .priv_data_size = sizeof(struct dshow_ctx),
1095  .read_header = dshow_read_header,
1096  .read_packet = dshow_read_packet,
1097  .read_close = dshow_read_close,
1098  .flags = AVFMT_NOFILE,
1099  .priv_class = &dshow_class,
1100 };