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