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

多媒体编程

开发平台:

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 "DSMSplitter.h"
  23. #include "......DSUtilDSUtil.h"
  24. #include <initguid.h>
  25. #include "........includemoreuuids.h"
  26. #ifdef REGISTER_FILTER
  27. const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
  28. {
  29. {&MEDIATYPE_Stream, &MEDIASUBTYPE_DirectShowMedia},
  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(CDSMSplitterFilter), L"DSM Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins},
  40. {&__uuidof(CDSMSourceFilter), L"DSM Source", MERIT_NORMAL, 0, NULL},
  41. };
  42. CFactoryTemplate g_Templates[] =
  43. {
  44. {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDSMSplitterFilter>, NULL, &sudFilter[0]},
  45. {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CDSMSourceFilter>, NULL, &sudFilter[1]},
  46. };
  47. int g_cTemplates = countof(g_Templates);
  48. STDAPI DllRegisterServer()
  49. {
  50. CString str;
  51. str.Format(_T("0,%d,,%%0%dI64x"), DSMSW_SIZE, DSMSW_SIZE*2);
  52. str.Format(CString(str), DSMSW);
  53. RegisterSourceFilter(
  54. CLSID_AsyncReader, 
  55. MEDIASUBTYPE_DirectShowMedia, 
  56. str, NULL);
  57. return AMovieDllRegisterServer2(TRUE);
  58. }
  59. STDAPI DllUnregisterServer()
  60. {
  61. UnRegisterSourceFilter(MEDIASUBTYPE_DirectShowMedia);
  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. // CDSMSplitterFilter
  72. //
  73. CDSMSplitterFilter::CDSMSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
  74. : CBaseSplitterFilter(NAME("CDSMSplitterFilter"), pUnk, phr, __uuidof(this))
  75. {
  76. }
  77. CDSMSplitterFilter::~CDSMSplitterFilter()
  78. {
  79. }
  80. static int compare_id(const void* id1, const void* id2) {return (int)*(BYTE*)id1 - (int)*(BYTE*)id2;}
  81. HRESULT CDSMSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
  82. {
  83. CheckPointer(pAsyncReader, E_POINTER);
  84. HRESULT hr = E_FAIL;
  85. m_pFile.Free();
  86. m_pFile.Attach(new CDSMSplitterFile(pAsyncReader, hr, *this, *this));
  87. if(!m_pFile) return E_OUTOFMEMORY;
  88. if(FAILED(hr)) {m_pFile.Free(); return hr;}
  89. m_rtNewStart = m_rtCurrent = 0;
  90. m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->m_rtDuration;
  91. CArray<BYTE> ids;
  92. POSITION pos = m_pFile->m_mts.GetStartPosition();
  93. while(pos)
  94. {
  95. BYTE id;
  96. CMediaType mt;
  97. m_pFile->m_mts.GetNextAssoc(pos, id, mt);
  98. ids.Add(id);
  99. }
  100. qsort(ids.GetData(), ids.GetCount(), sizeof(BYTE), compare_id);
  101. for(int i = 0; i < ids.GetCount(); i++)
  102. {
  103. BYTE id = ids[i];
  104. CMediaType& mt = m_pFile->m_mts[id];
  105. CStringW name, lang;
  106. name.Format(L"Output %02d", id);
  107. CArray<CMediaType> mts;
  108. mts.Add(mt);
  109. CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, name, this, this, &hr));
  110. name.Empty();
  111. pos = m_pFile->m_sim[id].GetStartPosition();
  112. while(pos)
  113. {
  114. CStringA key; CStringW value;
  115. m_pFile->m_sim[id].GetNextAssoc(pos, key, value);
  116. pPinOut->SetProperty(CStringW(key), value);
  117. if(key == "NAME") name = value;
  118. if(key == "LANG") if((lang = ISO6392ToLanguage(CStringA(CString(value)))).IsEmpty()) lang = value;
  119. }
  120. if(!name.IsEmpty() || !lang.IsEmpty())
  121. {
  122. if(!name.IsEmpty()) {if(!lang.IsEmpty()) name += L" (" + lang + L")";}
  123. else if(!lang.IsEmpty()) name = lang;
  124. pPinOut->SetName(name);
  125. }
  126. EXECUTE_ASSERT(SUCCEEDED(AddOutputPin(id, pPinOut)));
  127. }
  128. pos = m_pFile->m_fim.GetStartPosition();
  129. while(pos)
  130. {
  131. CStringA key; CStringW value;
  132. m_pFile->m_fim.GetNextAssoc(pos, key, value);
  133. SetProperty(CStringW(key), value);
  134. }
  135. for(int i = 0; i < m_resources.GetCount(); i++)
  136. {
  137. const CDSMResource& r = m_resources[i];
  138. if(r.mime == "application/x-truetype-font")
  139. m_fontinst.InstallFont(r.data);
  140. }
  141. return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
  142. }
  143. bool CDSMSplitterFilter::DemuxInit()
  144. {
  145. return(true);
  146. }
  147. void CDSMSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
  148. {
  149. m_pFile->Seek(m_pFile->FindSyncPoint(rt));
  150. }
  151. bool CDSMSplitterFilter::DemuxLoop()
  152. {
  153. HRESULT hr = S_OK;
  154. while(SUCCEEDED(hr) && !CheckRequest(NULL) && m_pFile->GetPos() < m_pFile->GetLength())
  155. {
  156. dsmp_t type;
  157. UINT64 len;
  158. if(!m_pFile->Sync(type, len))
  159. continue;
  160. __int64 pos = m_pFile->GetPos();
  161. if(type == DSMP_SAMPLE)
  162. {
  163. CAutoPtr<Packet> p(new Packet());
  164. if(m_pFile->Read(len, p))
  165. {
  166. if(p->rtStart != Packet::INVALID_TIME)
  167. {
  168. p->rtStart -= m_pFile->m_rtFirst;
  169. p->rtStop -= m_pFile->m_rtFirst;
  170. }
  171. hr = DeliverPacket(p);
  172. }
  173. }
  174. m_pFile->Seek(pos + len);
  175. }
  176. return(true);
  177. }
  178. // IKeyFrameInfo
  179. STDMETHODIMP CDSMSplitterFilter::GetKeyFrameCount(UINT& nKFs)
  180. {
  181. CheckPointer(m_pFile, E_UNEXPECTED);
  182. nKFs = m_pFile->m_sps.GetCount();
  183. return S_OK;
  184. }
  185. STDMETHODIMP CDSMSplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs)
  186. {
  187. CheckPointer(pFormat, E_POINTER);
  188. CheckPointer(pKFs, E_POINTER);
  189. CheckPointer(m_pFile, E_UNEXPECTED);
  190. if(*pFormat != TIME_FORMAT_MEDIA_TIME) return E_INVALIDARG;
  191. // these aren't really the keyframes, but quicky accessable points in the stream
  192. for(nKFs = 0; nKFs < m_pFile->m_sps.GetCount(); nKFs++)
  193. pKFs[nKFs] = m_pFile->m_sps[nKFs].rt;
  194. return S_OK;
  195. }
  196. //
  197. // CDSMSourceFilter
  198. //
  199. CDSMSourceFilter::CDSMSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
  200. : CDSMSplitterFilter(pUnk, phr)
  201. {
  202. m_clsid = __uuidof(this);
  203. m_pInput.Free();
  204. }