mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-22 02:40:26 +00:00
DShow: multiple changes
* restructuralize a bit * marked unsupported formats with flag (C - unsupported codec and F - VIDEOINFOHEADER2) * mark interlaced formats (but cannot be used since VIDEOINFOHEADER2 is unsupported by Sample Grabber Filter) * make output prettier
This commit is contained in:
committed by
Martin Pulec
parent
7c1bb0c1e1
commit
5b1a45cbbf
@@ -64,6 +64,8 @@
|
||||
#define EXIT_FAIL_NETWORK 10
|
||||
#define EXIT_FAIL_AUDIO 11
|
||||
|
||||
#define BUG_MSG "Please report a bug to " PACKAGE_BUGREPORT " if you reach here."
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
#include "debug.h"
|
||||
#include "lib_common.h"
|
||||
#include "rang.hpp"
|
||||
#include "tv.h"
|
||||
#include "utils/color_out.h"
|
||||
#include "video.h"
|
||||
#include "video_capture.h"
|
||||
|
||||
@@ -24,13 +26,17 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define MOD_NAME "[dshow] "
|
||||
|
||||
using rang::fg;
|
||||
using rang::style;
|
||||
using namespace std;
|
||||
|
||||
static void DeleteMediaType(AM_MEDIA_TYPE *mediaType);
|
||||
static const CHAR * GetSubtypeName(const GUID *pSubtype);
|
||||
static codec_t get_ug_codec(const GUID *pSubtype);
|
||||
|
||||
void ErrorDescription(HRESULT hr)
|
||||
static void ErrorDescription(HRESULT hr)
|
||||
{
|
||||
if(FACILITY_WINDOWS == HRESULT_FACILITY(hr))
|
||||
hr = HRESULT_CODE(hr);
|
||||
@@ -64,14 +70,10 @@ struct vidcap_dshow_state {
|
||||
int deviceNumber;
|
||||
char *deviceName;
|
||||
int modeNumber;
|
||||
int width;
|
||||
int height;
|
||||
double fps;
|
||||
codec_t color_spec;
|
||||
struct video_desc desc;
|
||||
bool convert_YUYV_RGB; ///< @todo check - currently newer set
|
||||
|
||||
struct video_frame *frame;
|
||||
struct tile *tile;
|
||||
long frameLength;
|
||||
long grabBufferLen;
|
||||
long returnBufferLen;
|
||||
@@ -152,11 +154,11 @@ public:
|
||||
// We need to make a copy, DirectShow will do something with the data
|
||||
// Apparently DirectShow uses bottom-to-top line ordering so we want make
|
||||
// it top-to-bottom
|
||||
int linesize = vc_get_linesize(s->width, s->color_spec);
|
||||
if (s->color_spec == BGR) {
|
||||
for(int i = 0; i < s->height; ++i) {
|
||||
int linesize = vc_get_linesize(s->desc.width, s->desc.color_spec);
|
||||
if (s->desc.color_spec == BGR) {
|
||||
for(unsigned int i = 0; i < s->desc.height; ++i) {
|
||||
memcpy((char *) s->grabBuffer + i * linesize,
|
||||
(char *) buffer + (s->height - i - 1) * linesize,
|
||||
(char *) buffer + (s->desc.height - i - 1) * linesize,
|
||||
linesize);
|
||||
}
|
||||
} else {
|
||||
@@ -217,12 +219,13 @@ static bool common_init(struct vidcap_dshow_state *s) {
|
||||
// set defaults
|
||||
s->deviceNumber = 1;
|
||||
s->modeNumber = 0;
|
||||
s->width = DEFAULT_VIDEO_WIDTH;
|
||||
s->height = DEFAULT_VIDEO_HEIGHT;
|
||||
s->fps = DEFAULT_FPS;
|
||||
s->desc.width = DEFAULT_VIDEO_WIDTH;
|
||||
s->desc.height = DEFAULT_VIDEO_HEIGHT;
|
||||
s->desc.fps = DEFAULT_FPS;
|
||||
s->desc.tile_count = 1;
|
||||
s->desc.interlacing = PROGRESSIVE;
|
||||
|
||||
s->frame = NULL;
|
||||
s->tile = NULL;
|
||||
s->grabBufferLen = 0;
|
||||
s->returnBufferLen = 0;
|
||||
s->grabBuffer = NULL;
|
||||
@@ -297,12 +300,48 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct video_desc vidcap_dshow_get_video_desc(AM_MEDIA_TYPE *mediaType)
|
||||
{
|
||||
BITMAPINFOHEADER *bmiHeader;
|
||||
struct video_desc desc{};
|
||||
if (mediaType->formattype != FORMAT_VideoInfo && mediaType->formattype != FORMAT_VideoInfo2) {
|
||||
LOG(LOG_LEVEL_WARNING) << MOD_NAME "Unsupported format type!\n";
|
||||
return desc;
|
||||
}
|
||||
|
||||
desc.color_spec = get_ug_codec(&mediaType->subtype);
|
||||
desc.tile_count = 1;
|
||||
desc.interlacing = PROGRESSIVE;
|
||||
if (mediaType->formattype == FORMAT_VideoInfo) {
|
||||
VIDEOINFOHEADER *infoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
desc.fps = 10000000.0/infoHeader->AvgTimePerFrame;
|
||||
} else {
|
||||
VIDEOINFOHEADER2 *infoHeader = reinterpret_cast<VIDEOINFOHEADER2*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
desc.fps = 10000000.0/infoHeader->AvgTimePerFrame;
|
||||
if (infoHeader->dwInterlaceFlags & AMINTERLACE_IsInterlaced) {
|
||||
if (infoHeader->dwInterlaceFlags & AMINTERLACE_1FieldPerSample) {
|
||||
LOG(LOG_LEVEL_WARNING) << MOD_NAME "1 Field Per Sample is not supported! " BUG_MSG "\n";
|
||||
} else {
|
||||
desc.interlacing = INTERLACED_MERGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
desc.width = bmiHeader->biWidth;
|
||||
desc.height = bmiHeader->biHeight;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void show_help(struct vidcap_dshow_state *s) {
|
||||
printf("dshow grabber options:\n");
|
||||
printf("\t-t dshow[:device=<DeviceNumber>][:mode=<ModeNumber>][:RGB]\n");
|
||||
printf("\t Flag RGB forces use of RGB codec, otherwise native is used if possible.\n");
|
||||
cout << style::bold << fg::red << "\t-t dshow" << fg::reset << "[:device=<DeviceNumber>][:mode=<ModeNumber>][:RGB]\n" << style::reset;
|
||||
cout << "\t Flag " << style::bold << "RGB" << style::reset << " forces use of RGB codec, otherwise native is used if possible.\n";
|
||||
printf("\tor\n");
|
||||
printf("\t-t dshow:[Device]<DeviceNumber>:RGB:<width>:<height>:<fps>\n\n");
|
||||
cout << style::bold << fg::red << "\t-t dshow:[Device]<DeviceNumber>:RGB:<width>:<height>:<fps>\n\n" << fg::reset << style::reset;
|
||||
|
||||
bool show_legend = false;
|
||||
|
||||
if (!common_init(s)) return;
|
||||
|
||||
@@ -330,7 +369,8 @@ static void show_help(struct vidcap_dshow_state *s) {
|
||||
// Ignore the device
|
||||
continue;
|
||||
}
|
||||
printf("Device %d: %ls\n", n, var.bstrVal);
|
||||
printf("Device %d: ", n);
|
||||
color_out(COLOR_OUT_BOLD, "%ls\n", var.bstrVal);
|
||||
|
||||
// clean up structures
|
||||
VariantClear(&var);
|
||||
@@ -387,22 +427,20 @@ static void show_help(struct vidcap_dshow_state *s) {
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_help: Unsupported format type for capability #%d.\n", i);
|
||||
continue;
|
||||
}
|
||||
BITMAPINFOHEADER *bmiHeader;
|
||||
char fps_string[128] = "";
|
||||
if (mediaType->formattype == FORMAT_VideoInfo) {
|
||||
VIDEOINFOHEADER *infoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
snprintf(fps_string, sizeof fps_string, "@%0.2f", 10000000.0/infoHeader->AvgTimePerFrame);
|
||||
} else {
|
||||
VIDEOINFOHEADER2 *infoHeader = reinterpret_cast<VIDEOINFOHEADER2*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
snprintf(fps_string, sizeof fps_string, "@%0.2f", 10000000.0/infoHeader->AvgTimePerFrame);
|
||||
// TODO: add also interlacing suffix
|
||||
}
|
||||
printf(" Mode %2d: %s %ldx%ld %s", i, GetSubtypeName(&mediaType->subtype),
|
||||
bmiHeader->biWidth,
|
||||
bmiHeader->biHeight,
|
||||
fps_string);
|
||||
struct video_desc desc = vidcap_dshow_get_video_desc(mediaType);
|
||||
if (desc.width == 0) {
|
||||
continue;
|
||||
}
|
||||
printf(" Mode %2d: %s %ux%u @%0.2lf%s %s%s", i, GetSubtypeName(&mediaType->subtype),
|
||||
desc.width, desc.height,
|
||||
desc.fps * (desc.interlacing == INTERLACED_MERGED ? 2 : 1),
|
||||
get_interlacing_suffix(desc.interlacing),
|
||||
desc.color_spec ? "" : "C",
|
||||
mediaType->formattype == FORMAT_VideoInfo ? "" : "F");
|
||||
|
||||
if (!desc.color_spec || mediaType->formattype != FORMAT_VideoInfo) {
|
||||
show_legend = true;
|
||||
}
|
||||
|
||||
DeleteMediaType(mediaType);
|
||||
|
||||
@@ -420,6 +458,10 @@ static void show_help(struct vidcap_dshow_state *s) {
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
if (show_legend) {
|
||||
printf("C - codec is not supported in UG; F - video format is not supported\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -530,30 +572,19 @@ static struct vidcap_type * vidcap_dshow_probe(bool verbose)
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_help: Cannot read stream capabilities #%d.\n", i);
|
||||
continue;
|
||||
}
|
||||
if (mediaType->formattype != FORMAT_VideoInfo && mediaType->formattype != FORMAT_VideoInfo2) {
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_help: Unsupported format type for capability #%d.\n", i);
|
||||
struct video_desc desc = vidcap_dshow_get_video_desc(mediaType);
|
||||
if (desc.width == 0) {
|
||||
continue;
|
||||
}
|
||||
BITMAPINFOHEADER *bmiHeader;
|
||||
char fps_string[128] = "";
|
||||
if (mediaType->formattype == FORMAT_VideoInfo) {
|
||||
VIDEOINFOHEADER *infoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
snprintf(fps_string, sizeof fps_string, "@%0.2f", 10000000.0/infoHeader->AvgTimePerFrame);
|
||||
} else {
|
||||
VIDEOINFOHEADER2 *infoHeader = reinterpret_cast<VIDEOINFOHEADER2*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
snprintf(fps_string, sizeof fps_string, "@%0.2f", 10000000.0/infoHeader->AvgTimePerFrame);
|
||||
// TODO: add also interlacing suffix
|
||||
}
|
||||
|
||||
snprintf(vt->cards[vt->card_count - 1].modes[i].id,
|
||||
sizeof vt->cards[vt->card_count - 1].modes[i].id,
|
||||
"{\"mode\":\"%d\"}", i);
|
||||
snprintf(vt->cards[vt->card_count - 1].modes[i].name,
|
||||
sizeof vt->cards[vt->card_count - 1].modes[i].name,
|
||||
"%s %ldx%ld %s", GetSubtypeName(&mediaType->subtype),
|
||||
bmiHeader->biWidth, bmiHeader->biHeight, fps_string);
|
||||
"%s %ux%u @%0.2lf%s%s", GetSubtypeName(&mediaType->subtype),
|
||||
desc.width, desc.height, desc.fps * (desc.interlacing == INTERLACED_MERGED ? 2 : 1), get_interlacing_suffix(desc.interlacing),
|
||||
desc.color_spec ? "" : " (U)");
|
||||
|
||||
DeleteMediaType(mediaType);
|
||||
}
|
||||
@@ -597,8 +628,8 @@ static bool process_args(struct vidcap_dshow_state *s, char *init_fmt) {
|
||||
s->modeNumber = atoi(token);
|
||||
} else {
|
||||
s->modeNumber = -1;
|
||||
if (strcmp(token, "YUYV") == 0) s->color_spec = YUYV;
|
||||
else if (strcmp(token, "RGB") == 0) s->color_spec = BGR;
|
||||
if (strcmp(token, "YUYV") == 0) s->desc.color_spec = YUYV;
|
||||
else if (strcmp(token, "RGB") == 0) s->desc.color_spec = BGR;
|
||||
else {
|
||||
fprintf(stderr, "[dshow] Unsupported video format: %s. "
|
||||
"Please contact us via %s if you need support for this codec.\n",
|
||||
@@ -609,31 +640,31 @@ static bool process_args(struct vidcap_dshow_state *s, char *init_fmt) {
|
||||
break;
|
||||
case 3 :
|
||||
if (s->modeNumber != -1) {
|
||||
if (strcmp(token, "RGB") == 0) s->color_spec = BGR;
|
||||
if (strcmp(token, "RGB") == 0) s->desc.color_spec = BGR;
|
||||
else {
|
||||
fprintf(stderr, "[dshow] Unknown parameter: %s.\n", token);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
s->width = atoi(token);
|
||||
if (s->width <= 0) {
|
||||
s->desc.width = atoi(token);
|
||||
if (s->desc.width <= 0) {
|
||||
fprintf(stderr, "[dshow] Invalid video width parameter: %s.\n", token);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 4 :
|
||||
if (s->modeNumber != -1) break;
|
||||
s->height = atoi(token);
|
||||
if (s->height <= 0) {
|
||||
s->desc.height = atoi(token);
|
||||
if (s->desc.height <= 0) {
|
||||
fprintf(stderr, "[dshow] Invalid video height parameter: %s.\n", token);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 5 :
|
||||
if (s->modeNumber != -1) break;
|
||||
s->fps = atoi(token);
|
||||
if (s->fps <= 0) {
|
||||
s->desc.fps = atoi(token);
|
||||
if (s->desc.fps <= 0) {
|
||||
fprintf(stderr, "[dshow] Invalid video fps parameter: %s.\n", token);
|
||||
return false;
|
||||
}
|
||||
@@ -660,7 +691,7 @@ static bool process_args(struct vidcap_dshow_state *s, char *init_fmt) {
|
||||
token = strchr(token, '=') + 1;
|
||||
s->modeNumber = atoi(token);
|
||||
} else if (strcmp(token, "RGB") == 0) {
|
||||
s->color_spec = BGR;
|
||||
s->desc.color_spec = BGR;
|
||||
} else {
|
||||
log_msg(LOG_LEVEL_WARNING, "[dshow] Unknown argument: %s, ignoring.\n", token);
|
||||
}
|
||||
@@ -670,7 +701,7 @@ static bool process_args(struct vidcap_dshow_state *s, char *init_fmt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT PinIsConnected(IPin *pin, bool *result) {
|
||||
static HRESULT PinIsConnected(IPin *pin, bool *result) {
|
||||
IPin *connectedPin;
|
||||
|
||||
HRESULT res = pin->ConnectedTo(&connectedPin);
|
||||
@@ -685,7 +716,7 @@ HRESULT PinIsConnected(IPin *pin, bool *result) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT PinHasDirection(IPin *pin, PIN_DIRECTION direction, bool *result) {
|
||||
static HRESULT PinHasDirection(IPin *pin, PIN_DIRECTION direction, bool *result) {
|
||||
PIN_DIRECTION pinDir;
|
||||
|
||||
HRESULT res = pin->QueryDirection(&pinDir);
|
||||
@@ -696,7 +727,7 @@ HRESULT PinHasDirection(IPin *pin, PIN_DIRECTION direction, bool *result) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT FindUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION direction, IPin **pin) {
|
||||
static HRESULT FindUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION direction, IPin **pin) {
|
||||
IEnumPins *pinEnum = NULL;
|
||||
IPin *filterPin = NULL;
|
||||
bool pinFound;
|
||||
@@ -743,7 +774,7 @@ error:
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT ConnectFilters(IGraphBuilder *g, IPin *fromPin, IBaseFilter *toFilter) {
|
||||
static HRESULT ConnectFilters(IGraphBuilder *g, IPin *fromPin, IBaseFilter *toFilter) {
|
||||
IPin *toPin = NULL;
|
||||
|
||||
HRESULT res = FindUnconnectedPin(toFilter, PINDIR_INPUT, &toPin);
|
||||
@@ -755,7 +786,7 @@ HRESULT ConnectFilters(IGraphBuilder *g, IPin *fromPin, IBaseFilter *toFilter) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT ConnectFilters(IGraphBuilder *g, IBaseFilter *fromFilter, IBaseFilter *toFilter) {
|
||||
static HRESULT ConnectFilters(IGraphBuilder *g, IBaseFilter *fromFilter, IBaseFilter *toFilter) {
|
||||
IPin *fromPin = NULL;
|
||||
|
||||
HRESULT res = FindUnconnectedPin(fromFilter, PINDIR_OUTPUT, &fromPin);
|
||||
@@ -767,7 +798,7 @@ HRESULT ConnectFilters(IGraphBuilder *g, IBaseFilter *fromFilter, IBaseFilter *t
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT GraphRun(IMediaControl *mc) {
|
||||
static HRESULT GraphRun(IMediaControl *mc) {
|
||||
HRESULT res;
|
||||
|
||||
if ((res = mc->Run()) == S_FALSE) {
|
||||
@@ -788,7 +819,7 @@ HRESULT GraphRun(IMediaControl *mc) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT GraphPause(IMediaControl *mc) {
|
||||
static HRESULT GraphPause(IMediaControl *mc) {
|
||||
HRESULT res;
|
||||
|
||||
if ((res = mc->Pause()) == S_FALSE) {
|
||||
@@ -807,7 +838,7 @@ HRESULT GraphPause(IMediaControl *mc) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT GetPinCategory(IPin *pPin, GUID *pPinCategory)
|
||||
static HRESULT GetPinCategory(IPin *pPin, GUID *pPinCategory)
|
||||
{
|
||||
IKsPropertySet *pKs = NULL;
|
||||
|
||||
@@ -1009,37 +1040,28 @@ static int vidcap_dshow_init(const struct vidcap_params *params, void **state) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (s->color_spec == VIDEO_CODEC_NONE && get_ug_codec(&mediaType->subtype) != VIDEO_CODEC_NONE) {
|
||||
if (s->desc.color_spec == VIDEO_CODEC_NONE && get_ug_codec(&mediaType->subtype) != VIDEO_CODEC_NONE) {
|
||||
res = s->sampleGrabber->SetMediaType(mediaType);
|
||||
if (res != S_OK) {
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_init: Cannot setup media type of grabber filter.\n");
|
||||
goto error;
|
||||
}
|
||||
s->color_spec = get_ug_codec(&mediaType->subtype);
|
||||
s->desc.color_spec = get_ug_codec(&mediaType->subtype);
|
||||
} else {
|
||||
|
||||
if (sampleGrabberMT.subtype == MEDIASUBTYPE_RGB24) s->color_spec = BGR;
|
||||
else if (sampleGrabberMT.subtype == MEDIASUBTYPE_YUY2) s->color_spec = YUYV;
|
||||
if (sampleGrabberMT.subtype == MEDIASUBTYPE_RGB24) s->desc.color_spec = BGR;
|
||||
else if (sampleGrabberMT.subtype == MEDIASUBTYPE_YUY2) s->desc.color_spec = YUYV;
|
||||
else {
|
||||
fprintf(stderr, "[dshow] Unknown color specifiation of the chosen format, cannot grab.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
BITMAPINFOHEADER *bmiHeader;
|
||||
double fps;
|
||||
if (mediaType->formattype == FORMAT_VideoInfo) {
|
||||
VIDEOINFOHEADER *infoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
fps = 10000000.0/infoHeader->AvgTimePerFrame;
|
||||
} else {
|
||||
VIDEOINFOHEADER2 *infoHeader = reinterpret_cast<VIDEOINFOHEADER2*>(mediaType->pbFormat);
|
||||
bmiHeader = &infoHeader->bmiHeader;
|
||||
fps = 10000000.0/infoHeader->AvgTimePerFrame;
|
||||
}
|
||||
s->width = bmiHeader->biWidth;
|
||||
s->height = bmiHeader->biHeight;
|
||||
s->fps = fps;
|
||||
struct video_desc desc = vidcap_dshow_get_video_desc(mediaType);
|
||||
s->desc.width = desc.width;
|
||||
s->desc.height = desc.height;
|
||||
s->desc.fps = desc.fps;
|
||||
s->desc.interlacing = desc.interlacing;
|
||||
|
||||
format_found = true;
|
||||
} else {
|
||||
@@ -1049,21 +1071,12 @@ static int vidcap_dshow_init(const struct vidcap_params *params, void **state) {
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_help: Cannot read stream capabilities #%d.\n", i);
|
||||
continue;
|
||||
}
|
||||
if (mediaType->formattype != FORMAT_VideoInfo && mediaType->formattype != FORMAT_VideoInfo2) { fprintf(stderr, "[dshow] vidcap_dshow_help: Unsupported format type for capability #%d.\n", i);
|
||||
continue;
|
||||
}
|
||||
if ((s->color_spec == BGR && mediaType->subtype != MEDIASUBTYPE_RGB24) ||
|
||||
(s->color_spec == YUYV && mediaType->subtype != MEDIASUBTYPE_YUY2))
|
||||
if ((s->desc.color_spec == BGR && mediaType->subtype != MEDIASUBTYPE_RGB24) ||
|
||||
(s->desc.color_spec == YUYV && mediaType->subtype != MEDIASUBTYPE_YUY2))
|
||||
continue;
|
||||
|
||||
BITMAPINFOHEADER *bmiHeader;
|
||||
if (mediaType->formattype == FORMAT_VideoInfo) {
|
||||
bmiHeader = &reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat)->bmiHeader;
|
||||
} else {
|
||||
bmiHeader = &reinterpret_cast<VIDEOINFOHEADER2*>(mediaType->pbFormat)->bmiHeader;
|
||||
}
|
||||
if (bmiHeader->biHeight == s->height &&
|
||||
bmiHeader->biWidth == s->width) {
|
||||
struct video_desc desc = vidcap_dshow_get_video_desc(mediaType);
|
||||
if (desc.height == s->desc.height && desc.width == s->desc.width) {
|
||||
format_found = true;
|
||||
break;
|
||||
}
|
||||
@@ -1083,7 +1096,7 @@ static int vidcap_dshow_init(const struct vidcap_params *params, void **state) {
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_init: Cannot get current capture format.\n");
|
||||
goto error;
|
||||
}
|
||||
switch (s->color_spec) {
|
||||
switch (s->desc.color_spec) {
|
||||
case BGR : mediaType->subtype = MEDIASUBTYPE_RGB24;
|
||||
break;
|
||||
case YUYV : mediaType->subtype = MEDIASUBTYPE_YUY2;
|
||||
@@ -1094,9 +1107,9 @@ static int vidcap_dshow_init(const struct vidcap_params *params, void **state) {
|
||||
}
|
||||
VIDEOINFOHEADER *infoHeader;
|
||||
infoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);
|
||||
infoHeader->rcSource.bottom = s->height;
|
||||
infoHeader->rcSource.right = s->width;
|
||||
infoHeader->AvgTimePerFrame = (REFERENCE_TIME) (1e7 / s->fps);
|
||||
infoHeader->rcSource.bottom = s->desc.height;
|
||||
infoHeader->rcSource.right = s->desc.width;
|
||||
infoHeader->AvgTimePerFrame = (REFERENCE_TIME) (1e7 / s->desc.fps);
|
||||
}
|
||||
res = s->streamConfig->SetFormat(mediaType);
|
||||
if (res != S_OK) {
|
||||
@@ -1106,7 +1119,7 @@ static int vidcap_dshow_init(const struct vidcap_params *params, void **state) {
|
||||
DeleteMediaType(mediaType);
|
||||
|
||||
if (s->convert_YUYV_RGB) {
|
||||
s->convert_buffer = (BYTE *) malloc(s->height * s->width * 3);
|
||||
s->convert_buffer = (BYTE *) malloc(s->desc.height * s->desc.width * 3);
|
||||
if (s->convert_buffer == NULL) {
|
||||
fprintf(stderr, "[dshow] vidcap_dshow_init: memory allocation error\n");
|
||||
goto error;
|
||||
@@ -1207,13 +1220,7 @@ static int vidcap_dshow_init(const struct vidcap_params *params, void **state) {
|
||||
InitializeCriticalSectionAndSpinCount(&s->returnBufferCS, 0x40);
|
||||
s->haveNewReturnBuffer = false;
|
||||
|
||||
s->frame = vf_alloc(1);
|
||||
s->tile = vf_get_tile(s->frame, 0);
|
||||
s->frame->interlacing = PROGRESSIVE;
|
||||
s->frame->color_spec = s->color_spec;
|
||||
s->frame->fps = s->fps;
|
||||
s->tile->width = s->width;
|
||||
s->tile->height = s->height;
|
||||
s->frame = vf_alloc_desc(s->desc);
|
||||
s->frameLength = 0;
|
||||
|
||||
s->frames = 0;
|
||||
@@ -1295,10 +1302,10 @@ static struct video_frame * vidcap_dshow_grab(void *state, struct audio_frame **
|
||||
}
|
||||
//fprintf(stderr, "[dshow] s: %p\n", s);
|
||||
|
||||
s->tile->data = (char *) s->returnBuffer;
|
||||
s->frame->tiles[0].data = (char *) s->returnBuffer;
|
||||
//fprintf(stderr, "[dshow] s: %p\n", s);
|
||||
//s->tile->data_len = s->width * s->height * 3;
|
||||
s->tile->data_len = s->returnBufferLen;
|
||||
s->frame->tiles[0].data_len = s->returnBufferLen;
|
||||
|
||||
/*
|
||||
fprintf(stderr, "[dshow] s5: %p\n", s);
|
||||
@@ -1377,7 +1384,7 @@ static const struct {
|
||||
&MEDIASUBTYPE_Overlay, 0, "Overlay", L"Overlay", VIDEO_CODEC_NONE,
|
||||
&GUID_I420 , 12, "I420", L"I420", VIDEO_CODEC_NONE,
|
||||
&MEDIASUBTYPE_YUY2, 12, "YUY2", L"YUY2", YUYV,
|
||||
//&GUID_R210, 12, "r210", L"r210", r210,
|
||||
&GUID_R210, 12, "r210", L"r210", VIDEO_CODEC_NONE,
|
||||
&GUID_v210, 12, "v210", L"v210", v210,
|
||||
&GUID_V210, 12, "V210", L"V210", v210,
|
||||
&MEDIASUBTYPE_UYVY, 12, "UYVY", L"UYVY", UYVY,
|
||||
|
||||
Reference in New Issue
Block a user