您的位置:首页 > 其它

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)。

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: