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

多媒体编程

开发平台:

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 "Shlwapi.h"
  23. #include <atlpath.h>
  24. #include <mmreg.h>
  25. #include <ks.h>
  26. #include <ksmedia.h>
  27. #include "AudioSwitcher.h"
  28. #include "Audio.h"
  29. #include "......DSUtilDSUtil.h"
  30. #include <initguid.h>
  31. #include "........includeOggOggDS.h"
  32. #ifdef REGISTER_FILTER
  33. const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
  34. {
  35. {&MEDIATYPE_Audio, &MEDIASUBTYPE_NULL}
  36. };
  37. const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
  38. {
  39. {&MEDIATYPE_Audio, &MEDIASUBTYPE_NULL}
  40. };
  41. const AMOVIESETUP_PIN sudpPins[] =
  42. {
  43.     {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
  44.     {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
  45. };
  46. const AMOVIESETUP_FILTER sudFilter[] =
  47. {
  48. {&__uuidof(CAudioSwitcherFilter), L"AudioSwitcher", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins}
  49. };
  50. CFactoryTemplate g_Templates[] =
  51. {
  52.     {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CAudioSwitcherFilter>, NULL, &sudFilter[0]}
  53. };
  54. int g_cTemplates = countof(g_Templates);
  55. STDAPI DllRegisterServer()
  56. {
  57. return AMovieDllRegisterServer2(TRUE);
  58. }
  59. STDAPI DllUnregisterServer()
  60. {
  61. return AMovieDllRegisterServer2(FALSE);
  62. }
  63. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  64. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  65. {
  66.     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  67. }
  68. #endif
  69. //
  70. // CAudioSwitcherFilter
  71. //
  72. CAudioSwitcherFilter::CAudioSwitcherFilter(LPUNKNOWN lpunk, HRESULT* phr)
  73. : CStreamSwitcherFilter(lpunk, phr, __uuidof(this))
  74. {
  75. if(phr)
  76. {
  77. if(FAILED(*phr)) return;
  78. else *phr = S_OK;
  79. }
  80. m_fCustomChannelMapping = false;
  81. memset(m_pSpeakerToChannelMap, 0, sizeof(m_pSpeakerToChannelMap));
  82. m_fDownSampleTo441 = false;
  83. m_rtAudioTimeShift = 0;
  84. m_rtNextStart = 0;
  85. m_rtNextStop = 1;
  86. }
  87. STDMETHODIMP CAudioSwitcherFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  88. {
  89. return
  90. QI(IAudioSwitcherFilter)
  91. __super::NonDelegatingQueryInterface(riid, ppv);
  92. }
  93. HRESULT CAudioSwitcherFilter::CheckMediaType(const CMediaType* pmt)
  94. {
  95. if(pmt->formattype == FORMAT_WaveFormatEx
  96. && ((WAVEFORMATEX*)pmt->pbFormat)->nChannels > 2
  97. && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag != WAVE_FORMAT_EXTENSIBLE)
  98. return VFW_E_INVALIDMEDIATYPE; // stupid iviaudio tries to fool us
  99. return (pmt->majortype == MEDIATYPE_Audio
  100. && pmt->formattype == FORMAT_WaveFormatEx
  101. && (((WAVEFORMATEX*)pmt->pbFormat)->wBitsPerSample == 8
  102. || ((WAVEFORMATEX*)pmt->pbFormat)->wBitsPerSample == 16
  103. || ((WAVEFORMATEX*)pmt->pbFormat)->wBitsPerSample == 24
  104. || ((WAVEFORMATEX*)pmt->pbFormat)->wBitsPerSample == 32)
  105. && (((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_PCM
  106. || ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_IEEE_FLOAT
  107. || ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3_SPDIF
  108. || ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_EXTENSIBLE))
  109. ? S_OK
  110. : VFW_E_TYPE_NOT_ACCEPTED;
  111. }
  112. #define mixchannels(type, sumtype, mintype, maxtype) 
  113. sumtype sum = 0; 
  114. int num = 0; 
  115. for(int j = 0; j < 18 && j < wfe->nChannels; j++) 
  116. if(Channel&(1<<j)) 
  117. num++; 
  118. sum += *(type*)&pDataIn[bps*(j + wfe->nChannels*k)]; 
  119. sum = min(max(sum, mintype), maxtype); 
  120. *(type*)&pDataOut[bps*(i + wfeout->nChannels*k)] = (type)sum; 
  121. HRESULT CAudioSwitcherFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
  122. {
  123. CStreamSwitcherInputPin* pInPin = GetInputPin();
  124. CStreamSwitcherOutputPin* pOutPin = GetOutputPin();
  125. if(!pInPin || !pOutPin) 
  126. return __super::Transform(pIn, pOut);
  127. WAVEFORMATEX* wfe = (WAVEFORMATEX*)pInPin->CurrentMediaType().pbFormat;
  128. WAVEFORMATEX* wfeout = (WAVEFORMATEX*)pOutPin->CurrentMediaType().pbFormat;
  129. WAVEFORMATEXTENSIBLE* wfex = (WAVEFORMATEXTENSIBLE*)wfe;
  130. WAVEFORMATEXTENSIBLE* wfexout = (WAVEFORMATEXTENSIBLE*)wfeout;
  131. int bps = wfe->wBitsPerSample>>3;
  132. int len = pIn->GetActualDataLength() / (bps*wfe->nChannels);
  133. int lenout = len * wfeout->nSamplesPerSec / wfe->nSamplesPerSec;
  134. REFERENCE_TIME rtStart, rtStop;
  135. if(SUCCEEDED(pIn->GetTime(&rtStart, &rtStop)))
  136. {
  137. rtStart += m_rtAudioTimeShift;
  138. rtStop += m_rtAudioTimeShift;
  139. pOut->SetTime(&rtStart, &rtStop);
  140. m_rtNextStart = rtStart;
  141. m_rtNextStop = rtStop;
  142. }
  143. else
  144. {
  145. pOut->SetTime(&m_rtNextStart, &m_rtNextStop);
  146. }
  147. m_rtNextStart += 10000000i64*len/wfe->nSamplesPerSec;
  148. m_rtNextStop += 10000000i64*len/wfe->nSamplesPerSec;
  149. bool fPCM = wfe->wFormatTag == WAVE_FORMAT_PCM
  150. || wfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE && wfex->SubFormat == KSDATAFORMAT_SUBTYPE_PCM;
  151. bool fFloat = wfe->wFormatTag == WAVE_FORMAT_IEEE_FLOAT
  152. || wfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE && wfex->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
  153. if(!fPCM && !fFloat)
  154. return __super::Transform(pIn, pOut);
  155. BYTE* pDataIn = NULL;
  156. BYTE* pDataOut = NULL;
  157. HRESULT hr;
  158. if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
  159. if(FAILED(hr = pOut->GetPointer(&pDataOut))) return hr;
  160. if(!pDataIn || !pDataOut || len <= 0 || lenout <= 0) return S_FALSE;
  161. memset(pDataOut, 0, pOut->GetSize());
  162. if(m_fCustomChannelMapping)
  163. {
  164. if(m_chs[wfe->nChannels-1].GetCount() > 0)
  165. {
  166. for(int i = 0; i < wfeout->nChannels; i++)
  167. {
  168. DWORD Channel = m_chs[wfe->nChannels-1][i].Channel, nChannels = 0;
  169. for(int k = 0; k < len; k++)
  170. {
  171. if(fPCM && wfe->wBitsPerSample == 8)
  172. {
  173. mixchannels(unsigned char, __int64, 0, UCHAR_MAX);
  174. }
  175. else if(fPCM && wfe->wBitsPerSample == 16)
  176. {
  177. mixchannels(short, __int64, SHRT_MIN, SHRT_MAX);
  178. }
  179. else if(fPCM && wfe->wBitsPerSample == 24)
  180. {
  181. // mixchannels(_int24, __int64, _INT24_MIN, _INT24_MAX);
  182. __int64 sum = 0;
  183. int num = 0;
  184. for(int j = 0; j < 18 && j < wfe->nChannels; j++)
  185. {
  186. if(Channel&(1<<j))
  187. {
  188. num++;
  189. int tmp;
  190. memcpy((BYTE*)&tmp+1, &pDataIn[bps*(j + wfe->nChannels*k)], 3);
  191. tmp>>=8;
  192. sum += tmp;
  193. }
  194. }
  195. sum = min(max(sum, -(1<<24)), (1<<24)-1);
  196. memcpy(&pDataOut[bps*(i + wfeout->nChannels*k)], (BYTE*)&sum, 3);
  197. }
  198. else if(fPCM && wfe->wBitsPerSample == 32)
  199. {
  200. mixchannels(int, __int64, INT_MIN, INT_MAX);
  201. }
  202. else if(fFloat && wfe->wBitsPerSample == 32)
  203. {
  204. mixchannels(float, double, -1, 1);
  205. }
  206. else if(fFloat && wfe->wBitsPerSample == 64)
  207. {
  208. mixchannels(double, double, -1, 1);
  209. }
  210. }
  211. }
  212. }
  213. else
  214. {
  215. BYTE* pDataOut = NULL;
  216. HRESULT hr;
  217. if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut) return hr;
  218. memset(pDataOut, 0, pOut->GetSize());
  219. }
  220. }
  221. else
  222. {
  223. HRESULT hr;
  224. if(S_OK != (hr = __super::Transform(pIn, pOut)))
  225. return hr;
  226. }
  227. if(m_fDownSampleTo441
  228. && wfe->nSamplesPerSec > 44100 && wfeout->nSamplesPerSec == 44100 
  229. && wfe->wBitsPerSample <= 16 && fPCM)
  230. {
  231. if(BYTE* buff = new BYTE[len*bps])
  232. {
  233. for(int ch = 0; ch < wfeout->nChannels; ch++)
  234. {
  235. memset(buff, 0, len*bps);
  236. for(int i = 0; i < len; i++)
  237. memcpy(buff + i*bps, (char*)pDataOut + (ch + i*wfeout->nChannels)*bps, bps);
  238. m_pResamplers[ch]->Downsample(buff, len, buff, lenout);
  239. for(int i = 0; i < lenout; i++)
  240. memcpy((char*)pDataOut + (ch + i*wfeout->nChannels)*bps, buff + i*bps, bps);
  241. }
  242. delete [] buff;
  243. }
  244. }
  245. pOut->SetActualDataLength(lenout*bps*wfeout->nChannels);
  246. return S_OK;
  247. }
  248. CMediaType CAudioSwitcherFilter::CreateNewOutputMediaType(CMediaType mt, long& cbBuffer)
  249. {
  250. CStreamSwitcherInputPin* pInPin = GetInputPin();
  251. CStreamSwitcherOutputPin* pOutPin = GetOutputPin();
  252. if(!pInPin || !pOutPin || ((WAVEFORMATEX*)mt.pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3_SPDIF) 
  253. return __super::CreateNewOutputMediaType(mt, cbBuffer);
  254. WAVEFORMATEX* wfe = (WAVEFORMATEX*)pInPin->CurrentMediaType().pbFormat;
  255. if(m_fCustomChannelMapping)
  256. {
  257. m_chs[wfe->nChannels-1].RemoveAll();
  258. DWORD mask = DWORD((__int64(1)<<wfe->nChannels)-1);
  259. for(int i = 0; i < 18; i++)
  260. {
  261. if(m_pSpeakerToChannelMap[wfe->nChannels-1][i]&mask)
  262. {
  263. ChMap cm = {1<<i, m_pSpeakerToChannelMap[wfe->nChannels-1][i]};
  264. m_chs[wfe->nChannels-1].Add(cm);
  265. }
  266. }
  267. if(m_chs[wfe->nChannels-1].GetCount() > 0)
  268. {
  269. mt.ReallocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
  270. WAVEFORMATEXTENSIBLE* wfex = (WAVEFORMATEXTENSIBLE*)mt.pbFormat;
  271. wfex->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
  272. wfex->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
  273. wfex->Samples.wValidBitsPerSample = wfe->wBitsPerSample;
  274. wfex->SubFormat = 
  275. wfe->wFormatTag == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM :
  276. wfe->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT :
  277. wfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? ((WAVEFORMATEXTENSIBLE*)wfe)->SubFormat :
  278. KSDATAFORMAT_SUBTYPE_PCM; // can't happen
  279. wfex->dwChannelMask = 0;
  280. for(int i = 0; i < m_chs[wfe->nChannels-1].GetCount(); i++)
  281. wfex->dwChannelMask |= m_chs[wfe->nChannels-1][i].Speaker;
  282. wfex->Format.nChannels = (WORD)m_chs[wfe->nChannels-1].GetCount();
  283. wfex->Format.nBlockAlign = wfex->Format.nChannels*wfex->Format.wBitsPerSample>>3;
  284. wfex->Format.nAvgBytesPerSec = wfex->Format.nBlockAlign*wfex->Format.nSamplesPerSec;
  285. }
  286. }
  287. WAVEFORMATEX* wfeout = (WAVEFORMATEX*)mt.pbFormat;
  288. if(m_fDownSampleTo441)
  289. {
  290. if(wfeout->nSamplesPerSec > 44100 && wfeout->wBitsPerSample <= 16)
  291. {
  292. wfeout->nSamplesPerSec = 44100;
  293. wfeout->nAvgBytesPerSec = wfeout->nBlockAlign*wfeout->nSamplesPerSec;
  294. }
  295. }
  296. int bps = wfe->wBitsPerSample>>3;
  297. int len = cbBuffer / (bps*wfe->nChannels);
  298. int lenout = len * wfeout->nSamplesPerSec / wfe->nSamplesPerSec;
  299. cbBuffer = lenout*bps*wfeout->nChannels;
  300. // mt.lSampleSize = (ULONG)max(mt.lSampleSize, wfe->nAvgBytesPerSec * rtLen / 10000000i64);
  301. // mt.lSampleSize = (mt.lSampleSize + (wfe->nBlockAlign-1)) & ~(wfe->nBlockAlign-1);
  302. return mt;
  303. }
  304. void CAudioSwitcherFilter::OnNewOutputMediaType(const CMediaType& mtIn, const CMediaType& mtOut)
  305. {
  306. const WAVEFORMATEX* wfe = (WAVEFORMATEX*)mtIn.pbFormat;
  307. const WAVEFORMATEX* wfeout = (WAVEFORMATEX*)mtOut.pbFormat;
  308. m_pResamplers.RemoveAll();
  309. for(int i = 0; i < wfeout->nChannels; i++)
  310. {
  311. CAutoPtr<AudioStreamResampler> pResampler;
  312. pResampler.Attach(new AudioStreamResampler(wfeout->wBitsPerSample>>3, wfe->nSamplesPerSec, wfeout->nSamplesPerSec, true));
  313. m_pResamplers.Add(pResampler);
  314. }
  315. }
  316. // IAudioSwitcherFilter
  317. STDMETHODIMP CAudioSwitcherFilter::GetInputSpeakerConfig(DWORD* pdwChannelMask)
  318. {
  319. if(!pdwChannelMask) 
  320. return E_POINTER;
  321. *pdwChannelMask = 0;
  322. CStreamSwitcherInputPin* pInPin = GetInputPin();
  323. if(!pInPin || !pInPin->IsConnected())
  324. return E_UNEXPECTED;
  325. WAVEFORMATEX* wfe = (WAVEFORMATEX*)pInPin->CurrentMediaType().pbFormat;
  326. if(wfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
  327. {
  328. WAVEFORMATEXTENSIBLE* wfex = (WAVEFORMATEXTENSIBLE*)wfe;
  329. *pdwChannelMask = wfex->dwChannelMask;
  330. }
  331. else
  332. {
  333. *pdwChannelMask = 0/*wfe->nChannels == 1 ? 4 : wfe->nChannels == 2 ? 3 : 0*/;
  334. }
  335. return S_OK;
  336. }
  337. STDMETHODIMP CAudioSwitcherFilter::GetSpeakerConfig(bool* pfCustomChannelMapping, DWORD pSpeakerToChannelMap[18][18])
  338. {
  339. if(pfCustomChannelMapping) *pfCustomChannelMapping = m_fCustomChannelMapping;
  340. memcpy(pSpeakerToChannelMap, m_pSpeakerToChannelMap, sizeof(m_pSpeakerToChannelMap));
  341. return S_OK;
  342. }
  343. STDMETHODIMP CAudioSwitcherFilter::SetSpeakerConfig(bool fCustomChannelMapping, DWORD pSpeakerToChannelMap[18][18])
  344. {
  345. if(m_State == State_Stopped || m_fCustomChannelMapping != fCustomChannelMapping
  346. || memcmp(m_pSpeakerToChannelMap, pSpeakerToChannelMap, sizeof(m_pSpeakerToChannelMap)))
  347. {
  348. PauseGraph;
  349. CStreamSwitcherInputPin* pInput = GetInputPin();
  350. SelectInput(NULL);
  351. m_fCustomChannelMapping = fCustomChannelMapping;
  352. memcpy(m_pSpeakerToChannelMap, pSpeakerToChannelMap, sizeof(m_pSpeakerToChannelMap));
  353. SelectInput(pInput);
  354. ResumeGraph;
  355. }
  356. return S_OK;
  357. }
  358. STDMETHODIMP_(int) CAudioSwitcherFilter::GetNumberOfInputChannels()
  359. {
  360. CStreamSwitcherInputPin* pInPin = GetInputPin();
  361. return pInPin ? ((WAVEFORMATEX*)pInPin->CurrentMediaType().pbFormat)->nChannels : 0;
  362. }
  363. STDMETHODIMP_(bool) CAudioSwitcherFilter::IsDownSamplingTo441Enabled()
  364. {
  365. return(m_fDownSampleTo441);
  366. }
  367. STDMETHODIMP CAudioSwitcherFilter::EnableDownSamplingTo441(bool fEnable)
  368. {
  369. if(m_fDownSampleTo441 != fEnable)
  370. {
  371. PauseGraph;
  372. m_fDownSampleTo441 = fEnable;
  373. ResumeGraph;
  374. }
  375. return S_OK;
  376. }
  377. STDMETHODIMP_(REFERENCE_TIME) CAudioSwitcherFilter::GetAudioTimeShift()
  378. {
  379. return(m_rtAudioTimeShift);
  380. }
  381. STDMETHODIMP CAudioSwitcherFilter::SetAudioTimeShift(REFERENCE_TIME rtAudioTimeShift)
  382. {
  383. m_rtAudioTimeShift = rtAudioTimeShift;
  384. return S_OK;
  385. }