00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include <mmreg.h>
00024 #include "BaseMuxer.h"
00025 #include "..\..\..\DSUtil\DSUtil.h"
00026 #include "..\..\..\..\include\moreuuids.h"
00027
00028 #include <initguid.h>
00029 #include "..\..\..\..\include\ogg\OggDS.h"
00030
00031 #define MAXQUEUESIZE 100
00032
00033
00034
00035
00036
00037 CBaseMuxerInputPin::CBaseMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
00038 : CBaseInputPin(NAME("CBaseMuxerInputPin"), pFilter, pLock, phr, pName)
00039 , m_rtDuration(0)
00040 , m_evAcceptPacket(TRUE)
00041 {
00042 static int s_iID = 0;
00043 m_iID = s_iID++;
00044 }
00045
00046 CBaseMuxerInputPin::~CBaseMuxerInputPin()
00047 {
00048 }
00049
00050 STDMETHODIMP CBaseMuxerInputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00051 {
00052 CheckPointer(ppv, E_POINTER);
00053
00054 return
00055 QI(IPropertyBag)
00056 QI(IPropertyBag2)
00057 QI(IDSMPropertyBag)
00058 __super::NonDelegatingQueryInterface(riid, ppv);
00059 }
00060
00061 bool CBaseMuxerInputPin::IsSubtitleStream()
00062 {
00063 return m_mt.majortype == MEDIATYPE_Subtitle || m_mt.majortype == MEDIATYPE_Text;
00064 }
00065
00066 void CBaseMuxerInputPin::PushPacket(CAutoPtr<MuxerPacket> pPacket)
00067 {
00068 for(int i = 0; m_pFilter->IsActive() && !m_bFlushing
00069 && !m_evAcceptPacket.Wait(1)
00070 && i < 1000;
00071 i++);
00072
00073 if(!m_pFilter->IsActive() || m_bFlushing)
00074 return;
00075
00076 CAutoLock cAutoLock(&m_csQueue);
00077
00078 m_queue.AddTail(pPacket);
00079
00080 if(m_queue.GetCount() >= MAXQUEUESIZE)
00081 m_evAcceptPacket.Reset();
00082 }
00083
00084 CAutoPtr<MuxerPacket> CBaseMuxerInputPin::PopPacket()
00085 {
00086 CAutoPtr<MuxerPacket> pPacket;
00087
00088 CAutoLock cAutoLock(&m_csQueue);
00089
00090 if(m_queue.GetCount())
00091 pPacket = m_queue.RemoveHead();
00092 if(m_queue.GetCount() < MAXQUEUESIZE)
00093 m_evAcceptPacket.Set();
00094
00095 return pPacket;
00096 }
00097
00098 HRESULT CBaseMuxerInputPin::CheckMediaType(const CMediaType* pmt)
00099 {
00100 if(pmt->formattype == FORMAT_WaveFormatEx)
00101 {
00102 WORD wFormatTag = ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag;
00103 if((wFormatTag == WAVE_FORMAT_PCM
00104 || wFormatTag == WAVE_FORMAT_EXTENSIBLE
00105 || wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
00106 && pmt->subtype != FOURCCMap(wFormatTag)
00107 && pmt->subtype != MEDIASUBTYPE_DVD_LPCM_AUDIO
00108 && pmt->subtype != MEDIASUBTYPE_DOLBY_AC3
00109 && pmt->subtype != MEDIASUBTYPE_DTS)
00110 {
00111 return E_INVALIDARG;
00112 }
00113 }
00114
00115 return pmt->majortype == MEDIATYPE_Video
00116 || pmt->majortype == MEDIATYPE_Audio && pmt->formattype != FORMAT_VorbisFormat
00117 || pmt->majortype == MEDIATYPE_Text && pmt->subtype == MEDIASUBTYPE_NULL && pmt->formattype == FORMAT_None
00118 || pmt->majortype == MEDIATYPE_Subtitle
00119 ? S_OK
00120 : E_INVALIDARG;
00121 }
00122
00123 HRESULT CBaseMuxerInputPin::BreakConnect()
00124 {
00125 HRESULT hr = __super::BreakConnect();
00126 if(FAILED(hr)) return hr;
00127
00128 RemoveAll();
00129
00130
00131
00132 return hr;
00133 }
00134
00135 HRESULT CBaseMuxerInputPin::CompleteConnect(IPin* pReceivePin)
00136 {
00137 HRESULT hr = __super::CompleteConnect(pReceivePin);
00138 if(FAILED(hr)) return hr;
00139
00140
00141
00142 m_rtDuration = 0;
00143 CComQIPtr<IMediaSeeking> pMS;
00144 if((pMS = GetFilterFromPin(pReceivePin)) || (pMS = pReceivePin))
00145 pMS->GetDuration(&m_rtDuration);
00146
00147
00148
00149 for(CComPtr<IPin> pPin = pReceivePin; pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin)))
00150 {
00151 if(CComQIPtr<IDSMPropertyBag> pPB = pPin)
00152 {
00153 ULONG cProperties = 0;
00154 if(SUCCEEDED(pPB->CountProperties(&cProperties)) && cProperties > 0)
00155 {
00156 for(ULONG iProperty = 0; iProperty < cProperties; iProperty++)
00157 {
00158 PROPBAG2 PropBag;
00159 memset(&PropBag, 0, sizeof(PropBag));
00160 ULONG cPropertiesReturned = 0;
00161 if(FAILED(pPB->GetPropertyInfo(iProperty, 1, &PropBag, &cPropertiesReturned)))
00162 continue;
00163
00164 HRESULT hr;
00165 CComVariant var;
00166 if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
00167 SetProperty(PropBag.pstrName, &var);
00168
00169 CoTaskMemFree(PropBag.pstrName);
00170 }
00171 }
00172 }
00173 }
00174
00175 ((CBaseMuxerFilter*)m_pFilter)->AddInput();
00176
00177 return S_OK;
00178 }
00179
00180 HRESULT CBaseMuxerInputPin::Active()
00181 {
00182 m_rtMaxStart = _I64_MIN;
00183 m_fEOS = false;
00184 m_evAcceptPacket.Set();
00185 return __super::Active();
00186 }
00187
00188 HRESULT CBaseMuxerInputPin::Inactive()
00189 {
00190 CAutoLock cAutoLock(&m_csQueue);
00191 m_queue.RemoveAll();
00192 return __super::Inactive();
00193 }
00194
00195 STDMETHODIMP CBaseMuxerInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00196 {
00197 CAutoLock cAutoLock(&m_csReceive);
00198
00199 return __super::NewSegment(tStart, tStop, dRate);
00200 }
00201
00202 STDMETHODIMP CBaseMuxerInputPin::Receive(IMediaSample* pSample)
00203 {
00204 CAutoLock cAutoLock(&m_csReceive);
00205
00206 HRESULT hr = __super::Receive(pSample);
00207 if(FAILED(hr)) return hr;
00208
00209 CAutoPtr<MuxerPacket> pPacket(new MuxerPacket(this));
00210
00211 long len = pSample->GetActualDataLength();
00212
00213 BYTE* pData = NULL;
00214 if(FAILED(pSample->GetPointer(&pData)) || !pData)
00215 return S_OK;
00216
00217 pPacket->pData.SetSize(len);
00218 memcpy(pPacket->pData.GetData(), pData, len);
00219
00220 if(S_OK == pSample->IsSyncPoint() || m_mt.majortype == MEDIATYPE_Audio && !m_mt.bTemporalCompression)
00221 {
00222 pPacket->flags |= MuxerPacket::syncpoint;
00223 }
00224
00225 if(S_OK == pSample->GetTime(&pPacket->rtStart, &pPacket->rtStop))
00226 {
00227 pPacket->flags |= MuxerPacket::timevalid;
00228
00229 pPacket->rtStart += m_tStart;
00230 pPacket->rtStop += m_tStart;
00231
00232 if((pPacket->flags & MuxerPacket::syncpoint) && pPacket->rtStart < m_rtMaxStart)
00233 {
00234 pPacket->flags &= ~MuxerPacket::syncpoint;
00235 pPacket->flags |= MuxerPacket::bogus;
00236 }
00237
00238 m_rtMaxStart = max(m_rtMaxStart, pPacket->rtStart);
00239 }
00240
00241 if(S_OK == pSample->IsDiscontinuity())
00242 {
00243 pPacket->flags |= MuxerPacket::discontinuity;
00244 }
00245
00246 PushPacket(pPacket);
00247
00248 return S_OK;
00249 }
00250
00251 STDMETHODIMP CBaseMuxerInputPin::EndOfStream()
00252 {
00253 CAutoLock cAutoLock(&m_csReceive);
00254
00255 HRESULT hr = __super::EndOfStream();
00256 if(FAILED(hr)) return hr;
00257
00258 ASSERT(!m_fEOS);
00259
00260 CAutoPtr<MuxerPacket> pPacket(new MuxerPacket(this));
00261 pPacket->flags |= MuxerPacket::eos;
00262 PushPacket(pPacket);
00263
00264 m_fEOS = true;
00265
00266 return hr;
00267 }
00268