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  ff_dshow_pin_Release(ctx->capture_pin[VideoDevice]);
91  if (ctx->capture_pin[AudioDevice])
92  ff_dshow_pin_Release(ctx->capture_pin[AudioDevice]);
93  if (ctx->capture_filter[VideoDevice])
94  ff_dshow_filter_Release(ctx->capture_filter[VideoDevice]);
95  if (ctx->capture_filter[AudioDevice])
96  ff_dshow_filter_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  PacketList *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  PacketList **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(PacketList));
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);
372  const 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  }
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  WAVEFORMATEX *fx;
415 #if DSHOWDEBUG
416  AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
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(
426  avctx,
427  AV_LOG_INFO,
428  " ch=%2u, bits=%2u, rate=%6lu\n",
429  fx->nChannels, fx->wBitsPerSample, fx->nSamplesPerSec
430  );
431  continue;
432  }
433  if (
434  (ctx->sample_rate && ctx->sample_rate != fx->nSamplesPerSec) ||
435  (ctx->sample_size && ctx->sample_size != fx->wBitsPerSample) ||
436  (ctx->channels && ctx->channels != fx->nChannels )
437  ) {
438  goto next;
439  }
440  }
441  if (IAMStreamConfig_SetFormat(config, type) != S_OK)
442  goto next;
443  format_set = 1;
444 next:
445  if (type->pbFormat)
446  CoTaskMemFree(type->pbFormat);
447  CoTaskMemFree(type);
448  }
449 end:
450  IAMStreamConfig_Release(config);
451  av_free(caps);
452  if (pformat_set)
453  *pformat_set = format_set;
454 }
455 
456 /**
457  * Set audio device buffer size in milliseconds (which can directly impact
458  * latency, depending on the device).
459  */
460 static int
462 {
463  struct dshow_ctx *ctx = avctx->priv_data;
464  IAMBufferNegotiation *buffer_negotiation = NULL;
465  ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
466  IAMStreamConfig *config = NULL;
467  AM_MEDIA_TYPE *type = NULL;
468  int ret = AVERROR(EIO);
469 
470  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
471  goto end;
472  if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
473  goto end;
474  if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
475  goto end;
476 
477  props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
478  * ctx->audio_buffer_size / 1000;
479 
480  if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
481  goto end;
482  if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
483  goto end;
484 
485  ret = 0;
486 
487 end:
488  if (buffer_negotiation)
489  IAMBufferNegotiation_Release(buffer_negotiation);
490  if (type) {
491  if (type->pbFormat)
492  CoTaskMemFree(type->pbFormat);
493  CoTaskMemFree(type);
494  }
495  if (config)
496  IAMStreamConfig_Release(config);
497 
498  return ret;
499 }
500 
501 /**
502  * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
503  */
504 void
506  ISpecifyPropertyPages *property_pages = NULL;
507  IUnknown *device_filter_iunknown = NULL;
508  HRESULT hr;
509  FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
510  CAUUID ca_guid = {0};
511 
512  hr = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
513  if (hr != S_OK) {
514  av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
515  goto end;
516  }
517  hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
518  if (hr != S_OK) {
519  goto fail;
520  }
521  hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
522  if (hr != S_OK) {
523  goto fail;
524  }
525  hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
526  if (hr != S_OK) {
527  goto fail;
528  }
529  hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
530  ca_guid.pElems, 0, 0, NULL);
531  if (hr != S_OK) {
532  goto fail;
533  }
534  goto end;
535 fail:
536  av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
537 end:
538  if (property_pages)
539  ISpecifyPropertyPages_Release(property_pages);
540  if (device_filter_iunknown)
541  IUnknown_Release(device_filter_iunknown);
542  if (filter_info.pGraph)
543  IFilterGraph_Release(filter_info.pGraph);
544  if (ca_guid.pElems)
545  CoTaskMemFree(ca_guid.pElems);
546 }
547 
548 /**
549  * Cycle through available pins using the device_filter device, of type
550  * devtype, retrieve the first output pin and return the pointer to the
551  * object found in *ppin.
552  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
553  */
554 static int
556  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
557 {
558  struct dshow_ctx *ctx = avctx->priv_data;
559  IEnumPins *pins = 0;
560  IPin *device_pin = NULL;
561  IPin *pin;
562  int r;
563 
564  const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
565  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
566  const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
567 
568  int set_format = (devtype == VideoDevice && (ctx->framerate ||
569  (ctx->requested_width && ctx->requested_height) ||
570  ctx->pixel_format != AV_PIX_FMT_NONE ||
572  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate || ctx->sample_size));
573  int format_set = 0;
574  int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
575 
576  if (should_show_properties)
578 
579  r = IBaseFilter_EnumPins(device_filter, &pins);
580  if (r != S_OK) {
581  av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
582  return AVERROR(EIO);
583  }
584 
585  if (!ppin) {
586  av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
587  devtypename, sourcetypename);
588  }
589 
590  while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
591  IKsPropertySet *p = NULL;
592  IEnumMediaTypes *types = NULL;
593  PIN_INFO info = {0};
594  AM_MEDIA_TYPE *type;
595  GUID category;
596  DWORD r2;
597  char *name_buf = NULL;
598  wchar_t *pin_id = NULL;
599  char *pin_buf = NULL;
600  char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
601 
602  IPin_QueryPinInfo(pin, &info);
603  IBaseFilter_Release(info.pFilter);
604 
605  if (info.dir != PINDIR_OUTPUT)
606  goto next;
607  if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
608  goto next;
609  if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
610  NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
611  goto next;
612  if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
613  goto next;
614  name_buf = dup_wchar_to_utf8(info.achName);
615 
616  r = IPin_QueryId(pin, &pin_id);
617  if (r != S_OK) {
618  av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
619  return AVERROR(EIO);
620  }
621  pin_buf = dup_wchar_to_utf8(pin_id);
622 
623  if (!ppin) {
624  av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
625  dshow_cycle_formats(avctx, devtype, pin, NULL);
626  goto next;
627  }
628 
629  if (desired_pin_name) {
630  if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
631  av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
632  name_buf, pin_buf, desired_pin_name);
633  goto next;
634  }
635  }
636 
637  if (set_format) {
638  dshow_cycle_formats(avctx, devtype, pin, &format_set);
639  if (!format_set) {
640  goto next;
641  }
642  }
643  if (devtype == AudioDevice && ctx->audio_buffer_size) {
644  if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
645  av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
646  }
647  }
648 
649  if (IPin_EnumMediaTypes(pin, &types) != S_OK)
650  goto next;
651 
652  IEnumMediaTypes_Reset(types);
653  /* in case format_set was not called, just verify the majortype */
654  while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
655  if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
656  device_pin = pin;
657  av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
658  goto next;
659  }
660  CoTaskMemFree(type);
661  }
662 
663 next:
664  if (types)
665  IEnumMediaTypes_Release(types);
666  if (p)
667  IKsPropertySet_Release(p);
668  if (device_pin != pin)
669  IPin_Release(pin);
670  av_free(name_buf);
671  av_free(pin_buf);
672  if (pin_id)
673  CoTaskMemFree(pin_id);
674  }
675 
676  IEnumPins_Release(pins);
677 
678  if (ppin) {
679  if (set_format && !format_set) {
680  av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
681  return AVERROR(EIO);
682  }
683  if (!device_pin) {
684  av_log(avctx, AV_LOG_ERROR,
685  "Could not find output pin from %s capture device.\n", devtypename);
686  return AVERROR(EIO);
687  }
688  *ppin = device_pin;
689  }
690 
691  return 0;
692 }
693 
694 /**
695  * List options for device with type devtype, source filter type sourcetype
696  *
697  * @param devenum device enumerator used for accessing the device
698  */
699 static int
700 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
701  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
702 {
703  struct dshow_ctx *ctx = avctx->priv_data;
704  IBaseFilter *device_filter = NULL;
705  char *device_unique_name = NULL;
706  int r;
707 
708  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name)) < 0)
709  return r;
710  ctx->device_filter[devtype] = device_filter;
711  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
712  return r;
714  return 0;
715 }
716 
717 static int
718 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
719  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
720 {
721  struct dshow_ctx *ctx = avctx->priv_data;
722  IBaseFilter *device_filter = NULL;
723  char *device_filter_unique_name = NULL;
724  IGraphBuilder *graph = ctx->graph;
725  IPin *device_pin = NULL;
728  ICaptureGraphBuilder2 *graph_builder2 = NULL;
729  int ret = AVERROR(EIO);
730  int r;
731  IStream *ifile_stream = NULL;
732  IStream *ofile_stream = NULL;
733  IPersistStream *pers_stream = NULL;
734  enum dshowDeviceType otherDevType = (devtype == VideoDevice) ? AudioDevice : VideoDevice;
735 
736  const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
737 
738 
739  if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
740  ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
741  HRESULT hr;
742  char *filename = NULL;
743 
744  if (sourcetype == AudioSourceDevice)
745  filename = ctx->audio_filter_load_file;
746  else
747  filename = ctx->video_filter_load_file;
748 
749  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
750  if (S_OK != hr) {
751  av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
752  goto error;
753  }
754 
755  hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
756  if (hr != S_OK) {
757  av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
758  goto error;
759  }
760 
761  if (sourcetype == AudioSourceDevice)
762  av_log(avctx, AV_LOG_INFO, "Audio-");
763  else
764  av_log(avctx, AV_LOG_INFO, "Video-");
765  av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
766  } else {
767 
768  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_filter_unique_name)) < 0) {
769  ret = r;
770  goto error;
771  }
772  }
773  if (ctx->device_filter[otherDevType]) {
774  // avoid adding add two instances of the same device to the graph, one for video, one for audio
775  // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK)
776  if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) {
777  av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name);
778  IBaseFilter_Release(device_filter);
779  device_filter = ctx->device_filter[otherDevType];
780  IBaseFilter_AddRef(ctx->device_filter[otherDevType]);
781  } else {
782  av_log(avctx, AV_LOG_DEBUG, "not reusing previous graph capture filter %s != %s\n", device_filter_unique_name, ctx->device_unique_name[otherDevType]);
783  }
784  }
785 
786  ctx->device_filter [devtype] = device_filter;
787  ctx->device_unique_name [devtype] = device_filter_unique_name;
788 
789  r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
790  if (r != S_OK) {
791  av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
792  goto error;
793  }
794 
795  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
796  ret = r;
797  goto error;
798  }
799 
800  ctx->device_pin[devtype] = device_pin;
801 
803  if (!capture_filter) {
804  av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
805  goto error;
806  }
807  ctx->capture_filter[devtype] = capture_filter;
808 
809  if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
810  ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
811 
812  HRESULT hr;
813  char *filename = NULL;
814 
815  if (sourcetype == AudioSourceDevice)
816  filename = ctx->audio_filter_save_file;
817  else
818  filename = ctx->video_filter_save_file;
819 
820  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
821  if (S_OK != hr) {
822  av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
823  goto error;
824  }
825 
826  hr = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
827  if (hr != S_OK) {
828  av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
829  goto error;
830  }
831 
832  hr = OleSaveToStream(pers_stream, ofile_stream);
833  if (hr != S_OK) {
834  av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
835  goto error;
836  }
837 
838  hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
839  if (S_OK != hr) {
840  av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
841  goto error;
842  }
843 
844  if (sourcetype == AudioSourceDevice)
845  av_log(avctx, AV_LOG_INFO, "Audio-");
846  else
847  av_log(avctx, AV_LOG_INFO, "Video-");
848  av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
849  }
850 
851  r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
852  filter_name[devtype]);
853  if (r != S_OK) {
854  av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
855  goto error;
856  }
857 
860  ctx->capture_pin[devtype] = capture_pin;
861 
862  r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
863  &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
864  if (r != S_OK) {
865  av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
866  goto error;
867  }
868  ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
869  if (r != S_OK) {
870  av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
871  goto error;
872  }
873 
874  r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
875  (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
876 
877  if (r != S_OK) {
878  av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
879  goto error;
880  }
881 
882  r = ff_dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
883 
884  if (r != S_OK) {
885  av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
886  goto error;
887  }
888 
889  ret = 0;
890 
891 error:
892  if (graph_builder2 != NULL)
893  ICaptureGraphBuilder2_Release(graph_builder2);
894 
895  if (pers_stream)
896  IPersistStream_Release(pers_stream);
897 
898  if (ifile_stream)
899  IStream_Release(ifile_stream);
900 
901  if (ofile_stream)
902  IStream_Release(ofile_stream);
903 
904  return ret;
905 }
906 
907 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
908 {
909  switch (sample_fmt) {
913  default: return AV_CODEC_ID_NONE; /* Should never happen. */
914  }
915 }
916 
918 {
919  switch (bits) {
920  case 8: return AV_SAMPLE_FMT_U8;
921  case 16: return AV_SAMPLE_FMT_S16;
922  case 32: return AV_SAMPLE_FMT_S32;
923  default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
924  }
925 }
926 
927 static int
929  enum dshowDeviceType devtype)
930 {
931  struct dshow_ctx *ctx = avctx->priv_data;
932  AM_MEDIA_TYPE type;
933  AVCodecParameters *par;
934  AVStream *st;
935  int ret = AVERROR(EIO);
936 
937  type.pbFormat = NULL;
938 
939  st = avformat_new_stream(avctx, NULL);
940  if (!st) {
941  ret = AVERROR(ENOMEM);
942  goto error;
943  }
944  st->id = devtype;
945 
946  ctx->capture_filter[devtype]->stream_index = st->index;
947 
948  ff_dshow_pin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
949 
950  par = st->codecpar;
951  if (devtype == VideoDevice) {
952  BITMAPINFOHEADER *bih = NULL;
953  AVRational time_base;
954 
955  if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
956  VIDEOINFOHEADER *v = (void *) type.pbFormat;
957  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
958  bih = &v->bmiHeader;
959  } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
960  VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
961  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
962  bih = &v->bmiHeader;
963  }
964  if (!bih) {
965  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
966  goto error;
967  }
968 
969  st->avg_frame_rate = av_inv_q(time_base);
970  st->r_frame_rate = av_inv_q(time_base);
971 
973  par->width = bih->biWidth;
974  par->height = bih->biHeight;
975  par->codec_tag = bih->biCompression;
976  par->format = dshow_pixfmt(bih->biCompression, bih->biBitCount);
977  if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
978  av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
979  par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
980  }
981  if (par->format == AV_PIX_FMT_NONE) {
982  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
983  par->codec_id = av_codec_get_id(tags, bih->biCompression);
984  if (par->codec_id == AV_CODEC_ID_NONE) {
985  av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
986  "Please report type 0x%X.\n", (int) bih->biCompression);
988  goto error;
989  }
990  par->bits_per_coded_sample = bih->biBitCount;
991  } else {
993  if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
994  par->bits_per_coded_sample = bih->biBitCount;
995  if (par->height < 0) {
996  par->height *= -1;
997  } else {
999  if (par->extradata) {
1000  par->extradata_size = 9;
1001  memcpy(par->extradata, "BottomUp", 9);
1002  }
1003  }
1004  }
1005  }
1006  } else {
1007  WAVEFORMATEX *fx = NULL;
1008 
1009  if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
1010  fx = (void *) type.pbFormat;
1011  }
1012  if (!fx) {
1013  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1014  goto error;
1015  }
1016 
1018  par->format = sample_fmt_bits_per_sample(fx->wBitsPerSample);
1019  par->codec_id = waveform_codec_id(par->format);
1020  par->sample_rate = fx->nSamplesPerSec;
1021  par->channels = fx->nChannels;
1022  }
1023 
1024  avpriv_set_pts_info(st, 64, 1, 10000000);
1025 
1026  ret = 0;
1027 
1028 error:
1029  if (type.pbFormat)
1030  CoTaskMemFree(type.pbFormat);
1031  return ret;
1032 }
1033 
1035 {
1036  struct dshow_ctx *ctx = avctx->priv_data;
1037  char **device_name = ctx->device_name;
1038  char *name = av_strdup(avctx->url);
1039  char *tmp = name;
1040  int ret = 1;
1041  char *type;
1042 
1043  while ((type = strtok(tmp, "="))) {
1044  char *token = strtok(NULL, ":");
1045  tmp = NULL;
1046 
1047  if (!strcmp(type, "video")) {
1048  device_name[0] = token;
1049  } else if (!strcmp(type, "audio")) {
1050  device_name[1] = token;
1051  } else {
1052  device_name[0] = NULL;
1053  device_name[1] = NULL;
1054  break;
1055  }
1056  }
1057 
1058  if (!device_name[0] && !device_name[1]) {
1059  ret = 0;
1060  } else {
1061  if (device_name[0])
1063  if (device_name[1])
1065  }
1066 
1067  av_free(name);
1068  return ret;
1069 }
1070 
1072 {
1073  struct dshow_ctx *ctx = avctx->priv_data;
1074  IGraphBuilder *graph = NULL;
1075  ICreateDevEnum *devenum = NULL;
1076  IMediaControl *control = NULL;
1077  IMediaEvent *media_event = NULL;
1078  HANDLE media_event_handle;
1079  HANDLE proc;
1080  int ret = AVERROR(EIO);
1081  int r;
1082 
1083  CoInitialize(0);
1084 
1085  if (!ctx->list_devices && !parse_device_name(avctx)) {
1086  av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
1087  goto error;
1088  }
1089 
1090  ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
1092  if (ctx->pixel_format != AV_PIX_FMT_NONE) {
1094  av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
1095  "video codec is not set or set to rawvideo\n");
1096  ret = AVERROR(EINVAL);
1097  goto error;
1098  }
1099  }
1100  if (ctx->framerate) {
1101  r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
1102  if (r < 0) {
1103  av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
1104  goto error;
1105  }
1106  }
1107 
1108  r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1109  &IID_IGraphBuilder, (void **) &graph);
1110  if (r != S_OK) {
1111  av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
1112  goto error;
1113  }
1114  ctx->graph = graph;
1115 
1116  r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
1117  &IID_ICreateDevEnum, (void **) &devenum);
1118  if (r != S_OK) {
1119  av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
1120  goto error;
1121  }
1122 
1123  if (ctx->list_devices) {
1124  av_log(avctx, AV_LOG_INFO, "DirectShow video devices (some may be both video and audio devices)\n");
1126  av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
1128  ret = AVERROR_EXIT;
1129  goto error;
1130  }
1131  if (ctx->list_options) {
1132  if (ctx->device_name[VideoDevice])
1133  if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
1134  ret = r;
1135  goto error;
1136  }
1137  if (ctx->device_name[AudioDevice]) {
1139  /* show audio options from combined video+audio sources as fallback */
1140  if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
1141  ret = r;
1142  goto error;
1143  }
1144  }
1145  }
1146  }
1147  if (ctx->device_name[VideoDevice]) {
1148  if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
1149  (r = dshow_add_device(avctx, VideoDevice)) < 0) {
1150  ret = r;
1151  goto error;
1152  }
1153  }
1154  if (ctx->device_name[AudioDevice]) {
1155  if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
1156  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1157  av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
1158  /* see if there's a video source with an audio pin with the given audio name */
1159  if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
1160  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1161  ret = r;
1162  goto error;
1163  }
1164  }
1165  }
1166  if (ctx->list_options) {
1167  /* allow it to list crossbar options in dshow_open_device */
1168  ret = AVERROR_EXIT;
1169  goto error;
1170  }
1171  ctx->curbufsize[0] = 0;
1172  ctx->curbufsize[1] = 0;
1173  ctx->mutex = CreateMutex(NULL, 0, NULL);
1174  if (!ctx->mutex) {
1175  av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
1176  goto error;
1177  }
1178  ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
1179  if (!ctx->event[1]) {
1180  av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
1181  goto error;
1182  }
1183 
1184  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
1185  if (r != S_OK) {
1186  av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
1187  goto error;
1188  }
1189  ctx->control = control;
1190 
1191  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
1192  if (r != S_OK) {
1193  av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
1194  goto error;
1195  }
1196  ctx->media_event = media_event;
1197 
1198  r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
1199  if (r != S_OK) {
1200  av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
1201  goto error;
1202  }
1203  proc = GetCurrentProcess();
1204  r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
1205  0, 0, DUPLICATE_SAME_ACCESS);
1206  if (!r) {
1207  av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
1208  goto error;
1209  }
1210 
1211  r = IMediaControl_Run(control);
1212  if (r == S_FALSE) {
1213  OAFilterState pfs;
1214  r = IMediaControl_GetState(control, 0, &pfs);
1215  }
1216  if (r != S_OK) {
1217  av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
1218  goto error;
1219  }
1220 
1221  ret = 0;
1222 
1223 error:
1224 
1225  if (devenum)
1226  ICreateDevEnum_Release(devenum);
1227 
1228  if (ret < 0)
1229  dshow_read_close(avctx);
1230 
1231  return ret;
1232 }
1233 
1234 /**
1235  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1236  * purges all events that might be in the event queue to stop the trigger
1237  * of event notification.
1238  */
1239 static int dshow_check_event_queue(IMediaEvent *media_event)
1240 {
1241  LONG_PTR p1, p2;
1242  long code;
1243  int ret = 0;
1244 
1245  while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1246  if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1247  ret = -1;
1248  IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1249  }
1250 
1251  return ret;
1252 }
1253 
1255 {
1256  struct dshow_ctx *ctx = s->priv_data;
1257  PacketList *pktl = NULL;
1258 
1259  while (!ctx->eof && !pktl) {
1260  WaitForSingleObject(ctx->mutex, INFINITE);
1261  pktl = ctx->pktl;
1262  if (pktl) {
1263  *pkt = pktl->pkt;
1264  ctx->pktl = ctx->pktl->next;
1265  av_free(pktl);
1266  ctx->curbufsize[pkt->stream_index] -= pkt->size;
1267  }
1268  ResetEvent(ctx->event[1]);
1269  ReleaseMutex(ctx->mutex);
1270  if (!pktl) {
1271  if (dshow_check_event_queue(ctx->media_event) < 0) {
1272  ctx->eof = 1;
1273  } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1274  return AVERROR(EAGAIN);
1275  } else {
1276  WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1277  }
1278  }
1279  }
1280 
1281  return ctx->eof ? AVERROR(EIO) : pkt->size;
1282 }
1283 
1284 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1285 #define DEC AV_OPT_FLAG_DECODING_PARAM
1286 static const AVOption options[] = {
1287  { "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 },
1288  { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1289  { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1290  { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1291  { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1292  { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1293  { "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 },
1294  { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1295  { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1296  { "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 },
1297  { "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 },
1298  { "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 },
1299  { "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 },
1300  { "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 },
1301  { "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 },
1302  { "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 },
1303  { "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 },
1304  { "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 },
1305  { "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 },
1306  { "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 },
1307  { "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 },
1308  { "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 },
1309  { "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 },
1310  { "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 },
1311  { "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 },
1312  { NULL },
1313 };
1314 
1315 static const AVClass dshow_class = {
1316  .class_name = "dshow indev",
1317  .item_name = av_default_item_name,
1318  .option = options,
1319  .version = LIBAVUTIL_VERSION_INT,
1321 };
1322 
1324  .name = "dshow",
1325  .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1326  .priv_data_size = sizeof(struct dshow_ctx),
1328  .read_packet = dshow_read_packet,
1329  .read_close = dshow_read_close,
1330  .flags = AVFMT_NOFILE,
1331  .priv_class = &dshow_class,
1332 };
avformat_get_riff_video_tags
const struct AVCodecTag * avformat_get_riff_video_tags(void)
Definition: riff.c:622
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:314
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:417
AVCodec
AVCodec.
Definition: codec.h:202
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:186
dshow_ctx::show_audio_crossbar_connection_dialog
int show_audio_crossbar_connection_dialog
Definition: dshow_capture.h:310
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:718
r
const char * r
Definition: vf_curves.c:116
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:760
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:300
dshow_ctx::list_devices
int list_devices
Definition: dshow_capture.h:301
dshow_ctx::requested_width
int requested_width
Definition: dshow_capture.h:340
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
VideoDevice
@ VideoDevice
Definition: dshow_capture.h:63
dshow_ctx::media_event
IMediaEvent * media_event
Definition: dshow_capture.h:334
dshow_capture.h
dshow_ctx::video_filter_save_file
char * video_filter_save_file
Definition: dshow_capture.h:316
DEC
#define DEC
Definition: dshow.c:1285
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:63
graph
fg outputs[0] graph
Definition: ffmpeg_filter.c:174
ff_print_VIDEO_STREAM_CONFIG_CAPS
void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:85
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
pixdesc.h
index
fg index
Definition: ffmpeg_filter.c:168
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:373
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:1315
AVOption
AVOption.
Definition: opt.h:247
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:1003
PacketList
Definition: packet_internal.h:26
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
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
waveform_codec_id
static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
Definition: dshow.c:907
AVFormatContext::video_codec_id
enum AVCodecID video_codec_id
Forced video codec_id.
Definition: avformat.h:1363
dshow_ctx::device_filter
IBaseFilter * device_filter[2]
Definition: dshow_capture.h:318
dshow_pixfmt
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
Definition: dshow.c:34
tf_sess_config.config
config
Definition: tf_sess_config.py:33
sample_rate
sample_rate
Definition: ffmpeg_filter.c:156
dshow_ctx::video_filter_load_file
char * video_filter_load_file
Definition: dshow_capture.h:315
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::capture_pin
DShowPin * capture_pin[2]
Definition: dshow_capture.h:321
dshow_ctx::audio_device_number
int audio_device_number
Definition: dshow_capture.h:298
fail
#define fail()
Definition: checkasm.h:127
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_dshow_filter_Create
DShowFilter * ff_dshow_filter_Create(void *, void *, enum dshowDeviceType)
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:1071
ff_dshow_pin_AddRef
unsigned long ff_dshow_pin_AddRef(DShowPin *)
raw.h
dshow_ctx
Definition: dshow_capture.h:287
DShowFilter::pin
DShowPin * pin
Definition: dshow_capture.h:256
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:1239
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVInputFormat
Definition: avformat.h:638
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVCodecTag
Definition: internal.h:50
sample_fmt_bits_per_sample
static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
Definition: dshow.c:917
dshow_ctx::show_analog_tv_tuner_audio_dialog
int show_analog_tv_tuner_audio_dialog
Definition: dshow_capture.h:312
ff_dshow_filter_Release
unsigned long ff_dshow_filter_Release(DShowFilter *)
ff_dshow_try_setup_crossbar_options
HRESULT ff_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
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:99
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:277
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:643
dshow_ctx::pktl
PacketList * pktl
Definition: dshow_capture.h:326
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:141
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
dshow_read_packet
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dshow.c:1254
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:555
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:41
DShowFilter
Definition: dshow_capture.h:250
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:439
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
ff_dshow_pin_ConnectionMediaType
long ff_dshow_pin_ConnectionMediaType(DShowPin *, AM_MEDIA_TYPE *)
Definition: dshow_pin.c:91
AVFormatContext
Format I/O context.
Definition: avformat.h:1188
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1083
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:66
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
dshow_ctx::audio_buffer_size
int audio_buffer_size
Definition: dshow_capture.h:302
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:700
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
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:673
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
Definition: opt.h:234
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
parseutils.h
PacketList::next
struct PacketList * next
Definition: packet_internal.h:27
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:41
ff_print_AUDIO_STREAM_CONFIG_CAPS
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:115
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:308
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
avcodec_find_decoder
const AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:920
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:305
dshowSourceFilterType
dshowSourceFilterType
Definition: dshow_capture.h:67
dshow_ctx::list_options
int list_options
Definition: dshow_capture.h:300
AudioDevice
@ AudioDevice
Definition: dshow_capture.h:64
AVPacket::size
int size
Definition: packet.h:374
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:117
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1271
ff_dshow_show_filter_properties
void ff_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:505
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
size
int size
Definition: twinvq_data.h:10344
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
dshow_ctx::crossbar_audio_input_pin_number
int crossbar_audio_input_pin_number
Definition: dshow_capture.h:304
avdevice.h
friendly_name
const char * friendly_name
Definition: hwcontext_vaapi.c:330
dshow_ctx::show_video_device_dialog
int show_video_device_dialog
Definition: dshow_capture.h:307
options
static const AVOption options[]
Definition: dshow.c:1286
AudioSourceDevice
@ AudioSourceDevice
Definition: dshow_capture.h:69
PacketList::pkt
AVPacket pkt
Definition: packet_internal.h:28
dshow_ctx::device_name
char * device_name[2]
Definition: dshow_capture.h:294
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
dshow_add_device
static int dshow_add_device(AVFormatContext *avctx, enum dshowDeviceType devtype)
Definition: dshow.c:928
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:181
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:41
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:366
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:314
ff_dshow_pin_Release
unsigned long ff_dshow_pin_Release(DShowPin *)
AV_SAMPLE_FMT_U8
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition: samplefmt.h:60
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:379
dshow_ctx::audio_pin_name
char * audio_pin_name
Definition: dshow_capture.h:306
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:263
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
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:336
dshow_ctx::capture_filter
DShowFilter * capture_filter[2]
Definition: dshow_capture.h:320
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:297
dshow_ctx::crossbar_video_input_pin_number
int crossbar_video_input_pin_number
Definition: dshow_capture.h:303
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:562
AVFMT_FLAG_NONBLOCK
#define AVFMT_FLAG_NONBLOCK
Do not block when reading packets from input.
Definition: avformat.h:1309
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:937
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:923
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:71
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:368
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
L
#define L(x)
Definition: vp56_arith.h:36
VideoSourceDevice
@ VideoSourceDevice
Definition: dshow_capture.h:68
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:461
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:931
dshow_ctx::show_analog_tv_tuner_dialog
int show_analog_tv_tuner_dialog
Definition: dshow_capture.h:311
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
dshow_ctx::device_pin
IPin * device_pin[2]
Definition: dshow_capture.h:319
ff_dshow_demuxer
const AVInputFormat ff_dshow_demuxer
Definition: dshow.c:1323
dshow_ctx::sample_size
int sample_size
Definition: dshow_capture.h:345
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:1072
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, 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:1186
AV_OPT_TYPE_PIXEL_FMT
@ AV_OPT_TYPE_PIXEL_FMT
Definition: opt.h:235
AVPacket::stream_index
int stream_index
Definition: packet.h:375
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:279
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:322
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:319
dshow_ctx::audio_filter_load_file
char * audio_filter_load_file
Definition: dshow_capture.h:313
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:309
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
dshow_ctx::control
IMediaControl * control
Definition: dshow_capture.h:333
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:350
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:241
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:1034
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
DShowPin
Definition: dshow_capture.h:161
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
dshowDeviceType
dshowDeviceType
Definition: dshow_capture.h:62
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:1216
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:2484
OFFSET
#define OFFSET(x)
Definition: dshow.c:1284
dshow_ctx::device_unique_name
char * device_unique_name[2]
Definition: dshow_capture.h:295