int CBaseSplitterOutputPin::ThreadProcDelivery(int cnt) { CAutoPtr<Packet> p; { CAutoLock cAutoLock(&m_queue); if((cnt = m_queue.GetCount()) > 0) p = m_queue.Remove(); } if(S_OK == m_hrDeliver && cnt > 0) { ASSERT(!m_fFlushing); m_fFlushed = false; // flushing can still start here, to release a blocked deliver call HRESULT hr = p ? DeliverPacket(p) : DeliverEndOfStream(); m_eEndFlush.Wait(); // .. so we have to wait until it is done if(hr != S_OK && !m_fFlushed) // and only report the error in m_hrDeliver if we didn't flush the stream { // CAutoLock cAutoLock(&m_csQueueLock); m_hrDeliver = hr; cnt = 0; } } return cnt; }
bool CMpaSplitterFilter::DemuxLoop() { HRESULT hr = S_OK; int FrameSize; REFERENCE_TIME rtDuration; while (SUCCEEDED(hr) && !CheckRequest(NULL) && m_pFile->GetPos() < m_pFile->GetEndPos() - 9) { if (!m_pFile->Sync(FrameSize, rtDuration)) { Sleep(1); continue; } CAutoPtr<Packet> p(DNew Packet()); p->SetCount(FrameSize); m_pFile->ByteRead(p->GetData(), FrameSize); p->TrackNumber = 0; p->rtStart = m_rtStart; p->rtStop = m_rtStart + rtDuration; p->bSyncPoint = TRUE; hr = DeliverPacket(p); m_rtStart += rtDuration; } return true; }
bool CDSMSplitterFilter::DemuxLoop() { HRESULT hr = S_OK; while (SUCCEEDED(hr) && !CheckRequest(nullptr) && m_pFile->GetRemaining()) { dsmp_t type; UINT64 len; if (!m_pFile->Sync(type, len)) { continue; } __int64 pos = m_pFile->GetPos(); if (type == DSMP_SAMPLE) { CAutoPtr<Packet> p(DEBUG_NEW Packet()); if (m_pFile->Read(len, p)) { if (p->rtStart != Packet::INVALID_TIME) { p->rtStart -= m_pFile->m_rtFirst; p->rtStop -= m_pFile->m_rtFirst; } hr = DeliverPacket(p); } } m_pFile->Seek(pos + len); } return true; }
int CEASpliterFilter::eav_get_packet( int size) { AVPacket *pkt = (AVPacket *)m_pkt; //int ret= av_new_packet(pkt, size); //if(ret<0) // return ret; pkt->pos= m_pFile->GetPos();//url_ftell(s); //ret= m_pFile->ByteRead( pkt->data, size); //get_buffer(s, pkt->data, size); //if(ret<=0) // av_free_packet(pkt); //else{ pkt->size= size; CAutoPtr<Packet> p; p.Attach(new Packet()); p->TrackNumber = pkt->stream_index; p->rtStart = pkt->pts; p->rtStop = p->rtStart + pkt->duration; p->bSyncPoint = pkt->flags; p->SetCount(size); m_pFile->ByteRead(p->GetData(), p->GetCount()); HRESULT hr = DeliverPacket(p); //} return (hr == S_OK); }
DWORD CBaseSplitterOutputPin::ThreadProc() { m_hrDeliver = S_OK; m_fFlushing = m_fFlushed = false; m_eEndFlush.Set(); while(1) { Sleep(1); DWORD cmd; if(CheckRequest(&cmd)) { m_hThread = NULL; cmd = GetRequest(); Reply(S_OK); ASSERT(cmd == CMD_EXIT); return 0; } int cnt = 0; do { CAutoPtr<Packet> p; { CAutoLock cAutoLock(&m_queue); if((cnt = m_queue.GetCount()) > 0) p = m_queue.Remove(); } if(S_OK == m_hrDeliver && cnt > 0) { ASSERT(!m_fFlushing); m_fFlushed = false; // flushing can still start here, to release a blocked deliver call HRESULT hr = p ? DeliverPacket(p) : DeliverEndOfStream(); m_eEndFlush.Wait(); // .. so we have to wait until it is done if(hr != S_OK && !m_fFlushed) // and only report the error in m_hrDeliver if we didn't flush the stream { // CAutoLock cAutoLock(&m_csQueueLock); m_hrDeliver = hr; break; } } } while(--cnt > 0); } }
void ReceivePackets(double now) { while (packetQueue.size() > 0) { std::map<double, Packet>::iterator ptr = packetQueue.begin(); if ((*ptr).first < now) { DeliverPacket((*ptr).second, now); packetQueue.erase(ptr); } else { break; } } }
DWORD CBaseSplitterOutputPin::ThreadProc() { SetThreadName(DWORD(-1), "CBaseSplitterOutputPin"); m_hrDeliver = S_OK; m_fFlushing = m_fFlushed = false; m_eEndFlush.Set(); // fix for Microsoft DTV-DVD Video Decoder - video freeze after STOP/PLAY bool iHaaliRenderConnect = false; CComPtr<IPin> pPinTo = this, pTmp; while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) { pTmp = nullptr; CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo); if (GetCLSID(pBF) == CLSID_DXR) { // Haali Renderer iHaaliRenderConnect = true; break; } pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT); } if (IsConnected() && !iHaaliRenderConnect) { GetConnected()->BeginFlush(); GetConnected()->EndFlush(); } for (;;) { Sleep(1); DWORD cmd; if (CheckRequest(&cmd)) { m_hThread = nullptr; cmd = GetRequest(); Reply(S_OK); ASSERT(cmd == CMD_EXIT); return 0; } int cnt = 0; do { CAutoPtr<Packet> p; { CAutoLock cAutoLock(&m_queue); if ((cnt = m_queue.GetCount()) > 0) { p = m_queue.Remove(); } } if (S_OK == m_hrDeliver && cnt > 0) { ASSERT(!m_fFlushing); m_fFlushed = false; // flushing can still start here, to release a blocked deliver call HRESULT hr = p ? DeliverPacket(p) : DeliverEndOfStream(); m_eEndFlush.Wait(); // .. so we have to wait until it is done if (hr != S_OK && !m_fFlushed) { // and only report the error in m_hrDeliver if we didn't flush the stream // CAutoLock cAutoLock(&m_csQueueLock); m_hrDeliver = hr; break; } } } while (--cnt > 0); } }
DWORD CLAVOutputPin::ThreadProc() { std::string name = "CLAVOutputPin " + std::string(CBaseDemuxer::CStreamList::ToString(m_pinType)); SetThreadName(-1, name.c_str()); m_hrDeliver = S_OK; m_fFlushing = m_fFlushed = false; m_eEndFlush.Set(); bool bFailFlush = false; while(1) { Sleep(1); DWORD cmd; if(CheckRequest(&cmd)) { cmd = GetRequest(); Reply(S_OK); ASSERT(cmd == CMD_EXIT); return 0; } size_t cnt = 0; do { Packet *pPacket = NULL; // Get a packet from the queue (scoped for lock) { CAutoLock cAutoLock(&m_queue); if((cnt = m_queue.Size()) > 0) { pPacket = m_queue.Get(); } } // We need to check cnt instead of pPacket, since it can be NULL for EndOfStream if(m_hrDeliver == S_OK && cnt > 0) { ASSERT(!m_fFlushing); m_fFlushed = false; // flushing can still start here, to release a blocked deliver call HRESULT hr = pPacket ? DeliverPacket(pPacket) : DeliverEndOfStream(); // .. so, wait until flush finished m_eEndFlush.Wait(); if(hr != S_OK && !m_fFlushed) { DbgLog((LOG_TRACE, 10, L"OutputPin::ThreadProc(): Delivery failed on %s pin, hr: %0#.8x", CBaseDemuxer::CStreamList::ToStringW(GetPinType()), hr)); if (!bFailFlush && hr == S_FALSE) { DbgLog((LOG_TRACE, 10, L"OutputPin::ThreadProc(): Trying to revive it by flushing...")); GetConnected()->BeginFlush(); GetConnected()->EndFlush(); bFailFlush = true; } else { m_hrDeliver = hr; } break; } } else if (pPacket) { // in case of stream switches or other events, we may end up here SAFE_DELETE(pPacket); } } while(cnt > 1 && m_hrDeliver == S_OK); } return 0; }
bool CNutSplitterFilter::DemuxLoop() { bool fKeyFrame = false; while(!CheckRequest(NULL) && m_pFile->GetRemaining()) { CNutFile::frame_header fh; fh.checksum_flag = 1; UINT64 id = 0; if(m_pFile->BitRead(1, true) == 0) { fh.zero_bit = m_pFile->BitRead(1); fh.priority = m_pFile->BitRead(2); fh.checksum_flag = m_pFile->BitRead(1); fh.msb_timestamp_flag = m_pFile->BitRead(1); fh.subpacket_type = m_pFile->BitRead(2); fh.reserved = m_pFile->BitRead(1); } else { if((id = m_pFile->BitRead(64)) == NUTK) { fKeyFrame = true; continue; } } CNutFile::packet_header ph; m_pFile->Read(ph); if(id == 0) { CNutFile::vint stream_id; m_pFile->Read(stream_id); CNutFile::stream_header* sh = NULL; POSITION pos = m_pFile->m_streams.GetHeadPosition(); while(pos) { CNutFile::stream_header* tmp = m_pFile->m_streams.GetNext(pos); if(tmp->stream_id == stream_id) {sh = tmp; break;} } if(sh) { if(fh.msb_timestamp_flag) m_pFile->Read(sh->msb_timestamp); CNutFile::svint lsb_timestamp = 0; m_pFile->Read(lsb_timestamp); TRACE(_T("[%I64d]: %I64d:%I64d\n"), stream_id, sh->msb_timestamp, lsb_timestamp); CAutoPtr<Packet> p(new Packet()); p->TrackNumber = (DWORD)stream_id; p->bSyncPoint = fKeyFrame; p->rtStart = 10000i64 * ((sh->msb_timestamp << sh->msb_timestamp_shift) + lsb_timestamp) * sh->time_base_nom / sh->time_base_denom; p->rtStop = p->rtStart+1; fKeyFrame = false; CNutFile::vint len = ph.fptr - (m_pFile->GetPos() - ph.pos); if(fh.checksum_flag) len -= 4; if(fh.subpacket_type == 1) { p->SetCount(len); m_pFile->ByteRead(p->GetData(), p->GetCount()); if(FAILED(DeliverPacket(p))) break; } else { // TODO /* vint subpacket_count; Read(subpacket_count); if(fh.subpacket_type & 1) { CArray<vint> keyframe_run; keyframe_run.SetSize(subpacket_count); for(int i = 0; i < subpacket_count; i++) Read(keyframe_run[i]); } CArray<vint> timestamp_diff; timestamp_diff.SetSize(subpacket_count); CArray<vint> timestamp_diff_run; timestamp_diff_run.SetSize(subpacket_count); for(int i = 0; i < subpacket_count; i++) { Read(timestamp_diff[i]); if(timestamp_diff[i] & 1) Read(timestamp_diff_run[i]); } if(fh.subpacket_type & 2) { CArray<string> subpacket_size_diff; for(int i = 0; i < subpacket_count-1; i++) { Read(subpacket_size_diff[i]); } } for(int i = 0; i < subpacket_count; i++) { } */ } } } if(fh.checksum_flag) { m_pFile->Seek(ph.pos + ph.fptr - 4); ph.checksum = (UINT32)m_pFile->BitRead(32); } m_pFile->Seek(ph.pos + ph.fptr); } return(true); }