From a8719e5ec1754612f2fd2007b9690f56943fc9f7 Mon Sep 17 00:00:00 2001 From: v0lt Date: Fri, 10 May 2013 10:33:12 +0400 Subject: AviSplitter: improved playback for non interleaved AVI files, reduced memory usage, "Non interleaved files support" option is always enabled now. --- src/filters/parser/AviSplitter/AviSplitter.cpp | 96 +++++++++------------- .../parser/AviSplitter/AviSplitterSettingsWnd.cpp | 1 + 2 files changed, 38 insertions(+), 59 deletions(-) diff --git a/src/filters/parser/AviSplitter/AviSplitter.cpp b/src/filters/parser/AviSplitter/AviSplitter.cpp index d8f25c862..1fc39699a 100644 --- a/src/filters/parser/AviSplitter/AviSplitter.cpp +++ b/src/filters/parser/AviSplitter/AviSplitter.cpp @@ -24,7 +24,7 @@ #include "AviFile.h" #include "AviSplitter.h" -#define MAXPACKETS_AVI 10000 +#define MAXPACKETS_AVI 100 #ifdef STANDALONE_FILTER @@ -119,7 +119,7 @@ CAviSplitterFilter::CAviSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr) , m_bNonInterleavedFilesSupport(true) { #ifdef STANDALONE_FILTER - CRegKey key; + /*CRegKey key; if (ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, _T("Software\\Gabest\\Filters\\AVI Splitter"), KEY_READ)) { DWORD dw; @@ -127,9 +127,9 @@ CAviSplitterFilter::CAviSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr) if (ERROR_SUCCESS == key.QueryDWORDValue(_T("NonInterleavedFilesSupport"), dw)) { m_bNonInterleavedFilesSupport = !!dw; } - } + }*/ #else - m_bNonInterleavedFilesSupport = !!AfxGetApp()->GetProfileInt(_T("Filters\\AVI Splitter"), _T("NonInterleavedFilesSupport"), m_bNonInterleavedFilesSupport); + //m_bNonInterleavedFilesSupport = !!AfxGetApp()->GetProfileInt(_T("Filters\\AVI Splitter"), _T("NonInterleavedFilesSupport"), m_bNonInterleavedFilesSupport); #endif } @@ -498,15 +498,15 @@ HRESULT CAviSplitterFilter::ReIndex(__int64 end, UINT64* pSize) void CAviSplitterFilter::DemuxSeek(REFERENCE_TIME rt) { - memset((DWORD*)m_tFrame, 0, sizeof(DWORD)*m_pFile->m_avih.dwStreams); + size_t nTracks = m_pFile->m_strms.GetCount(); + + memset((DWORD*)m_tFrame, 0, nTracks * sizeof(DWORD)); m_pFile->Seek(0); DbgLog((LOG_TRACE, 0, _T("Seek: %I64d"), rt / 10000)); if (rt > 0) { - UINT64 minfp = _I64_MAX; - - for (unsigned int j = 0; j < m_pFile->m_strms.GetCount(); ++j) { + for (size_t j = 0; j < nTracks; ++j) { CAviFile::strm_t* s = m_pFile->m_strms[j]; if (s->IsRawSubtitleStream() || s->cs.IsEmpty()) { @@ -514,22 +514,8 @@ void CAviSplitterFilter::DemuxSeek(REFERENCE_TIME rt) } //ASSERT(s->GetFrame(rt) == s->GetKeyFrame(rt)); // fast seek test - UINT64 fp = s->cs[s->GetKeyFrame(rt)].filepos; - minfp = min(minfp, fp); - } - - for (unsigned int j = 0; j < m_pFile->m_strms.GetCount(); ++j) { - CAviFile::strm_t* s = m_pFile->m_strms[j]; - - for (unsigned int i = 0; i < s->cs.GetCount(); ++i) { - CAviFile::strm_t::chunk& c = s->cs[i]; - if (c.filepos >= minfp) { - m_tFrame[j] = i; - break; - } - } + m_tFrame[j] = s->GetKeyFrame(rt); } - DbgLog((LOG_TRACE, 0, _T("minfp: %I64d"), minfp)); } } @@ -541,50 +527,42 @@ bool CAviSplitterFilter::DemuxLoop() CAtlArray fDiscontinuity; fDiscontinuity.SetCount(nTracks); - memset(fDiscontinuity.GetData(), 0, nTracks * sizeof(bool)); + memset(fDiscontinuity.GetData(), 0, nTracks * sizeof(BOOL)); while (SUCCEEDED(hr) && !CheckRequest(nullptr)) { - size_t minTrack = nTracks; - UINT64 minFilePos = _I64_MAX; + DWORD curTrack; - for (unsigned int i = 0; i < nTracks; ++i) { - CAviFile::strm_t* s = m_pFile->m_strms[i]; + REFERENCE_TIME minTime = INT64_MAX; + for (size_t j = 0; j < nTracks; ++j) { + CAviFile::strm_t* s = m_pFile->m_strms[j]; + DWORD f = m_tFrame[j]; - DWORD f = m_tFrame[i]; - if (f >= (DWORD)s->cs.GetCount()) { + if (f >= (DWORD)s->cs.GetCount() || s->IsRawSubtitleStream()) { continue; } - bool fUrgent = s->IsRawSubtitleStream(); - - if (fUrgent || s->cs[f].filepos < minFilePos) { - minTrack = i; - minFilePos = s->cs[f].filepos; - } - - if (fUrgent) { - break; + REFERENCE_TIME start = s->GetRefTime(f, s->cs[f].size); + if (start < minTime) { + minTime = start; + curTrack = j; } } - if (minTrack == nTracks) { - break; + if (minTime == INT64_MAX) { + return true; } - DWORD& f = m_tFrame[minTrack]; - do { - CAviFile::strm_t* s = m_pFile->m_strms[minTrack]; + CAviFile::strm_t* s = m_pFile->m_strms[curTrack]; + DWORD f = m_tFrame[curTrack]; m_pFile->Seek(s->cs[f].filepos); - DWORD size = 0; if (s->cs[f].fChunkHdr) { DWORD id = 0; - if (S_OK != m_pFile->Read(id) || id == 0 || minTrack != TRACKNUM(id) - || S_OK != m_pFile->Read(size)) { - fDiscontinuity[minTrack] = true; + if (S_OK != m_pFile->Read(id) || id == 0 || curTrack != TRACKNUM(id) || S_OK != m_pFile->Read(size)) { + fDiscontinuity[curTrack] = true; break; } @@ -593,7 +571,7 @@ bool CAviSplitterFilter::DemuxLoop() : s->totalsize - s->cs[f].size; if (expectedsize != s->GetChunkSize(size)) { - fDiscontinuity[minTrack] = true; + fDiscontinuity[curTrack] = true; //ASSERT(0); break; } @@ -603,11 +581,11 @@ bool CAviSplitterFilter::DemuxLoop() CAutoPtr p(DEBUG_NEW Packet()); - p->TrackNumber = (DWORD)minTrack; - p->bSyncPoint = (BOOL)s->cs[f].fKeyFrame; - p->bDiscontinuity = fDiscontinuity[minTrack]; - p->rtStart = s->GetRefTime(f, s->cs[f].size); - p->rtStop = s->GetRefTime(f + 1, f + 1 < (DWORD)s->cs.GetCount() ? s->cs[f + 1].size : s->totalsize); + p->TrackNumber = (DWORD)curTrack; + p->bSyncPoint = (BOOL)s->cs[f].fKeyFrame; + p->bDiscontinuity = fDiscontinuity[curTrack]; + p->rtStart = s->GetRefTime(f, s->cs[f].size); + p->rtStop = s->GetRefTime(f + 1, f + 1 < (DWORD)s->cs.GetCount() ? s->cs[f + 1].size : s->totalsize); p->SetCount(size); if (S_OK != (hr = m_pFile->ByteRead(p->GetData(), p->GetCount()))) { return true; // break; @@ -624,10 +602,10 @@ bool CAviSplitterFilter::DemuxLoop() hr = DeliverPacket(p); - fDiscontinuity[minTrack] = false; + fDiscontinuity[curTrack] = false; } while (0); - ++f; + m_tFrame[curTrack]++; } if (m_maxTimeStamp != Packet::INVALID_TIME) { @@ -941,12 +919,12 @@ STDMETHODIMP CAviSplitterFilter::CreatePage(const GUID& guid, IPropertyPage** pp STDMETHODIMP CAviSplitterFilter::Apply() { #ifdef STANDALONE_FILTER - CRegKey key; + /*CRegKey key; if (ERROR_SUCCESS == key.Create(HKEY_CURRENT_USER, _T("Software\\Gabest\\Filters\\AVI Splitter"))) { key.SetDWORDValue(_T("NonInterleavedFilesSupport"), m_bNonInterleavedFilesSupport); - } + }*/ #else - AfxGetApp()->WriteProfileInt(_T("Filters\\AVI Splitter"), _T("NonInterleavedFilesSupport"), m_bNonInterleavedFilesSupport); + //AfxGetApp()->WriteProfileInt(_T("Filters\\AVI Splitter"), _T("NonInterleavedFilesSupport"), m_bNonInterleavedFilesSupport); #endif return S_OK; diff --git a/src/filters/parser/AviSplitter/AviSplitterSettingsWnd.cpp b/src/filters/parser/AviSplitter/AviSplitterSettingsWnd.cpp index 699a11db0..c2abc83ef 100644 --- a/src/filters/parser/AviSplitter/AviSplitterSettingsWnd.cpp +++ b/src/filters/parser/AviSplitter/AviSplitterSettingsWnd.cpp @@ -65,6 +65,7 @@ bool CAviSplitterSettingsWnd::OnActivate() if (m_pASF) { m_cbNonInterleavedFilesSupport.SetCheck(m_pASF->GetNonInterleavedFilesSupport()); } + m_cbNonInterleavedFilesSupport.EnableWindow(FALSE); for (CWnd* pWnd = GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow()) { pWnd->SetFont(&m_font, FALSE); -- cgit v1.2.3