STDMETHODIMP CRenderer::Render(SubPicDesc& spd, REFERENCE_TIME rt, double fps, RECT& bbox) { CheckPointer(m_file, E_UNEXPECTED); CheckPointer(m_renderer, E_UNEXPECTED); if(spd.type != MSP_RGB32) return E_INVALIDARG; CAutoLock csAutoLock(m_pLock); CRect bbox2; bbox2.SetRectEmpty(); CAutoPtrList<Subtitle> subs; m_file->Lookup((float)rt/10000000, subs); m_renderer->NextSegment(subs); POSITION pos = subs.GetHeadPosition(); while(pos) { const Subtitle* s = subs.GetNext(pos); const RenderedSubtitle* rs = m_renderer->Lookup(s, CSize(spd.w, spd.h), spd.vidrect); if(rs) bbox2 |= rs->Draw(spd); } bbox = bbox2 & CRect(0, 0, spd.w, spd.h); return S_OK; }
CBasePin* CStreamDriveThruFilter::GetPin(int n) { CAutoLock csAutoLock(&m_csLock); if(n == 0) return m_pInput; else if(n == 1) return m_pOutput; return NULL; }
CStreamDriveThruFilter::~CStreamDriveThruFilter() { CAutoLock csAutoLock(&m_csLock); CAMThread::CallWorker(CMD_EXIT); CAMThread::Close(); delete m_pInput; delete m_pOutput; }
CBasePin* CStreamDriveThruFilter::GetPin(int n) { CAutoLock csAutoLock(&m_csLock); if (n == 0) { return m_pInput; } else if (n == 1) { return m_pOutput; } return nullptr; }
STDMETHODIMP CRenderer::Reload() { CAutoLock csAutoLock(m_pLock); return !m_fn.IsEmpty() && Open(m_fn, m_name) ? S_OK : E_FAIL; }
DWORD CStreamDriveThruFilter::ThreadProc() { while(1) { DWORD cmd = GetRequest(); switch(cmd) { default: case CMD_EXIT: Reply(S_OK); return 0; case CMD_STOP: Reply(S_OK); break; case CMD_PAUSE: Reply(S_OK); break; case CMD_RUN: Reply(S_OK); do { CComPtr<IAsyncReader> pAsyncReader; CComPtr<IStream> pStream; if(!m_pInput || !m_pInput->IsConnected() || FAILED(m_pInput->GetAsyncReader(&pAsyncReader)) || !m_pOutput || !m_pOutput->IsConnected() || FAILED(m_pOutput->GetStream(&pStream))) break; LARGE_INTEGER li = {0}; ULARGE_INTEGER uli = {0}; if(FAILED(pStream->Seek(li, STREAM_SEEK_SET, NULL)) || FAILED(pStream->SetSize(uli))) break; if(CComQIPtr<IFileSinkFilter2> pFSF = GetFilterFromPin(m_pOutput->GetConnected())) { pFSF->SetMode(AM_FILE_OVERWRITE); LPOLESTR pfn; if(SUCCEEDED(pFSF->GetCurFile(&pfn, NULL))) { pFSF->SetFileName(pfn, NULL); CoTaskMemFree(pfn); } } m_position = 0; BYTE buff[PACKETSIZE]; do { while(!CheckRequest(&cmd)) { CAutoLock csAutoLock(&m_csLock); LONGLONG total = 0, available = 0; if(FAILED(pAsyncReader->Length(&total, &available)) || m_position >= total) { cmd = CMD_STOP; break; } LONG size = (LONG)min(PACKETSIZE, total - m_position); if(FAILED(pAsyncReader->SyncRead(m_position, size, buff))) { cmd = CMD_STOP; break; } ULONG written = 0; if(FAILED(pStream->Write(buff, (ULONG)size, &written)) || (ULONG)size != written) { cmd = CMD_STOP; break; } m_position += size; } if(cmd == CMD_PAUSE) { Reply(S_OK); // reply to CMD_PAUSE while(!CheckRequest(&cmd)) Sleep(50); Reply(S_OK); // reply to something } } while(cmd == CMD_RUN); uli.QuadPart = m_position; pStream->SetSize(uli); if(CComPtr<IPin> pPin = m_pOutput->GetConnected()) pPin->EndOfStream(); } while(false); break; } } return 0; }