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 "libavutil/mem.h"
27 #include "libavformat/internal.h"
28 #include "libavformat/riff.h"
29 #include "avdevice.h"
30 #include "libavcodec/raw.h"
31 #include "objidl.h"
32 #include "shlwapi.h"
33 // NB: technically, we should include dxva.h and use
34 // DXVA_ExtendedFormat, but that type is not defined in
35 // the MinGW headers. The DXVA2_ExtendedFormat and the
36 // contents of its fields is identical to
37 // DXVA_ExtendedFormat (see https://docs.microsoft.com/en-us/windows/win32/medfound/extended-color-information#color-space-in-media-types)
38 // and is provided by MinGW as well, so we use that
39 // instead. NB also that per the Microsoft docs, the
40 // lowest 8 bits of the structure, i.e. the SampleFormat
41 // field, contain AMCONTROL_xxx flags instead of sample
42 // format information, and should thus not be used.
43 // NB further that various values in the structure's
44 // fields (e.g. BT.2020 color space) are not provided
45 // for either of the DXVA structs, but are provided in
46 // the flags of the corresponding fields of Media Foundation.
47 // These may be provided by DirectShow devices (e.g. LAVFilters
48 // does so). So we use those values here too (the equivalence is
49 // indicated by Microsoft example code: https://docs.microsoft.com/en-us/windows/win32/api/dxva2api/ns-dxva2api-dxva2_videodesc)
50 #include "d3d9types.h"
51 #include "dxva2api.h"
52 
53 #ifndef AMCONTROL_COLORINFO_PRESENT
54 // not defined in some versions of MinGW's dvdmedia.h
55 # define AMCONTROL_COLORINFO_PRESENT 0x00000080 // if set, indicates DXVA color info is present in the upper (24) bits of the dwControlFlags
56 #endif
57 
58 
59 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
60 {
61  switch(biCompression) {
62  case BI_BITFIELDS:
63  case BI_RGB:
64  switch(biBitCount) { /* 1-8 are untested */
65  case 1:
66  return AV_PIX_FMT_MONOWHITE;
67  case 4:
68  return AV_PIX_FMT_RGB4;
69  case 8:
70  return AV_PIX_FMT_RGB8;
71  case 16:
72  return AV_PIX_FMT_RGB555;
73  case 24:
74  return AV_PIX_FMT_BGR24;
75  case 32:
76  return AV_PIX_FMT_0RGB32;
77  }
78  }
79  return avpriv_pix_fmt_find(PIX_FMT_LIST_RAW, biCompression); // all others
80 }
81 
82 static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
83 {
84  switch (fmt_info->NominalRange)
85  {
86  case DXVA2_NominalRange_Unknown:
88  case DXVA2_NominalRange_Normal: // equal to DXVA2_NominalRange_0_255
89  return AVCOL_RANGE_JPEG;
90  case DXVA2_NominalRange_Wide: // equal to DXVA2_NominalRange_16_235
91  return AVCOL_RANGE_MPEG;
92  case DXVA2_NominalRange_48_208:
93  // not an ffmpeg color range
95 
96  // values from MediaFoundation SDK (mfobjects.h)
97  case 4: // MFNominalRange_64_127
98  // not an ffmpeg color range
100 
101  default:
103  }
104 }
105 
106 static enum AVColorSpace dshow_color_space(DXVA2_ExtendedFormat *fmt_info)
107 {
108  switch (fmt_info->VideoTransferMatrix)
109  {
110  case DXVA2_VideoTransferMatrix_BT709:
111  return AVCOL_SPC_BT709;
112  case DXVA2_VideoTransferMatrix_BT601:
113  return AVCOL_SPC_BT470BG;
114  case DXVA2_VideoTransferMatrix_SMPTE240M:
115  return AVCOL_SPC_SMPTE240M;
116 
117  // values from MediaFoundation SDK (mfobjects.h)
118  case 4: // MFVideoTransferMatrix_BT2020_10
119  case 5: // MFVideoTransferMatrix_BT2020_12
120  if (fmt_info->VideoTransferFunction == 12) // MFVideoTransFunc_2020_const
121  return AVCOL_SPC_BT2020_CL;
122  else
123  return AVCOL_SPC_BT2020_NCL;
124 
125  default:
126  return AVCOL_SPC_UNSPECIFIED;
127  }
128 }
129 
130 static enum AVColorPrimaries dshow_color_primaries(DXVA2_ExtendedFormat *fmt_info)
131 {
132  switch (fmt_info->VideoPrimaries)
133  {
134  case DXVA2_VideoPrimaries_Unknown:
135  return AVCOL_PRI_UNSPECIFIED;
136  case DXVA2_VideoPrimaries_reserved:
137  return AVCOL_PRI_RESERVED;
138  case DXVA2_VideoPrimaries_BT709:
139  return AVCOL_PRI_BT709;
140  case DXVA2_VideoPrimaries_BT470_2_SysM:
141  return AVCOL_PRI_BT470M;
142  case DXVA2_VideoPrimaries_BT470_2_SysBG:
143  case DXVA2_VideoPrimaries_EBU3213: // this is PAL
144  return AVCOL_PRI_BT470BG;
145  case DXVA2_VideoPrimaries_SMPTE170M:
146  case DXVA2_VideoPrimaries_SMPTE_C:
147  return AVCOL_PRI_SMPTE170M;
148  case DXVA2_VideoPrimaries_SMPTE240M:
149  return AVCOL_PRI_SMPTE240M;
150 
151  // values from MediaFoundation SDK (mfobjects.h)
152  case 9: // MFVideoPrimaries_BT2020
153  return AVCOL_PRI_BT2020;
154  case 10: // MFVideoPrimaries_XYZ
155  return AVCOL_PRI_SMPTE428;
156  case 11: // MFVideoPrimaries_DCI_P3
157  return AVCOL_PRI_SMPTE431;
158  case 12: // MFVideoPrimaries_ACES (Academy Color Encoding System)
159  // not an FFmpeg color primary
160  return AVCOL_PRI_UNSPECIFIED;
161 
162  default:
163  return AVCOL_PRI_UNSPECIFIED;
164  }
165 }
166 
167 static enum AVColorTransferCharacteristic dshow_color_trc(DXVA2_ExtendedFormat *fmt_info)
168 {
169  switch (fmt_info->VideoTransferFunction)
170  {
171  case DXVA2_VideoTransFunc_Unknown:
172  return AVCOL_TRC_UNSPECIFIED;
173  case DXVA2_VideoTransFunc_10:
174  return AVCOL_TRC_LINEAR;
175  case DXVA2_VideoTransFunc_18:
176  // not an FFmpeg transfer characteristic
177  return AVCOL_TRC_UNSPECIFIED;
178  case DXVA2_VideoTransFunc_20:
179  // not an FFmpeg transfer characteristic
180  return AVCOL_TRC_UNSPECIFIED;
181  case DXVA2_VideoTransFunc_22:
182  return AVCOL_TRC_GAMMA22;
183  case DXVA2_VideoTransFunc_709:
184  return AVCOL_TRC_BT709;
185  case DXVA2_VideoTransFunc_240M:
186  return AVCOL_TRC_SMPTE240M;
187  case DXVA2_VideoTransFunc_sRGB:
188  return AVCOL_TRC_IEC61966_2_1;
189  case DXVA2_VideoTransFunc_28:
190  return AVCOL_TRC_GAMMA28;
191 
192  // values from MediaFoundation SDK (mfobjects.h)
193  case 9: // MFVideoTransFunc_Log_100
194  return AVCOL_TRC_LOG;
195  case 10: // MFVideoTransFunc_Log_316
196  return AVCOL_TRC_LOG_SQRT;
197  case 11: // MFVideoTransFunc_709_sym
198  // not an FFmpeg transfer characteristic
199  return AVCOL_TRC_UNSPECIFIED;
200  case 12: // MFVideoTransFunc_2020_const
201  case 13: // MFVideoTransFunc_2020
202  if (fmt_info->VideoTransferMatrix == 5) // MFVideoTransferMatrix_BT2020_12
203  return AVCOL_TRC_BT2020_12;
204  else
205  return AVCOL_TRC_BT2020_10;
206  case 14: // MFVideoTransFunc_26
207  // not an FFmpeg transfer characteristic
208  return AVCOL_TRC_UNSPECIFIED;
209  case 15: // MFVideoTransFunc_2084
210  return AVCOL_TRC_SMPTEST2084;
211  case 16: // MFVideoTransFunc_HLG
212  return AVCOL_TRC_ARIB_STD_B67;
213  case 17: // MFVideoTransFunc_10_rel
214  // not an FFmpeg transfer characteristic? Undocumented also by MS
215  return AVCOL_TRC_UNSPECIFIED;
216 
217  default:
218  return AVCOL_TRC_UNSPECIFIED;
219  }
220 }
221 
222 static enum AVChromaLocation dshow_chroma_loc(DXVA2_ExtendedFormat *fmt_info)
223 {
224  if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_Cosited) // that is: (DXVA2_VideoChromaSubsampling_Horizontally_Cosited | DXVA2_VideoChromaSubsampling_Vertically_Cosited | DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes)
225  return AVCHROMA_LOC_TOPLEFT;
226  else if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_MPEG1) // that is: DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes
227  return AVCHROMA_LOC_CENTER;
228  else if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_MPEG2) // that is: (DXVA2_VideoChromaSubsampling_Horizontally_Cosited | DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes)
229  return AVCHROMA_LOC_LEFT;
230  else if (fmt_info->VideoChromaSubsampling == DXVA2_VideoChromaSubsampling_DV_PAL) // that is: (DXVA2_VideoChromaSubsampling_Horizontally_Cosited | DXVA2_VideoChromaSubsampling_Vertically_Cosited)
231  return AVCHROMA_LOC_TOPLEFT;
232  else
233  // unknown
235 }
236 
237 static int
239 {
240  struct dshow_ctx *ctx = s->priv_data;
242 
243  if (ctx->control) {
244  IMediaControl_Stop(ctx->control);
245  IMediaControl_Release(ctx->control);
246  }
247 
248  if (ctx->media_event)
249  IMediaEvent_Release(ctx->media_event);
250 
251  if (ctx->graph) {
252  IEnumFilters *fenum;
253  int r;
254  r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
255  if (r == S_OK) {
256  IBaseFilter *f;
257  IEnumFilters_Reset(fenum);
258  while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
259  if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
260  IEnumFilters_Reset(fenum); /* When a filter is removed,
261  * the list must be reset. */
262  IBaseFilter_Release(f);
263  }
264  IEnumFilters_Release(fenum);
265  }
266  IGraphBuilder_Release(ctx->graph);
267  }
268 
269  if (ctx->capture_pin[VideoDevice])
270  ff_dshow_pin_Release(ctx->capture_pin[VideoDevice]);
271  if (ctx->capture_pin[AudioDevice])
272  ff_dshow_pin_Release(ctx->capture_pin[AudioDevice]);
273  if (ctx->capture_filter[VideoDevice])
274  ff_dshow_filter_Release(ctx->capture_filter[VideoDevice]);
275  if (ctx->capture_filter[AudioDevice])
276  ff_dshow_filter_Release(ctx->capture_filter[AudioDevice]);
277 
278  if (ctx->device_pin[VideoDevice])
279  IPin_Release(ctx->device_pin[VideoDevice]);
280  if (ctx->device_pin[AudioDevice])
281  IPin_Release(ctx->device_pin[AudioDevice]);
282  if (ctx->device_filter[VideoDevice])
283  IBaseFilter_Release(ctx->device_filter[VideoDevice]);
284  if (ctx->device_filter[AudioDevice])
285  IBaseFilter_Release(ctx->device_filter[AudioDevice]);
286 
287  av_freep(&ctx->device_name[0]);
288  av_freep(&ctx->device_name[1]);
289  av_freep(&ctx->device_unique_name[0]);
290  av_freep(&ctx->device_unique_name[1]);
291 
292  if(ctx->mutex)
293  CloseHandle(ctx->mutex);
294  if(ctx->event[0])
295  CloseHandle(ctx->event[0]);
296  if(ctx->event[1])
297  CloseHandle(ctx->event[1]);
298 
299  pktl = ctx->pktl;
300  while (pktl) {
301  PacketListEntry *next = pktl->next;
303  av_free(pktl);
304  pktl = next;
305  }
306 
307  CoUninitialize();
308 
309  return 0;
310 }
311 
312 static char *dup_wchar_to_utf8(wchar_t *w)
313 {
314  char *s = NULL;
315  int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
316  s = av_malloc(l);
317  if (s)
318  WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
319  return s;
320 }
321 
322 static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype)
323 {
324  struct dshow_ctx *ctx = s->priv_data;
325  static const uint8_t dropscore[] = {62, 75, 87, 100};
326  const int ndropscores = FF_ARRAY_ELEMS(dropscore);
327  unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
328  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
329 
330  if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
332  "real-time buffer [%s] [%s input] too full or near too full (%d%% of size: %d [rtbufsize parameter])! frame dropped!\n",
333  ctx->device_name[devtype], devtypename, buffer_fullness, s->max_picture_buffer);
334  return 1;
335  }
336 
337  return 0;
338 }
339 
340 static void
341 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
342 {
343  AVFormatContext *s = priv_data;
344  struct dshow_ctx *ctx = s->priv_data;
345  PacketListEntry **ppktl, *pktl_next;
346 
347 // dump_videohdr(s, vdhdr);
348 
349  WaitForSingleObject(ctx->mutex, INFINITE);
350 
351  if(shall_we_drop(s, index, devtype))
352  goto fail;
353 
354  pktl_next = av_mallocz(sizeof(*pktl_next));
355  if(!pktl_next)
356  goto fail;
357 
358  if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
359  av_free(pktl_next);
360  goto fail;
361  }
362 
363  pktl_next->pkt.stream_index = index;
364  pktl_next->pkt.pts = time;
365  memcpy(pktl_next->pkt.data, buf, buf_size);
366 
367  for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
368  *ppktl = pktl_next;
369  ctx->curbufsize[index] += buf_size;
370 
371  SetEvent(ctx->event[1]);
372  ReleaseMutex(ctx->mutex);
373 
374  return;
375 fail:
376  ReleaseMutex(ctx->mutex);
377  return;
378 }
379 
380 static void
382  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter,
383  enum AVMediaType **media_types, int *nb_media_types)
384 {
385  IEnumPins *pins = 0;
386  IPin *pin;
387  int has_audio = 0, has_video = 0;
388 
389  if (IBaseFilter_EnumPins(device_filter, &pins) != S_OK)
390  return;
391 
392  while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
393  IKsPropertySet *p = NULL;
394  PIN_INFO info = { 0 };
395  GUID category;
396  DWORD r2;
397  IEnumMediaTypes *types = NULL;
398  AM_MEDIA_TYPE *type;
399 
400  if (IPin_QueryPinInfo(pin, &info) != S_OK)
401  goto next;
402  IBaseFilter_Release(info.pFilter);
403 
404  if (info.dir != PINDIR_OUTPUT)
405  goto next;
406  if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
407  goto next;
408  if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
409  NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
410  goto next;
411  if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
412  goto next;
413 
414  if (IPin_EnumMediaTypes(pin, &types) != S_OK)
415  goto next;
416 
417  // enumerate media types exposed by pin
418  // NB: don't know if a pin can expose both audio and video, check 'm all to be safe
419  IEnumMediaTypes_Reset(types);
420  while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
421  if (IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) {
422  has_video = 1;
423  } else if (IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) {
424  has_audio = 1;
425  }
426  CoTaskMemFree(type);
427  }
428 
429  next:
430  if (types)
431  IEnumMediaTypes_Release(types);
432  if (p)
433  IKsPropertySet_Release(p);
434  if (pin)
435  IPin_Release(pin);
436  }
437 
438  IEnumPins_Release(pins);
439 
440  if (has_audio || has_video) {
441  int nb_types = has_audio + has_video;
442  *media_types = av_malloc_array(nb_types, sizeof(enum AVMediaType));
443  if (*media_types) {
444  if (has_audio)
445  (*media_types)[0] = AVMEDIA_TYPE_AUDIO;
446  if (has_video)
447  (*media_types)[0 + has_audio] = AVMEDIA_TYPE_VIDEO;
448  *nb_media_types = nb_types;
449  }
450  }
451 }
452 
453 /**
454  * Cycle through available devices using the device enumerator devenum,
455  * retrieve the device with type specified by devtype and return the
456  * pointer to the object found in *pfilter.
457  * If pfilter is NULL, list all device names.
458  * If device_list is not NULL, populate it with found devices instead of
459  * outputting device names to log
460  */
461 static int
462 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
463  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype,
464  IBaseFilter **pfilter, char **device_unique_name,
465  AVDeviceInfoList **device_list)
466 {
467  struct dshow_ctx *ctx = avctx->priv_data;
468  IBaseFilter *device_filter = NULL;
469  IEnumMoniker *classenum = NULL;
470  IMoniker *m = NULL;
471  const char *device_name = ctx->device_name[devtype];
472  int skip = (devtype == VideoDevice) ? ctx->video_device_number
473  : ctx->audio_device_number;
474  int r;
475 
476  const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
477  &CLSID_AudioInputDeviceCategory };
478  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
479  const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
480 
481  r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype],
482  (IEnumMoniker **) &classenum, 0);
483  if (r != S_OK) {
484  av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n",
485  devtypename);
486  return AVERROR(EIO);
487  }
488 
489  while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
490  IPropertyBag *bag = NULL;
491  char *friendly_name = NULL;
492  char *unique_name = NULL;
493  VARIANT var;
494  IBindCtx *bind_ctx = NULL;
495  LPOLESTR olestr = NULL;
496  LPMALLOC co_malloc = NULL;
497  AVDeviceInfo *device = NULL;
498  enum AVMediaType *media_types = NULL;
499  int nb_media_types = 0;
500  int i;
501 
502  r = CoGetMalloc(1, &co_malloc);
503  if (r != S_OK)
504  goto fail;
505  r = CreateBindCtx(0, &bind_ctx);
506  if (r != S_OK)
507  goto fail;
508  /* GetDisplayname works for both video and audio, DevicePath doesn't */
509  r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr);
510  if (r != S_OK)
511  goto fail;
512  unique_name = dup_wchar_to_utf8(olestr);
513  /* replace ':' with '_' since we use : to delineate between sources */
514  for (i = 0; i < strlen(unique_name); i++) {
515  if (unique_name[i] == ':')
516  unique_name[i] = '_';
517  }
518 
519  r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
520  if (r != S_OK)
521  goto fail;
522 
523  var.vt = VT_BSTR;
524  r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
525  if (r != S_OK)
526  goto fail;
527  friendly_name = dup_wchar_to_utf8(var.bstrVal);
528 
529  if (pfilter) {
530  if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name))
531  goto fail;
532 
533  if (!skip--) {
534  r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
535  if (r != S_OK) {
536  av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name);
537  goto fail;
538  }
539  *device_unique_name = unique_name;
540  unique_name = NULL;
541  // success, loop will end now
542  }
543  } else {
544  // get media types exposed by pins of device
545  if (IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void* ) &device_filter) == S_OK) {
546  dshow_get_device_media_types(avctx, devtype, sourcetype, device_filter, &media_types, &nb_media_types);
547  IBaseFilter_Release(device_filter);
549  }
550  if (device_list) {
551  device = av_mallocz(sizeof(AVDeviceInfo));
552  if (!device)
553  goto fail;
554 
556  device->device_description = av_strdup(unique_name);
557  if (!device->device_name || !device->device_description)
558  goto fail;
559 
560  // make space in device_list for this new device
561  if (av_reallocp_array(&(*device_list)->devices,
562  (*device_list)->nb_devices + 1,
563  sizeof(*(*device_list)->devices)) < 0)
564  goto fail;
565 
566  // attach media_types to device
567  device->nb_media_types = nb_media_types;
568  device->media_types = media_types;
569  nb_media_types = 0;
570  media_types = NULL;
571 
572  // store device in list
573  (*device_list)->devices[(*device_list)->nb_devices] = device;
574  (*device_list)->nb_devices++;
575  device = NULL; // copied into array, make sure not freed below
576  }
577  else {
578  av_log(avctx, AV_LOG_INFO, "\"%s\"", friendly_name);
579  if (nb_media_types > 0) {
580  const char* media_type = av_get_media_type_string(media_types[0]);
581  av_log(avctx, AV_LOG_INFO, " (%s", media_type ? media_type : "unknown");
582  for (int i = 1; i < nb_media_types; ++i) {
583  media_type = av_get_media_type_string(media_types[i]);
584  av_log(avctx, AV_LOG_INFO, ", %s", media_type ? media_type : "unknown");
585  }
586  av_log(avctx, AV_LOG_INFO, ")");
587  } else {
588  av_log(avctx, AV_LOG_INFO, " (none)");
589  }
590  av_log(avctx, AV_LOG_INFO, "\n");
591  av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name);
592  }
593  }
594 
595  fail:
596  av_freep(&media_types);
597  if (device) {
598  av_freep(&device->device_name);
599  av_freep(&device->device_description);
600  // NB: no need to av_freep(&device->media_types), its only moved to device once nothing can fail anymore
601  av_free(device);
602  }
603  if (olestr && co_malloc)
604  IMalloc_Free(co_malloc, olestr);
605  if (bind_ctx)
606  IBindCtx_Release(bind_ctx);
608  av_freep(&unique_name);
609  if (bag)
610  IPropertyBag_Release(bag);
611  IMoniker_Release(m);
612  }
613 
614  IEnumMoniker_Release(classenum);
615 
616  if (pfilter) {
617  if (!device_filter) {
618  av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
619  devtypename, device_name, sourcetypename);
620  return AVERROR(EIO);
621  }
622  *pfilter = device_filter;
623  }
624 
625  return 0;
626 }
627 
629 {
630  ICreateDevEnum *devenum = NULL;
631  int r;
632  int ret = AVERROR(EIO);
633 
634  if (!device_list)
635  return AVERROR(EINVAL);
636 
637  CoInitialize(0);
638 
639  r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
640  &IID_ICreateDevEnum, (void**)&devenum);
641  if (r != S_OK) {
642  av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
643  goto error;
644  }
645 
646  ret = dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL, NULL, &device_list);
647  if (ret < S_OK)
648  goto error;
649  ret = dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL, NULL, &device_list);
650 
651 error:
652  if (devenum)
653  ICreateDevEnum_Release(devenum);
654 
655  CoUninitialize();
656 
657  return ret;
658 }
659 
661 {
662  struct dshow_ctx *ctx = avctx->priv_data;
663 
664  return (devtype == VideoDevice && (ctx->framerate ||
665  (ctx->requested_width && ctx->requested_height) ||
666  ctx->pixel_format != AV_PIX_FMT_NONE ||
668  || (devtype == AudioDevice && (ctx->channels || ctx->sample_size || ctx->sample_rate));
669 }
670 
671 
674  // video
675  int64_t framerate;
683  int width;
684  int height;
685  // audio
688  int channels;
689 };
690 
691 // user must av_free the returned pointer
692 static struct dshow_format_info *dshow_get_format_info(AM_MEDIA_TYPE *type)
693 {
694  struct dshow_format_info *fmt_info = NULL;
695  BITMAPINFOHEADER *bih;
696  DXVA2_ExtendedFormat *extended_format_info = NULL;
697  WAVEFORMATEX *fx;
699  int64_t framerate;
700 
701  if (!type)
702  return NULL;
703 
704  if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
705  VIDEOINFOHEADER *v = (void *) type->pbFormat;
706  framerate = v->AvgTimePerFrame;
707  bih = &v->bmiHeader;
709  } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
710  VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
712  framerate = v->AvgTimePerFrame;
713  bih = &v->bmiHeader;
714  if (v->dwControlFlags & AMCONTROL_COLORINFO_PRESENT)
715  extended_format_info = (DXVA2_ExtendedFormat *) &v->dwControlFlags;
716  } else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
717  fx = (void *) type->pbFormat;
719  } else {
720  return NULL;
721  }
722 
723  fmt_info = av_mallocz(sizeof(struct dshow_format_info));
724  if (!fmt_info)
725  return NULL;
726  // initialize fields where unset is not zero
727  fmt_info->pix_fmt = AV_PIX_FMT_NONE;
728  fmt_info->col_space = AVCOL_SPC_UNSPECIFIED;
729  fmt_info->col_prim = AVCOL_PRI_UNSPECIFIED;
730  fmt_info->col_trc = AVCOL_TRC_UNSPECIFIED;
731  // now get info about format
732  fmt_info->devtype = devtype;
733  if (devtype == VideoDevice) {
734  fmt_info->width = bih->biWidth;
735  fmt_info->height = bih->biHeight;
736  fmt_info->framerate = framerate;
737  fmt_info->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
738  if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
739  const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
740  fmt_info->codec_id = av_codec_get_id(tags, bih->biCompression);
741  }
742  else
743  fmt_info->codec_id = AV_CODEC_ID_RAWVIDEO;
744 
745  if (extended_format_info) {
746  fmt_info->col_range = dshow_color_range(extended_format_info);
747  fmt_info->col_space = dshow_color_space(extended_format_info);
748  fmt_info->col_prim = dshow_color_primaries(extended_format_info);
749  fmt_info->col_trc = dshow_color_trc(extended_format_info);
750  fmt_info->chroma_loc = dshow_chroma_loc(extended_format_info);
751  }
752  } else {
753  fmt_info->sample_rate = fx->nSamplesPerSec;
754  fmt_info->sample_size = fx->wBitsPerSample;
755  fmt_info->channels = fx->nChannels;
756  }
757 
758  return fmt_info;
759 }
760 
761 static void dshow_get_default_format(IPin *pin, IAMStreamConfig *config, enum dshowDeviceType devtype, AM_MEDIA_TYPE **type)
762 {
763  HRESULT hr;
764 
765  if ((hr = IAMStreamConfig_GetFormat(config, type)) != S_OK) {
766  if (hr == E_NOTIMPL || !IsEqualGUID(&(*type)->majortype, devtype == VideoDevice ? &MEDIATYPE_Video : &MEDIATYPE_Audio)) {
767  // default not available or of wrong type,
768  // fall back to iterating exposed formats
769  // until one of the right type is found
770  IEnumMediaTypes* types = NULL;
771  if (IPin_EnumMediaTypes(pin, &types) != S_OK)
772  return;
773  IEnumMediaTypes_Reset(types);
774  while (IEnumMediaTypes_Next(types, 1, type, NULL) == S_OK) {
775  if (IsEqualGUID(&(*type)->majortype, devtype == VideoDevice ? &MEDIATYPE_Video : &MEDIATYPE_Audio)) {
776  break;
777  }
778  CoTaskMemFree(*type);
779  *type = NULL;
780  }
781  IEnumMediaTypes_Release(types);
782  }
783  }
784 }
785 
786 /**
787  * Cycle through available formats available from the specified pin,
788  * try to set parameters specified through AVOptions, or the pin's
789  * default format if no such parameters were set. If successful,
790  * return 1 in *pformat_set.
791  * If pformat_set is NULL, list all pin capabilities.
792  */
793 static void
795  IPin *pin, int *pformat_set)
796 {
797  struct dshow_ctx *ctx = avctx->priv_data;
798  IAMStreamConfig *config = NULL;
799  AM_MEDIA_TYPE *type = NULL;
800  AM_MEDIA_TYPE *previous_match_type = NULL;
801  int format_set = 0;
802  void *caps = NULL;
803  int i, n, size, r;
804  int wait_for_better = 0;
805  int use_default;
806 
807  // format parameters requested by user
808  // if none are requested by user, the values will below be set to
809  // those of the default format
810  // video
811  enum AVCodecID requested_video_codec_id = ctx->video_codec_id;
812  enum AVPixelFormat requested_pixel_format = ctx->pixel_format;
813  int64_t requested_framerate = ctx->framerate ? ((int64_t)ctx->requested_framerate.den * 10000000)
814  / ctx->requested_framerate.num : 0;
815  int requested_width = ctx->requested_width;
816  int requested_height = ctx->requested_height;
817  // audio
818  int requested_sample_rate = ctx->sample_rate;
819  int requested_sample_size = ctx->sample_size;
820  int requested_channels = ctx->channels;
821 
822  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
823  return;
824  if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
825  goto end;
826 
827  caps = av_malloc(size);
828  if (!caps)
829  goto end;
830 
831  /**
832  * If we should open the device with the default format,
833  * then:
834  * 1. check what the format of the default device is, and
835  * 2. below we iterate all formats till we find a matching
836  * one, with most info exposed (see comment below).
837  */
838  use_default = !dshow_should_set_format(avctx, devtype);
839  if (use_default && pformat_set)
840  {
841  // get default
842  dshow_get_default_format(pin, config, devtype, &type);
843  if (!type)
844  // this pin does not expose any formats of the expected type
845  goto end;
846 
847  if (type) {
848  // interrogate default format, so we know what to search for below
849  struct dshow_format_info *fmt_info = dshow_get_format_info(type);
850  if (fmt_info) {
851  if (fmt_info->devtype == VideoDevice) {
852  requested_video_codec_id = fmt_info->codec_id;
853  requested_pixel_format = fmt_info->pix_fmt;
854  requested_framerate = fmt_info->framerate;
855  requested_width = fmt_info->width;
856  requested_height = fmt_info->height;
857  } else {
858  requested_sample_rate = fmt_info->sample_rate;
859  requested_sample_size = fmt_info->sample_size;
860  requested_channels = fmt_info->channels;
861  }
862  av_free(fmt_info); // free but don't set to NULL to enable below check
863  }
864 
865  if (type && type->pbFormat)
866  CoTaskMemFree(type->pbFormat);
867  CoTaskMemFree(type);
868  type = NULL;
869  if (!fmt_info)
870  // default format somehow invalid, can't continue with this pin
871  goto end;
872  fmt_info = NULL;
873  }
874  }
875 
876  // NB: some devices (e.g. Logitech C920) expose each video format twice:
877  // both a format containing a VIDEOINFOHEADER and a format containing
878  // a VIDEOINFOHEADER2. We want, if possible, to select a format with a
879  // VIDEOINFOHEADER2, as this potentially provides more info about the
880  // format. So, if in the iteration below we have found a matching format,
881  // but it is a VIDEOINFOHEADER, keep looking for a matching format that
882  // exposes contains a VIDEOINFOHEADER2. Fall back to the VIDEOINFOHEADER
883  // format if no corresponding VIDEOINFOHEADER2 is found when we finish
884  // iterating.
885  for (i = 0; i < n && !format_set; i++) {
886  struct dshow_format_info *fmt_info = NULL;
887  r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
888  if (r != S_OK)
889  goto next;
890 #if DSHOWDEBUG
892 #endif
893 
894  fmt_info = dshow_get_format_info(type);
895  if (!fmt_info)
896  goto next;
897 
898  if (devtype == VideoDevice) {
899  VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
900  BITMAPINFOHEADER *bih;
901  int64_t *fr;
902 #if DSHOWDEBUG
904 #endif
905 
906  if (fmt_info->devtype != VideoDevice)
907  goto next;
908 
909  if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
910  VIDEOINFOHEADER *v = (void *) type->pbFormat;
911  fr = &v->AvgTimePerFrame;
912  bih = &v->bmiHeader;
913  wait_for_better = 1;
914  } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
915  VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
916  fr = &v->AvgTimePerFrame;
917  bih = &v->bmiHeader;
918  wait_for_better = 0;
919  }
920 
921  if (!pformat_set) {
922  const char *chroma = av_chroma_location_name(fmt_info->chroma_loc);
923  if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
924  const AVCodec *codec = avcodec_find_decoder(fmt_info->codec_id);
925  if (fmt_info->codec_id == AV_CODEC_ID_NONE || !codec) {
926  av_log(avctx, AV_LOG_INFO, " unknown compression type 0x%X", (int) bih->biCompression);
927  } else {
928  av_log(avctx, AV_LOG_INFO, " vcodec=%s", codec->name);
929  }
930  } else {
931  av_log(avctx, AV_LOG_INFO, " pixel_format=%s", av_get_pix_fmt_name(fmt_info->pix_fmt));
932  }
933  av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g",
934  vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
935  1e7 / vcaps->MaxFrameInterval,
936  vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
937  1e7 / vcaps->MinFrameInterval);
938 
939  if (fmt_info->col_range != AVCOL_RANGE_UNSPECIFIED ||
940  fmt_info->col_space != AVCOL_SPC_UNSPECIFIED ||
941  fmt_info->col_prim != AVCOL_PRI_UNSPECIFIED ||
942  fmt_info->col_trc != AVCOL_TRC_UNSPECIFIED) {
943  const char *range = av_color_range_name(fmt_info->col_range);
944  const char *space = av_color_space_name(fmt_info->col_space);
945  const char *prim = av_color_primaries_name(fmt_info->col_prim);
946  const char *trc = av_color_transfer_name(fmt_info->col_trc);
947  av_log(avctx, AV_LOG_INFO, " (%s, %s/%s/%s",
948  range ? range : "unknown",
949  space ? space : "unknown",
950  prim ? prim : "unknown",
951  trc ? trc : "unknown");
952  if (fmt_info->chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
953  av_log(avctx, AV_LOG_INFO, ", %s", chroma ? chroma : "unknown");
954  av_log(avctx, AV_LOG_INFO, ")");
955  }
956  else if (fmt_info->chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
957  av_log(avctx, AV_LOG_INFO, "(%s)", chroma ? chroma : "unknown");
958 
959  av_log(avctx, AV_LOG_INFO, "\n");
960  goto next;
961  }
962  if (requested_video_codec_id != AV_CODEC_ID_RAWVIDEO) {
963  if (requested_video_codec_id != fmt_info->codec_id)
964  goto next;
965  }
966  if (requested_pixel_format != AV_PIX_FMT_NONE &&
967  requested_pixel_format != fmt_info->pix_fmt) {
968  goto next;
969  }
970  if (requested_framerate) {
971  if (requested_framerate > vcaps->MaxFrameInterval ||
972  requested_framerate < vcaps->MinFrameInterval)
973  goto next;
974  *fr = requested_framerate;
975  }
976  if (requested_width && requested_height) {
977  if (requested_width > vcaps->MaxOutputSize.cx ||
978  requested_width < vcaps->MinOutputSize.cx ||
979  requested_height > vcaps->MaxOutputSize.cy ||
980  requested_height < vcaps->MinOutputSize.cy)
981  goto next;
982  bih->biWidth = requested_width;
983  bih->biHeight = requested_height;
984  }
985  } else {
986  WAVEFORMATEX *fx;
987  AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
988 #if DSHOWDEBUG
990 #endif
991  if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
992  fx = (void *) type->pbFormat;
993  } else {
994  goto next;
995  }
996  if (!pformat_set) {
997  av_log(
998  avctx,
999  AV_LOG_INFO,
1000  " ch=%2u, bits=%2u, rate=%6lu\n",
1001  fx->nChannels, fx->wBitsPerSample, fx->nSamplesPerSec
1002  );
1003  continue;
1004  }
1005  if (
1006  (ctx->sample_rate && ctx->sample_rate != fx->nSamplesPerSec) ||
1007  (ctx->sample_size && ctx->sample_size != fx->wBitsPerSample) ||
1008  (ctx->channels && ctx->channels != fx->nChannels )
1009  ) {
1010  goto next;
1011  }
1012  }
1013 
1014  // found a matching format. Either apply or store
1015  // for safekeeping if we might maybe find a better
1016  // format with more info attached to it (see comment
1017  // above loop)
1018  if (!wait_for_better) {
1019  if (IAMStreamConfig_SetFormat(config, type) != S_OK)
1020  goto next;
1021  format_set = 1;
1022  }
1023  else if (!previous_match_type) {
1024  // store this matching format for possible later use.
1025  // If we have already found a matching format, ignore it
1026  previous_match_type = type;
1027  type = NULL;
1028  }
1029 next:
1030  av_freep(&fmt_info);
1031  if (type && type->pbFormat)
1032  CoTaskMemFree(type->pbFormat);
1033  CoTaskMemFree(type);
1034  type = NULL;
1035  }
1036 
1037  // set the pin's format, if wanted
1038  if (pformat_set && !format_set) {
1039  if (previous_match_type) {
1040  // previously found a matching VIDEOINFOHEADER format and stored
1041  // it for safe keeping. Searching further for a matching
1042  // VIDEOINFOHEADER2 format yielded nothing. So set the pin's
1043  // format based on the VIDEOINFOHEADER format.
1044  // NB: this never applies to an audio format because
1045  // previous_match_type always NULL in that case
1046  if (IAMStreamConfig_SetFormat(config, previous_match_type) == S_OK)
1047  format_set = 1;
1048  }
1049  else if (use_default) {
1050  // default format returned by device apparently was not contained
1051  // in the capabilities of any of the formats returned by the device
1052  // (sic?). Fall back to directly setting the default format
1054  if (IAMStreamConfig_SetFormat(config, type) == S_OK)
1055  format_set = 1;
1056  if (type && type->pbFormat)
1057  CoTaskMemFree(type->pbFormat);
1058  CoTaskMemFree(type);
1059  type = NULL;
1060  }
1061  }
1062 
1063 end:
1064  if (previous_match_type && previous_match_type->pbFormat)
1065  CoTaskMemFree(previous_match_type->pbFormat);
1066  CoTaskMemFree(previous_match_type);
1067  IAMStreamConfig_Release(config);
1068  av_free(caps);
1069  if (pformat_set)
1070  *pformat_set = format_set;
1071 }
1072 
1073 /**
1074  * Set audio device buffer size in milliseconds (which can directly impact
1075  * latency, depending on the device).
1076  */
1077 static int
1079 {
1080  struct dshow_ctx *ctx = avctx->priv_data;
1081  IAMBufferNegotiation *buffer_negotiation = NULL;
1082  ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
1083  IAMStreamConfig *config = NULL;
1084  AM_MEDIA_TYPE *type = NULL;
1085  int ret = AVERROR(EIO);
1086 
1087  if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
1088  goto end;
1089  if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
1090  goto end;
1091  if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
1092  goto end;
1093 
1094  props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
1095  * ctx->audio_buffer_size / 1000;
1096 
1097  if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
1098  goto end;
1099  if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
1100  goto end;
1101 
1102  ret = 0;
1103 
1104 end:
1105  if (buffer_negotiation)
1106  IAMBufferNegotiation_Release(buffer_negotiation);
1107  if (type) {
1108  if (type->pbFormat)
1109  CoTaskMemFree(type->pbFormat);
1110  CoTaskMemFree(type);
1111  }
1112  if (config)
1113  IAMStreamConfig_Release(config);
1114 
1115  return ret;
1116 }
1117 
1118 /**
1119  * Pops up a user dialog allowing them to adjust properties for the given filter, if possible.
1120  */
1121 void
1123  ISpecifyPropertyPages *property_pages = NULL;
1124  IUnknown *device_filter_iunknown = NULL;
1125  HRESULT hr;
1126  FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */
1127  CAUUID ca_guid = {0};
1128 
1129  hr = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages);
1130  if (hr != S_OK) {
1131  av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show");
1132  goto end;
1133  }
1134  hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info);
1135  if (hr != S_OK) {
1136  goto fail;
1137  }
1138  hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown);
1139  if (hr != S_OK) {
1140  goto fail;
1141  }
1142  hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid);
1143  if (hr != S_OK) {
1144  goto fail;
1145  }
1146  hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems,
1147  ca_guid.pElems, 0, 0, NULL);
1148  if (hr != S_OK) {
1149  goto fail;
1150  }
1151  goto end;
1152 fail:
1153  av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter");
1154 end:
1155  if (property_pages)
1156  ISpecifyPropertyPages_Release(property_pages);
1157  if (device_filter_iunknown)
1158  IUnknown_Release(device_filter_iunknown);
1159  if (filter_info.pGraph)
1160  IFilterGraph_Release(filter_info.pGraph);
1161  if (ca_guid.pElems)
1162  CoTaskMemFree(ca_guid.pElems);
1163 }
1164 
1165 /**
1166  * Cycle through available pins using the device_filter device, of type
1167  * devtype, retrieve the first output pin and return the pointer to the
1168  * object found in *ppin.
1169  * If ppin is NULL, cycle through all pins listing audio/video capabilities.
1170  */
1171 static int
1173  enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
1174 {
1175  struct dshow_ctx *ctx = avctx->priv_data;
1176  IEnumPins *pins = 0;
1177  IPin *device_pin = NULL;
1178  IPin *pin;
1179  int r;
1180 
1181  const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
1182  const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";
1183 
1184  int set_format = dshow_should_set_format(avctx, devtype);
1185  int format_set = 0;
1186  int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;
1187 
1188  if (should_show_properties)
1190 
1191  r = IBaseFilter_EnumPins(device_filter, &pins);
1192  if (r != S_OK) {
1193  av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
1194  return AVERROR(EIO);
1195  }
1196 
1197  if (!ppin) {
1198  av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
1199  devtypename, sourcetypename);
1200  }
1201 
1202  while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
1203  IKsPropertySet *p = NULL;
1204  PIN_INFO info = {0};
1205  GUID category;
1206  DWORD r2;
1207  char *name_buf = NULL;
1208  wchar_t *pin_id = NULL;
1209  char *pin_buf = NULL;
1210  char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;
1211 
1212  IPin_QueryPinInfo(pin, &info);
1213  IBaseFilter_Release(info.pFilter);
1214 
1215  if (info.dir != PINDIR_OUTPUT)
1216  goto next;
1217  if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
1218  goto next;
1219  if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
1220  NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
1221  goto next;
1222  if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
1223  goto next;
1224  name_buf = dup_wchar_to_utf8(info.achName);
1225 
1226  r = IPin_QueryId(pin, &pin_id);
1227  if (r != S_OK) {
1228  av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
1229  return AVERROR(EIO);
1230  }
1231  pin_buf = dup_wchar_to_utf8(pin_id);
1232 
1233  if (!ppin) {
1234  av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
1235  dshow_cycle_formats(avctx, devtype, pin, NULL);
1236  goto next;
1237  }
1238 
1239  if (desired_pin_name) {
1240  if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
1241  av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
1242  name_buf, pin_buf, desired_pin_name);
1243  goto next;
1244  }
1245  }
1246 
1247  // will either try to find format matching options supplied by user
1248  // or try to open default format. Successful if returns with format_set==1
1249  dshow_cycle_formats(avctx, devtype, pin, &format_set);
1250  if (!format_set) {
1251  goto next;
1252  }
1253 
1254  if (devtype == AudioDevice && ctx->audio_buffer_size) {
1255  if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
1256  av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
1257  }
1258  }
1259 
1260  if (format_set) {
1261  device_pin = pin;
1262  av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
1263  }
1264 next:
1265  if (p)
1266  IKsPropertySet_Release(p);
1267  if (device_pin != pin)
1268  IPin_Release(pin);
1269  av_free(name_buf);
1270  av_free(pin_buf);
1271  if (pin_id)
1272  CoTaskMemFree(pin_id);
1273  }
1274 
1275  IEnumPins_Release(pins);
1276 
1277  if (ppin) {
1278  if (set_format && !format_set) {
1279  av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
1280  return AVERROR(EIO);
1281  }
1282  if (!device_pin) {
1283  av_log(avctx, AV_LOG_ERROR,
1284  "Could not find output pin from %s capture device.\n", devtypename);
1285  return AVERROR(EIO);
1286  }
1287  *ppin = device_pin;
1288  }
1289 
1290  return 0;
1291 }
1292 
1293 /**
1294  * List options for device with type devtype, source filter type sourcetype
1295  *
1296  * @param devenum device enumerator used for accessing the device
1297  */
1298 static int
1299 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
1300  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
1301 {
1302  struct dshow_ctx *ctx = avctx->priv_data;
1303  IBaseFilter *device_filter = NULL;
1304  char *device_unique_name = NULL;
1305  int r;
1306 
1307  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name, NULL)) < 0)
1308  return r;
1309  ctx->device_filter[devtype] = device_filter;
1310  ctx->device_unique_name[devtype] = device_unique_name;
1311  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, NULL)) < 0)
1312  return r;
1313  return 0;
1314 }
1315 
1316 static int
1317 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
1318  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
1319 {
1320  struct dshow_ctx *ctx = avctx->priv_data;
1321  IBaseFilter *device_filter = NULL;
1322  char *device_filter_unique_name = NULL;
1323  IGraphBuilder *graph = ctx->graph;
1324  IPin *device_pin = NULL;
1327  ICaptureGraphBuilder2 *graph_builder2 = NULL;
1328  int ret = AVERROR(EIO);
1329  int r;
1330  IStream *ifile_stream = NULL;
1331  IStream *ofile_stream = NULL;
1332  IPersistStream *pers_stream = NULL;
1333  enum dshowDeviceType otherDevType = (devtype == VideoDevice) ? AudioDevice : VideoDevice;
1334 
1335  const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
1336 
1337 
1338  if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
1339  ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
1340  HRESULT hr;
1341  char *filename = NULL;
1342 
1343  if (sourcetype == AudioSourceDevice)
1344  filename = ctx->audio_filter_load_file;
1345  else
1346  filename = ctx->video_filter_load_file;
1347 
1348  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
1349  if (S_OK != hr) {
1350  av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
1351  goto error;
1352  }
1353 
1354  hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
1355  if (hr != S_OK) {
1356  av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
1357  goto error;
1358  }
1359 
1360  if (sourcetype == AudioSourceDevice)
1361  av_log(avctx, AV_LOG_INFO, "Audio-");
1362  else
1363  av_log(avctx, AV_LOG_INFO, "Video-");
1364  av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
1365  } else {
1366 
1367  if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_filter_unique_name, NULL)) < 0) {
1368  ret = r;
1369  goto error;
1370  }
1371  }
1372  if (ctx->device_filter[otherDevType]) {
1373  // avoid adding add two instances of the same device to the graph, one for video, one for audio
1374  // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK)
1375  if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) {
1376  av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name);
1377  IBaseFilter_Release(device_filter);
1378  device_filter = ctx->device_filter[otherDevType];
1379  IBaseFilter_AddRef(ctx->device_filter[otherDevType]);
1380  } else {
1381  av_log(avctx, AV_LOG_DEBUG, "not reusing previous graph capture filter %s != %s\n", device_filter_unique_name, ctx->device_unique_name[otherDevType]);
1382  }
1383  }
1384 
1385  ctx->device_filter [devtype] = device_filter;
1386  ctx->device_unique_name [devtype] = device_filter_unique_name;
1387 
1388  r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
1389  if (r != S_OK) {
1390  av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
1391  goto error;
1392  }
1393 
1394  if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
1395  ret = r;
1396  goto error;
1397  }
1398 
1399  ctx->device_pin[devtype] = device_pin;
1400 
1401  capture_filter = ff_dshow_filter_Create(avctx, callback, devtype);
1402  if (!capture_filter) {
1403  av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
1404  goto error;
1405  }
1406  ctx->capture_filter[devtype] = capture_filter;
1407 
1408  if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
1409  ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
1410 
1411  HRESULT hr;
1412  char *filename = NULL;
1413 
1414  if (sourcetype == AudioSourceDevice)
1415  filename = ctx->audio_filter_save_file;
1416  else
1417  filename = ctx->video_filter_save_file;
1418 
1419  hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
1420  if (S_OK != hr) {
1421  av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
1422  goto error;
1423  }
1424 
1425  hr = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
1426  if (hr != S_OK) {
1427  av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
1428  goto error;
1429  }
1430 
1431  hr = OleSaveToStream(pers_stream, ofile_stream);
1432  if (hr != S_OK) {
1433  av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
1434  goto error;
1435  }
1436 
1437  hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
1438  if (S_OK != hr) {
1439  av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
1440  goto error;
1441  }
1442 
1443  if (sourcetype == AudioSourceDevice)
1444  av_log(avctx, AV_LOG_INFO, "Audio-");
1445  else
1446  av_log(avctx, AV_LOG_INFO, "Video-");
1447  av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
1448  }
1449 
1450  r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
1451  filter_name[devtype]);
1452  if (r != S_OK) {
1453  av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
1454  goto error;
1455  }
1456 
1459  ctx->capture_pin[devtype] = capture_pin;
1460 
1461  r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
1462  &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
1463  if (r != S_OK) {
1464  av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
1465  goto error;
1466  }
1467  ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
1468  if (r != S_OK) {
1469  av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
1470  goto error;
1471  }
1472 
1473  r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
1474  (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */
1475 
1476  if (r != S_OK) {
1477  av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
1478  goto error;
1479  }
1480 
1481  r = ff_dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);
1482 
1483  if (r != S_OK) {
1484  av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
1485  goto error;
1486  }
1487 
1488  ret = 0;
1489 
1490 error:
1491  if (graph_builder2 != NULL)
1492  ICaptureGraphBuilder2_Release(graph_builder2);
1493 
1494  if (pers_stream)
1495  IPersistStream_Release(pers_stream);
1496 
1497  if (ifile_stream)
1498  IStream_Release(ifile_stream);
1499 
1500  if (ofile_stream)
1501  IStream_Release(ofile_stream);
1502 
1503  return ret;
1504 }
1505 
1506 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
1507 {
1508  switch (sample_fmt) {
1509  case AV_SAMPLE_FMT_U8: return AV_CODEC_ID_PCM_U8;
1512  default: return AV_CODEC_ID_NONE; /* Should never happen. */
1513  }
1514 }
1515 
1517 {
1518  switch (bits) {
1519  case 8: return AV_SAMPLE_FMT_U8;
1520  case 16: return AV_SAMPLE_FMT_S16;
1521  case 32: return AV_SAMPLE_FMT_S32;
1522  default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
1523  }
1524 }
1525 
1526 static int
1528  enum dshowDeviceType devtype)
1529 {
1530  struct dshow_ctx *ctx = avctx->priv_data;
1531  AM_MEDIA_TYPE type;
1532  AVCodecParameters *par;
1533  AVStream *st;
1534  struct dshow_format_info *fmt_info = NULL;
1535  int ret = AVERROR(EIO);
1536 
1537  type.pbFormat = NULL;
1538 
1539  st = avformat_new_stream(avctx, NULL);
1540  if (!st) {
1541  ret = AVERROR(ENOMEM);
1542  goto error;
1543  }
1544  st->id = devtype;
1545 
1546  ctx->capture_filter[devtype]->stream_index = st->index;
1547 
1549  fmt_info = dshow_get_format_info(&type);
1550  if (!fmt_info) {
1551  ret = AVERROR(EIO);
1552  goto error;
1553  }
1554 
1555  par = st->codecpar;
1556  if (devtype == VideoDevice) {
1557  BITMAPINFOHEADER *bih = NULL;
1558  AVRational time_base;
1559 
1560  if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
1561  VIDEOINFOHEADER *v = (void *) type.pbFormat;
1562  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
1563  bih = &v->bmiHeader;
1564  } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
1565  VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
1566  time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
1567  bih = &v->bmiHeader;
1568  }
1569  if (!bih) {
1570  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1571  goto error;
1572  }
1573 
1574  st->avg_frame_rate = av_inv_q(time_base);
1575  st->r_frame_rate = av_inv_q(time_base);
1576 
1578  par->width = fmt_info->width;
1579  par->height = fmt_info->height;
1580  par->codec_tag = bih->biCompression;
1581  par->format = fmt_info->pix_fmt;
1582  if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
1583  av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
1584  par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
1585  }
1586  par->color_range = fmt_info->col_range;
1587  par->color_space = fmt_info->col_space;
1588  par->color_primaries = fmt_info->col_prim;
1589  par->color_trc = fmt_info->col_trc;
1590  par->chroma_location = fmt_info->chroma_loc;
1591  par->codec_id = fmt_info->codec_id;
1592  if (par->codec_id == AV_CODEC_ID_RAWVIDEO) {
1593  if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
1594  par->bits_per_coded_sample = bih->biBitCount;
1595  if (par->height < 0) {
1596  par->height *= -1;
1597  } else {
1599  if (par->extradata) {
1600  par->extradata_size = 9;
1601  memcpy(par->extradata, "BottomUp", 9);
1602  }
1603  }
1604  }
1605  } else {
1606  if (par->codec_id == AV_CODEC_ID_NONE) {
1607  av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
1608  "Please report type 0x%X.\n", (int) bih->biCompression);
1610  goto error;
1611  }
1612  par->bits_per_coded_sample = bih->biBitCount;
1613  }
1614  } else {
1615  if (!IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
1616  av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
1617  goto error;
1618  }
1619 
1621  par->format = sample_fmt_bits_per_sample(fmt_info->sample_size);
1622  par->codec_id = waveform_codec_id(par->format);
1623  par->sample_rate = fmt_info->sample_rate;
1624  par->channels = fmt_info->channels;
1625  }
1626 
1627  avpriv_set_pts_info(st, 64, 1, 10000000);
1628 
1629  ret = 0;
1630 
1631 error:
1632  av_freep(&fmt_info);
1633  if (type.pbFormat)
1634  CoTaskMemFree(type.pbFormat);
1635  return ret;
1636 }
1637 
1639 {
1640  struct dshow_ctx *ctx = avctx->priv_data;
1641  char **device_name = ctx->device_name;
1642  char *name = av_strdup(avctx->url);
1643  char *tmp = name;
1644  int ret = 1;
1645  char *type;
1646 
1647  while ((type = strtok(tmp, "="))) {
1648  char *token = strtok(NULL, ":");
1649  tmp = NULL;
1650 
1651  if (!strcmp(type, "video")) {
1652  device_name[0] = token;
1653  } else if (!strcmp(type, "audio")) {
1654  device_name[1] = token;
1655  } else {
1656  device_name[0] = NULL;
1657  device_name[1] = NULL;
1658  break;
1659  }
1660  }
1661 
1662  if (!device_name[0] && !device_name[1]) {
1663  ret = 0;
1664  } else {
1665  if (device_name[0])
1667  if (device_name[1])
1669  }
1670 
1671  av_free(name);
1672  return ret;
1673 }
1674 
1676 {
1677  struct dshow_ctx *ctx = avctx->priv_data;
1678  IGraphBuilder *graph = NULL;
1679  ICreateDevEnum *devenum = NULL;
1680  IMediaControl *control = NULL;
1681  IMediaEvent *media_event = NULL;
1682  HANDLE media_event_handle;
1683  HANDLE proc;
1684  int ret = AVERROR(EIO);
1685  int r;
1686 
1687  CoInitialize(0);
1688 
1689  if (!ctx->list_devices && !parse_device_name(avctx)) {
1690  av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
1691  goto error;
1692  }
1693 
1694  ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
1696  if (ctx->pixel_format != AV_PIX_FMT_NONE) {
1698  av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
1699  "video codec is not set or set to rawvideo\n");
1700  ret = AVERROR(EINVAL);
1701  goto error;
1702  }
1703  }
1704  if (ctx->framerate) {
1705  r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
1706  if (r < 0) {
1707  av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
1708  goto error;
1709  }
1710  }
1711 
1712  r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1713  &IID_IGraphBuilder, (void **) &graph);
1714  if (r != S_OK) {
1715  av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
1716  goto error;
1717  }
1718  ctx->graph = graph;
1719 
1720  r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
1721  &IID_ICreateDevEnum, (void **) &devenum);
1722  if (r != S_OK) {
1723  av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
1724  goto error;
1725  }
1726 
1727  if (ctx->list_devices) {
1730  ret = AVERROR_EXIT;
1731  goto error;
1732  }
1733  if (ctx->list_options) {
1734  if (ctx->device_name[VideoDevice])
1735  if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) {
1736  ret = r;
1737  goto error;
1738  }
1739  if (ctx->device_name[AudioDevice]) {
1741  /* show audio options from combined video+audio sources as fallback */
1742  if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) {
1743  ret = r;
1744  goto error;
1745  }
1746  }
1747  }
1748  // don't exit yet, allow it to list crossbar options in dshow_open_device
1749  }
1750  if (ctx->device_name[VideoDevice]) {
1751  if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 ||
1752  (r = dshow_add_device(avctx, VideoDevice)) < 0) {
1753  ret = r;
1754  goto error;
1755  }
1756  }
1757  if (ctx->device_name[AudioDevice]) {
1758  if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 ||
1759  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1760  av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]);
1761  /* see if there's a video source with an audio pin with the given audio name */
1762  if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 ||
1763  (r = dshow_add_device(avctx, AudioDevice)) < 0) {
1764  ret = r;
1765  goto error;
1766  }
1767  }
1768  }
1769  if (ctx->list_options) {
1770  /* allow it to list crossbar options in dshow_open_device */
1771  ret = AVERROR_EXIT;
1772  goto error;
1773  }
1774  ctx->curbufsize[0] = 0;
1775  ctx->curbufsize[1] = 0;
1776  ctx->mutex = CreateMutex(NULL, 0, NULL);
1777  if (!ctx->mutex) {
1778  av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
1779  goto error;
1780  }
1781  ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
1782  if (!ctx->event[1]) {
1783  av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
1784  goto error;
1785  }
1786 
1787  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
1788  if (r != S_OK) {
1789  av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
1790  goto error;
1791  }
1792  ctx->control = control;
1793 
1794  r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
1795  if (r != S_OK) {
1796  av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
1797  goto error;
1798  }
1799  ctx->media_event = media_event;
1800 
1801  r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
1802  if (r != S_OK) {
1803  av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
1804  goto error;
1805  }
1806  proc = GetCurrentProcess();
1807  r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
1808  0, 0, DUPLICATE_SAME_ACCESS);
1809  if (!r) {
1810  av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
1811  goto error;
1812  }
1813 
1814  r = IMediaControl_Run(control);
1815  if (r == S_FALSE) {
1816  OAFilterState pfs;
1817  r = IMediaControl_GetState(control, 0, &pfs);
1818  }
1819  if (r != S_OK) {
1820  av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n");
1821  goto error;
1822  }
1823 
1824  ret = 0;
1825 
1826 error:
1827 
1828  if (devenum)
1829  ICreateDevEnum_Release(devenum);
1830 
1831  if (ret < 0)
1832  dshow_read_close(avctx);
1833 
1834  return ret;
1835 }
1836 
1837 /**
1838  * Checks media events from DirectShow and returns -1 on error or EOF. Also
1839  * purges all events that might be in the event queue to stop the trigger
1840  * of event notification.
1841  */
1842 static int dshow_check_event_queue(IMediaEvent *media_event)
1843 {
1844  LONG_PTR p1, p2;
1845  long code;
1846  int ret = 0;
1847 
1848  while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1849  if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
1850  ret = -1;
1851  IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1852  }
1853 
1854  return ret;
1855 }
1856 
1858 {
1859  struct dshow_ctx *ctx = s->priv_data;
1861 
1862  while (!ctx->eof && !pktl) {
1863  WaitForSingleObject(ctx->mutex, INFINITE);
1864  pktl = ctx->pktl;
1865  if (pktl) {
1866  *pkt = pktl->pkt;
1867  ctx->pktl = ctx->pktl->next;
1868  av_free(pktl);
1869  ctx->curbufsize[pkt->stream_index] -= pkt->size;
1870  }
1871  ResetEvent(ctx->event[1]);
1872  ReleaseMutex(ctx->mutex);
1873  if (!pktl) {
1874  if (dshow_check_event_queue(ctx->media_event) < 0) {
1875  ctx->eof = 1;
1876  } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
1877  return AVERROR(EAGAIN);
1878  } else {
1879  WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
1880  }
1881  }
1882  }
1883 
1884  return ctx->eof ? AVERROR(EIO) : pkt->size;
1885 }
1886 
1887 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1888 #define DEC AV_OPT_FLAG_DECODING_PARAM
1889 static const AVOption options[] = {
1890  { "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 },
1891  { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC },
1892  { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
1893  { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1894  { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
1895  { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
1896  { "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 },
1897  { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1898  { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, DEC },
1899  { "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 },
1900  { "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 },
1901  { "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 },
1902  { "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 },
1903  { "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 },
1904  { "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 },
1905  { "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 },
1906  { "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 },
1907  { "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 },
1908  { "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 },
1909  { "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 },
1910  { "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 },
1911  { "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 },
1912  { "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 },
1913  { "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 },
1914  { "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 },
1915  { "use_video_device_timestamps", "use device instead of wallclock timestamps for video frames", OFFSET(use_video_device_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
1916  { NULL },
1917 };
1918 
1919 static const AVClass dshow_class = {
1920  .class_name = "dshow indev",
1921  .item_name = av_default_item_name,
1922  .option = options,
1923  .version = LIBAVUTIL_VERSION_INT,
1925 };
1926 
1928  .name = "dshow",
1929  .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"),
1930  .priv_data_size = sizeof(struct dshow_ctx),
1932  .read_packet = dshow_read_packet,
1933  .read_close = dshow_read_close,
1934  .get_device_list= dshow_get_device_list,
1936  .priv_class = &dshow_class,
1937 };
AVCOL_PRI_RESERVED
@ AVCOL_PRI_RESERVED
Definition: pixfmt.h:473
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:424
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
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:483
dshow_format_info::height
int height
Definition: dshow.c:684
dshow_open_device
static int dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
Definition: dshow.c:1317
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:768
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
dshow_ctx::list_devices
int list_devices
Definition: dshow_capture.h:301
space
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated space
Definition: undefined.txt:4
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:494
dshow_get_format_info
static struct dshow_format_info * dshow_get_format_info(AM_MEDIA_TYPE *type)
Definition: dshow.c:692
dshow_ctx::requested_width
int requested_width
Definition: dshow_capture.h:341
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
VideoDevice
@ VideoDevice
Definition: dshow_capture.h:63
dshow_color_primaries
static enum AVColorPrimaries dshow_color_primaries(DXVA2_ExtendedFormat *fmt_info)
Definition: dshow.c:130
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:149
ff_dshow_pin_Release
unsigned long WINAPI ff_dshow_pin_Release(DShowPin *)
dshow_ctx::media_event
IMediaEvent * media_event
Definition: dshow_capture.h:335
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:503
dshow_capture.h
AVDeviceInfo::device_name
char * device_name
device name, format depends on device
Definition: avdevice.h:458
dshow_ctx::video_filter_save_file
char * video_filter_save_file
Definition: dshow_capture.h:316
DEC
#define DEC
Definition: dshow.c:1888
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:63
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:167
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:597
dshow_read_close
static int dshow_read_close(AVFormatContext *s)
Definition: dshow.c:238
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:322
dshow_class
static const AVClass dshow_class
Definition: dshow.c:1919
AVOption
AVOption.
Definition: opt.h:247
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:497
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1634
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:1015
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
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:510
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
dshow_format_info::framerate
int64_t framerate
Definition: dshow.c:675
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:469
waveform_codec_id
static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
Definition: dshow.c:1506
AVFormatContext::video_codec_id
enum AVCodecID video_codec_id
Forced video codec_id.
Definition: avformat.h:1375
AVFMT_NOBINSEARCH
#define AVFMT_NOBINSEARCH
Format does not allow to fall back on binary search via read_timestamp.
Definition: avformat.h:481
dshow_ctx::device_filter
IBaseFilter * device_filter[2]
Definition: dshow_capture.h:319
dshow_pixfmt
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
Definition: dshow.c:59
AVCOL_SPC_BT2020_CL
@ AVCOL_SPC_BT2020_CL
ITU-R BT2020 constant luminance system.
Definition: pixfmt.h:535
tf_sess_config.config
config
Definition: tf_sess_config.py:33
sample_rate
sample_rate
Definition: ffmpeg_filter.c:153
av_chroma_location_name
const char * av_chroma_location_name(enum AVChromaLocation location)
Definition: pixdesc.c:3069
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
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:147
framerate
int framerate
Definition: h264_levels.c:65
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:529
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
graph
ofilter graph
Definition: ffmpeg_filter.c:171
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:508
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3048
dshow_ctx::capture_pin
DShowPin * capture_pin[2]
Definition: dshow_capture.h:322
dshow_ctx::audio_device_number
int audio_device_number
Definition: dshow_capture.h:298
dshow_color_trc
static enum AVColorTransferCharacteristic dshow_color_trc(DXVA2_ExtendedFormat *fmt_info)
Definition: dshow.c:167
fail
#define fail()
Definition: checkasm.h:127
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:500
dshow_format_info::col_trc
enum AVColorTransferCharacteristic col_trc
Definition: dshow.c:681
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 available from the specified pin, try to set parameters specified thr...
Definition: dshow.c:794
dshow_read_header
static int dshow_read_header(AVFormatContext *avctx)
Definition: dshow.c:1675
AVCOL_TRC_LOG_SQRT
@ AVCOL_TRC_LOG_SQRT
"Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)"
Definition: pixfmt.h:505
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:499
raw.h
dshow_ctx
Definition: dshow_capture.h:287
DShowFilter::pin
DShowPin * pin
Definition: dshow_capture.h:256
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:148
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:1842
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:650
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVCodecTag
Definition: internal.h:51
sample_fmt_bits_per_sample
static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
Definition: dshow.c:1516
dshow_ctx::show_analog_tv_tuner_audio_dialog
int show_analog_tv_tuner_audio_dialog
Definition: dshow_capture.h:312
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:655
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
dshow_get_device_list
static int dshow_get_device_list(AVFormatContext *avctx, AVDeviceInfoList *device_list)
Definition: dshow.c:628
dshow_cycle_devices
static int dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter **pfilter, char **device_unique_name, AVDeviceInfoList **device_list)
Cycle through available devices using the device enumerator devenum, retrieve the device with type sp...
Definition: dshow.c:462
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
dshow_get_device_media_types
static void dshow_get_device_media_types(AVFormatContext *avctx, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, enum AVMediaType **media_types, int *nb_media_types)
Definition: dshow.c:381
dshow_format_info::sample_rate
int sample_rate
Definition: dshow.c:686
ctx
AVFormatContext * ctx
Definition: movenc.c:48
dshow_read_packet
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dshow.c:1857
channels
channels
Definition: aptx.h:33
AVCOL_PRI_SMPTE428
@ AVCOL_PRI_SMPTE428
SMPTE ST 428-1 (CIE 1931 XYZ)
Definition: pixfmt.h:481
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:1172
DShowFilter
Definition: dshow_capture.h:250
AVCOL_PRI_SMPTE240M
@ AVCOL_PRI_SMPTE240M
identical to above, also called "SMPTE C" even though it uses D65
Definition: pixfmt.h:478
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:472
f
#define f(width, name)
Definition: cbs_vp9.c:255
dshow_format_info::col_prim
enum AVColorPrimaries col_prim
Definition: dshow.c:680
AVDeviceInfo::media_types
enum AVMediaType * media_types
array indicating what media types(s), if any, a device can provide.
Definition: avdevice.h:460
AVCOL_PRI_BT470BG
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:476
callback
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
Definition: dshow.c:341
AVCOL_PRI_SMPTE170M
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:477
if
if(ret)
Definition: filter_design.txt:179
AVDeviceInfo::nb_media_types
int nb_media_types
length of media_types array, 0 if device cannot provide any media types
Definition: avdevice.h:461
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:2988
AVFormatContext
Format I/O context.
Definition: avformat.h:1200
dshow_format_info
Definition: dshow.c:672
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1095
dshow_format_info::channels
int channels
Definition: dshow.c:688
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
AVCHROMA_LOC_LEFT
@ AVCHROMA_LOC_LEFT
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
Definition: pixfmt.h:618
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:1299
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:620
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
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:471
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
parseutils.h
dshow_color_space
static enum AVColorSpace dshow_color_space(DXVA2_ExtendedFormat *fmt_info)
Definition: dshow.c:106
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3006
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:509
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
PacketListEntry::next
struct PacketListEntry * next
Definition: packet_internal.h:27
ff_print_AUDIO_STREAM_CONFIG_CAPS
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
Definition: dshow_common.c:115
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:563
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
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:480
dshow_format_info::col_range
enum AVColorRange col_range
Definition: dshow.c:678
avcodec_find_decoder
const AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:921
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
AVCOL_PRI_SMPTE431
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition: pixfmt.h:483
dshow_chroma_loc
static enum AVChromaLocation dshow_chroma_loc(DXVA2_ExtendedFormat *fmt_info)
Definition: dshow.c:222
dshow_ctx::list_options
int list_options
Definition: dshow_capture.h:300
AudioDevice
@ AudioDevice
Definition: dshow_capture.h:64
AVMediaType
AVMediaType
Definition: avutil.h:199
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
avpriv_pix_fmt_find
enum AVPixelFormat avpriv_pix_fmt_find(enum PixelFormatTagLists list, unsigned fourcc)
Definition: raw.c:352
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:502
dshow_ctx::requested_framerate
AVRational requested_framerate
Definition: dshow_capture.h:343
dshow_ctx::use_video_device_timestamps
int use_video_device_timestamps
Definition: dshow_capture.h:317
AVCOL_TRC_SMPTEST2084
@ AVCOL_TRC_SMPTEST2084
Definition: pixfmt.h:512
AVCOL_TRC_LOG
@ AVCOL_TRC_LOG
"Logarithmic transfer characteristic (100:1 range)"
Definition: pixfmt.h:504
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1283
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:1122
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
size
int size
Definition: twinvq_data.h:10344
PIX_FMT_LIST_RAW
@ PIX_FMT_LIST_RAW
Definition: raw.h:40
dshow_get_default_format
static void dshow_get_default_format(IPin *pin, IAMStreamConfig *config, enum dshowDeviceType devtype, AM_MEDIA_TYPE **type)
Definition: dshow.c:761
PacketListEntry::pkt
AVPacket pkt
Definition: packet_internal.h:28
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:464
AVDeviceInfo
Structure describes basic parameters of the device.
Definition: avdevice.h:457
AVCHROMA_LOC_UNSPECIFIED
@ AVCHROMA_LOC_UNSPECIFIED
Definition: pixfmt.h:617
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:333
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
Definition: mem.c:232
dshow_ctx::show_video_device_dialog
int show_video_device_dialog
Definition: dshow_capture.h:307
AVDeviceInfo::device_description
char * device_description
human friendly name
Definition: avdevice.h:459
options
static const AVOption options[]
Definition: dshow.c:1889
dshow_format_info::col_space
enum AVColorSpace col_space
Definition: dshow.c:679
AudioSourceDevice
@ AudioSourceDevice
Definition: dshow_capture.h:69
dshow_color_range
static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
Definition: dshow.c:82
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:1527
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:496
AVChromaLocation
AVChromaLocation
Location of chroma samples.
Definition: pixfmt.h:616
dshow_format_info::codec_id
enum AVCodecID codec_id
Definition: dshow.c:677
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:531
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
dshow_ctx::requested_height
int requested_height
Definition: dshow_capture.h:342
dup_wchar_to_utf8
static char * dup_wchar_to_utf8(wchar_t *w)
Definition: dshow.c:312
EC_DEVICE_LOST
#define EC_DEVICE_LOST
Definition: dshow_capture.h:41
PacketListEntry
Definition: packet_internal.h:26
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
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:534
dshow_format_info::devtype
enum dshowDeviceType devtype
Definition: dshow.c:673
AV_SAMPLE_FMT_U8
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition: samplefmt.h:60
AVCodecParameters::height
int height
Definition: codec_par.h:127
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:523
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:392
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:337
dshow_ctx::capture_filter
DShowFilter * capture_filter[2]
Definition: dshow_capture.h:321
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_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:526
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:580
AVFMT_FLAG_NONBLOCK
#define AVFMT_FLAG_NONBLOCK
Do not block when reading packets from input.
Definition: avformat.h:1321
dshow_format_info::width
int width
Definition: dshow.c:683
AVCOL_PRI_BT470M
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:474
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:949
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:935
dshow_ctx::pktl
PacketListEntry * pktl
Definition: dshow_capture.h:327
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:381
AVDeviceInfoList
List of devices.
Definition: avdevice.h:467
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AVCodecParameters::chroma_location
enum AVChromaLocation chroma_location
Definition: codec_par.h:150
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:1078
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:71
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:943
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:515
dshow_ctx::show_analog_tv_tuner_dialog
int show_analog_tv_tuner_dialog
Definition: dshow_capture.h:311
AVCHROMA_LOC_CENTER
@ AVCHROMA_LOC_CENTER
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
Definition: pixfmt.h:619
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:320
AVFMT_NOGENSEARCH
#define AVFMT_NOGENSEARCH
Format does not allow to fall back on generic search.
Definition: avformat.h:482
ff_dshow_demuxer
const AVInputFormat ff_dshow_demuxer
Definition: dshow.c:1927
dshow_ctx::sample_size
int sample_size
Definition: dshow_capture.h:346
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:1084
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:1196
ff_dshow_pin_ConnectionMediaType
long WINAPI ff_dshow_pin_ConnectionMediaType(DShowPin *, AM_MEDIA_TYPE *)
Definition: dshow_pin.c:91
AV_OPT_TYPE_PIXEL_FMT
@ AV_OPT_TYPE_PIXEL_FMT
Definition: opt.h:235
AVPacket::stream_index
int stream_index
Definition: packet.h:375
dshow_should_set_format
static int dshow_should_set_format(AVFormatContext *avctx, enum dshowDeviceType devtype)
Definition: dshow.c:660
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:279
ff_dshow_pin_AddRef
unsigned long WINAPI ff_dshow_pin_AddRef(DShowPin *)
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
mem.h
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_format_info::chroma_loc
enum AVChromaLocation chroma_loc
Definition: dshow.c:682
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:334
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
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
dshow_format_info::pix_fmt
enum AVPixelFormat pix_fmt
Definition: dshow.c:676
WaitForSingleObject
#define WaitForSingleObject(a, b)
Definition: w32pthreads.h:64
parse_device_name
static int parse_device_name(AVFormatContext *avctx)
Definition: dshow.c:1638
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
dshow_format_info::sample_size
int sample_size
Definition: dshow.c:687
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
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:525
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:562
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:1228
ff_dshow_filter_Release
unsigned long WINAPI ff_dshow_filter_Release(DShowFilter *)
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3027
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:2580
OFFSET
#define OFFSET(x)
Definition: dshow.c:1887
dshow_ctx::device_unique_name
char * device_unique_name[2]
Definition: dshow_capture.h:295
AMCONTROL_COLORINFO_PRESENT
#define AMCONTROL_COLORINFO_PRESENT
Definition: dshow.c:55