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 "DSMSplitter.h"
00024 #include "..\..\..\DSUtil\DSUtil.h"
00025
00026 #include <initguid.h>
00027 #include "..\..\..\..\include\moreuuids.h"
00028
00029 #ifdef REGISTER_FILTER
00030
00031 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00032 {
00033 {&MEDIATYPE_Stream, &MEDIASUBTYPE_DirectShowMedia},
00034 {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL},
00035 };
00036
00037 const AMOVIESETUP_PIN sudpPins[] =
00038 {
00039 {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00040 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
00041 };
00042
00043 const AMOVIESETUP_FILTER sudFilter[] =
00044 {
00045 {&__uuidof(CDSMSplitterFilter), L"DSM Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins},
00046 {&__uuidof(CDSMSourceFilter), L"DSM Source", MERIT_NORMAL, 0, NULL},
00047 };
00048
00049 CFactoryTemplate g_Templates[] =
00050 {
00051 {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDSMSplitterFilter>, NULL, &sudFilter[0]},
00052 {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CDSMSourceFilter>, NULL, &sudFilter[1]},
00053 };
00054
00055 int g_cTemplates = countof(g_Templates);
00056
00057 STDAPI DllRegisterServer()
00058 {
00059 CString str;
00060 str.Format(_T("0,%d,,%%0%dI64x"), DSMSW_SIZE, DSMSW_SIZE*2);
00061 str.Format(CString(str), DSMSW);
00062
00063 RegisterSourceFilter(
00064 CLSID_AsyncReader,
00065 MEDIASUBTYPE_DirectShowMedia,
00066 str, NULL);
00067
00068 return AMovieDllRegisterServer2(TRUE);
00069 }
00070
00071 STDAPI DllUnregisterServer()
00072 {
00073 UnRegisterSourceFilter(MEDIASUBTYPE_DirectShowMedia);
00074
00075 return AMovieDllRegisterServer2(FALSE);
00076 }
00077
00078 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00079
00080 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00081 {
00082 return DllEntryPoint((HINSTANCE)hModule, dwReason, 0);
00083 }
00084
00085 #endif
00086
00087
00088
00089
00090
00091 CDSMSplitterFilter::CDSMSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
00092 : CBaseSplitterFilter(NAME("CDSMSplitterFilter"), pUnk, phr, __uuidof(this))
00093 {
00094 }
00095
00096 CDSMSplitterFilter::~CDSMSplitterFilter()
00097 {
00098 }
00099
00100 static int compare_id(const void* id1, const void* id2) {return (int)*(BYTE*)id1 - (int)*(BYTE*)id2;}
00101
00102 HRESULT CDSMSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
00103 {
00104 CheckPointer(pAsyncReader, E_POINTER);
00105
00106 HRESULT hr = E_FAIL;
00107
00108 m_pFile.Free();
00109 m_pFile.Attach(new CDSMSplitterFile(pAsyncReader, hr, *this, *this));
00110 if(!m_pFile) return E_OUTOFMEMORY;
00111 if(FAILED(hr)) {m_pFile.Free(); return hr;}
00112
00113 m_rtNewStart = m_rtCurrent = 0;
00114 m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->m_rtDuration;
00115
00116 CArray<BYTE> ids;
00117
00118 POSITION pos = m_pFile->m_mts.GetStartPosition();
00119 while(pos)
00120 {
00121 BYTE id;
00122 CMediaType mt;
00123 m_pFile->m_mts.GetNextAssoc(pos, id, mt);
00124 ids.Add(id);
00125 }
00126
00127 qsort(ids.GetData(), ids.GetCount(), sizeof(BYTE), compare_id);
00128
00129 for(int i = 0; i < ids.GetCount(); i++)
00130 {
00131 BYTE id = ids[i];
00132 CMediaType& mt = m_pFile->m_mts[id];
00133
00134 CStringW name, lang;
00135 name.Format(L"Output %02d", id);
00136
00137 CArray<CMediaType> mts;
00138 mts.Add(mt);
00139
00140 CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, name, this, this, &hr));
00141
00142 name.Empty();
00143
00144 pos = m_pFile->m_sim[id].GetStartPosition();
00145 while(pos)
00146 {
00147 CStringA key; CStringW value;
00148 m_pFile->m_sim[id].GetNextAssoc(pos, key, value);
00149 pPinOut->SetProperty(CStringW(key), value);
00150
00151 if(key == "NAME") name = value;
00152 if(key == "LANG") if((lang = ISO6392ToLanguage(CStringA(CString(value)))).IsEmpty()) lang = value;
00153 }
00154
00155 if(!name.IsEmpty() || !lang.IsEmpty())
00156 {
00157 if(!name.IsEmpty()) {if(!lang.IsEmpty()) name += L" (" + lang + L")";}
00158 else if(!lang.IsEmpty()) name = lang;
00159 pPinOut->SetName(name);
00160 }
00161
00162 EXECUTE_ASSERT(SUCCEEDED(AddOutputPin(id, pPinOut)));
00163 }
00164
00165 pos = m_pFile->m_fim.GetStartPosition();
00166 while(pos)
00167 {
00168 CStringA key; CStringW value;
00169 m_pFile->m_fim.GetNextAssoc(pos, key, value);
00170 SetProperty(CStringW(key), value);
00171 }
00172
00173 for(int i = 0; i < m_resources.GetCount(); i++)
00174 {
00175 const CDSMResource& r = m_resources[i];
00176 if(r.mime == "application/x-truetype-font")
00177 m_fontinst.InstallFont(r.data);
00178 }
00179
00180 return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
00181 }
00182
00183 bool CDSMSplitterFilter::DemuxInit()
00184 {
00185 return(true);
00186 }
00187
00188 void CDSMSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
00189 {
00190 m_pFile->Seek(m_pFile->FindSyncPoint(rt));
00191 }
00192
00193 bool CDSMSplitterFilter::DemuxLoop()
00194 {
00195 HRESULT hr = S_OK;
00196
00197 while(SUCCEEDED(hr) && !CheckRequest(NULL) && m_pFile->GetPos() < m_pFile->GetLength())
00198 {
00199 dsmp_t type;
00200 UINT64 len;
00201
00202 if(!m_pFile->Sync(type, len))
00203 continue;
00204
00205 __int64 pos = m_pFile->GetPos();
00206
00207 if(type == DSMP_SAMPLE)
00208 {
00209 CAutoPtr<Packet> p(new Packet());
00210 if(m_pFile->Read(len, p))
00211 {
00212 if(p->rtStart != Packet::INVALID_TIME)
00213 {
00214 p->rtStart -= m_pFile->m_rtFirst;
00215 p->rtStop -= m_pFile->m_rtFirst;
00216 }
00217
00218 hr = DeliverPacket(p);
00219 }
00220 }
00221
00222 m_pFile->Seek(pos + len);
00223 }
00224
00225 return(true);
00226 }
00227
00228
00229
00230 STDMETHODIMP CDSMSplitterFilter::GetKeyFrameCount(UINT& nKFs)
00231 {
00232 CheckPointer(m_pFile, E_UNEXPECTED);
00233 nKFs = m_pFile->m_sps.GetCount();
00234 return S_OK;
00235 }
00236
00237 STDMETHODIMP CDSMSplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs)
00238 {
00239 CheckPointer(pFormat, E_POINTER);
00240 CheckPointer(pKFs, E_POINTER);
00241 CheckPointer(m_pFile, E_UNEXPECTED);
00242
00243 if(*pFormat != TIME_FORMAT_MEDIA_TIME) return E_INVALIDARG;
00244
00245
00246 for(nKFs = 0; nKFs < m_pFile->m_sps.GetCount(); nKFs++)
00247 pKFs[nKFs] = m_pFile->m_sps[nKFs].rt;
00248
00249 return S_OK;
00250 }
00251
00252
00253
00254
00255
00256 CDSMSourceFilter::CDSMSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
00257 : CDSMSplitterFilter(pUnk, phr)
00258 {
00259 m_clsid = __uuidof(this);
00260 m_pInput.Free();
00261 }