FFmpeg
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  unique_name = NULL;
282  // success, loop will end now
283  }
284  } else {
285  av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
286  av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", 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_freep(&friendly_name);
295  av_freep(&unique_name);
296  if (bag)
297  IPropertyBag_Release(bag);
298  IMoniker_Release(m);
299  }
300 
301  IEnumMoniker_Release(classenum);
302 
303  if (pfilter) {
304  if (!device_filter) {
305  av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
306  devtypename, device_name, sourcetypename);
307  return AVERROR(EIO);
308  }
309  *pfilter = device_filter;
310  }
311 
312  return 0;
313 }
314 
315 /**
316  * Cycle through available formats using the specified pin,
317  * try to set parameters specified through AVOptions and if successful
318  * return 1 in *pformat_set.
319  * If pformat_set is NULL, list all pin capabilities.
320  */
321 static void
323  IPin *pin, int *pformat_set)
324 {
325  struct dshow_ctx *ctx = avctx->priv_data;
326  IAMStreamConfig *config = NULL;
327  AM_MEDIA_TYPE *type = NULL;
328  int format_set = 0;
329  void *caps = NULL;
330  int i, n, size, r;
331 
332  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
333  return;
334  if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
335  goto end;
336 
337  caps = av_malloc(size);
338  if (!caps)
339  goto end;
340 
341  for (i = 0; i < n && !format_set; i++) {
342  r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
343  if (r != S_OK)
344  goto next;
345 #if DSHOWDEBUG
347 #endif
348 
349  if (devtype == VideoDevice) {
350  VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
351  BITMAPINFOHEADER *bih;
352  int64_t *fr;
353  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
354 #if DSHOWDEBUG
356 #endif
357  if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
358  VIDEOINFOHEADER *v = (void *) type->pbFormat;
359  fr = &v->AvgTimePerFrame;
360  bih = &v->bmiHeader;
361  } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
362  VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
363  fr = &v->AvgTimePerFrame;
364  bih = &v->bmiHeader;
365  } else {
366  goto next;
367  }
368  if (!pformat_set) {
369  enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
370  if (pix_fmt == AV_PIX_FMT_NONE) {
371  enum AVCodecID codec_id = av_codec_get_id(tags, bih->biCompression);
372  AVCodec *codec = avcodec_find_decoder(codec_id);
373  if (codec_id == AV_CODEC_ID_NONE || !codec) {
374  av_log(avctx, AV_LOG_INFO, " unknown compression type 0x%X", (int) bih->biCompression);
375  } else {
376  av_log(avctx, AV_LOG_INFO, " vcodec=%s", codec->name);
377  }
378  } else {
379  av_log(avctx, AV_LOG_INFO, " pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
380  }
381  av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
382  vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
383  1e7 / vcaps->MaxFrameInterval,
384  vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
385  1e7 / vcaps->MinFrameInterval);
386  continue;
387  }
388  if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
389  if (ctx->video_codec_id != av_codec_get_id(tags, bih->biCompression))
390  goto next;
391  }
392  if (ctx->pixel_format != AV_PIX_FMT_NONE &&
393  ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
394  goto next;
395  }
396  if (ctx->framerate) {
397  int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
398  / ctx->requested_framerate.num;
399  if (framerate > vcaps->MaxFrameInterval ||
400  framerate < vcaps->MinFrameInterval)
401  goto next;
402  *fr = framerate;
403  }
404  if (ctx->requested_width && ctx->requested_height) {
405  if (ctx->requested_width > vcaps->MaxOutputSize.cx ||
406  ctx->requested_width < vcaps->MinOutputSize.cx ||
407  ctx->requested_height > vcaps->MaxOutputSize.cy ||
408  ctx->requested_height < vcaps->MinOutputSize.cy)
409  goto next;
410  bih->biWidth = ctx->requested_width;
411  bih->biHeight = ctx->requested_height;
412  }
413  } else {
414  AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
415  WAVEFORMATEX *fx;
416 #if DSHOWDEBUG
418 #endif
419  if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
420  fx = (void *) type->pbFormat;
421  } else {
422  goto next;
423  }
424  if (!pformat_set) {
425  av_log(avctx, AV_LOG_INFO, " min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
426  acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
427  acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
428  continue;
429  }
430  if (ctx->sample_rate) {
431  if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
432  ctx->sample_rate < acaps->MinimumSampleFrequency)
433  goto next;
434  fx->nSamplesPerSec = ctx->sample_rate;
435  }
436  if (ctx->sample_size) {
437  if (ctx->sample_size > acaps->MaximumBitsPerSample ||
438  ctx->sample_size < acaps->MinimumBitsPerSample)
439  goto next;
440  fx->wBitsPerSample = ctx->sample_size;
441  }
442  if (ctx->channels) {
443  if (ctx->channels > acaps->MaximumChannels ||
444  ctx->channels < acaps->MinimumChannels)
445  goto next;
446  fx->nChannels = ctx->channels;
447  }
448  }
449  if (IAMStreamConfig_SetFormat(config, type) != S_OK)
450  goto next;
451  format_set = 1;
452 next:
453  if (type->pbFormat)
454  CoTaskMemFree(type->pbFormat);
455  CoTaskMemFree(type);
456  }
457 end:
458  IAMStreamConfig_Release(config);
459  av_free(caps);
460  if (pformat_set)
461  *pformat_set = format_set;
462 }
463 
464 /**
465  * Set audio device buffer size in milliseconds (which can directly impact
466  * latency, depending on the device).
467  */
468 static int
470 {
471  struct dshow_ctx *ctx = avctx->priv_data;
472  IAMBufferNegotiation *buffer_negotiation = NULL;
473  ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
474  IAMStreamConfig *config = NULL;
475  AM_MEDIA_TYPE *type = NULL;
476  int ret = AVERROR(EIO);
477 
478  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
479  goto end;
480  if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
481  goto end;
482  if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
483  goto end;
484 
485  props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
486  * ctx->audio_buffer_size / 1000;
487 
488  if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
489  goto end;
490  if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
491  goto end;
492 
493  ret = 0;
494 
495 end:
496  if (buffer_negotiation)
497  IAMBufferNegotiation_Release(buffer_negotiation);
498  if (type) {
499  if (type->pbFormat)
500  CoTaskMemFree(type->pbFormat);
501  CoTaskMemFree(type);
502  }
503  if (config)
504  IAMStreamConfig_Release(config);
505 
506  return ret;
507 }
508 
509 /**
510  * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
511  */
512 void
514  ISpecifyPropertyPages *property_pages = NULL;
515  IUnknown *device_filter_iunknown = NULL;
516  HRESULT hr;
517  FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
518  CAUUID ca_guid = {0};
519 
520  hr = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
521  if (hr != S_OK) {
522  av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
523  goto end;
524  }
525  hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
526  if (hr != S_OK) {
527  goto fail;
528  }
529  hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
530  if (hr != S_OK) {
531  goto fail;
532  }
533  hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
534  if (hr != S_OK) {
535  goto fail;
536  }
537  hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
538  ca_guid.pElems, 0, 0, NULL);
539  if (hr != S_OK) {
540  goto fail;
541  }
542  goto end;
543 fail:
544  av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
545 end:
546  if (property_pages)
547  ISpecifyPropertyPages_Release(property_pages);
548  if (device_filter_iunknown)
549  IUnknown_Release(device_filter_iunknown);
550  if (filter_info.pGraph)
551  IFilterGraph_Release(filter_info.pGraph);
552  if (ca_guid.pElems)
553  CoTaskMemFree(ca_guid.pElems);
554 }
555 
556 /**
557  * Cycle through available pins using the device_filter device, of type
558  * devtype, retrieve the first output pin and return the pointer to the
559  * object found in *ppin.
560  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
561  */
562 static int
564  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
565 {
566  struct dshow_ctx *ctx = avctx->priv_data;
567  IEnumPins *pins = 0;
568  IPin *device_pin = NULL;
569  IPin *pin;
570  int r;
571 
572  const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
573  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
574  const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
575 
576  int set_format = (devtype == VideoDevice && (ctx->framerate ||
577  (ctx->requested_width && ctx->requested_height) ||
578  ctx->pixel_format != AV_PIX_FMT_NONE ||
580  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
581  int format_set = 0;
582  int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
583 
584  if (should_show_properties)
585  dshow_show_filter_properties(device_filter, avctx);
586 
587  r = IBaseFilter_EnumPins(device_filter, &pins);
588  if (r != S_OK) {
589  av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
590  return AVERROR(EIO);
591  }
592 
593  if (!ppin) {
594  av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
595  devtypename, sourcetypename);
596  }
597 
598  while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
599  IKsPropertySet *p = NULL;
600  IEnumMediaTypes *types = NULL;
601  PIN_INFO info = {0};
602  AM_MEDIA_TYPE *type;
603  GUID category;
604  DWORD r2;
605  char *name_buf = NULL;
606  wchar_t *pin_id = NULL;
607  char *pin_buf = NULL;
608  char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
609 
610  IPin_QueryPinInfo(pin, &info);
611  IBaseFilter_Release(info.pFilter);
612 
613  if (info.dir != PINDIR_OUTPUT)
614  goto next;
615  if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
616  goto next;
617  if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
618  NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
619  goto next;
620  if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
621  goto next;
622  name_buf = dup_wchar_to_utf8(info.achName);
623 
624  r = IPin_QueryId(pin, &pin_id);
625  if (r != S_OK) {
626  av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
627  return AVERROR(EIO);
628  }
629  pin_buf = dup_wchar_to_utf8(pin_id);
630 
631  if (!ppin) {
632  av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
633  dshow_cycle_formats(avctx, devtype, pin, NULL);
634  goto next;
635  }
636 
637  if (desired_pin_name) {
638  if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
639  av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
640  name_buf, pin_buf, desired_pin_name);
641  goto next;
642  }
643  }
644 
645  if (set_format) {
646  dshow_cycle_formats(avctx, devtype, pin, &format_set);
647  if (!format_set) {
648  goto next;
649  }
650  }
651  if (devtype == AudioDevice && ctx->audio_buffer_size) {
652  if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
653  av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
654  }
655  }
656 
657  if (IPin_EnumMediaTypes(pin, &types) != S_OK)
658  goto next;
659 
660  IEnumMediaTypes_Reset(types);
661  /* in case format_set was not called, just verify the majortype */
662  while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
663  if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
664  device_pin = pin;
665  av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
666  goto next;
667  }
668  CoTaskMemFree(type);
669  }
670 
671 next:
672  if (types)
673  IEnumMediaTypes_Release(types);
674  if (p)
675  IKsPropertySet_Release(p);
676  if (device_pin != pin)
677  IPin_Release(pin);
678  av_free(name_buf);
679  av_free(pin_buf);
680  if (pin_id)
681  CoTaskMemFree(pin_id);
682  }
683 
684  IEnumPins_Release(pins);
685 
686  if (ppin) {
687  if (set_format && !format_set) {
688  av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
689  return AVERROR(EIO);
690  }
691  if (!device_pin) {
692  av_log(avctx, AV_LOG_ERROR,
693  "Could not find output pin from %s capture device.\n", devtypename);
694  return AVERROR(EIO);
695  }
696  *ppin = device_pin;
697  }
698 
699  return 0;
700 }
701 
702 /**
703  * List options for device with type devtype, source filter type sourcetype
704  *
705  * @param devenum device enumerator used for accessing the device
706  */
707 static int
708 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
709  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
710 {
711  struct dshow_ctx *ctx = avctx->priv_data;
712  IBaseFilter *device_filter = NULL;
713  char *device_unique_name = NULL;
714  int r;
715 
716  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name)) < 0)
717  return r;
718  ctx->device_filter[devtype] = device_filter;
719  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
720  return r;
721  av_freep(&device_unique_name);
722  return 0;
723 }
724 
725 static int
726 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
727  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
728 {
729  struct dshow_ctx *ctx = avctx->priv_data;
730  IBaseFilter *device_filter = NULL;
731  char *device_filter_unique_name = NULL;
732  IGraphBuilder *graph = ctx->graph;
733  IPin *device_pin = NULL;
736  ICaptureGraphBuilder2 *graph_builder2 = NULL;
737  int ret = AVERROR(EIO);
738  int r;
739  IStream *ifile_stream = NULL;
740  IStream *ofile_stream = NULL;
741  IPersistStream *pers_stream = NULL;
742  enum dshowDeviceType otherDevType = (devtype == VideoDevice) ? AudioDevice : VideoDevice;
743 
744  const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
745 
746 
747  if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
748  ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
749  HRESULT hr;
750  char *filename = NULL;
751 
752  if (sourcetype == AudioSourceDevice)
753  filename = ctx->audio_filter_load_file;
754  else
755  filename = ctx->video_filter_load_file;
756 
757  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
758  if (S_OK != hr) {
759  av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
760  goto error;
761  }
762 
763  hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
764  if (hr != S_OK) {
765  av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
766  goto error;
767  }
768 
769  if (sourcetype == AudioSourceDevice)
770  av_log(avctx, AV_LOG_INFO, "Audio-");
771  else
772  av_log(avctx, AV_LOG_INFO, "Video-");
773  av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
774  } else {
775 
776  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_filter_unique_name)) < 0) {
777  ret = r;
778  goto error;
779  }
780  }
781  if (ctx->device_filter[otherDevType]) {
782  // avoid adding add two instances of the same device to the graph, one for video, one for audio
783  // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK)
784  if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) {
785  av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name);
786  IBaseFilter_Release(device_filter);
787  device_filter = ctx->device_filter[otherDevType];
788  IBaseFilter_AddRef(ctx->device_filter[otherDevType]);
789  } else {
790  av_log(avctx, AV_LOG_DEBUG, "not reusing previous graph capture filter %s != %s\n", device_filter_unique_name, ctx->device_unique_name[otherDevType]);
791  }
792  }
793 
794  ctx->device_filter [devtype] = device_filter;
795  ctx->device_unique_name [devtype] = device_filter_unique_name;
796 
797  r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
798  if (r != S_OK) {
799  av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
800  goto error;
801  }
802 
803  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
804  ret = r;
805  goto error;
806  }
807 
808  ctx->device_pin[devtype] = device_pin;
809 
810  capture_filter = libAVFilter_Create(avctx, callback, devtype);
811  if (!capture_filter) {
812  av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
813  goto error;
814  }
815  ctx->capture_filter[devtype] = capture_filter;
816 
817  if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
818  ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
819 
820  HRESULT hr;
821  char *filename = NULL;
822 
823  if (sourcetype == AudioSourceDevice)
824  filename = ctx->audio_filter_save_file;
825  else
826  filename = ctx->video_filter_save_file;
827 
828  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
829  if (S_OK != hr) {
830  av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
831  goto error;
832  }
833 
834  hr = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
835  if (hr != S_OK) {
836  av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
837  goto error;
838  }
839 
840  hr = OleSaveToStream(pers_stream, ofile_stream);
841  if (hr != S_OK) {
842  av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
843  goto error;
844  }
845 
846  hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
847  if (S_OK != hr) {
848  av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
849  goto error;
850  }
851 
852  if (sourcetype == AudioSourceDevice)
853  av_log(avctx, AV_LOG_INFO, "Audio-");
854  else
855  av_log(avctx, AV_LOG_INFO, "Video-");
856  av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
857  }
858 
859  r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
860  filter_name[devtype]);
861  if (r != S_OK) {
862  av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
863  goto error;
864  }
865 
866  libAVPin_AddRef(capture_filter->pin);
867  capture_pin = capture_filter->pin;
868  ctx->capture_pin[devtype] = capture_pin;
869 
870  r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
871  &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
872  if (r != S_OK) {
873  av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
874  goto error;
875  }
876  ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
877  if (r != S_OK) {
878  av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
879  goto error;
880  }
881 
882  r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
883  (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
884 
885  if (r != S_OK) {
886  av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
887  goto error;
888  }
889 
890  r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
891 
892  if (r != S_OK) {
893  av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
894  goto error;
895  }
896 
897  ret = 0;
898 
899 error:
900  if (graph_builder2 != NULL)
901  ICaptureGraphBuilder2_Release(graph_builder2);
902 
903  if (pers_stream)
904  IPersistStream_Release(pers_stream);
905 
906  if (ifile_stream)
907  IStream_Release(ifile_stream);
908 
909  if (ofile_stream)
910  IStream_Release(ofile_stream);
911 
912  return ret;
913 }
914 
915 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
916 {
917  switch (sample_fmt) {
921  default: return AV_CODEC_ID_NONE; /* Should never happen. */
922  }
923 }
924 
926 {
927  switch (bits) {
928  case 8: return AV_SAMPLE_FMT_U8;
929  case 16: return AV_SAMPLE_FMT_S16;
930  case 32: return AV_SAMPLE_FMT_S32;
931  default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
932  }
933 }
934 
935 static int
937  enum dshowDeviceType devtype)
938 {
939  struct dshow_ctx *ctx = avctx->priv_data;
940  AM_MEDIA_TYPE type;
941  AVCodecParameters *par;
942  AVStream *st;
943  int ret = AVERROR(EIO);
944 
945  type.pbFormat = NULL;
946 
947  st = avformat_new_stream(avctx, NULL);
948  if (!st) {
949  ret = AVERROR(ENOMEM);
950  goto error;
951  }
952  st->id = devtype;
953 
954  ctx->capture_filter[devtype]->stream_index = st->index;
955 
956  libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
957 
958  par = st->codecpar;
959  if (devtype == VideoDevice) {
960  BITMAPINFOHEADER *bih = NULL;
961  AVRational time_base;
962 
963  if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
964  VIDEOINFOHEADER *v = (void *) type.pbFormat;
965  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
966  bih = &v->bmiHeader;
967  } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
968  VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
969  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
970  bih = &v->bmiHeader;
971  }
972  if (!bih) {
973  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
974  goto error;
975  }
976 
977  st->avg_frame_rate = av_inv_q(time_base);
978  st->r_frame_rate = av_inv_q(time_base);
979 
981  par->width = bih->biWidth;
982  par->height = bih->biHeight;
983  par->codec_tag = bih->biCompression;
984  par->format = dshow_pixfmt(bih->biCompression, bih->biBitCount);
985  if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
986  av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
987  par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
988  }
989  if (par->format == AV_PIX_FMT_NONE) {
990  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
991  par->codec_id = av_codec_get_id(tags, bih->biCompression);
992  if (par->codec_id == AV_CODEC_ID_NONE) {
993  av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
994  "Please report type 0x%X.\n", (int) bih->biCompression);
995  ret = AVERROR_PATCHWELCOME;
996  goto error;
997  }
998  par->bits_per_coded_sample = bih->biBitCount;
999  } else {
1001  if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
1002  par->bits_per_coded_sample = bih->biBitCount;
1003  if (par->height < 0) {
1004  par->height *= -1;
1005  } else {
1007  if (par->extradata) {
1008  par->extradata_size = 9;
1009  memcpy(par->extradata, "BottomUp", 9);
1010  }
1011  }
1012  }
1013  }
1014  } else {
1015  WAVEFORMATEX *fx = NULL;
1016 
1017  if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
1018  fx = (void *) type.pbFormat;
1019  }
1020  if (!fx) {
1021  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1022  goto error;
1023  }
1024 
1026  par->format = sample_fmt_bits_per_sample(fx->wBitsPerSample);
1027  par->codec_id = waveform_codec_id(par->format);
1028  par->sample_rate = fx->nSamplesPerSec;
1029  par->channels = fx->nChannels;
1030  }
1031 
1032  avpriv_set_pts_info(st, 64, 1, 10000000);
1033 
1034  ret = 0;
1035 
1036 error:
1037  if (type.pbFormat)
1038  CoTaskMemFree(type.pbFormat);
1039  return ret;
1040 }
1041 
1043 {
1044  struct dshow_ctx *ctx = avctx->priv_data;
1045  char **device_name = ctx->device_name;
1046  char *name = av_strdup(avctx->url);
1047  char *tmp = name;
1048  int ret = 1;
1049  char *type;
1050 
1051  while ((type = strtok(tmp, "="))) {
1052  char *token = strtok(NULL, ":");
1053  tmp = NULL;
1054 
1055  if (!strcmp(type, "video")) {
1056  device_name[0] = token;
1057  } else if (!strcmp(type, "audio")) {
1058  device_name[1] = token;
1059  } else {
1060  device_name[0] = NULL;
1061  device_name[1] = NULL;
1062  break;
1063  }
1064  }
1065 
1066  if (!device_name[0] && !device_name[1]) {
1067  ret = 0;
1068  } else {
1069  if (device_name[0])
1070  device_name[0] = av_strdup(device_name[0]);
1071  if (device_name[1])
1072  device_name[1] = av_strdup(device_name[1]);
1073  }
1074 
1075  av_free(name);
1076  return ret;
1077 }
1078 
1080 {
1081  struct dshow_ctx *ctx = avctx->priv_data;
1082  IGraphBuilder *graph = NULL;
1083  ICreateDevEnum *devenum = NULL;
1084  IMediaControl *control = NULL;
1085  IMediaEvent *media_event = NULL;
1086  HANDLE media_event_handle;
1087  HANDLE proc;
1088  int ret = AVERROR(EIO);
1089  int r;
1090 
1091  CoInitialize(0);
1092 
1093  if (!ctx->list_devices && !parse_device_name(avctx)) {
1094  av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
1095  goto error;
1096  }
1097 
1098  ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
1100  if (ctx->pixel_format != AV_PIX_FMT_NONE) {
1101  if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
1102  av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
1103  "video codec is not set or set to rawvideo\n");
1104  ret = AVERROR(EINVAL);
1105  goto error;
1106  }
1107  }
1108  if (ctx->framerate) {
1110  if (r < 0) {
1111  av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
1112  goto error;
1113  }
1114  }
1115 
1116  r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1117  &IID_IGraphBuilder, (void **) &graph);
1118  if (r != S_OK) {
1119  av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
1120  goto error;
1121  }
1122  ctx->graph = graph;
1123 
1124  r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
1125  &IID_ICreateDevEnum, (void **) &devenum);
1126  if (r != S_OK) {
1127  av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
1128  goto error;
1129  }
1130 
1131  if (ctx->list_devices) {
1132  av_log(avctx, AV_LOG_INFO, "DirectShow video devices (some may be both video and audio devices)\n");
1134  av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
1136  ret = AVERROR_EXIT;
1137  goto error;
1138  }
1139  if (ctx->list_options) {
1140  if (ctx->device_name[VideoDevice])
1141  if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
1142  ret = r;
1143  goto error;
1144  }
1145  if (ctx->device_name[AudioDevice]) {
1147  /* show audio options from combined video+audio sources as fallback */
1148  if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
1149  ret = r;
1150  goto error;
1151  }
1152  }
1153  }
1154  }
1155  if (ctx->device_name[VideoDevice]) {
1156  if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
1157  (r = dshow_add_device(avctx, VideoDevice)) < 0) {
1158  ret = r;
1159  goto error;
1160  }
1161  }
1162  if (ctx->device_name[AudioDevice]) {
1163  if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
1164  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1165  av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
1166  /* see if there's a video source with an audio pin with the given audio name */
1167  if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
1168  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1169  ret = r;
1170  goto error;
1171  }
1172  }
1173  }
1174  if (ctx->list_options) {
1175  /* allow it to list crossbar options in dshow_open_device */
1176  ret = AVERROR_EXIT;
1177  goto error;
1178  }
1179  ctx->curbufsize[0] = 0;
1180  ctx->curbufsize[1] = 0;
1181  ctx->mutex = CreateMutex(NULL, 0, NULL);
1182  if (!ctx->mutex) {
1183  av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
1184  goto error;
1185  }
1186  ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
1187  if (!ctx->event[1]) {
1188  av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
1189  goto error;
1190  }
1191 
1192  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
1193  if (r != S_OK) {
1194  av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
1195  goto error;
1196  }
1197  ctx->control = control;
1198 
1199  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
1200  if (r != S_OK) {
1201  av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
1202  goto error;
1203  }
1204  ctx->media_event = media_event;
1205 
1206  r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
1207  if (r != S_OK) {
1208  av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
1209  goto error;
1210  }
1211  proc = GetCurrentProcess();
1212  r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
1213  0, 0, DUPLICATE_SAME_ACCESS);
1214  if (!r) {
1215  av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
1216  goto error;
1217  }
1218 
1219  r = IMediaControl_Run(control);
1220  if (r == S_FALSE) {
1221  OAFilterState pfs;
1222  r = IMediaControl_GetState(control, 0, &pfs);
1223  }
1224  if (r != S_OK) {
1225  av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
1226  goto error;
1227  }
1228 
1229  ret = 0;
1230 
1231 error:
1232 
1233  if (devenum)
1234  ICreateDevEnum_Release(devenum);
1235 
1236  if (ret < 0)
1237  dshow_read_close(avctx);
1238 
1239  return ret;
1240 }
1241 
1242 /**
1243  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1244  * purges all events that might be in the event queue to stop the trigger
1245  * of event notification.
1246  */
1247 static int dshow_check_event_queue(IMediaEvent *media_event)
1248 {
1249  LONG_PTR p1, p2;
1250  long code;
1251  int ret = 0;
1252 
1253  while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1254  if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1255  ret = -1;
1256  IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1257  }
1258 
1259  return ret;
1260 }
1261 
1263 {
1264  struct dshow_ctx *ctx = s->priv_data;
1265  AVPacketList *pktl = NULL;
1266 
1267  while (!ctx->eof && !pktl) {
1268  WaitForSingleObject(ctx->mutex, INFINITE);
1269  pktl = ctx->pktl;
1270  if (pktl) {
1271  *pkt = pktl->pkt;
1272  ctx->pktl = ctx->pktl->next;
1273  av_free(pktl);
1274  ctx->curbufsize[pkt->stream_index] -= pkt->size;
1275  }
1276  ResetEvent(ctx->event[1]);
1277  ReleaseMutex(ctx->mutex);
1278  if (!pktl) {
1279  if (dshow_check_event_queue(ctx->media_event) < 0) {
1280  ctx->eof = 1;
1281  } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1282  return AVERROR(EAGAIN);
1283  } else {
1284  WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1285  }
1286  }
1287  }
1288 
1289  return ctx->eof ? AVERROR(EIO) : pkt->size;
1290 }
1291 
1292 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1293 #define DEC AV_OPT_FLAG_DECODING_PARAM
1294 static const AVOption options[] = {
1295  { "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 },
1296  { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1297  { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1298  { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1299  { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1300  { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1301  { "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 },
1302  { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1303  { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1304  { "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 },
1305  { "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 },
1306  { "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 },
1307  { "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 },
1308  { "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 },
1309  { "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 },
1310  { "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 },
1311  { "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 },
1312  { "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 },
1313  { "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 },
1314  { "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 },
1315  { "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 },
1316  { "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 },
1317  { "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 },
1318  { "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 },
1319  { "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 },
1320  { NULL },
1321 };
1322 
1323 static const AVClass dshow_class = {
1324  .class_name = "dshow indev",
1325  .item_name = av_default_item_name,
1326  .option = options,
1327  .version = LIBAVUTIL_VERSION_INT,
1329 };
1330 
1332  .name = "dshow",
1333  .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1334  .priv_data_size = sizeof(struct dshow_ctx),
1335  .read_header = dshow_read_header,
1336  .read_packet = dshow_read_packet,
1337  .read_close = dshow_read_close,
1338  .flags = AVFMT_NOFILE,
1339  .priv_class = &dshow_class,
1340 };
category
Definition: openal-dec.c:248
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:513
#define NULL
Definition: coverity.c:32
int requested_width
static enum AVPixelFormat pix_fmt
#define S_OK
Definition: windows2linux.h:40
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:563
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:4926
static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
Definition: dshow.c:925
unsigned int max_picture_buffer
Maximum amount of memory in bytes to use for buffering frames obtained from realtime capture devices...
Definition: avformat.h:1574
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:1331
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
Definition: qsv.c:77
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3968
IMediaEvent * media_event
int num
Numerator.
Definition: rational.h:59
int index
stream index in AVFormatContext
Definition: avformat.h:882
int size
Definition: avcodec.h:1481
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:936
char * video_filter_load_file
GLint GLenum type
Definition: opengl_enc.c:104
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
static AVPacket pkt
enum AVCodecID video_codec_id
AVCodec.
Definition: avcodec.h:3492
int framerate
Definition: h264_levels.c:65
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3960
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:87
int show_audio_crossbar_connection_dialog
Format I/O context.
Definition: avformat.h:1358
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:1492
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:602
int width
Video only.
Definition: avcodec.h:4034
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:2025
#define f(width, name)
Definition: cbs_vp9.c:255
static int dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
Definition: dshow.c:726
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:888
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:322
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4499
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1489
uint8_t * data
Definition: avcodec.h:1480
int audio_buffer_size
ptrdiff_t size
Definition: opengl_enc.c:100
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:1544
#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:1294
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
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
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 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:1454
const char * r
Definition: vf_curves.c:114
#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:3964
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
uint8_t bits
Definition: vp3data.h:202
unsigned long WINAPI libAVPin_AddRef(libAVPin *)
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:954
#define fail()
Definition: checkasm.h:122
int extradata_size
Size of the extradata content in bytes.
Definition: avcodec.h:3986
#define OFFSET(x)
Definition: dshow.c:1292
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:1323
MIPS optimizations info
Definition: mips.txt:2
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:1042
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:1079
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
#define s(width, name)
Definition: cbs_vp9.c:257
int n
Definition: avisynth_c.h:760
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
enum AVColorRange color_range
Video only.
Definition: avcodec.h:4054
#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
static void error(const char *err)
char * video_pin_name
#define FF_ARRAY_ELEMS(a)
if(ret)
#define DEC
Definition: dshow.c:1293
Stream structure.
Definition: avformat.h:881
#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:467
#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:652
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:894
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
Definition: dshow.c:915
const char * friendly_name
libAVPin * pin
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
Definition: dshow.c:34
void * buf
Definition: avisynth_c.h:766
#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:469
char * device_name[2]
int show_video_device_dialog
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:708
int crossbar_audio_input_pin_number
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
DWORD HRESULT
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:522
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:4078
int64_t curbufsize[2]
int video_device_number
unsigned long WINAPI libAVFilter_Release(libAVFilter *)
libAVFilter * capture_filter[2]
struct AVPacketList * next
Definition: avformat.h:2026
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:75
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:86
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
int den
Denominator.
Definition: rational.h:60
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dshow.c:1262
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:793
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:1386
const struct PixelFormatTag * avpriv_get_raw_pix_fmt_tags(void)
Definition: raw.c:299
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: avcodec.h:4010
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3982
int channels
Audio only.
Definition: avcodec.h:4074
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:654
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3972
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:2438
int stream_index
Definition: avcodec.h:1482
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
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:1247
#define MKTAG(a, b, c, d)
Definition: common.h:366
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:1005
unsigned int video_frame_num
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1457
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1473
int show_analog_tv_tuner_dialog
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:364
IGraphBuilder * graph
const char * name
Definition: opengl_enc.c:102
char * framerate
static uint8_t tmp[11]
Definition: aes_ctr.c:26