📄 mspool.cpp
字号:
AM_MEDIA_TYPE ** ppMediaType
)
{
if (ppMediaType == NULL) {
return E_POINTER ;
}
if ((m_dwFlags & SAMPLE_TYPECHANGED) == 0) {
ASSERT (m_pMediaType == NULL) ;
(* ppMediaType) = NULL ;
return S_FALSE ;
}
ASSERT (m_pMediaType != NULL) ;
(* ppMediaType) = CreateMediaType (m_pMediaType) ;
if (* ppMediaType) {
return E_OUTOFMEMORY ;
}
return S_OK ;
}
STDMETHODIMP
CTSMediaSample::SetMediaType (
AM_MEDIA_TYPE * pMediaType
)
{
if (m_pMediaType != NULL) {
DeleteMediaType (m_pMediaType) ;
m_pMediaType = NULL ;
}
// explicitely being cleared
if (pMediaType == NULL) {
m_dwFlags &= ~SAMPLE_TYPECHANGED ;
return S_OK ;
}
m_pMediaType = CreateMediaType (pMediaType) ;
if (m_pMediaType == NULL) {
m_dwFlags &= ~SAMPLE_TYPECHANGED ;
return E_OUTOFMEMORY ;
}
m_dwFlags |= SAMPLE_TYPECHANGED ;
return S_OK ;
}
// returns S_OK if there is a discontinuity in the data (this frame is
// not a continuation of the previous stream of data
// - there has been a seek or some dropped samples).
STDMETHODIMP
CTSMediaSample::IsDiscontinuity (
)
{
return (m_dwFlags & SAMPLE_DISCONTINUITY) ? S_OK : S_FALSE ;
}
// set the discontinuity property - TRUE if this sample is not a
// continuation, but a new sample after a seek or a dropped sample.
STDMETHODIMP
CTSMediaSample::SetDiscontinuity (
BOOL bDiscontinuity
)
{
if (bDiscontinuity) {
m_dwFlags |= SAMPLE_DISCONTINUITY ;
}
else {
m_dwFlags &= ~SAMPLE_DISCONTINUITY ;
}
return S_OK ;
}
// get the media times for this sample
STDMETHODIMP
CTSMediaSample::GetMediaTime (
OUT LONGLONG * pTimeStart,
OUT LONGLONG * pTimeEnd
)
{
if ((m_dwFlags & SAMPLE_MEDIATIMEVALID) == 0) {
return VFW_E_MEDIA_TIME_NOT_SET ;
}
if (pTimeStart == NULL ||
pTimeEnd == NULL) {
return E_POINTER ;
}
(* pTimeStart) = m_llMediaStart ;
(* pTimeEnd) = m_llMediaEnd ;
return S_OK ;
}
// Set the media times for this sample
// pTimeStart==pTimeEnd==NULL will invalidate the media time stamps in
// this sample
STDMETHODIMP
CTSMediaSample::SetMediaTime (
IN LONGLONG * pTimeStart,
IN LONGLONG * pTimeEnd
)
{
// caller is explicitely clearing the media time
if (pTimeStart == NULL) {
// toggle the bit OFF
m_dwFlags &= ~SAMPLE_MEDIATIMEVALID ;
return S_OK ;
}
if (pTimeEnd == NULL) {
return E_POINTER ;
}
// toggle the bit ON
m_dwFlags |= SAMPLE_MEDIATIMEVALID ;
// and save the times
m_rtStart = (* pTimeStart) ;
m_rtEnd = (* pTimeEnd) ;
return S_OK ;
}
// -------------------------------------------------------------------
// IMediaSample methods
// Set and get properties (IMediaSample2)
STDMETHODIMP
CTSMediaSample::GetProperties (
IN DWORD cbProperties,
OUT BYTE * pbProperties
)
{
AM_SAMPLE2_PROPERTIES Props ;
HRESULT hr ;
hr = S_OK ;
if (cbProperties > 0) {
if (pbProperties) {
Props.cbData = Min <DWORD> (cbProperties, sizeof Props) ;
Props.dwSampleFlags = m_dwFlags & ~SAMPLE_VALIDFLAGS ;
Props.dwTypeSpecificFlags = m_dwTypeSpecificFlags ;
Props.pbBuffer = m_pbPayload ;
Props.cbBuffer = m_lActual ; // same as actual
Props.lActual = m_lActual ;
Props.tStart = m_rtStart ;
Props.tStop = m_rtEnd ;
Props.dwStreamId = m_dwStreamId ;
if (m_dwFlags & AM_SAMPLE_TYPECHANGED) {
Props.pMediaType = m_pMediaType ;
} else {
Props.pMediaType = NULL ;
}
memcpy (pbProperties, & Props, Props.cbData) ;
}
else {
hr = E_POINTER ;
}
}
return hr ;
}
STDMETHODIMP
CTSMediaSample::SetProperties (
IN DWORD cbProperties,
IN const BYTE * pbProperties
)
{
return E_NOTIMPL ;
}
// ---------------------------------------------------------------------------
// CTSMediaSamplePool
// ---------------------------------------------------------------------------
CTSMediaSamplePool::CTSMediaSamplePool (
IN DWORD dwPoolSize,
IN CNetworkReceiverFilter * pHostingFilter,
OUT HRESULT * phr
) : m_hEvent (NULL),
m_dwPoolSize (0),
m_pHostingFilter (pHostingFilter)
{
CTSMediaSample * pMS ;
DWORD dw ;
ASSERT (m_pHostingFilter) ;
InitializeListHead (& m_leMSPool) ;
InitializeCriticalSection (& m_crt) ;
ASSERT (dwPoolSize > 0) ;
m_hEvent = CreateEvent (NULL, TRUE, TRUE, NULL) ;
if (m_hEvent == NULL) {
dw = GetLastError () ;
(* phr) = HRESULT_FROM_WIN32 (dw) ;
return ;
}
for (m_dwPoolSize = 0; m_dwPoolSize < dwPoolSize; m_dwPoolSize++) {
pMS = new CTSMediaSample (this) ;
if (pMS == NULL) {
(* phr) = E_OUTOFMEMORY ;
return ;
}
InsertHeadList (& m_leMSPool, & pMS -> m_ListEntry) ;
}
ASSERT (m_dwPoolSize > 0) ;
}
CTSMediaSamplePool::~CTSMediaSamplePool (
)
{
DWORD i ;
LIST_ENTRY * pListEntry ;
CTSMediaSample * pMS ;
for (i = 0; i < m_dwPoolSize; i++) {
ASSERT (!IsListEmpty (& m_leMSPool)) ;
pListEntry = RemoveHeadList (& m_leMSPool) ;
pMS = CONTAINING_RECORD (pListEntry, CTSMediaSample, m_ListEntry) ;
delete pMS ;
}
ASSERT (IsListEmpty (& m_leMSPool)) ;
DeleteCriticalSection (& m_crt) ;
}
void
CTSMediaSamplePool::RecycleMS (
IN CTSMediaSample * pMS
)
{
ASSERT (pMS) ;
Lock_ () ;
// always signal the event
SetEvent (m_hEvent) ;
InsertHeadList (& m_leMSPool, & pMS -> m_ListEntry) ;
// media sample's ref to the filter
m_pHostingFilter -> Release () ;
Unlock_ () ;
}
HRESULT
CTSMediaSamplePool::GetMediaSample_ (
IN CBuffer * pBuffer,
IN BYTE * pbPayload,
IN int iPayloadLength,
IN LONGLONG * pllMediaStart,
IN LONGLONG * pllMediaEnd,
IN REFERENCE_TIME * prtStart,
IN REFERENCE_TIME * prtEnd,
IN DWORD dwMediaSampleFlags,
OUT IMediaSample2 ** ppMS
)
{
CTSMediaSample * pTSMS ;
LIST_ENTRY * pListEntry ;
ASSERT (pllMediaStart) ;
ASSERT (pllMediaEnd) ;
ASSERT (prtStart) ;
ASSERT (prtEnd) ;
Lock_ () ;
// while the list is empty, non-signal the event and wait for a media
// sample
while (IsListEmpty (& m_leMSPool)) {
// media sample list is empty; setup to wait
// non-signal the event
ResetEvent (m_hEvent) ;
// release the lock and wait
Unlock_ () ;
WaitForSingleObject (m_hEvent, INFINITE) ;
// event has been signaled; reaquire the lock
Lock_ () ;
}
// remove the head of the media sample list
pListEntry = RemoveHeadList (& m_leMSPool) ;
pTSMS = CONTAINING_RECORD (pListEntry, CTSMediaSample, m_ListEntry) ;
// media sample's ref to the filter (so the filter does not get deleted
// while media samples are outstanding)
m_pHostingFilter -> AddRef () ;
// we have the media sample and have addref'd the filter, so we can
// now release the lock
Unlock_ () ;
// set the caller's ref
ASSERT (pTSMS) ;
pTSMS -> AddRef () ;
// assert we're within the bounds of the io block
ASSERT (pBuffer -> GetBuffer () <= pbPayload &&
pbPayload + iPayloadLength <= pBuffer -> GetBuffer () + pBuffer -> GetBufferLength ()) ;
// init the media sample wrapper
pTSMS -> Init (
pBuffer,
pbPayload,
iPayloadLength,
pllMediaStart,
pllMediaEnd,
prtStart,
prtEnd,
dwMediaSampleFlags
) ;
// set the outgoing parameter
(* ppMS) = pTSMS ;
return S_OK ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -