FFmpeg  4.0
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 "dshow_capture.h"
23 #include "libavutil/parseutils.h"
24 #include "libavutil/pixdesc.h"
25 #include "libavutil/opt.h"
26 #include "libavformat/internal.h"
27 #include "libavformat/riff.h"
28 #include "avdevice.h"
29 #include "libavcodec/raw.h"
30 #include "objidl.h"
31 #include "shlwapi.h"
32 
33 
34 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
35 {
36  switch(biCompression) {
37  case BI_BITFIELDS:
38  case BI_RGB:
39  switch(biBitCount) { /* 1-8 are untested */
40  case 1:
41  return AV_PIX_FMT_MONOWHITE;
42  case 4:
43  return AV_PIX_FMT_RGB4;
44  case 8:
45  return AV_PIX_FMT_RGB8;
46  case 16:
47  return AV_PIX_FMT_RGB555;
48  case 24:
49  return AV_PIX_FMT_BGR24;
50  case 32:
51  return AV_PIX_FMT_0RGB32;
52  }
53  }
54  return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression); // all others
55 }
56 
57 static int
59 {
60  struct dshow_ctx *ctx = s->priv_data;
62 
63  if (ctx->control) {
64  IMediaControl_Stop(ctx->control);
65  IMediaControl_Release(ctx->control);
66  }
67 
68  if (ctx->media_event)
69  IMediaEvent_Release(ctx->media_event);
70 
71  if (ctx->graph) {
72  IEnumFilters *fenum;
73  int r;
74  r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
75  if (r == S_OK) {
76  IBaseFilter *f;
77  IEnumFilters_Reset(fenum);
78  while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
79  if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
80  IEnumFilters_Reset(fenum); /* When a filter is removed,
81  * the list must be reset. */
82  IBaseFilter_Release(f);
83  }
84  IEnumFilters_Release(fenum);
85  }
86  IGraphBuilder_Release(ctx->graph);
87  }
88 
89  if (ctx->capture_pin[VideoDevice])
91  if (ctx->capture_pin[AudioDevice])
93  if (ctx->capture_filter[VideoDevice])
95  if (ctx->capture_filter[AudioDevice])
97 
98  if (ctx->device_pin[VideoDevice])
99  IPin_Release(ctx->device_pin[VideoDevice]);
100  if (ctx->device_pin[AudioDevice])
101  IPin_Release(ctx->device_pin[AudioDevice]);
102  if (ctx->device_filter[VideoDevice])
103  IBaseFilter_Release(ctx->device_filter[VideoDevice]);
104  if (ctx->device_filter[AudioDevice])
105  IBaseFilter_Release(ctx->device_filter[AudioDevice]);
106 
107  av_freep(&ctx->device_name[0]);
108  av_freep(&ctx->device_name[1]);
109  av_freep(&ctx->device_unique_name[0]);
110  av_freep(&ctx->device_unique_name[1]);
111 
112  if(ctx->mutex)
113  CloseHandle(ctx->mutex);
114  if(ctx->event[0])
115  CloseHandle(ctx->event[0]);
116  if(ctx->event[1])
117  CloseHandle(ctx->event[1]);
118 
119  pktl = ctx->pktl;
120  while (pktl) {
121  AVPacketList *next = pktl->next;
122  av_packet_unref(&pktl->pkt);
123  av_free(pktl);
124  pktl = next;
125  }
126 
127  CoUninitialize();
128 
129  return 0;
130 }
131 
132 static char *dup_wchar_to_utf8(wchar_t *w)
133 {
134  char *s = NULL;
135  int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
136  s = av_malloc(l);
137  if (s)
138  WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
139  return s;
140 }
141 
142 static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
143 {
144  struct dshow_ctx *ctx = s->priv_data;
145  static const uint8_t dropscore[] = {62, 75, 87, 100};
146  const int ndropscores = FF_ARRAY_ELEMS(dropscore);
147  unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
148  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
149 
150  if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
151  av_log(s, AV_LOG_ERROR,
152  "real-time buffer [%s] [%s input] too full or near too full (%d%% of size: %d [rtbufsize parameter])! frame dropped!\n",
153  ctx->device_name[devtype], devtypename, buffer_fullness, s->max_picture_buffer);
154  return 1;
155  }
156 
157  return 0;
158 }
159 
160 static void
161 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
162 {
163  AVFormatContext *s = priv_data;
164  struct dshow_ctx *ctx = s->priv_data;
165  AVPacketList **ppktl, *pktl_next;
166 
167 // dump_videohdr(s, vdhdr);
168 
169  WaitForSingleObject(ctx->mutex, INFINITE);
170 
171  if(shall_we_drop(s, index, devtype))
172  goto fail;
173 
174  pktl_next = av_mallocz(sizeof(AVPacketList));
175  if(!pktl_next)
176  goto fail;
177 
178  if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
179  av_free(pktl_next);
180  goto fail;
181  }
182 
183  pktl_next->pkt.stream_index = index;
184  pktl_next->pkt.pts = time;
185  memcpy(pktl_next->pkt.data, buf, buf_size);
186 
187  for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
188  *ppktl = pktl_next;
189  ctx->curbufsize[index] += buf_size;
190 
191  SetEvent(ctx->event[1]);
192  ReleaseMutex(ctx->mutex);
193 
194  return;
195 fail:
196  ReleaseMutex(ctx->mutex);
197  return;
198 }
199 
200 /**
201  * Cycle through available devices using the device enumerator devenum,
202  * retrieve the device with type specified by devtype and return the
203  * pointer to the object found in *pfilter.
204  * If pfilter is NULL, list all device names.
205  */
206 static int
207 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
208  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype,
209  IBaseFilter **pfilter, char **device_unique_name)
210 {
211  struct dshow_ctx *ctx = avctx->priv_data;
212  IBaseFilter *device_filter = NULL;
213  IEnumMoniker *classenum = NULL;
214  IMoniker *m = NULL;
215  const char *device_name = ctx->device_name[devtype];
216  int skip = (devtype == VideoDevice) ? ctx->video_device_number
217  : ctx->audio_device_number;
218  int r;
219 
220  const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
221  &CLSID_AudioInputDeviceCategory };
222  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
223  const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
224 
225  r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype],
226  (IEnumMoniker **) &classenum, 0);
227  if (r != S_OK) {
228  av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n",
229  devtypename);
230  return AVERROR(EIO);
231  }
232 
233  while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
234  IPropertyBag *bag = NULL;
235  char *friendly_name = NULL;
236  char *unique_name = NULL;
237  VARIANT var;
238  IBindCtx *bind_ctx = NULL;
239  LPOLESTR olestr = NULL;
240  LPMALLOC co_malloc = NULL;
241  int i;
242 
243  r = CoGetMalloc(1, &co_malloc);
244  if (r != S_OK)
245  goto fail1;
246  r = CreateBindCtx(0, &bind_ctx);
247  if (r != S_OK)
248  goto fail1;
249  /* GetDisplayname works for both video and audio, DevicePath doesn't */
250  r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr);
251  if (r != S_OK)
252  goto fail1;
253  unique_name = dup_wchar_to_utf8(olestr);
254  /* replace ':' with '_' since we use : to delineate between sources */
255  for (i = 0; i < strlen(unique_name); i++) {
256  if (unique_name[i] == ':')
257  unique_name[i] = '_';
258  }
259 
260  r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
261  if (r != S_OK)
262  goto fail1;
263 
264  var.vt = VT_BSTR;
265  r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
266  if (r != S_OK)
267  goto fail1;
268  friendly_name = dup_wchar_to_utf8(var.bstrVal);
269 
270  if (pfilter) {
271  if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name))
272  goto fail1;
273 
274  if (!skip--) {
275  r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
276  if (r != S_OK) {
277  av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name);
278  goto fail1;
279  }
280  *device_unique_name = unique_name;
281  // success, loop will end now
282  }
283  } else {
284  av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
285  av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name);
286  av_free(unique_name);
287  }
288 
289 fail1:
290  if (olestr && co_malloc)
291  IMalloc_Free(co_malloc, olestr);
292  if (bind_ctx)
293  IBindCtx_Release(bind_ctx);
294  av_free(friendly_name);
295  if (bag)
296  IPropertyBag_Release(bag);
297  IMoniker_Release(m);
298  }
299 
300  IEnumMoniker_Release(classenum);
301 
302  if (pfilter) {
303  if (!device_filter) {
304  av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
305  devtypename, device_name, sourcetypename);
306  return AVERROR(EIO);
307  }
308  *pfilter = device_filter;
309  }
310 
311  return 0;
312 }
313 
314 /**
315  * Cycle through available formats using the specified pin,
316  * try to set parameters specified through AVOptions and if successful
317  * return 1 in *pformat_set.
318  * If pformat_set is NULL, list all pin capabilities.
319  */
320 static void
322  IPin *pin, int *pformat_set)
323 {
324  struct dshow_ctx *ctx = avctx->priv_data;
325  IAMStreamConfig *config = NULL;
326  AM_MEDIA_TYPE *type = NULL;
327  int format_set = 0;
328  void *caps = NULL;
329  int i, n, size, r;
330 
331  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
332  return;
333  if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
334  goto end;
335 
336  caps = av_malloc(size);
337  if (!caps)
338  goto end;
339 
340  for (i = 0; i < n && !format_set; i++) {
341  r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
342  if (r != S_OK)
343  goto next;
344 #if DSHOWDEBUG
346 #endif
347 
348  if (devtype == VideoDevice) {
349  VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
350  BITMAPINFOHEADER *bih;
351  int64_t *fr;
352  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
353 #if DSHOWDEBUG
355 #endif
356  if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
357  VIDEOINFOHEADER *v = (void *) type->pbFormat;
358  fr = &v->AvgTimePerFrame;
359  bih = &v->bmiHeader;
360  } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
361  VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
362  fr = &v->AvgTimePerFrame;
363  bih = &v->bmiHeader;
364  } else {
365  goto next;
366  }
367  if (!pformat_set) {
368  enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
369  if (pix_fmt == AV_PIX_FMT_NONE) {
370  enum AVCodecID codec_id = av_codec_get_id(tags, bih->biCompression);
371  AVCodec *codec = avcodec_find_decoder(codec_id);
372  if (codec_id == AV_CODEC_ID_NONE || !codec) {
373  av_log(avctx, AV_LOG_INFO, " unknown compression type 0x%X", (int) bih->biCompression);
374  } else {
375  av_log(avctx, AV_LOG_INFO, " vcodec=%s", codec->name);
376  }
377  } else {
378  av_log(avctx, AV_LOG_INFO, " pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
379  }
380  av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
381  vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
382  1e7 / vcaps->MaxFrameInterval,
383  vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
384  1e7 / vcaps->MinFrameInterval);
385  continue;
386  }
387  if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
388  if (ctx->video_codec_id != av_codec_get_id(tags, bih->biCompression))
389  goto next;
390  }
391  if (ctx->pixel_format != AV_PIX_FMT_NONE &&
392  ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
393  goto next;
394  }
395  if (ctx->framerate) {
396  int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
397  / ctx->requested_framerate.num;
398  if (framerate > vcaps->MaxFrameInterval ||
399  framerate < vcaps->MinFrameInterval)
400  goto next;
401  *fr = framerate;
402  }
403  if (ctx->requested_width && ctx->requested_height) {
404  if (ctx->requested_width > vcaps->MaxOutputSize.cx ||
405  ctx->requested_width < vcaps->MinOutputSize.cx ||
406  ctx->requested_height > vcaps->MaxOutputSize.cy ||
407  ctx->requested_height < vcaps->MinOutputSize.cy)
408  goto next;
409  bih->biWidth = ctx->requested_width;
410  bih->biHeight = ctx->requested_height;
411  }
412  } else {
413  AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
414  WAVEFORMATEX *fx;
415 #if DSHOWDEBUG
417 #endif
418  if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
419  fx = (void *) type->pbFormat;
420  } else {
421  goto next;
422  }
423  if (!pformat_set) {
424  av_log(avctx, AV_LOG_INFO, " min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
425  acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
426  acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
427  continue;
428  }
429  if (ctx->sample_rate) {
430  if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
431  ctx->sample_rate < acaps->MinimumSampleFrequency)
432  goto next;
433  fx->nSamplesPerSec = ctx->sample_rate;
434  }
435  if (ctx->sample_size) {
436  if (ctx->sample_size > acaps->MaximumBitsPerSample ||
437  ctx->sample_size < acaps->MinimumBitsPerSample)
438  goto next;
439  fx->wBitsPerSample = ctx->sample_size;
440  }
441  if (ctx->channels) {
442  if (ctx->channels > acaps->MaximumChannels ||
443  ctx->channels < acaps->MinimumChannels)
444  goto next;
445  fx->nChannels = ctx->channels;
446  }
447  }
448  if (IAMStreamConfig_SetFormat(config, type) != S_OK)
449  goto next;
450  format_set = 1;
451 next:
452  if (type->pbFormat)
453  CoTaskMemFree(type->pbFormat);
454  CoTaskMemFree(type);
455  }
456 end:
457  IAMStreamConfig_Release(config);
458  av_free(caps);
459  if (pformat_set)
460  *pformat_set = format_set;
461 }
462 
463 /**
464  * Set audio device buffer size in milliseconds (which can directly impact
465  * latency, depending on the device).
466  */
467 static int
469 {
470  struct dshow_ctx *ctx = avctx->priv_data;
471  IAMBufferNegotiation *buffer_negotiation = NULL;
472  ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
473  IAMStreamConfig *config = NULL;
474  AM_MEDIA_TYPE *type = NULL;
475  int ret = AVERROR(EIO);
476 
477  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
478  goto end;
479  if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
480  goto end;
481  if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
482  goto end;
483 
484  props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
485  * ctx->audio_buffer_size / 1000;
486 
487  if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
488  goto end;
489  if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
490  goto end;
491 
492  ret = 0;
493 
494 end:
495  if (buffer_negotiation)
496  IAMBufferNegotiation_Release(buffer_negotiation);
497  if (type) {
498  if (type->pbFormat)
499  CoTaskMemFree(type->pbFormat);
500  CoTaskMemFree(type);
501  }
502  if (config)
503  IAMStreamConfig_Release(config);
504 
505  return ret;
506 }
507 
508 /**
509  * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
510  */
511 void
513  ISpecifyPropertyPages *property_pages = NULL;
514  IUnknown *device_filter_iunknown = NULL;
515  HRESULT hr;
516  FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
517  CAUUID ca_guid = {0};
518 
519  hr = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
520  if (hr != S_OK) {
521  av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
522  goto end;
523  }
524  hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
525  if (hr != S_OK) {
526  goto fail;
527  }
528  hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
529  if (hr != S_OK) {
530  goto fail;
531  }
532  hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
533  if (hr != S_OK) {
534  goto fail;
535  }
536  hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
537  ca_guid.pElems, 0, 0, NULL);
538  if (hr != S_OK) {
539  goto fail;
540  }
541  goto end;
542 fail:
543  av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
544 end:
545  if (property_pages)
546  ISpecifyPropertyPages_Release(property_pages);
547  if (device_filter_iunknown)
548  IUnknown_Release(device_filter_iunknown);
549  if (filter_info.pGraph)
550  IFilterGraph_Release(filter_info.pGraph);
551  if (ca_guid.pElems)
552  CoTaskMemFree(ca_guid.pElems);
553 }
554 
555 /**
556  * Cycle through available pins using the device_filter device, of type
557  * devtype, retrieve the first output pin and return the pointer to the
558  * object found in *ppin.
559  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
560  */
561 static int
563  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
564 {
565  struct dshow_ctx *ctx = avctx->priv_data;
566  IEnumPins *pins = 0;
567  IPin *device_pin = NULL;
568  IPin *pin;
569  int r;
570 
571  const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
572  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
573  const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
574 
575  int set_format = (devtype == VideoDevice && (ctx->framerate ||
576  (ctx->requested_width && ctx->requested_height) ||
577  ctx->pixel_format != AV_PIX_FMT_NONE ||
579  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
580  int format_set = 0;
581  int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
582 
583  if (should_show_properties)
584  dshow_show_filter_properties(device_filter, avctx);
585 
586  r = IBaseFilter_EnumPins(device_filter, &pins);
587  if (r != S_OK) {
588  av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
589  return AVERROR(EIO);
590  }
591 
592  if (!ppin) {
593  av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
594  devtypename, sourcetypename);
595  }
596 
597  while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
598  IKsPropertySet *p = NULL;
599  IEnumMediaTypes *types = NULL;
600  PIN_INFO info = {0};
601  AM_MEDIA_TYPE *type;
602  GUID category;
603  DWORD r2;
604  char *name_buf = NULL;
605  wchar_t *pin_id = NULL;
606  char *pin_buf = NULL;
607  char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
608 
609  IPin_QueryPinInfo(pin, &info);
610  IBaseFilter_Release(info.pFilter);
611 
612  if (info.dir != PINDIR_OUTPUT)
613  goto next;
614  if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
615  goto next;
616  if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
617  NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
618  goto next;
619  if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
620  goto next;
621  name_buf = dup_wchar_to_utf8(info.achName);
622 
623  r = IPin_QueryId(pin, &pin_id);
624  if (r != S_OK) {
625  av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
626  return AVERROR(EIO);
627  }
628  pin_buf = dup_wchar_to_utf8(pin_id);
629 
630  if (!ppin) {
631  av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
632  dshow_cycle_formats(avctx, devtype, pin, NULL);
633  goto next;
634  }
635 
636  if (desired_pin_name) {
637  if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
638  av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
639  name_buf, pin_buf, desired_pin_name);
640  goto next;
641  }
642  }
643 
644  if (set_format) {
645  dshow_cycle_formats(avctx, devtype, pin, &format_set);
646  if (!format_set) {
647  goto next;
648  }
649  }
650  if (devtype == AudioDevice && ctx->audio_buffer_size) {
651  if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
652  av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
653  }
654  }
655 
656  if (IPin_EnumMediaTypes(pin, &types) != S_OK)
657  goto next;
658 
659  IEnumMediaTypes_Reset(types);
660  /* in case format_set was not called, just verify the majortype */
661  while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
662  if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
663  device_pin = pin;
664  av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
665  goto next;
666  }
667  CoTaskMemFree(type);
668  }
669 
670 next:
671  if (types)
672  IEnumMediaTypes_Release(types);
673  if (p)
674  IKsPropertySet_Release(p);
675  if (device_pin != pin)
676  IPin_Release(pin);
677  av_free(name_buf);
678  av_free(pin_buf);
679  if (pin_id)
680  CoTaskMemFree(pin_id);
681  }
682 
683  IEnumPins_Release(pins);
684 
685  if (ppin) {
686  if (set_format && !format_set) {
687  av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
688  return AVERROR(EIO);
689  }
690  if (!device_pin) {
691  av_log(avctx, AV_LOG_ERROR,
692  "Could not find output pin from %s capture device.\n", devtypename);
693  return AVERROR(EIO);
694  }
695  *ppin = device_pin;
696  }
697 
698  return 0;
699 }
700 
701 /**
702  * List options for device with type devtype, source filter type sourcetype
703  *
704  * @param devenum device enumerator used for accessing the device
705  */
706 static int
707 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
708  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
709 {
710  struct dshow_ctx *ctx = avctx->priv_data;
711  IBaseFilter *device_filter = NULL;
712  char *device_unique_name = NULL;
713  int r;
714 
715  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name)) < 0)
716  return r;
717  ctx->device_filter[devtype] = device_filter;
718  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
719  return r;
720  av_freep(&device_unique_name);
721  return 0;
722 }
723 
724 static int
725 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
726  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
727 {
728  struct dshow_ctx *ctx = avctx->priv_data;
729  IBaseFilter *device_filter = NULL;
730  char *device_filter_unique_name = NULL;
731  IGraphBuilder *graph = ctx->graph;
732  IPin *device_pin = NULL;
735  ICaptureGraphBuilder2 *graph_builder2 = NULL;
736  int ret = AVERROR(EIO);
737  int r;
738  IStream *ifile_stream = NULL;
739  IStream *ofile_stream = NULL;
740  IPersistStream *pers_stream = NULL;
741  enum dshowDeviceType otherDevType = (devtype == VideoDevice) ? AudioDevice : VideoDevice;
742 
743  const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
744 
745 
746  if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
747  ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
748  HRESULT hr;
749  char *filename = NULL;
750 
751  if (sourcetype == AudioSourceDevice)
752  filename = ctx->audio_filter_load_file;
753  else
754  filename = ctx->video_filter_load_file;
755 
756  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
757  if (S_OK != hr) {
758  av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
759  goto error;
760  }
761 
762  hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
763  if (hr != S_OK) {
764  av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
765  goto error;
766  }
767 
768  if (sourcetype == AudioSourceDevice)
769  av_log(avctx, AV_LOG_INFO, "Audio-");
770  else
771  av_log(avctx, AV_LOG_INFO, "Video-");
772  av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
773  } else {
774 
775  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_filter_unique_name)) < 0) {
776  ret = r;
777  goto error;
778  }
779  }
780  if (ctx->device_filter[otherDevType]) {
781  // avoid adding add two instances of the same device to the graph, one for video, one for audio
782  // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK)
783  if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) {
784  av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name);
785  IBaseFilter_Release(device_filter);
786  device_filter = ctx->device_filter[otherDevType];
787  IBaseFilter_AddRef(ctx->device_filter[otherDevType]);
788  } else {
789  av_log(avctx, AV_LOG_DEBUG, "not reusing previous graph capture filter %s != %s\n", device_filter_unique_name, ctx->device_unique_name[otherDevType]);
790  }
791  }
792 
793  ctx->device_filter [devtype] = device_filter;
794  ctx->device_unique_name [devtype] = device_filter_unique_name;
795 
796  r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
797  if (r != S_OK) {
798  av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
799  goto error;
800  }
801 
802  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
803  ret = r;
804  goto error;
805  }
806 
807  ctx->device_pin[devtype] = device_pin;
808 
809  capture_filter = libAVFilter_Create(avctx, callback, devtype);
810  if (!capture_filter) {
811  av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
812  goto error;
813  }
814  ctx->capture_filter[devtype] = capture_filter;
815 
816  if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
817  ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
818 
819  HRESULT hr;
820  char *filename = NULL;
821 
822  if (sourcetype == AudioSourceDevice)
823  filename = ctx->audio_filter_save_file;
824  else
825  filename = ctx->video_filter_save_file;
826 
827  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
828  if (S_OK != hr) {
829  av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
830  goto error;
831  }
832 
833  hr = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
834  if (hr != S_OK) {
835  av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
836  goto error;
837  }
838 
839  hr = OleSaveToStream(pers_stream, ofile_stream);
840  if (hr != S_OK) {
841  av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
842  goto error;
843  }
844 
845  hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
846  if (S_OK != hr) {
847  av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
848  goto error;
849  }
850 
851  if (sourcetype == AudioSourceDevice)
852  av_log(avctx, AV_LOG_INFO, "Audio-");
853  else
854  av_log(avctx, AV_LOG_INFO, "Video-");
855  av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
856  }
857 
858  r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
859  filter_name[devtype]);
860  if (r != S_OK) {
861  av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
862  goto error;
863  }
864 
865  libAVPin_AddRef(capture_filter->pin);
866  capture_pin = capture_filter->pin;
867  ctx->capture_pin[devtype] = capture_pin;
868 
869  r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
870  &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
871  if (r != S_OK) {
872  av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
873  goto error;
874  }
875  ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
876  if (r != S_OK) {
877  av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
878  goto error;
879  }
880 
881  r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
882  (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
883 
884  if (r != S_OK) {
885  av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
886  goto error;
887  }
888 
889  r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
890 
891  if (r != S_OK) {
892  av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
893  goto error;
894  }
895 
896  ret = 0;
897 
898 error:
899  if (graph_builder2 != NULL)
900  ICaptureGraphBuilder2_Release(graph_builder2);
901 
902  if (pers_stream)
903  IPersistStream_Release(pers_stream);
904 
905  if (ifile_stream)
906  IStream_Release(ifile_stream);
907 
908  if (ofile_stream)
909  IStream_Release(ofile_stream);
910 
911  return ret;
912 }
913 
914 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
915 {
916  switch (sample_fmt) {
920  default: return AV_CODEC_ID_NONE; /* Should never happen. */
921  }
922 }
923 
925 {
926  switch (bits) {
927  case 8: return AV_SAMPLE_FMT_U8;
928  case 16: return AV_SAMPLE_FMT_S16;
929  case 32: return AV_SAMPLE_FMT_S32;
930  default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
931  }
932 }
933 
934 static int
936  enum dshowDeviceType devtype)
937 {
938  struct dshow_ctx *ctx = avctx->priv_data;
939  AM_MEDIA_TYPE type;
940  AVCodecParameters *par;
941  AVStream *st;
942  int ret = AVERROR(EIO);
943 
944  st = avformat_new_stream(avctx, NULL);
945  if (!st) {
946  ret = AVERROR(ENOMEM);
947  goto error;
948  }
949  st->id = devtype;
950 
951  ctx->capture_filter[devtype]->stream_index = st->index;
952 
953  libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
954 
955  par = st->codecpar;
956  if (devtype == VideoDevice) {
957  BITMAPINFOHEADER *bih = NULL;
958  AVRational time_base;
959 
960  if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
961  VIDEOINFOHEADER *v = (void *) type.pbFormat;
962  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
963  bih = &v->bmiHeader;
964  } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
965  VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
966  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
967  bih = &v->bmiHeader;
968  }
969  if (!bih) {
970  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
971  goto error;
972  }
973 
974  st->avg_frame_rate = av_inv_q(time_base);
975  st->r_frame_rate = av_inv_q(time_base);
976 
978  par->width = bih->biWidth;
979  par->height = bih->biHeight;
980  par->codec_tag = bih->biCompression;
981  par->format = dshow_pixfmt(bih->biCompression, bih->biBitCount);
982  if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
983  av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
984  par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
985  }
986  if (par->format == AV_PIX_FMT_NONE) {
987  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
988  par->codec_id = av_codec_get_id(tags, bih->biCompression);
989  if (par->codec_id == AV_CODEC_ID_NONE) {
990  av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
991  "Please report type 0x%X.\n", (int) bih->biCompression);
992  return AVERROR_PATCHWELCOME;
993  }
994  par->bits_per_coded_sample = bih->biBitCount;
995  } else {
997  if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
998  par->bits_per_coded_sample = bih->biBitCount;
1000  if (par->extradata) {
1001  par->extradata_size = 9;
1002  memcpy(par->extradata, "BottomUp", 9);
1003  }
1004  }
1005  }
1006  } else {
1007  WAVEFORMATEX *fx = NULL;
1008 
1009  if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
1010  fx = (void *) type.pbFormat;
1011  }
1012  if (!fx) {
1013  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1014  goto error;
1015  }
1016 
1018  par->format = sample_fmt_bits_per_sample(fx->wBitsPerSample);
1019  par->codec_id = waveform_codec_id(par->format);
1020  par->sample_rate = fx->nSamplesPerSec;
1021  par->channels = fx->nChannels;
1022  }
1023 
1024  avpriv_set_pts_info(st, 64, 1, 10000000);
1025 
1026  ret = 0;
1027 
1028 error:
1029  return ret;
1030 }
1031 
1033 {
1034  struct dshow_ctx *ctx = avctx->priv_data;
1035  char **device_name = ctx->device_name;
1036  char *name = av_strdup(avctx->url);
1037  char *tmp = name;
1038  int ret = 1;
1039  char *type;
1040 
1041  while ((type = strtok(tmp, "="))) {
1042  char *token = strtok(NULL, ":");
1043  tmp = NULL;
1044 
1045  if (!strcmp(type, "video")) {
1046  device_name[0] = token;
1047  } else if (!strcmp(type, "audio")) {
1048  device_name[1] = token;
1049  } else {
1050  device_name[0] = NULL;
1051  device_name[1] = NULL;
1052  break;
1053  }
1054  }
1055 
1056  if (!device_name[0] && !device_name[1]) {
1057  ret = 0;
1058  } else {
1059  if (device_name[0])
1060  device_name[0] = av_strdup(device_name[0]);
1061  if (device_name[1])
1062  device_name[1] = av_strdup(device_name[1]);
1063  }
1064 
1065  av_free(name);
1066  return ret;
1067 }
1068 
1070 {
1071  struct dshow_ctx *ctx = avctx->priv_data;
1072  IGraphBuilder *graph = NULL;
1073  ICreateDevEnum *devenum = NULL;
1074  IMediaControl *control = NULL;
1075  IMediaEvent *media_event = NULL;
1076  HANDLE media_event_handle;
1077  HANDLE proc;
1078  int ret = AVERROR(EIO);
1079  int r;
1080 
1081  CoInitialize(0);
1082 
1083  if (!ctx->list_devices && !parse_device_name(avctx)) {
1084  av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
1085  goto error;
1086  }
1087 
1088  ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
1090  if (ctx->pixel_format != AV_PIX_FMT_NONE) {
1091  if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
1092  av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
1093  "video codec is not set or set to rawvideo\n");
1094  ret = AVERROR(EINVAL);
1095  goto error;
1096  }
1097  }
1098  if (ctx->framerate) {
1100  if (r < 0) {
1101  av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
1102  goto error;
1103  }
1104  }
1105 
1106  r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1107  &IID_IGraphBuilder, (void **) &graph);
1108  if (r != S_OK) {
1109  av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
1110  goto error;
1111  }
1112  ctx->graph = graph;
1113 
1114  r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
1115  &IID_ICreateDevEnum, (void **) &devenum);
1116  if (r != S_OK) {
1117  av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
1118  goto error;
1119  }
1120 
1121  if (ctx->list_devices) {
1122  av_log(avctx, AV_LOG_INFO, "DirectShow video devices (some may be both video and audio devices)\n");
1124  av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
1126  ret = AVERROR_EXIT;
1127  goto error;
1128  }
1129  if (ctx->list_options) {
1130  if (ctx->device_name[VideoDevice])
1131  if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
1132  ret = r;
1133  goto error;
1134  }
1135  if (ctx->device_name[AudioDevice]) {
1137  /* show audio options from combined video+audio sources as fallback */
1138  if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
1139  ret = r;
1140  goto error;
1141  }
1142  }
1143  }
1144  }
1145  if (ctx->device_name[VideoDevice]) {
1146  if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
1147  (r = dshow_add_device(avctx, VideoDevice)) < 0) {
1148  ret = r;
1149  goto error;
1150  }
1151  }
1152  if (ctx->device_name[AudioDevice]) {
1153  if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
1154  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1155  av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
1156  /* see if there's a video source with an audio pin with the given audio name */
1157  if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
1158  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1159  ret = r;
1160  goto error;
1161  }
1162  }
1163  }
1164  if (ctx->list_options) {
1165  /* allow it to list crossbar options in dshow_open_device */
1166  ret = AVERROR_EXIT;
1167  goto error;
1168  }
1169  ctx->curbufsize[0] = 0;
1170  ctx->curbufsize[1] = 0;
1171  ctx->mutex = CreateMutex(NULL, 0, NULL);
1172  if (!ctx->mutex) {
1173  av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
1174  goto error;
1175  }
1176  ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
1177  if (!ctx->event[1]) {
1178  av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
1179  goto error;
1180  }
1181 
1182  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
1183  if (r != S_OK) {
1184  av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
1185  goto error;
1186  }
1187  ctx->control = control;
1188 
1189  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
1190  if (r != S_OK) {
1191  av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
1192  goto error;
1193  }
1194  ctx->media_event = media_event;
1195 
1196  r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
1197  if (r != S_OK) {
1198  av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
1199  goto error;
1200  }
1201  proc = GetCurrentProcess();
1202  r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
1203  0, 0, DUPLICATE_SAME_ACCESS);
1204  if (!r) {
1205  av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
1206  goto error;
1207  }
1208 
1209  r = IMediaControl_Run(control);
1210  if (r == S_FALSE) {
1211  OAFilterState pfs;
1212  r = IMediaControl_GetState(control, 0, &pfs);
1213  }
1214  if (r != S_OK) {
1215  av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
1216  goto error;
1217  }
1218 
1219  ret = 0;
1220 
1221 error:
1222 
1223  if (devenum)
1224  ICreateDevEnum_Release(devenum);
1225 
1226  if (ret < 0)
1227  dshow_read_close(avctx);
1228 
1229  return ret;
1230 }
1231 
1232 /**
1233  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1234  * purges all events that might be in the event queue to stop the trigger
1235  * of event notification.
1236  */
1237 static int dshow_check_event_queue(IMediaEvent *media_event)
1238 {
1239  LONG_PTR p1, p2;
1240  long code;
1241  int ret = 0;
1242 
1243  while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1244  if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1245  ret = -1;
1246  IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1247  }
1248 
1249  return ret;
1250 }
1251 
1253 {
1254  struct dshow_ctx *ctx = s->priv_data;
1255  AVPacketList *pktl = NULL;
1256 
1257  while (!ctx->eof && !pktl) {
1258  WaitForSingleObject(ctx->mutex, INFINITE);
1259  pktl = ctx->pktl;
1260  if (pktl) {
1261  *pkt = pktl->pkt;
1262  ctx->pktl = ctx->pktl->next;
1263  av_free(pktl);
1264  ctx->curbufsize[pkt->stream_index] -= pkt->size;
1265  }
1266  ResetEvent(ctx->event[1]);
1267  ReleaseMutex(ctx->mutex);
1268  if (!pktl) {
1269  if (dshow_check_event_queue(ctx->media_event) < 0) {
1270  ctx->eof = 1;
1271  } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1272  return AVERROR(EAGAIN);
1273  } else {
1274  WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1275  }
1276  }
1277  }
1278 
1279  return ctx->eof ? AVERROR(EIO) : pkt->size;
1280 }
1281 
1282 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1283 #define DEC AV_OPT_FLAG_DECODING_PARAM
1284 static const AVOption options[] = {
1285  { "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 },
1286  { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1287  { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1288  { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1289  { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1290  { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1291  { "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 },
1292  { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1293  { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1294  { "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 },
1295  { "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 },
1296  { "video_pin_name", "select video capture pin by name", OFFSET(video_pin_name),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
1297  { "audio_pin_name", "select audio capture pin by name", OFFSET(audio_pin_name),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
1298  { "crossbar_video_input_pin_number", "set video input pin number for crossbar device", OFFSET(crossbar_video_input_pin_number), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC },
1299  { "crossbar_audio_input_pin_number", "set audio input pin number for crossbar device", OFFSET(crossbar_audio_input_pin_number), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC },
1300  { "show_video_device_dialog", "display property dialog for video capture device", OFFSET(show_video_device_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1301  { "show_audio_device_dialog", "display property dialog for audio capture device", OFFSET(show_audio_device_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1302  { "show_video_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter on video device", OFFSET(show_video_crossbar_connection_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1303  { "show_audio_crossbar_connection_dialog", "display property dialog for crossbar connecting pins filter on audio device", OFFSET(show_audio_crossbar_connection_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1304  { "show_analog_tv_tuner_dialog", "display property dialog for analog tuner filter", OFFSET(show_analog_tv_tuner_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1305  { "show_analog_tv_tuner_audio_dialog", "display property dialog for analog tuner audio filter", OFFSET(show_analog_tv_tuner_audio_dialog), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1306  { "audio_device_load", "load audio capture filter device (and properties) from file", OFFSET(audio_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1307  { "audio_device_save", "save audio capture filter device (and properties) to file", OFFSET(audio_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1308  { "video_device_load", "load video capture filter device (and properties) from file", OFFSET(video_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1309  { "video_device_save", "save video capture filter device (and properties) to file", OFFSET(video_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1310  { NULL },
1311 };
1312 
1313 static const AVClass dshow_class = {
1314  .class_name = "dshow indev",
1315  .item_name = av_default_item_name,
1316  .option = options,
1317  .version = LIBAVUTIL_VERSION_INT,
1319 };
1320 
1322  .name = "dshow",
1323  .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1324  .priv_data_size = sizeof(struct dshow_ctx),
1325  .read_header = dshow_read_header,
1326  .read_packet = dshow_read_packet,
1327  .read_close = dshow_read_close,
1328  .flags = AVFMT_NOFILE,
1329  .priv_class = &dshow_class,
1330 };
category
Definition: openal-dec.c:248
const char * name
Definition: avisynth_c.h:775
void dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx)
Pops up a user dialog allowing them to adjust properties for the given filter, if possible...
Definition: dshow.c:512
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:768
int requested_width
static enum AVPixelFormat pix_fmt
#define S_OK
Definition: windows2linux.h:40
int size
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition: parseutils.c:179
static int dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
Cycle through available pins using the device_filter device, of type devtype, retrieve the first outp...
Definition: dshow.c:562
char * audio_filter_load_file
void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:85
AVOption.
Definition: opt.h:246
#define WaitForSingleObject(a, b)
Definition: w32pthreads.h:62
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4811
static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
Definition: dshow.c:924
unsigned int max_picture_buffer
Maximum amount of memory in bytes to use for buffering frames obtained from realtime capture devices...
Definition: avformat.h:1556
HRESULT dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx)
Given a fully constructed graph, check if there is a cross bar filter, and configure its pins if so...
int list_devices
AVInputFormat ff_dshow_demuxer
Definition: dshow.c:1321
int audio_device_number
channels
Definition: aptx.c:30
unsigned long WINAPI libAVPin_Release(libAVPin *)
dshowDeviceType
Definition: dshow_capture.h:61
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3884
IMediaEvent * media_event
int num
Numerator.
Definition: rational.h:59
int index
stream index in AVFormatContext
Definition: avformat.h:874
int size
Definition: avcodec.h:1431
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
static int dshow_add_device(AVFormatContext *avctx, enum dshowDeviceType devtype)
Definition: dshow.c:935
char * video_filter_load_file
static AVPacket pkt
enum AVCodecID video_codec_id
AVCodec.
Definition: avcodec.h:3408
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3876
int show_analog_tv_tuner_audio_dialog
packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in ...
Definition: pixfmt.h:83
int show_audio_crossbar_connection_dialog
Format I/O context.
Definition: avformat.h:1342
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define AVFMT_FLAG_NONBLOCK
Do not block when reading packets from input.
Definition: avformat.h:1476
IBaseFilter * device_filter[2]
const char * LPCSTR
uint8_t
#define av_malloc(s)
AV_SAMPLE_FMT_U8
const struct AVCodecTag * avformat_get_riff_video_tags(void)
Definition: riff.c:576
int width
Video only.
Definition: avcodec.h:3950
static int dshow_read_close(AVFormatContext *s)
Definition: dshow.c:58
AVOptions.
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
AVPacket pkt
Definition: avformat.h:2000
static int dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
Definition: dshow.c:725
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
libAVFilter * libAVFilter_Create(void *, void *, enum dshowDeviceType)
char * video_filter_save_file
int id
Format-specific stream ID.
Definition: avformat.h:880
AVPacketList * pktl
static void dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, IPin *pin, int *pformat_set)
Cycle through available formats using the specified pin, try to set parameters specified through AVOp...
Definition: dshow.c:321
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4441
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1473
uint8_t * data
Definition: avcodec.h:1430
int audio_buffer_size
signed 32 bits
Definition: samplefmt.h:62
dshowSourceFilterType
Definition: dshow_capture.h:66
enum AVCodecID video_codec_id
Forced video codec_id.
Definition: avformat.h:1526
#define av_log(a,...)
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Definition: opt.h:276
static const AVOption options[]
Definition: dshow.c:1284
static int dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter **pfilter, char **device_unique_name)
Cycle through available devices using the device enumerator devenum, retrieve the device with type sp...
Definition: dshow.c:207
Main libavdevice API header.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
libAVPin * capture_pin[2]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
unsigned short WORD
HANDLE mutex
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
char * url
input or output URL.
Definition: avformat.h:1438
const char * r
Definition: vf_curves.c:111
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3880
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
const char * name
Name of the codec implementation.
Definition: avcodec.h:3415
unsigned long WINAPI libAVPin_AddRef(libAVPin *)
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:946
#define fail()
Definition: checkasm.h:116
int extradata_size
Size of the extradata content in bytes.
Definition: avcodec.h:3902
#define OFFSET(x)
Definition: dshow.c:1282
static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
Definition: dshow.c:142
static char * dup_wchar_to_utf8(wchar_t *w)
Definition: dshow.c:132
static const AVClass dshow_class
Definition: dshow.c:1313
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
Definition: dshow.c:161
Raw Video Codec.
int32_t * LONG_PTR
static int parse_device_name(AVFormatContext *avctx)
Definition: dshow.c:1032
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:115
PVOID HANDLE
uint8_t w
Definition: llviddspenc.c:38
static int dshow_read_header(AVFormatContext *avctx)
Definition: dshow.c:1069
LPSTR LPOLESTR
AVRational requested_framerate
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
AVFormatContext * ctx
Definition: movenc.c:48
char * audio_filter_save_file
int n
Definition: avisynth_c.h:684
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:65
enum AVCodecID codec_id
Definition: vaapi_decode.c:362
enum AVColorRange color_range
Video only.
Definition: avcodec.h:3970
#define L(x)
Definition: vp56_arith.h:36
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
if(ret< 0)
Definition: vf_mcdeint.c:279
static void error(const char *err)
char * video_pin_name
#define FF_ARRAY_ELEMS(a)
#define DEC
Definition: dshow.c:1283
Stream structure.
Definition: avformat.h:873
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
sample_rate
enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
Definition: utils.c:457
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
static int set_format(void *obj, const char *name, int fmt, int search_flags, enum AVOptionType type, const char *desc, int nb_fmts)
Definition: opt.c:642
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:862
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:592
static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
Definition: dshow.c:914
const char * friendly_name
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
Definition: dshow.c:34
void * buf
Definition: avisynth_c.h:690
#define EC_DEVICE_LOST
Definition: dshow_capture.h:40
int list_options
Describe the class of an AVClass context structure.
Definition: log.h:67
enum AVPixelFormat pixel_format
int index
Definition: gxfenc.c:89
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int show_audio_device_dialog
static int dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
Set audio device buffer size in milliseconds (which can directly impact latency, depending on the dev...
Definition: dshow.c:468
char * device_name[2]
int show_video_device_dialog
cl_device_type type
int requested_height
offset must point to two consecutive integers
Definition: opt.h:233
uint32_t DWORD
HANDLE event[2]
misc parsing utilities
static int dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
List options for device with type devtype, source filter type sourcetype.
Definition: dshow.c:707
int crossbar_audio_input_pin_number
DWORD HRESULT
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:498
char * audio_pin_name
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
int sample_rate
Audio only.
Definition: avcodec.h:3994
int64_t curbufsize[2]
int video_device_number
unsigned long WINAPI libAVFilter_Release(libAVFilter *)
libAVFilter * capture_filter[2]
struct AVPacketList * next
Definition: avformat.h:2001
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:465
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:71
signed 16 bits
Definition: samplefmt.h:61
IMediaControl * control
long WINAPI libAVPin_ConnectionMediaType(libAVPin *, AM_MEDIA_TYPE *)
Definition: dshow_pin.c:96
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:82
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:356
int den
Denominator.
Definition: rational.h:60
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dshow.c:1252
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:773
char * device_unique_name[2]
int crossbar_video_input_pin_number
#define S_FALSE
Definition: windows2linux.h:41
#define av_free(p)
IPin * device_pin[2]
void * priv_data
Format private data.
Definition: avformat.h:1370
const struct PixelFormatTag * avpriv_get_raw_pix_fmt_tags(void)
Definition: raw.c:293
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: avcodec.h:3926
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3898
int channels
Audio only.
Definition: avcodec.h:3990
void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type)
Definition: dshow_common.c:134
#define av_freep(p)
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:647
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1020
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3888
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2279
int stream_index
Definition: avcodec.h:1432
int show_video_crossbar_connection_dialog
static int dshow_check_event_queue(IMediaEvent *media_event)
Checks media events from DirectShow and returns -1 on error or EOF.
Definition: dshow.c:1237
#define MKTAG(a, b, c, d)
Definition: common.h:366
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:997
unsigned int video_frame_num
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1407
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1423
int show_analog_tv_tuner_dialog
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:346
IGraphBuilder * graph
char * framerate
static uint8_t tmp[11]
Definition: aes_ctr.c:26