Commit 13ede345 authored by unknown's avatar unknown Committed by Alexander Alekhin

Add support for changing fourcc and support mono formats (e.g. Y8, Y16)

parent e5d7f446
...@@ -141,6 +141,10 @@ DEFINE_GUID(MEDIASUBTYPE_Y8, 0x20203859, 0x0000, 0x0010, 0x80, 0x00, ...@@ -141,6 +141,10 @@ DEFINE_GUID(MEDIASUBTYPE_Y8, 0x20203859, 0x0000, 0x0010, 0x80, 0x00,
0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
DEFINE_GUID(MEDIASUBTYPE_Y800, 0x30303859, 0x0000, 0x0010, 0x80, 0x00, DEFINE_GUID(MEDIASUBTYPE_Y800, 0x30303859, 0x0000, 0x0010, 0x80, 0x00,
0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
DEFINE_GUID(MEDIASUBTYPE_Y16, 0x20363159, 0x0000, 0x0010, 0x80, 0x00,
0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
DEFINE_GUID(MEDIASUBTYPE_BY8, 0x20385942, 0x0000, 0x0010, 0x80, 0x00,
0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
DEFINE_GUID(CLSID_CaptureGraphBuilder2,0xbf87b6e1,0x8c27,0x11d0,0xb3,0xf0,0x00,0xaa,0x00,0x37,0x61,0xc5); DEFINE_GUID(CLSID_CaptureGraphBuilder2,0xbf87b6e1,0x8c27,0x11d0,0xb3,0xf0,0x00,0xaa,0x00,0x37,0x61,0xc5);
DEFINE_GUID(CLSID_FilterGraph,0xe436ebb3,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_GUID(CLSID_FilterGraph,0xe436ebb3,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
...@@ -333,7 +337,7 @@ static void DebugPrintOut(const char *format, ...) ...@@ -333,7 +337,7 @@ static void DebugPrintOut(const char *format, ...)
//videoInput defines //videoInput defines
#define VI_VERSION 0.1995 #define VI_VERSION 0.1995
#define VI_MAX_CAMERAS 20 #define VI_MAX_CAMERAS 20
#define VI_NUM_TYPES 20 //MGB #define VI_NUM_TYPES 22 //MGB
#define VI_NUM_FORMATS 18 //DON'T TOUCH #define VI_NUM_FORMATS 18 //DON'T TOUCH
//defines for setPhyCon - tuner is not as well supported as composite and s-video //defines for setPhyCon - tuner is not as well supported as composite and s-video
...@@ -427,6 +431,7 @@ class videoDevice{ ...@@ -427,6 +431,7 @@ class videoDevice{
bool setupStarted; bool setupStarted;
bool specificFormat; bool specificFormat;
bool autoReconnect; bool autoReconnect;
bool convertRGB;
int nFramesForReconnect; int nFramesForReconnect;
unsigned long nFramesRunning; unsigned long nFramesRunning;
int connection; int connection;
...@@ -522,6 +527,10 @@ class videoInput{ ...@@ -522,6 +527,10 @@ class videoInput{
int getFourcc(int deviceID) const; int getFourcc(int deviceID) const;
double getFPS(int deviceID) const; double getFPS(int deviceID) const;
// RGB conversion setting
bool getConvertRGB(int deviceID);
bool setConvertRGB(int deviceID, bool enable);
//completely stops and frees a device //completely stops and frees a device
void stopDevice(int deviceID); void stopDevice(int deviceID);
...@@ -539,11 +548,13 @@ class videoInput{ ...@@ -539,11 +548,13 @@ class videoInput{
int property_window_count(int device_idx); int property_window_count(int device_idx);
GUID getMediasubtype(int deviceID);
private: private:
void setPhyCon(int deviceID, int conn); void setPhyCon(int deviceID, int conn);
void setAttemptCaptureSize(int deviceID, int w, int h,GUID mediaType=MEDIASUBTYPE_RGB24); void setAttemptCaptureSize(int deviceID, int w, int h,GUID mediaType=MEDIASUBTYPE_RGB24);
bool setup(int deviceID); bool setup(int deviceID);
void processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip); void processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip, int bytesperpixel = 3);
int start(int deviceID, videoDevice * VD); int start(int deviceID, videoDevice * VD);
int getDeviceCount(); int getDeviceCount();
void getMediaSubtypeAsString(GUID type, char * typeAsString); void getMediaSubtypeAsString(GUID type, char * typeAsString);
...@@ -586,6 +597,24 @@ class videoInput{ ...@@ -586,6 +597,24 @@ class videoInput{
/////////////////////////// HANDY FUNCTIONS ///////////////////////////// /////////////////////////// HANDY FUNCTIONS /////////////////////////////
//Included by e-con
//Checks whether the current formattype is single byte format
//Eg: MEDIASUBTYPE_Y800, MEDIASUBTYPE_Y8, MEDIASUBTYPE_GREY
static bool checkSingleByteFormat(GUID formatType)
{
if (formatType == MEDIASUBTYPE_Y800 ||
formatType == MEDIASUBTYPE_Y8 ||
formatType == MEDIASUBTYPE_GREY)
{
return true;
}
else
{
return false;
}
}
static void MyFreeMediaType(AM_MEDIA_TYPE& mt){ static void MyFreeMediaType(AM_MEDIA_TYPE& mt){
if (mt.cbFormat != 0) if (mt.cbFormat != 0)
{ {
...@@ -761,6 +790,7 @@ videoDevice::videoDevice(){ ...@@ -761,6 +790,7 @@ videoDevice::videoDevice(){
setupStarted = false; setupStarted = false;
specificFormat = false; specificFormat = false;
autoReconnect = false; autoReconnect = false;
convertRGB = true;
requestedFrameTime = -1; requestedFrameTime = -1;
pBuffer = 0; pBuffer = 0;
...@@ -788,7 +818,20 @@ void videoDevice::setSize(int w, int h){ ...@@ -788,7 +818,20 @@ void videoDevice::setSize(int w, int h){
{ {
width = w; width = w;
height = h; height = h;
videoSize = w*h*3;
if (checkSingleByteFormat(pAmMediaType->subtype))
{
videoSize = w * h;
}
else if (pAmMediaType->subtype == MEDIASUBTYPE_Y16)
{
videoSize = w * h * 2;
}
else
{
videoSize = w * h * 3;
}
sizeSet = true; sizeSet = true;
pixels = new unsigned char[videoSize]; pixels = new unsigned char[videoSize];
pBuffer = new char[videoSize]; pBuffer = new char[videoSize];
...@@ -1060,6 +1103,8 @@ videoInput::videoInput(){ ...@@ -1060,6 +1103,8 @@ videoInput::videoInput(){
mediaSubtypes[17] = MEDIASUBTYPE_Y8; mediaSubtypes[17] = MEDIASUBTYPE_Y8;
mediaSubtypes[18] = MEDIASUBTYPE_GREY; mediaSubtypes[18] = MEDIASUBTYPE_GREY;
mediaSubtypes[19] = MEDIASUBTYPE_I420; mediaSubtypes[19] = MEDIASUBTYPE_I420;
mediaSubtypes[20] = MEDIASUBTYPE_BY8;
mediaSubtypes[21] = MEDIASUBTYPE_Y16;
//The video formats we support //The video formats we support
formatTypes[VI_NTSC_M] = AnalogVideo_NTSC_M; formatTypes[VI_NTSC_M] = AnalogVideo_NTSC_M;
...@@ -1181,6 +1226,9 @@ bool videoInput::setupDeviceFourcc(int deviceNumber, int w, int h,int fourcc){ ...@@ -1181,6 +1226,9 @@ bool videoInput::setupDeviceFourcc(int deviceNumber, int w, int h,int fourcc){
GUID *mediaType = getMediaSubtypeFromFourcc(fourcc); GUID *mediaType = getMediaSubtypeFromFourcc(fourcc);
if ( mediaType ) { if ( mediaType ) {
setAttemptCaptureSize(deviceNumber,w,h,*mediaType); setAttemptCaptureSize(deviceNumber,w,h,*mediaType);
} else {
DebugPrintOut("SETUP: Unknown GUID \n");
return false;
} }
} else { } else {
setAttemptCaptureSize(deviceNumber,w,h); setAttemptCaptureSize(deviceNumber,w,h);
...@@ -1448,6 +1496,37 @@ int videoInput::getSize(int id) const ...@@ -1448,6 +1496,37 @@ int videoInput::getSize(int id) const
} }
// ----------------------------------------------------------------------
//
//
// ----------------------------------------------------------------------
bool videoInput::getConvertRGB(int id)
{
if (isDeviceSetup(id))
{
return VDList[id]->convertRGB;
}
else
{
return false;
}
}
bool videoInput::setConvertRGB(int id, bool enable)
{
if (isDeviceSetup(id))
{
VDList[id]->convertRGB = enable;
return true;
}
else
{
return false;
}
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Uses a supplied buffer // Uses a supplied buffer
...@@ -1472,7 +1551,24 @@ bool videoInput::getPixels(int id, unsigned char * dstBuffer, bool flipRedAndBlu ...@@ -1472,7 +1551,24 @@ bool videoInput::getPixels(int id, unsigned char * dstBuffer, bool flipRedAndBlu
int height = VDList[id]->height; int height = VDList[id]->height;
int width = VDList[id]->width; int width = VDList[id]->width;
processPixels(src, dst, width, height, flipRedAndBlue, flipImage); // Conditional processing for 8/16-bit images (e-Con systems)
if (checkSingleByteFormat(VDList[id]->pAmMediaType->subtype))
{
memcpy(dst, src, width * height);
}
else if (VDList[id]->pAmMediaType->subtype == MEDIASUBTYPE_Y16)
{
if (!VDList[id]->convertRGB) {
memcpy(dst, src, width * height * 2);
}
else {
processPixels(src, dst, width, height, flipRedAndBlue, flipImage, 2);
}
}
else
{
processPixels(src, dst, width, height, flipRedAndBlue, flipImage);
}
VDList[id]->sgCallback->newFrame = false; VDList[id]->sgCallback->newFrame = false;
LeaveCriticalSection(&VDList[id]->sgCallback->critSection); LeaveCriticalSection(&VDList[id]->sgCallback->critSection);
...@@ -2106,62 +2202,81 @@ bool videoInput::setup(int deviceNumber){ ...@@ -2106,62 +2202,81 @@ bool videoInput::setup(int deviceNumber){
// You have any combination of those. // You have any combination of those.
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
void videoInput::processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip){ void videoInput::processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip, int bytesperpixel){
int widthInBytes = width * 3; int widthInBytes = width * bytesperpixel;
int numBytes = widthInBytes * height; int numBytes = widthInBytes * height;
if(!bRGB){ if (bytesperpixel == 2) {
for (int i = 0; i < width*height; i++) {
if (bytesperpixel == 2) {
*dst = (uint8_t) (*((uint16_t*) src) >> 8);
dst++;
*dst = (uint8_t) (*((uint16_t*)src) >> 8);
dst++;
//int x = 0; *dst = (uint8_t) (*((uint16_t*)src) >> 8);
//int y = 0; dst++;
if(bFlip){ src += 2;
for(int y = 0; y < height; y++){
memcpy(dst + (y * widthInBytes), src + ( (height -y -1) * widthInBytes), widthInBytes);
} }
}else{
memcpy(dst, src, numBytes);
} }
}else{ }
if(bFlip){ else
{
if(!bRGB){
int x = 0; //int x = 0;
int y = (height - 1) * widthInBytes; //int y = 0;
src += y;
for(int i = 0; i < numBytes; i+=3){ if(bFlip){
if(x >= width){ for(int y = 0; y < height; y++){
x = 0; memcpy(dst + (y * widthInBytes), src + ( (height -y -1) * widthInBytes), widthInBytes);
src -= widthInBytes*2;
} }
*dst = *(src+2); }else{
dst++; memcpy(dst, src, numBytes);
}
}else{
if(bFlip){
*dst = *(src+1); int x = 0;
dst++; int y = (height - 1) * widthInBytes;
src += y;
*dst = *src; for(int i = 0; i < numBytes; i+=3){
dst++; if(x >= width){
x = 0;
src -= widthInBytes*2;
}
*dst = *(src+2);
dst++;
*dst = *(src+1);
dst++;
src+=3; *dst = *src;
x++; dst++;
src+=3;
x++;
}
} }
} else{
else{ for(int i = 0; i < numBytes; i+=3){
for(int i = 0; i < numBytes; i+=3){ *dst = *(src+2);
*dst = *(src+2); dst++;
dst++;
*dst = *(src+1); *dst = *(src+1);
dst++; dst++;
*dst = *src; *dst = *src;
dst++; dst++;
src+=3; src+=3;
}
} }
} }
} }
...@@ -2192,6 +2307,8 @@ void videoInput::getMediaSubtypeAsString(GUID type, char * typeAsString){ ...@@ -2192,6 +2307,8 @@ void videoInput::getMediaSubtypeAsString(GUID type, char * typeAsString){
else if(type == MEDIASUBTYPE_Y8) sprintf(tmpStr, "Y8"); else if(type == MEDIASUBTYPE_Y8) sprintf(tmpStr, "Y8");
else if(type == MEDIASUBTYPE_GREY) sprintf(tmpStr, "GREY"); else if(type == MEDIASUBTYPE_GREY) sprintf(tmpStr, "GREY");
else if(type == MEDIASUBTYPE_I420) sprintf(tmpStr, "I420"); else if(type == MEDIASUBTYPE_I420) sprintf(tmpStr, "I420");
else if (type == MEDIASUBTYPE_BY8) sprintf(tmpStr, "BY8");
else if (type == MEDIASUBTYPE_Y16) sprintf(tmpStr, "Y16");
else sprintf(tmpStr, "OTHER"); else sprintf(tmpStr, "OTHER");
memcpy(typeAsString, tmpStr, sizeof(char)*8); memcpy(typeAsString, tmpStr, sizeof(char)*8);
...@@ -2333,6 +2450,10 @@ void videoInput::getCameraPropertyAsString(int prop, char * propertyAsString){ ...@@ -2333,6 +2450,10 @@ void videoInput::getCameraPropertyAsString(int prop, char * propertyAsString){
memcpy(propertyAsString, tmpStr, sizeof(char)*16); memcpy(propertyAsString, tmpStr, sizeof(char)*16);
} }
GUID videoInput::getMediasubtype(int deviceID)
{
return VDList[deviceID]->pAmMediaType->subtype;
}
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------
static void findClosestSizeAndSubtype(videoDevice * VD, int widthIn, int heightIn, int &widthOut, int &heightOut, GUID & mediatypeOut){ static void findClosestSizeAndSubtype(videoDevice * VD, int widthIn, int heightIn, int &widthOut, int &heightOut, GUID & mediatypeOut){
...@@ -2720,7 +2841,17 @@ int videoInput::start(int deviceID, videoDevice *VD){ ...@@ -2720,7 +2841,17 @@ int videoInput::start(int deviceID, videoDevice *VD){
ZeroMemory(&mt,sizeof(AM_MEDIA_TYPE)); ZeroMemory(&mt,sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video; mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
// Disable format conversion if using 8/16-bit data (e-Con systems)
if (checkSingleByteFormat(VD->pAmMediaType->subtype) || (VD->pAmMediaType->subtype == MEDIASUBTYPE_Y16)) {
DebugPrintOut("SETUP: Not converting frames to RGB.\n");
mt.subtype = VD->pAmMediaType->subtype;
}
else
{
DebugPrintOut("SETUP: Converting frames to RGB.\n");
mt.subtype = MEDIASUBTYPE_RGB24; //Making it RGB24, does conversion from YUV to RGB
}
mt.formattype = FORMAT_VideoInfo; mt.formattype = FORMAT_VideoInfo;
//VD->pAmMediaType->subtype = VD->videoType; //VD->pAmMediaType->subtype = VD->videoType;
...@@ -3261,12 +3392,19 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal) ...@@ -3261,12 +3392,19 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
case CV_CAP_PROP_FOURCC: case CV_CAP_PROP_FOURCC:
m_fourcc = (int)(unsigned long)(propVal); m_fourcc = (int)(unsigned long)(propVal);
m_width = (int)getProperty(CAP_PROP_FRAME_WIDTH);
m_height = (int)getProperty(CAP_PROP_FRAME_HEIGHT);
if (-1 == m_fourcc) if (-1 == m_fourcc)
{ {
// following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1 // following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1
// TODO - how to create a capture pin dialog // TODO - how to create a capture pin dialog
} }
handled = true; else
{
handled = true;
}
break; break;
case CV_CAP_PROP_FPS: case CV_CAP_PROP_FPS:
...@@ -3295,6 +3433,12 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal) ...@@ -3295,6 +3433,12 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
} }
return g_VI.setVideoSettingCamera(m_index, CameraControl_Focus, currentFocus, enabled ? CameraControl_Flags_Auto | CameraControl_Flags_Manual : CameraControl_Flags_Manual, enabled ? true : false); return g_VI.setVideoSettingCamera(m_index, CameraControl_Focus, currentFocus, enabled ? CameraControl_Flags_Auto | CameraControl_Flags_Manual : CameraControl_Flags_Manual, enabled ? true : false);
} }
case CV_CAP_PROP_CONVERT_RGB:
{
return g_VI.setConvertRGB(m_index, cvRound(propVal) == 1);
}
} }
if (handled) if (handled)
...@@ -3302,7 +3446,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal) ...@@ -3302,7 +3446,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
// a stream setting // a stream setting
if (m_width > 0 && m_height > 0) if (m_width > 0 && m_height > 0)
{ {
if (m_width != g_VI.getWidth(m_index) || m_height != g_VI.getHeight(m_index) )//|| fourcc != VI.getFourcc(index) ) if (m_width != g_VI.getWidth(m_index) || m_height != g_VI.getHeight(m_index) || m_fourcc != g_VI.getFourcc(m_index) )
{ {
int fps = static_cast<int>(g_VI.getFPS(m_index)); int fps = static_cast<int>(g_VI.getFPS(m_index));
g_VI.stopDevice(m_index); g_VI.stopDevice(m_index);
...@@ -3313,10 +3457,14 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal) ...@@ -3313,10 +3457,14 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
bool success = g_VI.isDeviceSetup(m_index); bool success = g_VI.isDeviceSetup(m_index);
if (success) if (success)
{ {
DebugPrintOut("SETUP: Updated FourCC\n");
m_widthSet = m_width; m_widthSet = m_width;
m_heightSet = m_height; m_heightSet = m_height;
m_width = m_height = m_fourcc = -1; m_width = m_height = m_fourcc = -1;
} }
else {
DebugPrintOut("SETUP: Couldn't update FourCC\n");
}
return success; return success;
} }
return true; return true;
...@@ -3366,7 +3514,18 @@ bool VideoCapture_DShow::grabFrame() ...@@ -3366,7 +3514,18 @@ bool VideoCapture_DShow::grabFrame()
} }
bool VideoCapture_DShow::retrieveFrame(int, OutputArray frame) bool VideoCapture_DShow::retrieveFrame(int, OutputArray frame)
{ {
frame.create(Size(g_VI.getWidth(m_index), g_VI.getHeight(m_index)), CV_8UC3); int w = g_VI.getWidth(m_index), h = g_VI.getHeight(m_index);
bool convertRGB = g_VI.getConvertRGB(m_index);
// Set suitable output matrix type (e-Con systems)
if (checkSingleByteFormat(g_VI.getMediasubtype(m_index))){
frame.create(Size(w, h), CV_8UC1);
} else if (g_VI.getMediasubtype(m_index) == MEDIASUBTYPE_Y16 && !convertRGB) {
frame.create(Size(w, h), CV_16UC1);
} else {
frame.create(Size(w, h), CV_8UC3);
}
cv::Mat mat = frame.getMat(); cv::Mat mat = frame.getMat();
return g_VI.getPixels(m_index, mat.ptr(), false, true ); return g_VI.getPixels(m_index, mat.ptr(), false, true );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment