directX--关于CSource和CSourceStream (谁调用了fillbuffer)
CSourceStream类,是CSource类的OutputPin[source.h/source.cpp]
派生自CAMThread和CBaseOutputPin
l 成员变量:
CSource *m_pFilter; // The parent of this stream//在构造的时候作为输入参数
l 新增加的virtual函数:
// Override this to provide the worker thread a means of processing a buffer
virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;
// Called as the thread is created/destroyed - use to perform
// jobs such as start/stop streaming mode
// If OnThreadCreate returns an error the thread will exit.
virtual HRESULT OnThreadCreate(void) {return NOERROR;};
virtual HRESULT OnThreadDestroy(void) {return NOERROR;};
virtual HRESULT OnThreadStartPlay(void) {return NOERROR;};
virtual HRESULT DoBufferProcessingLoop(void); // the loop executed whilst running
{
Command com;
OnThreadStartPlay();//你可以重载这个函数,可以在play之前作一些操作
do
{
while (!CheckRequest(&com))//
//Determines if a command is waiting for the thread.
//TRUE if the pCom parameter contains a command; otherwise, returns FALSE
{
IMediaSample *pSample;
HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
//这个函数是baseoutputpin的成员函数,返回一块空白的内存区域,需要去填充数据的
//实际上是调用IMemAllocator::GetBuffer函数来实现的
if (FAILED(hr)) { Sleep(1); continue;}
// Virtual function user will override.
//得到数据之后,就填充数据
hr = FillBuffer(pSample);
if (hr == S_OK)
{ hr = Deliver(pSample); pSample->Release();if(hr != S_OK) return S_OK;}
//上面的这个函数调用的是This method calls the IMemInputPin::Receive method on the input pin. //Receive can block if the IMemInputPin::ReceiveCanBlock method returns S_OK.
//这样你的接收的filter就阻塞去接收数据
else if (hr == S_FALSE)
{ pSample->Release();DeliverEndOfStream();return S_OK;}
else
{
pSample->Release();DeliverEndOfStream();
m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
return hr;
}
}
if (com == CMD_RUN || com == CMD_PAUSE) { Reply(NOERROR); }
else if (com != CMD_STOP) { Reply((DWORD) E_UNEXPECTED);}
}
while (com != CMD_STOP);
return S_FALSE;
}
上面的reply是下面的一个CAMThread的函数
上面BOOL CheckRequest(Command *pCom) { return CAMThread::CheckRequest( (DWORD *) pCom); }
继承的CBasePin的virtual函数:
HRESULT Active(void); // Starts up the worker thread
{
CAutoLock lock(m_pFilter->pStateLock());
if (m_pFilter->IsActive()) {return S_FALSE;}
if (!IsConnected()) {return NOERROR;}
hr = CBaseOutputPin::Active();
if (FAILED(hr)) {return hr;}
ASSERT(!ThreadExists());
// start the thread
if (!Create()) {return E_FAIL;}
// Tell thread to initialize. If OnThreadCreate Fails, so does this.
hr = Init();
if (FAILED(hr)) return hr;
return Pause();
}
HRESULT Inactive(void); // Exits the worker thread.
{
CAutoLock lock(m_pFilter->pStateLock());
if (!IsConnected()) {return NOERROR;}
// !!! need to do this before trying to stop the thread, because
// we may be stuck waiting for our own allocator!!!
hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
if (FAILED(hr)) {return hr;}
if (ThreadExists())
{
hr = Stop();if (FAILED(hr)) {return hr;}
hr = Exit();if (FAILED(hr)) {return hr;}
Close(); // Wait for the thread to exit, then tidy up.
}
return NOERROR;
}
virtual HRESULT CheckMediaType(const CMediaType *pMediaType);
{
// 默认只支持一种格式,即只调用新增加的GetMediaType函数得到MediaType,
// 与输入的Type进行比较
}
virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); // List pos. 0-n
{
// 判断iPosition必须为0,返回新增加的GetMediaType函数
}
l 操作函数:
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); }
我们通过上面的代码发现,CAMThread和CBaseOutputPin关联很紧密,下面我们来看看CAMThread是一个什么样的类
l CAMThread的virtual函数
// override these if you want to add thread commands
// Return codes > 0 indicate an error occured
virtual DWORD ThreadProc(void); // the thread function
{
// 整个函数实现了一个同步的通讯Thread。
Command com;
do { com = GetRequest();if (com != CMD_INIT) { Reply((DWORD) E_UNEXPECTED);} }
while (com != CMD_INIT);
hr = OnThreadCreate(); // perform set up tasks
if (FAILED(hr))
{
OnThreadDestroy();
Reply(hr); // send failed return code from OnThreadCreate
return 1;
}
Reply(NOERROR);
Command cmd;
do
{
cmd = GetRequest();
switch (cmd) {
case CMD_EXIT: Reply(NOERROR); break;
case CMD_RUN:
case CMD_PAUSE:Reply(NOERROR); DoBufferProcessingLoop();break;
case CMD_STOP: Reply(NOERROR); break;
default: Reply((DWORD) E_NOTIMPL); break;}
}
while (cmd != CMD_EXIT);
hr = OnThreadDestroy(); // tidy up.
if (FAILED(hr)) { return 1;}
return 0;
}
l Constructor:
// increments the number of pins present on the filter
CSourceStream(TCHAR *pObjectName, HRESULT *phr, CSource *ps, LPCWSTR pPinName)
: CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
m_pFilter(ps) {*phr = m_pFilter->AddPin(this);}
l Deconstructor:
~CSourceStream(void) {m_pFilter->RemovePin(this);}
这个类要实现就是这个函数了,注意Reply函数经常调用,因为
CAMThread::Reply(DWORD dw)
{
m_dwReturnVal = dw;
// The request is now complete so CheckRequest should fail from
// now on
//
// This event should be reset BEFORE we signal the client or
// the client may Set it before we reset it and we'll then
// reset it (!)
m_EventSend.Reset();
// Tell the client we're finished
m_EventComplete.Set();
}
directX--关于CSource和CSourceStream (谁调用了fillbuffer)的更多相关文章
- directX--大约CSource和CSourceStream (谁在叫fillbuffer)
CSourceStream类别,它是CSource类别OutputPin[source.h/source.cpp] 派生自CAMThread和CBaseOutputPinl 成员变量: ...
- Windows 8 DirectX 和Xaml UI 混合处理方案
原文 http://www.cnblogs.com/chenkai/archive/2012/11/29/2794983.html [如果不想读这么长问题描述和通用的解决方案. 可以直接skip 这段 ...
- VLC说明
一.简介 vlc的全名是Video Lan Client,是一个开源的.跨平台的视频播放器.VLC支持大量的音视频传输.封装和编码格式,完整的功能特性列表可以在这里获得http://www.video ...
- hlsl 和cg 涉及 mul 左乘 右乘
error: 1. mul' implicit truncation of vector type 2. matrixXXX: array dimensions of(unknown scope en ...
- kinect for windows - DepthBasics-D2D详解之一
Depth在kinect中经常被翻译为深度图,指的是图像到摄像头的距离,这些距离数据能让机器知道物理距离有多远.kinect通过两个红外摄像头来实现这个功能的.在这个例子里,就实现了深度图的提取和现实 ...
- kinect for windows - DepthBasics-D2D详解
引自:http://blog.csdn.net/itcastcpp/article/details/20282667 Depth在kinect中经常被翻译为深度图,指的是图像到摄像头的距离,这些距离数 ...
- VLC框架分析
功能部份:VLC媒体播放器的核心是libvlc ,它提供了界面,应用处理功能,如播放列表管理,音频和视频解码和输出,线程系统.所有libvlc源文件设在的/src目录及其子目录:# config/ ...
- VLC简介及使用说明
一.简介 VLC的全名是Video Lan Client,是一个开源的.跨平台的视频播放器.VLC支持大量的音视频传输.封装和编码格式,完整的功能特性列表可以在这里获得http://www.vi ...
- C++实现一个Vector3空间向量类(转)
转自:http://www.2cto.com/kf/201311/260139.html ector2,3,4类在DirectX中都有现成的可以调用,不过要实现其中的功能其实也不难,也都是一些简单的数 ...
随机推荐
- 免费分享Navicat12各版本破解(仅供学习使用)
花了几个小时终于找到比较"绿色"的安装包了...(无力吐槽下现在网上好多挂羊头卖狗肉的网站) https://pan.baidu.com/s/1geMIkfT 密码:9a98 里面 ...
- es随想二
一.es运行状态的监控 es长时间批量入库时,需要对入库的性能进行监控,否则可能导致es重启,入库任务失败. 可以编写shell脚本,每分钟用cat命令监控pending的数量,数量逐渐增大时就需要注 ...
- BZOJ 2287. [HZOI 2015]疯狂的机器人 [FFT 组合计数]
2287. [HZOI 2015]疯狂的机器人 题意:从原点出发,走n次,每次上下左右不动,只能在第一象限,最后回到原点方案数 这不煞笔提,组合数写出来发现卷积NTT,然后没考虑第一象限gg 其实就是 ...
- POJ 2409 Let it Bead [置换群 Polya]
传送门 题意:$m$种颜色$n$颗珠子,定义旋转和翻转两种置换,求不等价着色数 暴力求每个置换的循环节也许会$T?$ 我们可以发现一些规律: 翻转: $n$为奇数时每个置换有$1+\frac{n-1} ...
- Linux压缩解压命令汇总
01-.tar格式 解包:[*******]$ tar xvf FileName.tar 打包:[*******]$ tar cvf FileName.tar DirName (注:tar是打包,不是 ...
- Maven入门知识介绍
1.1 Maven简介 Apache Maven 是一个软件项目管理工具.基于项目对象模型的概念,Maven可用来管理项目的依赖.编译.文档 等信息. 使用maven管理项目时,项目的依赖的jar包将 ...
- ConcurrenHashMap源码分析(二)
本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...
- 初识vps,域名与购买,初步配置
终于还是到了这一天,不管我们是不是程序员,当我们想拥有自己的一个的博客,当我们想有自己的一个空间,当我们想在网上有一个自己可以随心所欲编写任何不被限制的仅仅是酷炫的效果,当我们想收录自己的技术,经历, ...
- Python自动化--语言基础2--运算符、格式化输出、条件语句、循环语句、列表、元组
运算符包括:算术运算符.比较运算符.赋值运算符.逻辑运算符.成员运算符.身份运算符 算术运算符 % 取模(余数) // 取相除的整数部分 / (5/2=2.5) 比较运算符 == 等于 ! ...
- 高并发关于微博、秒杀抢单等应用场景在PHP环境下结合Redis队列延迟入库
第一步:创建模拟数据表. CREATE TABLE `test_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NUL ...