STDMETHODIMP CSubtitleInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) { CAutoLock cAutoLock(&m_csReceive); if (m_mt.majortype == MEDIATYPE_Text || m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/ || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2)) { CAutoLock cAutoLock2(m_pSubLock); CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->RemoveAll(); pRTS->CreateSegments(); } else if (m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_VOBSUB)) { CAutoLock cAutoLock2(m_pSubLock); CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->RemoveAll(); } else if (IsHdmvSub(&m_mt)) { CAutoLock cAutoLock2(m_pSubLock); CRenderedHdmvSubtitle* pHdmvSubtitle = (CRenderedHdmvSubtitle*)(ISubStream*)m_pSubStream; pHdmvSubtitle->NewSegment(tStart, tStop, dRate); } return __super::NewSegment(tStart, tStop, dRate); }
STDMETHODIMP CSubtitleInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) { CAutoLock cAutoLock(&m_csReceive); if (m_mt.majortype == MEDIATYPE_Text || m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/ || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2)) { CAutoLock cAutoLock2(m_pSubLock); CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->RemoveAll(); pRTS->CreateSegments(); } else if (m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_VOBSUB)) { CAutoLock cAutoLock2(m_pSubLock); CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->RemoveAll(); } else if (IsHdmvSub(&m_mt)) { CAutoLock cAutoLock2(m_pSubLock); CRenderedHdmvSubtitle* pHdmvSubtitle = (CRenderedHdmvSubtitle*)(ISubStream*)m_pSubStream; pHdmvSubtitle->NewSegment(tStart, tStop, dRate); } TRACE(_T("NewSegment: InvalidateSubtitle(%I64d, ...)\n"), tStart); // IMPORTANT: m_pSubLock must not be locked when calling this InvalidateSubtitle(tStart, m_pSubStream); return __super::NewSegment(tStart, tStop, dRate); }
void CPlayerSubresyncBar::SaveSubtitle() { CMainFrame* pFrame = ((CMainFrame*)AfxGetMainWnd()); if (!pFrame) { return; } CLSID clsid; m_pSubStream->GetClassID(&clsid); if (clsid == __uuidof(CVobSubFile) && m_mode == VOBSUB) { CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream; CAutoLock cAutoLock(m_pSubLock); ASSERT(pVSF->m_iLang >= 0); CAtlArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos; for (size_t i = 0, j = sp.GetCount(); i < j; i++) { sp[i].fValid = false; } for (int i = 0, j = (int)m_sts.GetCount(); i < j; i++) { int vobid, cellid, forced, spnum; TCHAR c; if (_stscanf_s(m_sts.GetStrW(i), _T("%d%c%d%c%d%c%d"), &vobid, &c, 1, &cellid, &c, 1, &forced, &c, 1, &spnum) != 7) { continue; } sp[spnum].start = m_sts[i].start; sp[spnum].stop = m_sts[i].end; sp[spnum].fValid = true; } } else if (clsid == __uuidof(CRenderedTextSubtitle) && m_mode == TEXTSUB) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; CAutoLock cAutoLock(m_pSubLock); pRTS->Copy(m_sts); } else { return; } pFrame->InvalidateSubtitle(); }
STDMETHODIMP CSubtitleInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) { CAutoLock cAutoLock(&m_csReceive); if(m_mt.majortype == MEDIATYPE_Text || m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/ || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2)) { CAutoLock cAutoLock(m_pSubLock); CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->RemoveAll(); pRTS->CreateSegments(); } else if(m_mt.majortype == MEDIATYPE_Subtitle && m_mt.subtype == MEDIASUBTYPE_SSF) { CAutoLock cAutoLock(m_pSubLock); ssf::CRenderer* pSSF = (ssf::CRenderer*)(ISubStream*)m_pSubStream; // LAME, implement RemoveSubtitles DWORD dwOffset = ((SUBTITLEINFO*)m_mt.pbFormat)->dwOffset; pSSF->Open(ssf::MemoryInputStream(m_mt.pbFormat + dwOffset, m_mt.cbFormat - dwOffset, false, false), _T("")); // pSSF->RemoveSubtitles(); } else if(m_mt.majortype == MEDIATYPE_Subtitle && (m_mt.subtype == MEDIASUBTYPE_VOBSUB)) { CAutoLock cAutoLock(m_pSubLock); CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->RemoveAll(); } else if (IsHdmvSub(&m_mt)) { CAutoLock cAutoLock(m_pSubLock); CRenderedHdmvSubtitle* pHdmvSubtitle = (CRenderedHdmvSubtitle*)(ISubStream*)m_pSubStream; pHdmvSubtitle->NewSegment (tStart, tStop, dRate); } return __super::NewSegment(tStart, tStop, dRate); }
void CPlayerSubresyncBar::SaveSubtitle() { CMainFrame* pFrame = ((CMainFrame*)AfxGetMainWnd()); if (!pFrame) { return; } CLSID clsid; m_pSubStream->GetClassID(&clsid); if (clsid == __uuidof(CVobSubFile) && m_mode == VOBSUB) { CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream; CAutoLock cAutoLock(m_pSubLock); ASSERT(pVSF->m_iLang >= 0); CAtlArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos; for (size_t i = 0, j = sp.GetCount(); i < j; i++) { sp[i].fValid = false; } for (size_t i = 0, j = m_sts.GetCount(); i < j; i++) { int spnum = m_sts[i].readorder; sp[spnum].start = m_sts[i].start; sp[spnum].stop = m_sts[i].end; sp[spnum].fValid = true; } } else if (clsid == __uuidof(CRenderedTextSubtitle) && m_mode == TEXTSUB) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; CAutoLock cAutoLock(m_pSubLock); pRTS->Copy(m_sts); } else { return; } pFrame->InvalidateSubtitle(); }
HRESULT CSubtitleInputPin::CompleteConnect(IPin* pReceivePin) { if(m_mt.majortype == MEDIATYPE_Text) { if(!(m_pSubStream = DNew CRenderedTextSubtitle(m_pSubLock))) return E_FAIL; CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->m_name = CString(GetPinName(pReceivePin)) + _T(" (embeded)"); pRTS->m_dstScreenSize = CSize(384, 288); pRTS->CreateDefaultStyle(DEFAULT_CHARSET); } else if(m_mt.majortype == MEDIATYPE_Subtitle) { SUBTITLEINFO* psi = (SUBTITLEINFO*)m_mt.pbFormat; DWORD dwOffset = 0; CString name; LCID lcid = 0; if (psi != NULL) { dwOffset = psi->dwOffset; name = ISO6392ToLanguage(psi->IsoLang); lcid = ISO6392ToLcid(psi->IsoLang); if(name.IsEmpty()) name = _T("Unknown"); if(wcslen(psi->TrackName) > 0) name += _T(" (") + CString(psi->TrackName) + _T(")"); } if(m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/ || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2) { if(!(m_pSubStream = DNew CRenderedTextSubtitle(m_pSubLock))) return E_FAIL; CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->m_name = name; pRTS->m_lcid = lcid; pRTS->m_dstScreenSize = CSize(384, 288); pRTS->CreateDefaultStyle(DEFAULT_CHARSET); if(dwOffset > 0 && m_mt.cbFormat - dwOffset > 0) { CMediaType mt = m_mt; if(mt.pbFormat[dwOffset+0] != 0xef && mt.pbFormat[dwOffset+1] != 0xbb && mt.pbFormat[dwOffset+2] != 0xfb) { dwOffset -= 3; mt.pbFormat[dwOffset+0] = 0xef; mt.pbFormat[dwOffset+1] = 0xbb; mt.pbFormat[dwOffset+2] = 0xbf; } pRTS->Open(mt.pbFormat + dwOffset, mt.cbFormat - dwOffset, DEFAULT_CHARSET, pRTS->m_name); } } else if(m_mt.subtype == MEDIASUBTYPE_SSF) { if(!(m_pSubStream = DNew ssf::CRenderer(m_pSubLock))) return E_FAIL; ssf::CRenderer* pSSF = (ssf::CRenderer*)(ISubStream*)m_pSubStream; pSSF->Open(ssf::MemoryInputStream(m_mt.pbFormat + dwOffset, m_mt.cbFormat - dwOffset, false, false), name); } else if(m_mt.subtype == MEDIASUBTYPE_VOBSUB) { if(!(m_pSubStream = DNew CVobSubStream(m_pSubLock))) return E_FAIL; CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->Open(name, m_mt.pbFormat + dwOffset, m_mt.cbFormat - dwOffset); } else if (IsHdmvSub(&m_mt)) { if(!(m_pSubStream = DNew CRenderedHdmvSubtitle(m_pSubLock, (m_mt.subtype == MEDIASUBTYPE_DVB_SUBTITLES) ? ST_DVB : ST_HDMV))) return E_FAIL; } } AddSubStream(m_pSubStream); return __super::CompleteConnect(pReceivePin); }
STDMETHODIMP CSubtitleInputPin::Receive(IMediaSample* pSample) { HRESULT hr; hr = __super::Receive(pSample); if(FAILED(hr)) return hr; CAutoLock cAutoLock(&m_csReceive); REFERENCE_TIME tStart, tStop; pSample->GetTime(&tStart, &tStop); tStart += m_tStart; tStop += m_tStart; BYTE* pData = NULL; hr = pSample->GetPointer(&pData); if(FAILED(hr) || pData == NULL) return hr; int len = pSample->GetActualDataLength(); bool fInvalidate = false; if(m_mt.majortype == MEDIATYPE_Text) { CAutoLock cAutoLock(m_pSubLock); CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; if(!strncmp((char*)pData, __GAB1__, strlen(__GAB1__))) { char* ptr = (char*)&pData[strlen(__GAB1__)+1]; char* end = (char*)&pData[len]; while(ptr < end) { WORD tag = *((WORD*)(ptr)); ptr += 2; WORD size = *((WORD*)(ptr)); ptr += 2; if(tag == __GAB1_LANGUAGE__) { pRTS->m_name = CString(ptr); } else if(tag == __GAB1_ENTRY__) { pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr+4)); fInvalidate = true; } else if(tag == __GAB1_LANGUAGE_UNICODE__) { pRTS->m_name = (WCHAR*)ptr; } else if(tag == __GAB1_ENTRY_UNICODE__) { pRTS->Add((WCHAR*)(ptr+8), true, *(int*)ptr, *(int*)(ptr+4)); fInvalidate = true; } ptr += size; } } else if(!strncmp((char*)pData, __GAB2__, strlen(__GAB2__))) { char* ptr = (char*)&pData[strlen(__GAB2__)+1]; char* end = (char*)&pData[len]; while(ptr < end) { WORD tag = *((WORD*)(ptr)); ptr += 2; DWORD size = *((DWORD*)(ptr)); ptr += 4; if(tag == __GAB1_LANGUAGE_UNICODE__) { pRTS->m_name = (WCHAR*)ptr; } else if(tag == __GAB1_RAWTEXTSUBTITLE__) { pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, pRTS->m_name); fInvalidate = true; } ptr += size; } } else if(pData != 0 && len > 1 && *pData != 0) { CStringA str((char*)pData, len); str.Replace("\r\n", "\n"); str.Trim(); if(!str.IsEmpty()) { pRTS->Add(AToW(str), false, (int)(tStart / 10000), (int)(tStop / 10000)); fInvalidate = true; } } } else if(m_mt.majortype == MEDIATYPE_Subtitle) { CAutoLock cAutoLock(m_pSubLock); if(m_mt.subtype == MEDIASUBTYPE_UTF8) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim(); if(!str.IsEmpty()) { pRTS->Add(str, true, (int)(tStart / 10000), (int)(tStop / 10000)); fInvalidate = true; } } else if(m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim(); if(!str.IsEmpty()) { STSEntry stse; int fields = m_mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9; CAtlList<CStringW> sl; Explode(str, sl, ',', fields); if(sl.GetCount() == (size_t)fields) { stse.readorder = wcstol(sl.RemoveHead(), NULL, 10); stse.layer = wcstol(sl.RemoveHead(), NULL, 10); stse.style = sl.RemoveHead(); stse.actor = sl.RemoveHead(); stse.marginRect.left = wcstol(sl.RemoveHead(), NULL, 10); stse.marginRect.right = wcstol(sl.RemoveHead(), NULL, 10); stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10); if(fields == 10) stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10); stse.effect = sl.RemoveHead(); stse.str = sl.RemoveHead(); } if(!stse.str.IsEmpty()) { pRTS->Add(stse.str, true, (int)(tStart / 10000), (int)(tStop / 10000), stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder); fInvalidate = true; } } } else if(m_mt.subtype == MEDIASUBTYPE_SSF) { ssf::CRenderer* pSSF = (ssf::CRenderer*)(ISubStream*)m_pSubStream; CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim(); if(!str.IsEmpty()) { pSSF->Append(tStart, tStop, str); fInvalidate = true; } } else if(m_mt.subtype == MEDIASUBTYPE_VOBSUB) { CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->Add(tStart, tStop, pData, len); } else if (IsHdmvSub(&m_mt)) { CAutoLock cAutoLock(m_pSubLock); CRenderedHdmvSubtitle* pHdmvSubtitle = (CRenderedHdmvSubtitle*)(ISubStream*)m_pSubStream; pHdmvSubtitle->ParseSample (pSample); } } if(fInvalidate) { TRACE(_T("InvalidateSubtitle(%I64d, ..)\n"), tStart); // IMPORTANT: m_pSubLock must not be locked when calling this InvalidateSubtitle(tStart, m_pSubStream); } hr = S_OK; return hr; }
HRESULT CSubtitleInputPin::CompleteConnect(IPin* pReceivePin) { if (m_mt.majortype == MEDIATYPE_Text) { if (!(m_pSubStream = DEBUG_NEW CRenderedTextSubtitle(m_pSubLock))) { return E_FAIL; } CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->m_name = CString(GetPinName(pReceivePin)) + _T(" (embeded)"); pRTS->m_dstScreenSize = CSize(384, 288); pRTS->CreateDefaultStyle(DEFAULT_CHARSET); } else if (m_mt.majortype == MEDIATYPE_Subtitle) { SUBTITLEINFO* psi = (SUBTITLEINFO*)m_mt.pbFormat; DWORD dwOffset = 0; CString name; LCID lcid = 0; if (psi != nullptr) { dwOffset = psi->dwOffset; name = ISO6392ToLanguage(psi->IsoLang); lcid = ISO6392ToLcid(psi->IsoLang); CString trackName(psi->TrackName); trackName.Trim(); if (!trackName.IsEmpty()) { if (!name.IsEmpty()) { if (trackName[0] != _T('(') && trackName[0] != _T('[')) { name += _T(","); } name += _T(" "); } name += trackName; } if (name.IsEmpty()) { name = _T("Unknown"); } } name.Replace(_T(""), _T("")); name.Replace(_T(""), _T("")); if (m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/ || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2) { if (!(m_pSubStream = DEBUG_NEW CRenderedTextSubtitle(m_pSubLock))) { return E_FAIL; } CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; pRTS->m_name = name; pRTS->m_lcid = lcid; pRTS->m_dstScreenSize = CSize(384, 288); pRTS->CreateDefaultStyle(DEFAULT_CHARSET); if (dwOffset > 0 && m_mt.cbFormat - dwOffset > 0) { CMediaType mt = m_mt; if (mt.pbFormat[dwOffset + 0] != 0xef && mt.pbFormat[dwOffset + 1] != 0xbb && mt.pbFormat[dwOffset + 2] != 0xfb) { dwOffset -= 3; mt.pbFormat[dwOffset + 0] = 0xef; mt.pbFormat[dwOffset + 1] = 0xbb; mt.pbFormat[dwOffset + 2] = 0xbf; } pRTS->Open(mt.pbFormat + dwOffset, mt.cbFormat - dwOffset, DEFAULT_CHARSET, pRTS->m_name); } } else if (m_mt.subtype == MEDIASUBTYPE_VOBSUB) { if (!(m_pSubStream = DEBUG_NEW CVobSubStream(m_pSubLock))) { return E_FAIL; } CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->Open(name, m_mt.pbFormat + dwOffset, m_mt.cbFormat - dwOffset); } else if (IsHdmvSub(&m_mt)) { if (!(m_pSubStream = DEBUG_NEW CRenderedHdmvSubtitle(m_pSubLock, (m_mt.subtype == MEDIASUBTYPE_DVB_SUBTITLES) ? ST_DVB : ST_HDMV, name, lcid))) { return E_FAIL; } } } AddSubStream(m_pSubStream); return __super::CompleteConnect(pReceivePin); }
REFERENCE_TIME CSubtitleInputPin::DecodeSample(const CAutoPtr<SubtitleSample>& pSample) { bool bInvalidate = false; if (m_mt.majortype == MEDIATYPE_Text) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; char* pData = (char*)pSample->data.data(); if (!strncmp(pData, __GAB1__, strlen(__GAB1__))) { char* ptr = &pData[strlen(__GAB1__) + 1]; char* end = &pData[pSample->data.size()]; while (ptr < end) { WORD tag = *((WORD*)(ptr)); ptr += 2; WORD size = *((WORD*)(ptr)); ptr += 2; if (tag == __GAB1_LANGUAGE__) { pRTS->m_name = CString(ptr); } else if (tag == __GAB1_ENTRY__) { pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr + 4)); bInvalidate = true; } else if (tag == __GAB1_LANGUAGE_UNICODE__) { pRTS->m_name = (WCHAR*)ptr; } else if (tag == __GAB1_ENTRY_UNICODE__) { pRTS->Add((WCHAR*)(ptr + 8), true, *(int*)ptr, *(int*)(ptr + 4)); bInvalidate = true; } ptr += size; } } else if (!strncmp(pData, __GAB2__, strlen(__GAB2__))) { char* ptr = &pData[strlen(__GAB2__) + 1]; char* end = &pData[pSample->data.size()]; while (ptr < end) { WORD tag = *((WORD*)(ptr)); ptr += 2; DWORD size = *((DWORD*)(ptr)); ptr += 4; if (tag == __GAB1_LANGUAGE_UNICODE__) { pRTS->m_name = (WCHAR*)ptr; } else if (tag == __GAB1_RAWTEXTSUBTITLE__) { pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, pRTS->m_name); bInvalidate = true; } ptr += size; } } else if (pSample->data.size() > 1 && *pData != '\0') { CStringA str(pData, (int)pSample->data.size()); str.Replace("\r\n", "\n"); str.Trim(); if (!str.IsEmpty()) { pRTS->Add(AToW(str), false, (int)(pSample->rtStart / 10000), (int)(pSample->rtStop / 10000)); bInvalidate = true; } } } else if (m_mt.majortype == MEDIATYPE_Subtitle) { if (m_mt.subtype == MEDIASUBTYPE_UTF8) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; CStringW str = UTF8To16(CStringA((LPCSTR)pSample->data.data(), (int)pSample->data.size())).Trim(); if (!str.IsEmpty()) { pRTS->Add(str, true, (int)(pSample->rtStart / 10000), (int)(pSample->rtStop / 10000)); bInvalidate = true; } } else if (m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; CStringW str = UTF8To16(CStringA((LPCSTR)pSample->data.data(), (int)pSample->data.size())).Trim(); if (!str.IsEmpty()) { STSEntry stse; int fields = m_mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9; CAtlList<CStringW> sl; Explode(str, sl, ',', fields); if (sl.GetCount() == (size_t)fields) { stse.readorder = wcstol(sl.RemoveHead(), nullptr, 10); stse.layer = wcstol(sl.RemoveHead(), nullptr, 10); stse.style = sl.RemoveHead(); stse.actor = sl.RemoveHead(); stse.marginRect.left = wcstol(sl.RemoveHead(), nullptr, 10); stse.marginRect.right = wcstol(sl.RemoveHead(), nullptr, 10); stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), nullptr, 10); if (fields == 10) { stse.marginRect.bottom = wcstol(sl.RemoveHead(), nullptr, 10); } stse.effect = sl.RemoveHead(); stse.str = sl.RemoveHead(); } if (!stse.str.IsEmpty()) { pRTS->Add(stse.str, true, (int)(pSample->rtStart / 10000), (int)(pSample->rtStop / 10000), stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder); bInvalidate = true; } } } else if (m_mt.subtype == MEDIASUBTYPE_VOBSUB) { CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream; pVSS->Add(pSample->rtStart, pSample->rtStop, pSample->data.data(), (int)pSample->data.size()); } else if (IsRLECodedSub(&m_mt)) { CRLECodedSubtitle* pRLECodedSubtitle = (CRLECodedSubtitle*)(ISubStream*)m_pSubStream; pRLECodedSubtitle->ParseSample(pSample->rtStart, pSample->rtStop, pSample->data.data(), (int)pSample->data.size()); } } return bInvalidate ? pSample->rtStart : -1; }
void CPlayerSubresyncBar::ReloadSubtitle() { m_mode = NONE; m_lastSegment = -1; m_sts.Empty(); m_vobSub.RemoveAll(); ResetSubtitle(); for (int i = 0, count = m_list.GetHeaderCtrl()->GetItemCount(); i < count; i++) { m_list.DeleteColumn(0); } if (!m_pSubStream) { return; } CLSID clsid; m_pSubStream->GetClassID(&clsid); if (clsid == __uuidof(CVobSubFile)) { CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream; m_mode = VOBSUB; pVSF->Lock(); ASSERT(pVSF->m_iLang >= 0); m_vobSub.Copy(pVSF->m_langs[pVSF->m_iLang].subpos); for (size_t i = 0, j = m_vobSub.GetCount(); i < j; i++) { CString str; str.Format(_T("%d,%d,%d,%Iu"), m_vobSub[i].vobid, m_vobSub[i].cellid, m_vobSub[i].fForced, i); m_sts.Add(TToW(str), false, (int)m_vobSub[i].start, (int)m_vobSub[i].stop); } pVSF->Unlock(); m_sts.CreateDefaultStyle(DEFAULT_CHARSET); pVSF->m_fOnlyShowForcedSubs = false; m_list.InsertColumn(COL_START, ResStr(IDS_SUBRESYNC_CLN_TIME), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_END, ResStr(IDS_SUBRESYNC_CLN_END), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_PREVSTART, ResStr(IDS_SUBRESYNC_CLN_PREVIEW), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_PREVEND, ResStr(IDS_SUBRESYNC_CLN_END), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_VOBID, ResStr(IDS_SUBRESYNC_CLN_VOB_ID), LVCFMT_CENTER, 60); m_list.InsertColumn(COL_CELLID, ResStr(IDS_SUBRESYNC_CLN_CELL_ID), LVCFMT_CENTER, 60); m_list.InsertColumn(COL_FORCED, ResStr(IDS_SUBRESYNC_CLN_FORCED), LVCFMT_CENTER, 60); } else if (clsid == __uuidof(CRenderedTextSubtitle)) { CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream; m_mode = TEXTSUB; pRTS->Lock(); m_sts.Copy(*pRTS); pRTS->Unlock(); m_sts.ConvertToTimeBased(m_fps); m_sts.Sort(true); /*!!m_bUnlink*/ m_list.InsertColumn(COL_START, ResStr(IDS_SUBRESYNC_CLN_TIME), LVCFMT_LEFT, 90); m_list.InsertColumn(COL_END, ResStr(IDS_SUBRESYNC_CLN_END), LVCFMT_LEFT, 4); m_list.InsertColumn(COL_PREVSTART, ResStr(IDS_SUBRESYNC_CLN_PREVIEW), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_PREVEND, ResStr(IDS_SUBRESYNC_CLN_END), LVCFMT_LEFT, 4); m_list.InsertColumn(COL_TEXT, ResStr(IDS_SUBRESYNC_CLN_TEXT), LVCFMT_LEFT, 275); m_list.InsertColumn(COL_STYLE, ResStr(IDS_SUBRESYNC_CLN_STYLE), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_FONT, ResStr(IDS_SUBRESYNC_CLN_FONT), LVCFMT_LEFT, 60); m_list.InsertColumn(COL_CHARSET, ResStr(IDS_SUBRESYNC_CLN_CHARSET), LVCFMT_CENTER, 20); m_list.InsertColumn(COL_UNICODE, ResStr(IDS_SUBRESYNC_CLN_UNICODE), LVCFMT_CENTER, 40); m_list.InsertColumn(COL_LAYER, ResStr(IDS_SUBRESYNC_CLN_LAYER), LVCFMT_CENTER, 50); m_list.InsertColumn(COL_ACTOR, ResStr(IDS_SUBRESYNC_CLN_ACTOR), LVCFMT_LEFT, 80); m_list.InsertColumn(COL_EFFECT, ResStr(IDS_SUBRESYNC_CLN_EFFECT), LVCFMT_LEFT, 80); } m_subtimes.SetCount(m_sts.GetCount()); for (size_t i = 0, j = m_sts.GetCount(); i < j; i++) { m_subtimes[i].orgStart = m_sts[i].start; m_subtimes[i].orgEnd = m_sts[i].end; } ResetSubtitle(); }
STDMETHODIMP_(CSubtitleInputPinHelper*) CSubtitleInputPin::CreateHelper( const CMediaType& mt, IPin* pReceivePin ) { XY_LOG_INFO(XY_LOG_VAR_2_STR(pReceivePin)); CSubtitleInputPinHelper *ret = NULL; if(mt.majortype == MEDIATYPE_Text) { XY_LOG_INFO("Create CTextSubtitleInputPinHepler"); CRenderedTextSubtitle* pRTS = DEBUG_NEW CRenderedTextSubtitle(m_pSubLock); pRTS->m_name = CString(GetPinName(pReceivePin)) + _T(" (embeded)"); pRTS->m_dstScreenSize = CSize(384, 288); ret = DEBUG_NEW CTextSubtitleInputPinHepler(pRTS, m_mt); } else if(mt.majortype == MEDIATYPE_Subtitle) { SUBTITLEINFO* psi = (SUBTITLEINFO*)mt.pbFormat; DWORD dwOffset = 0; CString name; LCID lcid = 0; if (psi != NULL) { dwOffset = psi->dwOffset; name = ISO6392ToLanguage(psi->IsoLang); lcid = ISO6392ToLcid(psi->IsoLang); CString trackName(psi->TrackName); trackName.Trim(); if (!trackName.IsEmpty()) { if (!name.IsEmpty()) { if (trackName[0] != _T('(') && trackName[0] != _T('[')) { name += _T(","); } name += _T(" "); } name += trackName; } if (name.IsEmpty()) { name = _T("Unknown"); } } name.Replace(_T(""), _T(""));//CAUTION: VS may show name.Replace(_T(""),_T("")), however there is a character in the first _T("") name.Replace(_T(""), _T(""));//CAUTION: VS may show name.Replace(_T(""),_T("")), however there is a character in the first _T("") if(mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/ || mt.subtype == MEDIASUBTYPE_SSA || mt.subtype == MEDIASUBTYPE_ASS || mt.subtype == MEDIASUBTYPE_ASS2) { XY_LOG_INFO("Create CTextSubtitleInputPinHepler"); CRenderedTextSubtitle* pRTS = DEBUG_NEW CRenderedTextSubtitle(m_pSubLock); pRTS->m_name = name; pRTS->m_lcid = lcid; pRTS->m_dstScreenSize = CSize(384, 288); if(dwOffset > 0 && mt.cbFormat - dwOffset > 0) { CMediaType mt1 = mt; if(mt1.pbFormat[dwOffset+0] != 0xef && mt1.pbFormat[dwOffset+1] != 0xbb && mt1.pbFormat[dwOffset+2] != 0xfb) { dwOffset -= 3; mt1.pbFormat[dwOffset+0] = 0xef; mt1.pbFormat[dwOffset+1] = 0xbb; mt1.pbFormat[dwOffset+2] = 0xbf; } pRTS->Open(mt1.pbFormat + dwOffset, mt1.cbFormat - dwOffset, DEFAULT_CHARSET, pRTS->m_name); } ret = DEBUG_NEW CTextSubtitleInputPinHepler(pRTS, m_mt); } else if(mt.subtype == MEDIASUBTYPE_SSF) { XY_LOG_INFO("Create CSSFInputPinHepler"); ssf::CRenderer* pSSF = DEBUG_NEW ssf::CRenderer(m_pSubLock); pSSF->Open(ssf::MemoryInputStream(mt.pbFormat + dwOffset, mt.cbFormat - dwOffset, false, false), name); ret = DEBUG_NEW CSSFInputPinHepler(pSSF, m_mt); } else if(mt.subtype == MEDIASUBTYPE_VOBSUB) { XY_LOG_INFO("Create CVobsubInputPinHepler"); CVobSubStream* pVSS = DEBUG_NEW CVobSubStream(m_pSubLock); pVSS->Open(name, mt.pbFormat + dwOffset, mt.cbFormat - dwOffset); ret = DEBUG_NEW CVobsubInputPinHepler(pVSS, m_mt); } else if (IsHdmvSub(&mt)) { XY_LOG_INFO("Create CHdmvInputPinHepler"); CRenderedHdmvSubtitle *hdmv_sub = DEBUG_NEW CRenderedHdmvSubtitle(m_pSubLock, (mt.subtype == MEDIASUBTYPE_DVB_SUBTITLES) ? ST_DVB : ST_HDMV, name, lcid); ret = DEBUG_NEW CHdmvInputPinHepler(hdmv_sub, m_mt); } } return ret; }
STDMETHODIMP CTextSubtitleInputPinHepler::Receive( IMediaSample* pSample ) { REFERENCE_TIME tStart, tStop; pSample->GetTime(&tStart, &tStop); tStart += m_tStart; tStop += m_tStart; BYTE* pData = NULL; HRESULT hr = pSample->GetPointer(&pData); if(FAILED(hr) || pData == NULL) return hr; int len = pSample->GetActualDataLength(); if(m_mt.majortype == MEDIATYPE_Text) { if(!strncmp((char*)pData, __GAB1__, strlen(__GAB1__))) { char* ptr = (char*)&pData[strlen(__GAB1__)+1]; char* end = (char*)&pData[len]; while(ptr < end) { WORD tag = *((WORD*)(ptr)); ptr += 2; WORD size = *((WORD*)(ptr)); ptr += 2; if(tag == __GAB1_LANGUAGE__) { m_pRTS->m_name = CString(ptr); } else if(tag == __GAB1_ENTRY__) { m_pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr+4)); } else if(tag == __GAB1_LANGUAGE_UNICODE__) { m_pRTS->m_name = (WCHAR*)ptr; } else if(tag == __GAB1_ENTRY_UNICODE__) { m_pRTS->Add((WCHAR*)(ptr+8), true, *(int*)ptr, *(int*)(ptr+4)); } ptr += size; } } else if(!strncmp((char*)pData, __GAB2__, strlen(__GAB2__))) { char* ptr = (char*)&pData[strlen(__GAB2__)+1]; char* end = (char*)&pData[len]; while(ptr < end) { WORD tag = *((WORD*)(ptr)); ptr += 2; DWORD size = *((DWORD*)(ptr)); ptr += 4; if(tag == __GAB1_LANGUAGE_UNICODE__) { m_pRTS->m_name = (WCHAR*)ptr; } else if(tag == __GAB1_RAWTEXTSUBTITLE__) { m_pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, m_pRTS->m_name); } ptr += size; } } else if(pData != 0 && len > 1 && *pData != 0) { CStringA str((char*)pData, len); str.Replace("\r\n", "\n"); str.Trim(); if(!str.IsEmpty()) { m_pRTS->Add(AToW(str), false, (int)(tStart / 10000), (int)(tStop / 10000)); } } else { XY_LOG_WARN("Unexpected data"); } } else if(m_mt.majortype == MEDIATYPE_Subtitle) { if(m_mt.subtype == MEDIASUBTYPE_UTF8) { CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim(); if(!str.IsEmpty()) { m_pRTS->Add(str, true, (int)(tStart / 10000), (int)(tStop / 10000)); } else { XY_LOG_WARN("Empty data"); } } else if(m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS || m_mt.subtype == MEDIASUBTYPE_ASS2) { CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim(); if(!str.IsEmpty()) { STSEntry stse; int fields = m_mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9; CAtlList<CStringW> sl; Explode(str, sl, ',', fields); if(sl.GetCount() == fields) { stse.readorder = wcstol(sl.RemoveHead(), NULL, 10); stse.layer = wcstol(sl.RemoveHead(), NULL, 10); stse.style = sl.RemoveHead(); stse.actor = sl.RemoveHead(); stse.marginRect.left = wcstol(sl.RemoveHead(), NULL, 10); stse.marginRect.right = wcstol(sl.RemoveHead(), NULL, 10); stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10); if(fields == 10) stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10); stse.effect = sl.RemoveHead(); stse.str = sl.RemoveHead(); } if(!stse.str.IsEmpty()) { m_pRTS->Add(stse.str, true, (int)(tStart / 10000), (int)(tStop / 10000), stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder); } } else { XY_LOG_WARN("Empty data"); } } else { XY_LOG_WARN("Unsupported media type "<<XyUuidToString(m_mt.subtype)); } } else { XY_LOG_WARN("Unsupported media type "<<XyUuidToString(m_mt.majortype)); } return S_OK; }
STDMETHODIMP CTextSubtitleInputPinHepler::NewSegment( REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate ) { m_pRTS->RemoveAllEntries(); m_pRTS->CreateSegments(); return __super::NewSegment(tStart,tStop,dRate); }