📄 memfilter.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 + -