⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memfilter.h

📁 WINCE下的播放器
💻 H
字号:
//
// MemFilter.h
//
#ifndef  __MemFilter_h__
#define  __MemFilter_h__

#include <streams.h>
#include <stdio.h>
#include <tchar.h>
#include "asyncio.h"
#include "asyncrdr.h"

#include "CMediaSocketClient.h"
#include "CDataAdmin.h"
#include "MyDef.h"


//////////////////////////////////////////////////////////////////////
//  Define an internal filter that wraps the base CBaseReader stuff //
//////////////////////////////////////////////////////////////////////
class CMemStream : public CAsyncStream
{
private:
    CCritSec       m_csLock;          //数据超作的同步对象,临界区对象

	CDataAdmin *   m_pDataList;       //数据接收队列管理器
    ULONG          m_ulPositionInPack;//当前缓冲块内的偏移量
    // Total length available
	LONGLONG       m_llLength;        //当前可以获得的数据总长度
	// Bytes totally read
 
public:
    CMemStream(CDataAdmin* inBuffer)
    {
		m_pDataList         = inBuffer;
		m_ulPositionInPack  = 0;
		m_llLength          = 0;   
    }

    HRESULT SetPointer(LONGLONG llPos)//没有实际作用
    {
		return S_OK;
    }

	//读取一定量的数据到指定的缓存中;当Splitter要求数据时,必须在这个函数中提供
    HRESULT Read(PBYTE pbBuffer,           //装载读出数据的缓存地址,输出变量,就是要播放的数据
                 DWORD dwBytesToRead,      //要求读取的字节数,输入变量
                 BOOL bAlign,              //数据对齐方式,输入变量
                 LPDWORD pdwBytesRead)     //实际读取的字节数,输出变量,表示读了的数据长度
    {
		if (m_pDataList == NULL)
		{
			return S_FALSE;
		}
		CAutoLock     lck(&m_csLock);
		DWORD         dwHaveRead = 0;  //已经读取的字节数
		PMPEG1_PACK   pPack  = NULL;
        //如果已经读取的字节数没有达到要求的字节数,则继续While循环
		while (dwHaveRead < dwBytesToRead)
		{
			//如果剩下还要读取的字节数大于当前缓冲块中剩余的有效字节数
			//则直接将当前缓存块中的剩余数据读出
			if (dwBytesToRead - dwHaveRead >= MPEG1_PACK_SIZE - m_ulPositionInPack)
			{
				// Just copy the whole pack data
				//首先得到缓冲块的指针
				pPack = m_pDataList->GetDataBuffer();
				if (pPack != NULL)
				{
					//NOTE:CE不支持CopyMemory,by XQF 2007-5-1(CE下考虑Memcpy)
					//从我们的缓冲块中得到要播放的数据
					CopyMemory((PVOID)(pbBuffer + dwHaveRead), 
						(PVOID)((PBYTE)(pPack) + m_ulPositionInPack), (SIZE_T)MPEG1_PACK_SIZE - m_ulPositionInPack);
					//回收数据已经被完全读出的缓冲块,等待下次接受数据
					m_pDataList->ReleaseDataBuffer(pPack);
					//修改已经读取的字节数
					dwHaveRead += MPEG1_PACK_SIZE - m_ulPositionInPack;
					//缓存块内的偏移置0
					m_ulPositionInPack = 0;
				}
				else if (m_pDataList->IsFlushing())
				{
				//	FILE * fp = fopen("c:\\log.txt","a+");
				//	fprintf(fp,"failed!\n");
				//	fclose(fp); 
					return E_FAIL; //跳出WHILE循环
				}
				else 
				{
				//	FILE * fp = fopen("c:\\log.txt","a+");
				//	fprintf(fp,"SLEEP!\n");
				//	fclose(fp); 
					Sleep(10); //等待接受更多的数据
				}
			}
			else
			{
				// Copy part of the pack data
				pPack = m_pDataList->PointToDataHead();//取得数据队列头
				if (pPack != NULL)
				{
					//记住缓存块内的偏移
					m_ulPositionInPack = dwBytesToRead - dwHaveRead;

					//NOTE:CE不支持CopyMemory,by XQF 2007-5-1(CE下考虑Memcpy)
					//把未播放的数据移动到(pbBuffer + dwHaveRead)的开头
					CopyMemory((PVOID)(pbBuffer + dwHaveRead), 
						(PVOID)(pPack), (SIZE_T)m_ulPositionInPack);

					//修改已经读取的字节数
					dwHaveRead += m_ulPositionInPack;
				}
				else if (m_pDataList->IsFlushing())
				{
					return E_FAIL;
				}
				else 
				{
					Sleep(10);
				}
			}
		}
		*pdwBytesRead = dwBytesToRead;

		return S_OK;
    }

	//数据流总长度以及当前可以获得的数据长度
    LONGLONG Size(LONGLONG *pSizeAvailable)
    {
        *pSizeAvailable = m_llLength;
        return 0x7fffffffff; //不知道服务器要发送多少数据,则取一个很大值
    }

    DWORD Alignment()
    {
        return 1; //数据按1字节对齐
    }
    //NOTE:CE下为Bool Lock() by XQF 2007-5-1
	//数据读取操作同步--锁定/解锁
    void Lock()//获取访问临界区的权利
    {
        m_csLock.Lock();
    }
    //NOTE:CE下为Bool UnLock() by XQF 2007-5-1
    void Unlock()//释放临界区对象
    {
        m_csLock.Unlock();
    }

	void AddAvailableLength(LONGLONG inLength)
	{
		m_llLength += inLength;
	}
};

class CMemReader : public CAsyncReader
{
public:

    //  We're not going to be CoCreate'd so we don't need registration
    //  stuff etc
    STDMETHODIMP Register()
    {
        return S_OK;
    }
    STDMETHODIMP Unregister()
    {
        return S_OK;
    }

	//指定从CMemStream中读取数据
    CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) :
        CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr)
    {
        m_mt = *pmt;
    }
};

#endif  // __MemFilter_h__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -