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

多媒体编程

开发平台:

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 <atlbase.h>
  23. #include "avi2ac3filter.h"
  24. #include "......DSUtilDSUtil.h"
  25. #include <initguid.h>
  26. #include "........includemoreuuids.h"
  27. #ifdef REGISTER_FILTER
  28. const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
  29. {
  30. {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE_DOLBY_AC3},
  31. {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE_DTS},
  32. };
  33. const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
  34. {
  35. {&MEDIATYPE_Audio, &MEDIASUBTYPE_NULL},
  36. };
  37. const AMOVIESETUP_PIN sudpPins[] =
  38. {
  39.     {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
  40.     {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
  41. };
  42. const AMOVIESETUP_FILTER sudFilter[] =
  43. {
  44. {&__uuidof(CAVI2AC3Filter), L"AVI<->AC3/DTS", MERIT_UNLIKELY, countof(sudpPins), sudpPins}
  45. };
  46. CFactoryTemplate g_Templates[] =
  47. {
  48.     {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CAVI2AC3Filter>, NULL, &sudFilter[0]}
  49. };
  50. int g_cTemplates = countof(g_Templates);
  51. STDAPI DllRegisterServer()
  52. {
  53. return AMovieDllRegisterServer2(TRUE);
  54. }
  55. STDAPI DllUnregisterServer()
  56. {
  57. return AMovieDllRegisterServer2(FALSE);
  58. }
  59. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  60. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  61. {
  62.     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  63. }
  64. #endif
  65. //
  66. // CAVI2AC3Filter
  67. //
  68. CAVI2AC3Filter::CAVI2AC3Filter(LPUNKNOWN lpunk, HRESULT* phr)
  69. : CTransformFilter(NAME("CAVI2AC3Filter"), lpunk, __uuidof(this))
  70. {
  71. if(phr) *phr = S_OK;
  72. }
  73. CAVI2AC3Filter::~CAVI2AC3Filter()
  74. {
  75. }
  76. HRESULT CAVI2AC3Filter::Transform(IMediaSample* pSample, IMediaSample* pOutSample)
  77. {
  78. HRESULT hr;
  79. BYTE* pIn = NULL;
  80. if(FAILED(hr = pSample->GetPointer(&pIn))) return hr;
  81. BYTE* pInOrg = pIn;
  82. long len = pSample->GetActualDataLength();
  83. if(len <= 0) return S_FALSE;
  84. BYTE* pOut = NULL;
  85. if(FAILED(hr = pOutSample->GetPointer(&pOut))) return hr;
  86. BYTE* pOutOrg = pOut;
  87. int size = pOutSample->GetSize();
  88. if((CheckAC3(&m_pInput->CurrentMediaType()) || CheckDTS(&m_pInput->CurrentMediaType()))
  89. && (CheckWAVEAC3(&m_pOutput->CurrentMediaType()) || CheckWAVEDTS(&m_pOutput->CurrentMediaType())))
  90. {
  91. if(*(DWORD*)pIn == 0xBA010000)
  92. {
  93. pIn += 14;
  94. }
  95. if(*(DWORD*)pIn == 0xBD010000)
  96. {
  97. pIn += 8 + 1 + pIn[8] + 1 + 3;
  98. }
  99. len -= (pInOrg - pIn);
  100. if(size < len) return E_FAIL;
  101. memcpy(pOut, pIn, len);
  102. pOut += len;
  103. }
  104. else if((CheckWAVEAC3(&m_pInput->CurrentMediaType()) || CheckWAVEDTS(&m_pInput->CurrentMediaType()))
  105. && (CheckAC3(&m_pOutput->CurrentMediaType()) || CheckDTS(&m_pOutput->CurrentMediaType())))
  106. {
  107. if((m_pOutput->CurrentMediaType().majortype == MEDIATYPE_DVD_ENCRYPTED_PACK
  108. || m_pOutput->CurrentMediaType().majortype == MEDIATYPE_MPEG2_PES)
  109. && (len + 12 + 3) >= 0x10000) // damn, this can happen if the interleave time is too big
  110. {
  111. REFERENCE_TIME rtStart = 0, rtStop = 1;
  112. bool fHasTime = (S_OK == pSample->GetTime(&rtStart, &rtStop));
  113. bool fDiscontinuity = (S_OK == pOutSample->IsDiscontinuity());
  114. int pos = 0;
  115. while(pos < len)
  116. {
  117. int curlen = min(len - pos, 2013);
  118. pos += 2013;
  119. CComPtr<IMediaSample> pOutSample;
  120. hr = InitializeOutputSample(pSample, &pOutSample);
  121. if(fDiscontinuity)
  122. {
  123. if(fHasTime)
  124. {
  125. rtStop = rtStart + (rtStop - rtStart) * curlen / len;
  126. pOutSample->SetTime(&rtStart, &rtStop);
  127. }
  128. fDiscontinuity = false;
  129. }
  130. else
  131. {
  132. pOutSample->SetTime(NULL, NULL);
  133. pOutSample->SetDiscontinuity(FALSE);
  134. }
  135. BYTE* pOut = NULL;
  136. if(FAILED(hr = pOutSample->GetPointer(&pOut))) return hr;
  137. BYTE* pOutOrg = pOut;
  138. int size = pOutSample->GetSize();
  139. const GUID* majortype = &m_pOutput->CurrentMediaType().majortype;
  140. const GUID* subtype = &m_pOutput->CurrentMediaType().subtype;
  141. if(*majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
  142. {
  143. if(size < curlen + 32 + 3) return E_FAIL;
  144. BYTE PESHeader[] = 
  145. {
  146. 0x00,0x00,0x01,0xBA, // PES id
  147. 0x44,0x00,0x04,0x00,0x04,0x01, // SCR (0)
  148. 0x01,0x89,0xC3,0xF8, // mux rate (1260000 bytes/sec, 22bits), marker (2bits), reserved (~0, 5bits), stuffing (0, 3bits)
  149. };
  150. memcpy(pOut, &PESHeader, sizeof(PESHeader));
  151. pOut += sizeof(PESHeader);
  152. majortype = &MEDIATYPE_MPEG2_PES;
  153. }
  154. if(*majortype == MEDIATYPE_MPEG2_PES)
  155. {
  156. if(size < curlen + 20 + 3) return E_FAIL;
  157. BYTE Private1Header[] = 
  158. {
  159. 0x00,0x00,0x01,0xBD, // private stream 1 id
  160. 0x07,0xEC, // packet length (TODO: modify it later)
  161. 0x81,0x80, // marker, original, PTS - flags
  162. 0x08, // packet data starting offset
  163. 0x21,0x00,0x01,0x00,0x01, // PTS (0)
  164. 0xFF,0xFF,0xFF, // stuffing
  165. 0x80, // stream id (0)
  166. 0x01,0x00,0x01, // no idea about the first byte, the sencond+third seem to show the ac3/dts header sync offset plus one (dvd2avi doesn't output it to the ac3/dts file so we have to put it back)
  167. };
  168. int packetlen = curlen + 12 + 3;
  169. ASSERT(packetlen <= 0xffff);
  170. Private1Header[4] = (packetlen>>8)&0xff;
  171. Private1Header[5] = packetlen&0xff;
  172. if(*subtype == MEDIASUBTYPE_DTS)
  173. {
  174. Private1Header[17] += 8;
  175. }
  176. if(*subtype == MEDIASUBTYPE_DOLBY_AC3)
  177. {
  178. for(int i = 0; i < curlen; i++)
  179. {
  180. if(*(DWORD*)&pIn[i] == 0x770B)
  181. {
  182. i++;
  183. Private1Header[19] = (i>>8)&0xff;
  184. Private1Header[20] = i&0xff;
  185. break;
  186. }
  187. }
  188. }
  189. else if(*subtype == MEDIASUBTYPE_DTS)
  190. {
  191. for(int i = 0; i < curlen; i++)
  192. {
  193. if(*(DWORD*)&pIn[i] == 0x0180FE7F)
  194. {
  195. i++;
  196. Private1Header[19] = (i>>8)&0xff;
  197. Private1Header[20] = i&0xff;
  198. break;
  199. }
  200. }
  201. }
  202. memcpy(pOut, &Private1Header, sizeof(Private1Header));
  203. pOut += sizeof(Private1Header);
  204. majortype = &MEDIATYPE_Audio;
  205. }
  206. if(*majortype == MEDIATYPE_Audio)
  207. {
  208. if(size < curlen) return E_FAIL;
  209. memcpy(pOut, pIn, curlen);
  210. pIn += curlen;
  211. pOut += curlen;
  212. }
  213. pOutSample->SetActualDataLength(pOut - pOutOrg);
  214. hr = m_pOutput->Deliver(pOutSample);
  215. }
  216. return S_FALSE;
  217. }
  218. else // phew, we can do the easier way
  219. {
  220. const GUID* majortype = &m_pOutput->CurrentMediaType().majortype;
  221. const GUID* subtype = &m_pOutput->CurrentMediaType().subtype;
  222. if(*majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
  223. {
  224. if(size < len + 32 + 3) return E_FAIL;
  225. BYTE PESHeader[] = 
  226. {
  227. 0x00,0x00,0x01,0xBA, // PES id
  228. 0x44,0x00,0x04,0x00,0x04,0x01, // SCR (0)
  229. 0x01,0x89,0xC3,0xF8, // mux rate (1260000 bytes/sec, 22bits), marker (2bits), reserved (~0, 5bits), stuffing (0, 3bits)
  230. };
  231. memcpy(pOut, &PESHeader, sizeof(PESHeader));
  232. pOut += sizeof(PESHeader);
  233. majortype = &MEDIATYPE_MPEG2_PES;
  234. }
  235. if(*majortype == MEDIATYPE_MPEG2_PES)
  236. {
  237. if(size < len + 20 + 3) return E_FAIL;
  238. BYTE Private1Header[] = 
  239. {
  240. 0x00,0x00,0x01,0xBD, // private stream 1 id
  241. 0x07,0xEC, // packet length (TODO: modify it later)
  242. 0x81,0x80, // marker, original, PTS - flags
  243. 0x08, // packet data starting offset
  244. 0x21,0x00,0x01,0x00,0x01, // PTS (0)
  245. 0xFF,0xFF,0xFF, // stuffing
  246. 0x80, // stream id (0)
  247. 0x01,0x00,0x01, // no idea about the first byte, the sencond+third seem to show the ac3/dts header sync offset plus one (dvd2avi doesn't output it to the ac3/dts file so we have to put it back)
  248. };
  249. int packetlen = len + 12 + 3;
  250. ASSERT(packetlen <= 0xffff);
  251. Private1Header[4] = (packetlen>>8)&0xff;
  252. Private1Header[5] = packetlen&0xff;
  253. if(*subtype == MEDIASUBTYPE_DTS)
  254. {
  255. Private1Header[17] += 8;
  256. }
  257. memcpy(pOut, &Private1Header, sizeof(Private1Header));
  258. pOut += sizeof(Private1Header);
  259. majortype = &MEDIATYPE_Audio;
  260. }
  261. if(*majortype == MEDIATYPE_Audio)
  262. {
  263. if(size < len) return E_FAIL;
  264. memcpy(pOut, pIn, len);
  265. pIn += len;
  266. pOut += len;
  267. }
  268. }
  269. }
  270. else
  271. {
  272. return E_FAIL;
  273. }
  274. pOutSample->SetActualDataLength(pOut - pOutOrg);
  275. return S_OK;
  276. }
  277. bool CAVI2AC3Filter::CheckAC3(const CMediaType* pmt)
  278. {
  279. return (pmt->majortype == MEDIATYPE_Audio
  280. || pmt->majortype == MEDIATYPE_MPEG2_PES 
  281. || pmt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
  282. && pmt->subtype == MEDIASUBTYPE_DOLBY_AC3;
  283. }
  284. bool CAVI2AC3Filter::CheckDTS(const CMediaType* pmt)
  285. {
  286. return (pmt->majortype == MEDIATYPE_Audio
  287. || pmt->majortype == MEDIATYPE_MPEG2_PES 
  288. || pmt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
  289. && pmt->subtype == MEDIASUBTYPE_DTS;
  290. }
  291. bool CAVI2AC3Filter::CheckWAVEAC3(const CMediaType* pmt)
  292. {
  293. return pmt->majortype == MEDIATYPE_Audio
  294. && pmt->subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3
  295. && pmt->formattype == FORMAT_WaveFormatEx
  296. && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3;
  297. }
  298. bool CAVI2AC3Filter::CheckWAVEDTS(const CMediaType* pmt)
  299. {
  300. return pmt->majortype == MEDIATYPE_Audio
  301. && pmt->subtype == MEDIASUBTYPE_WAVE_DTS
  302. && pmt->formattype == FORMAT_WaveFormatEx
  303. && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DVD_DTS;
  304. }
  305. HRESULT CAVI2AC3Filter::CheckInputType(const CMediaType* mtIn)
  306. {
  307. bool fWaveFormatEx = !!(mtIn->formattype == FORMAT_WaveFormatEx);
  308. return CheckAC3(mtIn) && fWaveFormatEx || CheckDTS(mtIn) && fWaveFormatEx
  309. || CheckWAVEAC3(mtIn) || CheckWAVEDTS(mtIn)
  310. ? S_OK
  311. : VFW_E_TYPE_NOT_ACCEPTED;
  312. }
  313. HRESULT CAVI2AC3Filter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
  314. {
  315. return CheckAC3(mtIn) && CheckWAVEAC3(mtOut)
  316. || CheckWAVEAC3(mtIn) && CheckAC3(mtOut)
  317. || CheckDTS(mtIn) && CheckWAVEDTS(mtOut)
  318. || CheckWAVEDTS(mtIn) && CheckDTS(mtOut)
  319. ? S_OK
  320. : VFW_E_TYPE_NOT_ACCEPTED;
  321. }
  322. HRESULT CAVI2AC3Filter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
  323. {
  324. if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  325. CComPtr<IMemAllocator> pAllocatorIn;
  326. m_pInput->GetAllocator(&pAllocatorIn);
  327. if(!pAllocatorIn) return E_UNEXPECTED;
  328. pAllocatorIn->GetProperties(pProperties);
  329. pProperties->cBuffers = 2;
  330. pProperties->cbBuffer = max(pProperties->cbBuffer, 1024*1024); // this should be enough...
  331. pProperties->cbAlign = 1;
  332. pProperties->cbPrefix = 0;
  333. HRESULT hr;
  334. ALLOCATOR_PROPERTIES Actual;
  335.     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) 
  336. return hr;
  337.     return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
  338. ? E_FAIL
  339. : NOERROR);
  340. }
  341. HRESULT CAVI2AC3Filter::GetMediaType(int iPosition, CMediaType* pMediaType)
  342. {
  343.     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  344. const GUID& majortype = m_pInput->CurrentMediaType().majortype;
  345. const GUID& subtype = m_pInput->CurrentMediaType().subtype;
  346. if(CheckAC3(&m_pInput->CurrentMediaType()) || CheckDTS(&m_pInput->CurrentMediaType()))
  347. {
  348. if(iPosition < 0) return E_INVALIDARG;
  349. if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
  350. pMediaType->majortype = MEDIATYPE_Audio;
  351. pMediaType->formattype = FORMAT_WaveFormatEx;
  352. WAVEFORMATEX* wfe = (WAVEFORMATEX*)pMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
  353. memset(wfe, 0, sizeof(WAVEFORMATEX));
  354. wfe->cbSize = sizeof(WAVEFORMATEX);
  355. wfe->nAvgBytesPerSec = ((WAVEFORMATEX*)m_pInput->CurrentMediaType().pbFormat)->nAvgBytesPerSec;
  356. wfe->nSamplesPerSec = ((WAVEFORMATEX*)m_pInput->CurrentMediaType().pbFormat)->nSamplesPerSec;
  357. wfe->wBitsPerSample = ((WAVEFORMATEX*)m_pInput->CurrentMediaType().pbFormat)->wBitsPerSample;
  358. wfe->nChannels = 2;
  359. wfe->nBlockAlign = 1;
  360. if(subtype == MEDIASUBTYPE_DOLBY_AC3)
  361. {
  362. pMediaType->subtype = MEDIASUBTYPE_WAVE_DOLBY_AC3;
  363. wfe->wFormatTag = WAVE_FORMAT_DOLBY_AC3;
  364. }
  365. else if(subtype == MEDIASUBTYPE_DTS)
  366. {
  367. pMediaType->subtype = MEDIASUBTYPE_WAVE_DTS;
  368. wfe->wFormatTag = WAVE_FORMAT_DVD_DTS;
  369. }
  370. else
  371. {
  372. return E_INVALIDARG;
  373. }
  374. }
  375. else if(CheckWAVEAC3(&m_pInput->CurrentMediaType()) || CheckWAVEDTS(&m_pInput->CurrentMediaType()))
  376. {
  377. if(iPosition < 0) return E_INVALIDARG;
  378. if(iPosition > 4) return VFW_S_NO_MORE_ITEMS;
  379. if(subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3)
  380. {
  381. pMediaType->subtype = MEDIASUBTYPE_DOLBY_AC3;
  382. pMediaType->formattype = FORMAT_WaveFormatEx;
  383. DOLBYAC3WAVEFORMAT* wfe = (DOLBYAC3WAVEFORMAT*)pMediaType->AllocFormatBuffer(sizeof(DOLBYAC3WAVEFORMAT));
  384. memset(wfe, 0, sizeof(DOLBYAC3WAVEFORMAT));
  385. // unfortunately we can't tell what we are going to get in transform, 
  386. // so we just set the most common values and hope that the ac3 decoder 
  387. // is flexible enough (it is usually :) to find out these from the bitstream
  388. wfe->wfx.cbSize = sizeof(DOLBYAC3WAVEFORMAT) - sizeof(WAVEFORMATEX);
  389. wfe->wfx.wFormatTag = WAVE_FORMAT_DOLBY_AC3;
  390. wfe->wfx.nSamplesPerSec = 48000;
  391. wfe->wfx.nChannels = 6;
  392. wfe->bBigEndian = TRUE;
  393. }
  394. else if(subtype == MEDIASUBTYPE_WAVE_DTS)
  395. {
  396. pMediaType->subtype = MEDIASUBTYPE_DTS;
  397. pMediaType->formattype = FORMAT_WaveFormatEx;
  398. WAVEFORMATEX* wfe = (WAVEFORMATEX*)pMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
  399. memset(wfe, 0, sizeof(WAVEFORMATEX));
  400. // same case as with ac3, but this time we don't even know the structure
  401. wfe->cbSize = sizeof(WAVEFORMATEX);
  402. wfe->wFormatTag = WAVE_FORMAT_PCM;
  403. wfe->nSamplesPerSec = 48000;
  404. wfe->nChannels = 6;
  405. }
  406. else
  407. {
  408. return E_INVALIDARG;
  409. }
  410. switch(iPosition)
  411. {
  412. case 0:
  413. pMediaType->majortype = MEDIATYPE_Audio;
  414. break;
  415. case 1:
  416. pMediaType->ResetFormatBuffer();
  417. pMediaType->formattype = FORMAT_None;
  418. case 2:
  419. pMediaType->majortype = MEDIATYPE_MPEG2_PES;
  420. break;
  421. case 3:
  422. pMediaType->ResetFormatBuffer();
  423. pMediaType->formattype = FORMAT_None;
  424. case 4:
  425. pMediaType->majortype = MEDIATYPE_DVD_ENCRYPTED_PACK;
  426. break;
  427. default:
  428. return E_INVALIDARG;
  429. }
  430. }
  431. else
  432. {
  433. return VFW_S_NO_MORE_ITEMS;
  434. }
  435. return S_OK;
  436. }