- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }