DSMSplitter.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:6k
- /*
- * Copyright (C) 2003-2005 Gabest
- * http://www.gabest.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
- #include "StdAfx.h"
- #include "DSMSplitter.h"
- #include "......DSUtilDSUtil.h"
- #include <initguid.h>
- #include "........includemoreuuids.h"
- #ifdef REGISTER_FILTER
- const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
- {
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_DirectShowMedia},
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL},
- };
- const AMOVIESETUP_PIN sudpPins[] =
- {
- {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
- {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
- };
- const AMOVIESETUP_FILTER sudFilter[] =
- {
- {&__uuidof(CDSMSplitterFilter), L"DSM Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins},
- {&__uuidof(CDSMSourceFilter), L"DSM Source", MERIT_NORMAL, 0, NULL},
- };
- CFactoryTemplate g_Templates[] =
- {
- {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDSMSplitterFilter>, NULL, &sudFilter[0]},
- {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CDSMSourceFilter>, NULL, &sudFilter[1]},
- };
- int g_cTemplates = countof(g_Templates);
- STDAPI DllRegisterServer()
- {
- CString str;
- str.Format(_T("0,%d,,%%0%dI64x"), DSMSW_SIZE, DSMSW_SIZE*2);
- str.Format(CString(str), DSMSW);
- RegisterSourceFilter(
- CLSID_AsyncReader,
- MEDIASUBTYPE_DirectShowMedia,
- str, NULL);
- return AMovieDllRegisterServer2(TRUE);
- }
- STDAPI DllUnregisterServer()
- {
- UnRegisterSourceFilter(MEDIASUBTYPE_DirectShowMedia);
- return AMovieDllRegisterServer2(FALSE);
- }
- extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
- BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
- {
- return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
- }
- #endif
- //
- // CDSMSplitterFilter
- //
- CDSMSplitterFilter::CDSMSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CBaseSplitterFilter(NAME("CDSMSplitterFilter"), pUnk, phr, __uuidof(this))
- {
- }
- CDSMSplitterFilter::~CDSMSplitterFilter()
- {
- }
- static int compare_id(const void* id1, const void* id2) {return (int)*(BYTE*)id1 - (int)*(BYTE*)id2;}
- HRESULT CDSMSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
- {
- CheckPointer(pAsyncReader, E_POINTER);
- HRESULT hr = E_FAIL;
- m_pFile.Free();
- m_pFile.Attach(new CDSMSplitterFile(pAsyncReader, hr, *this, *this));
- if(!m_pFile) return E_OUTOFMEMORY;
- if(FAILED(hr)) {m_pFile.Free(); return hr;}
- m_rtNewStart = m_rtCurrent = 0;
- m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->m_rtDuration;
- CArray<BYTE> ids;
- POSITION pos = m_pFile->m_mts.GetStartPosition();
- while(pos)
- {
- BYTE id;
- CMediaType mt;
- m_pFile->m_mts.GetNextAssoc(pos, id, mt);
- ids.Add(id);
- }
- qsort(ids.GetData(), ids.GetCount(), sizeof(BYTE), compare_id);
- for(int i = 0; i < ids.GetCount(); i++)
- {
- BYTE id = ids[i];
- CMediaType& mt = m_pFile->m_mts[id];
- CStringW name, lang;
- name.Format(L"Output %02d", id);
- CArray<CMediaType> mts;
- mts.Add(mt);
- CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, name, this, this, &hr));
-
- name.Empty();
- pos = m_pFile->m_sim[id].GetStartPosition();
- while(pos)
- {
- CStringA key; CStringW value;
- m_pFile->m_sim[id].GetNextAssoc(pos, key, value);
- pPinOut->SetProperty(CStringW(key), value);
- if(key == "NAME") name = value;
- if(key == "LANG") if((lang = ISO6392ToLanguage(CStringA(CString(value)))).IsEmpty()) lang = value;
- }
- if(!name.IsEmpty() || !lang.IsEmpty())
- {
- if(!name.IsEmpty()) {if(!lang.IsEmpty()) name += L" (" + lang + L")";}
- else if(!lang.IsEmpty()) name = lang;
- pPinOut->SetName(name);
- }
- EXECUTE_ASSERT(SUCCEEDED(AddOutputPin(id, pPinOut)));
- }
- pos = m_pFile->m_fim.GetStartPosition();
- while(pos)
- {
- CStringA key; CStringW value;
- m_pFile->m_fim.GetNextAssoc(pos, key, value);
- SetProperty(CStringW(key), value);
- }
- for(int i = 0; i < m_resources.GetCount(); i++)
- {
- const CDSMResource& r = m_resources[i];
- if(r.mime == "application/x-truetype-font")
- m_fontinst.InstallFont(r.data);
- }
- return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
- }
- bool CDSMSplitterFilter::DemuxInit()
- {
- return(true);
- }
- void CDSMSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
- {
- m_pFile->Seek(m_pFile->FindSyncPoint(rt));
- }
- bool CDSMSplitterFilter::DemuxLoop()
- {
- HRESULT hr = S_OK;
- while(SUCCEEDED(hr) && !CheckRequest(NULL) && m_pFile->GetPos() < m_pFile->GetLength())
- {
- dsmp_t type;
- UINT64 len;
- if(!m_pFile->Sync(type, len))
- continue;
- __int64 pos = m_pFile->GetPos();
- if(type == DSMP_SAMPLE)
- {
- CAutoPtr<Packet> p(new Packet());
- if(m_pFile->Read(len, p))
- {
- if(p->rtStart != Packet::INVALID_TIME)
- {
- p->rtStart -= m_pFile->m_rtFirst;
- p->rtStop -= m_pFile->m_rtFirst;
- }
- hr = DeliverPacket(p);
- }
- }
- m_pFile->Seek(pos + len);
- }
- return(true);
- }
- // IKeyFrameInfo
- STDMETHODIMP CDSMSplitterFilter::GetKeyFrameCount(UINT& nKFs)
- {
- CheckPointer(m_pFile, E_UNEXPECTED);
- nKFs = m_pFile->m_sps.GetCount();
- return S_OK;
- }
- STDMETHODIMP CDSMSplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs)
- {
- CheckPointer(pFormat, E_POINTER);
- CheckPointer(pKFs, E_POINTER);
- CheckPointer(m_pFile, E_UNEXPECTED);
- if(*pFormat != TIME_FORMAT_MEDIA_TIME) return E_INVALIDARG;
- // these aren't really the keyframes, but quicky accessable points in the stream
- for(nKFs = 0; nKFs < m_pFile->m_sps.GetCount(); nKFs++)
- pKFs[nKFs] = m_pFile->m_sps[nKFs].rt;
- return S_OK;
- }
- //
- // CDSMSourceFilter
- //
- CDSMSourceFilter::CDSMSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CDSMSplitterFilter(pUnk, phr)
- {
- m_clsid = __uuidof(this);
- m_pInput.Free();
- }