给个修改后的memfile.h你看看吧.
这个问题我只能回答到这里了.SORRY
#include <dshow.h>
#include <streams.h>
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
class CMemStream : public CAsyncStream
{
public:
CMemStream(LPBYTE pbData, LONGLONG llLength, DWORD dwKBPerSec = INFINITE) :
m_pbData(pbData),
m_llLength(llLength),
m_rllPosition(0),
m_dwKBPerSec(dwKBPerSec)
{
m_dwTimeStart = timeGetTime();
clearPlayBuf();
m_packetsize = 1024*32;
m_packetnum = 32; //1M
m_playbufsize = m_packetsize * m_packetnum;
m_playbuf = new BYTE[m_playbufsize];
m_llLength = 4000000000000;
m_fileheadsize = m_packetsize * 10;
hMutex = CreateMutex(NULL,FALSE,"protect buf");
m_bheadover = FALSE;
m_breadnum = 0;
hLogFile = fopen("log.txt","w+");
}
~CMemStream()
{
clearPlayBuf();
delete m_playbuf;
fclose(hLogFile);
}
HRESULT Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
CAutoLock lck(&m_csLock);
DWORD dwReadLength;
dwReadLength = dwBytesToRead;
//当没有处理完播放头的时候处于等待状态
if(!m_bheadover)
{
while(m_a_fw < m_fileheadsize)
{
fprintf(hLogFile,"Wait Head/n");
Sleep(100);
}
}
m_bheadover = TRUE;
while(CanR()==false)
{
fprintf(hLogFile,"CanR=false");
Sleep(100);
}
fprintf(hLogFile,"/n");
m_rllPosition = m_a_fr % m_playbufsize;
//fprintf(hLogFile,"Read:m_rllPosition=%d/n",m_rllPosition);
//fprintf(hLogFile,"Read:m_wllPosition=%d/n/n",m_wllPosition);
//读取缓冲区数据并播放
WaitForSingleObject(hMutex,INFINITE);
CopyMemory((PVOID)pbBuffer,
(PVOID)(m_playbuf+m_rllPosition),
dwReadLength);
ReleaseMutex(hMutex);
m_a_fr += dwReadLength;
*pdwBytesRead = dwReadLength;
return S_OK;
}
bool Write(PBYTE buf)
{
if(CanW()==false)
{
fprintf(hLogFile,"CanW=false");
return false;
}
fprintf(hLogFile,"/n");
m_wllPosition = m_a_fw % m_playbufsize;
//fprintf(hLogFile,"Write:m_rllPosition=%d/n",m_rllPosition);
//fprintf(hLogFile,"Write:m_wllPosition=%d/n/n",m_wllPosition);
//添加新的数据进缓冲区
WaitForSingleObject(hMutex,INFINITE);
CopyMemory((PVOID)(m_playbuf+m_wllPosition),
(PVOID)buf,
m_packetsize);
ReleaseMutex(hMutex);
m_a_fw += m_packetsize;
return true;
}
ULONG getPacketSize()
{
return m_packetsize;
}
HRESULT SetPointer(LONGLONG llPos)
{
if (llPos < 0 || llPos > m_llLength) {
return S_FALSE;
} else
{
//关键,过滤器要对流预读,会有一次跳回0.
//害的我调试了两天,发发牢骚,哈哈~
m_a_fr = llPos;
return S_OK;
}
}
void setFileHeadSize(ULONG fileheadsize)
{
if(fileheadsize > m_packetsize *10)
{
m_fileheadsize = fileheadsize;
}else
{
m_fileheadsize = m_packetsize*10;
}
}
LONGLONG Size(LONGLONG *pSizeAvailable)
{
LONGLONG llCurrentAvailable = Int32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec);
*pSizeAvailable = min(m_llLength, llCurrentAvailable);
return m_llLength;
}
void clearPlayBuf()
{
m_rllPosition = 0;
m_wllPosition = 0;
m_a_fr = 0;
m_a_fw = 0;
}
bool CanR()
{
if ((m_a_fw-m_a_fr)>= m_packetsize)
{
return true;
}else
{
return false;
}
}
bool CanW()
{
if ((m_a_fw-m_a_fr)<= (m_playbufsize-m_packetsize))
{
return true;
}else
{
return false;
}
}
DWORD Alignment()
{
return 1;
}
void Lock()
{
m_csLock.Lock();
}
void Unlock()
{
m_csLock.Unlock();
}
private:
CCritSec m_csLock;
const PBYTE m_pbData;
LONGLONG m_llLength;
DWORD m_dwKBPerSec;
DWORD m_dwTimeStart;
PBYTE m_playbuf; //自定义缓冲区
ULONG m_playbufsize;
//自定义缓冲区大小
ULONG m_packetsize; //一帧的大小
ULONG m_packetnum; //缓冲区中帧的数量
ULONG m_wllPosition;
//相对写地址
ULONG m_rllPosition;
//相对读地址
LONGLONG m_a_fr; //绝对读地址
LONGLONG m_a_fw; //绝对写地址
HANDLE hMutex; //关键段保护
ULONG m_fileheadsize; //要预读的文件头大小
BOOL m_bheadover; //时候读完头
ULONG m_breadnum; //流指针跳回0的次数
FILE *hLogFile;
};
class CMemReader : public CAsyncReader
{
public:
STDMETHODIMP Register()
{
return S_OK;
}
STDMETHODIMP Unregister()
{
return S_OK;
}
CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) :
CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr)
{
m_mt = *pmt;
}
};