d***@gmail.com
2007-07-04 16:32:21 UTC
Hello,
I have a problem with seeking implementation in my custom source
filter.
After this code:
m_pMediaControl->Pause();
LONGLONG qwNewPosition = 0;
m_pMediaSeeking->SetPositions(&qwNewPosition,
AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
I see the sample #1.
I found that my
UpdateFromSeek function calls FillBuffer twice: after
DeliverBeginFlush()
and after Run(). Why ?
The source code:
void CStreamSourceVideo::UpdateFromSeek()
{
if (ThreadExists())
{
DeliverBeginFlush();
Stop();
DeliverEndFlush();
Run();
}
}
HRESULT CStreamSourceVideo::OnThreadStartPlay()
{
m_bDiscontinuity = TRUE;
return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
}
HRESULT CStreamSourceVideo::ChangeStart( )
{
{
CAutoLock lock(CSourceSeeking::m_pLock);
m_rtSampleTime = 0; // Reset the time stamps.
m_rtMediaTime = m_rtStart; // Reset the media times.
}
UpdateFromSeek();
return S_OK;
}
HRESULT CStreamSourceVideo::ChangeStop( )
{
CAutoLock lock(CSourceSeeking::m_pLock);
if (m_rtMediaTime < m_rtStop)
{
return S_OK;
}
UpdateFromSeek();
return S_OK;
}
STDMETHODIMP CStreamSourceVideo::Notify(IBaseFilter *pSelf, Quality
q)
{
return E_FAIL;
}
HRESULT CStreamSourceVideo::FillBuffer(IMediaSample *pSample)
{
HRESULT hr;
BYTE *pBuffer;
long lSize;
CAutoLock lock(m_pFilter->pStateLock());
CMediaType *pmt = NULL;
hr = pSample->GetMediaType((AM_MEDIA_TYPE**)&pmt);
if (hr == S_OK)
{
SetMediaType(pmt);
DeleteMediaType(pmt);
}
ASSERT(m_mt.formattype == FORMAT_VideoInfo);
ASSERT(m_mt.cbFormat >= sizeof(VIDEOINFOHEADER));
VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*) m_mt.pbFormat;
Ipp32u dwLineStep = pvi->bmiHeader.biWidth * 2;
pSample->GetPointer(&pBuffer);
lSize = pSample->GetSize();
if (m_rtMediaTime >= m_rtStop)
{
return S_FALSE;
}
REFERENCE_TIME rtStart, rtStop;
rtStart = static_cast<REFERENCE_TIME>(m_rtSampleTime /
m_dRateSeeking);
rtStop = rtStart + static_cast<int>(m_rtFrameLength /
m_dRateSeeking);
pSample->SetTime(&rtStart, &rtStop);
QWORD qwCurrentSample = m_rtMediaTime / m_rtFrameLength;
m_rtSampleTime += m_rtFrameLength;
m_rtMediaTime += m_rtFrameLength;
pSample->SetSyncPoint(TRUE);
if (m_bDiscontinuity)
{
pSample->SetDiscontinuity(TRUE);
m_bDiscontinuity = FALSE;
}
return NOERROR;
}
HRESULT CStreamSourceVideo::OnThreadCreate(void)
{
m_rtSampleTime = 0; // Reset the time stamps.
m_rtMediaTime = m_rtStart; // Reset the media times.
return NOERROR;
I have a problem with seeking implementation in my custom source
filter.
After this code:
m_pMediaControl->Pause();
LONGLONG qwNewPosition = 0;
m_pMediaSeeking->SetPositions(&qwNewPosition,
AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
I see the sample #1.
I found that my
UpdateFromSeek function calls FillBuffer twice: after
DeliverBeginFlush()
and after Run(). Why ?
The source code:
void CStreamSourceVideo::UpdateFromSeek()
{
if (ThreadExists())
{
DeliverBeginFlush();
Stop();
DeliverEndFlush();
Run();
}
}
HRESULT CStreamSourceVideo::OnThreadStartPlay()
{
m_bDiscontinuity = TRUE;
return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
}
HRESULT CStreamSourceVideo::ChangeStart( )
{
{
CAutoLock lock(CSourceSeeking::m_pLock);
m_rtSampleTime = 0; // Reset the time stamps.
m_rtMediaTime = m_rtStart; // Reset the media times.
}
UpdateFromSeek();
return S_OK;
}
HRESULT CStreamSourceVideo::ChangeStop( )
{
CAutoLock lock(CSourceSeeking::m_pLock);
if (m_rtMediaTime < m_rtStop)
{
return S_OK;
}
UpdateFromSeek();
return S_OK;
}
STDMETHODIMP CStreamSourceVideo::Notify(IBaseFilter *pSelf, Quality
q)
{
return E_FAIL;
}
HRESULT CStreamSourceVideo::FillBuffer(IMediaSample *pSample)
{
HRESULT hr;
BYTE *pBuffer;
long lSize;
CAutoLock lock(m_pFilter->pStateLock());
CMediaType *pmt = NULL;
hr = pSample->GetMediaType((AM_MEDIA_TYPE**)&pmt);
if (hr == S_OK)
{
SetMediaType(pmt);
DeleteMediaType(pmt);
}
ASSERT(m_mt.formattype == FORMAT_VideoInfo);
ASSERT(m_mt.cbFormat >= sizeof(VIDEOINFOHEADER));
VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*) m_mt.pbFormat;
Ipp32u dwLineStep = pvi->bmiHeader.biWidth * 2;
pSample->GetPointer(&pBuffer);
lSize = pSample->GetSize();
if (m_rtMediaTime >= m_rtStop)
{
return S_FALSE;
}
REFERENCE_TIME rtStart, rtStop;
rtStart = static_cast<REFERENCE_TIME>(m_rtSampleTime /
m_dRateSeeking);
rtStop = rtStart + static_cast<int>(m_rtFrameLength /
m_dRateSeeking);
pSample->SetTime(&rtStart, &rtStop);
QWORD qwCurrentSample = m_rtMediaTime / m_rtFrameLength;
m_rtSampleTime += m_rtFrameLength;
m_rtMediaTime += m_rtFrameLength;
pSample->SetSyncPoint(TRUE);
if (m_bDiscontinuity)
{
pSample->SetDiscontinuity(TRUE);
m_bDiscontinuity = FALSE;
}
return NOERROR;
}
HRESULT CStreamSourceVideo::OnThreadCreate(void)
{
m_rtSampleTime = 0; // Reset the time stamps.
m_rtMediaTime = m_rtStart; // Reset the media times.
return NOERROR;