Dshow--分析点播命令
2013-01-22 15:31
253 查看
数据输出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)。
}
处理原数据的线程类 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)。
}
相关文章推荐
- Web 网站 故障常用分析命令
- hbase简单分析及其命令
- 几条分析apache访问日志的命令
- 运行npm update等命令出错后如何分析问题根源
- 淘宝服务市场 PHP封装商品橱窗类 (仅提供思路分析,类内调用的命令还需要自己编写)
- 利用grep命令查找字符串分析log文件的一次实践
- 日志分析常用命令
- MySQL数据库服务器逐渐变慢分析与解决(6)vmstat命令输出的六个部分
- VSS源代码管理器运行代码分析工具的命令
- Nova client源码分析---nova list命令
- linux性能分析命令ps,top,vmstat 使用
- curl 分析tcp与ssl握手时间命令
- Linux服务器分析命令
- Linux下日志分析的几个常用命令
- Nginx日志常用分析命令汇总 (转)
- Linux常用命令(6)-性能瓶颈分析(java)
- uboot命令分析+实现【转】
- 网站排障分析常用的命令
- linux tcpdump命令以及结果分析
- JVM常用分析命令与工具