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 <initguid.h>
00025 #include "MpaSplitter.h"
00026 #include "..\..\..\..\include\moreuuids.h"
00027
00028 #ifdef REGISTER_FILTER
00029
00030 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00031 {
00032 {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
00033 {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL}
00034 };
00035
00036 const AMOVIESETUP_PIN sudpPins[] =
00037 {
00038 {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00039 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
00040 };
00041
00042 const AMOVIESETUP_FILTER sudFilter[] =
00043 {
00044 {&__uuidof(CMpaSplitterFilter), L"Mpa Splitter", MERIT_NORMAL+1, countof(sudpPins), sudpPins},
00045 {&__uuidof(CMpaSourceFilter), L"Mpa Source", MERIT_NORMAL+1, 0, NULL},
00046 };
00047
00048 CFactoryTemplate g_Templates[] =
00049 {
00050 {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CMpaSplitterFilter>, NULL, &sudFilter[0]},
00051 {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CMpaSourceFilter>, NULL, &sudFilter[1]},
00052 };
00053
00054 int g_cTemplates = countof(g_Templates);
00055
00056 STDAPI DllRegisterServer()
00057 {
00058 CList<CString> chkbytes;
00059 chkbytes.AddTail(_T("0,2,FFE0,FFE0"));
00060 chkbytes.AddTail(_T("0,10,FFFFFFFF000000000000,494433030080808080"));
00061
00062 RegisterSourceFilter(
00063 CLSID_AsyncReader,
00064 MEDIASUBTYPE_MPEG1Audio,
00065 chkbytes,
00066 NULL);
00067
00068 return AMovieDllRegisterServer2(TRUE);
00069 }
00070
00071 STDAPI DllUnregisterServer()
00072 {
00073 return AMovieDllRegisterServer2(FALSE);
00074 }
00075
00076 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00077
00078 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00079 {
00080 return DllEntryPoint((HINSTANCE)hModule, dwReason, 0);
00081 }
00082
00083 #endif
00084
00085
00086
00087
00088
00089 CMpaSplitterFilter::CMpaSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
00090 : CBaseSplitterFilter(NAME("CMpaSplitterFilter"), pUnk, phr, __uuidof(this))
00091 {
00092 }
00093
00094 STDMETHODIMP CMpaSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00095 {
00096 CheckPointer(ppv, E_POINTER);
00097
00098 return
00099 __super::NonDelegatingQueryInterface(riid, ppv);
00100 }
00101
00102 HRESULT CMpaSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
00103 {
00104 CheckPointer(pAsyncReader, E_POINTER);
00105
00106 HRESULT hr = E_FAIL;
00107
00108 m_pFile.Free();
00109
00110 m_pFile.Attach(new CMpaSplitterFile(pAsyncReader, hr));
00111 if(!m_pFile) return E_OUTOFMEMORY;
00112 if(FAILED(hr)) {m_pFile.Free(); return hr;}
00113
00114 CArray<CMediaType> mts;
00115 mts.Add(m_pFile->GetMediaType());
00116
00117 CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Audio", this, this, &hr));
00118 AddOutputPin(0, pPinOut);
00119
00120 m_rtNewStart = m_rtCurrent = 0;
00121 m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->GetDuration();
00122
00123 CString str, title;
00124 if(m_pFile->m_tags.Lookup('TIT2', str)) title = str;
00125 if(m_pFile->m_tags.Lookup('TPE1', str)) title = title.IsEmpty() ? str : str + _T(" - ") + title;
00126 if(m_pFile->m_tags.Lookup('TYER', str) && !title.IsEmpty() && !str.IsEmpty()) title += _T(" (") + str + _T(")");
00127 if(!title.IsEmpty()) SetProperty(L"TITL", CStringW(title));
00128 if(m_pFile->m_tags.Lookup('TCOP', str)) SetProperty(L"CPYR", CStringW(str));
00129 if(m_pFile->m_tags.Lookup('COMM', str)) SetProperty(L"DESC", CStringW(str));
00130
00131 return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
00132 }
00133
00134 STDMETHODIMP CMpaSplitterFilter::GetDuration(LONGLONG* pDuration)
00135 {
00136 CheckPointer(pDuration, E_POINTER);
00137 CheckPointer(m_pFile, VFW_E_NOT_CONNECTED);
00138
00139 *pDuration = m_pFile->GetDuration();
00140
00141 return S_OK;
00142 }
00143
00144 bool CMpaSplitterFilter::DemuxInit()
00145 {
00146 if(!m_pFile) return(false);
00147
00148
00149
00150 return(true);
00151 }
00152
00153 void CMpaSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
00154 {
00155 __int64 startpos = m_pFile->GetStartPos();
00156 __int64 endpos = m_pFile->GetEndPos();
00157
00158 if(rt <= 0 || m_pFile->GetDuration() <= 0)
00159 {
00160 m_pFile->Seek(startpos);
00161 m_rtStart = 0;
00162 }
00163 else
00164 {
00165 m_pFile->Seek(startpos + (__int64)((1.0 * rt / m_pFile->GetDuration()) * (endpos - startpos)));
00166 m_rtStart = rt;
00167 }
00168
00169 }
00170
00171 bool CMpaSplitterFilter::DemuxLoop()
00172 {
00173 HRESULT hr = S_OK;
00174
00175 int FrameSize;
00176 REFERENCE_TIME rtDuration;
00177
00178 while(SUCCEEDED(hr) && !CheckRequest(NULL) && m_pFile->GetPos() < m_pFile->GetEndPos() - 9)
00179 {
00180 if(!m_pFile->Sync(FrameSize, rtDuration)) {Sleep(1); continue;}
00181
00182 CAutoPtr<Packet> p(new Packet());
00183 p->pData.SetSize(FrameSize);
00184 m_pFile->Read(p->pData.GetData(), FrameSize);
00185
00186 p->TrackNumber = 0;
00187 p->rtStart = m_rtStart;
00188 p->rtStop = m_rtStart + rtDuration;
00189 p->bSyncPoint = TRUE;
00190
00191 hr = DeliverPacket(p);
00192
00193 m_rtStart += rtDuration;
00194 }
00195
00196 return(true);
00197 }
00198
00199
00200
00201
00202
00203 CMpaSourceFilter::CMpaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
00204 : CMpaSplitterFilter(pUnk, phr)
00205 {
00206 m_clsid = __uuidof(this);
00207 m_pInput.Free();
00208 }