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])
90  libAVPin_Release(ctx->capture_pin[VideoDevice]);
91  if (ctx->capture_pin[AudioDevice])
92  libAVPin_Release(ctx->capture_pin[AudioDevice]);
93  if (ctx->capture_filter[VideoDevice])
94  libAVFilter_Release(ctx->capture_filter[VideoDevice]);
95  if (ctx->capture_filter[AudioDevice])
96  libAVFilter_Release(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;
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) {
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);
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);
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  }
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)
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;
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 
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);
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])
1071  if (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) {
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) {
1109  r = av_parse_video_rate(&ctx->requested_framerate, 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),
1336  .read_packet = dshow_read_packet,
1337  .read_close = dshow_read_close,
1338  .flags = AVFMT_NOFILE,
1339  .priv_class = &dshow_class,
1340 };
avformat_get_riff_video_tags
const struct AVCodecTag * avformat_get_riff_video_tags(void)
Definition: riff.c:608
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:29
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:301
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
AVCodec
AVCodec.
Definition: codec.h:190
av_codec_get_id
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
dshow_ctx::show_audio_crossbar_connection_dialog
int show_audio_crossbar_connection_dialog
Definition: dshow_capture.h:309
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:74
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
dshow_open_device
static int dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
Definition: dshow.c:726
r
const char * r
Definition: vf_curves.c:114
AVERROR
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
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4526
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
avpriv_get_raw_pix_fmt_tags
const struct PixelFormatTag * avpriv_get_raw_pix_fmt_tags(void)
Definition: raw.c:299
dshow_ctx::list_devices
int list_devices
Definition: dshow_capture.h:300
dshow_ctx::requested_width
int requested_width
Definition: dshow_capture.h:339
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
VideoDevice
@ VideoDevice
Definition: dshow_capture.h:62
MKTAG
#define MKTAG(a, b, c, d)
Definition: common.h:406
dshow_ctx::media_event
IMediaEvent * media_event
Definition: dshow_capture.h:333
libAVFilter::pin
libAVPin * pin
Definition: dshow_capture.h:255
libAVPin_AddRef
unsigned long WINAPI libAVPin_AddRef(libAVPin *)
dshow_capture.h
dshow_ctx::video_filter_save_file
char * video_filter_save_file
Definition: dshow_capture.h:315
DEC
#define DEC
Definition: dshow.c:1293
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:62
AVPacketList::next
struct AVPacketList * next
Definition: avformat.h:2010
ff_print_VIDEO_STREAM_CONFIG_CAPS
void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:85
dshow_ctx::pktl
AVPacketList * pktl
Definition: dshow_capture.h:325
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
dshow_read_close
static int dshow_read_close(AVFormatContext *s)
Definition: dshow.c:58
AVPacket::data
uint8_t * data
Definition: packet.h:355
shall_we_drop
static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
Definition: dshow.c:142
dshow_class
static const AVClass dshow_class
Definition: dshow.c:1323
AVOption
AVOption.
Definition: opt.h:246
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:938
AV_PIX_FMT_MONOWHITE
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:75
category
category
Definition: openal-dec.c:248
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
dshow_ctx::graph
IGraphBuilder * graph
Definition: dshow_capture.h:291
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
ff_dshow_demuxer
AVInputFormat ff_dshow_demuxer
Definition: dshow.c:1331
waveform_codec_id
static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
Definition: dshow.c:915
AVFormatContext::video_codec_id
enum AVCodecID video_codec_id
Forced video codec_id.
Definition: avformat.h:1521
dshow_ctx::device_filter
IBaseFilter * device_filter[2]
Definition: dshow_capture.h:317
dshow_pixfmt
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
Definition: dshow.c:34
sample_rate
sample_rate
Definition: ffmpeg_filter.c:192
dshow_ctx::video_filter_load_file
char * video_filter_load_file
Definition: dshow_capture.h:314
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
framerate
int framerate
Definition: h264_levels.c:65
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
dshow_ctx::audio_device_number
int audio_device_number
Definition: dshow_capture.h:297
fail
#define fail()
Definition: checkasm.h:123
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
ff_print_AM_MEDIA_TYPE
void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type)
Definition: dshow_common.c:134
dshow_cycle_formats
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
dshow_read_header
static int dshow_read_header(AVFormatContext *avctx)
Definition: dshow.c:1079
raw.h
dshow_ctx
Definition: dshow_capture.h:286
dshow_check_event_queue
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
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVInputFormat
Definition: avformat.h:636
AVCodecTag
Definition: internal.h:42
sample_fmt_bits_per_sample
static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
Definition: dshow.c:925
dshow_ctx::show_analog_tv_tuner_audio_dialog
int show_analog_tv_tuner_audio_dialog
Definition: dshow_capture.h:311
libAVPin
Definition: dshow_capture.h:160
s
#define s(width, name)
Definition: cbs_vp9.c:257
dshow_try_setup_crossbar_options
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.
Definition: dshow_crossbar.c:140
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:88
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Definition: opt.h:276
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:641
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:126
info
MIPS optimizations info
Definition: mips.txt:2
bits
uint8_t bits
Definition: vp3data.h:202
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
ctx
AVFormatContext * ctx
Definition: movenc.c:48
dshow_read_packet
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dshow.c:1262
channels
channels
Definition: aptx.h:33
AV_PIX_FMT_RGB4
@ AV_PIX_FMT_RGB4
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
dshow_cycle_pins
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
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:40
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
f
#define f(width, name)
Definition: cbs_vp9.c:255
avpriv_find_pix_fmt
enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
Definition: utils.c:477
callback
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
Definition: dshow.c:161
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1335
dshow_ctx::capture_pin
libAVPin * capture_pin[2]
Definition: dshow_capture.h:320
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1012
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
dshow_ctx::audio_buffer_size
int audio_buffer_size
Definition: dshow_capture.h:301
dshow_list_device_options
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
libAVPin_Release
unsigned long WINAPI libAVPin_Release(libAVPin *)
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
libAVFilter_Create
libAVFilter * libAVFilter_Create(void *, void *, enum dshowDeviceType)
set_format
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:670
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
Definition: opt.h:233
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
parseutils.h
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
@ AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
Definition: log.h:42
ff_print_AUDIO_STREAM_CONFIG_CAPS
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:115
AV_SAMPLE_FMT_U8
AV_SAMPLE_FMT_U8
Definition: audio_convert.c:194
index
int index
Definition: gxfenc.c:89
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:170
dshow_ctx::show_audio_device_dialog
int show_audio_device_dialog
Definition: dshow_capture.h:307
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:78
dshow_ctx::video_pin_name
char * video_pin_name
Definition: dshow_capture.h:304
dshowSourceFilterType
dshowSourceFilterType
Definition: dshow_capture.h:66
dshow_ctx::list_options
int list_options
Definition: dshow_capture.h:299
libAVFilter_Release
unsigned long WINAPI libAVFilter_Release(libAVFilter *)
AudioDevice
@ AudioDevice
Definition: dshow_capture.h:63
AVPacket::size
int size
Definition: packet.h:356
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
avpriv_set_pts_info
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:4948
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1431
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
size
int size
Definition: twinvq_data.h:11134
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:458
dshow_ctx::crossbar_audio_input_pin_number
int crossbar_audio_input_pin_number
Definition: dshow_capture.h:303
avdevice.h
friendly_name
const char * friendly_name
Definition: hwcontext_vaapi.c:307
dshow_ctx::show_video_device_dialog
int show_video_device_dialog
Definition: dshow_capture.h:306
options
static const AVOption options[]
Definition: dshow.c:1294
AudioSourceDevice
@ AudioSourceDevice
Definition: dshow_capture.h:68
dshow_ctx::device_name
char * device_name[2]
Definition: dshow_capture.h:293
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
dshow_add_device
static int dshow_add_device(AVFormatContext *avctx, enum dshowDeviceType devtype)
Definition: dshow.c:936
av_parse_video_rate
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition: parseutils.c:179
dup_wchar_to_utf8
static char * dup_wchar_to_utf8(wchar_t *w)
Definition: dshow.c:132
EC_DEVICE_LOST
#define EC_DEVICE_LOST
Definition: dshow_capture.h:40
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:348
code
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
Definition: filter_design.txt:178
dshow_ctx::audio_filter_save_file
char * audio_filter_save_file
Definition: dshow_capture.h:313
AVCodecParameters::height
int height
Definition: codec_par.h:127
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:385
dshow_ctx::audio_pin_name
char * audio_pin_name
Definition: dshow_capture.h:305
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
dshow_ctx::pixel_format
enum AVPixelFormat pixel_format
Definition: dshow_capture.h:335
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:146
dshow_ctx::video_device_number
int video_device_number
Definition: dshow_capture.h:296
libAVPin_ConnectionMediaType
long WINAPI libAVPin_ConnectionMediaType(libAVPin *, AM_MEDIA_TYPE *)
Definition: dshow_pin.c:96
dshow_ctx::crossbar_video_input_pin_number
int crossbar_video_input_pin_number
Definition: dshow_capture.h:302
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:534
AVFMT_FLAG_NONBLOCK
#define AVFMT_FLAG_NONBLOCK
Do not block when reading packets from input.
Definition: avformat.h:1469
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:872
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:865
AVPacketList::pkt
AVPacket pkt
Definition: avformat.h:2009
AVClass::class_name
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
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:374
avcodec_find_decoder
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:919
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: avcodec.h:215
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
L
#define L(x)
Definition: vp56_arith.h:36
VideoSourceDevice
@ VideoSourceDevice
Definition: dshow_capture.h:67
dshow_set_audio_buffer_size
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
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:866
dshow_ctx::show_analog_tv_tuner_dialog
int show_analog_tv_tuner_dialog
Definition: dshow_capture.h:310
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
dshow_ctx::device_pin
IPin * device_pin[2]
Definition: dshow_capture.h:318
dshow_ctx::sample_size
int sample_size
Definition: dshow_capture.h:344
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:989
libAVFilter
Definition: dshow_capture.h:249
AV_OPT_TYPE_PIXEL_FMT
@ AV_OPT_TYPE_PIXEL_FMT
Definition: opt.h:234
AVPacket::stream_index
int stream_index
Definition: packet.h:357
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:253
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:309
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:102
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:306
dshow_ctx::audio_filter_load_file
char * audio_filter_load_file
Definition: dshow_capture.h:312
AVCodecParameters::format
int format
Definition: codec_par.h:84
dshow_ctx::show_video_crossbar_connection_dialog
int show_video_crossbar_connection_dialog
Definition: dshow_capture.h:308
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
dshow_ctx::control
IMediaControl * control
Definition: dshow_capture.h:332
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:332
dshow_cycle_devices
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
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
riff.h
WaitForSingleObject
#define WaitForSingleObject(a, b)
Definition: w32pthreads.h:64
parse_device_name
static int parse_device_name(AVFormatContext *avctx)
Definition: dshow.c:1042
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
dshowDeviceType
dshowDeviceType
Definition: dshow_capture.h:61
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:62
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1363
dshow_show_filter_properties
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
dshow_ctx::capture_filter
libAVFilter * capture_filter[2]
Definition: dshow_capture.h:319
av_get_pix_fmt_name
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:2465
AVPacketList
Definition: avformat.h:2008
OFFSET
#define OFFSET(x)
Definition: dshow.c:1292
dshow_ctx::device_unique_name
char * device_unique_name[2]
Definition: dshow_capture.h:294