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)的更多相关文章

  1. directX--大约CSource和CSourceStream (谁在叫fillbuffer)

    CSourceStream类别,它是CSource类别OutputPin[source.h/source.cpp] 派生自CAMThread和CBaseOutputPinl         成员变量: ...

  2. Windows 8 DirectX 和Xaml UI 混合处理方案

    原文 http://www.cnblogs.com/chenkai/archive/2012/11/29/2794983.html [如果不想读这么长问题描述和通用的解决方案. 可以直接skip 这段 ...

  3. VLC说明

    一.简介 vlc的全名是Video Lan Client,是一个开源的.跨平台的视频播放器.VLC支持大量的音视频传输.封装和编码格式,完整的功能特性列表可以在这里获得http://www.video ...

  4. hlsl 和cg 涉及 mul 左乘 右乘

    error: 1. mul' implicit truncation of vector type 2. matrixXXX: array dimensions of(unknown scope en ...

  5. kinect for windows - DepthBasics-D2D详解之一

    Depth在kinect中经常被翻译为深度图,指的是图像到摄像头的距离,这些距离数据能让机器知道物理距离有多远.kinect通过两个红外摄像头来实现这个功能的.在这个例子里,就实现了深度图的提取和现实 ...

  6. kinect for windows - DepthBasics-D2D详解

    引自:http://blog.csdn.net/itcastcpp/article/details/20282667 Depth在kinect中经常被翻译为深度图,指的是图像到摄像头的距离,这些距离数 ...

  7. VLC框架分析

      功能部份:VLC媒体播放器的核心是libvlc ,它提供了界面,应用处理功能,如播放列表管理,音频和视频解码和输出,线程系统.所有libvlc源文件设在的/src目录及其子目录:# config/ ...

  8. VLC简介及使用说明

    一.简介    VLC的全名是Video Lan Client,是一个开源的.跨平台的视频播放器.VLC支持大量的音视频传输.封装和编码格式,完整的功能特性列表可以在这里获得http://www.vi ...

  9. C++实现一个Vector3空间向量类(转)

    转自:http://www.2cto.com/kf/201311/260139.html ector2,3,4类在DirectX中都有现成的可以调用,不过要实现其中的功能其实也不难,也都是一些简单的数 ...

随机推荐

  1. iOS-主线程刷新UI【+单例】

    主线程刷新UI dispatch_async(dispatch_get_main_queue(), ^{ /// }); 单例 static Tools *_sharedManger; @implem ...

  2. 【转】我读过最好的epoll讲解(来自知乎)

    首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象.不管是文件,还是套接字,还是管道,我们都可以把他们看作流.之后我们来讨论I/O的操作,通过read,我 ...

  3. I/O多路转接模型

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  4. Kolakoski序列产生器

    /* 本程序说明: Kolakoski序列是一个仅由1和2组成的无限数列,是一种通过“自描述”来定义的数列. 他的前几项为1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1 ...

  5. PYTHON3 RE正则表达:

    The special characters are: "." Matches any character except a newline. "^" Matc ...

  6. Java中的Throable类是不是受查异常?

    Q: Throable是不是受查异常? A: 是 在Java规范中,对非受查异常和受查异常的定义是这样的: The unchecked exception classes are the run-ti ...

  7. 2017年 Java 程序员,风光背后的危机

    不得不承认,经历过行业的飞速发展期,互联网的整体发展趋于平稳.为什么这么说?为什么要放在 Java 程序员的盘点下说? 的确,对于进可攻前端,后可守后端大本营的 Java 程序员而言,虽然供应逐年上涨 ...

  8. MysqL错误之_ERROR! MySQL server PID file could not be found!

    在配置Mysql主从GTID模式下,启动Mysql服务时出现报错,搜索了一番,找到了一个简单可靠的方法,直接成功.如果遇到相同问题没有解决的童鞋,那就去试一下很多其他方案,如,强制杀掉进程重启,修改其 ...

  9. python实现汉诺塔移动

    汉诺塔问题 汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大 ...

  10. UVA 816 bfs

    算法入门经典上面的题.题目链接 uva816 大致题意 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求一条最短路(多解时任意输出一个即可).详细题意请看原题 思路 其实就是b ...