[Sumover-dev] [svn commit] r4360 - vic/branches/mpeg4/video
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Fri Jan 23 13:36:52 GMT 2009
Author: douglask
Date: Fri Jan 23 13:36:39 2009
New Revision: 4360
Modified:
vic/branches/mpeg4/video/grabber-win32DS.cpp
vic/branches/mpeg4/video/grabber-win32DS.h
Log:
Added code to enable using GraphEdit's "Connect to Remote Graph" feature. GraphEdit comes with later versions of the Microsoft Platform SDK. Can also use the superior GraphStudio available here:
http://blog.monogram.sk/janos/tools/monogram-graphstudio/
grabber-win32DS is now supports capturing various YUV pixelformats instead of RGB24, which makes it compatible with more devices and also faster.
Fixes white virticle line artifact issue with 480i DV capture.
Modified: vic/branches/mpeg4/video/grabber-win32DS.cpp
==============================================================================
--- vic/branches/mpeg4/video/grabber-win32DS.cpp (original)
+++ vic/branches/mpeg4/video/grabber-win32DS.cpp Fri Jan 23 13:36:39 2009
@@ -129,7 +129,7 @@
#include "grabber.h"
#include "device-input.h"
#include "module.h"
-#include "rgb-converter.h"
+#include "yuv_convert.h"
#include "grabber-win32DS.h"
@@ -137,6 +137,9 @@
static DirectShowScanner findDirectShowDevices;
#endif
+static const GUID MEDIASUBTYPE_I420 =
+{0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+
#define NAMEBUF_LEN 200
IBaseFilter *pCaptureFilter[NUM_DEVS];
@@ -176,7 +179,7 @@
//#########################################################################
// DirectShowGrabber definition
-DirectShowGrabber::DirectShowGrabber(IBaseFilter *filt, const char *nick) {
+DirectShowGrabber::DirectShowGrabber(IBaseFilter *filt, const char * cformat, const char *nick) {
HRESULT hr;
WCHAR nameBufW[NAMEBUF_LEN];
@@ -189,7 +192,6 @@
svideoPort = -1;
compositePort = -1;
decimate_ = 2; //default
- converter_=0;
cb_mutex_=0;
crossbar_ = crossbarCursor_ = NULL;
pNullBaseFilter_=0;
@@ -198,12 +200,24 @@
pMediaControl_=0;
pGraph_=0;
pBuild_=0;
+ dwRegister_=0;
pCaptureFilter_ = filt;
pXBar_ = NULL;
pFilter_ = NULL;
capturing_=0;
max_fps_ = 30;
+ if(!strcmp(cformat, "420"))
+ cformat_ = CF_420;
+ if(!strcmp(cformat, "422"))
+ cformat_ = CF_422;
+ if(!strcmp(cformat, "cif"))
+ cformat_ = CF_CIF;
+
+ have_I420_ = false;
+ have_UYVY_ = false;
+ have_YUY2_ = false;
+
setport("external-in");
basewidth_ = NTSC_BASE_WIDTH;
@@ -245,9 +259,8 @@
return;
}
debug_msg("DirectShowGrabber::DirectShowGrabber(): graph instance acquired\n");
-
- // Tell the capture graph builder about the Filter Graph Manager (FGM).
+ // Tell the capture graph builder about the Filter Graph Manager (FGM).
hr = pBuild_->SetFiltergraph(pGraph_);
//showErrorMessage(hr);
if (FAILED(hr)) {
@@ -317,14 +330,18 @@
routeCrossbar();
}
- // We can presumably inspect crossbar==NULL here to determine if we want
- // to change the Sample Grabber media type.
ZeroMemory(&mt_, sizeof(AM_MEDIA_TYPE));
mt_.majortype = MEDIATYPE_Video;
- mt_.subtype = MEDIASUBTYPE_RGB24;
- //mt_.subtype = MEDIASUBTYPE_UYVY;
- //mt_.formattype == FORMAT_VideoInfo;
- hr = pSampleGrabber_->SetMediaType(&mt_);
+
+ if (have_I420_) {
+ mt_.subtype = MEDIASUBTYPE_I420; // Planar YUV 420
+ } else if (have_UYVY_) {
+ mt_.subtype = MEDIASUBTYPE_UYVY; // Packed YUV 420
+ } else if (have_YUY2_) {
+ mt_.subtype = MEDIASUBTYPE_YUY2; // Packed YUV 420
+ }
+
+ hr = pSampleGrabber_->SetMediaType(&mt_);
//showErrorMessage(hr);
// Obtain the interface used to run, stop, and pause the graph
@@ -335,6 +352,26 @@
return;
}
debug_msg("DirectShowGrabber::DirectShowGrabber(): graph media control interface acquired\n");
+
+ IMoniker * pMoniker = NULL;
+ IRunningObjectTable *pROT = NULL;
+
+ // register the filter graph instance in the Running Object Table (ROT)
+ // so can use GraphEdit to view graph, e.g.
+ // in GraphEdit's File menu, click "Connect to Remote Graph..."
+ if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
+ const size_t STRING_LENGTH = 256;
+
+ WCHAR wsz[STRING_LENGTH];
+ swprintf(wsz, STRING_LENGTH, L"FilterGraph %08x pid %08x", (DWORD_PTR)pGraph_, GetCurrentProcessId());
+
+ HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
+ if (SUCCEEDED(hr)) {
+ hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pGraph_, pMoniker, &dwRegister_);
+ pMoniker->Release();
+ }
+ pROT->Release();
+ }
}
//--------------------------------
@@ -346,19 +383,26 @@
//capturing_ = !capturing_;
if (capturing_) hr = pMediaControl_->Stop();
- //showErrorMessage(hr);
+ //showErrorMessage(hr);
- CloseHandle(cb_mutex_);
+ CloseHandle(cb_mutex_);
+
+ // unregister the filter graph instance in the Running Object Table (ROT).
+ IRunningObjectTable *pROT;
+ if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
+ pROT->Revoke(dwRegister_);
+ pROT->Release();
+ }
// Release COM objects in reverse order of instantiation
callback_->Release();
//delete callback; - done by above Release() call
pNullBaseFilter_->Release();
pSampleGrabber_->Release();
- pGrabberBaseFilter_->Release();
+ pGrabberBaseFilter_->Release();
pMediaControl_->Release();
- pGraph_->Release();
- pBuild_->Release();
+ pGraph_->Release();
+ pBuild_->Release();
}
//--------------------------------
@@ -467,7 +511,7 @@
setsize();
setCaptureOutputFormat();
hr = pBuild_->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
- pCaptureFilter_, pGrabberBaseFilter_, pNullBaseFilter_);
+ pCaptureFilter_, pGrabberBaseFilter_, pNullBaseFilter_);
if (SUCCEEDED(hr) )
debug_msg("DirectShowGrabber::DirectShowGrabber(): builder render stream\n");
else {
@@ -480,7 +524,7 @@
WaitForSingleObject(cb_mutex_, INFINITE);
- capturing_ = 1;
+ capturing_ = 1;
last_frame_ = NULL;
debug_msg("DirectShowGrabber::start(): starting capture graph...\n");
@@ -493,6 +537,8 @@
//showErrorMessage(hr);
Grabber::start();
+ ReleaseMutex(cb_mutex_);
+ Grabber::timeout();
}
//--------------------------------
@@ -508,9 +554,7 @@
//showErrorMessage(hr);
ReleaseMutex(cb_mutex_);
- delete converter_;
- capturing_ = 0;
- converter_ = 0;
+ capturing_ = 0;
last_frame_ = 0;
Grabber::stop();
@@ -527,6 +571,27 @@
Grabber::fps(f);
}
+void DirectShowGrabber::setsize() {
+
+ if (max_width_ >= D1_BASE_WIDTH){
+ max_width_ = D1_BASE_WIDTH;
+ max_height_ = D1_BASE_HEIGHT;
+ }
+
+ if (decimate_ == 1){ //i.e. Large
+ width_ = max_width_;
+ height_ = max_height_;
+ } else {
+ width_ = basewidth_ / decimate_;
+ height_ = baseheight_ / decimate_;
+ }
+
+ debug_msg("DirectShowGrabber::setsize: %dx%d\n", width_, height_);
+
+ set_size_cif(width_, height_);
+ allocref();
+}
+
//--------------------------------
void DirectShowGrabber::capture(BYTE *frameBuf, long bufLen) {
@@ -551,9 +616,26 @@
ReleaseMutex(cb_mutex_);
return FALSE;
}
-
- converter_->convert((u_int8_t*)last_frame_, width_,
- height_, frame_, outw_, outh_, TRUE);
+ switch (cformat_) {
+ case CF_420:
+ case CF_CIF:
+ if (have_I420_)
+ planarYUYV420_to_planarYUYV420((char *)frame_, outw_, outh_, (char *)last_frame_, inw_, inh_);
+ else if (have_UYVY_)
+ packedUYVY422_to_planarYUYV420((char *)frame_, outw_, outh_, (char *)last_frame_, inw_, inh_);
+ else if (have_YUY2_)
+ planarYUYV422_to_planarYUYV420((char *)frame_, outw_, outh_, (char *)last_frame_, inw_, inh_);
+ break;
+
+ case CF_422:
+ if (have_I420_)
+ planarYUYV420_to_planarYUYV422((char *)frame_, outw_, outh_, (char *)last_frame_, inw_, inh_);
+ else if (have_UYVY_)
+ packedUYVY422_to_planarYUYV422((char *)frame_, outw_, outh_, (char *)last_frame_, inw_, inh_);
+ else if (have_YUY2_)
+ planarYUYV420_to_planarYUYV422((char *)frame_, outw_, outh_, (char *)last_frame_, inw_, inh_);
+ break;
+ }
last_frame_ = NULL;
@@ -625,11 +707,13 @@
hr = pBuild_->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pCaptureFilter_, IID_IAMStreamConfig, (void**)&pConfig);
if (FAILED(hr)) {
- return FALSE;
+ return FALSE;
}
max_width_ = 0;
max_height_ = 0;
+ min_width_ = 0xFFFF;
+ min_height_ = 0xFFFF;
iCount = iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// Check the size to make sure we pass in the correct structure.
@@ -637,41 +721,47 @@
if ( iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS) ) {
for (int iFormat = 0; iFormat < iCount; iFormat++) {
- hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE *)&scc);
- //showErrorMessage(hr);
- // if pmtConfig->subtype for the capture filter is different from MEDIASUBTYPE_RGB24
- // (which is set in the SampleGrabber filter) then the FGM should insert an
- // appropriate converter into the filter graph - provided RenderStream() has not been called.
- // e.g // 59565955-0000-0010-8000-00AA00389B71 'UYVY' == MEDIASUBTYPE_UYVY
- // for simple firewire cam
- if( SUCCEEDED(hr) ) {
- if ((pmtConfig->majortype == MEDIATYPE_Video) &&
- //(pmtConfig->subtype == MEDIASUBTYPE_RGB24) &&
- (pmtConfig->formattype == FORMAT_VideoInfo) &&
- (pmtConfig->cbFormat >= sizeof (VIDEOINFOHEADER)) &&
- (pmtConfig->pbFormat != NULL)) {
- if(scc.MaxOutputSize.cx > max_width_){
- max_width_ = scc.MaxOutputSize.cx;
- max_height_ = scc.MaxOutputSize.cy;
- }
- debug_msg("Windows GDI BITMAPINFOHEADER follows:\n");
- pVih = (VIDEOINFOHEADER *)pmtConfig->pbFormat;
- debug_msg("biWidth= %d\n", pVih->bmiHeader.biWidth);
- debug_msg("biHeight= %d\n", pVih->bmiHeader.biHeight);
- debug_msg("biSize= %d\n", pVih->bmiHeader.biSize);
- debug_msg("biPlanes= %d\n", pVih->bmiHeader.biPlanes);
- debug_msg("biBitCount= %d\n", pVih->bmiHeader.biBitCount);
- debug_msg("biCompression= %d\n", pVih->bmiHeader.biCompression);
- debug_msg("biSizeImage= %d\n", pVih->bmiHeader.biSizeImage);
- debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter);
- debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter);
- }
- DeleteMediaType(pmtConfig);
- }
+ hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE *)&scc);
+ //showErrorMessage(hr);
+ if( SUCCEEDED(hr) ) {
+ if ((pmtConfig->majortype == MEDIATYPE_Video) &&
+ (pmtConfig->formattype == FORMAT_VideoInfo) &&
+ (pmtConfig->cbFormat >= sizeof (VIDEOINFOHEADER)) &&
+ (pmtConfig->pbFormat != NULL)) {
+ if(scc.MaxOutputSize.cx > max_width_){
+ max_width_ = scc.MaxOutputSize.cx;
+ max_height_ = scc.MaxOutputSize.cy;
+ }
+ if(scc.MinOutputSize.cx < min_width_){
+ min_width_ = scc.MinOutputSize.cx;
+ min_height_ = scc.MinOutputSize.cy;
+ }
+ if (pmtConfig->subtype == MEDIASUBTYPE_I420) {
+ have_I420_ = true; // Planar YUV 420
+ } else if (pmtConfig->subtype == MEDIASUBTYPE_UYVY) {
+ have_UYVY_ = true; // Packed YUV 420
+ } else if (pmtConfig->subtype == MEDIASUBTYPE_YUY2) {
+ have_YUY2_ = true; // Packed YUV 420
+ }
+
+ debug_msg("Windows GDI BITMAPINFOHEADER follows:\n");
+ pVih = (VIDEOINFOHEADER *)pmtConfig->pbFormat;
+ debug_msg("biWidth= %d\n", pVih->bmiHeader.biWidth);
+ debug_msg("biHeight= %d\n", pVih->bmiHeader.biHeight);
+ debug_msg("biSize= %d\n", pVih->bmiHeader.biSize);
+ debug_msg("biPlanes= %d\n", pVih->bmiHeader.biPlanes);
+ debug_msg("biBitCount= %d\n", pVih->bmiHeader.biBitCount);
+ debug_msg("biCompression= %d\n", pVih->bmiHeader.biCompression);
+ debug_msg("biSizeImage= %d\n", pVih->bmiHeader.biSizeImage);
+ debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter);
+ debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter);
+ }
+ DeleteMediaType(pmtConfig);
+ }
}
}
pConfig->Release();
- if (max_width_>0)
+ if (max_width_>0)
return TRUE;
return FALSE;
@@ -681,9 +771,9 @@
IAMStreamConfig *pConfig;
int iCount;
int iSize;
- int curr_w=0;
- int curr_h=0;
- int temp_w, temp_h;
+ int curr_w=0;
+ int curr_h=0;
+ int temp_w, temp_h;
VIDEOINFOHEADER *pVih;
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmtConfig;
@@ -699,9 +789,9 @@
hr = pBuild_->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pCaptureFilter_, IID_IAMStreamConfig, (void**)&pConfig);
if (FAILED(hr)) {
- debug_msg("Failed to FindInterface\n");
- Grabber::status_=-1;
- return;
+ debug_msg("Failed to FindInterface\n");
+ Grabber::status_=-1;
+ return;
}
debug_msg("DirectShowGrabber::setCaptureOutputFormat(): IAMStreamConfig interface acquired\n");
@@ -719,81 +809,81 @@
if( SUCCEEDED(hr) ) {
if ((pmtConfig->majortype == MEDIATYPE_Video) &&
//(pmtConfig->subtype == MEDIASUBTYPE_RGB24) &&
+ (pmtConfig->subtype == MEDIASUBTYPE_I420) &&
(pmtConfig->formattype == FORMAT_VideoInfo) &&
(pmtConfig->cbFormat >= sizeof (VIDEOINFOHEADER)) &&
- (pmtConfig->pbFormat != NULL) /* &&
- (scc.MaxOutputSize.cx <= width_) &&
- (scc.MaxOutputSize.cy <= height_)*/){
-
- if ((abs(width_ - scc.MaxOutputSize.cx) + abs(height_ - scc.MaxOutputSize.cy))<
- (abs(width_ - curr_w) +abs(height_ - curr_h))) {
-
- pVih = (VIDEOINFOHEADER *)pmtConfig->pbFormat;
- //pVih->bmiHeader.biWidth = width_;
- //pVih->bmiHeader.biHeight = height_;
- //pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
- // AvgTimePerFrame value that specifies the video frame'
- // average display time, in 100-nanosecond units.
- //if (fps_)
- //pVih->AvgTimePerFrame = 10000000/fps_;
-
- debug_msg("fps_= %d, AvgTimePerFrame: %d\n", fps_, pVih->AvgTimePerFrame);
-
- debug_msg("Windows GDI BITMAPINFOHEADER follows:\n");
- debug_msg("biWidth= %d\n", pVih->bmiHeader.biWidth);
- debug_msg("biHeight= %d\n", pVih->bmiHeader.biHeight);
- debug_msg("biSize= %d\n", pVih->bmiHeader.biSize);
- debug_msg("biPlanes= %d\n", pVih->bmiHeader.biPlanes);
- debug_msg("biBitCount= %d\n", pVih->bmiHeader.biBitCount);
- debug_msg("biCompression= %d\n", pVih->bmiHeader.biCompression);
- debug_msg("biSizeImage= %d\n", pVih->bmiHeader.biSizeImage);
- debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter);
- debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter);
- debug_msg("biClrUsed= %d\n", pVih->bmiHeader.biClrUsed);
- debug_msg("biClrImportant= %d\n", pVih->bmiHeader.biClrImportant);
-
- //pmtConfig->subtype = MEDIASUBTYPE_RGB24;
- temp_w = pVih->bmiHeader.biWidth;
- temp_h = pVih->bmiHeader.biHeight;
- pVih->bmiHeader.biWidth = width_;
- pVih->bmiHeader.biHeight = height_;
- hr = pConfig->SetFormat(pmtConfig);
- if (SUCCEEDED(hr)) {
- curr_w = width_;
- curr_h = height_;
- formatSet = 1;
- debug_msg("Set(wxh): %dx%d, and Got: %dx%d\n",width_,height_, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight);
- break;
- } else {
- if ((temp_w < width_) && (temp_h < height_)) {
- pVih->bmiHeader.biWidth = temp_w;
- pVih->bmiHeader.biHeight = temp_h;
- hr = pConfig->SetFormat(pmtConfig);
- if (SUCCEEDED(hr)) {
- curr_w = temp_w;
- curr_h = temp_h;
- formatSet = 1;
- debug_msg("Set(wxh): %dx%d, and Got: %dx%d\n",width_,height_, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight);
- }
- } else {
- debug_msg("Failed to Set format this time - trying again\n");
- }
- }
- }
+ (pmtConfig->pbFormat != NULL) /* &&
+ (scc.MaxOutputSize.cx <= width_) &&
+ (scc.MaxOutputSize.cy <= height_)*/){
+
+ if ((abs(width_ - scc.MaxOutputSize.cx) + abs(height_ - scc.MaxOutputSize.cy))<
+ (abs(width_ - curr_w) +abs(height_ - curr_h))) {
+
+ pVih = (VIDEOINFOHEADER *)pmtConfig->pbFormat;
+ //pVih->bmiHeader.biWidth = width_;
+ //pVih->bmiHeader.biHeight = height_;
+ //pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
+ // AvgTimePerFrame value that specifies the video frame'
+ // average display time, in 100-nanosecond units.
+ //if (fps_)
+ //pVih->AvgTimePerFrame = 10000000/fps_;
+
+ debug_msg("fps_= %d, AvgTimePerFrame: %d\n", fps_, pVih->AvgTimePerFrame);
+
+ debug_msg("Windows GDI BITMAPINFOHEADER follows:\n");
+ debug_msg("biWidth= %d\n", pVih->bmiHeader.biWidth);
+ debug_msg("biHeight= %d\n", pVih->bmiHeader.biHeight);
+ debug_msg("biSize= %d\n", pVih->bmiHeader.biSize);
+ debug_msg("biPlanes= %d\n", pVih->bmiHeader.biPlanes);
+ debug_msg("biBitCount= %d\n", pVih->bmiHeader.biBitCount);
+ debug_msg("biCompression= %d\n", pVih->bmiHeader.biCompression);
+ debug_msg("biSizeImage= %d\n", pVih->bmiHeader.biSizeImage);
+ debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter);
+ debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter);
+ debug_msg("biClrUsed= %d\n", pVih->bmiHeader.biClrUsed);
+ debug_msg("biClrImportant= %d\n", pVih->bmiHeader.biClrImportant);
+
+ temp_w = pVih->bmiHeader.biWidth;
+ temp_h = pVih->bmiHeader.biHeight;
+ pVih->bmiHeader.biWidth = width_;
+ pVih->bmiHeader.biHeight = height_;
+ hr = pConfig->SetFormat(pmtConfig);
+ if (SUCCEEDED(hr)) {
+ curr_w = width_;
+ curr_h = height_;
+ formatSet = 1;
+ debug_msg("Set(wxh): %dx%d, and Got: %dx%d\n",width_,height_, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight);
+ break;
+ } else {
+ if ((temp_w < width_) && (temp_h < height_)) {
+ pVih->bmiHeader.biWidth = temp_w;
+ pVih->bmiHeader.biHeight = temp_h;
+ hr = pConfig->SetFormat(pmtConfig);
+ if (SUCCEEDED(hr)) {
+ curr_w = temp_w;
+ curr_h = temp_h;
+ formatSet = 1;
+ debug_msg("Set(wxh): %dx%d, and Got: %dx%d\n",width_,height_, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight);
+ }
+ } else {
+ debug_msg("Failed to Set format this time - trying again\n");
+ }
+ }
+ }
}
DeleteMediaType(pmtConfig);
- }
+ }
}
}
pConfig->Release();
if ( formatSet ) {
if ( (curr_w != width_) || (curr_h != height_ )) {
- width_ = curr_w;
- height_ = curr_h;
- debug_msg("DirectShowGrabber::setCaptureOutputFormat: format set to near res: %dx%d\n",width_,height_);
+ width_ = curr_w;
+ height_ = curr_h;
+ debug_msg("DirectShowGrabber::setCaptureOutputFormat: format set to near res: %dx%d\n",width_,height_);
} else
- debug_msg("DirectShowGrabber::setCaptureOutputFormat: format set\n");
+ debug_msg("DirectShowGrabber::setCaptureOutputFormat: format set\n");
}
else
debug_msg("DirectShowGrabber::setCaptureOutputFormat: format not set\n");
@@ -859,66 +949,30 @@
}
-//#########################################################################
-// DirectShowCIFGrabber class
-
-DirectShowCIFGrabber::DirectShowCIFGrabber(IBaseFilter *f, const char * nick) : DirectShowGrabber(f, nick) {
- debug_msg("DirectShowCIFGrabber\n");
-}
-
-//--------------------------------
-
-DirectShowCIFGrabber::~DirectShowCIFGrabber() {
- debug_msg("~DirectShowCIFGrabber\n");
-}
-
-//--------------------------------
-
-void DirectShowCIFGrabber::start() {
- DirectShowGrabber::start();
- converter(new RGB_Converter_420(24, (u_int8_t *)NULL, 0));
- ReleaseMutex(cb_mutex_);
- Grabber::timeout();
-}
-
-//--------------------------------
-
-void DirectShowCIFGrabber::setsize() {
-
- if(max_width_ >= D1_BASE_WIDTH){
- max_width_ = D1_BASE_WIDTH;
- max_height_ = D1_BASE_HEIGHT;
- }
-
- if(decimate_ == 1){ //i.e. Large
- width_ = max_width_;
- height_ = max_height_;
- } else {
- width_ = basewidth_ / decimate_;
- height_ = baseheight_ / decimate_;
- }
-
- debug_msg("DirectShowCIFGrabber::setsize: %dx%d\n", width_, height_);
-
- set_size_cif(width_, height_);
- allocref();
-}
//#########################################################################
// DirectShowDevice class
DirectShowDevice::DirectShowDevice(char *friendlyName, IBaseFilter *pCapFilt) : InputDevice(friendlyName) {
- attri_ = new char[100];
+ attri_ = new char[128];
attri_[0] = 0;
debug_msg("new DirectShowDevice(): friendlyName=%s\n", friendlyName);
- pDirectShowFilter_ = pCapFilt;
- //SV: XXX got rid of 422 format since there's no grabber returned for it and vic crashes
- attributes_ = "format { 420 } size { large small cif } port { extern-in } type { pal ntsc } ";
- DirectShowCIFGrabber o(pDirectShowFilter_, friendlyName);
+ pDirectShowFilter_ = pCapFilt;
+ DirectShowGrabber o(pDirectShowFilter_, "420", friendlyName);
- strcat(attri_, "format { 420 } size { large small cif } type { pal ntsc } port { ");
+ strcat(attri_, "format { 420 422 cif } size { ");
+
+ if (o.minWidth() > (CIF_BASE_WIDTH / 2)) {
+ strcat(attri_, "large");
+ } else if (o.maxWidth() < NTSC_BASE_WIDTH) {
+ strcat(attri_, "small cif");
+ } else {
+ strcat(attri_, "small cif large");
+ }
+
+ strcat(attri_, " } type { pal ntsc } port { ");
if(o.hasSVideo() || o.hasComposite()){
if(o.hasSVideo()){
strcat(attri_, "S-Video ");
@@ -945,11 +999,8 @@
Tcl& tcl = Tcl::instance();
if ((argc == 3) && (strcmp(argv[1], "open") == 0)) {
TclObject* o = 0;
- if (strcmp(argv[2], "cif") == 0){
- o = directShowGrabber_ = new DirectShowCIFGrabber(pDirectShowFilter_);
- }else if (strcmp(argv[2], "422") == 0)
- o = directShowGrabber_ = 0; // one day oughta be "new DirectShow422Grabber(directShowFilter_);" // msp
+ o = directShowGrabber_ = new DirectShowGrabber(pDirectShowFilter_, argv[2]);
if (o != 0)
Tcl::instance().result(o->name());
return (TCL_OK);
Modified: vic/branches/mpeg4/video/grabber-win32DS.h
==============================================================================
--- vic/branches/mpeg4/video/grabber-win32DS.h (original)
+++ vic/branches/mpeg4/video/grabber-win32DS.h Fri Jan 23 13:36:39 2009
@@ -52,6 +52,9 @@
//extern void ShowErrorMessage(HRESULT, int, char* );
+#define CF_422 0
+#define CF_420 1
+#define CF_CIF 2
static const int D1_BASE_WIDTH = 720;
static const int D1_BASE_HEIGHT = 480;
@@ -82,12 +85,10 @@
class DirectShowGrabber : public Grabber {
public:
- DirectShowGrabber(IBaseFilter *, const char * nick);
+ DirectShowGrabber(IBaseFilter *, const char * cformat, const char * nick = 0);
~DirectShowGrabber();
virtual int command(int argc, const char*const* argv);
- inline void converter(Converter* v) {
- converter_ = v;
- }
+
void capture(BYTE *, long);
bool hasComposite(){
@@ -98,13 +99,29 @@
return (svideoPort >= 0);
}
+ int maxWidth(){
+ return max_width_;
+ }
+
+ int maxHeight(){
+ return max_height_;
+ }
+
+ int minWidth(){
+ return min_width_;
+ }
+
+ int minHeight(){
+ return min_height_;
+ }
+
int capturing_;
HANDLE cb_mutex_;
protected:
virtual void start();
virtual void stop();
virtual void fps(int);
- virtual void setsize() = 0;
+ virtual void setsize();
virtual int grab();
void setport(const char *port);
int getCaptureCapabilities();
@@ -116,14 +133,20 @@
u_int max_fps_;
int max_width_;
int max_height_;
+ int min_width_;
+ int min_height_;
int width_;
int height_;
+ int cformat_;
int compositePort;
int svideoPort;
+ bool have_I420_; // YUV 4:2:0 planar
+ bool have_UYVY_; // YUV 4:2:0 packed
+ bool have_YUY2_; // as for UYVY but with different component ordering
+
u_int decimate_; // set in this::command via small/normal/large in vic UI; msp
BYTE *last_frame_;
- Converter *converter_;
private:
IBaseFilter* pFilter_;
@@ -135,6 +158,7 @@
IGraphBuilder* pGraph_;
ICaptureGraphBuilder2* pBuild_;
IMediaControl* pMediaControl_;
+ DWORD dwRegister_;
AM_MEDIA_TYPE mt_;
Callback *callback_;
@@ -150,10 +174,10 @@
//#########################################################################
-class DirectShowCIFGrabber : public DirectShowGrabber {
+class DirectShowCIGrabber : public DirectShowGrabber {
public:
- DirectShowCIFGrabber(IBaseFilter *, const char *nick = 0 );
- ~DirectShowCIFGrabber();
+ DirectShowCIGrabber(IBaseFilter *, const char *nick = 0 );
+ ~DirectShowCIGrabber();
protected:
virtual void start();
virtual void setsize();
More information about the Sumover-dev
mailing list