MpaSplitter.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:5k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "StdAfx.h"
  22. #include <mmreg.h>
  23. #include <initguid.h>
  24. #include "MpaSplitter.h"
  25. #include "........includemoreuuids.h"
  26. #ifdef REGISTER_FILTER
  27. const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
  28. {
  29. {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
  30. {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL}
  31. };
  32. const AMOVIESETUP_PIN sudpPins[] =
  33. {
  34. {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
  35. {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
  36. };
  37. const AMOVIESETUP_FILTER sudFilter[] =
  38. {
  39. {&__uuidof(CMpaSplitterFilter), L"Mpa Splitter", MERIT_NORMAL+1, countof(sudpPins), sudpPins},
  40. {&__uuidof(CMpaSourceFilter), L"Mpa Source", MERIT_NORMAL+1, 0, NULL},
  41. };
  42. CFactoryTemplate g_Templates[] =
  43. {
  44. {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CMpaSplitterFilter>, NULL, &sudFilter[0]},
  45. {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CMpaSourceFilter>, NULL, &sudFilter[1]},
  46. };
  47. int g_cTemplates = countof(g_Templates);
  48. STDAPI DllRegisterServer()
  49. {
  50. CList<CString> chkbytes;
  51. chkbytes.AddTail(_T("0,2,FFE0,FFE0"));
  52. chkbytes.AddTail(_T("0,10,FFFFFFFF000000000000,494433030080808080"));
  53. RegisterSourceFilter(
  54. CLSID_AsyncReader, 
  55. MEDIASUBTYPE_MPEG1Audio, 
  56. chkbytes,
  57. NULL);
  58. return AMovieDllRegisterServer2(TRUE);
  59. }
  60. STDAPI DllUnregisterServer()
  61. {
  62. return AMovieDllRegisterServer2(FALSE);
  63. }
  64. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  65. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  66. {
  67. return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  68. }
  69. #endif
  70. //
  71. // CMpaSplitterFilter
  72. //
  73. CMpaSplitterFilter::CMpaSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
  74. : CBaseSplitterFilter(NAME("CMpaSplitterFilter"), pUnk, phr, __uuidof(this))
  75. {
  76. }
  77. STDMETHODIMP CMpaSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  78. {
  79.     CheckPointer(ppv, E_POINTER);
  80.     return 
  81. __super::NonDelegatingQueryInterface(riid, ppv);
  82. }
  83. HRESULT CMpaSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
  84. {
  85. CheckPointer(pAsyncReader, E_POINTER);
  86. HRESULT hr = E_FAIL;
  87. m_pFile.Free();
  88. m_pFile.Attach(new CMpaSplitterFile(pAsyncReader, hr));
  89. if(!m_pFile) return E_OUTOFMEMORY;
  90. if(FAILED(hr)) {m_pFile.Free(); return hr;}
  91. CArray<CMediaType> mts;
  92. mts.Add(m_pFile->GetMediaType());
  93. CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Audio", this, this, &hr));
  94. AddOutputPin(0, pPinOut);
  95. m_rtNewStart = m_rtCurrent = 0;
  96. m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->GetDuration();
  97. CString str, title;
  98. if(m_pFile->m_tags.Lookup('TIT2', str)) title = str;
  99. if(m_pFile->m_tags.Lookup('TPE1', str)) title = title.IsEmpty() ? str : str + _T(" - ") + title;
  100. if(m_pFile->m_tags.Lookup('TYER', str) && !title.IsEmpty() && !str.IsEmpty()) title += _T(" (") + str + _T(")");
  101. if(!title.IsEmpty()) SetProperty(L"TITL", CStringW(title));
  102. if(m_pFile->m_tags.Lookup('TCOP', str)) SetProperty(L"CPYR", CStringW(str));
  103. if(m_pFile->m_tags.Lookup('COMM', str)) SetProperty(L"DESC", CStringW(str));
  104. return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
  105. }
  106. STDMETHODIMP CMpaSplitterFilter::GetDuration(LONGLONG* pDuration)
  107. {
  108. CheckPointer(pDuration, E_POINTER);
  109. CheckPointer(m_pFile, VFW_E_NOT_CONNECTED);
  110. *pDuration = m_pFile->GetDuration();
  111. return S_OK;
  112. }
  113. bool CMpaSplitterFilter::DemuxInit()
  114. {
  115. if(!m_pFile) return(false);
  116. // TODO
  117. return(true);
  118. }
  119. void CMpaSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
  120. {
  121. __int64 startpos = m_pFile->GetStartPos();
  122. __int64 endpos = m_pFile->GetEndPos();
  123. if(rt <= 0 || m_pFile->GetDuration() <= 0)
  124. {
  125. m_pFile->Seek(startpos);
  126. m_rtStart = 0;
  127. }
  128. else
  129. {
  130. m_pFile->Seek(startpos + (__int64)((1.0 * rt / m_pFile->GetDuration()) * (endpos - startpos)));
  131. m_rtStart = rt;
  132. }
  133. }
  134. bool CMpaSplitterFilter::DemuxLoop()
  135. {
  136. HRESULT hr = S_OK;
  137. int FrameSize;
  138. REFERENCE_TIME rtDuration;
  139. while(SUCCEEDED(hr) && !CheckRequest(NULL) && m_pFile->GetPos() < m_pFile->GetEndPos() - 9)
  140. {
  141. if(!m_pFile->Sync(FrameSize, rtDuration)) {Sleep(1); continue;}
  142. CAutoPtr<Packet> p(new Packet());
  143. p->pData.SetSize(FrameSize);
  144. m_pFile->Read(p->pData.GetData(), FrameSize);
  145. p->TrackNumber = 0;
  146. p->rtStart = m_rtStart;
  147. p->rtStop = m_rtStart + rtDuration;
  148. p->bSyncPoint = TRUE;
  149. hr = DeliverPacket(p);
  150. m_rtStart += rtDuration;
  151. }
  152. return(true);
  153. }
  154. //
  155. // CMpaSourceFilter
  156. //
  157. CMpaSourceFilter::CMpaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
  158. : CMpaSplitterFilter(pUnk, phr)
  159. {
  160. m_clsid = __uuidof(this);
  161. m_pInput.Free();
  162. }