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