MpaSplitter.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
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); // "DllMain" of the dshow baseclasses;
00081 }
00082 
00083 #endif
00084 
00085 //
00086 // CMpaSplitterFilter
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         // TODO
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 // CMpaSourceFilter
00201 //
00202 
00203 CMpaSourceFilter::CMpaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
00204         : CMpaSplitterFilter(pUnk, phr)
00205 {
00206         m_clsid = __uuidof(this);
00207         m_pInput.Free();
00208 }

Generated on Tue Dec 13 14:47:21 2005 for guliverkli by  doxygen 1.4.5