SubtitleSource.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include "subtitlesource.h"
00024 #include "..\..\..\DSUtil\DSUtil.h"
00025 
00026 #include <initguid.h>
00027 #include "..\..\..\..\include\matroska\matroska.h"
00028 
00029 static int _WIDTH = 640;
00030 static int _HEIGHT = 480;
00031 static int _ATPF = 400000;
00032 
00033 #ifdef REGISTER_FILTER
00034 
00035 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00036 {
00037         {&MEDIATYPE_Subtitle, &MEDIASUBTYPE_NULL},
00038         {&MEDIATYPE_Text, &MEDIASUBTYPE_NULL},
00039         {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB32},
00040 };
00041 
00042 const AMOVIESETUP_PIN sudOpPin[] =
00043 {
00044         {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut},
00045 };
00046 
00047 const AMOVIESETUP_FILTER sudFilter[] =
00048 {
00049         {&__uuidof(CSubtitleSourceASCII), L"SubtitleSource (S_TEXT/ASCII)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00050         {&__uuidof(CSubtitleSourceUTF8), L"SubtitleSource (S_TEXT/UTF8)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00051         {&__uuidof(CSubtitleSourceSSA), L"SubtitleSource (S_TEXT/SSA)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00052         {&__uuidof(CSubtitleSourceASS), L"SubtitleSource (S_TEXT/ASS)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00053         {&__uuidof(CSubtitleSourceUSF), L"SubtitleSource (S_TEXT/USF)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00054         {&__uuidof(CSubtitleSourcePreview), L"SubtitleSource (Preview)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00055         {&__uuidof(CSubtitleSourceARGB), L"SubtitleSource (ARGB)", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin},
00056 };
00057 
00058 CFactoryTemplate g_Templates[] =
00059 {
00060         {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CSubtitleSourceASCII>, NULL, &sudFilter[0]},
00061         {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CSubtitleSourceUTF8>, NULL, &sudFilter[1]},
00062         {sudFilter[2].strName, sudFilter[2].clsID, CreateInstance<CSubtitleSourceSSA>, NULL, &sudFilter[2]},
00063         {sudFilter[3].strName, sudFilter[3].clsID, CreateInstance<CSubtitleSourceASS>, NULL, &sudFilter[3]},
00064 //      {sudFilter[4].strName, sudFilter[4].clsID, CreateInstance<CSubtitleSourceUSF>, NULL, &sudFilter[4]},
00065         {sudFilter[5].strName, sudFilter[5].clsID, CreateInstance<CSubtitleSourcePreview>, NULL, &sudFilter[5]},
00066         {sudFilter[6].strName, sudFilter[6].clsID, CreateInstance<CSubtitleSourceARGB>, NULL, &sudFilter[6]},
00067 };
00068 
00069 int g_cTemplates = countof(g_Templates);
00070 
00071 #include "..\..\registry.cpp"
00072 
00073 STDAPI DllRegisterServer()
00074 {
00075 /*
00076         CString clsid = CStringFromGUID(__uuidof(CSubtitleSourcePreview));
00077 
00078         SetRegKeyValue(
00079                 _T("Media Type\\Extensions"), _T(".sub"), 
00080                 _T("Source Filter"), clsid);
00081 
00082         SetRegKeyValue(
00083                 _T("Media Type\\Extensions"), _T(".srt"), 
00084                 _T("Source Filter"), clsid);
00085 
00086         SetRegKeyValue(
00087                 _T("Media Type\\Extensions"), _T(".smi"), 
00088                 _T("Source Filter"), clsid);
00089 
00090         SetRegKeyValue(
00091                 _T("Media Type\\Extensions"), _T(".ssa"), 
00092                 _T("Source Filter"), clsid);
00093 
00094         SetRegKeyValue(
00095                 _T("Media Type\\Extensions"), _T(".ass"), 
00096                 _T("Source Filter"), clsid);
00097 
00098         SetRegKeyValue(
00099                 _T("Media Type\\Extensions"), _T(".xss"), 
00100                 _T("Source Filter"), clsid);
00101 
00102         SetRegKeyValue(
00103                 _T("Media Type\\Extensions"), _T(".usf"), 
00104                 _T("Source Filter"), clsid);
00105 */
00106         return AMovieDllRegisterServer2(TRUE);
00107 }
00108 
00109 STDAPI DllUnregisterServer()
00110 {
00111         DeleteRegKey(_T("Media Type\\Extensions"), _T(".sub"));
00112         DeleteRegKey(_T("Media Type\\Extensions"), _T(".srt"));
00113         DeleteRegKey(_T("Media Type\\Extensions"), _T(".smi"));
00114         DeleteRegKey(_T("Media Type\\Extensions"), _T(".ssa"));
00115         DeleteRegKey(_T("Media Type\\Extensions"), _T(".ass"));
00116         DeleteRegKey(_T("Media Type\\Extensions"), _T(".xss"));
00117         DeleteRegKey(_T("Media Type\\Extensions"), _T(".usf"));
00118 
00119         return AMovieDllRegisterServer2(FALSE);
00120 }
00121 
00122 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00123 
00124 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00125 {
00126         if(dwReason == DLL_PROCESS_ATTACH)
00127         {
00128                 _WIDTH = GetProfileInt(_T("SubtitleSource"), _T("w"), 640);
00129                 _HEIGHT = GetProfileInt(_T("SubtitleSource"), _T("h"), 480);
00130                 _ATPF = GetProfileInt(_T("SubtitleSource"), _T("atpf"), 400000);
00131                 if(_ATPF <= 0) _ATPF = 400000;
00132                 CString str; 
00133                 str.Format(_T("%d"), _WIDTH);
00134                 WriteProfileString(_T("SubtitleSource"), _T("w"), str);
00135                 str.Format(_T("%d"), _HEIGHT);
00136                 WriteProfileString(_T("SubtitleSource"), _T("h"), str);
00137                 str.Format(_T("%d"), _ATPF);
00138                 WriteProfileString(_T("SubtitleSource"), _T("atpf"), str);
00139         }
00140 
00141     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
00142 }
00143 
00144 #endif
00145 
00146 //
00147 // CSubtitleSource
00148 //
00149 
00150 CSubtitleSource::CSubtitleSource(LPUNKNOWN lpunk, HRESULT* phr, const CLSID& clsid)
00151         : CSource(NAME("CSubtitleSource"), lpunk, clsid)
00152 {
00153 }
00154 
00155 CSubtitleSource::~CSubtitleSource()
00156 {
00157 }
00158 
00159 STDMETHODIMP CSubtitleSource::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00160 {
00161     CheckPointer(ppv, E_POINTER);
00162 
00163         return 
00164                 QI(IFileSourceFilter)
00165                 QI(IAMFilterMiscFlags)
00166                 __super::NonDelegatingQueryInterface(riid, ppv);
00167 }
00168 
00169 // IFileSourceFilter
00170 
00171 STDMETHODIMP CSubtitleSource::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt) 
00172 {
00173         if(GetPinCount() > 0)
00174                 return VFW_E_ALREADY_CONNECTED;
00175 
00176         HRESULT hr = S_OK;
00177         if(!(new CSubtitleStream(pszFileName, this, &hr)))
00178                 return E_OUTOFMEMORY;
00179 
00180         if(FAILED(hr))
00181                 return hr;
00182 
00183         m_fn = pszFileName;
00184 
00185         return S_OK;
00186 }
00187 
00188 STDMETHODIMP CSubtitleSource::GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt)
00189 {
00190         if(!ppszFileName) return E_POINTER;
00191         
00192         if(!(*ppszFileName = (LPOLESTR)CoTaskMemAlloc((m_fn.GetLength()+1)*sizeof(WCHAR))))
00193                 return E_OUTOFMEMORY;
00194 
00195         wcscpy(*ppszFileName, m_fn);
00196 
00197         return S_OK;
00198 }
00199 
00200 // IAMFilterMiscFlags
00201 
00202 ULONG CSubtitleSource::GetMiscFlags()
00203 {
00204         return AM_FILTER_MISC_FLAGS_IS_SOURCE;
00205 }
00206 
00207 //
00208 // CSubtitleStream
00209 //
00210 
00211 CSubtitleStream::CSubtitleStream(const WCHAR* wfn, CSubtitleSource* pParent, HRESULT* phr) 
00212         : CSourceStream(NAME("SubtitleStream"), phr, pParent, L"Output")
00213         , CSourceSeeking(NAME("SubtitleStream"), (IPin*)this, phr, &m_cSharedState)
00214         , m_bDiscontinuity(FALSE), m_bFlushing(FALSE)
00215         , m_nPosition(0)
00216         , m_rts(NULL)
00217 {
00218         CAutoLock cAutoLock(&m_cSharedState);
00219 
00220         CString fn(wfn);
00221 
00222         if(!m_rts.Open(fn, DEFAULT_CHARSET))
00223         {
00224                 if(phr) *phr = E_FAIL;
00225                 return;
00226         }
00227 
00228         m_rts.CreateDefaultStyle(DEFAULT_CHARSET);
00229         m_rts.ConvertToTimeBased(25);
00230         m_rts.Sort();
00231 
00232         m_rtDuration = 0;
00233         for(int i = 0, cnt = m_rts.GetCount(); i < cnt; i++)
00234                 m_rtDuration = max(m_rtDuration, 10000i64*m_rts[i].end);
00235 
00236         m_rtStop = m_rtDuration;
00237 
00238         if(phr) *phr = m_rtDuration > 0 ? S_OK : E_FAIL;
00239 }
00240 
00241 CSubtitleStream::~CSubtitleStream()
00242 {
00243         CAutoLock cAutoLock(&m_cSharedState);
00244 }
00245 
00246 STDMETHODIMP CSubtitleStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00247 {
00248     CheckPointer(ppv, E_POINTER);
00249 
00250         return (riid == IID_IMediaSeeking) ? CSourceSeeking::NonDelegatingQueryInterface(riid, ppv) //GetInterface((IMediaSeeking*)this, ppv)
00251                 : CSourceStream::NonDelegatingQueryInterface(riid, ppv);
00252 }
00253 
00254 void CSubtitleStream::UpdateFromSeek()
00255 {
00256         if(ThreadExists())
00257         {
00258                 // next time around the loop, the worker thread will
00259                 // pick up the position change.
00260                 // We need to flush all the existing data - we must do that here
00261                 // as our thread will probably be blocked in GetBuffer otherwise
00262             
00263                 m_bFlushing = TRUE;
00264 
00265                 DeliverBeginFlush();
00266                 // make sure we have stopped pushing
00267                 Stop();
00268                 // complete the flush
00269                 DeliverEndFlush();
00270 
00271         m_bFlushing = FALSE;
00272 
00273                 // restart
00274                 Run();
00275         }
00276 }
00277 
00278 HRESULT CSubtitleStream::SetRate(double dRate)
00279 {
00280         if(dRate <= 0)
00281                 return E_INVALIDARG;
00282 
00283         {
00284                 CAutoLock lock(CSourceSeeking::m_pLock);
00285                 m_dRateSeeking = dRate;
00286         }
00287 
00288         UpdateFromSeek();
00289 
00290         return S_OK;
00291 }
00292 
00293 HRESULT CSubtitleStream::OnThreadStartPlay()
00294 {
00295     m_bDiscontinuity = TRUE;
00296     return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
00297 }
00298 
00299 HRESULT CSubtitleStream::ChangeStart()
00300 {
00301     {
00302         CAutoLock lock(CSourceSeeking::m_pLock);
00303 
00304                 OnThreadCreate();
00305 /*
00306                 if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_ARGB32)
00307                 {
00308                         m_nPosition = (int)(m_rtStart/10000)*1/1000;
00309                 }
00310                 else if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_RGB32)
00311                 {
00312                         int m_nSegments = 0;
00313                         if(!m_rts.SearchSubs((int)(m_rtStart/10000), 25, &m_nPosition, &m_nSegments))
00314                                 m_nPosition = m_nSegments;
00315                 }
00316                 else
00317                 {
00318                         m_nPosition = m_rts.SearchSub((int)(m_rtStart/10000), 25);
00319                         if(m_nPosition < 0) m_nPosition = 0;
00320                         else if(m_rts[m_nPosition].end <= (int)(m_rtStart/10000)) m_nPosition++;
00321                 }
00322 */    }
00323 
00324     UpdateFromSeek();
00325 
00326     return S_OK;
00327 }
00328 
00329 HRESULT CSubtitleStream::ChangeStop()
00330 {
00331 /*
00332     {
00333         CAutoLock lock(CSourceSeeking::m_pLock);
00334         if(m_rtPosition < m_rtStop)
00335                         return S_OK;
00336     }
00337 */
00338     // We're already past the new stop time -- better flush the graph.
00339     UpdateFromSeek();
00340 
00341     return S_OK;
00342 }
00343 
00344 HRESULT CSubtitleStream::OnThreadCreate()
00345 {
00346     CAutoLock cAutoLockShared(&m_cSharedState);
00347 
00348         if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_ARGB32)
00349         {
00350                 m_nPosition = m_rtStart/_ATPF;
00351         }
00352         else if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_RGB32)
00353         {
00354                 int m_nSegments = 0;
00355                 if(!m_rts.SearchSubs((int)(m_rtStart/10000), 10000000/_ATPF, &m_nPosition, &m_nSegments))
00356                         m_nPosition = m_nSegments;
00357         }
00358         else
00359         {
00360                 m_nPosition = m_rts.SearchSub((int)(m_rtStart/10000), 25);
00361                 if(m_nPosition < 0) m_nPosition = 0;
00362                 else if(m_rts[m_nPosition].end <= (int)(m_rtStart/10000)) m_nPosition++;
00363         }
00364 
00365     return CSourceStream::OnThreadCreate();
00366 }
00367 
00368 HRESULT CSubtitleStream::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
00369 {
00370 //    CAutoLock cAutoLock(m_pFilter->pStateLock());
00371 
00372     ASSERT(pAlloc);
00373     ASSERT(pProperties);
00374 
00375     HRESULT hr = NOERROR;
00376 
00377         if(m_mt.majortype == MEDIATYPE_Video)
00378         {
00379                 pProperties->cBuffers = 2;
00380                 pProperties->cbBuffer = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biSizeImage;
00381         }
00382         else
00383         {
00384                 pProperties->cBuffers = 1;
00385                 pProperties->cbBuffer = 0x10000;
00386         }
00387 
00388     ALLOCATOR_PROPERTIES Actual;
00389     if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
00390 
00391     if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
00392     ASSERT(Actual.cBuffers == pProperties->cBuffers);
00393 
00394     return NOERROR;
00395 }
00396 
00397 HRESULT CSubtitleStream::FillBuffer(IMediaSample* pSample)
00398 {
00399         HRESULT hr;
00400 
00401         {
00402                 CAutoLock cAutoLockShared(&m_cSharedState);
00403 
00404                 BYTE* pData = NULL;
00405                 if(FAILED(hr = pSample->GetPointer(&pData)) || !pData)
00406                         return S_FALSE;
00407 
00408                 AM_MEDIA_TYPE* pmt;
00409                 if(SUCCEEDED(pSample->GetMediaType(&pmt)) && pmt)
00410                 {
00411                         CMediaType mt(*pmt);
00412                         SetMediaType(&mt);
00413                         DeleteMediaType(pmt);
00414                 }
00415 
00416                 int len = 0;
00417                 REFERENCE_TIME rtStart, rtStop;
00418 
00419                 if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_ARGB32)
00420                 {
00421                         rtStart = (REFERENCE_TIME)((m_nPosition*_ATPF - m_rtStart) / m_dRateSeeking);
00422                         rtStop = (REFERENCE_TIME)(((m_nPosition+1)*_ATPF - m_rtStart) / m_dRateSeeking);
00423                         if(m_rtStart+rtStart >= m_rtDuration)
00424                                 return S_FALSE;
00425 
00426                         BITMAPINFOHEADER& bmi = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader;
00427 
00428                         SubPicDesc spd;
00429                         spd.w = _WIDTH;
00430                         spd.h = _HEIGHT;
00431                         spd.bpp = 32;
00432                         spd.pitch = bmi.biWidth*4;
00433                         spd.bits = pData;
00434 
00435                         len = spd.h*spd.pitch;
00436 
00437                         for(int y = 0; y < spd.h; y++)
00438                                 memsetd((DWORD*)(pData + spd.pitch*y), 0xff000000, spd.w*4);
00439 
00440                         RECT bbox;
00441                         m_rts.Render(spd, m_nPosition*_ATPF, 10000000.0/_ATPF, bbox);
00442 
00443                         for(int y = 0; y < spd.h; y++)
00444                         {
00445                                 DWORD* p = (DWORD*)(pData + spd.pitch*y);
00446                                 for(int x = 0; x < spd.w; x++, p++)
00447                                         *p = (0xff000000-(*p&0xff000000))|(*p&0xffffff);
00448                         }
00449                 }
00450                 else if(m_mt.majortype == MEDIATYPE_Video && m_mt.subtype == MEDIASUBTYPE_RGB32)
00451                 {
00452                         const STSSegment* stss = m_rts.GetSegment(m_nPosition);
00453                         if(!stss) return S_FALSE;
00454 
00455                         BITMAPINFOHEADER& bmi = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader;
00456 
00457                         SubPicDesc spd;
00458                         spd.w = _WIDTH;
00459                         spd.h = _HEIGHT;
00460                         spd.bpp = 32;
00461                         spd.pitch = bmi.biWidth*4;
00462                         spd.bits = pData;
00463 
00464                         len = spd.h*spd.pitch;
00465 
00466                         for(int y = 0; y < spd.h; y++)
00467                         {
00468                                 DWORD c1 = 0xff606060, c2 = 0xffa0a0a0;
00469                                 if(y&32) c1 ^= c2, c2 ^= c1, c1 ^= c2;
00470                                 DWORD* p = (DWORD*)(pData + spd.pitch*y);
00471                                 for(int x = 0; x < spd.w; x+=32, p+=32)
00472                                         memsetd(p, (x&32) ? c1 : c2, min(spd.w-x,32)*4);
00473                         }
00474 
00475                         RECT bbox;
00476                         m_rts.Render(spd, 10000i64*(stss->start+stss->end)/2, 10000000.0/_ATPF, bbox);
00477 
00478                         rtStart = (REFERENCE_TIME)((10000i64*stss->start - m_rtStart) / m_dRateSeeking);
00479                         rtStop = (REFERENCE_TIME)((10000i64*stss->end - m_rtStart) / m_dRateSeeking);
00480                 }
00481                 else
00482                 {
00483                         if(m_nPosition >= m_rts.GetCount())
00484                                 return S_FALSE;
00485 
00486                         STSEntry& stse = m_rts[m_nPosition];
00487 
00488                         if(stse.start >= m_rtStop/10000)
00489                                 return S_FALSE;
00490 
00491                         if(m_mt.majortype == MEDIATYPE_Subtitle && m_mt.subtype == MEDIASUBTYPE_UTF8)
00492                         {
00493                                 CStringA str = UTF16To8(m_rts.GetStrW(m_nPosition, false));
00494                                 memcpy((char*)pData, str, len = str.GetLength());
00495                         }
00496                         else if(m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS))
00497                         {
00498                                 CStringW line;
00499                                 line.Format(L"%d,%d,%s,%s,%d,%d,%d,%s,%s", 
00500                                         stse.readorder, stse.layer, CStringW(stse.style), CStringW(stse.actor), 
00501                                         stse.marginRect.left, stse.marginRect.right, (stse.marginRect.top+stse.marginRect.bottom)/2,
00502                                         CStringW(stse.effect), m_rts.GetStrW(m_nPosition, true));
00503 
00504                                 CStringA str = UTF16To8(line);
00505                                 memcpy((char*)pData, str, len = str.GetLength());
00506                         }
00507                         else if(m_mt.majortype == MEDIATYPE_Text && m_mt.subtype == MEDIASUBTYPE_NULL)
00508                         {
00509                                 CStringA str = m_rts.GetStrA(m_nPosition, false);
00510                                 memcpy((char*)pData, str, len = str.GetLength());
00511                         }
00512                         else
00513                         {
00514                                 return S_FALSE;
00515                         }
00516 
00517                         rtStart = (REFERENCE_TIME)((10000i64*stse.start - m_rtStart) / m_dRateSeeking);
00518                         rtStop = (REFERENCE_TIME)((10000i64*stse.end - m_rtStart) / m_dRateSeeking);
00519                 }
00520 
00521                 pSample->SetTime(&rtStart, &rtStop);
00522                 pSample->SetActualDataLength(len);
00523 
00524                 m_nPosition++;
00525         }
00526 
00527         pSample->SetSyncPoint(TRUE);
00528 
00529         if(m_bDiscontinuity) 
00530     {
00531                 pSample->SetDiscontinuity(TRUE);
00532                 m_bDiscontinuity = FALSE;
00533         }
00534 
00535         return S_OK;
00536 }
00537 
00538 HRESULT CSubtitleStream::GetMediaType(CMediaType* pmt)
00539 {
00540         return ((CSubtitleSource*)m_pFilter)->GetMediaType(pmt);
00541 }
00542 
00543 HRESULT CSubtitleStream::CheckMediaType(const CMediaType* pmt)
00544 {
00545     CAutoLock lock(m_pFilter->pStateLock());
00546 
00547     CMediaType mt;
00548     GetMediaType(&mt);
00549 
00550         if(mt.majortype == pmt->majortype && mt.subtype == pmt->subtype)
00551         {
00552         return NOERROR;
00553     }
00554 
00555     return E_FAIL;
00556 }
00557 
00558 STDMETHODIMP CSubtitleStream::Notify(IBaseFilter* pSender, Quality q)
00559 {
00560         return E_NOTIMPL;
00561 }
00562 
00563 //
00564 // CSubtitleSourceASCII
00565 //
00566 
00567 CSubtitleSourceASCII::CSubtitleSourceASCII(LPUNKNOWN lpunk, HRESULT* phr)
00568         : CSubtitleSource(lpunk, phr, __uuidof(this))
00569 {
00570 }
00571 
00572 HRESULT CSubtitleSourceASCII::GetMediaType(CMediaType* pmt)
00573 {
00574     CAutoLock cAutoLock(pStateLock());
00575 
00576         pmt->InitMediaType();
00577         pmt->SetType(&MEDIATYPE_Text);
00578         pmt->SetSubtype(&MEDIASUBTYPE_NULL);
00579         pmt->SetFormatType(&FORMAT_None);
00580         pmt->ResetFormatBuffer();
00581 
00582     return NOERROR;
00583 }
00584 
00585 //
00586 // CSubtitleSourceUTF8
00587 //
00588 
00589 CSubtitleSourceUTF8::CSubtitleSourceUTF8(LPUNKNOWN lpunk, HRESULT* phr)
00590         : CSubtitleSource(lpunk, phr, __uuidof(this))
00591 {
00592 }
00593 
00594 HRESULT CSubtitleSourceUTF8::GetMediaType(CMediaType* pmt)
00595 {
00596     CAutoLock cAutoLock(pStateLock());
00597 
00598         pmt->InitMediaType();
00599         pmt->SetType(&MEDIATYPE_Subtitle);
00600         pmt->SetSubtype(&MEDIASUBTYPE_UTF8);
00601         pmt->SetFormatType(&FORMAT_SubtitleInfo);
00602         SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO));
00603         memset(psi, 0, pmt->FormatLength());
00604         strcpy(psi->IsoLang, "eng");
00605 
00606     return NOERROR;
00607 }
00608 
00609 //
00610 // CSubtitleSourceSSA
00611 //
00612 
00613 CSubtitleSourceSSA::CSubtitleSourceSSA(LPUNKNOWN lpunk, HRESULT* phr)
00614         : CSubtitleSource(lpunk, phr, __uuidof(this))
00615 {
00616 }
00617 
00618 HRESULT CSubtitleSourceSSA::GetMediaType(CMediaType* pmt)
00619 {
00620     CAutoLock cAutoLock(pStateLock());
00621 
00622         pmt->InitMediaType();
00623         pmt->SetType(&MEDIATYPE_Subtitle);
00624         pmt->SetSubtype(&MEDIASUBTYPE_SSA);
00625         pmt->SetFormatType(&FORMAT_SubtitleInfo);
00626 
00627         CSimpleTextSubtitle sts;
00628         sts.Open(CString(m_fn), DEFAULT_CHARSET);
00629         sts.RemoveAll();
00630 
00631         CFile f;
00632         TCHAR path[MAX_PATH], fn[MAX_PATH];
00633         if(!GetTempPath(MAX_PATH, path) || !GetTempFileName(path, _T("mpc_sts"), 0, fn))
00634                 return E_FAIL;
00635 
00636         _tcscat(fn, _T(".ssa"));
00637 
00638         if(!sts.SaveAs(fn, EXTSSA, -1, CTextFile::UTF8) || !f.Open(fn, CFile::modeRead))
00639                 return E_FAIL;
00640 
00641         int len = (int)f.GetLength()-3;
00642         f.Seek(3, CFile::begin);
00643 
00644         SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO) + len);
00645         memset(psi, 0, pmt->FormatLength());
00646         psi->dwOffset = sizeof(SUBTITLEINFO);
00647         strcpy(psi->IsoLang, "eng");
00648         f.Read(pmt->pbFormat + psi->dwOffset, len);
00649         f.Close();
00650 
00651         _tremove(fn);
00652 
00653     return NOERROR;
00654 }
00655 
00656 //
00657 // CSubtitleSourceASS
00658 //
00659 
00660 CSubtitleSourceASS::CSubtitleSourceASS(LPUNKNOWN lpunk, HRESULT* phr)
00661         : CSubtitleSource(lpunk, phr, __uuidof(this))
00662 {
00663 }
00664 
00665 HRESULT CSubtitleSourceASS::GetMediaType(CMediaType* pmt)
00666 {
00667     CAutoLock cAutoLock(pStateLock());
00668 
00669         pmt->InitMediaType();
00670         pmt->SetType(&MEDIATYPE_Subtitle);
00671         pmt->SetSubtype(&MEDIASUBTYPE_ASS);
00672         pmt->SetFormatType(&FORMAT_SubtitleInfo);
00673 
00674         CSimpleTextSubtitle sts;
00675         sts.Open(CString(m_fn), DEFAULT_CHARSET);
00676         sts.RemoveAll();
00677 
00678         CFile f;
00679         TCHAR path[MAX_PATH], fn[MAX_PATH];
00680         if(!GetTempPath(MAX_PATH, path) || !GetTempFileName(path, _T("mpc_sts"), 0, fn))
00681                 return E_FAIL;
00682 
00683         _tcscat(fn, _T(".ass"));
00684 
00685         if(!sts.SaveAs(fn, EXTASS, -1, CTextFile::UTF8) || !f.Open(fn, CFile::modeRead))
00686                 return E_FAIL;
00687 
00688         int len = (int)f.GetLength();
00689 
00690         SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO) + len);
00691         memset(psi, 0, pmt->FormatLength());
00692         psi->dwOffset = sizeof(SUBTITLEINFO);
00693         strcpy(psi->IsoLang, "eng");
00694         f.Read(pmt->pbFormat + psi->dwOffset, len);
00695         f.Close();
00696 
00697         _tremove(fn);
00698 
00699     return NOERROR;
00700 }
00701 
00702 //
00703 // CSubtitleSourceUSF
00704 //
00705 
00706 CSubtitleSourceUSF::CSubtitleSourceUSF(LPUNKNOWN lpunk, HRESULT* phr)
00707         : CSubtitleSource(lpunk, phr, __uuidof(this))
00708 {
00709 }
00710 
00711 HRESULT CSubtitleSourceUSF::GetMediaType(CMediaType* pmt)
00712 {
00713     CAutoLock cAutoLock(pStateLock());
00714 
00715         pmt->InitMediaType();
00716         pmt->SetType(&MEDIATYPE_Subtitle);
00717         pmt->SetSubtype(&MEDIASUBTYPE_USF);
00718         pmt->SetFormatType(&FORMAT_SubtitleInfo);
00719         SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO));
00720         memset(psi, 0, pmt->FormatLength());
00721         strcpy(psi->IsoLang, "eng");
00722         // TODO: ...
00723 
00724     return NOERROR;
00725 }
00726 
00727 //
00728 // CSubtitleSourcePreview
00729 //
00730 
00731 CSubtitleSourcePreview::CSubtitleSourcePreview(LPUNKNOWN lpunk, HRESULT* phr)
00732         : CSubtitleSource(lpunk, phr, __uuidof(this))
00733 {
00734 }
00735 
00736 HRESULT CSubtitleSourcePreview::GetMediaType(CMediaType* pmt)
00737 {
00738     CAutoLock cAutoLock(pStateLock());
00739 
00740         pmt->InitMediaType();
00741         pmt->SetType(&MEDIATYPE_Video);
00742         pmt->SetSubtype(&MEDIASUBTYPE_RGB32);
00743         pmt->SetFormatType(&FORMAT_VideoInfo);
00744         VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00745         memset(pvih, 0, pmt->FormatLength());
00746         pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader);
00747         pvih->bmiHeader.biWidth = _WIDTH;
00748         pvih->bmiHeader.biHeight = _HEIGHT;
00749         pvih->bmiHeader.biBitCount = 32;
00750         pvih->bmiHeader.biCompression = BI_RGB;
00751         pvih->bmiHeader.biPlanes = 1;
00752         pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth*abs(pvih->bmiHeader.biHeight)*pvih->bmiHeader.biBitCount>>3;
00753 
00754     return NOERROR;
00755 }
00756 
00757 //
00758 // CSubtitleSourceARGB
00759 //
00760 
00761 CSubtitleSourceARGB::CSubtitleSourceARGB(LPUNKNOWN lpunk, HRESULT* phr)
00762         : CSubtitleSource(lpunk, phr, __uuidof(this))
00763 {
00764 }
00765 
00766 HRESULT CSubtitleSourceARGB::GetMediaType(CMediaType* pmt)
00767 {
00768     CAutoLock cAutoLock(pStateLock());
00769 
00770         pmt->InitMediaType();
00771         pmt->SetType(&MEDIATYPE_Video);
00772         pmt->SetSubtype(&MEDIASUBTYPE_ARGB32);
00773         pmt->SetFormatType(&FORMAT_VideoInfo);
00774         VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00775         memset(pvih, 0, pmt->FormatLength());
00776         pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader);
00777         // TODO: read w,h,fps from a config file or registry
00778         pvih->bmiHeader.biWidth = _WIDTH;
00779         pvih->bmiHeader.biHeight = _HEIGHT;
00780         pvih->bmiHeader.biBitCount = 32;
00781         pvih->bmiHeader.biCompression = BI_RGB;
00782         pvih->bmiHeader.biPlanes = 1;
00783         pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth*abs(pvih->bmiHeader.biHeight)*pvih->bmiHeader.biBitCount>>3;
00784 
00785     return NOERROR;
00786 }

Generated on Tue Dec 13 14:47:25 2005 for guliverkli by  doxygen 1.4.5