数据输出pin,class CVideoOutPin : public CSourceStream;
处理原数据的线程类 class AM_NOVTABLE CAMThread;
class CSourceStream : public CAMThread, public CBaseOutputPin {
...
enum Command {CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT};
HRESULT Init(void) { return CallWorker(CMD_INIT); }
HRESULT Exit(void) { return CallWorker(CMD_EXIT); }
HRESULT Run(void) { return CallWorker(CMD_RUN); }
HRESULT Pause(void) { return CallWorker(CMD_PAUSE); }
HRESULT Stop(void) { return CallWorker(CMD_STOP); }
...
}
点播
graph调用mMediaControl->Run(),引起CBaseFilter::Pause(),CBaseFilter::Run(),引起CSourceStream::Active() ,
CSourceStream::Active(void) {
CBaseOutputPin::Active();//执行return m_pAllocator->Commit();
CAMThread::Create()//创建线程,调用CAMThread::InitialThreadProc。
Init();
}
接收处理
//循环的内容为:
DWORD CSourceStream::ThreadProc(void) {
...
Command cmd;
do {
cmd = GetRequest();
switch (cmd) {
case CMD_EXIT:
Reply(NOERROR);
break;
case CMD_RUN:
DbgLog((LOG_ERROR, 1, TEXT("CMD_RUN received before a CMD_PAUSE???")));
// !!! fall through???
case CMD_PAUSE:
Reply(NOERROR);
DoBufferProcessingLoop();
break;
case CMD_STOP:
Reply(NOERROR);
break;
default:
DbgLog((LOG_ERROR, 1, TEXT("Unknown command %d received!"), cmd));
Reply((DWORD) E_NOTIMPL);
break;
}
} while (cmd != CMD_EXIT);
...
}
HRESULT CSourceStream::DoBufferProcessingLoop(void) {
Command com;
OnThreadStartPlay();
do {
while (!CheckRequest(&com)) { 退出的标志。
IMediaSample *pSample;
HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
if (FAILED(hr)) {
Sleep(1);
continue; // go round again. Perhaps the error will go away
// or the allocator is decommited & we will be asked to
// exit soon.
}
// Virtual function user will override.
hr = FillBuffer(pSample); //填充数据
if (hr == S_OK) {
hr = Deliver(pSample); //发送数据
pSample->Release(); //引用减减
// downstream filter returns S_FALSE if it wants us to
// stop or an error if it's reporting an error.
if(hr != S_OK)
{
DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr));
return S_OK;
}
} else if (hr == S_FALSE) {
// derived class wants us to stop pushing data
pSample->Release();
DeliverEndOfStream();
return S_OK;
} else {
// derived class encountered an error
pSample->Release();
DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr));
DeliverEndOfStream();
m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
return hr;
}
// all paths release the sample
}
// For all commands sent to us there must be a Reply call!
if (com == CMD_RUN || com == CMD_PAUSE) {
Reply(NOERROR);
} else if (com != CMD_STOP) {
Reply((DWORD) E_UNEXPECTED);
DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!")));
}
} while (com != CMD_STOP);
return S_FALSE;
}
CBaseOutputPin::Deliver(IMediaSample * pSample)
{
return m_pInputPin->Receive(pSample); //下游的开始接收
}
暂停
调用CBaseFilter::Pause(),不能让DoBufferProcessingLoop()停止工作,除非把接收的函数堵住。
停止
mMediaControl->Stop()引起CBaseFilter::Stop(),引起如下:
HRESULT CSourceStream::Inactive(void) {
...
CBaseOutputPin::Inactive();//主要语句为return m_pAllocator->Decommit();。
Stop();//调用CAMThread::CallWorker(CMD_STOP)。
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务