📄 cdxgraph.cpp
字号:
bool CDXGraph::SetCurrentPosition(double inPosition)
{
if (mSeeking)
{
__int64 one = 10000000;
__int64 position = (__int64)(one * inPosition);
HRESULT hr = mSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,
0, AM_SEEKING_NoPositioning);
return SUCCEEDED(hr);
}
return false;
}
bool CDXGraph::SetStartStopPosition(double inStart, double inStop)
{
if (mSeeking)
{
__int64 one = 10000000;
__int64 startPos = (__int64)(one * inStart);
__int64 stopPos = (__int64)(one * inStop);
HRESULT hr = mSeeking->SetPositions(&startPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,
&stopPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame);
return SUCCEEDED(hr);
}
return false;
}
bool CDXGraph::GetDuration(double * outDuration)
{
if (mSeeking)
{
__int64 length = 0;
if (SUCCEEDED(mSeeking->GetDuration(&length)))
{
*outDuration = ((double)length) / 10000000.;
return true;
}
}
return false;
}
bool CDXGraph::SetPlaybackRate(double inRate)
{
if (mSeeking)
{
if (SUCCEEDED(mSeeking->SetRate(inRate)))
{
return true;
}
}
return false;
}
// Attention: range from -10000 to 0, and 0 is FULL_VOLUME.
bool CDXGraph::SetAudioVolume(long inVolume)
{
if (mBasicAudio)
{
HRESULT hr = mBasicAudio->put_Volume(inVolume);
return SUCCEEDED(hr);
}
return false;
}
long CDXGraph::GetAudioVolume(void)
{
long volume = 0;
if (mBasicAudio)
{
mBasicAudio->get_Volume(&volume);
}
return volume;
}
// Attention: range from -10000(left) to 10000(right), and 0 is both.
bool CDXGraph::SetAudioBalance(long inBalance)
{
if (mBasicAudio)
{
HRESULT hr = mBasicAudio->put_Balance(inBalance);
return SUCCEEDED(hr);
}
return false;
}
long CDXGraph::GetAudioBalance(void)
{
long balance = 0;
if (mBasicAudio)
{
mBasicAudio->get_Balance(&balance);
}
return balance;
}
bool CDXGraph::RenderFile(const char * inFile)
{
if (mGraph)
{
WCHAR szFilePath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);
if (SUCCEEDED(mGraph->RenderFile(szFilePath, NULL)))
{
return true;
}
}
return false;
}
bool CDXGraph::SnapshotBitmap(const char * outFile)
{
if (mBasicVideo)
{
long bitmapSize = 0;
if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0)))
{
bool pass = false;
unsigned char * buffer = new unsigned char[bitmapSize];
if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, (long *)buffer)))
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)buffer;
int nColors = 1 << lpbi->biBitCount;
if (nColors > 256)
nColors = 0;
hdr.bfType = ((WORD) ('M' << 8) | 'B'); //always is "BM"
hdr.bfSize = bitmapSize + sizeof( hdr );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + lpbi->biSize +
nColors * sizeof(RGBQUAD));
CFile bitmapFile(outFile, CFile::modeReadWrite | CFile::modeCreate | CFile::typeBinary);
bitmapFile.Write(&hdr, sizeof(BITMAPFILEHEADER));
bitmapFile.Write(buffer, bitmapSize);
bitmapFile.Close();
pass = true;
}
delete [] buffer;
return pass;
}
}
return false;
}
//////////////////////// For GraphEdit Dubug purpose /////////////////////////////
void CDXGraph::AddToObjectTable(void)
{
IMoniker * pMoniker = 0;
IRunningObjectTable * objectTable = 0;
if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))
{
WCHAR wsz[256];
wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)mGraph, GetCurrentProcessId());
HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
if (SUCCEEDED(hr))
{
hr = objectTable->Register(0, mGraph, pMoniker, &mObjectTableEntry);
pMoniker->Release();
}
objectTable->Release();
}
}
void CDXGraph::RemoveFromObjectTable(void)
{
IRunningObjectTable * objectTable = 0;
if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))
{
objectTable->Revoke(mObjectTableEntry);
objectTable->Release();
mObjectTableEntry = 0;
}
}
bool CDXGraph::CreateSampleGrabber()
{
if(!pGrabberF)
{
HRESULT hr=CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER,
IID_IBaseFilter,reinterpret_cast<void**>(&pGrabberF));
if(!SUCCEEDED(hr))
{
return hr;
}
hr=mGraph->AddFilter(pGrabberF,L"Sample Grabber");
if(FAILED(hr))
{
return hr;
}
pGrabberF->QueryInterface(IID_ISampleGrabber,(void**)&pGrabber);
}
}
bool CDXGraph::SpecifyMediaType()
{
HDC hdc = GetDC(NULL);
int iBitDepth = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(NULL, hdc);
// Set the media type.
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
switch (iBitDepth)
{
case 8:
mt.subtype = MEDIASUBTYPE_RGB8;
break;
case 16:
mt.subtype = MEDIASUBTYPE_RGB555;
break;
case 24:
mt.subtype = MEDIASUBTYPE_RGB24;
break;
case 32:
mt.subtype = MEDIASUBTYPE_RGB32;
break;
default:
return E_FAIL;
}
HRESULT hr= pGrabber->SetMediaType(&mt);
return hr;
}
HRESULT CDXGraph::CompleteBuildGraph(const char * inFile)
{
WCHAR szFilePath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);
IBaseFilter *pSrc;
HRESULT hr=mGraph->AddSourceFilter(szFilePath,L"Source", &pSrc);
hr = ConnectFilters(mGraph, pSrc, pGrabberF);
if(FAILED(hr))return hr;
IBaseFilter *pNull = NULL;
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, reinterpret_cast<void**>(&pNull));
if(FAILED(hr))return hr;
hr = mGraph->AddFilter(pNull, L"NullRenderer");
if(FAILED(hr))return hr;
hr = ConnectFilters(mGraph, pGrabberF, pNull);
return hr;
}
HRESULT CDXGraph::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
{
IEnumPins *pEnum;
IPin *pPin;
pFilter->EnumPins(&pEnum);
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (PinDir == PinDirThis)
{
pEnum->Release();
*ppPin = pPin;
return S_OK;
}
pPin->Release();
}
pEnum->Release();
return E_FAIL;
}
HRESULT CDXGraph::ConnectFilters(IGraphBuilder *pGraph, IBaseFilter *pFirst, IBaseFilter *pSecond)
{
IPin *pOut = NULL, *pIn = NULL;
HRESULT hr = GetPin(pFirst, PINDIR_OUTPUT, &pOut);
if (FAILED(hr)) return hr;
hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
if (FAILED(hr))
{
pOut->Release();
return E_FAIL;
}
hr = pGraph->Connect(pOut, pIn);
pIn->Release();
pOut->Release();
return hr;
}
HRESULT CDXGraph::RunGrabberGraph()
{
// Set one-shot mode and buffering.
HRESULT hr= pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);
if (FAILED(hr))
return hr;
mMediaControl->Run(); // Run the graph.
LONG FAR evCode=0xFFFFFFFF;
mEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.
return evCode;
}
long CDXGraph::GetSample(char *pBuffer)
{
long cbBuffer = 0;
HRESULT hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
if(FAILED(hr))return hr;
pBuffer = new char[cbBuffer];
if (!pBuffer)
{
return E_OUTOFMEMORY;
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer,
reinterpret_cast<long*>(pBuffer));
if(FAILED(hr))
return hr;
return cbBuffer;
}
HRESULT CDXGraph::Display(HDC hdc,char *pBuffer)
{
AM_MEDIA_TYPE mt;
HRESULT hr = pGrabber->GetConnectedMediaType(&mt);
VIDEOINFOHEADER *pVih;
if ((mt.formattype == FORMAT_VideoInfo) &&
(mt.cbFormat>=sizeof(VIDEOINFOHEADER))&&
(mt.pbFormat!=NULL))
pVih = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
else
{
// Free the format block when you are done:
FreeMediaType(mt);
return VFW_E_INVALIDMEDIATYPE; // Something went wrong
// pVih->bmiHeader is the BITMAPINFOHEADER for the frame.
}
SetDIBitsToDevice(
hdc,0,0,
pVih->bmiHeader.biWidth,
pVih->bmiHeader.biHeight,
0,0,
0,
pVih->bmiHeader.biHeight,
pBuffer,
(BITMAPINFO*)&pVih->bmiHeader,
DIB_RGB_COLORS
);
FreeMediaType(mt);
return hr;
}
bool CDXGraph::Snapshot(HDC hdc,const char *outFile, unsigned char *buffer)
{
if (mBasicVideo)
{
long bitmapSize = 0;
if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0)))
{
bool pass = false;
buffer = new unsigned char[bitmapSize];
if (!SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, (long *)buffer)))
return FALSE;
LPBITMAPINFOHEADER pVih;
pVih = (LPBITMAPINFOHEADER)buffer;
SetDIBitsToDevice(
hdc,0,0,
pVih->biWidth,
pVih->biHeight,
0,0,
0,
pVih->biHeight,
buffer,
(BITMAPINFO*)pVih,
DIB_RGB_COLORS
);
}
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -