|
|
最近在用DirectShow播放缓冲区内容时遇到了奇怪的问题,百思不得其解。
我用DirectShow的例子MEMFile改写了一个播放缓冲区内容的播放器,从网络获取数据,写入一个循环缓冲区,然后当DS需要数据时就从缓冲区取数据进行填充,也就是“拉”的模式。
我的缓冲区是20M,先缓冲满缓冲区(如果文件大于缓冲区的话,也就是预缓冲),然后进行播放,播放过程中在适当的时候在进行缓冲。
现在情况是:预缓冲成功完成,并且可以开始播放,但是播放几分钟后就会出现错误“First-chance exception in Peer.exe (XVIDCORE.DLL): 0xC0000005: Access Violation”。这几分钟肯定没有把预缓冲的20M播放完,并且每次出错的位置都不一样。
我实在想不出其中原因。如果哪位遇到过类似的问题,还望给予指教,在此表示感谢!
相关代码大概列出:
HRESULT CMemStream::Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
CAutoLock lck(&m_csLock);
DWORD dwReadLength = 0;
/* Wait until the bytes are here! */
DWORD dwTime = timeGetTime();
if (m_llPosition + dwBytesToRead > m_llLength) {
dwReadLength = (DWORD)(m_llLength - m_llPosition);
} else {
dwReadLength = dwBytesToRead;
}
DWORD dwTimeToArrive =
((DWORD)m_llPosition + dwReadLength) / m_dwKBPerSec;
if (dwTime - m_dwTimeStart < dwTimeToArrive) {
Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
// copy data from my buffer to DS's buffer
int iPos = m_llPosition % BUFFER_SIZE;
if (iPos+dwReadLength > BUFFER_SIZE) {
memcpy((PVOID)pbBuffer, (PVOID)(m_pbData + iPos), (BUFFER_SIZE-iPos) );
memcpy((PVOID)pbBuffer, (PVOID)(m_pbData), (dwReadLength - (BUFFER_SIZE-iPos)) );
} else {
memcpy((PVOID)pbBuffer, (PVOID)(m_pbData + iPos), dwReadLength);
}
m_llPosition += dwReadLength;
*pdwBytesRead = dwReadLength;
// buffer when need
// ...
return S_OK;
}
|
|