32#define MOD_NAME "[dshow] "
37typedef void (*
convert_t)(
int width,
int height,
const unsigned char *in,
49 bool include_unsupported);
53 if(FACILITY_WINDOWS == HRESULT_FACILITY(hr))
54 hr = HRESULT_CODE(hr);
59#define DEFAULT_DEVNUM 1
60#define MAX_STRING_LEN 1000
61#define DEFAULT_VIDEO_WIDTH 640
62#define DEFAULT_VIDEO_HEIGHT 480
65#define MAX_YUV_CLAMP 535
66#define MIN_YUV_CLAMP -276
122 if (pointer == NULL)
return E_POINTER;
123 if (iface == IID_IUnknown || iface == IID_ISampleGrabberCB) {
128 return E_NOINTERFACE;
139 STDMETHODIMP
SampleCB(
double sampleTime, IMediaSample *ms) {
149 if (
len <= 0)
return S_OK;
170 bool grabMightWait =
false;
172 grabMightWait =
true;
224#define HANDLE_ERR_ACTION(res, action, msg, ...) \
226 MSG(ERROR, msg ": %s\n", \
227 __VA_ARGS__ __VA_OPT__(, ) hresult_to_str(res)); \
232#define HANDLE_ERR(msg, ...) \
233 HANDLE_ERR_ACTION(res, goto error, \
234 "vidcap_dshow_init: " msg __VA_OPT__(, ) \
282 res = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&s->
devEnumerator));
283 HANDLE_ERR(
"Cannot create System Device Enumerator");
286 if (res == S_FALSE) {
287 MSG(ERROR,
"no devices found\n");
290 HANDLE_ERR(
"Cannot create Video Input Device enumerator");
294 res = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
296 HANDLE_ERR(
"Cannot create instance of Capture Graph Builder 2");
299 res = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
301 HANDLE_ERR(
"Cannot create instance of Filter Graph");
305 HANDLE_ERR(
"Cannot attach Filter Graph to Graph Builder");
317 BITMAPINFOHEADER *bmiHeader;
319 if (mediaType->formattype != FORMAT_VideoInfo && mediaType->formattype != FORMAT_VideoInfo2) {
327 if (mediaType->formattype == FORMAT_VideoInfo) {
328 VIDEOINFOHEADER *infoHeader =
reinterpret_cast<VIDEOINFOHEADER*
>(mediaType->pbFormat);
329 bmiHeader = &infoHeader->bmiHeader;
330 desc.
fps = 10000000.0/infoHeader->AvgTimePerFrame;
332 VIDEOINFOHEADER2 *infoHeader =
reinterpret_cast<VIDEOINFOHEADER2*
>(mediaType->pbFormat);
333 bmiHeader = &infoHeader->bmiHeader;
334 desc.
fps = 10000000.0/infoHeader->AvgTimePerFrame;
335 if (infoHeader->dwInterlaceFlags & AMINTERLACE_IsInterlaced) {
336 if (infoHeader->dwInterlaceFlags & AMINTERLACE_1FieldPerSample) {
338 "1 Field Per Sample is not supported! ");
353 const bool short_h = strcmp(help_str,
"shorthelp") == 0;
354 const bool full_h = strcmp(help_str,
"fullhelp") == 0;
355 printf(
"dshow grabber options:\n");
356 col() <<
SBOLD(
"\t-t dshow:[full|short]help") <<
"\n";
357 col() <<
SBOLD(
SRED(
"\t-t dshow") <<
"[:device=<DeviceNumber>|<DeviceName>][:mode=<ModeNumber>][:RGB]")
"\n";
358 col() <<
"\t Flag " <<
SBOLD(
"RGB") <<
" forces use of RGB codec, otherwise native is used if possible.\n";
360 col() <<
SBOLD(
SRED(
"\t-t dshow:[Device]<DeviceNumber>:<codec>:<width>:<height>:<fps>"))
"\n\n";
367 void (*
deleter)(
void *) = NULL;
371 for (
int n = 0; n <
count; ++n) {
379 while (strlen(cards[n].modes[i].
id) > 0) {
380 fputs(i == 0 ?
"" : i % 2 == 0 ?
"\n" :
"\t", stdout);
382 sscanf(cards[n].modes[i].
id,
"{\"mode\":\"%d", &mode_idx);
384 printf(
" Mode %2d: %s", mode_idx, cards[n].modes[i].
name);
393 printf(
"%sMode flags:\n", short_h ?
"\n" :
"");
394 printf(
"C - codec not natively supported by UG%s\n\n",
395 full_h ?
"; F - video format is "
397 :
"\n(use ':fullhelp' to see also unsupported modes)");
403#define HANDLE_ERR(msg, ...) \
404 HANDLE_ERR_ACTION(res, return {}, "%s: " msg, \
405 __func__ __VA_OPT__(, ) __VA_ARGS__)
406 IPropertyBag *properties =
nullptr;
407 const string device_id = idx == -1 ?
"" : to_string(idx) +
" ";
409 HRESULT res = moniker->BindToStorage(0, 0, IID_PPV_ARGS(&properties));
410 HANDLE_ERR(
"Failed to read device %s properties", device_id.c_str());
414 res = properties->Read(L
"FriendlyName", &var, NULL);
415 HANDLE_ERR(
"Failed to read device %s FriendlyName", device_id.c_str());
419 wcstombs(buf, var.bstrVal,
sizeof buf);
423 properties->Release();
431 void (**
deleter)(
void *),
bool include_unsupported)
449 memset(&cards[n - 1], 0,
sizeof(
struct device_info));
450 snprintf(cards[n-1].
dev,
sizeof cards[n-1].
dev - 1,
":device=%d", n);
451 snprintf(cards[n-1].
name,
sizeof cards[n-1].
name - 1,
"_DSHOW_FAILED_TO_READ_NAME_%d_", n);
454 if (friendly_name.empty()) {
459 const char *
name = friendly_name.c_str();;
460 snprintf(cards[n - 1].
name,
sizeof cards[n - 1].
name,
"%s",
463#define HANDLE_ERR(msg, ...) \
464 HANDLE_ERR_ACTION(res, continue, "vidcap_dshow_help: %s: " msg, \
465 name __VA_OPT__(, ) __VA_ARGS__)
467 IBaseFilter *captureFilter;
468 res = s->
moniker->BindToObject(NULL, NULL, IID_IBaseFilter, (
void **) &captureFilter);
469 HANDLE_ERR(
"Cannot bind capture filter to device");
472 res = s->
filterGraph->AddFilter(captureFilter, L
"Capture filter");
473 HANDLE_ERR(
"Cannot add capture filter to filter graph");
476 res = s->
graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, captureFilter,
478 HANDLE_ERR(
"Cannot find interface for reading capture capabilites");
480 int capCount, capSize;
482 res = s->
streamConfig->GetNumberOfCapabilities(&capCount, &capSize);
483 HANDLE_ERR(
"Cannot read number of capture capabilites");
485 if (capSize !=
sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
492 for (
int i = 0; i < capCount; i++) {
494 (
int) (
sizeof cards[card_count - 1].
modes /
495 sizeof cards[card_count - 1].
modes[0]) -
500 AM_MEDIA_TYPE *mediaType;
501 VIDEO_STREAM_CONFIG_CAPS streamCaps;
504 HANDLE_ERR(
"Cannot read stream capabilities #%d", i);
511 if (mediaType->formattype != FORMAT_VideoInfo && !include_unsupported) {
519 snprintf(cards[card_count - 1].modes[mode_idx].
id,
520 sizeof cards[card_count - 1].modes[mode_idx].
id,
522 "\"force_rgb\":\"%c\"}",
523 i, force_rgb ?
't' :
'f');
524 snprintf(cards[card_count - 1].modes[mode_idx].
name,
525 sizeof cards[card_count - 1].modes[mode_idx].
name,
529 mediaType->formattype == FORMAT_VideoInfo ?
"" :
"F");
536 res = s ->
filterGraph->RemoveFilter(captureFilter);
537 HANDLE_ERR(
"Cannot remove capture filter from filter graph");
538 captureFilter->Release();
540 dev_add_option(&cards[card_count - 1],
"Force no sync source",
"Only use if capture is stuck",
"no_sync_source",
":no_sync_source",
true);
543 *available_cards = cards;
556 char *strtok_context;
559 if (strchr(init_fmt,
'=') == NULL) {
560 while ((token = strtok_s(init_fmt,
":", &strtok_context)) != NULL) {
564 if (strstr(token,
"Device") == token) token = token + strlen(
"Device");
565 if (isdigit(token[0])) {
568 s->
deviceName = (
char *) malloc(
sizeof(
char) * (strlen(token) + 100));
570 strcpy_s(s->
deviceName, strlen(token) + 1, token);
575 if (strstr(token,
"Mode") == token) token = token + strlen(
"Mode");
576 if (isdigit(token[0])) {
632 while ((token = strtok_s(init_fmt,
":", &strtok_context)) != NULL) {
635 token = strchr(token,
'=') + 1;
636 if (isdigit(token[0])) {
639 s->
deviceName = (
char *) malloc(
sizeof(
char) * (strlen(token) + 100));
640 strcpy_s(s->
deviceName, strlen(token) + 1, token);
644 token = strchr(token,
'=') + 1;
646 }
else if (strcmp(token,
"RGB") == 0) {
648 }
else if (strcmp(token,
"no_sync_source") == 0) {
651 MSG(ERROR,
"Unknown argument: %s\n", token);
663 HRESULT res = pin->ConnectedTo(&connectedPin);
666 }
else if (res == VFW_E_NOT_CONNECTED) {
671 if (connectedPin != NULL) connectedPin->Release();
676 PIN_DIRECTION pinDir;
678 HRESULT res = pin->QueryDirection(&pinDir);
680 *result = (pinDir == direction);
687 IEnumPins *pinEnum = NULL;
688 IPin *filterPin = NULL;
691 HRESULT res =
filter->EnumPins(&pinEnum);
697 while ((res = pinEnum->Next(1, &filterPin, NULL)) == S_OK) {
707 if (!hasDirection)
continue;
720 if (filterPin != NULL) filterPin->Release();
724 res = VFW_E_NOT_FOUND;
728 if (pinEnum != NULL) pinEnum->Release();
729 if (filterPin != NULL) filterPin->Release();
733static HRESULT
ConnectFilters(IGraphBuilder *g, IPin *fromPin, IBaseFilter *toFilter) {
738 res = g->Connect(fromPin, toPin);
745static HRESULT
ConnectFilters(IGraphBuilder *g, IBaseFilter *fromFilter, IBaseFilter *toFilter) {
746 IPin *fromPin = NULL;
757[[maybe_unused]]
static HRESULT
GraphRun(IMediaControl *mc) {
760 if ((res = mc->Run()) == S_FALSE) {
763 while ((res = mc->GetState(500, (OAFilterState*) &fs)) != VFW_S_CANT_CUE && !(res == S_OK && fs == State_Running)) {
764 if (res != VFW_S_STATE_INTERMEDIATE && res != S_OK) {
778[[maybe_unused]]
static HRESULT
GraphPause(IMediaControl *mc) {
781 if ((res = mc->Pause()) == S_FALSE) {
784 while ((res = mc->GetState(500, (OAFilterState*) &fs)) != VFW_S_CANT_CUE && !(res == S_OK && fs == State_Paused)) {
785 if (res != VFW_S_STATE_INTERMEDIATE && res != S_OK)
break;
799 IKsPropertySet *pKs = NULL;
801 HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs));
808 DWORD cbReturned = 0;
809 hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
810 pPinCategory,
sizeof(GUID), &cbReturned);
814 if (pKs != NULL) pKs->Release();
820 EnterCriticalSection(&s->returnBufferCS);
821 s->should_exit =
true;
822 LeaveCriticalSection(&s->returnBufferCS);
823 WakeConditionVariable(&s->grabWaitCV);
827#define HANDLE_ERR(msg, ...) \
828 HANDLE_ERR_ACTION(res, goto error, \
829 "vidcap_dshow_init: " msg __VA_OPT__(, ) __VA_ARGS__)
873 if (res != S_OK)
break;
882 if (strcasecmp(s->
deviceName, friendly_name.c_str()) == 0) {
903 HANDLE_ERR(
"Cannot bind capture filter to device");
906 HANDLE_ERR(
"Cannot add capture filter to filter graph");
910 HANDLE_ERR(
"Cannot find interface for reading capture capabilites");
914 HANDLE_ERR(
"Cannot create instance of sample grabber");
918 HANDLE_ERR(
"Cannot add sample grabber to filter graph");
922 HANDLE_ERR(
"Cannot query sample grabber filter for control interface");
926 HANDLE_ERR(
"Cannot set sample grabber to buffer samples");
929 AM_MEDIA_TYPE sampleGrabberMT;
930 ZeroMemory(&sampleGrabberMT,
sizeof(sampleGrabberMT));
931 sampleGrabberMT.majortype = MEDIATYPE_Video;
932 sampleGrabberMT.subtype = MEDIASUBTYPE_RGB24;
934 HANDLE_ERR(
"Cannot setup media type of grabber filter");
936 int capCount, capSize;
937 res = s->
streamConfig->GetNumberOfCapabilities(&capCount, &capSize);
938 HANDLE_ERR(
"Cannot read number of capture capabilites");
939 if (capSize !=
sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
945 format_found =
false;
946 AM_MEDIA_TYPE *mediaType;
947 VIDEO_STREAM_CONFIG_CAPS streamCaps;
952 if (res == S_FALSE || res == E_INVALIDARG) {
958 "Cannot read stream capabilities #%d (index is correct)",
966 "Pixel format %.4s not supported directly, "
968 (
char *) &mediaType->subtype.Data1);
973 "of grabber filter");
985 for (
int i = 0; i < capCount; i++) {
1001 "of grabber filter");
1009 if (!format_found) {
1016 "Capturing a compressed format directly. You may consider "
1017 "enforcing conversion to RGB (':RGB' option), eg. to "
1018 "use another compression.\n");
1024 HANDLE_ERR(
"Cannot get current capture format");
1026 case BGR : mediaType->subtype = MEDIASUBTYPE_RGB24;
1028 case YUYV : mediaType->subtype = MEDIASUBTYPE_YUY2;
1034 VIDEOINFOHEADER *infoHeader;
1035 infoHeader =
reinterpret_cast<VIDEOINFOHEADER*
>(mediaType->pbFormat);
1036 infoHeader->rcSource.bottom = s->
desc.
height;
1037 infoHeader->rcSource.right = s->
desc.
width;
1038 infoHeader->AvgTimePerFrame = (REFERENCE_TIME) (1e7 / s->
desc.
fps);
1056 for (
int j = 1; j <= 254; j++, i++) {
1065 res = CoCreateInstance(
CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,
1070 HANDLE_ERR(
"Cannot add null renderer to filter graph");
1076 HANDLE_ERR(
"Error enumerating pins of capture filter");
1078 while (pinEnum->Next(1, &pin, NULL) == S_OK) {
1080 if (pin != NULL) pin->Release();
1085 HANDLE_ERR(
"Cannot connect capture filter to sample grabber");
1087 res = s->
sampleGrabber->GetConnectedMediaType(&sampleGrabberMT);
1088 HANDLE_ERR(
"Cannot get current grabber format");
1089 MSG(INFO,
"streaming type: %s, grabber type: %s, output: %s\n",
1097 HANDLE_ERR(
"Cannot connect sample grabber to null renderer");
1112 HANDLE_ERR(
"Cannot find media control interface");
1115 IMediaFilter *pMediaFilter;
1116 res = s->
filterGraph->QueryInterface(IID_IMediaFilter, (
void **) &pMediaFilter);
1117 HANDLE_ERR(
"Cannot find media filter interface");
1119 pMediaFilter->SetSyncSource(NULL);
1124 while ((res = s->
mediaControl->GetState(500, (OAFilterState*) &fs)) != VFW_S_CANT_CUE && !(res == S_OK && fs == State_Running)) {
1125 if (res != VFW_S_STATE_INTERMEDIATE && res != S_OK) {
1160 int yy = (y - 16) * 298;
1164 dst[0] =
yuv_clamp[(yy + uu * 516 + 128) >> 8];
1165 dst[1] =
yuv_clamp[(yy - uu * 100 - vv * 208 + 128) >> 8];
1166 dst[2] =
yuv_clamp[(yy + 409 * vv + 128) >> 8];
1173 for (
int i = 0; i < input_len; i += 4) {
1247 if (mt.cbFormat != 0) {
1248 CoTaskMemFree((PVOID)mt.pbFormat);
1254 if (mt.pUnk != NULL) {
1268 CoTaskMemFree((PVOID)pmt);
1272nv12_to_uyvy(
int width,
int height,
const unsigned char *in,
unsigned char *out)
1275 for (ptrdiff_t y = 0; y < height; ++y) {
1276 const unsigned char *src_y = in + width * y;
1277 const unsigned char *src_cbcr =
1278 in + (ptrdiff_t) width * height + width * (y / 2);
1279 unsigned char *dst = out + y * uyvy_linesize;
1283 *dst++ = *src_cbcr++;
1285 *dst++ = *src_cbcr++;
1298 for (
int i = 0; i < height; ++i) {
1299 memcpy(out + i * linesize, in + (height - i - 1) * linesize,
1310 for (
int i = 0; i < height; ++i) {
1312 in + (height - i - 1) * linesize, linesize, 16,
1319#define GUID_FROM_FOURCC(fourcc) {fourcc, 0x0000, 0x10, {0x80,0x0,0x0,0xAA,0x0,0x38,0x9B,0x71}}
1329static const struct {
1335 {&MEDIASUBTYPE_RGB1,
"RGB Monochrome",
VC_NONE,
nullptr },
1336 { &MEDIASUBTYPE_RGB4,
"RGB VGA",
VC_NONE,
nullptr },
1337 { &MEDIASUBTYPE_RGB8,
"RGB 8",
VC_NONE,
nullptr },
1338 { &MEDIASUBTYPE_RGB565,
"RGB 565 (16 bit)",
VC_NONE,
nullptr },
1339 { &MEDIASUBTYPE_RGB555,
"RGB 555 (16 bit)",
VC_NONE,
nullptr },
1342 { &MEDIASUBTYPE_ARGB32,
"ARGB 32",
VC_NONE,
nullptr },
1343 { &MEDIASUBTYPE_Overlay,
"Overlay",
VC_NONE,
nullptr },
1345 { &MEDIASUBTYPE_YUY2,
"YUY2",
YUYV,
nullptr },
1349 { &MEDIASUBTYPE_UYVY,
"UYVY",
UYVY,
nullptr },
1351 { &MEDIASUBTYPE_MJPG,
"MJPG",
MJPG,
nullptr },
1356 { &GUID_NULL,
"UNKNOWN",
VC_NONE,
nullptr },
1382 const GUID *pMediaSubtype;
1399 if (IsEqualGUID(*pMediaSubtype,*
pSubtype) ||
1400 IsEqualGUID(*pMediaSubtype,GUID_NULL)
static void vidcap_dshow_probe_internal(device_info **available_cards, int *count, void(**deleter)(void *), bool include_unsupported)
static const GUID GUID_H264
static HRESULT GetPinCategory(IPin *pPin, GUID *pPinCategory)
static HRESULT PinIsConnected(IPin *pin, bool *result)
static void abgr_flip_and_swap(int width, int height, const unsigned char *in, unsigned char *out)
convert from ABGR and bottom-to-top
static const GUID GUID_HDYC
const struct video_capture_info vidcap_dshow_info
static int vidcap_dshow_init(struct vidcap_params *params, void **state)
static convert_t get_conversion(const GUID *pSubtype)
static const GUID GUID_v210
static const GUID GUID_V210
static codec_t get_ug_from_subtype_name(const char *subtype_name)
static void convert_yuv_rgb(BYTE y, BYTE u, BYTE v, BYTE *dst)
#define DEFAULT_VIDEO_HEIGHT
static HRESULT PinHasDirection(IPin *pin, PIN_DIRECTION direction, bool *result)
EXTERN_C const CLSID CLSID_NullRenderer
static const GUID GUID_HEVC
static const CHAR * GetSubtypeNameA(const GUID *pSubtype)
static HRESULT GraphPause(IMediaControl *mc)
static const GUID GUID_I420
#define HANDLE_ERR(msg,...)
static const GUID GUID_AV01
static const struct @69 BitCountMap[]
static int LocateSubtype(const GUID *pSubtype)
static void vidcap_dshow_should_exit(void *state)
static const CHAR * GetSubtypeName(const GUID *pSubtype)
static void DeleteMediaType(AM_MEDIA_TYPE *mediaType)
static string get_friendly_name(IMoniker *moniker, int idx=-1)
static HRESULT ConnectFilters(IGraphBuilder *g, IPin *fromPin, IBaseFilter *toFilter)
static void vidcap_dshow_done(void *state)
static void convert_yuyv_rgb(BYTE *src, BYTE *dst, int input_len)
static bool process_args(struct vidcap_dshow_state *s, char *init_fmt)
static void ErrorDescription(HRESULT hr)
#define DEFAULT_VIDEO_WIDTH
static struct video_frame * vidcap_dshow_grab(void *state, struct audio_frame **audio)
static bool common_init(struct vidcap_dshow_state *s)
static void nv12_to_uyvy(int width, int height, const unsigned char *in, unsigned char *out)
static void FreeMediaType(AM_MEDIA_TYPE &mt)
static codec_t get_ug_codec(const GUID *pSubtype)
EXTERN_C const CLSID CLSID_SampleGrabber
static HRESULT GraphRun(IMediaControl *mc)
static void bgr_flip_lines(int width, int height, const unsigned char *in, unsigned char *out)
static HRESULT FindUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION direction, IPin **pin)
static void vidcap_dshow_probe(device_info **available_cards, int *count, void(**deleter)(void *))
static struct video_desc vidcap_dshow_get_video_desc(AM_MEDIA_TYPE *mediaType)
#define GUID_FROM_FOURCC(fourcc)
static const GUID GUID_R210
struct audio_frame ** audio
int void(** deleter)(void *))
void vf_free(struct video_frame *buf)
Frees video_frame structure.
int vc_get_linesize(unsigned int width, codec_t codec)
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
codec_t get_codec_from_name(const char *name)
static af_result_code filter(void *state, struct audio_frame **frame)
STDMETHODIMP SampleCB(double sampleTime, IMediaSample *ms)
SampleGrabberCallback(struct vidcap_dshow_state *s, unsigned long *frameNumber)
STDMETHODIMP_(unsigned long) AddRef()
STDMETHODIMP_(unsigned long) Release()
STDMETHODIMP BufferCB(double sampleTime, BYTE *buffer, long len)
STDMETHODIMP QueryInterface(REFIID iface, void **pointer)
struct vidcap_dshow_state * s
unsigned long * frameNumber
int color_printf(const char *format,...)
void log_msg(int level, const char *format,...)
void bug_msg(int level, const char *format,...)
prints the error with the advice to report the bug
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define LOG_LEVEL_WARNING
less severe errors
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
#define VIDCAP_INIT_OK
initialization successful
#define VIDEO_CAPTURE_ABI_VERSION
#define VIDCAP_INIT_FAIL
error ocured
#define VIDCAP_INIT_AUDIO_NOT_SUPPORTED
card does not support audio
void register_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
void unregister_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
@ LIBRARY_CLASS_VIDEO_CAPTURE
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
#define UG_ASSERT_NO_FATAL(cond)
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
#define IF_NOT_NULL_ELSE(val, default_val)
#define to_fourcc(a, b, c, d)
Creates FourCC word.
void(*)(struct video_frame *, const uint8_t *, int in_stride, int field_idx, int total_fields) convert_t
decoder_func_t vc_copylineRGBA
const char * pretty_print_fourcc(const void *fcc)
struct used to comunicate with audio capture/playback device
struct device_info::mode modes[512]
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
IBaseFilter * sampleGrabberFilter
IEnumMoniker * videoInputEnumerator
IBaseFilter * nullRenderer
SampleGrabberCallback * SGCallback
CONDITION_VARIABLE grabWaitCV
ICreateDevEnum * devEnumerator
IMediaControl * mediaControl
IGraphBuilder * filterGraph
struct video_frame * frame
IAMStreamConfig * streamConfig
ICaptureGraphBuilder2 * graphBuilder
CRITICAL_SECTION returnBufferCS
ISampleGrabber * sampleGrabber
IBaseFilter * captureFilter
enum interlacing_t interlacing
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
Struct video_frame represents a video frame and contains video description.
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
void dev_add_option(struct device_info *dev, const char *name, const char *desc, const char *key, const char *opt_str, bool is_boolean)
@ PROGRESSIVE
progressive frame
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
@ YUYV
YCbCr 422 8-bit - Y0 Cb Y1 Cr.
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
@ VIDEO_CODEC_NONE
dummy color spec
@ MJPG
JPEG image, without restart intervals.
@ RGBA
RGBA 8-bit, big-endian.
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
This is an umbrella header for video functions.
struct module * vidcap_params_get_parent(const struct vidcap_params *params)
const char * vidcap_params_get_fmt(const struct vidcap_params *params)
unsigned int vidcap_params_get_flags(const struct vidcap_params *params)
#define VIDCAP_FLAG_AUDIO_ANY
void i420_8_to_uyvy(int width, int height, const unsigned char *in, unsigned char *out)
bool is_codec_opaque(codec_t codec)
bool codec_is_planar(codec_t codec)
size_t vc_get_datalen(unsigned int width, unsigned int height, codec_t codec)
const char * get_interlacing_suffix(enum interlacing_t interlacing)
Returns suffix describing interlacing Eg. p, i or psf.
bool com_initialize(bool *com_initialized, const char *err_prefix)
void com_uninitialize(bool *com_initialized)