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