00001 #include "stdafx.h"
00002 #include ".\cmmlrawsourcefilter.h"
00003
00004 CFactoryTemplate g_Templates[] =
00005 {
00006 {
00007 L"CMMLRawDemuxFilter",
00008 &CLSID_CMMLRawSourceFilter,
00009 CMMLRawSourceFilter::CreateInstance,
00010 NULL,
00011 NULL
00012 }
00013
00014 };
00015
00016
00017 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
00018
00019
00020 CUnknown* WINAPI CMMLRawSourceFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
00021 {
00022 CMMLRawSourceFilter *pNewObject = new CMMLRawSourceFilter();
00023 if (pNewObject == NULL) {
00024 *pHr = E_OUTOFMEMORY;
00025 }
00026 return pNewObject;
00027 }
00028
00029 STDMETHODIMP CMMLRawSourceFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00030 {
00031 if (riid == IID_IFileSourceFilter) {
00032 *ppv = (IFileSourceFilter*)this;
00033 ((IUnknown*)*ppv)->AddRef();
00034 return NOERROR;
00035 }
00036 return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
00037 }
00038
00039 CMMLRawSourceFilter::CMMLRawSourceFilter(void)
00040 : CBaseFilter(NAME("CMMLRawSourceFilter"), NULL, m_pLock, CLSID_CMMLRawSourceFilter)
00041 , mCMMLDoc(NULL)
00042 , mUptoTag(0)
00043 {
00044 m_pLock = new CCritSec;
00045 mCMMLSourcePin = new CMMLRawSourcePin( this
00046 , this->m_pLock);
00047
00048
00049
00050 }
00051
00052 CMMLRawSourceFilter::~CMMLRawSourceFilter(void)
00053 {
00054
00055 delete mCMMLSourcePin;
00056 delete mCMMLDoc;
00057 delete m_pLock;
00058 }
00059
00060
00061 int CMMLRawSourceFilter::GetPinCount() {
00062 return 1;
00063 }
00064 CBasePin* CMMLRawSourceFilter::GetPin(int inPinNo) {
00065
00066 if (inPinNo == 0) {
00067 return mCMMLSourcePin;
00068 } else {
00069 return NULL;
00070 }
00071 }
00072
00073
00074 ULONG CMMLRawSourceFilter::GetMiscFlags(void) {
00075 return AM_FILTER_MISC_FLAGS_IS_SOURCE;
00076 }
00077
00078
00079 STDMETHODIMP CMMLRawSourceFilter::GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType) {
00080
00081
00082
00083 LPOLESTR x = SysAllocString(mFileName.c_str());
00084 *outFileName = x;
00085
00086 return S_OK;
00087 }
00088
00089
00090 STDMETHODIMP CMMLRawSourceFilter::Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType) {
00091
00092 CAutoLock locLock(m_pLock);
00093 mFileName = inFileName;
00094
00095 delete mCMMLDoc;
00096 mCMMLDoc = new C_CMMLDoc;
00097 bool retVal = mCMMLParser.parseDocFromFile(mFileName, mCMMLDoc);
00098
00099 mUptoTag = -1;
00100
00101 if (retVal) {
00102 return S_OK;
00103 } else {
00104 return S_FALSE;
00105 }
00106
00107
00108 }
00109
00110
00111 DWORD CMMLRawSourceFilter::ThreadProc(void) {
00112
00113
00114 while(true) {
00115 DWORD locThreadCommand = GetRequest();
00116
00117 switch(locThreadCommand) {
00118 case THREAD_EXIT:
00119
00120 Reply(S_OK);
00121 return S_OK;
00122
00123 case THREAD_RUN:
00124
00125 Reply(S_OK);
00126 DataProcessLoop();
00127 break;
00128 }
00129
00130 }
00131 return S_OK;
00132 }
00133
00134
00135 HRESULT CMMLRawSourceFilter::DataProcessLoop()
00136 {
00137 C_ClipTag* locClip = NULL;
00138 DWORD locCommand = 0;
00139 while(true) {
00140 if(CheckRequest(&locCommand) == TRUE) {
00141
00142 return S_OK;
00143 }
00144
00145 if (mUptoTag == -1) {
00146
00147 mCMMLSourcePin->deliverTag(mCMMLDoc->root()->head());
00148 } else if (mUptoTag < mCMMLDoc->root()->clipList()->numTags()) {
00149
00150 locClip = mCMMLDoc->root()->clipList()->getTag(mUptoTag);
00151
00152 wstring locTrackName = locClip->track();
00153
00154 if (locTrackName == L"") {
00155 locTrackName = L"default";
00156 }
00157
00158
00159 tTrackMap::iterator locIt = mTrackMap.find(locTrackName);
00160 if (locIt != mTrackMap.end()) {
00161
00162
00163
00164
00165
00166
00167 C_TimeStamp locStamp;
00168 locStamp.parseTimeStamp(StringHelper::toNarrowStr(locClip->start()));
00169 __int64 locStartTime = locStamp.toHunNanos();
00170
00171
00172 if (locStartTime <= locIt->second) {
00173
00174
00175 mTrackMap.erase(locIt);
00176
00177 } else {
00178
00179
00180 C_ClipTag* locEndTag = new C_ClipTag;
00181 locEndTag->setStart(StringHelper::toWStr(StringHelper::numToString(locIt->second)));
00182 locEndTag->setTrack(locTrackName);
00183 mCMMLSourcePin->deliverTag(locEndTag);
00184
00185
00186 mTrackMap.erase(locIt);
00187 }
00188 }
00189
00190
00191
00192 if (locClip->end() != L"") {
00193
00194
00195
00196
00197 C_TimeStamp locStamp;
00198 locStamp.parseTimeStamp(StringHelper::toNarrowStr(locClip->end()));
00199 __int64 locEndTime = locStamp.toHunNanos();
00200
00201
00202 mTrackMap.insert(tTrackMap::value_type(locTrackName, locEndTime));
00203 }
00204
00205 mCMMLSourcePin->deliverTag(locClip);
00206 } else {
00207 mCMMLSourcePin->DeliverEndOfStream();
00208 return S_OK;
00209 }
00210 mUptoTag++;
00211
00212 }
00213 return S_OK;
00214
00215 }
00216
00217 STDMETHODIMP CMMLRawSourceFilter::Run(REFERENCE_TIME tStart) {
00218 CAutoLock locLock(m_pLock);
00219 return CBaseFilter::Run(tStart);
00220 }
00221 STDMETHODIMP CMMLRawSourceFilter::Pause(void) {
00222 CAutoLock locLock(m_pLock);
00223 if (m_State == State_Stopped) {
00224 if (ThreadExists() == FALSE) {
00225 Create();
00226 }
00227 CallWorker(THREAD_RUN);
00228 }
00229
00230 HRESULT locHR = CBaseFilter::Pause();
00231 return locHR;
00232
00233 }
00234 STDMETHODIMP CMMLRawSourceFilter::Stop(void) {
00235 CAutoLock locLock(m_pLock);
00236 CallWorker(THREAD_EXIT);
00237 Close();
00238
00239
00240 mUptoTag = -1;
00241 mCMMLSourcePin->DeliverBeginFlush();
00242 mCMMLSourcePin->DeliverEndFlush();
00243 return CBaseFilter::Stop();
00244 }