This commit is contained in:
2024-08-07 09:16:27 -04:00
parent fdfadd5c7e
commit 5f971cf684
5200 changed files with 731717 additions and 0 deletions

View File

@@ -0,0 +1,939 @@
#include <dvcap/CaptureDeviceGraph.hpp>
#include <com/variant.hpp>
#include <com/bstring.hpp>
#include <dvcap/dvcap.hpp>
CaptureDeviceGraph::CaptureDeviceGraph()
: mVideoFormat(DVENCODERVIDEOFORMAT_NTSC),
mDVResolution(DVRESOLUTION_HALF),
mSubunitMode(VCRMode), mLogFile("dvcap.log","wb")
{
SystemTime systemTime;
mLogFile.writeLine("*********************************************************************");
mLogFile.writeLine(String(" DVCAPTURE LOG FILE STARTED AT:")+systemTime.toString());
mLogFile.writeLine("*********************************************************************");
}
CaptureDeviceGraph::~CaptureDeviceGraph()
{
if(mVideoWindow.isOkay())
{
mVideoWindow->put_Visible(OAFALSE);
mVideoWindow->put_Owner(0);
}
freeFilters();
}
void CaptureDeviceGraph::freeFilters()
{
mGraph.Release();
mCaptureGraphBuilder.Release();
mMediaEvent.Release();
mInputFileFilter.Release();
mDeviceFilter.Release();
mExtDevice.Release();
mExtTransport.Release();
mTimecodeReader.Release();
mVideoWindow.Release();
mDroppedFrames.Release();
}
bool CaptureDeviceGraph::buildBasicGraph()
{
ComResult comResult;
if(!initializeGraph())
{
error("[CaptureDeviceGraph::buildBasicGraph] Failed to create filter graph.");
return false;
}
if(!addDeviceFilter())
{
error("[CaptureDeviceGraph::buildBasicGraph] Failed to add device filter.");
return false;
}
LOG("[CaptureDeviceGraph::buildBasicGraph] mDeviceFilter->QueryInterface(IID_IAMExtTransport,(void**)(IAMExtTransport**)mExtTransport)");
comResult=mDeviceFilter->QueryInterface(IID_IAMExtTransport,(void**)(IAMExtTransport**)mExtTransport);
if(!comResult.success())
{
error("[CaptureDeviceGraph::buildBasicGraph] Failed to QueryInterface IID_IAMExtTransport.");
return false;
}
LOG("[CaptureDeviceGraph::buildBasicGraph] mDeviceFilter->QueryInterface(IID_IAMExtDevice,(void**)(IAMExtDevice**)mExtDevice)");
comResult=mDeviceFilter->QueryInterface(IID_IAMExtDevice,(void**)(IAMExtDevice**)mExtDevice);
if(!comResult.success())
{
error("[CaptureDeviceGraph::buildBasicGraph] Failed to QueryInterface IID_IAMExtDevice.");
return false;
}
LOG("[CaptureDeviceGraph::buildBasicGraph] mDeviceFilter->QueryInterface(IID_IAMTimecodeReader,(void**)(IAMTimecodeReader**)mTimecodeReader)");
comResult=mDeviceFilter->QueryInterface(IID_IAMTimecodeReader,(void**)(IAMTimecodeReader**)mTimecodeReader);
if(!comResult.success())
{
error("[CaptureDeviceGraph::buildBasicGraph] Failed to QueryInterface IID_IAMTimecodeReader.");
return false;
}
mSubunitMode=getDVMode();
return true;
}
bool CaptureDeviceGraph::initializeGraph()
{
ComResult comResult;
mGraph.Release();
mCaptureGraphBuilder.Release();
mMediaEvent.Release();
mMediaControl.Release();
mVideoWindow.Release();
LOG("[CaptureDeviceGraph::initializeGraph] mGraph.createInstance(CLSID_FilterGraph,IID_IGraphBuilder)");
comResult=mGraph.createInstance(CLSID_FilterGraph,IID_IGraphBuilder);
if(!comResult.success())
{
error("[CaptureDeviceGraph::initializeGraph] Failed to create CLSID_FilterGraph.");
return false;
}
LOG("[CaptureDeviceGraph::initializeGraph] mCaptureGraphBuilder.createInstance(CLSID_CaptureGraphBuilder2,IID_ICaptureGraphBuilder2)");
comResult=mCaptureGraphBuilder.createInstance(CLSID_CaptureGraphBuilder2,IID_ICaptureGraphBuilder2);
if(!comResult.success())
{
error("[CaptureDeviceGraph::initializeGraph] Failed to create CLSID_CaptureGraphBuilder2.");
return false;
}
LOG("[CaptureDeviceGraph::initializeGraph] mCaptureGraphBuilder->SetFiltergraph(mGraph)");
comResult=mCaptureGraphBuilder->SetFiltergraph(mGraph);
if(!comResult.success())
{
error("[CaptureDeviceGraph::initializeGraph] Failed to SetFiltergraph.");
return false;
}
LOG("[CaptureDeviceGraph::initializeGraph] mGraph->QueryInterface(IID_IMediaEventEx,(void**)(IMediaEventEx**)mMediaEvent)");
comResult=mGraph->QueryInterface(IID_IMediaEventEx,(void**)(IMediaEventEx**)mMediaEvent);
if(!comResult.success())
{
error("[CaptureDeviceGraph::initializeGraph] Failed to QueryInterface IMediaEventEx.");
return false;
}
LOG("[CaptureDeviceGraph::initializeGraph] mGraph->QueryInterface(IID_IMediaControl,(void**)(IMediaControl**)mMediaControl)");
comResult=mGraph->QueryInterface(IID_IMediaControl,(void**)(IMediaControl**)mMediaControl);
if(!comResult.success())
{
error("[CaptureDeviceGraph::initializeGraph] Failed to QueryInterface IMediaControl.");
return false;
}
LOG("[CaptureDeviceGraph::initializeGraph] mGraph->QueryInterface(IID_IVideoWindow,(void**)(IVideoWindow**)mVideoWindow)");
comResult=mGraph->QueryInterface(IID_IVideoWindow,(void**)(IVideoWindow**)mVideoWindow);
if(!comResult.success())
{
error("[CaptureDeviceGraph::initializeGraph] Failed to QueryInterface IVideoWindow.");
return false;
}
return true;
}
bool CaptureDeviceGraph::addDeviceFilter()
{
ComResult comResult;
ComPointer<ICreateDevEnum> createDevEnum;
ComPointer<IEnumMoniker> enumMoniker;
ComPointer<IMoniker> moniker;
ULONG nFetched=0;
LOG("[CaptureDeviceGraph::addDeviceFilter] createDevEnum.createInstance(CLSID_SystemDeviceEnum,IID_ICreateDevEnum)");
comResult=createDevEnum.createInstance(CLSID_SystemDeviceEnum,IID_ICreateDevEnum);
if(!comResult.success())
{
error("[CaptureDeviceGraph::addDeviceFilter] Failed to create CLSID_SystemDeviceEnum");
return false;
}
LOG("[CaptureDeviceGraph::addDeviceFilter] createDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,(IEnumMoniker**)enumMoniker,0)");
if(!ComResult(createDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,(IEnumMoniker**)enumMoniker,0)).success())
{
error("[CaptureDeviceGraph::addDeviceFilter] createDevEnum->CreateClassEnumerator() Failed.");
return false;
}
if(!enumMoniker.isOkay())
{
error("[CaptureDeviceGraph::addDeviceFilter] createDevEnum->CreateClassEnumerator() Failed.");
return false;
}
enumMoniker->Reset();
while(ComResult(enumMoniker->Next(1,(IMoniker**)moniker,&nFetched)).success())
{
ComPointer<IPropertyBag> propertyBag;
Variant vName;
LOG("[CaptureDeviceGraph::addDeviceFilter] moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)(IPropertyBag**)propertyBag)");
comResult=moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)(IPropertyBag**)propertyBag);
if(!comResult.success())
{
error("[CaptureDeviceGraph::addDeviceFilter] Failed to BindToStorage on moniker");
continue;
}
LOG("[CaptureDeviceGraph::addDeviceFilter] propertyBag->Read(L\"FriendlyName\",&vName.getVARIANT(),0)");
comResult=propertyBag->Read(L"FriendlyName",&vName.getVARIANT(),0);
if(!comResult.success())
{
error("[CaptureDeviceGraph::addDeviceFilter] Failed to Read FriendlyName");
continue;
}
vName.getData(mDeviceName);
if(mDeviceName=="Microsoft DV Camera and VCR")
{
LOG("[CaptureDeviceGraph::addDeviceFilter] moniker->BindToObject(0,0,IID_IBaseFilter,(void**)(IBaseFilter**)mDeviceFilter)");
comResult=moniker->BindToObject(0,0,IID_IBaseFilter,(void**)(IBaseFilter**)mDeviceFilter);
if(!comResult.success())
{
error("[CaptureDeviceGraph::addDeviceFilter] Failed to Bind DeviceFilter");
return false;
}
LOG("[CaptureDeviceGraph::addDeviceFilter] mGraph->AddFilter(mDeviceFilter,L\"Filter\")");
comResult=mGraph->AddFilter(mDeviceFilter,L"Filter");
if(!comResult.success())
{
error("[CaptureDeviceGraph::addDeviceFilter] Failed to AddFilter");
return false;
}
break;
}
}
return mDeviceFilter.isOkay();
}
CaptureDeviceGraph::DVMode CaptureDeviceGraph::getDVMode(void)
{
ComResult comResult;
LONG deviceType;
LOG("[CaptureDeviceGraph::getDVMode] mExtDevice->GetCapability(ED_DEVCAP_DEVICE_TYPE,&deviceType,0)");
comResult=mExtDevice->GetCapability(ED_DEVCAP_DEVICE_TYPE,&deviceType,0);
if(!comResult.success())
{
error("[CaptureDeviceGraph::getDVMode] mExtDevice->GetCapability(ED_DEVCAP_DEVICE_TYPE,&deviceType,0) Failed.(Non-Fatal)");
return UnknownMode;
}
switch(deviceType)
{
case ED_DEVTYPE_VCR :
return VCRMode;
case ED_DEVTYPE_CAMERA :
return CameraMode;
case 0 :
default :
return UnknownMode;
}
}
bool CaptureDeviceGraph::getTapeInfo(void)
{
ComResult comResult;
LONG mediaType;
LONG inSignalMode;
LOG("[CaptureDeviceGraph::getTapeInfo] mExtTransport->GetStatus(ED_MEDIA_TYPE,&mediaType)");
comResult=mExtTransport->GetStatus(ED_MEDIA_TYPE,&mediaType);
if(!comResult.success())return false;
if(ED_MEDIA_NOT_PRESENT==mediaType)return false; // fail if no tape installed
else
{
if(ED_MEDIA_DVC!=mediaType)return false; // tape type should be DVC
LOG("[CaptureDeviceGraph::getTapeInfo] mExtTransport->GetTransportBasicParameters(ED_TRANSBASIC_INPUT_SIGNAL,&inSignalMode,0)");
comResult=mExtTransport->GetTransportBasicParameters(ED_TRANSBASIC_INPUT_SIGNAL,&inSignalMode,0);
if(!comResult.success())return false;
switch(inSignalMode)
{
case ED_TRANSBASIC_SIGNAL_525_60_SD :
mAverageTimePerFrame=33; // 33 ms(29.97 FPS)
mVideoFormat=DVENCODERVIDEOFORMAT_NTSC;
break;
case ED_TRANSBASIC_SIGNAL_525_60_SDL :
mAverageTimePerFrame=33; // 33 ms(29.97 FPS)
mVideoFormat=DVENCODERVIDEOFORMAT_NTSC;
break;
case ED_TRANSBASIC_SIGNAL_625_50_SD :
mAverageTimePerFrame=40; // 40 ms (25 FPS)
mVideoFormat=DVENCODERVIDEOFORMAT_PAL;
break;
case ED_TRANSBASIC_SIGNAL_625_50_SDL :
mAverageTimePerFrame=40; // 40 ms (25 FPS)
mVideoFormat=DVENCODERVIDEOFORMAT_PAL;
break;
default :
error("[CaptureDeviceGraph::getTapeInfo] unsupported or unrecognized tape format type");
mAverageTimePerFrame=33;
break;
}
}
return true;
}
// DV_Cam(AV Out)->DVSplitter(vid)->DVCodec->VideoWindow
// DVSplitter(aud)->Default DirectSound device
bool CaptureDeviceGraph::makePreviewGraph(void)
{
ComResult comResult;
mGraphType=GraphPreview;
LOG("[CaptureDeviceGraph::makePreviewGraph] mExtTransport->GetTransportBasicParameters(ED_TRANSBASIC_INPUT_SIGNAL,&inSignalMode,0)");
comResult=mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,mDeviceFilter,0,0);
if(!comResult.success())return false;
return true;
}
// DV_Cam(AV Out)->SmartTee(capture)->AviMux->FileWriter
// SmartTee(preview)->DVSplitter(vid)->DVCodec->VideoWindow
// DVSplitter(aud)->Default DirectSound device
bool CaptureDeviceGraph::makeDVToFileGraphType1(const BString &pathOutputFileName)
{
ComPointer<IBaseFilter> ppf;
ComPointer<IFileSinkFilter> pSink;
USES_CONVERSION;
if(!pathOutputFileName.isOkay())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType1] pathOutputFileName is null.");
return false;
}
mGraphType=GraphDVToFile;
LOG("[CaptureDeviceGraph::makeDVToFileGraphType1] mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)pSink)");
if(!ComResult(mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)pSink)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType1] SetOutputFileName failed.");
return false;
}
if(!setAviOptions(ppf,INTERLEAVE_NONE))return false;
// Connect interleaved stream of MSDV to the AVI Mux/FW
LOG("[CaptureDeviceGraph::makeDVToFileGraphType1] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,0,ppf)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,0,ppf)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType1] mCaptureGraphBuilder->RenderStream() failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphType1] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,mDeviceFilter,0,0)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,mDeviceFilter,0,0)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType1] mCaptureGraphBuilder->RenderStream() failed.");
return true; // smk test
}
return true;
}
bool CaptureDeviceGraph::makeDVToFileGraphNoPreType1(const BString &pathOutputFileName)
{
ComPointer<IBaseFilter> ppf;
ComPointer<IFileSinkFilter> sink;
mGraphType=GraphDVToFileNoPre;
USES_CONVERSION;
// if(!ComResult(mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),ppf,sink)).success())
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType1] mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink)");
if(!ComResult(mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType1] mCaptureGraphBuilder->SetOutputFileName() failed.");
return false;
}
if(!setAviOptions(ppf,INTERLEAVE_NONE))return false;
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType1] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,0,ppf)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,0,ppf)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType1] mCaptureGraphBuilder->RenderStream() failed.");
return false;
}
return true;
}
// FileSource->AVI_Splitter->InfPinTee->DV_Camera
// InfPinTee->DVSplitter(vid)->DVDecoder->VideoWIndow
// DVSplitter(aud)->Default DirectSound device
// the graph we're making is: Async Reader --> AVI SPlitter --> Tee --> MSDV
// --> DV Splitter --> DV Decoder --> VidRend
// --> AudRend
bool CaptureDeviceGraph::makeFileToDVGraphType1(const BString &pathInputFileName)
{
mGraphType=GraphFileToDV;
ComPointer<IBaseFilter> aviSplitter;
ComPointer<IBaseFilter> inFTee;
USES_CONVERSION;
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)");
if(!ComResult(mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mGraph->AddSourceFilter() Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] aviSplitter.createInstance(CLSID_AviSplitter,IID_IBaseFilter)");
if(!ComResult(aviSplitter.createInstance(CLSID_AviSplitter,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] aviSplitter->createInstance(CLSID_AviSplitter,IID_IBaseFilter) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] inFTee.createInstance(CLSID_InfTee,IID_IBaseFilter)");
if(!ComResult(inFTee.createInstance(CLSID_InfTee,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] inFTee->createInstance(CLSID_InfTee,IID_BaseFilter) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mGraph->AddFilter(aviSplitter,L\"AVI Splitter\")");
if(!ComResult(mGraph->AddFilter(aviSplitter,L"AVI Splitter")).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mGraph->AddFilter(aviSplitter) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,aviSplitter)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,aviSplitter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(..,aviSplitter) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mGraph->AddFilter(inFTee,L\"Infinite Tee\")");
if(!ComResult(mGraph->AddFilter(inFTee,L"Infinite Tee")).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mGraph->AddFilter(inFTee) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(0,&MEDIATYPE_Interleaved,aviSplitter,0,inFTee)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,&MEDIATYPE_Interleaved,aviSplitter,0,inFTee)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(..,inFTee) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,mDeviceFilter)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,mDeviceFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(..,mDeviceFilter) Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,0)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,0)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType1] mCaptureGraphBuilder->RenderStream(..,inFTee,0,0) Failed.");
return false;
}
return true;
}
//FileSource->AVI_Splitter->DV_Camera
// Graph : Async Reader --> AVI Splitter --> MSDV
bool CaptureDeviceGraph::makeFileToDVGraphNoPreType1(const BString &pathInputFileName)
{
mGraphType=GraphFileToDVNoPre;
USES_CONVERSION;
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType1] mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)");
if(!ComResult(mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType1] mGraph->AddSourceFilter() Failed.");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType1] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,mDeviceFilter)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,mDeviceFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType1] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,mDeviceFilter) Failed.");
return false;
}
return true;
}
// the graph we're making is: MSDV --> Smart Tee --> DV SPLITTER --> AVI MUX --> File Writer
// -->
//
// --> DV SPLITTER --> DV DEC --> Video Renderer
// --> Audio Renderer
bool CaptureDeviceGraph::makeDVToFileGraphType2(const BString &pathOutputFileName)
{
mGraphType=GraphDVToFileType2;
ComPointer<IBaseFilter> dvSplitter;
ComPointer<IBaseFilter> ppf;
ComPointer<IFileSinkFilter> sink;
USES_CONVERSION;
LOG("[CaptureDeviceGraph::makeDVToFileGraphType2] dvSplitter.createInstance(CLSID_DVSplitter,IID_IBaseFilter)");
if(!ComResult(dvSplitter.createInstance(CLSID_DVSplitter,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType2] createInstance(CLSID_DVSplitter,IID_IBaseFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphType2] mGraph->AddFilter(dvSplitter,L\"DV Splitter\")");
if(!ComResult(mGraph->AddFilter(dvSplitter,L"DV Splitter")).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType2] mGraph->AddFilter(dvSplitter,L\"DV Splitter\") Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink)");
if(!ComResult(mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink) Failed");
return false;
}
if(!setAviOptions(ppf,INTERLEAVE_NONE))return false;
LOG("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,dvSplitter,ppf)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,dvSplitter,ppf)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,dvSplitter,ppf) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->RenderStream(0,0,dvSplitter,0,ppf)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,dvSplitter,0,ppf)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->RenderStream(0,0,dvSplitter,0,ppf) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,mDeviceFilter,0,0)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,mDeviceFilter,0,0)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphType2] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,mDeviceFilter,0,0) Failed");
return false;
}
return true;
}
// the graph we're making is: MSDV --> Smart Tee --> DV SPLITTER --> AVI MUX --> File Writer
// -->
bool CaptureDeviceGraph::makeDVToFileGraphNoPreType2(const BString &pathOutputFileName)
{
mGraphType=GraphDVToFileNoPreType2;
ComPointer<IBaseFilter> dvSplitter;
ComPointer<IBaseFilter> ppf;
ComPointer<IFileSinkFilter> sink;
USES_CONVERSION;
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] dvSplitter.createInstance(CLSID_DVSplitter,IID_IBaseFilter)");
if(!ComResult(dvSplitter.createInstance(CLSID_DVSplitter,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] dvSplitter.createInstance(CLSID_DVSplitter,IID_IBaseFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mGraph->AddFilter(dvSplitter,L\"DV Splitter\")");
if(!ComResult(mGraph->AddFilter(dvSplitter,L"DV Splitter")).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mGraph->AddFilter(dvSplitter,L\"DV Splitter\") Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink)");
if(!ComResult(mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mCaptureGraphBuilder->SetOutputFileName(&MEDIASUBSTYPE_Avi,pathOutputFileName.str(),(IBaseFilter**)ppf,(IFileSinkFilter**)sink) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,dvSplitter,ppf)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,dvSplitter,ppf)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,mDeviceFilter,dvSplitter,ppf) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,dvSplitter,0,ppf)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,dvSplitter,0,ppf)).success())
{
error("[CaptureDeviceGraph::makeDVToFileGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,dvSplitter,0,ppf) Failed");
return false;
}
if(!setAviOptions(ppf,INTERLEAVE_NONE))return false;
return true;
}
// the graph we need to build is: ASYNC reader --> AVI SPLITTER --> DV MUX --> TEE --> MSDV
// --> --> DVSP --> DV DEC --> VR
// --> AR
bool CaptureDeviceGraph::makeFileToDVGraphType2(const BString &pathInputFileName)
{
ComPointer<IBaseFilter> dvMux;
ComPointer<IBaseFilter> inFTee;
ComPointer<IPin> out;
mGraphType=GraphFileToDVType2;
USES_CONVERSION;
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] dvMux.createInstance(CLSID_DVMux,IID_IBaseFilter)");
if(!ComResult(dvMux.createInstance(CLSID_DVMux,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] dvMux.createInstance(CLSID_DVMux,IID_IBaseFiler) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] inFTee.createInstance(CLSID_InfTee,IID_IBaseFilter)");
if(!ComResult(inFTee.createInstance(CLSID_InfTee,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] inFTee.createInstance(CLSID_InfTee,IID_IBaseFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)");
if(!ComResult(mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->AddFilter(dvMux,L\"DV Muxer\")");
if(!ComResult(mGraph->AddFilter(dvMux,L"DV Muxer")).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->AddFilter(dvMux,L\"DV Muxer\") Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->AddFilter(inFTee,L\"Infinite Tee\")");
if(!ComResult(mGraph->AddFilter(inFTee,L"Infinite Tee")).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->AddFilter(inFTee,L\"Infinite Tee\") Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->RenderStream(0,0,dvMux,0,inFTee)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,dvMux,0,inFTee)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->RenderStream(0,0,dvMux,0,inFTee) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,mDeviceFilter)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,mDeviceFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->RenderStream(0,0,inFTee,0,mDeviceFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->FindPin(inFTee,PINDIR_OUTPUT,0,0,true,0,(IPin**)out)");
if(!ComResult(mCaptureGraphBuilder->FindPin(inFTee,PINDIR_OUTPUT,0,0,true,0,(IPin**)out)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mCaptureGraphBuilder->FindPin(inFTee,PINDIR_OUTPUT,0,0,true,0,(IPin**)out) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->Render(out)");
if(!ComResult(mGraph->Render(out)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphType2] mGraph->Render(out) Failed");
return false;
}
return true;
}
// the graph we need to build is: ASYNC reader --> AVI SPLITTER --> DV MUX --> MSDV
// -->
// connect file video stream to DV MUX
bool CaptureDeviceGraph::makeFileToDVGraphNoPreType2(const BString &pathInputFileName)
{
ComPointer<IBaseFilter> dvMux;
mGraphType=GraphFileToDVNoPreType2;
USES_CONVERSION;
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] dvMux.createInstance(CLSID_DVMux,IID_IBaseFilter)");
if(!ComResult(dvMux.createInstance(CLSID_DVMux,IID_IBaseFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] dvMux.createInstance(CLSID_DVMux,IID_IBaseFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)");
if(!ComResult(mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mGraph->AddSourceFilter(pathInputFileName.str(),pathInputFileName.str(),(IBaseFilter**)mInputFileFilter) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mGraph->AddFilter(dvMux,L\"DV Muxer\")");
if(!ComResult(mGraph->AddFilter(dvMux,L"DV Muxer")).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mGraph->AddFilter(dvMux,L\"DV Muxer\") Failed");
return false;
}
// connect video
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux) Failed");
return false;
}
// connect audio - looks suspicious because this line same as previous
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,mInputFileFilter,0,dvMux) Failed");
return false;
}
LOG("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,dvMux,0,mDeviceFilter)");
if(!ComResult(mCaptureGraphBuilder->RenderStream(0,0,dvMux,0,mDeviceFilter)).success())
{
error("[CaptureDeviceGraph::makeFileToDVGraphNoPreType2] mCaptureGraphBuilder->RenderStream(0,0,dvMux,0,mDeviceFilter) Failed");
return false;
}
return true;
}
bool CaptureDeviceGraph::setAviOptions(ComPointer<IBaseFilter> &ppf,InterleavingMode interleavingMode)
{
ComPointer<IConfigAviMux> mux;
ComPointer<IConfigInterleaving> interleaving;
LOG("[CaptureDeviceGraph::setAviOptions] ppf->QueryInterface(IID_IConfigAviMux,(void**)(IConfigAviMux**)mux)");
if(!ComResult(ppf->QueryInterface(IID_IConfigAviMux,(void**)(IConfigAviMux**)mux)).success())
{
error("[CaptureDeviceGraph::setAviOptions] Failed to QueryInterface on IID_IConfigAviMux");
return false;
}
LOG("[CaptureDeviceGraph::setAviOptions] mux->SetOutputCompatibilityIndex(true)");
if(!ComResult(mux->SetOutputCompatibilityIndex(true)).success())
{
error("[CaptureDeviceGraph::setAviOptions] mux->SetOutputCompatibilityIndex failed");
return false;
}
LOG("[CaptureDeviceGraph::setAviOptions] ppf->QueryInterface(IID_IConfigInterleaving,(void**)(IConfigInterleaving**)interleaving)");
if(!ComResult(ppf->QueryInterface(IID_IConfigInterleaving,(void**)(IConfigInterleaving**)interleaving)).success())
{
error("[CaptureDeviceGraph::setAviOptions] QueryInterface IConfigInterleaving failed");
return false;
}
LOG("[CaptureDeviceGraph::setAviOptions] interleaving->put_Mode(interleavingMode)");
if(!ComResult(interleaving->put_Mode(interleavingMode)).success()) // full,none,half
{
error("[CaptureDeviceGraph::setAviOptions] interleaving->put_Mode failed");
return false;
}
return true;
}
bool CaptureDeviceGraph::getVideoWindowDimensions(int &width,int &height,bool changeResolution,GUIWindow &window)
{
if(window.isValid())
{
if(!getResolutionFromDVDecoderPropertyPage(window,changeResolution))return false;
}
switch(mDVResolution)
{
case DVRESOLUTION_FULL:
width=DVEncoderWidth;
if(DVENCODERVIDEOFORMAT_PAL==mVideoFormat)height=PALDVEncoderHeight;
else if(DVENCODERVIDEOFORMAT_NTSC==mVideoFormat)height=NTSCDVEncoderHeight;
break;
case DVRESOLUTION_HALF:
width=DVEncoderWidth/2;
if(DVENCODERVIDEOFORMAT_PAL==mVideoFormat)height=PALDVEncoderHeight/2;
else if(DVENCODERVIDEOFORMAT_NTSC==mVideoFormat)height=NTSCDVEncoderHeight/2;
break;
case DVRESOLUTION_QUARTER:
width=DVEncoderWidth/4;
if(DVENCODERVIDEOFORMAT_PAL==mVideoFormat)height=PALDVEncoderHeight/4;
else if(DVENCODERVIDEOFORMAT_NTSC==mVideoFormat)height=NTSCDVEncoderHeight/4;
break;
case DVRESOLUTION_DC:
width = 88;
if(DVENCODERVIDEOFORMAT_PAL==mVideoFormat)height=PALDVEncoderHeight/8;
else if(DVENCODERVIDEOFORMAT_NTSC==mVideoFormat)height=NTSCDVEncoderHeight/8;
break;
}
return true;
}
bool CaptureDeviceGraph::getResolutionFromDVDecoderPropertyPage(GUIWindow &window,bool changeResolution)
{
ComPointer<IBaseFilter> dvDecoder;
ComPointer<IIPDVDec> ipDVDec;
ComPointer<ISpecifyPropertyPages> propertyPages;
FILTER_INFO filterInfo;
LOG("[CaptureDeviceGraph::getResolutionFromDVDecoderPropertyPage] mGraph->FindFilterByName(L\"DV Video Decoder\",(IBaseFilter**)dvDecoder)");
if(!ComResult(mGraph->FindFilterByName(L"DV Video Decoder",(IBaseFilter**)dvDecoder)).success())
{
error("[CaptureDeviceGraph::getResolutionFromDVPropertyPage] mGraph->FindFilterByName() Failed.");
return false;
}
LOG("[CaptureDeviceGraph::getResolutionFromDVDecoderPropertyPage] dvDecoder->QueryInterface(IID_ISpecifyPropertyPages,(void**)(ISpecifyPropertyPages**)propertyPages)");
if(!ComResult(dvDecoder->QueryInterface(IID_ISpecifyPropertyPages,(void**)(ISpecifyPropertyPages**)propertyPages)).success())
{
error("[CaptureDeviceGraph::getResolutionFromDVPropertyPage] QueryInterface ISpecifyPropertyPages Failed.");
return false;
}
LOG("[CaptureDeviceGraph::getResolutionFromDVDecoderPropertyPage] dvDecoder->QueryFilterInfo(&filterInfo)");
if(!ComResult(dvDecoder->QueryFilterInfo(&filterInfo)).success())
{
error("[CaptureDeviceGraph::getResolutionFromDVPropertyPage] dvDecoder->QueryFilterInfo() Failed.");
return false;
}
if(changeResolution)
{
CAUUID caGUID;
propertyPages->GetPages(&caGUID);
::OleCreatePropertyFrame(window, // parent window
0,0, // reserved
filterInfo.achName, // caption for dialog box
1, // number of objects
(IUnknown**)(IBaseFilter**)dvDecoder, // array of object pointers
caGUID.cElems, // number of property pages
caGUID.pElems, // array of property page CLSID's
0, // locale identifier
0,0); // reserved
::CoTaskMemFree(caGUID.pElems);
}
filterInfo.pGraph->Release();
LOG("[CaptureDeviceGraph::getResolutionFromDVDecoderPropertyPage] dvDecoder->QueryInterface(IID_IIPDVDec,(void**)(IIPDVDec**)ipDVDec)");
if(!ComResult(dvDecoder->QueryInterface(IID_IIPDVDec,(void**)(IIPDVDec**)ipDVDec)).success())
{
error("[CaptureDeviceGraph::getResolutionFromDVPropertyPage] QueryInterface IIPDVDec Failed");
return false;
}
LOG("[CaptureDeviceGraph::getResolutionFromDVDecoderPropertyPage] ipDVDec->get_IPDisplay((int*)&mDVResolution)");
if(!ComResult(ipDVDec->get_IPDisplay((int*)&mDVResolution)).success())
{
error("[CaptureDeviceGraph::getResolutionFromDVPropertyPage] ipDVDec->get_IPDisplay() Failed.");
return false;
}
return true;
}
bool CaptureDeviceGraph::startGraph(void)
{
LOG("[CaptureDeviceGraph::startGraph] mMediaControl->Run()");
if(!ComResult(mMediaControl->Run()).success())
{
stopGraph();
error("[CaptureDeviceGraph::startGraph] mMediaControl->Run() Failed.");
return false;
}
return true;
}
bool CaptureDeviceGraph::stopGraph(void)
{
LOG("[CaptureDeviceGraph::stopGraph] mMediaControl->Stop()");
if(!ComResult(mMediaControl->Stop()).success())
{
error("[CaptureDeviceGraph::stopGraph] mMediaControl->Stop() Failed.");
return false;
}
return true;
}
bool CaptureDeviceGraph::pauseGraph(void)
{
LOG("[CaptureDeviceGraph::pauseGraph] mMediaControl->Pause()");
if(!ComResult(mMediaControl->Pause()).success())
{
stopGraph();
error("[CaptureDeviceGraph::pauseGraph] mMediaControl->Stop() Failed.");
return false;
}
return true;
}
bool CaptureDeviceGraph::getTimecode(TIMECODE_SAMPLE &tcSample)
{
LOG("[CaptureDeviceGraph::getTimecode] mTimecodeReader->GetTimecode(&tcSample)");
if(!ComResult(mTimecodeReader->GetTimecode(&tcSample)).success())return false;
return true;
}
bool CaptureDeviceGraph::setNotifyWindow(GUIWindow &window,int command)
{
LOG("[CaptureDeviceGraph::setNotifyWindow] mMediaEvent->SetNotifyWindow((LONG_PTR)window.getHandle(),command,0)");
if(!ComResult(mMediaEvent->SetNotifyWindow((LONG_PTR)window.getHandle(),command,0)).success())return false;
return true;
}
bool CaptureDeviceGraph::putOwner(GUIWindow &window)
{
LOG("[CaptureDeviceGraph::putOwner] mVideoWindow->put_Owner((OAHWND)window.getHandle())");
if(!ComResult(mVideoWindow->put_Owner((OAHWND)window.getHandle())).success())return false;
return true;
}
bool CaptureDeviceGraph::putWindowStyle(int style)
{
LOG("[CaptureDeviceGraph::putWindowStyle] mVideoWindow->put_WindowStyle(style)");
if(!ComResult(mVideoWindow->put_WindowStyle(style)).success())return false;
return true;
}
bool CaptureDeviceGraph::setVideoWindowPosition(int left,int top,int width,int height)
{
LOG("[CaptureDeviceGraph::setVideoWindowPosition] mVideoWindow->SetWindowPosition(left,top,width,height)");
if(!ComResult(mVideoWindow->SetWindowPosition(left,top,width,height)).success())return false;
return true;
}
bool CaptureDeviceGraph::setVideoWindowVisible(bool visible)
{
LOG("[CaptureDeviceGraph::setVideoWindowVisible] mVideoWindow->put_Visible(visible?OATRUE:OAFALSE)");
if(!ComResult(mVideoWindow->put_Visible(visible?OATRUE:OAFALSE)).success())return false;
return true;
}
bool CaptureDeviceGraph::putIAMExtTransportMode(int mode)
{
if(!mExtTransport.isOkay())return false;
LOG("[CaptureDeviceGraph::putIAMExtTransportMode] mExtTransport->put_Mode(mode)");
return mExtTransport->put_Mode(mode);
}
bool CaptureDeviceGraph::seekAtn(int hour,int minute,int second,int frame)
{
BYTE rawAVCPkt[8]={0x00,0x20,0x52,0x20,0xff,0xff,0xff,0xff}; // raw AVC for seek atn
ULONG searchTrackNumber;
ComResult comResult;
long iCnt=sizeof(rawAVCPkt);
bool returnCode=false;
if(DVENCODERVIDEOFORMAT_PAL==mVideoFormat && (frame>25))
{
error("[CaptureDeviceGraph::seekAtn] Frame should be less than 25 for PAL");
return false;
}
if(DVENCODERVIDEOFORMAT_NTSC==mVideoFormat && (frame>30))
{
error("[CaptureDeviceGraph::seekAtn] Frame should be less than 30 for NTSC");
return false;
}
if((hour<26)&&(hour>=0)&&(minute<60)&&(minute>=0)&&(second<60))
{
if(40==mAverageTimePerFrame)
{
searchTrackNumber=((minute*60+second)*25+frame)*12*2;
}
else // drop two frame every minutes
{
searchTrackNumber=((minute*60+second)*30+frame-((minute-(minute/10))*2))*10*2;
}
rawAVCPkt[4]=(BYTE)(searchTrackNumber&0x000000ff);
rawAVCPkt[5]=(BYTE)((searchTrackNumber&0x0000ff00) >> 8);
rawAVCPkt[6]=(BYTE)((searchTrackNumber&0x00ff0000) >> 16);
LOG("[CaptureDeviceGraph::seekAtn] mExtTransport->GetTransportBasicParameters(ED_RAW_EXT_DEV_CMD,&iCnt,(LPOLESTR *)rawAVCPkt)");
comResult=mExtTransport->GetTransportBasicParameters(ED_RAW_EXT_DEV_CMD,&iCnt,(LPOLESTR *)rawAVCPkt);
if(!comResult.success())
{
if(ERROR_TIMEOUT==comResult.result())::OutputDebugString("ATN Seek returns ERROR_TIMEOUT\n");
else if(ERROR_REQ_NOT_ACCEP==comResult.result())::OutputDebugString(" ATN Seek returns ERROR_REQ_NOT_ACCEP\n");
else if(ERROR_NOT_SUPPORTED==comResult.result())::OutputDebugString(" ATN Seek returns ERROR_NOT_SUPPORTED\n");
else if(ERROR_REQUEST_ABORTED==comResult.result())::OutputDebugString(" ATN Seek returns ERROR_REQUEST_ABORTED\n");
}
returnCode=true;
}
else
{
error("Invalid Parameter - Time entered should be:\nHour:Minute:Second:Frame");
}
return returnCode;
}
bool CaptureDeviceGraph::nukeInputFileFilter()
{
Nuker nuker(mGraph);
if(!nuker.nukeFilter(mInputFileFilter,true,false))
{
LOG("[CaptureDeviceGraph::nukeInputFileFilter] Failed.");
return false;
}
mGraph->RemoveFilter(mInputFileFilter);
mInputFileFilter.Release();
return true;
}
bool CaptureDeviceGraph::nukeDeviceFilter()
{
Nuker nuker(mGraph);
if(!nuker.nukeFilter(mDeviceFilter,true,true))
{
LOG("[CaptureDeviceGraph::nukeDeviceFilter] Failed.");
return false;
}
return true;
}

View File

@@ -0,0 +1,140 @@
#ifndef _DVCAP_CAPTUREDEVICEGRAPH_HPP_
#define _DVCAP_CAPTUREDEVICEGRAPH_HPP_
#ifndef _COMMON_DXSDK_HPP_
#include <common/dxsdk.hpp>
#endif
#ifndef _COMMON_GUIWINDOW_HPP_
#include <common/GUIWnd.hpp>
#endif
#ifndef _COMMON_FILE_HPP_
#include <common/file.hpp>
#endif
#ifndef _COMMON_SYSTEMTIME_HPP_
#include <common/systime.hpp>
#endif
#ifndef _COM_COM_HPP_
#include <com/com.hpp>
#endif
#ifndef _COM_BSTRING_HPP_
#include <com/bstring.hpp>
#endif
#ifndef _COM_COMPOINTER_HPP_
#include <com/comptr.hpp>
#endif
#ifndef _DVCAP_NUKER_HPP_
#include <dvcap/Nuker.hpp>
#endif
#ifdef _DVCAP_DEBUG
#define LOG(s) log(s)
#else
#define LOG(s)
#endif
class CaptureDeviceGraph
{
public:
typedef enum DVMode{CameraMode=0,VCRMode,UnknownMode};
typedef enum GraphType{GraphPreview,GraphDVToFile,GraphDVToFileNoPre,GraphFileToDV,GraphFileToDVNoPre,
GraphDVToFileType2,GraphDVToFileNoPreType2,GraphFileToDVType2,GraphFileToDVNoPreType2};
CaptureDeviceGraph();
virtual ~CaptureDeviceGraph();
bool buildBasicGraph(void);
bool getTapeInfo(void);
_DVENCODERVIDEOFORMAT getVideoFormat(void)const;
const BString &getDeviceName(void)const;
bool getTimecode(TIMECODE_SAMPLE &tcSample); // should wrap TIMECODE_SAMPLE & provide formatting capabilities
bool seekAtn(int hour,int minute,int second,int frame);
bool stopGraph(void);
bool pauseGraph(void);
bool startGraph(void);
bool makePreviewGraph(void);
// type 1 file (capture/playback/transmit)
bool makeDVToFileGraphType1(const BString &pathOutputFileName);
bool makeDVToFileGraphNoPreType1(const BString &pathOutputFileName);
bool makeFileToDVGraphType1(const BString &pathInputFileName);
bool makeFileToDVGraphNoPreType1(const BString &pathInputFileName);
bool makeDVToFileGraphType2(const BString &pathOutputFileName);
bool makeDVToFileGraphNoPreType2(const BString &pathOutputFileName);
bool makeFileToDVGraphType2(const BString &pathInputFileName);
bool makeFileToDVGraphNoPreType2(const BString &pathInputFileName);
bool getDroppedFrameNum(bool &isModeTransmit,long &dropped,long &notDropped);
bool changeFrameRate(bool halfFrameRate);
bool getVideoWindowDimensions(int &width,int &height,bool changeResolution=false,GUIWindow &window=GUIWindow());
bool setNotifyWindow(GUIWindow &window,int command);
bool putOwner(GUIWindow &window);
bool putWindowStyle(int style);
bool setVideoWindowPosition(int left,int top,int width,int height);
bool setVideoWindowVisible(bool visible);
bool putIAMExtTransportMode(int mode);
bool seekATN(int iHr,int iMn,int iSc,int iFr);
DVMode getDVMode(void);
bool saveGraphToFile(const BString &pathOutputFileName);
bool nukeInputFileFilter();
bool nukeDeviceFilter();
private:
enum{DVEncoderWidth=720,PALDVEncoderHeight=576,NTSCDVEncoderHeight=480};
void freeFilters(void);
bool initializeGraph(void);
bool addDeviceFilter(void);
bool getResolutionFromDVDecoderPropertyPage(GUIWindow &window,bool changeResolution);
bool setAviOptions(ComPointer<IBaseFilter> &ppf,InterleavingMode interleaveMode);
void log(const String &string);
void error(const String &string);
ComPointer<IGraphBuilder> mGraph;
ComPointer<ICaptureGraphBuilder2> mCaptureGraphBuilder;
ComPointer<IMediaControl> mMediaControl;
ComPointer<IMediaEventEx> mMediaEvent;
ComPointer<IBaseFilter> mDeviceFilter;
ComPointer<IBaseFilter> mInputFileFilter;
ComPointer<IVideoWindow> mVideoWindow;
ComPointer<IAMDroppedFrames> mDroppedFrames;
ComPointer<IAMExtDevice> mExtDevice;
ComPointer<IAMExtTransport> mExtTransport;
ComPointer<IAMTimecodeReader> mTimecodeReader;
BString mDeviceName;
DVMode mSubunitMode;
GraphType mGraphType;
_DVENCODERVIDEOFORMAT mVideoFormat;
LONG mAverageTimePerFrame;
_DVRESOLUTION mDVResolution;
BString mLastErrorText;
File mLogFile;
};
inline
_DVENCODERVIDEOFORMAT CaptureDeviceGraph::getVideoFormat(void)const
{
return mVideoFormat;
}
inline
const BString &CaptureDeviceGraph::getDeviceName(void)const
{
return mDeviceName;
}
inline
void CaptureDeviceGraph::error(const String &string)
{
SystemTime systemTime;
mLogFile.writeLine(String("[ERROR]")+String("[")+systemTime.toString()+String("]")+string);
mLastErrorText=string;
}
inline
void CaptureDeviceGraph::log(const String &string)
{
SystemTime systemTime;
mLogFile.writeLine(String("[LOG]")+String("[")+systemTime.toString()+String("]")+string);
}
#endif

BIN
dvcap/Debug/RCa00736 Normal file

Binary file not shown.

BIN
dvcap/Debug/dvcap.exe Normal file

Binary file not shown.

BIN
dvcap/Debug/dvcap.exp Normal file

Binary file not shown.

BIN
dvcap/Debug/dvcap.lib Normal file

Binary file not shown.

5
dvcap/Debug/dvcap.log Normal file
View File

@@ -0,0 +1,5 @@
*********************************************************************
DVCAPTURE LOG FILE STARTED AT:Monday, March 2,2009 19:59:51
*********************************************************************
[ERROR][Monday, March 2,2009 19:59:52][CaptureDeviceGraph::addDeviceFilter] createDevEnum->CreateClassEnumerator() Failed.
[ERROR][Monday, March 2,2009 19:59:52][CaptureDeviceGraph::buildBasicGraph] Failed to add device filter.

BIN
dvcap/Debug/dvcap.res Normal file

Binary file not shown.

BIN
dvcap/Debug/vc60.idb Normal file

Binary file not shown.

View File

@@ -0,0 +1,66 @@
#ifndef _PROTO_DEVICEDESCRIPTOR_HPP_
#define _PROTO_DEVICEDESCRIPTOR_HPP_
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
class DeviceDescriptor
{
public:
DeviceDescriptor();
DeviceDescriptor(const String &name,const String &description);
virtual ~DeviceDescriptor();
const String &getName(void)const;
void setName(const String &name);
const String &getDescription(void)const;
void setDescription(const String &description);
private:
String mName;
String mDescription;
};
inline
DeviceDescriptor::DeviceDescriptor()
{
}
inline
DeviceDescriptor::DeviceDescriptor(const String &name,const String &description)
: mName(name), mDescription(description)
{
}
inline
DeviceDescriptor::~DeviceDescriptor()
{
}
inline
const String &DeviceDescriptor::getName(void)const
{
return mName;
}
inline
void DeviceDescriptor::setName(const String &name)
{
mName=name;
}
inline
const String &DeviceDescriptor::getDescription(void)const
{
return mDescription;
}
inline
void DeviceDescriptor::setDescription(const String &description)
{
mDescription=description;
}
typedef Block<DeviceDescriptor> DeviceDescriptors;
#endif

102
dvcap/DeviceEnumerator.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include <com/com.hpp>
#include <com/variant.hpp>
#include <com/comptr.hpp>
#include <dvcap/DeviceEnumerator.hpp>
bool DeviceEnumerator::enumerateCategory(DeviceDescriptors &descriptors,DevCat devCat)
{
switch(devCat)
{
case AudioCaptureSources :
return enumerateCategory(descriptors,CLSID_AudioInputDeviceCategory);
case AudioCompressors :
return enumerateCategory(descriptors,CLSID_AudioCompressorCategory);
case AudioRenderers :
return enumerateCategory(descriptors,CLSID_AudioRendererCategory);
case DeviceControlFilters :
return enumerateCategory(descriptors,CLSID_DeviceControlCategory);
case DirectShowFilters :
return enumerateCategory(descriptors,CLSID_LegacyAmFilterCategory);
case ExternalRenderers :
return enumerateCategory(descriptors,CLSID_TransmitCategory);
case MidiRenderers :
return enumerateCategory(descriptors,CLSID_MidiRendererCategory);
case VideoCaptureSources :
return enumerateCategory(descriptors,CLSID_VideoInputDeviceCategory);
case VideoCompressors :
return enumerateCategory(descriptors,CLSID_VideoCompressorCategory);
case VideoEffects1 :
return enumerateCategory(descriptors,CLSID_VideoEffects1Category);
case VideoEffects2 :
return enumerateCategory(descriptors,CLSID_VideoEffects2Category);
case WDMStreamingDecompressionDevices :
return enumerateCategory(descriptors,KSCATEGORY_DATADECOMPRESSOR);
case WDMStreamingCaptureDevices :
return enumerateCategory(descriptors,AM_KSCATEGORY_CAPTURE);
case WDMStreamingCommunicationTransforms :
return enumerateCategory(descriptors,KSCATEGORY_COMMUNICATIONSTRANSFORM);
case WDMStreamingCrossbarDevices :
return enumerateCategory(descriptors,AM_KSCATEGORY_CROSSBAR);
case WDMStreamingDataTransforms :
return enumerateCategory(descriptors,KSCATEGORY_DATATRANSFORM);
case WDMStreamingInterfaceTransforms :
return enumerateCategory(descriptors,KSCATEGORY_INTERFACETRANSFORM);
case WDMStreamingMixerDevices :
return enumerateCategory(descriptors,KSCATEGORY_MIXER);
case WDMRenderingDevices :
return enumerateCategory(descriptors,AM_KSCATEGORY_RENDER);
case WDMStreamingSystemAudioDevices :
return enumerateCategory(descriptors,KSCATEGORY_AUDIO_DEVICE);
case WDMStreamingTeeSplitterDevices :
return enumerateCategory(descriptors,AM_KSCATEGORY_SPLITTER);
case WDMStreamingTVAudioDevices :
return enumerateCategory(descriptors,AM_KSCATEGORY_TVAUDIO);
case WDMStreamingTVTunerDevices :
return enumerateCategory(descriptors,AM_KSCATEGORY_TVTUNER);
case WDMStreamingVBICodes :
return enumerateCategory(descriptors,AM_KSCATEGORY_VBICODEC);
case ActiveMovieFilterCategories :
return enumerateCategory(descriptors,CLSID_ActiveMovieCategories);
}
return false;
}
bool DeviceEnumerator::enumerateCategory(DeviceDescriptors &descriptors,GUID classID)
{
ComInitializer comInit;
ComPointer<ICreateDevEnum> sysDevEnum;
ComPointer<IEnumMoniker> enumMoniker;
ComPointer<IMoniker> moniker;
ComObj comObj;
ComResult comResult;
BString bstring;
DeviceDescriptor descriptor;
ULONG cFetched;
descriptors.remove();
comResult=sysDevEnum.createInstance(CLSID_SystemDeviceEnum,IID_ICreateDevEnum);
if(comResult.error())return false;
comResult=sysDevEnum->CreateClassEnumerator(classID,(IEnumMoniker**)enumMoniker,0);
if(comResult.error())return false;
while(S_OK==enumMoniker->Next(1,(IMoniker**)moniker,&cFetched))
{
ComPointer<IPropertyBag> propertyBag;
moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)(IPropertyBag**)propertyBag);
Variant varName;
comResult=propertyBag->Read(L"FriendlyName", &varName.getVARIANT(), 0);
if(comResult.success())
{
varName.getData(bstring);
descriptor.setName(bstring.toString());
}
comResult=propertyBag->Read(L"Description",&varName.getVARIANT(), 0);
if(comResult.success())
{
varName.getData(bstring);
descriptor.setDescription(bstring.toString());
}
if(descriptor.getName().isNull()&&descriptor.getDescription().isNull())continue;
descriptors.insert(&descriptor);
}
return true;
}

View File

@@ -0,0 +1,31 @@
#ifndef _PROTO_DEVICEENUMERATOR_HPP_
#define _PROTO_DEVICEENUMERATOR_HPP_
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_DXSDK_HPP_
#include <common/dxsdk.hpp>
#endif
#ifndef _PROTO_DEVICEDESCRIPTOR_HPP_
#include <proto/DeviceDescriptor.hpp>
#endif
class DeviceEnumerator
{
public:
typedef enum DevCat{AudioCaptureSources,AudioCompressors,AudioRenderers,DeviceControlFilters,
DirectShowFilters,ExternalRenderers,MidiRenderers,VideoCaptureSources,VideoCompressors,
VideoEffects1,VideoEffects2,WDMStreamingDecompressionDevices,WDMStreamingCaptureDevices,
WDMStreamingCommunicationTransforms,WDMStreamingCrossbarDevices,WDMStreamingDataTransforms,
WDMStreamingInterfaceTransforms,WDMStreamingMixerDevices,WDMRenderingDevices,
WDMStreamingSystemAudioDevices,WDMStreamingTeeSplitterDevices,WDMStreamingTVAudioDevices,
WDMStreamingTVTunerDevices,WDMStreamingVBICodes,ActiveMovieFilterCategories};
static bool enumerateCategory(DeviceDescriptors &descriptors,DevCat devCat);
private:
static bool enumerateCategory(DeviceDescriptors &descriptors,GUID classID);
};
#endif

23
dvcap/DeviceNotify.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include <dvcap/DeviceNotify.hpp>
#include <com/com.hpp>
#include <common/dxsdk.hpp>
#include <common/dbt.hpp>
bool DeviceNotification::registerDeviceNotification(GUIWindow &guiWindow)
{
DEV_BROADCAST_DEVICEINTERFACE filterData;
::memset(&filterData,0,sizeof(filterData));
filterData.dbcc_size=sizeof(filterData);
filterData.dbcc_devicetype=DBT_DEVTYP_DEVICEINTERFACE;
filterData.dbcc_classguid=AM_KSCATEGORY_CAPTURE;
mhDevNotify=::RegisterDeviceNotification(guiWindow,&filterData,DEVICE_NOTIFY_WINDOW_HANDLE);
return isOkay();
}
void DeviceNotification::unRegisterDeviceNotification()
{
if(!isOkay())return;
::UnregisterDeviceNotification(mhDevNotify);
mhDevNotify=0;
}

51
dvcap/DeviceNotify.hpp Normal file
View File

@@ -0,0 +1,51 @@
#ifndef _DVCAP_DEVICENOTIFICATION_HPP_
#define _DVCAP_DEVICENOTIFICATION_HPP_
#ifndef _COMMON_GUIWINDOW_HPP_
#include <common/guiwnd.hpp>
#endif
class DeviceNotification
{
public:
DeviceNotification();
virtual ~DeviceNotification();
bool registerDeviceNotification(GUIWindow &guiWindow);
void unRegisterDeviceNotification();
bool isOkay(void)const;
private:
DeviceNotification(const DeviceNotification &deviceNotification);
DeviceNotification &operator=(const DeviceNotification &deviceNotification);
void *mhDevNotify;
};
inline
DeviceNotification::DeviceNotification()
: mhDevNotify(0)
{
}
inline
DeviceNotification::~DeviceNotification()
{
unRegisterDeviceNotification();
}
inline
DeviceNotification::DeviceNotification(const DeviceNotification &deviceNotification)
{ // private
*this=deviceNotification;
}
inline
DeviceNotification &DeviceNotification::operator=(const DeviceNotification &deviceNotification)
{ // private
return *this;
}
inline
bool DeviceNotification::isOkay(void)const
{
return mhDevNotify?true:false;
}
#endif

49
dvcap/Main.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include <common/windows.hpp>
#include <dvcap/mainwnd.hpp>
int PASCAL WinMain(HINSTANCE /*hInstance*/,HINSTANCE /*hPrevInstance*/,LPSTR /*lpszCmdLine*/,int /*nCmdShow*/)
{
MainWindow mainWindow;
return mainWindow.messageLoop();
/*
#include <dvcap/DeviceEnumerator.hpp>
#include <dvcap/DeviceDescriptor.hpp>
#include <dvcap/DevNotify.hpp>
#include <dvcap/VideoCapture.hpp>
ComInitializer comInitializer;
DeviceDescriptors descriptors;
BString deviceName("Microsoft DV Camera and VCR");
*/
/*
ComResult comResult;
ComPointer<ICreateDevEnum> deviceEnumerator;
ComPointer<IEnumMoniker> devEnum;
comResult=deviceEnumerator.createInstance(CLSID_SystemDeviceEnum,IID_ICreateDevEnum);
if(!comResult.success())return;
comResult=deviceEnumerator->CreateClassEnumerator(CLSID_VideoCompressorCategory,(IEnumMoniker**)devEnum,0);
if(!comResult.success())return;
*/
/* VideoCapture videoCapture;
if(!videoCapture.capture(deviceName))
{
::OutputDebugString(String("Capture failed on device '")+deviceName.toString()+String("'\n"));
return 0;
}
*/
/* DeviceEnumerator::enumerateCategory(descriptors,DeviceEnumerator::VideoCaptureSources);
// DeviceEnumerator::enumerateCategory(descriptors,DeviceEnumerator::VideoCompressors);
for(int index=0;index<descriptors.size();index++)
::OutputDebugString(descriptors[index].getName()+String("\n"));
*/
return 0;
}

883
dvcap/Mainwnd.cpp Normal file
View File

@@ -0,0 +1,883 @@
#include <dvcap/mainwnd.hpp>
#include <common/dxsdk.hpp>
#include <common/opendlg.hpp>
#include <dvcap/dvcap.hpp>
#include <dvcap/CaptureDeviceGraph.hpp>
#include <common/assert.hpp>
#include <common/dbt.hpp>
char MainWindow::szClassName[]="DVCAP [v1.00]";
char MainWindow::szMenuName[]="DVCAP";
MainWindow::MainWindow(void)
: mHaveDevice(false), mVideoWidth(0), mVideoHeight(0), mCapStartTime(0),
mHours(0), mMinutes(0), mSeconds(0)
{
mPaintHandler.setCallback(this,&MainWindow::paintHandler);
mDestroyHandler.setCallback(this,&MainWindow::destroyHandler);
mCommandHandler.setCallback(this,&MainWindow::commandHandler);
mKeyDownHandler.setCallback(this,&MainWindow::keyDownHandler);
mSizeHandler.setCallback(this,&MainWindow::sizeHandler);
mCreateHandler.setCallback(this,&MainWindow::createHandler);
mUserHandler.setCallback(this,&MainWindow::userHandler);
mDeviceChangeHandler.setCallback(this,&MainWindow::deviceChangeHandler);
mATNTimerHandler.setCallback(this,&MainWindow::atnTimerHandler);
mCapLimitTimerHandler.setCallback(this,&MainWindow::capLimitTimerHandler);
mFramesTimerHandler.setCallback(this,&MainWindow::framesTimerHandler);
mAtnTimer.insertHandler(&mATNTimerHandler);
mCapLimitTimer.insertHandler(&mCapLimitTimerHandler);
mFramesTimer.insertHandler(&mFramesTimerHandler);
insertHandlers();
registerClass();
::CreateWindow(szClassName,szClassName,WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SIZEBOX|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_DLGFRAME,CW_USEDEFAULT,CW_USEDEFAULT,InitialWidth,InitialHeight,NULL,NULL,processInstance(),(LPSTR)this);
show(SW_SHOW);
update();
}
MainWindow::~MainWindow()
{
destroy();
}
void MainWindow::insertHandlers(void)
{
insertHandler(VectorHandler::DestroyHandler,&mDestroyHandler);
insertHandler(VectorHandler::PaintHandler,&mPaintHandler);
insertHandler(VectorHandler::CommandHandler,&mCommandHandler);
insertHandler(VectorHandler::SizeHandler,&mSizeHandler);
insertHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler);
insertHandler(VectorHandler::CreateHandler,&mCreateHandler);
insertHandler(VectorHandler::UserHandler,&mUserHandler);
insertHandler(VectorHandler::DeviceChangeHandler,&mDeviceChangeHandler);
}
void MainWindow::removeHandlers(void)
{
removeHandler(VectorHandler::DestroyHandler,&mDestroyHandler);
removeHandler(VectorHandler::PaintHandler,&mPaintHandler);
removeHandler(VectorHandler::CommandHandler,&mCommandHandler);
removeHandler(VectorHandler::SizeHandler,&mSizeHandler);
removeHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler);
removeHandler(VectorHandler::CreateHandler,&mCreateHandler);
removeHandler(VectorHandler::UserHandler,&mUserHandler);
removeHandler(VectorHandler::DeviceChangeHandler,&mDeviceChangeHandler);
}
void MainWindow::registerClass(void)
{
HINSTANCE hInstance(processInstance());
WNDCLASS wndClass;
if(::GetClassInfo(hInstance,className(),(WNDCLASS FAR*)&wndClass))return;
wndClass.style =CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_OWNDC;
wndClass.lpfnWndProc =(WNDPROC)Window::WndProc;
wndClass.cbClsExtra =0;
wndClass.cbWndExtra =sizeof(MainWindow*);
wndClass.hInstance =hInstance;
wndClass.hIcon =::LoadIcon(processInstance(),"DVCAP");
wndClass.hCursor =::LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground =(HBRUSH)::GetStockObject(GRAY_BRUSH);
wndClass.lpszMenuName =szMenuName;
wndClass.lpszClassName =szClassName;
::RegisterClass(&wndClass);
assert(0!=::GetClassInfo(hInstance,className(),(WNDCLASS FAR*)&wndClass));
}
CallbackData::ReturnType MainWindow::destroyHandler(CallbackData &/*someCallbackData*/)
{
if(mCaptureDeviceGraph.isOkay())mCaptureDeviceGraph.destroy();
removeHandlers();
::PostQuitMessage(0);
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::sizeHandler(CallbackData &someCallbackData)
{
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::deviceChangeHandler(CallbackData &someCallbackData)
{
handleDeviceChange(someCallbackData);
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::commandHandler(CallbackData &someCallbackData)
{
switch(someCallbackData.wParam())
{
case DVCAPMENU_FILE_SETOUTPUT :
handleFileSetOutput();
break;
case DVCAPMENU_FILE_SETINPUT :
handleFileSetInput();
break;
case DVCAPMENU_FILE_SAVEGRAPH :
handleFileSaveGraph();
break;
case DVCAPMENU_FILE_CAPTURESIZE :
handleFileCaptureSize();
break;
case DVCAPMENU_FILE_EXIT :
sendMessage(WM_CLOSE,0,0L);
break;
case DVCAPMENU_MODE_PREVIEW :
handleModePreview();
break;
case DVCAPMENU_MODE_DVTOFILE :
handleModeDVToFile();
break;
case DVCAPMENU_MODE_DVTOFILE_NOPRE :
handleModeDVToFileNoPre();
break;
case DVCAPMENU_MODE_FILETODV :
handleModeFileToDV();
break;
case DVCAPMENU_MODE_FILETODV_NOPRE :
handleModeFileToDVNoPre();
break;
case DVCAPMENU_MODE_DVTOFILE_TYPE2 :
handleModeDVToFileType2();
break;
case DVCAPMENU_MODE_DVTOFILE_NOPRE_TYPE2 :
handleModeDVToFileNoPreType2();
break;
case DVCAPMENU_MODE_FILETODV_TYPE2 :
handleModeFileToDVType2();
break;
case DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2 :
handleModeFileToDVNoPreType2();
break;
case DVCAPMENU_OPTIONS_REFRESH_MODE :
handleOptionsRefreshMode();
break;
case DVCAPMENU_OPTIONS_CHECK_TAPE :
handleOptionsCheckTape();
break;
case DVCAPMENU_OPTIONS_DECODE_SIZE :
handleOptionsDecodeSize();
break;
case DVCAPMENU_OPTIONS_FRAME_RATE :
handleOptionsFrameRate();
break;
case DVCAPMENU_HELP_ABOUT :
handleHelpAbout();
break;
case IDM_PLAY :
handlePlay();
break;
case IDM_PAUSE :
handlePause();
break;
case IDM_STOP :
handleStop();
break;
case IDM_RECORD :
handleRecord();
break;
case IDM_FORWARD :
handleForward();
break;
case IDM_REVERSE :
handleReverse();
break;
case IDM_FORWARDFASTEST :
handleForwardFastest();
break;
case IDM_SKIPNEXT :
handleSkipNext();
break;
case IDM_SKIPPREV :
handleSkipPrev();
break;
case IDM_REVERSEFASTEST :
handleReverseFastest();
break;
case IDM_SEEKATN :
handleSeekATN();
break;
default :
break;
}
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::keyDownHandler(CallbackData &/*someCallbackData*/)
{
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::createHandler(CallbackData &/*someCallbackData*/)
{
mAppMenu=getMenu();
mToolBar=::new ToolBar();
mToolBar.disposition(PointerDisposition::Delete);
mToolBar->create(*this,ToolBarID);
mToolBar->addBitmap(AddBitmap("TOOLBAR"));
mToolBar->addButton(ToolBarButton(0,IDM_PLAY,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(1,IDM_PAUSE,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(2,IDM_STOP,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(3,IDM_RECORD,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(4,IDM_FORWARD,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(5,IDM_REVERSE,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(6,IDM_FORWARDFASTEST,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(7,IDM_SKIPNEXT,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(8,IDM_SKIPPREV,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(9,IDM_REVERSEFASTEST,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mToolBar->addButton(ToolBarButton(10,IDM_SEEKATN,ToolBarButton::StateEnabled,ToolBarButton::StyleButton));
mStatusBar=::new StatusBarEx(*this,StatusBarID);
mStatusBar.disposition(PointerDisposition::Delete);
setParts();
mDeviceNotification.registerDeviceNotification(*this);
mCaptureDeviceGraph=::new CaptureDeviceGraph();
mCaptureDeviceGraph.disposition(PointerDisposition::Delete);
dvAppSetup(mCaptureDeviceGraph->buildBasicGraph());
int left=350;
Rect initRect;
mEdit1=::new Control();
mEdit1.disposition(PointerDisposition::Delete);
initRect=Rect(left,2,25,22);
mEdit1->createControl(WS_EX_CLIENTEDGE,"edit","00",WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP|ES_NUMBER,initRect,*mToolBar,EditHourID);
mEdit2=::new Control();
mEdit2.disposition(PointerDisposition::Delete);
initRect=Rect(left+25,2,25,22);
mEdit2->createControl(WS_EX_CLIENTEDGE,"edit","00",WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP|ES_NUMBER,initRect,*mToolBar,EditMinuteID);
mEdit3=::new Control();
mEdit3.disposition(PointerDisposition::Delete);
initRect=Rect(left+48,2,25,22);
mEdit3->createControl(WS_EX_CLIENTEDGE,"edit","00",WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP|ES_NUMBER,initRect,*mToolBar,EditSecondID);
mEdit4=::new Control();
mEdit4.disposition(PointerDisposition::Delete);
initRect=Rect(left+71,2,25,22);
mEdit4->createControl(WS_EX_CLIENTEDGE,"edit","00",WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP|ES_NUMBER,initRect,*mToolBar,EditFrameID);
mTCButton=::new Control();
mTCButton.disposition(PointerDisposition::Delete);
initRect=Rect(left+100,2,190,22);
mTCButton->createControl("button","Display Timecodes",WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP|ES_NUMBER,initRect,*mToolBar,TCButtonID);
mTCButton->sendMessage(BM_SETCHECK,true,0L);
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::paintHandler(CallbackData &someCallbackData)
{
return (CallbackData::ReturnType)FALSE;
}
CallbackData::ReturnType MainWindow::userHandler(CallbackData &someCallbackData)
{
switch(someCallbackData.wParam())
{
case WM_FGNOTIFY :
break;
}
return (CallbackData::ReturnType)FALSE;
}
// begin timer handlers
CallbackData::ReturnType MainWindow::atnTimerHandler(CallbackData &someCallbackData)
{
return true;
}
CallbackData::ReturnType MainWindow::capLimitTimerHandler(CallbackData &someCallbackData)
{
return true;
}
CallbackData::ReturnType MainWindow::framesTimerHandler(CallbackData &someCallbackData)
{
return true;
}
// end timer handlers
void MainWindow::setParts()
{
GlobalData<int> parts;
int partWidth=width()/3;
parts.size(3);
parts[0]=partWidth;
parts[1]=parts[0]+partWidth;
parts[2]=parts[1]+partWidth;
mStatusBar->setParts(parts);
}
void MainWindow::handleDeviceChange(CallbackData &cbData)
{
PDEV_BROADCAST_HDR pDevBroadcastHeader=0;
PDEV_BROADCAST_DEVICEINTERFACE pDevBroadcastInterface=0;
if(DBT_DEVICEARRIVAL!=cbData.wParam())return;
dvStatusText("Detected new capture device.");
mStatusBar->update();
pDevBroadcastHeader=(PDEV_BROADCAST_HDR)cbData.lParam();
if(DBT_DEVTYP_DEVICEINTERFACE!=pDevBroadcastHeader->dbch_devicetype)return;
pDevBroadcastInterface=(PDEV_BROADCAST_DEVICEINTERFACE)cbData.lParam();
if(pDevBroadcastInterface->dbcc_classguid!=AM_KSCATEGORY_CAPTURE)return;
if(!mHaveDevice)
{
message("New capture device detected");
mCaptureDeviceGraph=::new CaptureDeviceGraph();
mCaptureDeviceGraph.disposition(PointerDisposition::Delete);
dvAppSetup(mCaptureDeviceGraph->buildBasicGraph());
}
}
void MainWindow::handleFileSaveGraph(void)
{
}
void MainWindow::handleFileSetInput(void)
{
OpenDialog openDialog;
String pathFileName;
if(!openDialog.getOpenFileName(*this,"Microsoft AVI\0*.avi\0\0","Set Output File Name","Capture.avi",pathFileName))return;
mInputFileName=pathFileName;
}
bool MainWindow::handleFileSetOutput(void)
{
OpenDialog openDialog;
String pathFileName;
if(!openDialog.getSaveFileName(*this,"Microsoft AVI\0*.avi\0\0","Set Output File Name","Capture.avi",pathFileName))
return false;
mOutputFileName=pathFileName;
return true;
}
void MainWindow::handleFileCaptureSize()
{
}
void MainWindow::handleModePreview()
{
}
void MainWindow::handleModeDVToFile()
{
if(mOutputFileName.isNull()&&!handleFileSetOutput())return;
if(CaptureDeviceGraph::GraphDVToFile==mGraphType)return;
if(!mCaptureDeviceGraph->stopGraph())return;
mCaptureDeviceGraph->nukeDeviceFilter();
if(!mCaptureDeviceGraph->makeDVToFileGraphType1(mOutputFileName))
{
message("MakeDVToFileGraphType1() Failed");
return;
}
setPreviewWindow();
markGraphModeMenu(DVCAPMENU_MODE_DVTOFILE);
markToolBarButton(true,true);
}
void MainWindow::handleModeDVToFileNoPre()
{
}
void MainWindow::handleModeFileToDV()
{
}
void MainWindow::handleModeFileToDVNoPre()
{
}
void MainWindow::handleModeDVToFileType2()
{
if(mOutputFileName.isNull()&&!handleFileSetOutput())return;
if(CaptureDeviceGraph::GraphDVToFileType2==mGraphType)return;
if(!mCaptureDeviceGraph->stopGraph())return;
mCaptureDeviceGraph->nukeDeviceFilter();
if(!mCaptureDeviceGraph->makeDVToFileGraphType2(mOutputFileName))
{
message("MakeDVToFileGraphType2() Failed");
return;
}
setPreviewWindow();
markGraphModeMenu(DVCAPMENU_MODE_DVTOFILE_TYPE2);
markToolBarButton(true,false);
}
void MainWindow::handleModeDVToFileNoPreType2()
{
}
void MainWindow::handleModeFileToDVType2()
{
}
void MainWindow::handleModeFileToDVNoPreType2()
{
}
void MainWindow::handleOptionsRefreshMode()
{
}
void MainWindow::handleOptionsCheckTape()
{
}
void MainWindow::handleOptionsDecodeSize()
{
}
void MainWindow::handleOptionsFrameRate()
{
}
void MainWindow::handleHelpAbout()
{
}
// start transport handlers
void MainWindow::handlePlay()
{
if(CaptureDeviceGraph::GraphFileToDV==mGraphType ||
CaptureDeviceGraph::GraphFileToDVNoPre==mGraphType ||
CaptureDeviceGraph::GraphFileToDVType2==mGraphType ||
CaptureDeviceGraph::GraphFileToDVNoPreType2==mGraphType)
{
mToolBar->setState(IDM_PLAY,ToolBar::Indeterminate);
mCapStartTime=::GetTickCount();
mFramesTimer.startTimer(TimerResolution);
mCaptureDeviceGraph->startGraph();
}
else
{
dvPutVcrMode(ED_MODE_PLAY);
if(CaptureDeviceGraph::GraphPreview==mGraphType)mCaptureDeviceGraph->startGraph();
if(BST_CHECKED==mTCButton->sendMessage(BM_GETCHECK,0,0L))
mAtnTimer.startTimer(TimerResolution);
}
}
void MainWindow::handleStop()
{
mAtnTimer.stopTimer();
mCapLimitTimer.stopTimer();
mFramesTimer.stopTimer();
mCaptureDeviceGraph->stopGraph();
dvPutVcrMode(ED_MODE_STOP);
mToolBar->setState(IDM_PLAY,ToolBar::Enabled);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Indeterminate);
mToolBar->setState(IDM_SKIPPREV,ToolBar::Indeterminate);
}
void MainWindow::handlePause(void)
{
if(CaptureDeviceGraph::GraphFileToDV==mGraphType ||
CaptureDeviceGraph::GraphFileToDVNoPre==mGraphType ||
CaptureDeviceGraph::GraphFileToDVType2==mGraphType ||
CaptureDeviceGraph::GraphFileToDVNoPreType2==mGraphType)
{
mCaptureDeviceGraph->pauseGraph();
}
else
{
dvPutVcrMode(ED_MODE_FREEZE);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Enabled);
mToolBar->setState(IDM_SKIPPREV,ToolBar::Enabled);
}
}
void MainWindow::handleForward()
{
dvPutVcrMode(ED_MODE_PLAY_FASTEST_FWD);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Indeterminate);
mToolBar->setState(IDM_SKIPPREV,ToolBar::Indeterminate);
}
void MainWindow::handleReverse()
{
dvPutVcrMode(ED_MODE_PLAY_FASTEST_REV);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Indeterminate);
mToolBar->setState(IDM_SKIPPREV,ToolBar::Indeterminate);
}
void MainWindow::handleForwardFastest()
{
dvPutVcrMode(ED_MODE_FF);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Indeterminate);
mToolBar->setState(IDM_SKIPPREV,ToolBar::Indeterminate);
}
void MainWindow::handleSkipNext()
{
mAtnTimer.stopTimer();
dvPutVcrMode(ED_MODE_STEP_FWD);
dvDisplayTimecode();
}
void MainWindow::handleSkipPrev()
{
mAtnTimer.stopTimer();
dvPutVcrMode(ED_MODE_STEP_REV);
dvDisplayTimecode();
}
void MainWindow::handleReverseFastest()
{
dvPutVcrMode(ED_MODE_REW);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Indeterminate);
mToolBar->setState(IDM_SKIPPREV,ToolBar::Indeterminate);
}
void MainWindow::handleSeekATN()
{
dvSeekAtn(); // this needs to be completed
dvDisplayTimecode();
}
void MainWindow::handleRecord()
{
message("Record");
}
/*
case IDM_RECORD :
// update the toolbar accordingly
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
// check to see if it is a capture graph
if (GRAPH_DV_TO_FILE == g_iGraphType || GRAPH_DV_TO_FILE_NOPRE == g_iGraphType ||
GRAPH_DV_TO_FILE_TYPE2 == g_iGraphType || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iGraphType)
{
//do something here to record to an avi file on the disk - or to start recording on the vcr.
switch (g_dwCaptureLimit)
{
case DV_CAPLIMIT_NONE :
break;
case DV_CAPLIMIT_TIME :
SetTimer(hwnd, DV_TIMER_CAPLIMIT, g_dwTimeLimit * 1000, (TIMERPROC) DV_StopRecProc);
break;
case DV_CAPLIMIT_SIZE :
//rather than monitor disk usage, we'll just do the math and set a timer
SetTimer(hwnd, DV_TIMER_CAPLIMIT, ((g_dwDiskSpace * 100000) / DV_BYTESPERMSEC), (TIMERPROC) DV_StopRecProc);
break;
default :
//MBOX(TEXT("Bad value for g_dwCaptureLimit (%d)"), g_dwCaptureLimit);
break;
}
//update the status bar with the dropped frames information
g_CapStartTime = GetTickCount();
SetTimer(hwnd, DV_TIMER_FRAMES, DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
//run the graph - assume that the camera is already playing if in Vcr mode
g_pGraph->StartGraph();
}
else if (GRAPH_FILE_TO_DV == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE == g_iGraphType ||
GRAPH_FILE_TO_DV_TYPE2 == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iGraphType)
{
// if transmit graph then record on tape of the device
DV_PutVcrMode(ED_MODE_RECORD);
}
else
{
//we shouldn't get here
MBOX( TEXT("Undefined graph mode (maybe GRAPH_PREVIEW) in IDM_RECORD message"));
}
break;
*/
// end transport handlers
void MainWindow::dvAppSetup(bool graphResult)
{
int appWidth;
int appHeight;
if(!graphResult)
{
message("No DV camcorder devices detected");
mHaveDevice=false;
mToolBar->show(SW_HIDE);
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_REFRESH_MODE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_CHECK_TAPE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_DECODE_SIZE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_PREVIEW,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE_NOPRE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE_NOPRE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
}
else
{
mHaveDevice=true;
mToolBar->show(SW_SHOWNORMAL);
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_REFRESH_MODE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_CHECK_TAPE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_DECODE_SIZE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_PREVIEW,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE_NOPRE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_DVTOFILE_NOPRE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
dvRefreshMode();
dvStatusText(mCaptureDeviceGraph->getDeviceName().toString());
if(!mCaptureDeviceGraph->makePreviewGraph())
{
message("MakePreviewGraph() Failed.");
return;
}
mCaptureDeviceGraph->getVideoWindowDimensions(mVideoWidth,mVideoHeight);
appWidth=mVideoWidth+WidthEdge;
appHeight=mVideoHeight+HeightEdge;
postMessage(*this,WM_SIZE,SIZE_RESTORED,MAKELONG(appWidth,appHeight));
if(!mCaptureDeviceGraph->setNotifyWindow(*this,WM_FGNOTIFY))
{
message("SetNotifyWindow Failed.");
return;
}
mGraphType=CaptureDeviceGraph::GraphPreview;
markGraphModeMenu(DVCAPMENU_MODE_PREVIEW);
markToolBarButton(false,true);
setPreviewWindow();
}
}
bool MainWindow::dvRefreshMode()
{
CaptureDeviceGraph::DVMode subunitMode;
bool returnCode=false;
if(!mCaptureDeviceGraph.isOkay())return false;
subunitMode=mCaptureDeviceGraph->getDVMode();
switch(subunitMode)
{
case CaptureDeviceGraph::CameraMode :
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_CHECK_TAPE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemGrayed|PureMenu::ItemDisabled));
dvStatusText("Camera Mode.");
returnCode=true;
break;
case CaptureDeviceGraph::VCRMode :
dvUpdateTapeInfo();
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
mAppMenu.enableMenuItem(DVCAPMENU_OPTIONS_CHECK_TAPE,PureMenu::ByCommand,PureMenu::InsertFlags(PureMenu::ItemEnabled));
dvStatusText("VCR Mode.");
returnCode=true;
break;
case CaptureDeviceGraph::UnknownMode :
dvStatusText("Unknown Mode.");
break;
}
return returnCode;
}
bool MainWindow::dvUpdateTapeInfo()
{
if(!mCaptureDeviceGraph.isOkay())return false;
if(!mCaptureDeviceGraph->getTapeInfo())
{
dvStatusText("VCR Mode - No tape, or unknown format");
return false;
}
switch(mCaptureDeviceGraph->getVideoFormat())
{
case DVENCODERVIDEOFORMAT_NTSC :
dvStatusText("VCR Mode - NTSC");
break;
case DVENCODERVIDEOFORMAT_PAL :
dvStatusText("VCR Mode - PAL");
break;
default :
dvStatusText("Unsupported or unrecognized tape format type.");
break;
}
return true;
}
bool MainWindow::setPreviewWindow(void)
{
Rect cliRect;
Rect tbRect;
if(!mCaptureDeviceGraph.isOkay())return false;
if(!mCaptureDeviceGraph->putOwner(*this))return false;
if(!mCaptureDeviceGraph->putWindowStyle(WS_CHILD|WS_CLIPSIBLINGS))return false;
clientRect(cliRect);
mToolBar->clientRect(tbRect);
if(!mCaptureDeviceGraph->setVideoWindowPosition(0,tbRect.bottom()-tbRect.top(),mVideoWidth,mVideoHeight))return false;
if(!mCaptureDeviceGraph->setVideoWindowVisible(true))return false;
return true;
}
void MainWindow::markGraphModeMenu(int itemID)
{
mAppMenu.checkMenuItem(DVCAPMENU_MODE_PREVIEW,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_FILETODV,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_DVTOFILE,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_DVTOFILE_NOPRE,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_FILETODV_TYPE2,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_DVTOFILE_TYPE2,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(DVCAPMENU_MODE_DVTOFILE_NOPRE_TYPE2,PureMenu::ItemUnchecked);
mAppMenu.checkMenuItem(itemID,PureMenu::ItemChecked);
}
void MainWindow::markToolBarButton(bool enableRecord,bool enableOthers)
{
if(true==enableRecord)mToolBar->setState(IDM_RECORD,ToolBar::Enabled);
else mToolBar->setState(IDM_RECORD,ToolBar::Indeterminate);
if(enableOthers)
{
mToolBar->setState(IDM_SKIPPREV,ToolBar::Enabled);
mToolBar->setState(IDM_REVERSEFASTEST,ToolBar::Enabled);
mToolBar->setState(IDM_REVERSE,ToolBar::Enabled);
mToolBar->setState(IDM_FORWARD,ToolBar::Enabled);
mToolBar->setState(IDM_FORWARDFASTEST,ToolBar::Enabled);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Enabled);
mToolBar->setState(IDM_SEEKATN,ToolBar::Enabled);
}
else
{
mToolBar->setState(IDM_SKIPPREV,ToolBar::Indeterminate);
mToolBar->setState(IDM_REVERSEFASTEST,ToolBar::Indeterminate);
mToolBar->setState(IDM_REVERSE,ToolBar::Indeterminate);
mToolBar->setState(IDM_FORWARD,ToolBar::Indeterminate);
mToolBar->setState(IDM_FORWARDFASTEST,ToolBar::Indeterminate);
mToolBar->setState(IDM_SKIPNEXT,ToolBar::Indeterminate);
mToolBar->setState(IDM_SEEKATN,ToolBar::Indeterminate);
}
}
bool MainWindow::dvPutVcrMode(int mode)
{
if(!mCaptureDeviceGraph.isOkay())return false;
return mCaptureDeviceGraph->putIAMExtTransportMode(mode);
}
bool MainWindow::dvSeekAtn(void)
{
int status=false;
int hour;
int minute;
int second;
int frame;
hour=::GetDlgItemInt(*mToolBar,EditHourID,&status,false);
minute=::GetDlgItemInt(*mToolBar,EditMinuteID,&status,false);
second=::GetDlgItemInt(*mToolBar,EditSecondID,&status,false);
frame=::GetDlgItemInt(*mToolBar,EditFrameID,&status,false);
if(!mCaptureDeviceGraph->seekAtn(hour,minute,second,frame))
{
message("Seek Failed - Time should be :\nHour:Minute:Second:Frame");
return false;
}
return true;
}
// this called through both menu selections and timer callback
bool MainWindow::dvDisplayTimecode(void)
{
TIMECODE_SAMPLE tcSample;
tcSample.timecode.dwFrames=0;
tcSample.dwFlags=ED_DEVCAP_TIMECODE_READ;
if(!mCaptureDeviceGraph->getTimecode(tcSample))return false;
if(mHours!=(tcSample.timecode.dwFrames&0xFF000000)>>24)
{
::sprintf(mStrTimecode.str(),"%.2x",(tcSample.timecode.dwFrames&0xFF000000)>>24);
::SetDlgItemText(*mToolBar,EditHourID,mStrTimecode.str());
}
mHours=(tcSample.timecode.dwFrames&0xFF000000)>>24;
if(mMinutes!=(tcSample.timecode.dwFrames&0x00FF0000)>>16)
{
::sprintf(mStrTimecode.str(),"%.2x",(tcSample.timecode.dwFrames&0x00FF0000)>>16);
::SetDlgItemText(*mToolBar,EditMinuteID,mStrTimecode.str());
}
mMinutes=(tcSample.timecode.dwFrames&0x00FF0000)>>16;
if(mSeconds!=(tcSample.timecode.dwFrames&0x0000FF00)>>8)
{
::sprintf(mStrTimecode.str(),"%.2x",(tcSample.timecode.dwFrames&0x0000FF00)>>8);
::SetDlgItemText(*mToolBar,EditMinuteID,mStrTimecode.str());
}
mSeconds=(tcSample.timecode.dwFrames&0x0000FF00)>>8;
::sprintf(mStrTimecode.str(),"%.2x",(tcSample.timecode.dwFrames & 0x000000FF));
::SetDlgItemText(*mToolBar,EditFrameID,mStrTimecode.str());
return true;
}
/*
void MainWindow::disconnect(CaptureDeviceGraph::GraphType graphType)
{
if(CaptureDeviceGraph::GraphFileToDV==graphType ||
CaptureDeviceGraph::GraphFileToDVNoPre==graphType ||
CaptureDeviceGraph::GraphFileToDVType2==graphType ||
CaptureDeviceGraph::GraphFileToDVNoPreType2==graphType)
{
mCaptureDeviceGraph->nukeFilters();
}
else
{
}
*/
/*
if (GRAPH_FILE_TO_DV == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE == g_iGraphType ||
GRAPH_FILE_TO_DV_TYPE2 == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iGraphType)
{
//DisconnectAll removes only the downstream filters - we need to remove the file filter by hand.
g_pGraph->NukeFilters( g_pGraph->m_pInputFileFilter, TRUE);
if (g_pGraph->m_pInputFileFilter )
{
g_pGraph->m_pGraph->RemoveFilter( g_pGraph->m_pInputFileFilter );
SAFE_RELEASE( g_pGraph->m_pInputFileFilter );
}
}
else
{
//DisconnectAll removes only the downstream filters
hr = g_pGraph->NukeFilters( g_pGraph->m_pDeviceFilter, TRUE);
if(FAILED(hr))
{
MBOX(TEXT("nukefilters() failed"));
}
}
*/
// typedef enum GraphType{GraphPreview,GraphDVToFile,GraphDVToFileNoPre,GraphFileToDV,GraphFileToDVNoPre,
// GraphDVToFileType2,GraphDVToFileNoPreType2,GraphFileToDVType2,GraphFileToDVNoPreType2};
/*
}
*/

163
dvcap/Mainwnd.hpp Normal file
View File

@@ -0,0 +1,163 @@
#ifndef _DVCAP_MAINWINDOW_HPP_
#define _DVCAP_MAINWINDOW_HPP_
#ifndef _COMMON_WINDOW_HPP_
#include <common/window.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_SMARTPOINTER_HPP_
#include <common/pointer.hpp>
#endif
#ifndef _COMMON_PUREMENU_HPP_
#include <common/puremenu.hpp>
#endif
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _COMMON_MMTIMER_HPP_
#include <common/mmtimer.hpp>
#endif
#ifndef _STATBAR_STATUSBAREX_HPP_
#include <statbar/statbarx.hpp>
#endif
#ifndef _DVCAP_DEVICENOTIFICATION_HPP_
#include <dvcap/DeviceNotify.hpp>
#endif
#ifndef _DVCAP_CAPTUREDEVICEGRAPH_HPP_
#include <dvcap/CaptureDeviceGraph.hpp>
#endif
#ifndef _TOOLBAR_TOOLBAR_HPP_
#include <toolbar/toolbar.hpp>
#endif
class MainWindow : public Window
{
public:
MainWindow(void);
virtual ~MainWindow();
static String className(void);
private:
enum{StatusBarID=200,ToolBarID=201,EditHourID=202,EditMinuteID=203,EditSecondID=204,EditFrameID=205,TCButtonID=206};
enum{InitialWidth=650,InitialHeight=480,DefaultVideoWidth=360,DefaultVideoHeight=240,WidthEdge=5,HeightEdge=95};
enum{TimerResolution=55}; // 55 ms
enum{Part1,Part2,DevStatusPart};
void registerClass(void);
void insertHandlers(void);
void removeHandlers(void);
void setParts(void);
void handleDeviceChange(CallbackData &cbData);
void message(const String &message)const;
void markGraphModeMenu(int itemID);
void markToolBarButton(bool enableRecord,bool enableOthers);
bool setPreviewWindow(void);
void dvAppSetup(bool graphResult);
bool dvRefreshMode(void);
void dvStatusText(const String &text);
bool dvUpdateTapeInfo(void);
bool dvPutVcrMode(int mode);
bool dvDisplayTimecode(void);
bool dvSeekAtn(void);
bool handleFileSetOutput(void);
void handleFileSetInput(void);
void handleFileSaveGraph(void);
void handleFileCaptureSize(void);
void handleModePreview(void);
void handleModeDVToFile(void);
void handleModeDVToFileNoPre(void);
void handleModeFileToDV(void);
void handleModeFileToDVNoPre(void);
void handleModeDVToFileType2(void);
void handleModeDVToFileNoPreType2(void);
void handleModeFileToDVType2(void);
void handleModeFileToDVNoPreType2(void);
void handleOptionsRefreshMode(void);
void handleOptionsCheckTape(void);
void handleOptionsDecodeSize(void);
void handleOptionsFrameRate(void);
void handleHelpAbout(void);
void handlePlay(void);
void handlePause(void);
void handleStop(void);
void handleRecord(void);
void handleForward(void);
void handleReverse(void);
void handleForwardFastest(void);
void handleSkipNext(void);
void handleSkipPrev(void);
void handleReverseFastest(void);
void handleSeekATN(void);
CallbackData::ReturnType paintHandler(CallbackData &someCallbackData);
CallbackData::ReturnType destroyHandler(CallbackData &someCallbackData);
CallbackData::ReturnType commandHandler(CallbackData &someCallbackData);
CallbackData::ReturnType keyDownHandler(CallbackData &someCallbackData);
CallbackData::ReturnType sizeHandler(CallbackData &someCallbackData);
CallbackData::ReturnType createHandler(CallbackData &someCallbackData);
CallbackData::ReturnType setFocusHandler(CallbackData &someCallbackData);
CallbackData::ReturnType userHandler(CallbackData &someCallbackData);
CallbackData::ReturnType deviceChangeHandler(CallbackData &someCallbackData);
CallbackData::ReturnType atnTimerHandler(CallbackData &someCallbackData);
CallbackData::ReturnType capLimitTimerHandler(CallbackData &someCallbackData);
CallbackData::ReturnType framesTimerHandler(CallbackData &someCallbackData);
Callback<MainWindow> mPaintHandler;
Callback<MainWindow> mDestroyHandler;
Callback<MainWindow> mCommandHandler;
Callback<MainWindow> mKeyDownHandler;
Callback<MainWindow> mSizeHandler;
Callback<MainWindow> mCreateHandler;
Callback<MainWindow> mUserHandler;
Callback<MainWindow> mDeviceChangeHandler;
Callback<MainWindow> mATNTimerHandler;
Callback<MainWindow> mCapLimitTimerHandler;
Callback<MainWindow> mFramesTimerHandler;
static char szClassName[];
static char szMenuName[];
DeviceNotification mDeviceNotification;
SmartPointer<StatusBarEx> mStatusBar;
SmartPointer<ToolBar> mToolBar;
SmartPointer<CaptureDeviceGraph> mCaptureDeviceGraph;
SmartPointer<Control> mEdit1;
SmartPointer<Control> mEdit2;
SmartPointer<Control> mEdit3;
SmartPointer<Control> mEdit4;
SmartPointer<Control> mTCButton;
CaptureDeviceGraph::GraphType mGraphType;
PureMenu mAppMenu;
bool mHaveDevice;
int mVideoWidth;
int mVideoHeight;
DWORD mCapStartTime;
MMTimer mAtnTimer;
MMTimer mCapLimitTimer;
MMTimer mFramesTimer;
String mStrTimecode; // so we don't have to allocate a string for each timer frequency period
DWORD mHours; // for timecode handling
DWORD mMinutes; // for timecode handling
DWORD mSeconds; // for timecode handling
String mOutputFileName;
String mInputFileName;
};
inline
String MainWindow::className(void)
{
return String(szClassName);
}
inline
void MainWindow::message(const String &message)const
{
::MessageBox(*this,message.str(),"DVCAP",MB_OK);
}
inline
void MainWindow::dvStatusText(const String &text)
{
if(!mStatusBar.isOkay())return;
mStatusBar->setText(text,DevStatusPart);
}
#endif

49
dvcap/Nuker.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include <dvcap/nuker.hpp>
Nuker::Nuker(ComPointer<IGraphBuilder> &graphBuilder)
: mGraphBuilder(graphBuilder)
{
mGraphBuilder->AddRef(); // make sure this does what you want (ie) we don't want the
} // graphBuilder to be destroyed when the constructor fires
Nuker::~Nuker()
{
}
bool Nuker::nukeFilter(ComPointer<IBaseFilter> &baseFilter,bool nukeDownstream,bool isDeviceFilter)
{
ComPointer<IEnumPins> enumPins;
ComPointer<IPin> pin;
ULONG fetched=0;
PIN_INFO pinInfo;
if(!baseFilter.isOkay())return false;
if(!ComResult(baseFilter->EnumPins((IEnumPins**)enumPins)).success())
message("[Nuker::nukeFilter]baseFilter->EnumPins((IEnumPins**)enumPins) failed.");
enumPins->Reset();
while(ComResult(enumPins->Next(1,(IPin**)pin,&fetched)).success())
{
ComPointer<IPin> toPin;
if(!pin.isOkay())break;
if(ComResult(pin->ConnectedTo((IPin**)toPin)).success()&&toPin.isOkay())
{
if(!ComResult(toPin->QueryPinInfo(&pinInfo)).success())
message("[Nuker::nukeFilter]toPin->QueryPinInfo(&pinInfo) Failed.");
if(PINDIR_INPUT==pinInfo.dir && nukeDownstream)
{
ComPointer<IBaseFilter> pinFilter(pinInfo.pFilter);
nukeFilter(pinFilter,nukeDownstream,isDeviceFilter); // have to do something with first argument
mGraphBuilder->Disconnect(toPin);
mGraphBuilder->Disconnect(pin);
if(!isDeviceFilter)
{
if(!ComResult(mGraphBuilder->RemoveFilter(pinInfo.pFilter)).success())
{
message("[Nuker::nukeFilter] mGraphBuilder->RemoveFilter(pinInfo.pFilter).");
}
}
}
}
}
return true;
}

29
dvcap/Nuker.hpp Normal file
View File

@@ -0,0 +1,29 @@
#ifndef _DVCAP_NUKER_HPP_
#define _DVCAP_NUKER_HPP_
#ifndef _COMMON_DXSDK_HPP_
#include <common/dxsdk.hpp>
#endif
#ifndef _COM_COM_HPP_
#include <com/com.hpp>
#endif
#ifndef _COM_COMPOINTER_HPP_
#include <com/comptr.hpp>
#endif
class Nuker
{
public:
Nuker(ComPointer<IGraphBuilder> &graphBuilder);
virtual ~Nuker();
bool nukeFilter(ComPointer<IBaseFilter> &baseFilter,bool nukeDownstream,bool isDeviceFilter);
private:
void message(const String &message);
ComPointer<IGraphBuilder> mGraphBuilder;
};
inline
void Nuker::message(const String &message)
{
::OutputDebugString(message+String("\n"));
}
#endif

BIN
dvcap/TOOLBAR.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

111
dvcap/VideoCapture.cpp Normal file
View File

@@ -0,0 +1,111 @@
#include <dvcap/VideoCapture.hpp>
bool VideoCapture::locateDevice(ComPointer<IBaseFilter> &baseFilter,BString &deviceName)
{
ComInitializer comInit;
ComPointer<ICreateDevEnum> deviceEnumerator;
ComPointer<IEnumMoniker> enumMoniker;
ComPointer<IMoniker> moniker;
ComResult comResult;
ULONG cFetched;
baseFilter.Release();
comResult=deviceEnumerator.createInstance(CLSID_SystemDeviceEnum,IID_ICreateDevEnum);
if(comResult.error())return false;
comResult=deviceEnumerator->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,(IEnumMoniker**)enumMoniker,0);
if(comResult.error())return false;
while(enumMoniker->Next(1,(IMoniker**)moniker,&cFetched)==S_OK)
{
ComPointer<IPropertyBag> propertyBag;
moniker->BindToStorage(0,0,IID_IPropertyBag,(void **)(IPropertyBag**)propertyBag);
BString devName;
Variant varName;
comResult=propertyBag->Read(L"FriendlyName", &varName.getVARIANT(),0);
varName.getData(devName);
if(!comResult.error()&&devName==deviceName)
{
comResult=moniker->BindToObject(0,0,IID_IBaseFilter,(void**)(IBaseFilter**)baseFilter);
break;
}
}
return baseFilter.isOkay();
}
bool VideoCapture::capture(BString &deviceName)
{
ComPointer<IBaseFilter> baseFilter;
ComPointer<IGraphBuilder> graph;
// CComPtr<IGraphBuilder> pGraph;
CComPtr<ICaptureGraphBuilder2> pBuilder;
CComPtr<IBaseFilter> ppf;
CComPtr<IBaseFilter> pSrc;
ComResult comResult;
if(!locateDevice(baseFilter,deviceName))return false;
// comResult=pGraph.CoCreateInstance(CLSID_FilterGraph);
comResult=graph.createInstance(CLSID_FilterGraph);
if(!comResult.success())return false;
comResult=pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);
if(!comResult.success())return false;
pBuilder->SetFiltergraph(graph);
comResult=graph->AddFilter(baseFilter,L"Capture");
if(!comResult.success())return false;
comResult=pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,L"d:\\cap.avi",&ppf,0);
if(!comResult.success())return false;
comResult=pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pSrc,0,ppf);
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,pSrc,0,ppf);
// if(!comResult.success())return false;
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pSrc,0,0);
// if(!comResult.success())return false;
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pSrc,0,ppf);
// if(!comResult.success())return false;
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pSrc,0,0);
// if(!comResult.success())return false;
const long ONE_SECOND = 10000000;
REFERENCE_TIME rtStart = 5 * ONE_SECOND;
REFERENCE_TIME rtStop = 10 * ONE_SECOND;
comResult=pBuilder->ControlStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pSrc,&rtStart,&rtStop,0,0);
if(comResult.error())
{
::OutputDebugString("Failed ControlStream\n");
return false;
}
CComQIPtr<IMediaControl> pControl(graph);
CComQIPtr<IMediaEventEx> pEvent(graph);
comResult=pControl->Run();
if(comResult.error())
{
::OutputDebugString("Run Error...\n");
return false;
}
while (1)
{
long evCode, lParam1, lParam2;
comResult=pEvent->GetEvent(&evCode, &lParam1, &lParam2, 100);
if(comResult.success())
{
comResult=pEvent->FreeEventParams(evCode, lParam1, lParam2);
if(evCode == EC_STREAM_CONTROL_STARTED)
{
::printf("Starting capture...\n");
}
else if (evCode == EC_STREAM_CONTROL_STOPPED)
{
::printf("Control Stopped...\n");
break;
}
}
else break;
}
pControl->Stop();
printf("... Done\n");
// baseFilter->Release();
return true;
}

24
dvcap/VideoCapture.hpp Normal file
View File

@@ -0,0 +1,24 @@
#ifndef _DVCAP_VIDEOCAPTURE_HPP_
#define _DVCAP_VIDEOCAPTURE_HPP_
#ifndef _COM_COM_HPP_
#include <com/com.hpp>
#endif
#ifndef _COM_VARIANT_HPP_
#include <com/variant.hpp>
#endif
#ifndef _COM_COMPOINTER_HPP_
#include <com/comptr.hpp>
#endif
#ifndef _COMMON_DXSDK_HPP_
#include <common/dxsdk.hpp>
#endif
class VideoCapture
{
public:
bool capture(BString &deviceName);
private:
bool locateDevice(ComPointer<IBaseFilter> &baseFilter,BString &deviceName);
};
#endif

134
dvcap/dvcap.dsp Normal file
View File

@@ -0,0 +1,134 @@
# Microsoft Developer Studio Project File - Name="dvcap" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=dvcap - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "dvcap.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "dvcap.mak" CFG="dvcap - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "dvcap - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "dvcap - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "dvcap - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "dvcap - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "__FLAT__" /D "STRICT" /D WINVER=0x4000 /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib strmiids.lib comctl32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "dvcap - Win32 Release"
# Name "dvcap - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CaptureDeviceGraph.cpp
# End Source File
# Begin Source File
SOURCE=.\DeviceEnumerator.cpp
# End Source File
# Begin Source File
SOURCE=.\DeviceNotify.cpp
# End Source File
# Begin Source File
SOURCE=.\dvcap.rc
# End Source File
# Begin Source File
SOURCE=.\Main.cpp
# End Source File
# Begin Source File
SOURCE=.\Mainwnd.cpp
# End Source File
# Begin Source File
SOURCE=.\Nuker.cpp
# End Source File
# Begin Source File
SOURCE=.\VideoCapture.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

89
dvcap/dvcap.dsw Normal file
View File

@@ -0,0 +1,89 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "com"=..\com\com.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "common"=..\common\common.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "dvcap"=.\dvcap.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name com
End Project Dependency
Begin Project Dependency
Project_Dep_Name common
End Project Dependency
Begin Project Dependency
Project_Dep_Name statbar
End Project Dependency
Begin Project Dependency
Project_Dep_Name toolbar
End Project Dependency
}}}
###############################################################################
Project: "statbar"=..\statbar\Statbar.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "toolbar"=..\toolbar\Toolbar.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

44
dvcap/dvcap.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef _DVCAP_DVCAP_H_
#define _DVCAP_DVCAP_H_
#define WM_FGNOTIFY WM_USER+1
// MENU DEFINES
#define DVCAPMENU_FILE_SETOUTPUT 10000
#define DVCAPMENU_FILE_SETINPUT 10001
#define DVCAPMENU_FILE_SAVEGRAPH 10002
#define DVCAPMENU_FILE_CAPTURESIZE 10003
#define DVCAPMENU_FILE_EXIT 10004
#define DVCAPMENU_MODE_PREVIEW 10010
#define DVCAPMENU_MODE_DVTOFILE 10011
#define DVCAPMENU_MODE_DVTOFILE_NOPRE 10012
#define DVCAPMENU_MODE_FILETODV 10013
#define DVCAPMENU_MODE_FILETODV_NOPRE 10014
#define DVCAPMENU_MODE_DVTOFILE_TYPE2 10020
#define DVCAPMENU_MODE_DVTOFILE_NOPRE_TYPE2 10021
#define DVCAPMENU_MODE_FILETODV_TYPE2 10022
#define DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2 10023
#define DVCAPMENU_OPTIONS_REFRESH_MODE 10030
#define DVCAPMENU_OPTIONS_CHECK_TAPE 10031
#define DVCAPMENU_OPTIONS_DECODE_SIZE 10032
#define DVCAPMENU_OPTIONS_FRAME_RATE 10033
#define DVCAPMENU_HELP_ABOUT 10040
#define IDM_PLAY 10050
#define IDM_PAUSE 10051
#define IDM_STOP 10052
#define IDM_RECORD 10053
#define IDM_FORWARD 10054
#define IDM_REVERSE 10055
#define IDM_FORWARDFASTEST 10056
#define IDM_SKIPNEXT 10057
#define IDM_SKIPPREV 10058
#define IDM_REVERSEFASTEST 10059
#define IDM_SEEKATN 10060
#endif

4
dvcap/dvcap.hpp Normal file
View File

@@ -0,0 +1,4 @@
#ifndef _DVCAP_DVCAP_HPP_
#define _DVCAP_DVCAP_HPP_
#include <dvcap/dvcap.h>
#endif

BIN
dvcap/dvcap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

3
dvcap/dvcap.log Normal file
View File

@@ -0,0 +1,3 @@
*********************************************************************
DVCAPTURE LOG FILE STARTED AT:Wednesday, November 20,2002 21:38:50
*********************************************************************

BIN
dvcap/dvcap.opt Normal file

Binary file not shown.

58
dvcap/dvcap.plg Normal file
View File

@@ -0,0 +1,58 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: dvcap - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP23.tmp" with contents
[
/nologo /MTd /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "__FLAT__" /D "STRICT" /D WINVER=0x4000 /Fp"Debug/dvcap.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"D:\work\dvcap\CaptureDeviceGraph.cpp"
"D:\work\dvcap\Main.cpp"
]
Creating command line "cl.exe @C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP23.tmp"
Creating temporary file "C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP24.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib strmiids.lib comctl32.lib winmm.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/dvcap.pdb" /debug /machine:I386 /out:"Debug/dvcap.exe" /pdbtype:sept
.\Debug\CaptureDeviceGraph.obj
.\Debug\DeviceEnumerator.obj
.\Debug\DeviceNotify.obj
.\Debug\Main.obj
.\Debug\Mainwnd.obj
.\Debug\Nuker.obj
.\Debug\VideoCapture.obj
.\Debug\dvcap.res
\work\exe\com.lib
\work\exe\mscommon.lib
\work\exe\statbar.lib
\work\exe\toolbar.lib
]
Creating command line "link.exe @C:\WINNT\Profiles\sean\LOCALS~1\Temp\RSP24.tmp"
<h3>Output Window</h3>
Compiling...
CaptureDeviceGraph.cpp
NOTE: WINVER has been defined as 0x0500 or greater which enables
Windows NT 5.0 and Windows 98 features. When these headers were released,
Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the current versions.
For this release when WINVER is defined as 0x0500 or greater, you can only
build beta or test applications. To build a retail application,
set WINVER to 0x0400 or visit http://www.microsoft.com/msdn/sdk
to see if retail Windows NT 5.0 or Windows 98 headers are available.
See the SDK release notes for more information.
Skipping... (no relevant changes detected)
Main.cpp
Linking...
<h3>Results</h3>
dvcap.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

49
dvcap/dvcap.rc Normal file
View File

@@ -0,0 +1,49 @@
/****************************************************************************
produced by Borland Resource Workshop
*****************************************************************************/
#include <windows.h>
#include <dvcap.h>
DVCAP ICON "DVCAP.ICO"
TOOLBAR BITMAP "TOOLBAR.BMP"
DVCAP MENU
{
POPUP "&File"
{
MENUITEM "Set &Output File...", DVCAPMENU_FILE_SETOUTPUT
MENUITEM "Set &Input File...", DVCAPMENU_FILE_SETINPUT
MENUITEM "&Save Graph to File...", DVCAPMENU_FILE_SAVEGRAPH
MENUITEM "&Capture Size...", DVCAPMENU_FILE_CAPTURESIZE
MENUITEM "E&xit", DVCAPMENU_FILE_EXIT
}
POPUP "Graph &Mode"
{
MENUITEM "&Preview", DVCAPMENU_MODE_PREVIEW, CHECKED
MENUITEM SEPARATOR
MENUITEM "&DV To File (Type1)", DVCAPMENU_MODE_DVTOFILE
MENUITEM "DV To File (Type1) (&no preview)", DVCAPMENU_MODE_DVTOFILE_NOPRE
MENUITEM "&File (Type1) To DV", DVCAPMENU_MODE_FILETODV
MENUITEM "File (Type1) To DV (no &preview)", DVCAPMENU_MODE_FILETODV_NOPRE
MENUITEM SEPARATOR
MENUITEM "D&V To File (Type2)", DVCAPMENU_MODE_DVTOFILE_TYPE2
MENUITEM "DV To File (Type2) (n&o preview)", DVCAPMENU_MODE_DVTOFILE_NOPRE_TYPE2
MENUITEM "File (&Type2) To DV", DVCAPMENU_MODE_FILETODV_TYPE2
MENUITEM "File (Type&2) To DV (no preview)", DVCAPMENU_MODE_FILETODV_NOPRE_TYPE2
}
POPUP "&Options"
{
MENUITEM "&Refresh Mode", DVCAPMENU_OPTIONS_REFRESH_MODE
MENUITEM "&Check Tape", DVCAPMENU_OPTIONS_CHECK_TAPE
MENUITEM "Change &Decode Size...", DVCAPMENU_OPTIONS_DECODE_SIZE
MENUITEM "&Half FrameRate", DVCAPMENU_OPTIONS_FRAME_RATE
}
POPUP "&Help"
{
MENUITEM "&About...", DVCAPMENU_HELP_ABOUT
}
}

124
dvcap/scraps.txt Normal file
View File

@@ -0,0 +1,124 @@
// wndClass.hbrBackground =(HBRUSH)COLOR_APPWORKSPACE;
// wndClass.hbrBackground =(HBRUSH)(COLOR_WINDOWFRAME);
/*
if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wparam))
{
ofn.lpstrFilter = TEXT("Filter Graph\0*.grf\0\0");
ofn.lpstrTitle = TEXT("Set FilterGraph File Name");
ofn.lpstrFile = g_FilterGraphFileName;
}
else if (IDM_SETOUTPUT == LOWORD (wparam))
{
ofn.lpstrFilter = TEXT("Microsoft AVI\0*.avi\0\0");
ofn.lpstrTitle = TEXT("Set output File Name");
ofn.lpstrFile = g_OutputFileName;
}
else
{
ofn.lpstrFilter = TEXT("Microsoft AVI\0*.avi\0\0");
ofn.lpstrTitle = TEXT("Set input File Name");
ofn.lpstrFile = g_InputFileName;
}
if (GetOpenFileName(&ofn))
{
if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wparam))
{
lstrcpy(g_FilterGraphFileName, ofn.lpstrFile);
// Save the current built filter graph to a *.grf file
if(g_pGraph != NULL)
g_pGraph->SaveGraphToFile(g_FilterGraphFileName);
}
else if (IDM_SETOUTPUT == LOWORD (wparam))
{
lstrcpy(g_OutputFileName, ofn.lpstrFile);
}
else
{
lstrcpy(g_InputFileName, ofn.lpstrFile);
}
}
break;
*/
// ******************************************************************************************
/*
HRESULT CDVGraph::NukeFilters(IBaseFilter *pFilter, BOOL bNukeDownStream)
{
HRESULT hr = S_OK;
IPin *pPin = NULL;
IPin *pToPin = NULL;
IEnumPins *pEnumPins = NULL;
ULONG uFetched = 0;
PIN_INFO PinInfo;
LONG lDelayCount = 100;
ASSERT(m_pGraph);
// Validating the the pointer to the Filter is not null
if(!pFilter)
{
Dump( TEXT("CAVCGraph::NukeFilters():: Invalid Argument:: Invalid filter to nuke from") );
return E_FAIL;
}
// enumerate all the pins on this filter
// reset the enumerator to the first pin
hr = pFilter->EnumPins(&pEnumPins);
CHECK_ERROR( TEXT("CAVCGraph::NukeFilters():: Could not enumerate pins on the filter to be nuked fro."), hr);
pEnumPins->Reset();
// Loop through all the pins of the filter
while( SUCCEEDED(pEnumPins->Next(1, &pPin, &uFetched)) && pPin )
{
// Get the pin & its pin_info struct that this filter's pin is connected to
hr = pPin->ConnectedTo(&pToPin);
if(SUCCEEDED(hr) &&pToPin )
{
hr = pToPin->QueryPinInfo(&PinInfo);
CHECK_ERROR( TEXT("pToPin->QueryPinInfo failed."), hr);
// Check that this ConnectedTo Pin is a input pin thus validating that our filter's pin is an output pin
if(PinInfo.dir == PINDIR_INPUT && bNukeDownStream)
{
// thus we have a pin on the downstream filter so nuke everything downstream of that filter recursively
NukeFilters(PinInfo.pFilter, bNukeDownStream);
// Disconnect the two pins and remove the downstream filter
m_pGraph->Disconnect(pToPin);
m_pGraph->Disconnect(pPin);
//always leave the Camera filter in the graph
if (PinInfo.pFilter != m_pDeviceFilter)
{
if(FAILED(m_pGraph->RemoveFilter(PinInfo.pFilter)))
{
Dump(TEXT("CAVCGraph::NukeFilters():: The Filter cannot be removed from the filtergraph"));
}
}
}
SAFE_RELEASE(PinInfo.pFilter);
SAFE_RELEASE(pToPin);
Dump(TEXT("CAVCGraph::NukeFilters():: release ToPin\n"));
}
SAFE_RELEASE(pPin);
}
SAFE_RELEASE(pEnumPins);
return S_OK;
}
*/