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

多媒体编程

开发平台:

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 "subtitlesource.h"
  23. #include "......DSUtilDSUtil.h"
  24. #include <initguid.h>
  25. #include "........includematroskamatroska.h"
  26. static int _WIDTH = 640;
  27. static int _HEIGHT = 480;
  28. static int _ATPF = 400000;
  29. #ifdef REGISTER_FILTER
  30. const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
  31. {
  32. {&MEDIATYPE_Subtitle, &MEDIASUBTYPE_NULL},
  33. {&MEDIATYPE_Text, &MEDIASUBTYPE_NULL},
  34. {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB32},
  35. };
  36. const AMOVIESETUP_PIN sudOpPin[] =
  37. {
  38. {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut},
  39. };
  40. const AMOVIESETUP_FILTER sudFilter[] =
  41. {
  42. {&__uuidof(CSubtitleSourceASCII), L"SubtitleSource (S_TEXT/ASCII)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  43. {&__uuidof(CSubtitleSourceUTF8), L"SubtitleSource (S_TEXT/UTF8)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  44. {&__uuidof(CSubtitleSourceSSA), L"SubtitleSource (S_TEXT/SSA)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  45. {&__uuidof(CSubtitleSourceASS), L"SubtitleSource (S_TEXT/ASS)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  46. {&__uuidof(CSubtitleSourceUSF), L"SubtitleSource (S_TEXT/USF)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  47. {&__uuidof(CSubtitleSourcePreview), L"SubtitleSource (Preview)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  48. {&__uuidof(CSubtitleSourceARGB), L"SubtitleSource (ARGB)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
  49. };
  50. CFactoryTemplate g_Templates[] =
  51. {
  52. {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CSubtitleSourceASCII>, NULL, &sudFilter[0]},
  53. {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CSubtitleSourceUTF8>, NULL, &sudFilter[1]},
  54. {sudFilter[2].strName, sudFilter[2].clsID, CreateInstance<CSubtitleSourceSSA>, NULL, &sudFilter[2]},
  55. {sudFilter[3].strName, sudFilter[3].clsID, CreateInstance<CSubtitleSourceASS>, NULL, &sudFilter[3]},
  56. // {sudFilter[4].strName, sudFilter[4].clsID, CreateInstance<CSubtitleSourceUSF>, NULL, &sudFilter[4]},
  57. {sudFilter[5].strName, sudFilter[5].clsID, CreateInstance<CSubtitleSourcePreview>, NULL, &sudFilter[5]},
  58. {sudFilter[6].strName, sudFilter[6].clsID, CreateInstance<CSubtitleSourceARGB>, NULL, &sudFilter[6]},
  59. };
  60. int g_cTemplates = countof(g_Templates);
  61. //#include "registry.cpp"
  62. STDAPI DllRegisterServer()
  63. {
  64. /*
  65. CString clsid = CStringFromGUID(__uuidof(CSubtitleSourcePreview));
  66. SetRegKeyValue(
  67. _T("Media Type\Extensions"), _T(".sub"), 
  68. _T("Source Filter"), clsid);
  69. SetRegKeyValue(
  70. _T("Media Type\Extensions"), _T(".srt"), 
  71. _T("Source Filter"), clsid);
  72. SetRegKeyValue(
  73. _T("Media Type\Extensions"), _T(".smi"), 
  74. _T("Source Filter"), clsid);
  75. SetRegKeyValue(
  76. _T("Media Type\Extensions"), _T(".ssa"), 
  77. _T("Source Filter"), clsid);
  78. SetRegKeyValue(
  79. _T("Media Type\Extensions"), _T(".ass"), 
  80. _T("Source Filter"), clsid);
  81. SetRegKeyValue(
  82. _T("Media Type\Extensions"), _T(".xss"), 
  83. _T("Source Filter"), clsid);
  84. SetRegKeyValue(
  85. _T("Media Type\Extensions"), _T(".usf"), 
  86. _T("Source Filter"), clsid);
  87. */
  88. return AMovieDllRegisterServer2(TRUE);
  89. }
  90. STDAPI DllUnregisterServer()
  91. {
  92. DeleteRegKey(_T("Media Type\Extensions"), _T(".sub"));
  93. DeleteRegKey(_T("Media Type\Extensions"), _T(".srt"));
  94. DeleteRegKey(_T("Media Type\Extensions"), _T(".smi"));
  95. DeleteRegKey(_T("Media Type\Extensions"), _T(".ssa"));
  96. DeleteRegKey(_T("Media Type\Extensions"), _T(".ass"));
  97. DeleteRegKey(_T("Media Type\Extensions"), _T(".xss"));
  98. DeleteRegKey(_T("Media Type\Extensions"), _T(".usf"));
  99. /**/
  100. return AMovieDllRegisterServer2(FALSE);
  101. }
  102. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  103. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  104. {
  105. if(dwReason == DLL_PROCESS_ATTACH)
  106. {
  107. _WIDTH = GetProfileInt(_T("SubtitleSource"), _T("w"), 640);
  108. _HEIGHT = GetProfileInt(_T("SubtitleSource"), _T("h"), 480);
  109. _ATPF = GetProfileInt(_T("SubtitleSource"), _T("atpf"), 400000);
  110. if(_ATPF <= 0) _ATPF = 400000;
  111. CString str; 
  112. str.Format(_T("%d"), _WIDTH);
  113. WriteProfileString(_T("SubtitleSource"), _T("w"), str);
  114. str.Format(_T("%d"), _HEIGHT);
  115. WriteProfileString(_T("SubtitleSource"), _T("h"), str);
  116. str.Format(_T("%d"), _ATPF);
  117. WriteProfileString(_T("SubtitleSource"), _T("atpf"), str);
  118. }
  119.     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  120. }
  121. #endif
  122. //
  123. // CSubtitleSource
  124. //
  125. CSubtitleSource::CSubtitleSource(LPUNKNOWN lpunk, HRESULT* phr, const CLSID& clsid)
  126. : CSource(NAME("CSubtitleSource"), lpunk, clsid)
  127. {
  128. }
  129. CSubtitleSource::~CSubtitleSource()
  130. {
  131. }
  132. STDMETHODIMP CSubtitleSource::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  133. {
  134.     CheckPointer(ppv, E_POINTER);
  135. return 
  136. QI(IFileSourceFilter)
  137. QI(IAMFilterMiscFlags)
  138. __super::NonDelegatingQueryInterface(riid, ppv);
  139. }
  140. // IFileSourceFilter
  141. STDMETHODIMP CSubtitleSource::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt) 
  142. {
  143. if(GetPinCount() > 0)
  144. return VFW_E_ALREADY_CONNECTED;
  145. HRESULT hr = S_OK;
  146. if(!(new CSubtitleStream(pszFileName, this, &hr)))
  147. return E_OUTOFMEMORY;
  148. if(FAILED(hr))
  149. return hr;
  150. m_fn = pszFileName;
  151. return S_OK;
  152. }
  153. STDMETHODIMP CSubtitleSource::GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt)
  154. {
  155. if(!ppszFileName) return E_POINTER;
  156. if(!(*ppszFileName = (LPOLESTR)CoTaskMemAlloc((m_fn.GetLength()+1)*sizeof(WCHAR))))
  157. return E_OUTOFMEMORY;
  158. wcscpy(*ppszFileName, m_fn);
  159. return S_OK;
  160. }
  161. // IAMFilterMiscFlags
  162. ULONG CSubtitleSource::GetMiscFlags()
  163. {
  164. return AM_FILTER_MISC_FLAGS_IS_SOURCE;
  165. }
  166. //
  167. // CSubtitleStream
  168. //
  169. CSubtitleStream::CSubtitleStream(const WCHAR* wfn, CSubtitleSource* pParent, HRESULT* phr) 
  170. : CSourceStream(NAME("SubtitleStream"), phr, pParent, L"Output")
  171. , CSourceSeeking(NAME("SubtitleStream"), (IPin*)this, phr, &m_cSharedState)
  172. , m_bDiscontinuity(FALSE), m_bFlushing(FALSE)
  173. , m_nPosition(0)
  174. , m_rts(NULL)
  175. {
  176. CAutoLock cAutoLock(&m_cSharedState);
  177. CString fn(wfn);
  178. if(!m_rts.Open(fn, DEFAULT_CHARSET))
  179. {
  180. if(phr) *phr = E_FAIL;
  181. return;
  182. }
  183. m_rts.CreateDefaultStyle(DEFAULT_CHARSET);
  184. m_rts.ConvertToTimeBased(25);
  185. m_rts.Sort();
  186. m_rtDuration = 0;
  187. for(int i = 0, cnt = m_rts.GetCount(); i < cnt; i++)
  188. m_rtDuration = max(m_rtDuration, 10000i64*m_rts[i].end);
  189. m_rtStop = m_rtDuration;
  190. if(phr) *phr = m_rtDuration > 0 ? S_OK : E_FAIL;
  191. }
  192. CSubtitleStream::~CSubtitleStream()
  193. {
  194. CAutoLock cAutoLock(&m_cSharedState);
  195. }
  196. STDMETHODIMP CSubtitleStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  197. {
  198.     CheckPointer(ppv, E_POINTER);
  199. return (riid == IID_IMediaSeeking) ? CSourceSeeking::NonDelegatingQueryInterface(riid, ppv) //GetInterface((IMediaSeeking*)this, ppv)
  200. : CSourceStream::NonDelegatingQueryInterface(riid, ppv);
  201. }
  202. void CSubtitleStream::UpdateFromSeek()
  203. {
  204. if(ThreadExists())
  205. {
  206. // next time around the loop, the worker thread will
  207. // pick up the position change.
  208. // We need to flush all the existing data - we must do that here
  209. // as our thread will probably be blocked in GetBuffer otherwise
  210.     
  211. m_bFlushing = TRUE;
  212. DeliverBeginFlush();
  213. // make sure we have stopped pushing
  214. Stop();
  215. // complete the flush
  216. DeliverEndFlush();
  217.         m_bFlushing = FALSE;
  218. // restart
  219. Run();
  220. }
  221. }
  222. HRESULT CSubtitleStream::SetRate(double dRate)
  223. {
  224. if(dRate <= 0)
  225. return E_INVALIDARG;
  226. {
  227. CAutoLock lock(CSourceSeeking::m_pLock);
  228. m_dRateSeeking = dRate;
  229. }
  230. UpdateFromSeek();
  231. return S_OK;
  232. }
  233. HRESULT CSubtitleStream::OnThreadStartPlay()
  234. {
  235.     m_bDiscontinuity = TRUE;
  236.     return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
  237. }
  238. HRESULT CSubtitleStream::ChangeStart()
  239. {
  240.     {
  241.         CAutoLock lock(CSourceSeeking::m_pLock);
  242. OnThreadCreate();
  243. /*
  244. if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_ARGB32)
  245. {
  246. m_nPosition = (int)(m_rtStart/10000)*1/1000;
  247. }
  248. else if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_RGB32)
  249. {
  250. int m_nSegments = 0;
  251. if(!m_rts.SearchSubs((int)(m_rtStart/10000), 25, &m_nPosition, &m_nSegments))
  252. m_nPosition = m_nSegments;
  253. }
  254. else
  255. {
  256. m_nPosition = m_rts.SearchSub((int)(m_rtStart/10000), 25);
  257. if(m_nPosition < 0) m_nPosition = 0;
  258. else if(m_rts[m_nPosition].end <= (int)(m_rtStart/10000)) m_nPosition++;
  259. }
  260. */    }
  261.     UpdateFromSeek();
  262.     return S_OK;
  263. }
  264. HRESULT CSubtitleStream::ChangeStop()
  265. {
  266. /*
  267.     {
  268.         CAutoLock lock(CSourceSeeking::m_pLock);
  269.         if(m_rtPosition < m_rtStop)
  270. return S_OK;
  271.     }
  272. */
  273.     // We're already past the new stop time -- better flush the graph.
  274.     UpdateFromSeek();
  275.     return S_OK;
  276. }
  277. HRESULT CSubtitleStream::OnThreadCreate()
  278. {
  279.     CAutoLock cAutoLockShared(&m_cSharedState);
  280. if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_ARGB32)
  281. {
  282. m_nPosition = m_rtStart/_ATPF;
  283. }
  284. else if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_RGB32)
  285. {
  286. int m_nSegments = 0;
  287. if(!m_rts.SearchSubs((int)(m_rtStart/10000), 10000000/_ATPF, &m_nPosition, &m_nSegments))
  288. m_nPosition = m_nSegments;
  289. }
  290. else
  291. {
  292. m_nPosition = m_rts.SearchSub((int)(m_rtStart/10000), 25);
  293. if(m_nPosition < 0) m_nPosition = 0;
  294. else if(m_rts[m_nPosition].end <= (int)(m_rtStart/10000)) m_nPosition++;
  295. }
  296.     return CSourceStream::OnThreadCreate();
  297. }
  298. HRESULT CSubtitleStream::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
  299. {
  300. //    CAutoLock cAutoLock(m_pFilter->pStateLock());
  301.     ASSERT(pAlloc);
  302.     ASSERT(pProperties);
  303.     HRESULT hr = NOERROR;
  304. if(m_mt.majortype == MEDIATYPE_Video)
  305. {
  306. pProperties->cBuffers = 2;
  307. pProperties->cbBuffer = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biSizeImage;
  308. }
  309. else
  310. {
  311. pProperties->cBuffers = 1;
  312. pProperties->cbBuffer = 0x10000;
  313. }
  314.     ALLOCATOR_PROPERTIES Actual;
  315.     if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
  316.     if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
  317.     ASSERT(Actual.cBuffers == pProperties->cBuffers);
  318.     return NOERROR;
  319. }
  320. HRESULT CSubtitleStream::FillBuffer(IMediaSample* pSample)
  321. {
  322. HRESULT hr;
  323. {
  324. CAutoLock cAutoLockShared(&m_cSharedState);
  325. BYTE* pData = NULL;
  326. if(FAILED(hr = pSample->GetPointer(&pData)) || !pData)
  327. return S_FALSE;
  328. AM_MEDIA_TYPE* pmt;
  329. if(SUCCEEDED(pSample->GetMediaType(&pmt)) && pmt)
  330. {
  331. CMediaType mt(*pmt);
  332. SetMediaType(&mt);
  333. DeleteMediaType(pmt);
  334. }
  335. int len = 0;
  336. REFERENCE_TIME rtStart, rtStop;
  337. if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_ARGB32)
  338. {
  339. rtStart = (REFERENCE_TIME)((m_nPosition*_ATPF - m_rtStart) / m_dRateSeeking);
  340. rtStop = (REFERENCE_TIME)(((m_nPosition+1)*_ATPF - m_rtStart) / m_dRateSeeking);
  341. if(m_rtStart+rtStart >= m_rtDuration)
  342. return S_FALSE;
  343. BITMAPINFOHEADER& bmi = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader;
  344. SubPicDesc spd;
  345. spd.w = _WIDTH;
  346. spd.h = _HEIGHT;
  347. spd.bpp = 32;
  348. spd.pitch = bmi.biWidth*4;
  349. spd.bits = pData;
  350. len = spd.h*spd.pitch;
  351. for(int y = 0; y < spd.h; y++)
  352. memsetd((DWORD*)(pData + spd.pitch*y), 0xff000000, spd.w*4);
  353. RECT bbox;
  354. m_rts.Render(spd, m_nPosition*_ATPF, 10000000.0/_ATPF, bbox);
  355. for(int y = 0; y < spd.h; y++)
  356. {
  357. DWORD* p = (DWORD*)(pData + spd.pitch*y);
  358. for(int x = 0; x < spd.w; x++, p++)
  359. *p = (0xff000000-(*p&0xff000000))|(*p&0xffffff);
  360. }
  361. }
  362. else if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_RGB32)
  363. {
  364. const STSSegment* stss = m_rts.GetSegment(m_nPosition);
  365. if(!stss) return S_FALSE;
  366. BITMAPINFOHEADER& bmi = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader;
  367. SubPicDesc spd;
  368. spd.w = _WIDTH;
  369. spd.h = _HEIGHT;
  370. spd.bpp = 32;
  371. spd.pitch = bmi.biWidth*4;
  372. spd.bits = pData;
  373. len = spd.h*spd.pitch;
  374. for(int y = 0; y < spd.h; y++)
  375. {
  376. DWORD c1 = 0xff606060, c2 = 0xffa0a0a0;
  377. if(y&32) c1 ^= c2, c2 ^= c1, c1 ^= c2;
  378. DWORD* p = (DWORD*)(pData + spd.pitch*y);
  379. for(int x = 0; x < spd.w; x+=32, p+=32)
  380. memsetd(p, (x&32) ? c1 : c2, min(spd.w-x,32)*4);
  381. }
  382. RECT bbox;
  383. m_rts.Render(spd, 10000i64*(stss->start+stss->end)/2, 10000000.0/_ATPF, bbox);
  384. rtStart = (REFERENCE_TIME)((10000i64*stss->start - m_rtStart) / m_dRateSeeking);
  385. rtStop = (REFERENCE_TIME)((10000i64*stss->end - m_rtStart) / m_dRateSeeking);
  386. }
  387. else
  388. {
  389. if(m_nPosition >= m_rts.GetCount())
  390. return S_FALSE;
  391. STSEntry& stse = m_rts[m_nPosition];
  392. if(stse.start >= m_rtStop/10000)
  393. return S_FALSE;
  394. if(m_mt.majortype == MEDIATYPE_Subtitle && m_mt.subtype == MEDIASUBTYPE_UTF8)
  395. {
  396. CStringA str = UTF16To8(m_rts.GetStrW(m_nPosition, false));
  397. memcpy((char*)pData, str, len = str.GetLength());
  398. }
  399. else if(m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS))
  400. {
  401. CStringW line;
  402. line.Format(L"%d,%d,%s,%s,%d,%d,%d,%s,%s", 
  403. stse.readorder, stse.layer, CStringW(stse.style), CStringW(stse.actor), 
  404. stse.marginRect.left, stse.marginRect.right, (stse.marginRect.top+stse.marginRect.bottom)/2,
  405. CStringW(stse.effect), m_rts.GetStrW(m_nPosition, true));
  406. CStringA str = UTF16To8(line);
  407. memcpy((char*)pData, str, len = str.GetLength());
  408. }
  409. else if(m_mt.majortype == MEDIATYPE_Text && m_mt.subtype == MEDIASUBTYPE_NULL)
  410. {
  411. CStringA str = m_rts.GetStrA(m_nPosition, false);
  412. memcpy((char*)pData, str, len = str.GetLength());
  413. }
  414. else
  415. {
  416. return S_FALSE;
  417. }
  418. rtStart = (REFERENCE_TIME)((10000i64*stse.start - m_rtStart) / m_dRateSeeking);
  419. rtStop = (REFERENCE_TIME)((10000i64*stse.end - m_rtStart) / m_dRateSeeking);
  420. }
  421. pSample->SetTime(&rtStart, &rtStop);
  422. pSample->SetActualDataLength(len);
  423. m_nPosition++;
  424. }
  425. pSample->SetSyncPoint(TRUE);
  426. if(m_bDiscontinuity) 
  427.     {
  428. pSample->SetDiscontinuity(TRUE);
  429. m_bDiscontinuity = FALSE;
  430. }
  431. return S_OK;
  432. }
  433. HRESULT CSubtitleStream::GetMediaType(CMediaType* pmt)
  434. {
  435. return ((CSubtitleSource*)m_pFilter)->GetMediaType(pmt);
  436. }
  437. HRESULT CSubtitleStream::CheckMediaType(const CMediaType* pmt)
  438. {
  439.     CAutoLock lock(m_pFilter->pStateLock());
  440.     CMediaType mt;
  441.     GetMediaType(&mt);
  442. if(mt.majortype == pmt->majortype && mt.subtype == pmt->subtype)
  443. {
  444.         return NOERROR;
  445.     }
  446.     return E_FAIL;
  447. }
  448. STDMETHODIMP CSubtitleStream::Notify(IBaseFilter* pSender, Quality q)
  449. {
  450. return E_NOTIMPL;
  451. }
  452. //
  453. // CSubtitleSourceASCII
  454. //
  455. CSubtitleSourceASCII::CSubtitleSourceASCII(LPUNKNOWN lpunk, HRESULT* phr)
  456. : CSubtitleSource(lpunk, phr, __uuidof(this))
  457. {
  458. }
  459. HRESULT CSubtitleSourceASCII::GetMediaType(CMediaType* pmt)
  460. {
  461.     CAutoLock cAutoLock(pStateLock());
  462. pmt->InitMediaType();
  463. pmt->SetType(&MEDIATYPE_Text);
  464. pmt->SetSubtype(&MEDIASUBTYPE_NULL);
  465. pmt->SetFormatType(&FORMAT_None);
  466. pmt->ResetFormatBuffer();
  467.     return NOERROR;
  468. }
  469. //
  470. // CSubtitleSourceUTF8
  471. //
  472. CSubtitleSourceUTF8::CSubtitleSourceUTF8(LPUNKNOWN lpunk, HRESULT* phr)
  473. : CSubtitleSource(lpunk, phr, __uuidof(this))
  474. {
  475. }
  476. HRESULT CSubtitleSourceUTF8::GetMediaType(CMediaType* pmt)
  477. {
  478.     CAutoLock cAutoLock(pStateLock());
  479. pmt->InitMediaType();
  480. pmt->SetType(&MEDIATYPE_Subtitle);
  481. pmt->SetSubtype(&MEDIASUBTYPE_UTF8);
  482. pmt->SetFormatType(&FORMAT_SubtitleInfo);
  483. SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO));
  484. memset(psi, 0, pmt->FormatLength());
  485. strcpy(psi->IsoLang, "eng");
  486.     return NOERROR;
  487. }
  488. //
  489. // CSubtitleSourceSSA
  490. //
  491. CSubtitleSourceSSA::CSubtitleSourceSSA(LPUNKNOWN lpunk, HRESULT* phr)
  492. : CSubtitleSource(lpunk, phr, __uuidof(this))
  493. {
  494. }
  495. HRESULT CSubtitleSourceSSA::GetMediaType(CMediaType* pmt)
  496. {
  497.     CAutoLock cAutoLock(pStateLock());
  498. pmt->InitMediaType();
  499. pmt->SetType(&MEDIATYPE_Subtitle);
  500. pmt->SetSubtype(&MEDIASUBTYPE_SSA);
  501. pmt->SetFormatType(&FORMAT_SubtitleInfo);
  502. CSimpleTextSubtitle sts;
  503. sts.Open(CString(m_fn), DEFAULT_CHARSET);
  504. sts.RemoveAll();
  505. CFile f;
  506. TCHAR path[MAX_PATH], fn[MAX_PATH];
  507. if(!GetTempPath(MAX_PATH, path) || !GetTempFileName(path, _T("mpc_sts"), 0, fn))
  508. return E_FAIL;
  509. _tcscat(fn, _T(".ssa"));
  510. if(!sts.SaveAs(fn, EXTSSA, -1, CTextFile::UTF8) || !f.Open(fn, CFile::modeRead))
  511. return E_FAIL;
  512. int len = (int)f.GetLength()-3;
  513. f.Seek(3, CFile::begin);
  514. SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO) + len);
  515. memset(psi, 0, pmt->FormatLength());
  516. psi->dwOffset = sizeof(SUBTITLEINFO);
  517. strcpy(psi->IsoLang, "eng");
  518. f.Read(pmt->pbFormat + psi->dwOffset, len);
  519. f.Close();
  520. _tremove(fn);
  521.     return NOERROR;
  522. }
  523. //
  524. // CSubtitleSourceASS
  525. //
  526. CSubtitleSourceASS::CSubtitleSourceASS(LPUNKNOWN lpunk, HRESULT* phr)
  527. : CSubtitleSource(lpunk, phr, __uuidof(this))
  528. {
  529. }
  530. HRESULT CSubtitleSourceASS::GetMediaType(CMediaType* pmt)
  531. {
  532.     CAutoLock cAutoLock(pStateLock());
  533. pmt->InitMediaType();
  534. pmt->SetType(&MEDIATYPE_Subtitle);
  535. pmt->SetSubtype(&MEDIASUBTYPE_ASS);
  536. pmt->SetFormatType(&FORMAT_SubtitleInfo);
  537. CSimpleTextSubtitle sts;
  538. sts.Open(CString(m_fn), DEFAULT_CHARSET);
  539. sts.RemoveAll();
  540. CFile f;
  541. TCHAR path[MAX_PATH], fn[MAX_PATH];
  542. if(!GetTempPath(MAX_PATH, path) || !GetTempFileName(path, _T("mpc_sts"), 0, fn))
  543. return E_FAIL;
  544. _tcscat(fn, _T(".ass"));
  545. if(!sts.SaveAs(fn, EXTASS, -1, CTextFile::UTF8) || !f.Open(fn, CFile::modeRead))
  546. return E_FAIL;
  547. int len = (int)f.GetLength();
  548. SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO) + len);
  549. memset(psi, 0, pmt->FormatLength());
  550. psi->dwOffset = sizeof(SUBTITLEINFO);
  551. strcpy(psi->IsoLang, "eng");
  552. f.Read(pmt->pbFormat + psi->dwOffset, len);
  553. f.Close();
  554. _tremove(fn);
  555.     return NOERROR;
  556. }
  557. //
  558. // CSubtitleSourceUSF
  559. //
  560. CSubtitleSourceUSF::CSubtitleSourceUSF(LPUNKNOWN lpunk, HRESULT* phr)
  561. : CSubtitleSource(lpunk, phr, __uuidof(this))
  562. {
  563. }
  564. HRESULT CSubtitleSourceUSF::GetMediaType(CMediaType* pmt)
  565. {
  566.     CAutoLock cAutoLock(pStateLock());
  567. pmt->InitMediaType();
  568. pmt->SetType(&MEDIATYPE_Subtitle);
  569. pmt->SetSubtype(&MEDIASUBTYPE_USF);
  570. pmt->SetFormatType(&FORMAT_SubtitleInfo);
  571. SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO));
  572. memset(psi, 0, pmt->FormatLength());
  573. strcpy(psi->IsoLang, "eng");
  574. // TODO: ...
  575.     return NOERROR;
  576. }
  577. //
  578. // CSubtitleSourcePreview
  579. //
  580. CSubtitleSourcePreview::CSubtitleSourcePreview(LPUNKNOWN lpunk, HRESULT* phr)
  581. : CSubtitleSource(lpunk, phr, __uuidof(this))
  582. {
  583. }
  584. HRESULT CSubtitleSourcePreview::GetMediaType(CMediaType* pmt)
  585. {
  586.     CAutoLock cAutoLock(pStateLock());
  587. pmt->InitMediaType();
  588. pmt->SetType(&MEDIATYPE_Video);
  589. pmt->SetSubtype(&MEDIASUBTYPE_RGB32);
  590. pmt->SetFormatType(&FORMAT_VideoInfo);
  591. VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  592. memset(pvih, 0, pmt->FormatLength());
  593. pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader);
  594. pvih->bmiHeader.biWidth = _WIDTH;
  595. pvih->bmiHeader.biHeight = _HEIGHT;
  596. pvih->bmiHeader.biBitCount = 32;
  597. pvih->bmiHeader.biCompression = BI_RGB;
  598. pvih->bmiHeader.biPlanes = 1;
  599. pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth*abs(pvih->bmiHeader.biHeight)*pvih->bmiHeader.biBitCount>>3;
  600.     return NOERROR;
  601. }
  602. //
  603. // CSubtitleSourceARGB
  604. //
  605. CSubtitleSourceARGB::CSubtitleSourceARGB(LPUNKNOWN lpunk, HRESULT* phr)
  606. : CSubtitleSource(lpunk, phr, __uuidof(this))
  607. {
  608. }
  609. HRESULT CSubtitleSourceARGB::GetMediaType(CMediaType* pmt)
  610. {
  611.     CAutoLock cAutoLock(pStateLock());
  612. pmt->InitMediaType();
  613. pmt->SetType(&MEDIATYPE_Video);
  614. pmt->SetSubtype(&MEDIASUBTYPE_ARGB32);
  615. pmt->SetFormatType(&FORMAT_VideoInfo);
  616. VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  617. memset(pvih, 0, pmt->FormatLength());
  618. pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader);
  619. // TODO: read w,h,fps from a config file or registry
  620. pvih->bmiHeader.biWidth = _WIDTH;
  621. pvih->bmiHeader.biHeight = _HEIGHT;
  622. pvih->bmiHeader.biBitCount = 32;
  623. pvih->bmiHeader.biCompression = BI_RGB;
  624. pvih->bmiHeader.biPlanes = 1;
  625. pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth*abs(pvih->bmiHeader.biHeight)*pvih->bmiHeader.biBitCount>>3;
  626.     return NOERROR;
  627. }