STDMETHODIMP CBaseSplitterFilter::GetStatus(int i, int& samples, int& size) { CAutoLock cAutoLock(m_pLock); if (POSITION pos = m_pOutputs.FindIndex(i)) { CBaseSplitterOutputPin* pPin = m_pOutputs.GetAt(pos); samples = pPin->QueueCount(); size = pPin->QueueSize(); return pPin->IsConnected() ? S_OK : S_FALSE; } return E_INVALIDARG; }
DWORD CBaseSplitterFilter::ThreadProc() { if (m_pSyncReader) { m_pSyncReader->SetBreakEvent(GetRequestHandle()); } if (!DemuxInit()) { for (;;) { DWORD cmd = GetRequest(); if (cmd == CMD_EXIT) { CAMThread::m_hThread = nullptr; } Reply(S_OK); if (cmd == CMD_EXIT) { return 0; } } } m_eEndFlush.Set(); m_fFlushing = false; for (DWORD cmd = DWORD_ERROR; ; cmd = GetRequest()) { if (cmd == CMD_EXIT) { m_hThread = nullptr; Reply(S_OK); return 0; } SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_NORMAL); m_rtStart = m_rtNewStart; m_rtStop = m_rtNewStop; DemuxSeek(m_rtStart); if (cmd != DWORD_ERROR) { Reply(S_OK); } m_eEndFlush.Wait(); m_pActivePins.RemoveAll(); POSITION pos = m_pOutputs.GetHeadPosition(); while (pos && !m_fFlushing) { CBaseSplitterOutputPin* pPin = m_pOutputs.GetNext(pos); if (pPin->IsConnected() && pPin->IsActive()) { m_pActivePins.AddTail(pPin); pPin->DeliverNewSegment(m_rtStart, m_rtStop, m_dRate); } } do { m_bDiscontinuitySent.RemoveAll(); } while (!DemuxLoop()); pos = m_pActivePins.GetHeadPosition(); while (pos && !CheckRequest(&cmd)) { m_pActivePins.GetNext(pos)->QueueEndOfStream(); } } ASSERT(0); // we should only exit via CMD_EXIT m_hThread = nullptr; return 0; }
HRESULT CBaseSplitterFilter::DeliverPacket(CAutoPtr<Packet> p) { HRESULT hr = S_FALSE; CBaseSplitterOutputPin* pPin = GetOutputPin(p->TrackNumber); if (!pPin || !pPin->IsConnected() || !m_pActivePins.Find(pPin)) { return S_FALSE; } if (p->rtStart != Packet::INVALID_TIME) { m_rtCurrent = p->rtStart; p->rtStart -= m_rtStart; p->rtStop -= m_rtStart; ASSERT(p->rtStart <= p->rtStop); } { CAutoLock cAutoLock(&m_csmtnew); CMediaType mt; if (m_mtnew.Lookup(p->TrackNumber, mt)) { p->pmt = CreateMediaType(&mt); m_mtnew.RemoveKey(p->TrackNumber); } } if (!m_bDiscontinuitySent.Find(p->TrackNumber)) { p->bDiscontinuity = TRUE; } DWORD TrackNumber = p->TrackNumber; BOOL bDiscontinuity = p->bDiscontinuity; #if defined(_DEBUG) && 0 TRACE(_T("[%d]: d%d s%d p%d, b=%d, [%20I64d - %20I64d]\n"), p->TrackNumber, p->bDiscontinuity, p->bSyncPoint, p->rtStart != Packet::INVALID_TIME && p->rtStart < 0, p->GetCount(), p->rtStart, p->rtStop); #endif hr = pPin->QueuePacket(p); if (S_OK != hr) { if (POSITION pos = m_pActivePins.Find(pPin)) { m_pActivePins.RemoveAt(pos); } if (!m_pActivePins.IsEmpty()) { // only die when all pins are down hr = S_OK; } return hr; } if (bDiscontinuity) { m_bDiscontinuitySent.AddTail(TrackNumber); } return hr; }