Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@users.sourceforge.net>2010-04-09 18:12:59 +0400
committerXhmikosR <xhmikosr@users.sourceforge.net>2010-04-09 18:12:59 +0400
commitefbc9d9043ff8ff92716ddd00a5f61412d535593 (patch)
tree8f3e621f756cf1f5b4d64d97964c7e7abd8aaf08 /src/filters/muxer
parentdf6b139a6d9027156f614b68687e039e3a5854db (diff)
revert r1783
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1785 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/muxer')
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxer.cpp662
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxer.h137
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxerInputPin.cpp324
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxerInputPin.h104
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.cpp793
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.h42
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.cpp14
-rw-r--r--src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.h27
-rw-r--r--src/filters/muxer/BaseMuxer/BitStream.cpp156
-rw-r--r--src/filters/muxer/BaseMuxer/BitStream.h51
-rw-r--r--src/filters/muxer/BaseMuxer/stdafx.cpp8
-rw-r--r--src/filters/muxer/BaseMuxer/stdafx.h8
-rw-r--r--src/filters/muxer/DSMMuxer/DSMMuxer.cpp671
-rw-r--r--src/filters/muxer/DSMMuxer/DSMMuxer.h52
-rw-r--r--src/filters/muxer/DSMMuxer/resource.h2
-rw-r--r--src/filters/muxer/DSMMuxer/stdafx.cpp8
-rw-r--r--src/filters/muxer/DSMMuxer/stdafx.h8
-rw-r--r--src/filters/muxer/MatroskaMuxer/MatroskaFile.cpp1056
-rw-r--r--src/filters/muxer/MatroskaMuxer/MatroskaFile.h731
-rw-r--r--src/filters/muxer/MatroskaMuxer/MatroskaMuxer.cpp2188
-rw-r--r--src/filters/muxer/MatroskaMuxer/MatroskaMuxer.h148
-rw-r--r--src/filters/muxer/MatroskaMuxer/resource.h2
-rw-r--r--src/filters/muxer/MatroskaMuxer/stdafx.cpp8
-rw-r--r--src/filters/muxer/MatroskaMuxer/stdafx.h8
-rw-r--r--src/filters/muxer/WavDest/WavDest.cpp97
-rw-r--r--src/filters/muxer/WavDest/WavDest.h10
-rw-r--r--src/filters/muxer/WavDest/stdafx.cpp8
-rw-r--r--src/filters/muxer/WavDest/stdafx.h8
28 files changed, 3546 insertions, 3785 deletions
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxer.cpp b/src/filters/muxer/BaseMuxer/BaseMuxer.cpp
index 7e28159f1..4ff8199f9 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxer.cpp
+++ b/src/filters/muxer/BaseMuxer/BaseMuxer.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -27,12 +27,12 @@
//
CBaseMuxerFilter::CBaseMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid)
- : CBaseFilter(NAME("CBaseMuxerFilter"), pUnk, this, clsid)
- , m_rtCurrent(0)
+ : CBaseFilter(NAME("CBaseMuxerFilter"), pUnk, this, clsid)
+ , m_rtCurrent(0)
{
- if(phr) *phr = S_OK;
- m_pOutput.Attach(DNew CBaseMuxerOutputPin(L"Output", this, this, phr));
- AddInput();
+ if(phr) *phr = S_OK;
+ m_pOutput.Attach(DNew CBaseMuxerOutputPin(L"Output", this, this, phr));
+ AddInput();
}
CBaseMuxerFilter::~CBaseMuxerFilter()
@@ -41,452 +41,396 @@ CBaseMuxerFilter::~CBaseMuxerFilter()
STDMETHODIMP CBaseMuxerFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
-
- *ppv = NULL;
-
- return
- QI(IMediaSeeking)
- QI(IPropertyBag)
- QI(IPropertyBag2)
- QI(IDSMPropertyBag)
- QI(IDSMResourceBag)
- QI(IDSMChapterBag)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ CheckPointer(ppv, E_POINTER);
+
+ *ppv = NULL;
+
+ return
+ QI(IMediaSeeking)
+ QI(IPropertyBag)
+ QI(IPropertyBag2)
+ QI(IDSMPropertyBag)
+ QI(IDSMResourceBag)
+ QI(IDSMChapterBag)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
//
void CBaseMuxerFilter::AddInput()
{
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- CBasePin* pPin = m_pInputs.GetNext(pos);
- if(!pPin->IsConnected()) return;
- }
-
- CStringW name;
-
- name.Format(L"Input %d", m_pInputs.GetCount() + 1);
-
- CBaseMuxerInputPin* pInputPin = NULL;
- if(FAILED(CreateInput(name, &pInputPin)) || !pInputPin)
- {
- ASSERT(0);
- return;
- }
- CAutoPtr<CBaseMuxerInputPin> pAutoPtrInputPin(pInputPin);
-
- name.Format(L"~Output %d", m_pRawOutputs.GetCount() + 1);
-
- CBaseMuxerRawOutputPin* pRawOutputPin = NULL;
- if(FAILED(CreateRawOutput(name, &pRawOutputPin)) || !pRawOutputPin)
- {
- ASSERT(0);
- return;
- }
- CAutoPtr<CBaseMuxerRawOutputPin> pAutoPtrRawOutputPin(pRawOutputPin);
-
- pInputPin->SetRelatedPin(pRawOutputPin);
- pRawOutputPin->SetRelatedPin(pInputPin);
-
- m_pInputs.AddTail(pAutoPtrInputPin);
- m_pRawOutputs.AddTail(pAutoPtrRawOutputPin);
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos)
+ {
+ CBasePin* pPin = m_pInputs.GetNext(pos);
+ if(!pPin->IsConnected()) return;
+ }
+
+ CStringW name;
+
+ name.Format(L"Input %d", m_pInputs.GetCount()+1);
+
+ CBaseMuxerInputPin* pInputPin = NULL;
+ if(FAILED(CreateInput(name, &pInputPin)) || !pInputPin) {ASSERT(0); return;}
+ CAutoPtr<CBaseMuxerInputPin> pAutoPtrInputPin(pInputPin);
+
+ name.Format(L"~Output %d", m_pRawOutputs.GetCount()+1);
+
+ CBaseMuxerRawOutputPin* pRawOutputPin = NULL;
+ if(FAILED(CreateRawOutput(name, &pRawOutputPin)) || !pRawOutputPin) {ASSERT(0); return;}
+ CAutoPtr<CBaseMuxerRawOutputPin> pAutoPtrRawOutputPin(pRawOutputPin);
+
+ pInputPin->SetRelatedPin(pRawOutputPin);
+ pRawOutputPin->SetRelatedPin(pInputPin);
+
+ m_pInputs.AddTail(pAutoPtrInputPin);
+ m_pRawOutputs.AddTail(pAutoPtrRawOutputPin);
}
HRESULT CBaseMuxerFilter::CreateInput(CStringW name, CBaseMuxerInputPin** ppPin)
{
- CheckPointer(ppPin, E_POINTER);
- HRESULT hr = S_OK;
- *ppPin = DNew CBaseMuxerInputPin(name, this, this, &hr);
- return hr;
+ CheckPointer(ppPin, E_POINTER);
+ HRESULT hr = S_OK;
+ *ppPin = DNew CBaseMuxerInputPin(name, this, this, &hr);
+ return hr;
}
HRESULT CBaseMuxerFilter::CreateRawOutput(CStringW name, CBaseMuxerRawOutputPin** ppPin)
{
- CheckPointer(ppPin, E_POINTER);
- HRESULT hr = S_OK;
- *ppPin = DNew CBaseMuxerRawOutputPin(name, this, this, &hr);
- return hr;
+ CheckPointer(ppPin, E_POINTER);
+ HRESULT hr = S_OK;
+ *ppPin = DNew CBaseMuxerRawOutputPin(name, this, this, &hr);
+ return hr;
}
//
DWORD CBaseMuxerFilter::ThreadProc()
{
- SetThreadPriority(m_hThread, THREAD_PRIORITY_ABOVE_NORMAL);
-
- POSITION pos;
-
- while(1)
- {
- DWORD cmd = GetRequest();
-
- switch(cmd)
- {
- default:
- case CMD_EXIT:
- CAMThread::m_hThread = NULL;
- Reply(S_OK);
- return 0;
-
- case CMD_RUN:
- m_pActivePins.RemoveAll();
- m_pPins.RemoveAll();
-
- pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- CBaseMuxerInputPin* pPin = m_pInputs.GetNext(pos);
- if(pPin->IsConnected())
- {
- m_pActivePins.AddTail(pPin);
- m_pPins.AddTail(pPin);
- }
- }
-
- m_rtCurrent = 0;
-
- Reply(S_OK);
-
- MuxInit();
-
- try
- {
- MuxHeaderInternal();
-
- while(!CheckRequest(NULL) && m_pActivePins.GetCount())
- {
- if(m_State == State_Paused)
- {
- Sleep(10);
- continue;
- }
-
- CAutoPtr<MuxerPacket> pPacket = GetPacket();
- if(!pPacket)
- {
- Sleep(1);
- continue;
- }
-
- if(pPacket->IsTimeValid())
- m_rtCurrent = pPacket->rtStart;
-
- if(pPacket->IsEOS())
- m_pActivePins.RemoveAt(m_pActivePins.Find(pPacket->pPin));
-
- MuxPacketInternal(pPacket);
- }
-
- MuxFooterInternal();
- }
- catch(HRESULT hr)
- {
- CComQIPtr<IMediaEventSink>(m_pGraph)->Notify(EC_ERRORABORT, hr, 0);
- }
-
- m_pOutput->DeliverEndOfStream();
-
- pos = m_pRawOutputs.GetHeadPosition();
- while(pos) m_pRawOutputs.GetNext(pos)->DeliverEndOfStream();
-
- m_pActivePins.RemoveAll();
- m_pPins.RemoveAll();
-
- break;
- }
- }
-
- ASSERT(0); // this function should only return via CMD_EXIT
-
- CAMThread::m_hThread = NULL;
- return 0;
+ SetThreadPriority(m_hThread, THREAD_PRIORITY_ABOVE_NORMAL);
+
+ POSITION pos;
+
+ while(1)
+ {
+ DWORD cmd = GetRequest();
+
+ switch(cmd)
+ {
+ default:
+ case CMD_EXIT:
+ CAMThread::m_hThread = NULL;
+ Reply(S_OK);
+ return 0;
+
+ case CMD_RUN:
+ m_pActivePins.RemoveAll();
+ m_pPins.RemoveAll();
+
+ pos = m_pInputs.GetHeadPosition();
+ while(pos)
+ {
+ CBaseMuxerInputPin* pPin = m_pInputs.GetNext(pos);
+ if(pPin->IsConnected())
+ {
+ m_pActivePins.AddTail(pPin);
+ m_pPins.AddTail(pPin);
+ }
+ }
+
+ m_rtCurrent = 0;
+
+ Reply(S_OK);
+
+ MuxInit();
+
+ try
+ {
+ MuxHeaderInternal();
+
+ while(!CheckRequest(NULL) && m_pActivePins.GetCount())
+ {
+ if(m_State == State_Paused) {Sleep(10); continue;}
+
+ CAutoPtr<MuxerPacket> pPacket = GetPacket();
+ if(!pPacket) {Sleep(1); continue;}
+
+ if(pPacket->IsTimeValid())
+ m_rtCurrent = pPacket->rtStart;
+
+ if(pPacket->IsEOS())
+ m_pActivePins.RemoveAt(m_pActivePins.Find(pPacket->pPin));
+
+ MuxPacketInternal(pPacket);
+ }
+
+ MuxFooterInternal();
+ }
+ catch(HRESULT hr)
+ {
+ CComQIPtr<IMediaEventSink>(m_pGraph)->Notify(EC_ERRORABORT, hr, 0);
+ }
+
+ m_pOutput->DeliverEndOfStream();
+
+ pos = m_pRawOutputs.GetHeadPosition();
+ while(pos) m_pRawOutputs.GetNext(pos)->DeliverEndOfStream();
+
+ m_pActivePins.RemoveAll();
+ m_pPins.RemoveAll();
+
+ break;
+ }
+ }
+
+ ASSERT(0); // this function should only return via CMD_EXIT
+
+ CAMThread::m_hThread = NULL;
+ return 0;
}
void CBaseMuxerFilter::MuxHeaderInternal()
{
- TRACE(_T("MuxHeader\n"));
+ TRACE(_T("MuxHeader\n"));
- if(CComQIPtr<IBitStream> pBitStream = m_pOutput->GetBitStream())
- MuxHeader(pBitStream);
+ if(CComQIPtr<IBitStream> pBitStream = m_pOutput->GetBitStream())
+ MuxHeader(pBitStream);
- MuxHeader();
+ MuxHeader();
- //
+ //
- POSITION pos = m_pPins.GetHeadPosition();
- while(pos)
- {
- if(CBaseMuxerInputPin* pInput = m_pPins.GetNext(pos))
- if(CBaseMuxerRawOutputPin* pOutput = dynamic_cast<CBaseMuxerRawOutputPin*>(pInput->GetRelatedPin()))
- pOutput->MuxHeader(pInput->CurrentMediaType());
- }
+ POSITION pos = m_pPins.GetHeadPosition();
+ while(pos)
+ {
+ if(CBaseMuxerInputPin* pInput = m_pPins.GetNext(pos))
+ if(CBaseMuxerRawOutputPin* pOutput = dynamic_cast<CBaseMuxerRawOutputPin*>(pInput->GetRelatedPin()))
+ pOutput->MuxHeader(pInput->CurrentMediaType());
+ }
}
void CBaseMuxerFilter::MuxPacketInternal(const MuxerPacket* pPacket)
{
- TRACE(_T("MuxPacket pPin=%x, size=%d, s%d e%d b%d, rt=(%I64d-%I64d)\n"),
- pPacket->pPin->GetID(),
- pPacket->pData.GetCount(),
- !!(pPacket->flags & MuxerPacket::syncpoint),
- !!(pPacket->flags & MuxerPacket::eos),
- !!(pPacket->flags & MuxerPacket::bogus),
- pPacket->rtStart / 10000, pPacket->rtStop / 10000);
-
- if(CComQIPtr<IBitStream> pBitStream = m_pOutput->GetBitStream())
- MuxPacket(pBitStream, pPacket);
-
- MuxPacket(pPacket);
-
- if(CBaseMuxerInputPin* pInput = pPacket->pPin)
- if(CBaseMuxerRawOutputPin* pOutput = dynamic_cast<CBaseMuxerRawOutputPin*>(pInput->GetRelatedPin()))
- pOutput->MuxPacket(pInput->CurrentMediaType(), pPacket);
+ TRACE(_T("MuxPacket pPin=%x, size=%d, s%d e%d b%d, rt=(%I64d-%I64d)\n"),
+ pPacket->pPin->GetID(),
+ pPacket->pData.GetCount(),
+ !!(pPacket->flags & MuxerPacket::syncpoint),
+ !!(pPacket->flags & MuxerPacket::eos),
+ !!(pPacket->flags & MuxerPacket::bogus),
+ pPacket->rtStart/10000, pPacket->rtStop/10000);
+
+ if(CComQIPtr<IBitStream> pBitStream = m_pOutput->GetBitStream())
+ MuxPacket(pBitStream, pPacket);
+
+ MuxPacket(pPacket);
+
+ if(CBaseMuxerInputPin* pInput = pPacket->pPin)
+ if(CBaseMuxerRawOutputPin* pOutput = dynamic_cast<CBaseMuxerRawOutputPin*>(pInput->GetRelatedPin()))
+ pOutput->MuxPacket(pInput->CurrentMediaType(), pPacket);
}
void CBaseMuxerFilter::MuxFooterInternal()
{
- TRACE(_T("MuxFooter\n"));
-
- if(CComQIPtr<IBitStream> pBitStream = m_pOutput->GetBitStream())
- MuxFooter(pBitStream);
+ TRACE(_T("MuxFooter\n"));
+
+ if(CComQIPtr<IBitStream> pBitStream = m_pOutput->GetBitStream())
+ MuxFooter(pBitStream);
- MuxFooter();
+ MuxFooter();
- //
+ //
- POSITION pos = m_pPins.GetHeadPosition();
- while(pos)
- {
- if(CBaseMuxerInputPin* pInput = m_pPins.GetNext(pos))
- if(CBaseMuxerRawOutputPin* pOutput = dynamic_cast<CBaseMuxerRawOutputPin*>(pInput->GetRelatedPin()))
- pOutput->MuxFooter(pInput->CurrentMediaType());
- }
+ POSITION pos = m_pPins.GetHeadPosition();
+ while(pos)
+ {
+ if(CBaseMuxerInputPin* pInput = m_pPins.GetNext(pos))
+ if(CBaseMuxerRawOutputPin* pOutput = dynamic_cast<CBaseMuxerRawOutputPin*>(pInput->GetRelatedPin()))
+ pOutput->MuxFooter(pInput->CurrentMediaType());
+ }
}
CAutoPtr<MuxerPacket> CBaseMuxerFilter::GetPacket()
{
- REFERENCE_TIME rtMin = _I64_MAX;
- CBaseMuxerInputPin* pPinMin = NULL;
- int i = int(m_pActivePins.GetCount());
-
- POSITION pos = m_pActivePins.GetHeadPosition();
- while(pos)
- {
- CBaseMuxerInputPin* pPin = m_pActivePins.GetNext(pos);
-
- CAutoLock cAutoLock(&pPin->m_csQueue);
- if(!pPin->m_queue.GetCount()) continue;
-
- MuxerPacket* p = pPin->m_queue.GetHead();
-
- if(p->IsBogus() || !p->IsTimeValid() || p->IsEOS())
- {
- pPinMin = pPin;
- i = 0;
- break;
- }
-
- if(p->rtStart < rtMin)
- {
- rtMin = p->rtStart;
- pPinMin = pPin;
- }
-
- i--;
- }
-
- CAutoPtr<MuxerPacket> pPacket;
-
- if(pPinMin && i == 0)
- {
- pPacket = pPinMin->PopPacket();
- }
- else
- {
- pos = m_pActivePins.GetHeadPosition();
- while(pos) m_pActivePins.GetNext(pos)->m_evAcceptPacket.Set();
- }
-
- return pPacket;
+ REFERENCE_TIME rtMin = _I64_MAX;
+ CBaseMuxerInputPin* pPinMin = NULL;
+ int i = int(m_pActivePins.GetCount());
+
+ POSITION pos = m_pActivePins.GetHeadPosition();
+ while(pos)
+ {
+ CBaseMuxerInputPin* pPin = m_pActivePins.GetNext(pos);
+
+ CAutoLock cAutoLock(&pPin->m_csQueue);
+ if(!pPin->m_queue.GetCount()) continue;
+
+ MuxerPacket* p = pPin->m_queue.GetHead();
+
+ if(p->IsBogus() || !p->IsTimeValid() || p->IsEOS())
+ {
+ pPinMin = pPin;
+ i = 0;
+ break;
+ }
+
+ if(p->rtStart < rtMin)
+ {
+ rtMin = p->rtStart;
+ pPinMin = pPin;
+ }
+
+ i--;
+ }
+
+ CAutoPtr<MuxerPacket> pPacket;
+
+ if(pPinMin && i == 0)
+ {
+ pPacket = pPinMin->PopPacket();
+ }
+ else
+ {
+ pos = m_pActivePins.GetHeadPosition();
+ while(pos) m_pActivePins.GetNext(pos)->m_evAcceptPacket.Set();
+ }
+
+ return pPacket;
}
//
int CBaseMuxerFilter::GetPinCount()
{
- return int(m_pInputs.GetCount()) + (m_pOutput ? 1 : 0) + int(m_pRawOutputs.GetCount());
+ return int(m_pInputs.GetCount()) + (m_pOutput ? 1 : 0) + int(m_pRawOutputs.GetCount());
}
CBasePin* CBaseMuxerFilter::GetPin(int n)
{
CAutoLock cAutoLock(this);
- if(n >= 0 && n < (int)m_pInputs.GetCount())
- {
- if(POSITION pos = m_pInputs.FindIndex(n))
- return m_pInputs.GetAt(pos);
- }
+ if(n >= 0 && n < (int)m_pInputs.GetCount())
+ {
+ if(POSITION pos = m_pInputs.FindIndex(n))
+ return m_pInputs.GetAt(pos);
+ }
- n -= int(m_pInputs.GetCount());
+ n -= int(m_pInputs.GetCount());
- if(n == 0 && m_pOutput)
- {
- return m_pOutput;
- }
+ if(n == 0 && m_pOutput)
+ {
+ return m_pOutput;
+ }
- n--;
+ n--;
- if(n >= 0 && n < (int)m_pRawOutputs.GetCount())
- {
- if(POSITION pos = m_pRawOutputs.FindIndex(n))
- return m_pRawOutputs.GetAt(pos);
- }
+ if(n >= 0 && n < (int)m_pRawOutputs.GetCount())
+ {
+ if(POSITION pos = m_pRawOutputs.FindIndex(n))
+ return m_pRawOutputs.GetAt(pos);
+ }
- n -= int(m_pRawOutputs.GetCount());
+ n -= int(m_pRawOutputs.GetCount());
- return NULL;
+ return NULL;
}
STDMETHODIMP CBaseMuxerFilter::Stop()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- HRESULT hr = __super::Stop();
- if(FAILED(hr)) return hr;
+ HRESULT hr = __super::Stop();
+ if(FAILED(hr)) return hr;
- CallWorker(CMD_EXIT);
+ CallWorker(CMD_EXIT);
- return hr;
+ return hr;
}
STDMETHODIMP CBaseMuxerFilter::Pause()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- FILTER_STATE fs = m_State;
+ FILTER_STATE fs = m_State;
- HRESULT hr = __super::Pause();
- if(FAILED(hr)) return hr;
+ HRESULT hr = __super::Pause();
+ if(FAILED(hr)) return hr;
- if(fs == State_Stopped && m_pOutput)
- {
- CAMThread::Create();
- CallWorker(CMD_RUN);
- }
+ if(fs == State_Stopped && m_pOutput)
+ {
+ CAMThread::Create();
+ CallWorker(CMD_RUN);
+ }
- return hr;
+ return hr;
}
STDMETHODIMP CBaseMuxerFilter::Run(REFERENCE_TIME tStart)
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- HRESULT hr = __super::Run(tStart);
- if(FAILED(hr)) return hr;
+ HRESULT hr = __super::Run(tStart);
+ if(FAILED(hr)) return hr;
- return hr;
+ return hr;
}
// IMediaSeeking
STDMETHODIMP CBaseMuxerFilter::GetCapabilities(DWORD* pCapabilities)
{
- return pCapabilities ? *pCapabilities = AM_SEEKING_CanGetDuration | AM_SEEKING_CanGetCurrentPos, S_OK : E_POINTER;
+ return pCapabilities ? *pCapabilities = AM_SEEKING_CanGetDuration|AM_SEEKING_CanGetCurrentPos, S_OK : E_POINTER;
}
STDMETHODIMP CBaseMuxerFilter::CheckCapabilities(DWORD* pCapabilities)
{
- CheckPointer(pCapabilities, E_POINTER);
- if(*pCapabilities == 0) return S_OK;
- DWORD caps;
- GetCapabilities(&caps);
- caps &= *pCapabilities;
- return caps == 0 ? E_FAIL : caps == *pCapabilities ? S_OK : S_FALSE;
-}
-STDMETHODIMP CBaseMuxerFilter::IsFormatSupported(const GUID* pFormat)
-{
- return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
-}
-STDMETHODIMP CBaseMuxerFilter::QueryPreferredFormat(GUID* pFormat)
-{
- return GetTimeFormat(pFormat);
-}
-STDMETHODIMP CBaseMuxerFilter::GetTimeFormat(GUID* pFormat)
-{
- return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;
-}
-STDMETHODIMP CBaseMuxerFilter::IsUsingTimeFormat(const GUID* pFormat)
-{
- return IsFormatSupported(pFormat);
-}
-STDMETHODIMP CBaseMuxerFilter::SetTimeFormat(const GUID* pFormat)
-{
- return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;
-}
+ CheckPointer(pCapabilities, E_POINTER);
+ if(*pCapabilities == 0) return S_OK;
+ DWORD caps;
+ GetCapabilities(&caps);
+ caps &= *pCapabilities;
+ return caps == 0 ? E_FAIL : caps == *pCapabilities ? S_OK : S_FALSE;
+}
+STDMETHODIMP CBaseMuxerFilter::IsFormatSupported(const GUID* pFormat) {return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;}
+STDMETHODIMP CBaseMuxerFilter::QueryPreferredFormat(GUID* pFormat) {return GetTimeFormat(pFormat);}
+STDMETHODIMP CBaseMuxerFilter::GetTimeFormat(GUID* pFormat) {return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;}
+STDMETHODIMP CBaseMuxerFilter::IsUsingTimeFormat(const GUID* pFormat) {return IsFormatSupported(pFormat);}
+STDMETHODIMP CBaseMuxerFilter::SetTimeFormat(const GUID* pFormat) {return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;}
STDMETHODIMP CBaseMuxerFilter::GetDuration(LONGLONG* pDuration)
{
- CheckPointer(pDuration, E_POINTER);
- *pDuration = 0;
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- REFERENCE_TIME rt = m_pInputs.GetNext(pos)->GetDuration();
- if(rt > *pDuration) *pDuration = rt;
- }
- return S_OK;
-}
-STDMETHODIMP CBaseMuxerFilter::GetStopPosition(LONGLONG* pStop)
-{
- return E_NOTIMPL;
+ CheckPointer(pDuration, E_POINTER);
+ *pDuration = 0;
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos) {REFERENCE_TIME rt = m_pInputs.GetNext(pos)->GetDuration(); if(rt > *pDuration) *pDuration = rt;}
+ return S_OK;
}
+STDMETHODIMP CBaseMuxerFilter::GetStopPosition(LONGLONG* pStop) {return E_NOTIMPL;}
STDMETHODIMP CBaseMuxerFilter::GetCurrentPosition(LONGLONG* pCurrent)
{
- CheckPointer(pCurrent, E_POINTER);
- *pCurrent = m_rtCurrent;
- return S_OK;
-}
-STDMETHODIMP CBaseMuxerFilter::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat)
-{
- return E_NOTIMPL;
+ CheckPointer(pCurrent, E_POINTER);
+ *pCurrent = m_rtCurrent;
+ return S_OK;
}
+STDMETHODIMP CBaseMuxerFilter::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat) {return E_NOTIMPL;}
STDMETHODIMP CBaseMuxerFilter::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
{
- FILTER_STATE fs;
-
- if(SUCCEEDED(GetState(0, &fs)) && fs == State_Stopped)
- {
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- CBasePin* pPin = m_pInputs.GetNext(pos);
- CComQIPtr<IMediaSeeking> pMS = pPin->GetConnected();
- if(!pMS) pMS = GetFilterFromPin(pPin->GetConnected());
- if(pMS) pMS->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
- }
-
- return S_OK;
- }
-
- return VFW_E_WRONG_STATE;
-}
-STDMETHODIMP CBaseMuxerFilter::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CBaseMuxerFilter::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CBaseMuxerFilter::SetRate(double dRate)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CBaseMuxerFilter::GetRate(double* pdRate)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CBaseMuxerFilter::GetPreroll(LONGLONG* pllPreroll)
-{
- return E_NOTIMPL;
-}
+ FILTER_STATE fs;
+
+ if(SUCCEEDED(GetState(0, &fs)) && fs == State_Stopped)
+ {
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos)
+ {
+ CBasePin* pPin = m_pInputs.GetNext(pos);
+ CComQIPtr<IMediaSeeking> pMS = pPin->GetConnected();
+ if(!pMS) pMS = GetFilterFromPin(pPin->GetConnected());
+ if(pMS) pMS->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
+ }
+
+ return S_OK;
+ }
+
+ return VFW_E_WRONG_STATE;
+}
+STDMETHODIMP CBaseMuxerFilter::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseMuxerFilter::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest) {return E_NOTIMPL;}
+STDMETHODIMP CBaseMuxerFilter::SetRate(double dRate) {return E_NOTIMPL;}
+STDMETHODIMP CBaseMuxerFilter::GetRate(double* pdRate) {return E_NOTIMPL;}
+STDMETHODIMP CBaseMuxerFilter::GetPreroll(LONGLONG* pllPreroll) {return E_NOTIMPL;}
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxer.h b/src/filters/muxer/BaseMuxer/BaseMuxer.h
index ce89c3af2..71aed60fa 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxer.h
+++ b/src/filters/muxer/BaseMuxer/BaseMuxer.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -25,88 +25,85 @@
#include "BaseMuxerOutputPin.h"
class CBaseMuxerFilter
- : public CBaseFilter
- , public CCritSec
- , public CAMThread
- , public IMediaSeeking
- , public IDSMPropertyBagImpl
- , public IDSMResourceBagImpl
- , public IDSMChapterBagImpl
+ : public CBaseFilter
+ , public CCritSec
+ , public CAMThread
+ , public IMediaSeeking
+ , public IDSMPropertyBagImpl
+ , public IDSMResourceBagImpl
+ , public IDSMChapterBagImpl
{
private:
- CAutoPtrList<CBaseMuxerInputPin> m_pInputs;
- CAutoPtr<CBaseMuxerOutputPin> m_pOutput;
- CAutoPtrList<CBaseMuxerRawOutputPin> m_pRawOutputs;
+ CAutoPtrList<CBaseMuxerInputPin> m_pInputs;
+ CAutoPtr<CBaseMuxerOutputPin> m_pOutput;
+ CAutoPtrList<CBaseMuxerRawOutputPin> m_pRawOutputs;
- enum {CMD_EXIT, CMD_RUN};
- DWORD ThreadProc();
+ enum {CMD_EXIT, CMD_RUN};
+ DWORD ThreadProc();
- REFERENCE_TIME m_rtCurrent;
- CAtlList<CBaseMuxerInputPin*> m_pActivePins;
+ REFERENCE_TIME m_rtCurrent;
+ CAtlList<CBaseMuxerInputPin*> m_pActivePins;
- CAutoPtr<MuxerPacket> GetPacket();
+ CAutoPtr<MuxerPacket> GetPacket();
- void MuxHeaderInternal();
- void MuxPacketInternal(const MuxerPacket* pPacket);
- void MuxFooterInternal();
+ void MuxHeaderInternal();
+ void MuxPacketInternal(const MuxerPacket* pPacket);
+ void MuxFooterInternal();
protected:
- CAtlList<CBaseMuxerInputPin*> m_pPins;
- CBaseMuxerOutputPin* GetOutputPin()
- {
- return m_pOutput;
- }
+ CAtlList<CBaseMuxerInputPin*> m_pPins;
+ CBaseMuxerOutputPin* GetOutputPin() {return m_pOutput;}
- virtual void MuxInit() = 0;
+ virtual void MuxInit() = 0;
- // only called when the output pin is connected
- virtual void MuxHeader(IBitStream* pBS) {}
- virtual void MuxPacket(IBitStream* pBS, const MuxerPacket* pPacket) {}
- virtual void MuxFooter(IBitStream* pBS) {}
+ // only called when the output pin is connected
+ virtual void MuxHeader(IBitStream* pBS) {}
+ virtual void MuxPacket(IBitStream* pBS, const MuxerPacket* pPacket) {}
+ virtual void MuxFooter(IBitStream* pBS) {}
- // always called (useful if the derived class wants to write somewhere else than downstream)
- virtual void MuxHeader() {}
- virtual void MuxPacket(const MuxerPacket* pPacket) {}
- virtual void MuxFooter() {}
+ // always called (useful if the derived class wants to write somewhere else than downstream)
+ virtual void MuxHeader() {}
+ virtual void MuxPacket(const MuxerPacket* pPacket) {}
+ virtual void MuxFooter() {}
- // allows customized pins in derived classes
- virtual HRESULT CreateInput(CStringW name, CBaseMuxerInputPin** ppPin);
- virtual HRESULT CreateRawOutput(CStringW name, CBaseMuxerRawOutputPin** ppPin);
+ // allows customized pins in derived classes
+ virtual HRESULT CreateInput(CStringW name, CBaseMuxerInputPin** ppPin);
+ virtual HRESULT CreateRawOutput(CStringW name, CBaseMuxerRawOutputPin** ppPin);
public:
- CBaseMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid);
- virtual ~CBaseMuxerFilter();
+ CBaseMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid);
+ virtual ~CBaseMuxerFilter();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- void AddInput();
-
- int GetPinCount();
- CBasePin* GetPin(int n);
-
- STDMETHODIMP Stop();
- STDMETHODIMP Pause();
- STDMETHODIMP Run(REFERENCE_TIME tStart);
-
- // IMediaSeeking
-
- STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* pFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
- STDMETHODIMP GetTimeFormat(GUID* pFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
- STDMETHODIMP SetTimeFormat(const GUID* pFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
- STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
- STDMETHODIMP SetRate(double dRate);
- STDMETHODIMP GetRate(double* pdRate);
- STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+ void AddInput();
+
+ int GetPinCount();
+ CBasePin* GetPin(int n);
+
+ STDMETHODIMP Stop();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Run(REFERENCE_TIME tStart);
+
+ // IMediaSeeking
+
+ STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+ STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+ STDMETHODIMP GetTimeFormat(GUID* pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+ STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+ STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+ STDMETHODIMP SetRate(double dRate);
+ STDMETHODIMP GetRate(double* pdRate);
+ STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
};
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.cpp b/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.cpp
index 4eb5d5cae..4aa1bedb9 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.cpp
+++ b/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -33,13 +33,13 @@
//
CBaseMuxerInputPin::CBaseMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseInputPin(NAME("CBaseMuxerInputPin"), pFilter, pLock, phr, pName)
- , m_rtDuration(0)
- , m_evAcceptPacket(TRUE)
- , m_iPacketIndex(0)
+ : CBaseInputPin(NAME("CBaseMuxerInputPin"), pFilter, pLock, phr, pName)
+ , m_rtDuration(0)
+ , m_evAcceptPacket(TRUE)
+ , m_iPacketIndex(0)
{
- static int s_iID = 0;
- m_iID = s_iID++;
+ static int s_iID = 0;
+ m_iID = s_iID++;
}
CBaseMuxerInputPin::~CBaseMuxerInputPin()
@@ -48,232 +48,232 @@ CBaseMuxerInputPin::~CBaseMuxerInputPin()
STDMETHODIMP CBaseMuxerInputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
-
- return
- QI(IBaseMuxerRelatedPin)
- QI(IPropertyBag)
- QI(IPropertyBag2)
- QI(IDSMPropertyBag)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IBaseMuxerRelatedPin)
+ QI(IPropertyBag)
+ QI(IPropertyBag2)
+ QI(IDSMPropertyBag)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
bool CBaseMuxerInputPin::IsSubtitleStream()
{
- return m_mt.majortype == MEDIATYPE_Subtitle || m_mt.majortype == MEDIATYPE_Text;
+ return m_mt.majortype == MEDIATYPE_Subtitle || m_mt.majortype == MEDIATYPE_Text;
}
void CBaseMuxerInputPin::PushPacket(CAutoPtr<MuxerPacket> pPacket)
{
- for(int i = 0; m_pFilter->IsActive() && !m_bFlushing
- && !m_evAcceptPacket.Wait(1)
- && i < 1000;
- i++);
+ for(int i = 0; m_pFilter->IsActive() && !m_bFlushing
+ && !m_evAcceptPacket.Wait(1)
+ && i < 1000;
+ i++);
- if(!m_pFilter->IsActive() || m_bFlushing)
- return;
+ if(!m_pFilter->IsActive() || m_bFlushing)
+ return;
- CAutoLock cAutoLock(&m_csQueue);
+ CAutoLock cAutoLock(&m_csQueue);
- m_queue.AddTail(pPacket);
+ m_queue.AddTail(pPacket);
- if(m_queue.GetCount() >= MAXQUEUESIZE)
- m_evAcceptPacket.Reset();
+ if(m_queue.GetCount() >= MAXQUEUESIZE)
+ m_evAcceptPacket.Reset();
}
CAutoPtr<MuxerPacket> CBaseMuxerInputPin::PopPacket()
{
- CAutoPtr<MuxerPacket> pPacket;
+ CAutoPtr<MuxerPacket> pPacket;
- CAutoLock cAutoLock(&m_csQueue);
+ CAutoLock cAutoLock(&m_csQueue);
- if(m_queue.GetCount())
- pPacket = m_queue.RemoveHead();
+ if(m_queue.GetCount())
+ pPacket = m_queue.RemoveHead();
- if(m_queue.GetCount() < MAXQUEUESIZE)
- m_evAcceptPacket.Set();
+ if(m_queue.GetCount() < MAXQUEUESIZE)
+ m_evAcceptPacket.Set();
- return pPacket;
+ return pPacket;
}
HRESULT CBaseMuxerInputPin::CheckMediaType(const CMediaType* pmt)
{
- if(pmt->formattype == FORMAT_WaveFormatEx)
- {
- WORD wFormatTag = ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag;
- if((wFormatTag == WAVE_FORMAT_PCM
- || wFormatTag == WAVE_FORMAT_EXTENSIBLE
- || wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
- && pmt->subtype != FOURCCMap(wFormatTag)
- && !(pmt->subtype == MEDIASUBTYPE_PCM && wFormatTag == WAVE_FORMAT_EXTENSIBLE)
- && !(pmt->subtype == MEDIASUBTYPE_PCM && wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
- && pmt->subtype != MEDIASUBTYPE_DVD_LPCM_AUDIO
- && pmt->subtype != MEDIASUBTYPE_DOLBY_AC3
- && pmt->subtype != MEDIASUBTYPE_DTS)
- {
- return E_INVALIDARG;
- }
- }
-
- return pmt->majortype == MEDIATYPE_Video
- || pmt->majortype == MEDIATYPE_Audio && pmt->formattype != FORMAT_VorbisFormat
- || pmt->majortype == MEDIATYPE_Text && pmt->subtype == MEDIASUBTYPE_NULL && pmt->formattype == FORMAT_None
- || pmt->majortype == MEDIATYPE_Subtitle
- ? S_OK
- : E_INVALIDARG;
+ if(pmt->formattype == FORMAT_WaveFormatEx)
+ {
+ WORD wFormatTag = ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag;
+ if((wFormatTag == WAVE_FORMAT_PCM
+ || wFormatTag == WAVE_FORMAT_EXTENSIBLE
+ || wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
+ && pmt->subtype != FOURCCMap(wFormatTag)
+ && !(pmt->subtype == MEDIASUBTYPE_PCM && wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ && !(pmt->subtype == MEDIASUBTYPE_PCM && wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
+ && pmt->subtype != MEDIASUBTYPE_DVD_LPCM_AUDIO
+ && pmt->subtype != MEDIASUBTYPE_DOLBY_AC3
+ && pmt->subtype != MEDIASUBTYPE_DTS)
+ {
+ return E_INVALIDARG;
+ }
+ }
+
+ return pmt->majortype == MEDIATYPE_Video
+ || pmt->majortype == MEDIATYPE_Audio && pmt->formattype != FORMAT_VorbisFormat
+ || pmt->majortype == MEDIATYPE_Text && pmt->subtype == MEDIASUBTYPE_NULL && pmt->formattype == FORMAT_None
+ || pmt->majortype == MEDIATYPE_Subtitle
+ ? S_OK
+ : E_INVALIDARG;
}
HRESULT CBaseMuxerInputPin::BreakConnect()
{
- HRESULT hr = __super::BreakConnect();
- if(FAILED(hr)) return hr;
+ HRESULT hr = __super::BreakConnect();
+ if(FAILED(hr)) return hr;
- RemoveAll();
+ RemoveAll();
- // TODO: remove extra disconnected pins, leave one
+ // TODO: remove extra disconnected pins, leave one
- return hr;
+ return hr;
}
HRESULT CBaseMuxerInputPin::CompleteConnect(IPin* pReceivePin)
{
- HRESULT hr = __super::CompleteConnect(pReceivePin);
- if(FAILED(hr)) return hr;
-
- // duration
-
- m_rtDuration = 0;
- CComQIPtr<IMediaSeeking> pMS;
- if((pMS = GetFilterFromPin(pReceivePin)) || (pMS = pReceivePin))
- pMS->GetDuration(&m_rtDuration);
-
- // properties
-
- for(CComPtr<IPin> pPin = pReceivePin; pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin)))
- {
- if(CComQIPtr<IDSMPropertyBag> pPB = pPin)
- {
- ULONG cProperties = 0;
- if(SUCCEEDED(pPB->CountProperties(&cProperties)) && cProperties > 0)
- {
- for(ULONG iProperty = 0; iProperty < cProperties; iProperty++)
- {
- PROPBAG2 PropBag;
- memset(&PropBag, 0, sizeof(PropBag));
- ULONG cPropertiesReturned = 0;
- if(FAILED(pPB->GetPropertyInfo(iProperty, 1, &PropBag, &cPropertiesReturned)))
- continue;
-
- HRESULT hr;
- CComVariant var;
- if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
- SetProperty(PropBag.pstrName, &var);
-
- CoTaskMemFree(PropBag.pstrName);
- }
- }
- }
- }
-
- (static_cast<CBaseMuxerFilter*>(m_pFilter))->AddInput();
-
- return S_OK;
+ HRESULT hr = __super::CompleteConnect(pReceivePin);
+ if(FAILED(hr)) return hr;
+
+ // duration
+
+ m_rtDuration = 0;
+ CComQIPtr<IMediaSeeking> pMS;
+ if((pMS = GetFilterFromPin(pReceivePin)) || (pMS = pReceivePin))
+ pMS->GetDuration(&m_rtDuration);
+
+ // properties
+
+ for(CComPtr<IPin> pPin = pReceivePin; pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin)))
+ {
+ if(CComQIPtr<IDSMPropertyBag> pPB = pPin)
+ {
+ ULONG cProperties = 0;
+ if(SUCCEEDED(pPB->CountProperties(&cProperties)) && cProperties > 0)
+ {
+ for(ULONG iProperty = 0; iProperty < cProperties; iProperty++)
+ {
+ PROPBAG2 PropBag;
+ memset(&PropBag, 0, sizeof(PropBag));
+ ULONG cPropertiesReturned = 0;
+ if(FAILED(pPB->GetPropertyInfo(iProperty, 1, &PropBag, &cPropertiesReturned)))
+ continue;
+
+ HRESULT hr;
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
+ SetProperty(PropBag.pstrName, &var);
+
+ CoTaskMemFree(PropBag.pstrName);
+ }
+ }
+ }
+ }
+
+ (static_cast<CBaseMuxerFilter*>(m_pFilter))->AddInput();
+
+ return S_OK;
}
HRESULT CBaseMuxerInputPin::Active()
{
- m_rtMaxStart = _I64_MIN;
- m_fEOS = false;
- m_iPacketIndex = 0;
- m_evAcceptPacket.Set();
- return __super::Active();
+ m_rtMaxStart = _I64_MIN;
+ m_fEOS = false;
+ m_iPacketIndex = 0;
+ m_evAcceptPacket.Set();
+ return __super::Active();
}
HRESULT CBaseMuxerInputPin::Inactive()
{
- CAutoLock cAutoLock(&m_csQueue);
- m_queue.RemoveAll();
- return __super::Inactive();
+ CAutoLock cAutoLock(&m_csQueue);
+ m_queue.RemoveAll();
+ return __super::Inactive();
}
STDMETHODIMP CBaseMuxerInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- CAutoLock cAutoLock(&m_csReceive);
+ CAutoLock cAutoLock(&m_csReceive);
- return __super::NewSegment(tStart, tStop, dRate);
+ return __super::NewSegment(tStart, tStop, dRate);
}
STDMETHODIMP CBaseMuxerInputPin::Receive(IMediaSample* pSample)
{
- CAutoLock cAutoLock(&m_csReceive);
+ CAutoLock cAutoLock(&m_csReceive);
- HRESULT hr = __super::Receive(pSample);
- if(FAILED(hr)) return hr;
+ HRESULT hr = __super::Receive(pSample);
+ if(FAILED(hr)) return hr;
- CAutoPtr<MuxerPacket> pPacket(DNew MuxerPacket(this));
+ CAutoPtr<MuxerPacket> pPacket(DNew MuxerPacket(this));
- long len = pSample->GetActualDataLength();
+ long len = pSample->GetActualDataLength();
- BYTE* pData = NULL;
- if(FAILED(pSample->GetPointer(&pData)) || !pData)
- return S_OK;
+ BYTE* pData = NULL;
+ if(FAILED(pSample->GetPointer(&pData)) || !pData)
+ return S_OK;
- pPacket->pData.SetCount(len);
- memcpy(pPacket->pData.GetData(), pData, len);
+ pPacket->pData.SetCount(len);
+ memcpy(pPacket->pData.GetData(), pData, len);
- if(S_OK == pSample->IsSyncPoint() || m_mt.majortype == MEDIATYPE_Audio && !m_mt.bTemporalCompression)
- {
- pPacket->flags |= MuxerPacket::syncpoint;
- }
+ if(S_OK == pSample->IsSyncPoint() || m_mt.majortype == MEDIATYPE_Audio && !m_mt.bTemporalCompression)
+ {
+ pPacket->flags |= MuxerPacket::syncpoint;
+ }
- if(S_OK == pSample->GetTime(&pPacket->rtStart, &pPacket->rtStop))
- {
- pPacket->flags |= MuxerPacket::timevalid;
+ if(S_OK == pSample->GetTime(&pPacket->rtStart, &pPacket->rtStop))
+ {
+ pPacket->flags |= MuxerPacket::timevalid;
- pPacket->rtStart += m_tStart;
- pPacket->rtStop += m_tStart;
+ pPacket->rtStart += m_tStart;
+ pPacket->rtStop += m_tStart;
- if((pPacket->flags & MuxerPacket::syncpoint) && pPacket->rtStart < m_rtMaxStart)
- {
- pPacket->flags &= ~MuxerPacket::syncpoint;
- pPacket->flags |= MuxerPacket::bogus;
- }
+ if((pPacket->flags & MuxerPacket::syncpoint) && pPacket->rtStart < m_rtMaxStart)
+ {
+ pPacket->flags &= ~MuxerPacket::syncpoint;
+ pPacket->flags |= MuxerPacket::bogus;
+ }
- m_rtMaxStart = max(m_rtMaxStart, pPacket->rtStart);
- }
- else if(pPacket->flags & MuxerPacket::syncpoint)
- {
- pPacket->flags &= ~MuxerPacket::syncpoint;
- pPacket->flags |= MuxerPacket::bogus;
- }
+ m_rtMaxStart = max(m_rtMaxStart, pPacket->rtStart);
+ }
+ else if(pPacket->flags & MuxerPacket::syncpoint)
+ {
+ pPacket->flags &= ~MuxerPacket::syncpoint;
+ pPacket->flags |= MuxerPacket::bogus;
+ }
- if(S_OK == pSample->IsDiscontinuity())
- {
- pPacket->flags |= MuxerPacket::discontinuity;
- }
+ if(S_OK == pSample->IsDiscontinuity())
+ {
+ pPacket->flags |= MuxerPacket::discontinuity;
+ }
- pPacket->index = m_iPacketIndex++;
+ pPacket->index = m_iPacketIndex++;
- PushPacket(pPacket);
+ PushPacket(pPacket);
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CBaseMuxerInputPin::EndOfStream()
{
- CAutoLock cAutoLock(&m_csReceive);
+ CAutoLock cAutoLock(&m_csReceive);
- HRESULT hr = __super::EndOfStream();
- if(FAILED(hr)) return hr;
+ HRESULT hr = __super::EndOfStream();
+ if(FAILED(hr)) return hr;
- ASSERT(!m_fEOS);
+ ASSERT(!m_fEOS);
- CAutoPtr<MuxerPacket> pPacket(DNew MuxerPacket(this));
- pPacket->flags |= MuxerPacket::eos;
- PushPacket(pPacket);
+ CAutoPtr<MuxerPacket> pPacket(DNew MuxerPacket(this));
+ pPacket->flags |= MuxerPacket::eos;
+ PushPacket(pPacket);
- m_fEOS = true;
+ m_fEOS = true;
- return hr;
+ return hr;
}
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.h b/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.h
index 826931e93..7b10c3474 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.h
+++ b/src/filters/muxer/BaseMuxer/BaseMuxerInputPin.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -28,88 +28,58 @@ class CBaseMuxerInputPin;
struct MuxerPacket
{
- CBaseMuxerInputPin* pPin;
- REFERENCE_TIME rtStart, rtStop;
- CAtlArray<BYTE> pData;
- enum flag_t {empty = 0, timevalid = 1, syncpoint = 2, discontinuity = 4, eos = 8, bogus = 16};
- DWORD flags;
- int index;
- struct MuxerPacket(CBaseMuxerInputPin* pPin)
- {
- this->pPin = pPin;
- rtStart = rtStop = _I64_MIN;
- flags = empty;
- index = -1;
- }
- bool IsTimeValid() const
- {
- return !!(flags & timevalid);
- }
- bool IsSyncPoint() const
- {
- return !!(flags & syncpoint);
- }
- bool IsDiscontinuity() const
- {
- return !!(flags & discontinuity);
- }
- bool IsEOS() const
- {
- return !!(flags & eos);
- }
- bool IsBogus() const
- {
- return !!(flags & bogus);
- }
+ CBaseMuxerInputPin* pPin;
+ REFERENCE_TIME rtStart, rtStop;
+ CAtlArray<BYTE> pData;
+ enum flag_t {empty = 0, timevalid = 1, syncpoint = 2, discontinuity = 4, eos = 8, bogus = 16};
+ DWORD flags;
+ int index;
+ struct MuxerPacket(CBaseMuxerInputPin* pPin) {this->pPin = pPin; rtStart = rtStop = _I64_MIN; flags = empty; index = -1;}
+ bool IsTimeValid() const {return !!(flags & timevalid);}
+ bool IsSyncPoint() const {return !!(flags & syncpoint);}
+ bool IsDiscontinuity() const {return !!(flags & discontinuity);}
+ bool IsEOS() const {return !!(flags & eos);}
+ bool IsBogus() const {return !!(flags & bogus);}
};
class CBaseMuxerInputPin : public CBaseInputPin, public CBaseMuxerRelatedPin, public IDSMPropertyBagImpl
{
private:
- int m_iID;
+ int m_iID;
- CCritSec m_csReceive;
- REFERENCE_TIME m_rtMaxStart, m_rtDuration;
- bool m_fEOS;
- int m_iPacketIndex;
+ CCritSec m_csReceive;
+ REFERENCE_TIME m_rtMaxStart, m_rtDuration;
+ bool m_fEOS;
+ int m_iPacketIndex;
- CCritSec m_csQueue;
- CAutoPtrList<MuxerPacket> m_queue;
- void PushPacket(CAutoPtr<MuxerPacket> pPacket);
- CAutoPtr<MuxerPacket> PopPacket();
- CAMEvent m_evAcceptPacket;
+ CCritSec m_csQueue;
+ CAutoPtrList<MuxerPacket> m_queue;
+ void PushPacket(CAutoPtr<MuxerPacket> pPacket);
+ CAutoPtr<MuxerPacket> PopPacket();
+ CAMEvent m_evAcceptPacket;
- friend class CBaseMuxerFilter;
+ friend class CBaseMuxerFilter;
public:
- CBaseMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CBaseMuxerInputPin();
+ CBaseMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CBaseMuxerInputPin();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- REFERENCE_TIME GetDuration()
- {
- return m_rtDuration;
- }
- int GetID()
- {
- return m_iID;
- }
- CMediaType& CurrentMediaType()
- {
- return m_mt;
- }
- bool IsSubtitleStream();
+ REFERENCE_TIME GetDuration() {return m_rtDuration;}
+ int GetID() {return m_iID;}
+ CMediaType& CurrentMediaType() {return m_mt;}
+ bool IsSubtitleStream();
HRESULT CheckMediaType(const CMediaType* pmt);
HRESULT BreakConnect();
HRESULT CompleteConnect(IPin* pReceivePin);
- HRESULT Active();
- HRESULT Inactive();
+ HRESULT Active();
+ HRESULT Inactive();
STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
- STDMETHODIMP Receive(IMediaSample* pSample);
+ STDMETHODIMP Receive(IMediaSample* pSample);
STDMETHODIMP EndOfStream();
};
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.cpp b/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.cpp
index 8f5c2019f..d827ba1f6 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.cpp
+++ b/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -34,28 +34,28 @@
//
CBaseMuxerOutputPin::CBaseMuxerOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseOutputPin(_T("CBaseMuxerOutputPin"), pFilter, pLock, phr, pName)
+ : CBaseOutputPin(_T("CBaseMuxerOutputPin"), pFilter, pLock, phr, pName)
{
}
IBitStream* CBaseMuxerOutputPin::GetBitStream()
{
- if(!m_pBitStream)
- {
- if(CComQIPtr<IStream> pStream = GetConnected())
- {
- m_pBitStream = DNew CBitStream(pStream, true);
- }
- }
-
- return m_pBitStream;
+ if(!m_pBitStream)
+ {
+ if(CComQIPtr<IStream> pStream = GetConnected())
+ {
+ m_pBitStream = DNew CBitStream(pStream, true);
+ }
+ }
+
+ return m_pBitStream;
}
HRESULT CBaseMuxerOutputPin::BreakConnect()
{
- m_pBitStream = NULL;
+ m_pBitStream = NULL;
- return __super::BreakConnect();
+ return __super::BreakConnect();
}
HRESULT CBaseMuxerOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
@@ -65,8 +65,8 @@ HRESULT CBaseMuxerOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_P
HRESULT hr = NOERROR;
- pProperties->cBuffers = 1;
- pProperties->cbBuffer = 1;
+ pProperties->cBuffers = 1;
+ pProperties->cbBuffer = 1;
ALLOCATOR_PROPERTIES Actual;
if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
@@ -79,37 +79,37 @@ HRESULT CBaseMuxerOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_P
HRESULT CBaseMuxerOutputPin::CheckMediaType(const CMediaType* pmt)
{
- return pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_NULL
- ? S_OK
- : E_INVALIDARG;
+ return pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_NULL
+ ? S_OK
+ : E_INVALIDARG;
}
HRESULT CBaseMuxerOutputPin::GetMediaType(int iPosition, CMediaType* pmt)
{
CAutoLock cAutoLock(m_pLock);
- if(iPosition < 0) return E_INVALIDARG;
- if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
+ if(iPosition < 0) return E_INVALIDARG;
+ if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
- pmt->ResetFormatBuffer();
- pmt->InitMediaType();
- pmt->majortype = MEDIATYPE_Stream;
- pmt->subtype = MEDIASUBTYPE_NULL;
- pmt->formattype = FORMAT_None;
+ pmt->ResetFormatBuffer();
+ pmt->InitMediaType();
+ pmt->majortype = MEDIATYPE_Stream;
+ pmt->subtype = MEDIASUBTYPE_NULL;
+ pmt->formattype = FORMAT_None;
- return S_OK;
+ return S_OK;
}
HRESULT CBaseMuxerOutputPin::DeliverEndOfStream()
{
- m_pBitStream = NULL;
+ m_pBitStream = NULL;
- return __super::DeliverEndOfStream();
+ return __super::DeliverEndOfStream();
}
STDMETHODIMP CBaseMuxerOutputPin::Notify(IBaseFilter* pSender, Quality q)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
//
@@ -117,392 +117,381 @@ STDMETHODIMP CBaseMuxerOutputPin::Notify(IBaseFilter* pSender, Quality q)
//
CBaseMuxerRawOutputPin::CBaseMuxerRawOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseMuxerOutputPin(pName, pFilter, pLock, phr)
+ : CBaseMuxerOutputPin(pName, pFilter, pLock, phr)
{
}
STDMETHODIMP CBaseMuxerRawOutputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- return
- QI(IBaseMuxerRelatedPin)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ QI(IBaseMuxerRelatedPin)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
void CBaseMuxerRawOutputPin::MuxHeader(const CMediaType& mt)
{
- CComQIPtr<IBitStream> pBitStream = GetBitStream();
- if(!pBitStream) return;
-
- const BYTE utf8bom[3] = {0xef, 0xbb, 0xbf};
-
- if((mt.subtype == FOURCCMap('1CVA') || mt.subtype == FOURCCMap('1cva')) && mt.formattype == FORMAT_MPEG2_VIDEO)
- {
- MPEG2VIDEOINFO* vih = (MPEG2VIDEOINFO*)mt.Format();
-
- for(DWORD i = 0; i < vih->cbSequenceHeader - 2; i += 2)
- {
- pBitStream->BitWrite(0x00000001, 32);
- WORD size = (((BYTE*)vih->dwSequenceHeader)[i+0] << 8) | ((BYTE*)vih->dwSequenceHeader)[i+1];
- pBitStream->ByteWrite(&((BYTE*)vih->dwSequenceHeader)[i+2], size);
- i += size;
- }
- }
- else if(mt.subtype == MEDIASUBTYPE_UTF8)
- {
- pBitStream->ByteWrite(utf8bom, sizeof(utf8bom));
- }
- else if(mt.subtype == MEDIASUBTYPE_SSA || mt.subtype == MEDIASUBTYPE_ASS || mt.subtype == MEDIASUBTYPE_ASS2)
- {
- SUBTITLEINFO* si = (SUBTITLEINFO*)mt.Format();
- BYTE* p = (BYTE*)si + si->dwOffset;
-
- if(memcmp(utf8bom, p, 3) != 0)
- pBitStream->ByteWrite(utf8bom, sizeof(utf8bom));
-
- CStringA str((char*)p, mt.FormatLength() - (p - mt.Format()));
- pBitStream->StrWrite(str + '\n', true);
-
- if(str.Find("[Events]") < 0)
- pBitStream->StrWrite("\n\n[Events]\n", true);
- }
- else if(mt.subtype == MEDIASUBTYPE_SSF)
- {
- DWORD dwOffset = ((SUBTITLEINFO*)mt.pbFormat)->dwOffset;
- try
- {
- m_ssf.Parse(ssf::MemoryInputStream(mt.pbFormat + dwOffset, mt.cbFormat - dwOffset, false, false));
- }
- catch(ssf::Exception&) {}
- }
- else if(mt.subtype == MEDIASUBTYPE_VOBSUB)
- {
- m_idx.RemoveAll();
- }
- else if(mt.majortype == MEDIATYPE_Audio
- && (mt.subtype == MEDIASUBTYPE_PCM
- || mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO
- || mt.subtype == FOURCCMap(WAVE_FORMAT_EXTENSIBLE)
- || mt.subtype == FOURCCMap(WAVE_FORMAT_IEEE_FLOAT))
- && mt.formattype == FORMAT_WaveFormatEx)
- {
- pBitStream->BitWrite('RIFF', 32);
- pBitStream->BitWrite(0, 32); // file length - 8, set later
- pBitStream->BitWrite('WAVE', 32);
-
- pBitStream->BitWrite('fmt ', 32);
- pBitStream->ByteWrite(&mt.cbFormat, 4);
- pBitStream->ByteWrite(mt.pbFormat, mt.cbFormat);
-
- pBitStream->BitWrite('data', 32);
- pBitStream->BitWrite(0, 32); // data length, set later
- }
+ CComQIPtr<IBitStream> pBitStream = GetBitStream();
+ if(!pBitStream) return;
+
+ const BYTE utf8bom[3] = {0xef, 0xbb, 0xbf};
+
+ if((mt.subtype == FOURCCMap('1CVA') || mt.subtype == FOURCCMap('1cva')) && mt.formattype == FORMAT_MPEG2_VIDEO)
+ {
+ MPEG2VIDEOINFO* vih = (MPEG2VIDEOINFO*)mt.Format();
+
+ for(DWORD i = 0; i < vih->cbSequenceHeader-2; i += 2)
+ {
+ pBitStream->BitWrite(0x00000001, 32);
+ WORD size = (((BYTE*)vih->dwSequenceHeader)[i+0]<<8) | ((BYTE*)vih->dwSequenceHeader)[i+1];
+ pBitStream->ByteWrite(&((BYTE*)vih->dwSequenceHeader)[i+2], size);
+ i += size;
+ }
+ }
+ else if(mt.subtype == MEDIASUBTYPE_UTF8)
+ {
+ pBitStream->ByteWrite(utf8bom, sizeof(utf8bom));
+ }
+ else if(mt.subtype == MEDIASUBTYPE_SSA || mt.subtype == MEDIASUBTYPE_ASS || mt.subtype == MEDIASUBTYPE_ASS2)
+ {
+ SUBTITLEINFO* si = (SUBTITLEINFO*)mt.Format();
+ BYTE* p = (BYTE*)si + si->dwOffset;
+
+ if(memcmp(utf8bom, p, 3) != 0)
+ pBitStream->ByteWrite(utf8bom, sizeof(utf8bom));
+
+ CStringA str((char*)p, mt.FormatLength() - (p - mt.Format()));
+ pBitStream->StrWrite(str + '\n', true);
+
+ if(str.Find("[Events]") < 0)
+ pBitStream->StrWrite("\n\n[Events]\n", true);
+ }
+ else if(mt.subtype == MEDIASUBTYPE_SSF)
+ {
+ DWORD dwOffset = ((SUBTITLEINFO*)mt.pbFormat)->dwOffset;
+ try {m_ssf.Parse(ssf::MemoryInputStream(mt.pbFormat + dwOffset, mt.cbFormat - dwOffset, false, false));}
+ catch(ssf::Exception&) {}
+ }
+ else if(mt.subtype == MEDIASUBTYPE_VOBSUB)
+ {
+ m_idx.RemoveAll();
+ }
+ else if(mt.majortype == MEDIATYPE_Audio
+ && (mt.subtype == MEDIASUBTYPE_PCM
+ || mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO
+ || mt.subtype == FOURCCMap(WAVE_FORMAT_EXTENSIBLE)
+ || mt.subtype == FOURCCMap(WAVE_FORMAT_IEEE_FLOAT))
+ && mt.formattype == FORMAT_WaveFormatEx)
+ {
+ pBitStream->BitWrite('RIFF', 32);
+ pBitStream->BitWrite(0, 32); // file length - 8, set later
+ pBitStream->BitWrite('WAVE', 32);
+
+ pBitStream->BitWrite('fmt ', 32);
+ pBitStream->ByteWrite(&mt.cbFormat, 4);
+ pBitStream->ByteWrite(mt.pbFormat, mt.cbFormat);
+
+ pBitStream->BitWrite('data', 32);
+ pBitStream->BitWrite(0, 32); // data length, set later
+ }
}
void CBaseMuxerRawOutputPin::MuxPacket(const CMediaType& mt, const MuxerPacket* pPacket)
{
- CComQIPtr<IBitStream> pBitStream = GetBitStream();
- if(!pBitStream) return;
-
- const BYTE* pData = pPacket->pData.GetData();
- const int DataSize = int(pPacket->pData.GetCount());
-
- if(mt.subtype == MEDIASUBTYPE_AAC && mt.formattype == FORMAT_WaveFormatEx)
- {
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
-
- int profile = 0;
-
- int srate_idx = 11;
- if(92017 <= wfe->nSamplesPerSec) srate_idx = 0;
- else if(75132 <= wfe->nSamplesPerSec) srate_idx = 1;
- else if(55426 <= wfe->nSamplesPerSec) srate_idx = 2;
- else if(46009 <= wfe->nSamplesPerSec) srate_idx = 3;
- else if(37566 <= wfe->nSamplesPerSec) srate_idx = 4;
- else if(27713 <= wfe->nSamplesPerSec) srate_idx = 5;
- else if(23004 <= wfe->nSamplesPerSec) srate_idx = 6;
- else if(18783 <= wfe->nSamplesPerSec) srate_idx = 7;
- else if(13856 <= wfe->nSamplesPerSec) srate_idx = 8;
- else if(11502 <= wfe->nSamplesPerSec) srate_idx = 9;
- else if(9391 <= wfe->nSamplesPerSec) srate_idx = 10;
-
- int channels = wfe->nChannels;
-
- if(wfe->cbSize >= 2)
- {
- BYTE* p = (BYTE*)(wfe + 1);
- profile = (p[0] >> 3) - 1;
- srate_idx = ((p[0] & 7) << 1) | ((p[1] & 0x80) >> 7);
- channels = (p[1] >> 3) & 15;
- }
-
- int len = (DataSize + 7) & 0x1fff;
-
- BYTE hdr[7] = {0xff, 0xf9};
- hdr[2] = (profile << 6) | (srate_idx << 2) | ((channels & 4) >> 2);
- hdr[3] = ((channels & 3) << 6) | (len >> 11);
- hdr[4] = (len >> 3) & 0xff;
- hdr[5] = ((len & 7) << 5) | 0x1f;
- hdr[6] = 0xfc;
-
- pBitStream->ByteWrite(hdr, sizeof(hdr));
- }
- else if((mt.subtype == FOURCCMap('1CVA') || mt.subtype == FOURCCMap('1cva')) && mt.formattype == FORMAT_MPEG2_VIDEO)
- {
- const BYTE* p = pData;
- int i = DataSize;
-
- while(i >= 4)
- {
- DWORD len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-
- i -= len + 4;
- p += len + 4;
- }
-
- if(i == 0)
- {
- p = pData;
- i = DataSize;
-
- while(i >= 4)
- {
- DWORD len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-
- pBitStream->BitWrite(0x00000001, 32);
-
- p += 4;
- i -= 4;
-
- if(len > i || len == 1)
- {
- len = i;
- ASSERT(0);
- }
-
- pBitStream->ByteWrite(p, len);
-
- p += len;
- i -= len;
- }
-
- return;
- }
- }
- else if(mt.subtype == MEDIASUBTYPE_UTF8 || mt.majortype == MEDIATYPE_Text)
- {
- CStringA str((char*)pData, DataSize);
- str.Trim();
- if(str.IsEmpty()) return;
-
- DVD_HMSF_TIMECODE start = RT2HMSF(pPacket->rtStart, 25);
- DVD_HMSF_TIMECODE stop = RT2HMSF(pPacket->rtStop, 25);
-
- str.Format("%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n%s\n\n",
- pPacket->index + 1,
- start.bHours, start.bMinutes, start.bSeconds, (int)((pPacket->rtStart / 10000) % 1000),
- stop.bHours, stop.bMinutes, stop.bSeconds, (int)((pPacket->rtStop / 10000) % 1000),
- CStringA(str));
-
- pBitStream->StrWrite(str, true);
-
- return;
- }
- else if(mt.subtype == MEDIASUBTYPE_SSA || mt.subtype == MEDIASUBTYPE_ASS || mt.subtype == MEDIASUBTYPE_ASS2)
- {
- CStringA str((char*)pData, DataSize);
- str.Trim();
- if(str.IsEmpty()) return;
-
- DVD_HMSF_TIMECODE start = RT2HMSF(pPacket->rtStart, 25);
- DVD_HMSF_TIMECODE stop = RT2HMSF(pPacket->rtStop, 25);
-
- int fields = mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9;
-
- CAtlList<CStringA> sl;
- Explode(str, sl, ',', fields);
- if(sl.GetCount() < fields) return;
-
- CStringA readorder = sl.RemoveHead(); // TODO
- CStringA layer = sl.RemoveHead();
- CStringA style = sl.RemoveHead();
- CStringA actor = sl.RemoveHead();
- CStringA left = sl.RemoveHead();
- CStringA right = sl.RemoveHead();
- CStringA top = sl.RemoveHead();
- if(fields == 10) top += ',' + sl.RemoveHead(); // bottom
- CStringA effect = sl.RemoveHead();
- str = sl.RemoveHead();
-
- if(mt.subtype == MEDIASUBTYPE_SSA) layer = "Marked=0";
-
- str.Format("Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s,%s,%s,%s,%s,%s,%s\n",
- layer,
- start.bHours, start.bMinutes, start.bSeconds, (int)((pPacket->rtStart / 100000) % 100),
- stop.bHours, stop.bMinutes, stop.bSeconds, (int)((pPacket->rtStop / 100000) % 100),
- style, actor, left, right, top, effect,
- CStringA(str));
-
- pBitStream->StrWrite(str, true);
-
- return;
- }
- else if(mt.subtype == MEDIASUBTYPE_SSF)
- {
- float start = (float)pPacket->rtStart / 10000000;
- float stop = (float)pPacket->rtStop / 10000000;
- m_ssf.Append(ssf::WCharInputStream(UTF8To16(CStringA((char*)pData, DataSize))), start, stop, true);
- return;
- }
- else if(mt.subtype == MEDIASUBTYPE_VOBSUB)
- {
- bool fTimeValid = pPacket->IsTimeValid();
-
- if(fTimeValid)
- {
- idx_t i;
- i.rt = pPacket->rtStart;
- i.fp = pBitStream->GetPos();
- m_idx.AddTail(i);
- }
-
- int DataSizeLeft = DataSize;
-
- while(DataSizeLeft > 0)
- {
- int BytesAvail = 0x7ec - (fTimeValid ? 9 : 4);
- int Size = min(BytesAvail, DataSizeLeft);
- int Padding = 0x800 - Size - 20 - (fTimeValid ? 9 : 4);
-
- pBitStream->BitWrite(0x000001ba, 32);
- pBitStream->BitWrite(0x440004000401ui64, 48);
- pBitStream->BitWrite(0x000003f8, 32);
- pBitStream->BitWrite(0x000001bd, 32);
-
- if(fTimeValid)
- {
- pBitStream->BitWrite(Size + 9, 16);
- pBitStream->BitWrite(0x8180052100010001ui64, 64);
- }
- else
- {
- pBitStream->BitWrite(Size + 4, 16);
- pBitStream->BitWrite(0x810000, 24);
- }
-
- pBitStream->BitWrite(0x20, 8);
-
- pBitStream->ByteWrite(pData, Size);
-
- pData += Size;
- DataSizeLeft -= Size;
-
- if(Padding > 0)
- {
- Padding -= 6;
- ASSERT(Padding >= 0);
- pBitStream->BitWrite(0x000001be, 32);
- pBitStream->BitWrite(Padding, 16);
- while(Padding-- > 0) pBitStream->BitWrite(0xff, 8);
- }
-
- fTimeValid = false;
- }
-
- return;
- }
- else if(mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
- {
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
-
- // This code is probably totally broken for anything but 16 bits
- for(int i = 0, bps = wfe->wBitsPerSample / 8; i < DataSize; i += bps)
- for(int j = bps - 1; j >= 0; j--)
- pBitStream->BitWrite(pData[i+j], 8);
-
- return;
- }
- // else // TODO: restore more streams (vorbis to ogg)
-
- pBitStream->ByteWrite(pData, DataSize);
+ CComQIPtr<IBitStream> pBitStream = GetBitStream();
+ if(!pBitStream) return;
+
+ const BYTE* pData = pPacket->pData.GetData();
+ const int DataSize = int(pPacket->pData.GetCount());
+
+ if(mt.subtype == MEDIASUBTYPE_AAC && mt.formattype == FORMAT_WaveFormatEx)
+ {
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
+
+ int profile = 0;
+
+ int srate_idx = 11;
+ if(92017 <= wfe->nSamplesPerSec) srate_idx = 0;
+ else if(75132 <= wfe->nSamplesPerSec) srate_idx = 1;
+ else if(55426 <= wfe->nSamplesPerSec) srate_idx = 2;
+ else if(46009 <= wfe->nSamplesPerSec) srate_idx = 3;
+ else if(37566 <= wfe->nSamplesPerSec) srate_idx = 4;
+ else if(27713 <= wfe->nSamplesPerSec) srate_idx = 5;
+ else if(23004 <= wfe->nSamplesPerSec) srate_idx = 6;
+ else if(18783 <= wfe->nSamplesPerSec) srate_idx = 7;
+ else if(13856 <= wfe->nSamplesPerSec) srate_idx = 8;
+ else if(11502 <= wfe->nSamplesPerSec) srate_idx = 9;
+ else if(9391 <= wfe->nSamplesPerSec) srate_idx = 10;
+
+ int channels = wfe->nChannels;
+
+ if(wfe->cbSize >= 2)
+ {
+ BYTE* p = (BYTE*)(wfe+1);
+ profile = (p[0]>>3)-1;
+ srate_idx = ((p[0]&7)<<1)|((p[1]&0x80)>>7);
+ channels = (p[1]>>3)&15;
+ }
+
+ int len = (DataSize + 7) & 0x1fff;
+
+ BYTE hdr[7] = {0xff, 0xf9};
+ hdr[2] = (profile<<6) | (srate_idx<<2) | ((channels&4)>>2);
+ hdr[3] = ((channels&3)<<6) | (len>>11);
+ hdr[4] = (len>>3)&0xff;
+ hdr[5] = ((len&7)<<5) | 0x1f;
+ hdr[6] = 0xfc;
+
+ pBitStream->ByteWrite(hdr, sizeof(hdr));
+ }
+ else if((mt.subtype == FOURCCMap('1CVA') || mt.subtype == FOURCCMap('1cva')) && mt.formattype == FORMAT_MPEG2_VIDEO)
+ {
+ const BYTE* p = pData;
+ int i = DataSize;
+
+ while(i >= 4)
+ {
+ DWORD len = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
+
+ i -= len + 4;
+ p += len + 4;
+ }
+
+ if(i == 0)
+ {
+ p = pData;
+ i = DataSize;
+
+ while(i >= 4)
+ {
+ DWORD len = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
+
+ pBitStream->BitWrite(0x00000001, 32);
+
+ p += 4;
+ i -= 4;
+
+ if(len > i || len == 1) {len = i; ASSERT(0);}
+
+ pBitStream->ByteWrite(p, len);
+
+ p += len;
+ i -= len;
+ }
+
+ return;
+ }
+ }
+ else if(mt.subtype == MEDIASUBTYPE_UTF8 || mt.majortype == MEDIATYPE_Text)
+ {
+ CStringA str((char*)pData, DataSize);
+ str.Trim();
+ if(str.IsEmpty()) return;
+
+ DVD_HMSF_TIMECODE start = RT2HMSF(pPacket->rtStart, 25);
+ DVD_HMSF_TIMECODE stop = RT2HMSF(pPacket->rtStop, 25);
+
+ str.Format("%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n%s\n\n",
+ pPacket->index+1,
+ start.bHours, start.bMinutes, start.bSeconds, (int)((pPacket->rtStart/10000)%1000),
+ stop.bHours, stop.bMinutes, stop.bSeconds, (int)((pPacket->rtStop/10000)%1000),
+ CStringA(str));
+
+ pBitStream->StrWrite(str, true);
+
+ return;
+ }
+ else if(mt.subtype == MEDIASUBTYPE_SSA || mt.subtype == MEDIASUBTYPE_ASS || mt.subtype == MEDIASUBTYPE_ASS2)
+ {
+ CStringA str((char*)pData, DataSize);
+ str.Trim();
+ if(str.IsEmpty()) return;
+
+ DVD_HMSF_TIMECODE start = RT2HMSF(pPacket->rtStart, 25);
+ DVD_HMSF_TIMECODE stop = RT2HMSF(pPacket->rtStop, 25);
+
+ int fields = mt.subtype == MEDIASUBTYPE_ASS2 ? 10 : 9;
+
+ CAtlList<CStringA> sl;
+ Explode(str, sl, ',', fields);
+ if(sl.GetCount() < fields) return;
+
+ CStringA readorder = sl.RemoveHead(); // TODO
+ CStringA layer = sl.RemoveHead();
+ CStringA style = sl.RemoveHead();
+ CStringA actor = sl.RemoveHead();
+ CStringA left = sl.RemoveHead();
+ CStringA right = sl.RemoveHead();
+ CStringA top = sl.RemoveHead();
+ if(fields == 10) top += ',' + sl.RemoveHead(); // bottom
+ CStringA effect = sl.RemoveHead();
+ str = sl.RemoveHead();
+
+ if(mt.subtype == MEDIASUBTYPE_SSA) layer = "Marked=0";
+
+ str.Format("Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s,%s,%s,%s,%s,%s,%s\n",
+ layer,
+ start.bHours, start.bMinutes, start.bSeconds, (int)((pPacket->rtStart/100000)%100),
+ stop.bHours, stop.bMinutes, stop.bSeconds, (int)((pPacket->rtStop/100000)%100),
+ style, actor, left, right, top, effect,
+ CStringA(str));
+
+ pBitStream->StrWrite(str, true);
+
+ return;
+ }
+ else if(mt.subtype == MEDIASUBTYPE_SSF)
+ {
+ float start = (float)pPacket->rtStart / 10000000;
+ float stop = (float)pPacket->rtStop / 10000000;
+ m_ssf.Append(ssf::WCharInputStream(UTF8To16(CStringA((char*)pData, DataSize))), start, stop, true);
+ return;
+ }
+ else if(mt.subtype == MEDIASUBTYPE_VOBSUB)
+ {
+ bool fTimeValid = pPacket->IsTimeValid();
+
+ if(fTimeValid)
+ {
+ idx_t i;
+ i.rt = pPacket->rtStart;
+ i.fp = pBitStream->GetPos();
+ m_idx.AddTail(i);
+ }
+
+ int DataSizeLeft = DataSize;
+
+ while(DataSizeLeft > 0)
+ {
+ int BytesAvail = 0x7ec - (fTimeValid ? 9 : 4);
+ int Size = min(BytesAvail, DataSizeLeft);
+ int Padding = 0x800 - Size - 20 - (fTimeValid ? 9 : 4);
+
+ pBitStream->BitWrite(0x000001ba, 32);
+ pBitStream->BitWrite(0x440004000401ui64, 48);
+ pBitStream->BitWrite(0x000003f8, 32);
+ pBitStream->BitWrite(0x000001bd, 32);
+
+ if(fTimeValid)
+ {
+ pBitStream->BitWrite(Size+9, 16);
+ pBitStream->BitWrite(0x8180052100010001ui64, 64);
+ }
+ else
+ {
+ pBitStream->BitWrite(Size+4, 16);
+ pBitStream->BitWrite(0x810000, 24);
+ }
+
+ pBitStream->BitWrite(0x20, 8);
+
+ pBitStream->ByteWrite(pData, Size);
+
+ pData += Size;
+ DataSizeLeft -= Size;
+
+ if(Padding > 0)
+ {
+ Padding -= 6;
+ ASSERT(Padding >= 0);
+ pBitStream->BitWrite(0x000001be, 32);
+ pBitStream->BitWrite(Padding, 16);
+ while(Padding-- > 0) pBitStream->BitWrite(0xff, 8);
+ }
+
+ fTimeValid = false;
+ }
+
+ return;
+ }
+ else if(mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
+ {
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
+
+ // This code is probably totally broken for anything but 16 bits
+ for(int i = 0, bps = wfe->wBitsPerSample/8; i < DataSize; i += bps)
+ for(int j = bps-1; j >= 0; j--)
+ pBitStream->BitWrite(pData[i+j], 8);
+
+ return;
+ }
+ // else // TODO: restore more streams (vorbis to ogg)
+
+ pBitStream->ByteWrite(pData, DataSize);
}
void CBaseMuxerRawOutputPin::MuxFooter(const CMediaType& mt)
{
- CComQIPtr<IBitStream> pBitStream = GetBitStream();
- if(!pBitStream) return;
-
- if(mt.majortype == MEDIATYPE_Audio
- && (mt.subtype == MEDIASUBTYPE_PCM
- || mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO
- || mt.subtype == FOURCCMap(WAVE_FORMAT_EXTENSIBLE)
- || mt.subtype == FOURCCMap(WAVE_FORMAT_IEEE_FLOAT))
- && mt.formattype == FORMAT_WaveFormatEx)
- {
- pBitStream->BitFlush();
-
- ASSERT(pBitStream->GetPos() <= 0xffffffff);
- UINT32 size = (UINT32)pBitStream->GetPos();
-
- size -= 8;
- pBitStream->Seek(4);
- pBitStream->ByteWrite(&size, 4);
-
- size -= sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + mt.FormatLength();
- pBitStream->Seek(sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + mt.FormatLength() + 4);
- pBitStream->ByteWrite(&size, 4);
- }
- else if(mt.subtype == MEDIASUBTYPE_SSF)
- {
- ssf::WCharOutputStream s;
- try
- {
- m_ssf.Dump(s);
- }
- catch(ssf::Exception&) {}
- CStringA str = UTF16To8(s.GetString());
- pBitStream->StrWrite(str, true);
- }
- else if(mt.subtype == MEDIASUBTYPE_VOBSUB)
- {
- if(CComQIPtr<IFileSinkFilter> pFSF = GetFilterFromPin(GetConnected()))
- {
- WCHAR* fn = NULL;
- if(SUCCEEDED(pFSF->GetCurFile(&fn, NULL)))
- {
- CPathW p(fn);
- p.RenameExtension(L".idx");
- CoTaskMemFree(fn);
-
- if(FILE* f = _tfopen(CString((LPCWSTR)p), _T("w")))
- {
- SUBTITLEINFO* si = (SUBTITLEINFO*)mt.Format();
-
- _ftprintf(f, _T("%s\n"), _T("# VobSub index file, v7 (do not modify this line!)"));
-
- fwrite(mt.Format() + si->dwOffset, mt.FormatLength() - si->dwOffset, 1, f);
-
- CString iso6391 = ISO6392To6391(si->IsoLang);
- if(iso6391.IsEmpty()) iso6391 = _T("--");
- _ftprintf(f, _T("\nlangidx: 0\n\nid: %s, index: 0\n"), iso6391);
-
- CString alt = CString(CStringW(si->TrackName));
- if(!alt.IsEmpty()) _ftprintf(f, _T("alt: %s\n"), alt);
-
- POSITION pos = m_idx.GetHeadPosition();
- while(pos)
- {
- const idx_t& i = m_idx.GetNext(pos);
- DVD_HMSF_TIMECODE start = RT2HMSF(i.rt, 25);
- _ftprintf(f, _T("timestamp: %02d:%02d:%02d:%03d, filepos: %09I64x\n"),
- start.bHours, start.bMinutes, start.bSeconds, (int)((i.rt / 10000) % 1000),
- i.fp);
- }
-
- fclose(f);
- }
- }
- }
- }
+ CComQIPtr<IBitStream> pBitStream = GetBitStream();
+ if(!pBitStream) return;
+
+ if(mt.majortype == MEDIATYPE_Audio
+ && (mt.subtype == MEDIASUBTYPE_PCM
+ || mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO
+ || mt.subtype == FOURCCMap(WAVE_FORMAT_EXTENSIBLE)
+ || mt.subtype == FOURCCMap(WAVE_FORMAT_IEEE_FLOAT))
+ && mt.formattype == FORMAT_WaveFormatEx)
+ {
+ pBitStream->BitFlush();
+
+ ASSERT(pBitStream->GetPos() <= 0xffffffff);
+ UINT32 size = (UINT32)pBitStream->GetPos();
+
+ size -= 8;
+ pBitStream->Seek(4);
+ pBitStream->ByteWrite(&size, 4);
+
+ size -= sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + mt.FormatLength();
+ pBitStream->Seek(sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + mt.FormatLength() + 4);
+ pBitStream->ByteWrite(&size, 4);
+ }
+ else if(mt.subtype == MEDIASUBTYPE_SSF)
+ {
+ ssf::WCharOutputStream s;
+ try {m_ssf.Dump(s);} catch(ssf::Exception&) {}
+ CStringA str = UTF16To8(s.GetString());
+ pBitStream->StrWrite(str, true);
+ }
+ else if(mt.subtype == MEDIASUBTYPE_VOBSUB)
+ {
+ if(CComQIPtr<IFileSinkFilter> pFSF = GetFilterFromPin(GetConnected()))
+ {
+ WCHAR* fn = NULL;
+ if(SUCCEEDED(pFSF->GetCurFile(&fn, NULL)))
+ {
+ CPathW p(fn);
+ p.RenameExtension(L".idx");
+ CoTaskMemFree(fn);
+
+ if(FILE* f = _tfopen(CString((LPCWSTR)p), _T("w")))
+ {
+ SUBTITLEINFO* si = (SUBTITLEINFO*)mt.Format();
+
+ _ftprintf(f, _T("%s\n"), _T("# VobSub index file, v7 (do not modify this line!)"));
+
+ fwrite(mt.Format() + si->dwOffset, mt.FormatLength() - si->dwOffset, 1, f);
+
+ CString iso6391 = ISO6392To6391(si->IsoLang);
+ if(iso6391.IsEmpty()) iso6391 = _T("--");
+ _ftprintf(f, _T("\nlangidx: 0\n\nid: %s, index: 0\n"), iso6391);
+
+ CString alt = CString(CStringW(si->TrackName));
+ if(!alt.IsEmpty()) _ftprintf(f, _T("alt: %s\n"), alt);
+
+ POSITION pos = m_idx.GetHeadPosition();
+ while(pos)
+ {
+ const idx_t& i = m_idx.GetNext(pos);
+ DVD_HMSF_TIMECODE start = RT2HMSF(i.rt, 25);
+ _ftprintf(f, _T("timestamp: %02d:%02d:%02d:%03d, filepos: %09I64x\n"),
+ start.bHours, start.bMinutes, start.bSeconds, (int)((i.rt/10000)%1000),
+ i.fp);
+ }
+
+ fclose(f);
+ }
+ }
+ }
+ }
}
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.h b/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.h
index 9ae84bc79..616943d3e 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.h
+++ b/src/filters/muxer/BaseMuxer/BaseMuxerOutputPin.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -28,15 +28,15 @@
class CBaseMuxerOutputPin : public CBaseOutputPin
{
- CComPtr<IBitStream> m_pBitStream;
+ CComPtr<IBitStream> m_pBitStream;
public:
- CBaseMuxerOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CBaseMuxerOutputPin() {}
+ CBaseMuxerOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CBaseMuxerOutputPin() {}
- IBitStream* GetBitStream();
+ IBitStream* GetBitStream();
- HRESULT BreakConnect();
+ HRESULT BreakConnect();
HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
@@ -45,28 +45,24 @@ public:
HRESULT DeliverEndOfStream();
- STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
+ STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
};
class CBaseMuxerRawOutputPin : public CBaseMuxerOutputPin, public CBaseMuxerRelatedPin
{
- struct idx_t
- {
- REFERENCE_TIME rt;
- __int64 fp;
- };
- CAtlList<idx_t> m_idx;
+ struct idx_t {REFERENCE_TIME rt; __int64 fp;};
+ CAtlList<idx_t> m_idx;
- ssf::SubtitleFile m_ssf;
+ ssf::SubtitleFile m_ssf;
public:
- CBaseMuxerRawOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CBaseMuxerRawOutputPin() {}
+ CBaseMuxerRawOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CBaseMuxerRawOutputPin() {}
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- virtual void MuxHeader(const CMediaType& mt);
- virtual void MuxPacket(const CMediaType& mt, const MuxerPacket* pPacket);
- virtual void MuxFooter(const CMediaType& mt);
+ virtual void MuxHeader(const CMediaType& mt);
+ virtual void MuxPacket(const CMediaType& mt, const MuxerPacket* pPacket);
+ virtual void MuxFooter(const CMediaType& mt);
};
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.cpp b/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.cpp
index 2b6548c65..c4ba9b3bd 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.cpp
+++ b/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -38,11 +38,11 @@ CBaseMuxerRelatedPin::~CBaseMuxerRelatedPin()
STDMETHODIMP CBaseMuxerRelatedPin::SetRelatedPin(CBasePin* pPin)
{
- m_pRelatedPin = pPin;
- return S_OK;
+ m_pRelatedPin = pPin;
+ return S_OK;
}
STDMETHODIMP_(CBasePin*) CBaseMuxerRelatedPin::GetRelatedPin()
{
- return m_pRelatedPin;
+ return m_pRelatedPin;
}
diff --git a/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.h b/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.h
index 5c7bd26cb..2b7f7095e 100644
--- a/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.h
+++ b/src/filters/muxer/BaseMuxer/BaseMuxerRelatedPin.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -22,23 +22,22 @@
#pragma once
[uuid("EE6F2741-7DB4-4AAD-A3CB-545208EE4C0A")]
-interface IBaseMuxerRelatedPin :
-public IUnknown
+interface IBaseMuxerRelatedPin : public IUnknown
{
- STDMETHOD(SetRelatedPin)(CBasePin* pPin) = 0;
- STDMETHOD_(CBasePin*, GetRelatedPin)() = 0;
+ STDMETHOD(SetRelatedPin) (CBasePin* pPin) = 0;
+ STDMETHOD_(CBasePin*, GetRelatedPin) () = 0;
};
class CBaseMuxerRelatedPin : public IBaseMuxerRelatedPin
{
- CBasePin* m_pRelatedPin; // should not hold a reference because it would be circular
+ CBasePin* m_pRelatedPin; // should not hold a reference because it would be circular
public:
- CBaseMuxerRelatedPin();
- virtual ~CBaseMuxerRelatedPin();
+ CBaseMuxerRelatedPin();
+ virtual ~CBaseMuxerRelatedPin();
- // IBaseMuxerRelatedPin
+ // IBaseMuxerRelatedPin
- STDMETHODIMP SetRelatedPin(CBasePin* pPin);
- STDMETHODIMP_(CBasePin*) GetRelatedPin();
+ STDMETHODIMP SetRelatedPin(CBasePin* pPin);
+ STDMETHODIMP_(CBasePin*) GetRelatedPin();
}; \ No newline at end of file
diff --git a/src/filters/muxer/BaseMuxer/BitStream.cpp b/src/filters/muxer/BaseMuxer/BitStream.cpp
index 55ac46500..3481740fa 100644
--- a/src/filters/muxer/BaseMuxer/BitStream.cpp
+++ b/src/filters/muxer/BaseMuxer/BitStream.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -27,134 +27,130 @@
//
CBitStream::CBitStream(IStream* pStream, bool fThrowError)
- : CUnknown(_T("CBitStream"), NULL)
- , m_pStream(pStream)
- , m_fThrowError(fThrowError)
- , m_bitlen(0)
+ : CUnknown(_T("CBitStream"), NULL)
+ , m_pStream(pStream)
+ , m_fThrowError(fThrowError)
+ , m_bitlen(0)
{
- ASSERT(m_pStream);
+ ASSERT(m_pStream);
- LARGE_INTEGER li = {0};
- m_pStream->Seek(li, STREAM_SEEK_SET, NULL);
+ LARGE_INTEGER li = {0};
+ m_pStream->Seek(li, STREAM_SEEK_SET, NULL);
- ULARGE_INTEGER uli = {0};
- m_pStream->SetSize(uli); // not that it worked...
+ ULARGE_INTEGER uli = {0};
+ m_pStream->SetSize(uli); // not that it worked...
- m_pStream->Commit(S_OK); // also seems to have no effect, but maybe in the future...
+ m_pStream->Commit(S_OK); // also seems to have no effect, but maybe in the future...
}
CBitStream::~CBitStream()
{
- BitFlush();
+ BitFlush();
}
STDMETHODIMP CBitStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- *ppv = NULL;
+ *ppv = NULL;
- return
- QI(IBitStream)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ QI(IBitStream)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
// IBitStream
STDMETHODIMP_(UINT64) CBitStream::GetPos()
{
- ULARGE_INTEGER pos = {0, 0};
- m_pStream->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_CUR, &pos);
- return pos.QuadPart;
+ ULARGE_INTEGER pos = {0, 0};
+ m_pStream->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_CUR, &pos);
+ return pos.QuadPart;
}
STDMETHODIMP_(UINT64) CBitStream::Seek(UINT64 pos)
{
- BitFlush();
-
- LARGE_INTEGER li;
- li.QuadPart = pos;
- ULARGE_INTEGER linew;
- linew.QuadPart = -1;
- m_pStream->Seek(li, STREAM_SEEK_SET, &linew);
- ASSERT(li.QuadPart == linew.QuadPart);
- return linew.QuadPart;
+ BitFlush();
+
+ LARGE_INTEGER li;
+ li.QuadPart = pos;
+ ULARGE_INTEGER linew;
+ linew.QuadPart = -1;
+ m_pStream->Seek(li, STREAM_SEEK_SET, &linew);
+ ASSERT(li.QuadPart == linew.QuadPart);
+ return linew.QuadPart;
}
STDMETHODIMP CBitStream::ByteWrite(const void* pData, int len)
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- BitFlush();
+ BitFlush();
- if(len > 0)
- {
- ULONG cbWritten = 0;
- hr = m_pStream->Write(pData, len, &cbWritten);
+ if(len > 0)
+ {
+ ULONG cbWritten = 0;
+ hr = m_pStream->Write(pData, len, &cbWritten);
- ASSERT(SUCCEEDED(hr));
- if(m_fThrowError && FAILED(hr)) throw hr;
- }
+ ASSERT(SUCCEEDED(hr));
+ if(m_fThrowError && FAILED(hr)) throw hr;
+ }
- return hr;
+ return hr;
}
STDMETHODIMP CBitStream::BitWrite(UINT64 data, int len)
{
- HRESULT hr = S_OK;
-
- ASSERT(len >= 0 && len <= 64);
+ HRESULT hr = S_OK;
- if(len > 56)
- {
- BitWrite(data >> 56, len - 56);
- len = 56;
- }
+ ASSERT(len >= 0 && len <= 64);
- m_bitbuff <<= len;
- m_bitbuff |= data & ((1ui64 << len) - 1);
- m_bitlen += len;
+ if(len > 56) {BitWrite(data >> 56, len - 56); len = 56;}
- while(m_bitlen >= 8)
- {
- BYTE b = (BYTE)(m_bitbuff >> (m_bitlen - 8));
- hr = m_pStream->Write(&b, 1, NULL);
- m_bitlen -= 8;
+ m_bitbuff <<= len;
+ m_bitbuff |= data & ((1ui64 << len) - 1);
+ m_bitlen += len;
+
+ while(m_bitlen >= 8)
+ {
+ BYTE b = (BYTE)(m_bitbuff >> (m_bitlen - 8));
+ hr = m_pStream->Write(&b, 1, NULL);
+ m_bitlen -= 8;
- ASSERT(SUCCEEDED(hr));
- if(m_fThrowError && FAILED(hr)) throw E_FAIL;
- }
+ ASSERT(SUCCEEDED(hr));
+ if(m_fThrowError && FAILED(hr)) throw E_FAIL;
+ }
- return hr;
+ return hr;
}
STDMETHODIMP CBitStream::BitFlush()
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- if(m_bitlen > 0)
- {
- ASSERT(m_bitlen < 8);
- BYTE b = (BYTE)(m_bitbuff << (8 - m_bitlen));
- hr = m_pStream->Write(&b, 1, NULL);
- m_bitlen = 0;
+ if(m_bitlen > 0)
+ {
+ ASSERT(m_bitlen < 8);
+ BYTE b = (BYTE)(m_bitbuff << (8 - m_bitlen));
+ hr = m_pStream->Write(&b, 1, NULL);
+ m_bitlen = 0;
- ASSERT(SUCCEEDED(hr));
- if(m_fThrowError && FAILED(hr)) throw E_FAIL;
- }
+ ASSERT(SUCCEEDED(hr));
+ if(m_fThrowError && FAILED(hr)) throw E_FAIL;
+ }
- return hr;
+ return hr;
}
STDMETHODIMP CBitStream::StrWrite(LPCSTR pData, BOOL bFixNewLine)
{
- CStringA str = pData;
+ CStringA str = pData;
- if(bFixNewLine)
- {
- str.Replace("\r", "");
- str.Replace("\n", "\r\n");
- }
+ if(bFixNewLine)
+ {
+ str.Replace("\r", "");
+ str.Replace("\n", "\r\n");
+ }
- return ByteWrite((LPCSTR)str, str.GetLength());
+ return ByteWrite((LPCSTR)str, str.GetLength());
}
diff --git a/src/filters/muxer/BaseMuxer/BitStream.h b/src/filters/muxer/BaseMuxer/BitStream.h
index 259c1f201..26621660e 100644
--- a/src/filters/muxer/BaseMuxer/BitStream.h
+++ b/src/filters/muxer/BaseMuxer/BitStream.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -22,37 +22,36 @@
#pragma once
[uuid("30AB78C7-5259-4594-AEFE-9C0FC2F08A5E")]
-interface IBitStream :
-public IUnknown
+interface IBitStream : public IUnknown
{
- STDMETHOD_(UINT64, GetPos)() = 0;
- STDMETHOD_(UINT64, Seek)(UINT64 pos) = 0; // it's a _stream_, please don't seek if you don't have to
- STDMETHOD(ByteWrite)(const void* pData, int len) = 0;
- STDMETHOD(BitWrite)(UINT64 data, int len) = 0;
- STDMETHOD(BitFlush)() = 0;
- STDMETHOD(StrWrite)(LPCSTR pData, BOOL bFixNewLine) = 0;
+ STDMETHOD_(UINT64, GetPos) () = 0;
+ STDMETHOD_(UINT64, Seek) (UINT64 pos) = 0; // it's a _stream_, please don't seek if you don't have to
+ STDMETHOD(ByteWrite) (const void* pData, int len) = 0;
+ STDMETHOD(BitWrite) (UINT64 data, int len) = 0;
+ STDMETHOD(BitFlush) () = 0;
+ STDMETHOD(StrWrite) (LPCSTR pData, BOOL bFixNewLine) = 0;
};
class CBitStream : public CUnknown, public IBitStream
{
- CComPtr<IStream> m_pStream;
- bool m_fThrowError;
- UINT64 m_bitbuff;
- int m_bitlen;
+ CComPtr<IStream> m_pStream;
+ bool m_fThrowError;
+ UINT64 m_bitbuff;
+ int m_bitlen;
public:
- CBitStream(IStream* pStream, bool m_fThrowError = false);
- virtual ~CBitStream();
+ CBitStream(IStream* pStream, bool m_fThrowError = false);
+ virtual ~CBitStream();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- // IBitStream
+ // IBitStream
- STDMETHODIMP_(UINT64) GetPos();
- STDMETHODIMP_(UINT64) Seek(UINT64 pos);
- STDMETHODIMP ByteWrite(const void* pData, int len);
- STDMETHODIMP BitWrite(UINT64 data, int len);
- STDMETHODIMP BitFlush();
- STDMETHODIMP StrWrite(LPCSTR pData, BOOL bFixNewLine);
+ STDMETHODIMP_(UINT64) GetPos();
+ STDMETHODIMP_(UINT64) Seek(UINT64 pos);
+ STDMETHODIMP ByteWrite(const void* pData, int len);
+ STDMETHODIMP BitWrite(UINT64 data, int len);
+ STDMETHODIMP BitFlush();
+ STDMETHODIMP StrWrite(LPCSTR pData, BOOL bFixNewLine);
};
diff --git a/src/filters/muxer/BaseMuxer/stdafx.cpp b/src/filters/muxer/BaseMuxer/stdafx.cpp
index fbb1d74c1..6f5d2a928 100644
--- a/src/filters/muxer/BaseMuxer/stdafx.cpp
+++ b/src/filters/muxer/BaseMuxer/stdafx.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/BaseMuxer/stdafx.h b/src/filters/muxer/BaseMuxer/stdafx.h
index 6c97773a5..a2674a8f9 100644
--- a/src/filters/muxer/BaseMuxer/stdafx.h
+++ b/src/filters/muxer/BaseMuxer/stdafx.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/DSMMuxer/DSMMuxer.cpp b/src/filters/muxer/DSMMuxer/DSMMuxer.cpp
index 79a60f381..ca349a306 100644
--- a/src/filters/muxer/DSMMuxer/DSMMuxer.cpp
+++ b/src/filters/muxer/DSMMuxer/DSMMuxer.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -32,7 +32,7 @@
const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
{
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_DirectShowMedia}
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_DirectShowMedia}
};
const AMOVIESETUP_PIN sudpPins[] =
@@ -43,24 +43,24 @@ const AMOVIESETUP_PIN sudpPins[] =
const AMOVIESETUP_FILTER sudFilter[] =
{
- {&__uuidof(CDSMMuxerFilter), L"MPC - DSM Muxer", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory}
+ {&__uuidof(CDSMMuxerFilter), L"MPC - DSM Muxer", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory}
};
CFactoryTemplate g_Templates[] =
{
- {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDSMMuxerFilter>, NULL, &sudFilter[0]}
+ {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDSMMuxerFilter>, NULL, &sudFilter[0]}
};
int g_cTemplates = countof(g_Templates);
STDAPI DllRegisterServer()
{
- return AMovieDllRegisterServer2(TRUE);
+ return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
- return AMovieDllRegisterServer2(FALSE);
+ return AMovieDllRegisterServer2(FALSE);
}
#include "../../FilterApp.h"
@@ -69,16 +69,13 @@ CFilterApp theApp;
#endif
-template<typename T> static T myabs(T n)
-{
- return n >= 0 ? n : -n;
-}
+template<typename T> static T myabs(T n) {return n >= 0 ? n : -n;}
static int GetByteLength(UINT64 data, int min = 0)
{
- int i = 7;
- while(i >= min && ((BYTE*)&data)[i] == 0) i--;
- return ++i;
+ int i = 7;
+ while(i >= min && ((BYTE*)&data)[i] == 0) i--;
+ return ++i;
}
//
@@ -86,11 +83,11 @@ static int GetByteLength(UINT64 data, int min = 0)
//
CDSMMuxerFilter::CDSMMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr, bool fAutoChap, bool fAutoRes)
- : CBaseMuxerFilter(pUnk, phr, __uuidof(this))
- , m_fAutoChap(fAutoChap)
- , m_fAutoRes(fAutoRes)
+ : CBaseMuxerFilter(pUnk, phr, __uuidof(this))
+ , m_fAutoChap(fAutoChap)
+ , m_fAutoRes(fAutoRes)
{
- if(phr) *phr = S_OK;
+ if(phr) *phr = S_OK;
}
CDSMMuxerFilter::~CDSMMuxerFilter()
@@ -99,360 +96,356 @@ CDSMMuxerFilter::~CDSMMuxerFilter()
STDMETHODIMP CDSMMuxerFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- *ppv = NULL;
+ *ppv = NULL;
- return
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
void CDSMMuxerFilter::MuxPacketHeader(IBitStream* pBS, dsmp_t type, UINT64 len)
{
- ASSERT(type < 32);
+ ASSERT(type < 32);
- int i = GetByteLength(len, 1);
+ int i = GetByteLength(len, 1);
- pBS->BitWrite(DSMSW, DSMSW_SIZE << 3);
- pBS->BitWrite(type, 5);
- pBS->BitWrite(i - 1, 3);
- pBS->BitWrite(len, i << 3);
+ pBS->BitWrite(DSMSW, DSMSW_SIZE<<3);
+ pBS->BitWrite(type, 5);
+ pBS->BitWrite(i-1, 3);
+ pBS->BitWrite(len, i<<3);
}
void CDSMMuxerFilter::MuxFileInfo(IBitStream* pBS)
{
- int len = 1;
- CSimpleMap<CStringA, CStringA> si;
-
- for(int i = 0; i < GetSize(); i++)
- {
- CStringA key = CStringA(CString(GetKeyAt(i))), value = UTF16To8(GetValueAt(i));
- if(key.GetLength() != 4) continue;
- si.Add(key, value);
- len += 4 + value.GetLength() + 1;
- }
-
- MuxPacketHeader(pBS, DSMP_FILEINFO, len);
- pBS->BitWrite(DSMF_VERSION, 8);
- for(int i = 0; i < si.GetSize(); i++)
- {
- CStringA key = si.GetKeyAt(i), value = si.GetValueAt(i);
- pBS->ByteWrite((LPCSTR)key, 4);
- pBS->ByteWrite((LPCSTR)value, value.GetLength() + 1);
- }
+ int len = 1;
+ CSimpleMap<CStringA, CStringA> si;
+
+ for(int i = 0; i < GetSize(); i++)
+ {
+ CStringA key = CStringA(CString(GetKeyAt(i))), value = UTF16To8(GetValueAt(i));
+ if(key.GetLength() != 4) continue;
+ si.Add(key, value);
+ len += 4 + value.GetLength() + 1;
+ }
+
+ MuxPacketHeader(pBS, DSMP_FILEINFO, len);
+ pBS->BitWrite(DSMF_VERSION, 8);
+ for(int i = 0; i < si.GetSize(); i++)
+ {
+ CStringA key = si.GetKeyAt(i), value = si.GetValueAt(i);
+ pBS->ByteWrite((LPCSTR)key, 4);
+ pBS->ByteWrite((LPCSTR)value, value.GetLength()+1);
+ }
}
void CDSMMuxerFilter::MuxStreamInfo(IBitStream* pBS, CBaseMuxerInputPin* pPin)
{
- int len = 1;
- CSimpleMap<CStringA, CStringA> si;
-
- for(int i = 0; i < pPin->GetSize(); i++)
- {
- CStringA key = CStringA(CString(pPin->GetKeyAt(i))), value = UTF16To8(pPin->GetValueAt(i));
- if(key.GetLength() != 4) continue;
- si.Add(key, value);
- len += 4 + value.GetLength() + 1;
- }
-
- if(len > 1)
- {
- MuxPacketHeader(pBS, DSMP_STREAMINFO, len);
- pBS->BitWrite(pPin->GetID(), 8);
- for(int i = 0; i < si.GetSize(); i++)
- {
- CStringA key = si.GetKeyAt(i), value = si.GetValueAt(i);
- pBS->ByteWrite((LPCSTR)key, 4);
- pBS->ByteWrite((LPCSTR)value, value.GetLength() + 1);
- }
- }
+ int len = 1;
+ CSimpleMap<CStringA, CStringA> si;
+
+ for(int i = 0; i < pPin->GetSize(); i++)
+ {
+ CStringA key = CStringA(CString(pPin->GetKeyAt(i))), value = UTF16To8(pPin->GetValueAt(i));
+ if(key.GetLength() != 4) continue;
+ si.Add(key, value);
+ len += 4 + value.GetLength() + 1;
+ }
+
+ if(len > 1)
+ {
+ MuxPacketHeader(pBS, DSMP_STREAMINFO, len);
+ pBS->BitWrite(pPin->GetID(), 8);
+ for(int i = 0; i < si.GetSize(); i++)
+ {
+ CStringA key = si.GetKeyAt(i), value = si.GetValueAt(i);
+ pBS->ByteWrite((LPCSTR)key, 4);
+ pBS->ByteWrite((LPCSTR)value, value.GetLength()+1);
+ }
+ }
}
void CDSMMuxerFilter::MuxInit()
{
- m_sps.RemoveAll();
- m_isps.RemoveAll();
- m_rtPrevSyncPoint = _I64_MIN;
+ m_sps.RemoveAll();
+ m_isps.RemoveAll();
+ m_rtPrevSyncPoint = _I64_MIN;
}
void CDSMMuxerFilter::MuxHeader(IBitStream* pBS)
{
- CString muxer;
- muxer.Format(_T("DSM Muxer (%s)"), CString(__TIMESTAMP__));
-
- SetProperty(L"MUXR", CStringW(muxer));
- SetProperty(L"DATE", CStringW(CTime::GetCurrentTime().FormatGmt(_T("%Y-%m-%d %H:%M:%S"))));
-
- MuxFileInfo(pBS);
-
- POSITION pos = m_pPins.GetHeadPosition();
- while(pos)
- {
- CBaseMuxerInputPin* pPin = m_pPins.GetNext(pos);
- const CMediaType& mt = pPin->CurrentMediaType();
-
- ASSERT((mt.lSampleSize >> 30) == 0); // you don't need >1GB samples, do you?
-
- MuxPacketHeader(pBS, DSMP_MEDIATYPE, 5 + sizeof(GUID) * 3 + mt.FormatLength());
- pBS->BitWrite(pPin->GetID(), 8);
- pBS->ByteWrite(&mt.majortype, sizeof(mt.majortype));
- pBS->ByteWrite(&mt.subtype, sizeof(mt.subtype));
- pBS->BitWrite(mt.bFixedSizeSamples, 1);
- pBS->BitWrite(mt.bTemporalCompression, 1);
- pBS->BitWrite(mt.lSampleSize, 30);
- pBS->ByteWrite(&mt.formattype, sizeof(mt.formattype));
- pBS->ByteWrite(mt.Format(), mt.FormatLength());
-
- MuxStreamInfo(pBS, pPin);
- }
-
- // resources & chapters
-
- CInterfaceList<IDSMResourceBag> pRBs;
- pRBs.AddTail(this);
-
- CComQIPtr<IDSMChapterBag> pCB = (IUnknown*)(INonDelegatingUnknown*)this;
-
- pos = m_pPins.GetHeadPosition();
- while(pos)
- {
- for(CComPtr<IPin> pPin = m_pPins.GetNext(pos)->GetConnected(); pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin)))
- {
- if(m_fAutoRes)
- {
- CComQIPtr<IDSMResourceBag> pPB = GetFilterFromPin(pPin);
- if(pPB && !pRBs.Find(pPB)) pRBs.AddTail(pPB);
- }
-
- if(m_fAutoChap)
- {
- if(!pCB || pCB->ChapGetCount() == 0) pCB = GetFilterFromPin(pPin);
- }
- }
- }
-
- // resources
-
- pos = pRBs.GetHeadPosition();
- while(pos)
- {
- IDSMResourceBag* pRB = pRBs.GetNext(pos);
-
- for(DWORD i = 0, j = pRB->ResGetCount(); i < j; i++)
- {
- CComBSTR name, desc, mime;
- BYTE* pData = NULL;
- DWORD len = 0;
- if(SUCCEEDED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL)))
- {
- CStringA utf8_name = UTF16To8(name);
- CStringA utf8_desc = UTF16To8(desc);
- CStringA utf8_mime = UTF16To8(mime);
-
- MuxPacketHeader(pBS, DSMP_RESOURCE,
- 1 +
- utf8_name.GetLength() + 1 +
- utf8_desc.GetLength() + 1 +
- utf8_mime.GetLength() + 1 +
- len);
-
- pBS->BitWrite(0, 2);
- pBS->BitWrite(0, 6); // reserved
- pBS->ByteWrite(utf8_name, utf8_name.GetLength() + 1);
- pBS->ByteWrite(utf8_desc, utf8_desc.GetLength() + 1);
- pBS->ByteWrite(utf8_mime, utf8_mime.GetLength() + 1);
- pBS->ByteWrite(pData, len);
-
- CoTaskMemFree(pData);
- }
- }
- }
-
- // chapters
-
- if(pCB)
- {
- CAtlList<CDSMChapter> chapters;
- REFERENCE_TIME rtPrev = 0;
- int len = 0;
-
- pCB->ChapSort();
-
- for(DWORD i = 0; i < pCB->ChapGetCount(); i++)
- {
- CDSMChapter c;
- CComBSTR name;
- if(SUCCEEDED(pCB->ChapGet(i, &c.rt, &name)))
- {
- REFERENCE_TIME rtDiff = c.rt - rtPrev;
- rtPrev = c.rt;
- c.rt = rtDiff;
- c.name = name;
- len += 1 + GetByteLength(myabs(c.rt)) + UTF16To8(c.name).GetLength() + 1;
- chapters.AddTail(c);
- }
- }
-
- if(chapters.GetCount())
- {
- MuxPacketHeader(pBS, DSMP_CHAPTERS, len);
-
- pos = chapters.GetHeadPosition();
- while(pos)
- {
- CDSMChapter& c = chapters.GetNext(pos);
- CStringA name = UTF16To8(c.name);
- int irt = GetByteLength(myabs(c.rt));
- pBS->BitWrite(c.rt < 0, 1);
- pBS->BitWrite(irt, 3);
- pBS->BitWrite(0, 4);
- pBS->BitWrite(myabs(c.rt), irt << 3);
- pBS->ByteWrite((LPCSTR)name, name.GetLength() + 1);
- }
- }
- }
+ CString muxer;
+ muxer.Format(_T("DSM Muxer (%s)"), CString(__TIMESTAMP__));
+
+ SetProperty(L"MUXR", CStringW(muxer));
+ SetProperty(L"DATE", CStringW(CTime::GetCurrentTime().FormatGmt(_T("%Y-%m-%d %H:%M:%S"))));
+
+ MuxFileInfo(pBS);
+
+ POSITION pos = m_pPins.GetHeadPosition();
+ while(pos)
+ {
+ CBaseMuxerInputPin* pPin = m_pPins.GetNext(pos);
+ const CMediaType& mt = pPin->CurrentMediaType();
+
+ ASSERT((mt.lSampleSize >> 30) == 0); // you don't need >1GB samples, do you?
+
+ MuxPacketHeader(pBS, DSMP_MEDIATYPE, 5 + sizeof(GUID)*3 + mt.FormatLength());
+ pBS->BitWrite(pPin->GetID(), 8);
+ pBS->ByteWrite(&mt.majortype, sizeof(mt.majortype));
+ pBS->ByteWrite(&mt.subtype, sizeof(mt.subtype));
+ pBS->BitWrite(mt.bFixedSizeSamples, 1);
+ pBS->BitWrite(mt.bTemporalCompression, 1);
+ pBS->BitWrite(mt.lSampleSize, 30);
+ pBS->ByteWrite(&mt.formattype, sizeof(mt.formattype));
+ pBS->ByteWrite(mt.Format(), mt.FormatLength());
+
+ MuxStreamInfo(pBS, pPin);
+ }
+
+ // resources & chapters
+
+ CInterfaceList<IDSMResourceBag> pRBs;
+ pRBs.AddTail(this);
+
+ CComQIPtr<IDSMChapterBag> pCB = (IUnknown*)(INonDelegatingUnknown*)this;
+
+ pos = m_pPins.GetHeadPosition();
+ while(pos)
+ {
+ for(CComPtr<IPin> pPin = m_pPins.GetNext(pos)->GetConnected(); pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin)))
+ {
+ if(m_fAutoRes)
+ {
+ CComQIPtr<IDSMResourceBag> pPB = GetFilterFromPin(pPin);
+ if(pPB && !pRBs.Find(pPB)) pRBs.AddTail(pPB);
+ }
+
+ if(m_fAutoChap)
+ {
+ if(!pCB || pCB->ChapGetCount() == 0) pCB = GetFilterFromPin(pPin);
+ }
+ }
+ }
+
+ // resources
+
+ pos = pRBs.GetHeadPosition();
+ while(pos)
+ {
+ IDSMResourceBag* pRB = pRBs.GetNext(pos);
+
+ for(DWORD i = 0, j = pRB->ResGetCount(); i < j; i++)
+ {
+ CComBSTR name, desc, mime;
+ BYTE* pData = NULL;
+ DWORD len = 0;
+ if(SUCCEEDED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL)))
+ {
+ CStringA utf8_name = UTF16To8(name);
+ CStringA utf8_desc = UTF16To8(desc);
+ CStringA utf8_mime = UTF16To8(mime);
+
+ MuxPacketHeader(pBS, DSMP_RESOURCE,
+ 1 +
+ utf8_name.GetLength()+1 +
+ utf8_desc.GetLength()+1 +
+ utf8_mime.GetLength()+1 +
+ len);
+
+ pBS->BitWrite(0, 2);
+ pBS->BitWrite(0, 6); // reserved
+ pBS->ByteWrite(utf8_name, utf8_name.GetLength()+1);
+ pBS->ByteWrite(utf8_desc, utf8_desc.GetLength()+1);
+ pBS->ByteWrite(utf8_mime, utf8_mime.GetLength()+1);
+ pBS->ByteWrite(pData, len);
+
+ CoTaskMemFree(pData);
+ }
+ }
+ }
+
+ // chapters
+
+ if(pCB)
+ {
+ CAtlList<CDSMChapter> chapters;
+ REFERENCE_TIME rtPrev = 0;
+ int len = 0;
+
+ pCB->ChapSort();
+
+ for(DWORD i = 0; i < pCB->ChapGetCount(); i++)
+ {
+ CDSMChapter c;
+ CComBSTR name;
+ if(SUCCEEDED(pCB->ChapGet(i, &c.rt, &name)))
+ {
+ REFERENCE_TIME rtDiff = c.rt - rtPrev; rtPrev = c.rt; c.rt = rtDiff;
+ c.name = name;
+ len += 1 + GetByteLength(myabs(c.rt)) + UTF16To8(c.name).GetLength()+1;
+ chapters.AddTail(c);
+ }
+ }
+
+ if(chapters.GetCount())
+ {
+ MuxPacketHeader(pBS, DSMP_CHAPTERS, len);
+
+ pos = chapters.GetHeadPosition();
+ while(pos)
+ {
+ CDSMChapter& c = chapters.GetNext(pos);
+ CStringA name = UTF16To8(c.name);
+ int irt = GetByteLength(myabs(c.rt));
+ pBS->BitWrite(c.rt < 0, 1);
+ pBS->BitWrite(irt, 3);
+ pBS->BitWrite(0, 4);
+ pBS->BitWrite(myabs(c.rt), irt<<3);
+ pBS->ByteWrite((LPCSTR)name, name.GetLength()+1);
+ }
+ }
+ }
}
void CDSMMuxerFilter::MuxPacket(IBitStream* pBS, const MuxerPacket* pPacket)
{
- if(pPacket->IsEOS())
- return;
-
- if(pPacket->pPin->CurrentMediaType().majortype == MEDIATYPE_Text)
- {
- CStringA str((char*)pPacket->pData.GetData(), pPacket->pData.GetCount());
- str.Replace("\xff", " ");
- str.Replace("&nbsp;", " ");
- str.Replace("&nbsp", " ");
- str.Trim();
- if(str.IsEmpty())
- return;
- }
-
- ASSERT(!pPacket->IsSyncPoint() || pPacket->IsTimeValid());
-
- REFERENCE_TIME rtTimeStamp = _I64_MIN, rtDuration = 0;
- int iTimeStamp = 0, iDuration = 0;
-
- if(pPacket->IsTimeValid())
- {
- rtTimeStamp = pPacket->rtStart;
- rtDuration = max(pPacket->rtStop - pPacket->rtStart, 0);
-
- iTimeStamp = GetByteLength(myabs(rtTimeStamp));
- ASSERT(iTimeStamp <= 7);
-
- iDuration = GetByteLength(rtDuration);
- ASSERT(iDuration <= 7);
-
- IndexSyncPoint(pPacket, pBS->GetPos());
- }
-
- int len = 2 + iTimeStamp + iDuration + pPacket->pData.GetCount(); // id + flags + data
-
- MuxPacketHeader(pBS, DSMP_SAMPLE, len);
- pBS->BitWrite(pPacket->pPin->GetID(), 8);
- pBS->BitWrite(pPacket->IsSyncPoint(), 1);
- pBS->BitWrite(rtTimeStamp < 0, 1);
- pBS->BitWrite(iTimeStamp, 3);
- pBS->BitWrite(iDuration, 3);
- pBS->BitWrite(myabs(rtTimeStamp), iTimeStamp << 3);
- pBS->BitWrite(rtDuration, iDuration << 3);
- pBS->ByteWrite(pPacket->pData.GetData(), pPacket->pData.GetCount());
+ if(pPacket->IsEOS())
+ return;
+
+ if(pPacket->pPin->CurrentMediaType().majortype == MEDIATYPE_Text)
+ {
+ CStringA str((char*)pPacket->pData.GetData(), pPacket->pData.GetCount());
+ str.Replace("\xff", " ");
+ str.Replace("&nbsp;", " ");
+ str.Replace("&nbsp", " ");
+ str.Trim();
+ if(str.IsEmpty())
+ return;
+ }
+
+ ASSERT(!pPacket->IsSyncPoint() || pPacket->IsTimeValid());
+
+ REFERENCE_TIME rtTimeStamp = _I64_MIN, rtDuration = 0;
+ int iTimeStamp = 0, iDuration = 0;
+
+ if(pPacket->IsTimeValid())
+ {
+ rtTimeStamp = pPacket->rtStart;
+ rtDuration = max(pPacket->rtStop - pPacket->rtStart, 0);
+
+ iTimeStamp = GetByteLength(myabs(rtTimeStamp));
+ ASSERT(iTimeStamp <= 7);
+
+ iDuration = GetByteLength(rtDuration);
+ ASSERT(iDuration <= 7);
+
+ IndexSyncPoint(pPacket, pBS->GetPos());
+ }
+
+ int len = 2 + iTimeStamp + iDuration + pPacket->pData.GetCount(); // id + flags + data
+
+ MuxPacketHeader(pBS, DSMP_SAMPLE, len);
+ pBS->BitWrite(pPacket->pPin->GetID(), 8);
+ pBS->BitWrite(pPacket->IsSyncPoint(), 1);
+ pBS->BitWrite(rtTimeStamp < 0, 1);
+ pBS->BitWrite(iTimeStamp, 3);
+ pBS->BitWrite(iDuration, 3);
+ pBS->BitWrite(myabs(rtTimeStamp), iTimeStamp<<3);
+ pBS->BitWrite(rtDuration, iDuration<<3);
+ pBS->ByteWrite(pPacket->pData.GetData(), pPacket->pData.GetCount());
}
void CDSMMuxerFilter::MuxFooter(IBitStream* pBS)
{
- // syncpoints
-
- int len = 0;
- CAtlList<IndexedSyncPoint> isps;
- REFERENCE_TIME rtPrev = 0, rt;
- UINT64 fpPrev = 0, fp;
-
- POSITION pos = m_isps.GetHeadPosition();
- while(pos)
- {
- IndexedSyncPoint& isp = m_isps.GetNext(pos);
- TRACE(_T("sp[%d]: %I64d %I64x\n"), isp.id, isp.rt, isp.fp);
-
- rt = isp.rt - rtPrev;
- rtPrev = isp.rt;
- fp = isp.fp - fpPrev;
- fpPrev = isp.fp;
-
- IndexedSyncPoint isp2;
- isp2.fp = fp;
- isp2.rt = rt;
- isps.AddTail(isp2);
-
- len += 1 + GetByteLength(myabs(rt)) + GetByteLength(fp); // flags + rt + fp
- }
-
- MuxPacketHeader(pBS, DSMP_SYNCPOINTS, len);
-
- pos = isps.GetHeadPosition();
- while(pos)
- {
- IndexedSyncPoint& isp = isps.GetNext(pos);
-
- int irt = GetByteLength(myabs(isp.rt));
- int ifp = GetByteLength(isp.fp);
-
- pBS->BitWrite(isp.rt < 0, 1);
- pBS->BitWrite(irt, 3);
- pBS->BitWrite(ifp, 3);
- pBS->BitWrite(0, 1); // reserved
- pBS->BitWrite(myabs(isp.rt), irt << 3);
- pBS->BitWrite(isp.fp, ifp << 3);
- }
+ // syncpoints
+
+ int len = 0;
+ CAtlList<IndexedSyncPoint> isps;
+ REFERENCE_TIME rtPrev = 0, rt;
+ UINT64 fpPrev = 0, fp;
+
+ POSITION pos = m_isps.GetHeadPosition();
+ while(pos)
+ {
+ IndexedSyncPoint& isp = m_isps.GetNext(pos);
+ TRACE(_T("sp[%d]: %I64d %I64x\n"), isp.id, isp.rt, isp.fp);
+
+ rt = isp.rt - rtPrev; rtPrev = isp.rt;
+ fp = isp.fp - fpPrev; fpPrev = isp.fp;
+
+ IndexedSyncPoint isp2;
+ isp2.fp = fp;
+ isp2.rt = rt;
+ isps.AddTail(isp2);
+
+ len += 1 + GetByteLength(myabs(rt)) + GetByteLength(fp); // flags + rt + fp
+ }
+
+ MuxPacketHeader(pBS, DSMP_SYNCPOINTS, len);
+
+ pos = isps.GetHeadPosition();
+ while(pos)
+ {
+ IndexedSyncPoint& isp = isps.GetNext(pos);
+
+ int irt = GetByteLength(myabs(isp.rt));
+ int ifp = GetByteLength(isp.fp);
+
+ pBS->BitWrite(isp.rt < 0, 1);
+ pBS->BitWrite(irt, 3);
+ pBS->BitWrite(ifp, 3);
+ pBS->BitWrite(0, 1); // reserved
+ pBS->BitWrite(myabs(isp.rt), irt<<3);
+ pBS->BitWrite(isp.fp, ifp<<3);
+ }
}
void CDSMMuxerFilter::IndexSyncPoint(const MuxerPacket* p, __int64 fp)
{
- // Yes, this is as complicated as it looks.
- // Rule #1: don't write this packet if you can't do it reliably.
- // (think about overlapped subtitles, line1: 0->10, line2: 1->9)
-
- // FIXME: the very last syncpoints won't get moved to m_isps because there are no more syncpoints to trigger it!
-
- if(fp < 0 || !p || !p->IsTimeValid() || !p->IsSyncPoint())
- return;
-
- ASSERT(p->rtStart >= m_rtPrevSyncPoint);
- m_rtPrevSyncPoint = p->rtStart;
-
- SyncPoint sp;
- sp.id = p->pPin->GetID();
- sp.rtStart = p->rtStart;
- sp.rtStop = p->pPin->IsSubtitleStream() ? p->rtStop : _I64_MAX;
- sp.fp = fp;
-
- {
- SyncPoint& head = !m_sps.IsEmpty() ? m_sps.GetHead() : sp;
- SyncPoint& tail = !m_sps.IsEmpty() ? m_sps.GetTail() : sp;
- REFERENCE_TIME rtfp = !m_isps.IsEmpty() ? m_isps.GetTail().rtfp : _I64_MIN;
-
- if(head.rtStart > rtfp + 1000000) // 100ms limit, just in case every stream had only keyframes, then sycnpoints would be too frequent
- {
- IndexedSyncPoint isp;
- isp.id = head.id;
- isp.rt = tail.rtStart;
- isp.rtfp = head.rtStart;
- isp.fp = head.fp;
- m_isps.AddTail(isp);
- }
- }
-
- POSITION pos = m_sps.GetHeadPosition();
- while(pos)
- {
- POSITION cur = pos;
- SyncPoint& sp2 = m_sps.GetNext(pos);
- if(sp2.id == sp.id && sp2.rtStop <= sp.rtStop || sp2.rtStop <= sp.rtStart)
- m_sps.RemoveAt(cur);
- }
-
- m_sps.AddTail(sp);
+ // Yes, this is as complicated as it looks.
+ // Rule #1: don't write this packet if you can't do it reliably.
+ // (think about overlapped subtitles, line1: 0->10, line2: 1->9)
+
+ // FIXME: the very last syncpoints won't get moved to m_isps because there are no more syncpoints to trigger it!
+
+ if(fp < 0 || !p || !p->IsTimeValid() || !p->IsSyncPoint())
+ return;
+
+ ASSERT(p->rtStart >= m_rtPrevSyncPoint);
+ m_rtPrevSyncPoint = p->rtStart;
+
+ SyncPoint sp;
+ sp.id = p->pPin->GetID();
+ sp.rtStart = p->rtStart;
+ sp.rtStop = p->pPin->IsSubtitleStream() ? p->rtStop : _I64_MAX;
+ sp.fp = fp;
+
+ {
+ SyncPoint& head = !m_sps.IsEmpty() ? m_sps.GetHead() : sp;
+ SyncPoint& tail = !m_sps.IsEmpty() ? m_sps.GetTail() : sp;
+ REFERENCE_TIME rtfp = !m_isps.IsEmpty() ? m_isps.GetTail().rtfp : _I64_MIN;
+
+ if(head.rtStart > rtfp + 1000000) // 100ms limit, just in case every stream had only keyframes, then sycnpoints would be too frequent
+ {
+ IndexedSyncPoint isp;
+ isp.id = head.id;
+ isp.rt = tail.rtStart;
+ isp.rtfp = head.rtStart;
+ isp.fp = head.fp;
+ m_isps.AddTail(isp);
+ }
+ }
+
+ POSITION pos = m_sps.GetHeadPosition();
+ while(pos)
+ {
+ POSITION cur = pos;
+ SyncPoint& sp2 = m_sps.GetNext(pos);
+ if(sp2.id == sp.id && sp2.rtStop <= sp.rtStop || sp2.rtStop <= sp.rtStart)
+ m_sps.RemoveAt(cur);
+ }
+
+ m_sps.AddTail(sp);
} \ No newline at end of file
diff --git a/src/filters/muxer/DSMMuxer/DSMMuxer.h b/src/filters/muxer/DSMMuxer/DSMMuxer.h
index 2c5caa023..1d3269127 100644
--- a/src/filters/muxer/DSMMuxer/DSMMuxer.h
+++ b/src/filters/muxer/DSMMuxer/DSMMuxer.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -27,40 +27,30 @@
[uuid("C6590B76-587E-4082-9125-680D0693A97B")]
class CDSMMuxerFilter : public CBaseMuxerFilter
{
- bool m_fAutoChap, m_fAutoRes;
+ bool m_fAutoChap, m_fAutoRes;
- struct SyncPoint
- {
- BYTE id;
- REFERENCE_TIME rtStart, rtStop;
- __int64 fp;
- };
- struct IndexedSyncPoint
- {
- BYTE id;
- REFERENCE_TIME rt, rtfp;
- __int64 fp;
- };
- CAtlList<SyncPoint> m_sps;
- CAtlList<IndexedSyncPoint> m_isps;
- REFERENCE_TIME m_rtPrevSyncPoint;
- void IndexSyncPoint(const MuxerPacket* p, __int64 fp);
+ struct SyncPoint {BYTE id; REFERENCE_TIME rtStart, rtStop; __int64 fp;};
+ struct IndexedSyncPoint {BYTE id; REFERENCE_TIME rt, rtfp; __int64 fp;};
+ CAtlList<SyncPoint> m_sps;
+ CAtlList<IndexedSyncPoint> m_isps;
+ REFERENCE_TIME m_rtPrevSyncPoint;
+ void IndexSyncPoint(const MuxerPacket* p, __int64 fp);
- void MuxPacketHeader(IBitStream* pBS, dsmp_t type, UINT64 len);
- void MuxFileInfo(IBitStream* pBS);
- void MuxStreamInfo(IBitStream* pBS, CBaseMuxerInputPin* pPin);
+ void MuxPacketHeader(IBitStream* pBS, dsmp_t type, UINT64 len);
+ void MuxFileInfo(IBitStream* pBS);
+ void MuxStreamInfo(IBitStream* pBS, CBaseMuxerInputPin* pPin);
protected:
- void MuxInit();
+ void MuxInit();
- void MuxHeader(IBitStream* pBS);
- void MuxPacket(IBitStream* pBS, const MuxerPacket* pPacket);
- void MuxFooter(IBitStream* pBS);
+ void MuxHeader(IBitStream* pBS);
+ void MuxPacket(IBitStream* pBS, const MuxerPacket* pPacket);
+ void MuxFooter(IBitStream* pBS);
public:
- CDSMMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr, bool fAutoChap = true, bool fAutoRes = true);
- virtual ~CDSMMuxerFilter();
+ CDSMMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr, bool fAutoChap = true, bool fAutoRes = true);
+ virtual ~CDSMMuxerFilter();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
};
diff --git a/src/filters/muxer/DSMMuxer/resource.h b/src/filters/muxer/DSMMuxer/resource.h
index 07b0c9339..be7a94010 100644
--- a/src/filters/muxer/DSMMuxer/resource.h
+++ b/src/filters/muxer/DSMMuxer/resource.h
@@ -4,7 +4,7 @@
//
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
diff --git a/src/filters/muxer/DSMMuxer/stdafx.cpp b/src/filters/muxer/DSMMuxer/stdafx.cpp
index b28942ef3..5e2cdab92 100644
--- a/src/filters/muxer/DSMMuxer/stdafx.cpp
+++ b/src/filters/muxer/DSMMuxer/stdafx.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/DSMMuxer/stdafx.h b/src/filters/muxer/DSMMuxer/stdafx.h
index 54ba53b6e..7be94a40c 100644
--- a/src/filters/muxer/DSMMuxer/stdafx.h
+++ b/src/filters/muxer/DSMMuxer/stdafx.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/MatroskaMuxer/MatroskaFile.cpp b/src/filters/muxer/MatroskaMuxer/MatroskaFile.cpp
index 8e26ed419..1de7b2956 100644
--- a/src/filters/muxer/MatroskaMuxer/MatroskaFile.cpp
+++ b/src/filters/muxer/MatroskaMuxer/MatroskaFile.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -27,8 +27,8 @@ using namespace MatroskaWriter;
static void bswap(BYTE* s, int len)
{
- for(BYTE* d = s + len - 1; s < d; s++, d--)
- *s ^= *d, *d ^= *s, *s ^= *d;
+ for(BYTE* d = s + len-1; s < d; s++, d--)
+ *s ^= *d, *d ^= *s, *s ^= *d;
}
//
@@ -39,824 +39,824 @@ CID::CID(DWORD id) : m_id(id)
MatroskaWriter::QWORD CID::Size(bool fWithHeader)
{
- return CUInt(0, m_id).Size(false);
+ return CUInt(0, m_id).Size(false);
}
HRESULT CID::Write(IStream* pStream)
{
- MatroskaWriter::QWORD len = CID::Size();
- DWORD id = m_id;
- bswap((BYTE*)&id, (int)len);
- *(BYTE*)&id = ((*(BYTE*)&id) & (1 << (8 - len)) - 1) | (1 << (8 - len));
- return pStream->Write(&id, (ULONG)len, NULL);
+ MatroskaWriter::QWORD len = CID::Size();
+ DWORD id = m_id;
+ bswap((BYTE*)&id, (int)len);
+ *(BYTE*)&id = ((*(BYTE*)&id)&(1<<(8-len))-1)|(1<<(8-len));
+ return pStream->Write(&id, (ULONG)len, NULL);
}
MatroskaWriter::QWORD CID::HeaderSize(MatroskaWriter::QWORD len)
{
- return CID::Size() + CLength(len).Size();
+ return CID::Size() + CLength(len).Size();
}
HRESULT CID::HeaderWrite(IStream* pStream)
{
- CID::Write(pStream);
- CLength(Size(false)).Write(pStream);
- return S_OK;
+ CID::Write(pStream);
+ CLength(Size(false)).Write(pStream);
+ return S_OK;
}
MatroskaWriter::QWORD CBinary::Size(bool fWithHeader)
{
- if(GetCount() == 0) return 0;
+ if(GetCount() == 0) return 0;
- MatroskaWriter::QWORD len = 0;
- len += GetCount();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += GetCount();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CBinary::Write(IStream* pStream)
{
- if(GetCount() == 0) return S_OK;
+ if(GetCount() == 0) return S_OK;
- HeaderWrite(pStream);
- return pStream->Write(GetData(), GetCount(), NULL);
+ HeaderWrite(pStream);
+ return pStream->Write(GetData(), GetCount(), NULL);
}
MatroskaWriter::QWORD CANSI::Size(bool fWithHeader)
{
- if(GetLength() == 0) return 0;
+ if(GetLength() == 0) return 0;
- MatroskaWriter::QWORD len = 0;
- len += GetLength();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += GetLength();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CANSI::Write(IStream* pStream)
{
- if(GetLength() == 0) return S_OK;
+ if(GetLength() == 0) return S_OK;
- HeaderWrite(pStream);
- return pStream->Write((LPCSTR) * this, GetLength(), NULL);
+ HeaderWrite(pStream);
+ return pStream->Write((LPCSTR)*this, GetLength(), NULL);
}
MatroskaWriter::QWORD CUTF8::Size(bool fWithHeader)
{
- if(GetLength() == 0) return 0;
+ if(GetLength() == 0) return 0;
- MatroskaWriter::QWORD len = 0;
- len += UTF16To8(*this).GetLength();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += UTF16To8(*this).GetLength();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CUTF8::Write(IStream* pStream)
{
- if(GetLength() == 0) return S_OK;
+ if(GetLength() == 0) return S_OK;
- HeaderWrite(pStream);
- CStringA str = UTF16To8(*this);
- return pStream->Write((BYTE*)(LPCSTR)str, str.GetLength(), NULL);
+ HeaderWrite(pStream);
+ CStringA str = UTF16To8(*this);
+ return pStream->Write((BYTE*)(LPCSTR)str, str.GetLength(), NULL);
}
template<class T, class BASE>
MatroskaWriter::QWORD CSimpleVar<T, BASE>::Size(bool fWithHeader)
{
- if(!m_fSet) return 0;
+ if(!m_fSet) return 0;
- MatroskaWriter::QWORD len = 0;
- len += sizeof(T);
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += sizeof(T);
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
template<class T, class BASE>
HRESULT CSimpleVar<T, BASE>::Write(IStream* pStream)
{
- if(!m_fSet) return S_OK;
+ if(!m_fSet) return S_OK;
- HeaderWrite(pStream);
- T val = m_val;
- bswap((BYTE*)&val, sizeof(T));
- return pStream->Write(&val, sizeof(T), NULL);
+ HeaderWrite(pStream);
+ T val = m_val;
+ bswap((BYTE*)&val, sizeof(T));
+ return pStream->Write(&val, sizeof(T), NULL);
}
MatroskaWriter::QWORD CUInt::Size(bool fWithHeader)
{
- if(!m_fSet) return 0;
-
- MatroskaWriter::QWORD len = 0;
-
- if(m_val == 0)
- {
- len++;
- }
- else
- {
- for(int i = 8; i > 0; i--)
- {
- if(((0xffi64 << ((i - 1) * 8))&m_val))
- {
- len += i;
- break;
- }
- }
- }
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ if(!m_fSet) return 0;
+
+ MatroskaWriter::QWORD len = 0;
+
+ if(m_val == 0)
+ {
+ len++;
+ }
+ else
+ {
+ for(int i = 8; i > 0; i--)
+ {
+ if(((0xffi64<<((i-1)*8))&m_val))
+ {
+ len += i;
+ break;
+ }
+ }
+ }
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CUInt::Write(IStream* pStream)
{
- if(!m_fSet) return S_OK;
+ if(!m_fSet) return S_OK;
- CID::Write(pStream);
- CLength l(Size(false));
- l.Write(pStream);
- UINT64 val = m_val;
- bswap((BYTE*)&val, (int)l);
- return pStream->Write(&val, (ULONG)l, NULL);
+ CID::Write(pStream);
+ CLength l(Size(false));
+ l.Write(pStream);
+ UINT64 val = m_val;
+ bswap((BYTE*)&val, (int)l);
+ return pStream->Write(&val, (ULONG)l, NULL);
}
MatroskaWriter::QWORD CInt::Size(bool fWithHeader)
{
- if(!m_fSet) return 0;
-
- MatroskaWriter::QWORD len = 0;
-
- if(m_val == 0)
- {
- len++;
- }
- else
- {
- UINT64 val = m_val >= 0 ? m_val : -m_val;
- for(int i = 8; i > 0; i--)
- {
- if(((0xffi64 << ((i - 1) * 8))&val))
- {
- len += i;
- if(m_val < 0 && !(m_val&(0x80 << (i - 1))))
- len++;
- break;
- }
- }
- }
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ if(!m_fSet) return 0;
+
+ MatroskaWriter::QWORD len = 0;
+
+ if(m_val == 0)
+ {
+ len++;
+ }
+ else
+ {
+ UINT64 val = m_val >= 0 ? m_val : -m_val;
+ for(int i = 8; i > 0; i--)
+ {
+ if(((0xffi64<<((i-1)*8))&val))
+ {
+ len += i;
+ if(m_val < 0 && !(m_val&(0x80<<(i-1))))
+ len++;
+ break;
+ }
+ }
+ }
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CInt::Write(IStream* pStream)
{
- if(!m_fSet) return S_OK;
+ if(!m_fSet) return S_OK;
- CID::Write(pStream);
- CLength l(Size(false));
- l.Write(pStream);
- UINT64 val = m_val;
- bswap((BYTE*)&val, (int)l);
- return pStream->Write(&val, (ULONG)l, NULL);
+ CID::Write(pStream);
+ CLength l(Size(false));
+ l.Write(pStream);
+ UINT64 val = m_val;
+ bswap((BYTE*)&val, (int)l);
+ return pStream->Write(&val, (ULONG)l, NULL);
}
MatroskaWriter::QWORD CLength::Size(bool fWithHeader)
{
- if(m_len == 0x00FFFFFFFFFFFFFFi64)
- return 8;
+ if(m_len == 0x00FFFFFFFFFFFFFFi64)
+ return 8;
- MatroskaWriter::QWORD len = 0;
- for(int i = 1; i <= 8; i++)
- {
- if(!(m_len&(~((1i64 << (7 * i)) - 1))) && (m_len&((1i64 << (7 * i)) - 1)) != ((1i64 << (7 * i)) - 1))
- {
- len += i;
- break;
- }
- }
- return len;
+ MatroskaWriter::QWORD len = 0;
+ for(int i = 1; i <= 8; i++)
+ {
+ if(!(m_len&(~((1i64<<(7*i))-1))) && (m_len&((1i64<<(7*i))-1)) != ((1i64<<(7*i))-1))
+ {
+ len += i;
+ break;
+ }
+ }
+ return len;
}
HRESULT CLength::Write(IStream* pStream)
{
- MatroskaWriter::QWORD len = Size(false);
- UINT64 val = m_len;
- bswap((BYTE*)&val, (int)len);
- *(BYTE*)&val = ((*(BYTE*)&val) & (1 << (8 - len)) - 1) | (1 << (8 - len));
- return pStream->Write(&val, (ULONG)len, NULL);
+ MatroskaWriter::QWORD len = Size(false);
+ UINT64 val = m_len;
+ bswap((BYTE*)&val, (int)len);
+ *(BYTE*)&val = ((*(BYTE*)&val)&(1<<(8-len))-1)|(1<<(8-len));
+ return pStream->Write(&val, (ULONG)len, NULL);
}
//
-EBML::EBML(DWORD id)
- : CID(id)
- , EBMLVersion(0x4286)
- , EBMLReadVersion(0x42F7)
- , EBMLMaxIDLength(0x42F2)
- , EBMLMaxSizeLength(0x42F3)
- , DocType(0x4282)
- , DocTypeVersion(0x4287)
- , DocTypeReadVersion(0x4285)
+EBML::EBML(DWORD id)
+ : CID(id)
+ , EBMLVersion(0x4286)
+ , EBMLReadVersion(0x42F7)
+ , EBMLMaxIDLength(0x42F2)
+ , EBMLMaxSizeLength(0x42F3)
+ , DocType(0x4282)
+ , DocTypeVersion(0x4287)
+ , DocTypeReadVersion(0x4285)
{
}
MatroskaWriter::QWORD EBML::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += EBMLVersion.Size();
- len += EBMLReadVersion.Size();
- len += EBMLMaxIDLength.Size();
- len += EBMLMaxSizeLength.Size();
- len += DocType.Size();
- len += DocTypeVersion.Size();
- len += DocTypeReadVersion.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += EBMLVersion.Size();
+ len += EBMLReadVersion.Size();
+ len += EBMLMaxIDLength.Size();
+ len += EBMLMaxSizeLength.Size();
+ len += DocType.Size();
+ len += DocTypeVersion.Size();
+ len += DocTypeReadVersion.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT EBML::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- EBMLVersion.Write(pStream);
- EBMLReadVersion.Write(pStream);
- EBMLMaxIDLength.Write(pStream);
- EBMLMaxSizeLength.Write(pStream);
- DocType.Write(pStream);
- DocTypeVersion.Write(pStream);
- DocTypeReadVersion.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ EBMLVersion.Write(pStream);
+ EBMLReadVersion.Write(pStream);
+ EBMLMaxIDLength.Write(pStream);
+ EBMLMaxSizeLength.Write(pStream);
+ DocType.Write(pStream);
+ DocTypeVersion.Write(pStream);
+ DocTypeReadVersion.Write(pStream);
+ return S_OK;
}
Info::Info(DWORD id)
- : CID(id)
- , SegmentUID(0x73A4)
- , SegmentFilename(0x7384)
- , PrevUID(0x3CB923)
- , PrevFilename(0x3C83AB)
- , NextUID(0x3EB923)
- , NextFilename(0x3E83BB)
- , TimeCodeScale(0x2AD7B1, 1000000ui64)
- , Duration(0x4489)
- , DateUTC(0x4461)
- , Title(0x7BA9)
- , MuxingApp(0x4D80)
- , WritingApp(0x5741)
+ : CID(id)
+ , SegmentUID(0x73A4)
+ , SegmentFilename(0x7384)
+ , PrevUID(0x3CB923)
+ , PrevFilename(0x3C83AB)
+ , NextUID(0x3EB923)
+ , NextFilename(0x3E83BB)
+ , TimeCodeScale(0x2AD7B1, 1000000ui64)
+ , Duration(0x4489)
+ , DateUTC(0x4461)
+ , Title(0x7BA9)
+ , MuxingApp(0x4D80)
+ , WritingApp(0x5741)
{
}
MatroskaWriter::QWORD Info::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += SegmentUID.Size();
- len += PrevUID.Size();
- len += NextUID.Size();
- len += SegmentFilename.Size();
- len += PrevFilename.Size();
- len += NextFilename.Size();
- len += TimeCodeScale.Size();
- len += Duration.Size();
- len += DateUTC.Size();
- len += Title.Size();
- len += MuxingApp.Size();
- len += WritingApp.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += SegmentUID.Size();
+ len += PrevUID.Size();
+ len += NextUID.Size();
+ len += SegmentFilename.Size();
+ len += PrevFilename.Size();
+ len += NextFilename.Size();
+ len += TimeCodeScale.Size();
+ len += Duration.Size();
+ len += DateUTC.Size();
+ len += Title.Size();
+ len += MuxingApp.Size();
+ len += WritingApp.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Info::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- SegmentUID.Write(pStream);
- PrevUID.Write(pStream);
- NextUID.Write(pStream);
- SegmentFilename.Write(pStream);
- PrevFilename.Write(pStream);
- NextFilename.Write(pStream);
- TimeCodeScale.Write(pStream);
- Duration.Write(pStream);
- DateUTC.Write(pStream);
- Title.Write(pStream);
- MuxingApp.Write(pStream);
- WritingApp.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ SegmentUID.Write(pStream);
+ PrevUID.Write(pStream);
+ NextUID.Write(pStream);
+ SegmentFilename.Write(pStream);
+ PrevFilename.Write(pStream);
+ NextFilename.Write(pStream);
+ TimeCodeScale.Write(pStream);
+ Duration.Write(pStream);
+ DateUTC.Write(pStream);
+ Title.Write(pStream);
+ MuxingApp.Write(pStream);
+ WritingApp.Write(pStream);
+ return S_OK;
}
Segment::Segment(DWORD id)
- : CID(id)
+ : CID(id)
{
}
MatroskaWriter::QWORD Segment::Size(bool fWithHeader)
{
- return 0x00FFFFFFFFFFFFFFi64;
- /*
- MatroskaWriter::QWORD len = 0;
- if(fWithHeader) len += HeaderSize(len);
- return len;
- */
+ return 0x00FFFFFFFFFFFFFFi64;
+/*
+ MatroskaWriter::QWORD len = 0;
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
+*/
}
HRESULT Segment::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ return S_OK;
}
Track::Track(DWORD id)
- : CID(id)
+ : CID(id)
{
}
MatroskaWriter::QWORD Track::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += TrackEntries.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += TrackEntries.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Track::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- TrackEntries.Write(pStream);
- return S_OK;
-}
-
-TrackEntry::TrackEntry(DWORD id)
- : CID(id)
- , TrackNumber(0xD7)
- , TrackUID(0x73C5)
- , TrackType(0x83)
- , FlagEnabled(0xB9)
- , FlagDefault(0x88)
- , FlagLacing(0x9C)
- , MinCache(0x6DE7)
- , MaxCache(0x6DF8)
- , Name(0x536E)
- , Language(0x22B59C)
- , CodecID(0x86)
- , CodecPrivate(0x63A2)
- , CodecName(0x258688)
- , CodecSettings(0x3A9697)
- , CodecInfoURL(0x3B4040)
- , CodecDownloadURL(0x26B240)
- , CodecDecodeAll(0xAA)
- , TrackOverlay(0x6FAB)
- , DefaultDuration(0x23E383)
- , v(0xE0)
- , a(0xE1)
-{
- DescType = NoDesc;
+ HeaderWrite(pStream);
+ TrackEntries.Write(pStream);
+ return S_OK;
+}
+
+TrackEntry::TrackEntry(DWORD id)
+ : CID(id)
+ , TrackNumber(0xD7)
+ , TrackUID(0x73C5)
+ , TrackType(0x83)
+ , FlagEnabled(0xB9)
+ , FlagDefault(0x88)
+ , FlagLacing(0x9C)
+ , MinCache(0x6DE7)
+ , MaxCache(0x6DF8)
+ , Name(0x536E)
+ , Language(0x22B59C)
+ , CodecID(0x86)
+ , CodecPrivate(0x63A2)
+ , CodecName(0x258688)
+ , CodecSettings(0x3A9697)
+ , CodecInfoURL(0x3B4040)
+ , CodecDownloadURL(0x26B240)
+ , CodecDecodeAll(0xAA)
+ , TrackOverlay(0x6FAB)
+ , DefaultDuration(0x23E383)
+ , v(0xE0)
+ , a(0xE1)
+{
+ DescType = NoDesc;
}
MatroskaWriter::QWORD TrackEntry::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += TrackNumber.Size();
- len += TrackUID.Size();
- len += TrackType.Size();
- len += FlagEnabled.Size();
- len += FlagDefault.Size();
- len += FlagLacing.Size();
- len += MinCache.Size();
- len += MaxCache.Size();
- len += Name.Size();
- len += Language.Size();
- len += CodecID.Size();
- len += CodecPrivate.Size();
- len += CodecName.Size();
- len += CodecSettings.Size();
- len += CodecInfoURL.Size();
- len += CodecDownloadURL.Size();
- len += CodecDecodeAll.Size();
- len += TrackOverlay.Size();
- len += DefaultDuration.Size();
- if(DescType == TypeVideo) len += v.Size();
- if(DescType == TypeAudio) len += a.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += TrackNumber.Size();
+ len += TrackUID.Size();
+ len += TrackType.Size();
+ len += FlagEnabled.Size();
+ len += FlagDefault.Size();
+ len += FlagLacing.Size();
+ len += MinCache.Size();
+ len += MaxCache.Size();
+ len += Name.Size();
+ len += Language.Size();
+ len += CodecID.Size();
+ len += CodecPrivate.Size();
+ len += CodecName.Size();
+ len += CodecSettings.Size();
+ len += CodecInfoURL.Size();
+ len += CodecDownloadURL.Size();
+ len += CodecDecodeAll.Size();
+ len += TrackOverlay.Size();
+ len += DefaultDuration.Size();
+ if(DescType == TypeVideo) len += v.Size();
+ if(DescType == TypeAudio) len += a.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT TrackEntry::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- TrackNumber.Write(pStream);
- TrackUID.Write(pStream);
- TrackType.Write(pStream);
- FlagEnabled.Write(pStream);
- FlagDefault.Write(pStream);
- FlagLacing.Write(pStream);
- MinCache.Write(pStream);
- MaxCache.Write(pStream);
- Name.Write(pStream);
- Language.Write(pStream);
- CodecID.Write(pStream);
- CodecPrivate.Write(pStream);
- CodecName.Write(pStream);
- CodecSettings.Write(pStream);
- CodecInfoURL.Write(pStream);
- CodecDownloadURL.Write(pStream);
- CodecDecodeAll.Write(pStream);
- TrackOverlay.Write(pStream);
- DefaultDuration.Write(pStream);
- if(DescType == TypeVideo) v.Write(pStream);
- if(DescType == TypeAudio) a.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ TrackNumber.Write(pStream);
+ TrackUID.Write(pStream);
+ TrackType.Write(pStream);
+ FlagEnabled.Write(pStream);
+ FlagDefault.Write(pStream);
+ FlagLacing.Write(pStream);
+ MinCache.Write(pStream);
+ MaxCache.Write(pStream);
+ Name.Write(pStream);
+ Language.Write(pStream);
+ CodecID.Write(pStream);
+ CodecPrivate.Write(pStream);
+ CodecName.Write(pStream);
+ CodecSettings.Write(pStream);
+ CodecInfoURL.Write(pStream);
+ CodecDownloadURL.Write(pStream);
+ CodecDecodeAll.Write(pStream);
+ TrackOverlay.Write(pStream);
+ DefaultDuration.Write(pStream);
+ if(DescType == TypeVideo) v.Write(pStream);
+ if(DescType == TypeAudio) a.Write(pStream);
+ return S_OK;
}
Video::Video(DWORD id)
- : CID(id)
- , FlagInterlaced(0x9A)
- , StereoMode(0x53B8)
- , PixelWidth(0xB0)
- , PixelHeight(0xBA)
- , DisplayWidth(0x54B0)
- , DisplayHeight(0x54BA)
- , DisplayUnit(0x54B2)
- , AspectRatioType(0x54B3)
- , ColourSpace(0x2EB524)
- , GammaValue(0x2FB523)
- , FramePerSec(0x2383E3)
+ : CID(id)
+ , FlagInterlaced(0x9A)
+ , StereoMode(0x53B8)
+ , PixelWidth(0xB0)
+ , PixelHeight(0xBA)
+ , DisplayWidth(0x54B0)
+ , DisplayHeight(0x54BA)
+ , DisplayUnit(0x54B2)
+ , AspectRatioType(0x54B3)
+ , ColourSpace(0x2EB524)
+ , GammaValue(0x2FB523)
+ , FramePerSec(0x2383E3)
{
}
MatroskaWriter::QWORD Video::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += FlagInterlaced.Size();
- len += StereoMode.Size();
- len += PixelWidth.Size();
- len += PixelHeight.Size();
- len += DisplayWidth.Size();
- len += DisplayHeight.Size();
- len += DisplayUnit.Size();
- len += AspectRatioType.Size();
- len += ColourSpace.Size();
- len += GammaValue.Size();
- len += FramePerSec.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += FlagInterlaced.Size();
+ len += StereoMode.Size();
+ len += PixelWidth.Size();
+ len += PixelHeight.Size();
+ len += DisplayWidth.Size();
+ len += DisplayHeight.Size();
+ len += DisplayUnit.Size();
+ len += AspectRatioType.Size();
+ len += ColourSpace.Size();
+ len += GammaValue.Size();
+ len += FramePerSec.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Video::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- FlagInterlaced.Write(pStream);
- StereoMode.Write(pStream);
- PixelWidth.Write(pStream);
- PixelHeight.Write(pStream);
- DisplayWidth.Write(pStream);
- DisplayHeight.Write(pStream);
- DisplayUnit.Write(pStream);
- AspectRatioType.Write(pStream);
- ColourSpace.Write(pStream);
- GammaValue.Write(pStream);
- FramePerSec.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ FlagInterlaced.Write(pStream);
+ StereoMode.Write(pStream);
+ PixelWidth.Write(pStream);
+ PixelHeight.Write(pStream);
+ DisplayWidth.Write(pStream);
+ DisplayHeight.Write(pStream);
+ DisplayUnit.Write(pStream);
+ AspectRatioType.Write(pStream);
+ ColourSpace.Write(pStream);
+ GammaValue.Write(pStream);
+ FramePerSec.Write(pStream);
+ return S_OK;
}
Audio::Audio(DWORD id)
- : CID(id)
- , SamplingFrequency(0xB5)
- , OutputSamplingFrequency(0x78B5)
- , Channels(0x9F)
- , ChannelPositions(0x7D7B)
- , BitDepth(0x6264)
+ : CID(id)
+ , SamplingFrequency(0xB5)
+ , OutputSamplingFrequency(0x78B5)
+ , Channels(0x9F)
+ , ChannelPositions(0x7D7B)
+ , BitDepth(0x6264)
{
}
MatroskaWriter::QWORD Audio::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += SamplingFrequency.Size();
- len += OutputSamplingFrequency.Size();
- len += Channels.Size();
- len += ChannelPositions.Size();
- len += BitDepth.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += SamplingFrequency.Size();
+ len += OutputSamplingFrequency.Size();
+ len += Channels.Size();
+ len += ChannelPositions.Size();
+ len += BitDepth.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Audio::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- SamplingFrequency.Write(pStream);
- OutputSamplingFrequency.Write(pStream);
- Channels.Write(pStream);
- ChannelPositions.Write(pStream);
- BitDepth.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ SamplingFrequency.Write(pStream);
+ OutputSamplingFrequency.Write(pStream);
+ Channels.Write(pStream);
+ ChannelPositions.Write(pStream);
+ BitDepth.Write(pStream);
+ return S_OK;
}
Cluster::Cluster(DWORD id)
- : CID(id)
- , TimeCode(0xE7)
- , Position(0xA7)
- , PrevSize(0xAB)
+ : CID(id)
+ , TimeCode(0xE7)
+ , Position(0xA7)
+ , PrevSize(0xAB)
{
}
MatroskaWriter::QWORD Cluster::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += TimeCode.Size();
- len += Position.Size();
- len += PrevSize.Size();
- len += BlockGroups.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += TimeCode.Size();
+ len += Position.Size();
+ len += PrevSize.Size();
+ len += BlockGroups.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Cluster::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- TimeCode.Write(pStream);
- Position.Write(pStream);
- PrevSize.Write(pStream);
- BlockGroups.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ TimeCode.Write(pStream);
+ Position.Write(pStream);
+ PrevSize.Write(pStream);
+ BlockGroups.Write(pStream);
+ return S_OK;
}
BlockGroup::BlockGroup(DWORD id)
- : CID(id)
- , BlockDuration(0x9B)
- , ReferencePriority(0xFA)
- , ReferenceBlock(0xFB)
- , ReferenceVirtual(0xFD)
- , CodecState(0xA4)
+ : CID(id)
+ , BlockDuration(0x9B)
+ , ReferencePriority(0xFA)
+ , ReferenceBlock(0xFB)
+ , ReferenceVirtual(0xFD)
+ , CodecState(0xA4)
{
}
MatroskaWriter::QWORD BlockGroup::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += BlockDuration.Size();
- len += ReferencePriority.Size();
- len += ReferenceBlock.Size();
- len += ReferenceVirtual.Size();
- len += CodecState.Size();
- len += Block.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += BlockDuration.Size();
+ len += ReferencePriority.Size();
+ len += ReferenceBlock.Size();
+ len += ReferenceVirtual.Size();
+ len += CodecState.Size();
+ len += Block.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT BlockGroup::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- BlockDuration.Write(pStream);
- ReferencePriority.Write(pStream);
- ReferenceBlock.Write(pStream);
- ReferenceVirtual.Write(pStream);
- CodecState.Write(pStream);
- Block.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ BlockDuration.Write(pStream);
+ ReferencePriority.Write(pStream);
+ ReferenceBlock.Write(pStream);
+ ReferenceVirtual.Write(pStream);
+ CodecState.Write(pStream);
+ Block.Write(pStream);
+ return S_OK;
}
CBlock::CBlock(DWORD id)
- : CID(id)
- , TimeCode(0)
+ : CID(id)
+ , TimeCode(0)
{
}
MatroskaWriter::QWORD CBlock::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += TrackNumber.Size() + 2 + 1; // TrackNumber + TimeCode + Lacing
- if(BlockData.GetCount() > 1)
- {
- len += 1; // nBlockData
- POSITION pos = BlockData.GetHeadPosition();
- while(pos)
- {
- CBinary* b = BlockData.GetNext(pos);
- if(pos) len += b->GetCount() / 255 + 1;
- }
- }
- POSITION pos = BlockData.GetHeadPosition();
- while(pos)
- {
- CBinary* b = BlockData.GetNext(pos);
- len += b->GetCount();
- }
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += TrackNumber.Size() + 2 + 1; // TrackNumber + TimeCode + Lacing
+ if(BlockData.GetCount() > 1)
+ {
+ len += 1; // nBlockData
+ POSITION pos = BlockData.GetHeadPosition();
+ while(pos)
+ {
+ CBinary* b = BlockData.GetNext(pos);
+ if(pos) len += b->GetCount()/255 + 1;
+ }
+ }
+ POSITION pos = BlockData.GetHeadPosition();
+ while(pos)
+ {
+ CBinary* b = BlockData.GetNext(pos);
+ len += b->GetCount();
+ }
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CBlock::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- TrackNumber.Write(pStream);
- short t = (short)TimeCode;
- bswap((BYTE*)&t, 2);
- pStream->Write(&t, 2, NULL);
- BYTE Lacing = 0;
- BYTE n = BlockData.GetCount();
- if(n > 1) Lacing |= 2;
- pStream->Write(&Lacing, 1, NULL);
- if(n > 1)
- {
- pStream->Write(&n, 1, NULL);
- POSITION pos = BlockData.GetHeadPosition();
- while(pos)
- {
- CBinary* b = BlockData.GetNext(pos);
- if(pos)
- {
- int len = b->GetCount();
- while(len >= 0)
- {
- n = min(len, 255);
- pStream->Write(&n, 1, NULL);
- len -= 255;
- }
- }
- }
- }
- POSITION pos = BlockData.GetHeadPosition();
- while(pos)
- {
- CBinary* b = BlockData.GetNext(pos);
- pStream->Write(b->GetData(), b->GetCount(), NULL);
- }
- return S_OK;
+ HeaderWrite(pStream);
+ TrackNumber.Write(pStream);
+ short t = (short)TimeCode;
+ bswap((BYTE*)&t, 2);
+ pStream->Write(&t, 2, NULL);
+ BYTE Lacing = 0;
+ BYTE n = BlockData.GetCount();
+ if(n > 1) Lacing |= 2;
+ pStream->Write(&Lacing, 1, NULL);
+ if(n > 1)
+ {
+ pStream->Write(&n, 1, NULL);
+ POSITION pos = BlockData.GetHeadPosition();
+ while(pos)
+ {
+ CBinary* b = BlockData.GetNext(pos);
+ if(pos)
+ {
+ int len = b->GetCount();
+ while(len >= 0)
+ {
+ n = min(len, 255);
+ pStream->Write(&n, 1, NULL);
+ len -= 255;
+ }
+ }
+ }
+ }
+ POSITION pos = BlockData.GetHeadPosition();
+ while(pos)
+ {
+ CBinary* b = BlockData.GetNext(pos);
+ pStream->Write(b->GetData(), b->GetCount(), NULL);
+ }
+ return S_OK;
}
Cue::Cue(DWORD id)
- : CID(id)
+ : CID(id)
{
}
MatroskaWriter::QWORD Cue::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += CuePoints.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += CuePoints.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Cue::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- CuePoints.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ CuePoints.Write(pStream);
+ return S_OK;
}
CuePoint::CuePoint(DWORD id)
- : CID(id)
- , CueTime(0xB3)
+ : CID(id)
+ , CueTime(0xB3)
{
}
MatroskaWriter::QWORD CuePoint::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += CueTime.Size();
- len += CueTrackPositions.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += CueTime.Size();
+ len += CueTrackPositions.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CuePoint::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- CueTime.Write(pStream);
- CueTrackPositions.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ CueTime.Write(pStream);
+ CueTrackPositions.Write(pStream);
+ return S_OK;
}
CueTrackPosition::CueTrackPosition(DWORD id)
- : CID(id)
- , CueTrack(0xF7)
- , CueClusterPosition(0xF1)
- , CueBlockNumber(0x5387)
- , CueCodecState(0xEA)
+ : CID(id)
+ , CueTrack(0xF7)
+ , CueClusterPosition(0xF1)
+ , CueBlockNumber(0x5387)
+ , CueCodecState(0xEA)
{
}
MatroskaWriter::QWORD CueTrackPosition::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += CueTrack.Size();
- len += CueClusterPosition.Size();
- len += CueBlockNumber.Size();
- len += CueCodecState.Size();
+ MatroskaWriter::QWORD len = 0;
+ len += CueTrack.Size();
+ len += CueClusterPosition.Size();
+ len += CueBlockNumber.Size();
+ len += CueCodecState.Size();
// len += CueReferences.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT CueTrackPosition::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- CueTrack.Write(pStream);
- CueClusterPosition.Write(pStream);
- CueBlockNumber.Write(pStream);
- CueCodecState.Write(pStream);
+ HeaderWrite(pStream);
+ CueTrack.Write(pStream);
+ CueClusterPosition.Write(pStream);
+ CueBlockNumber.Write(pStream);
+ CueCodecState.Write(pStream);
// CueReferences.Write(pStream);
- return S_OK;
+ return S_OK;
}
Seek::Seek(DWORD id)
- : CID(id)
+ : CID(id)
{
}
MatroskaWriter::QWORD Seek::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += SeekHeads.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += SeekHeads.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Seek::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- SeekHeads.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ SeekHeads.Write(pStream);
+ return S_OK;
}
SeekID::SeekID(DWORD id)
- : CID(id)
- , m_id(0)
+ : CID(id)
+ , m_id(0)
{
}
MatroskaWriter::QWORD SeekID::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += m_id.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += m_id.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT SeekID::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- m_id.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ m_id.Write(pStream);
+ return S_OK;
}
SeekHead::SeekHead(DWORD id)
- : CID(id)
- , Position(0x53AC)
+ : CID(id)
+ , Position(0x53AC)
{
}
MatroskaWriter::QWORD SeekHead::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += ID.Size();
- len += Position.Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += ID.Size();
+ len += Position.Size();
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT SeekHead::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- ID.Write(pStream);
- Position.Write(pStream);
- return S_OK;
+ HeaderWrite(pStream);
+ ID.Write(pStream);
+ Position.Write(pStream);
+ return S_OK;
}
Tags::Tags(DWORD id)
- : CID(id)
+ : CID(id)
{
}
MatroskaWriter::QWORD Tags::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
+ MatroskaWriter::QWORD len = 0;
// len += .Size();
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Tags::Write(IStream* pStream)
{
- HeaderWrite(pStream);
+ HeaderWrite(pStream);
// .Write(pStream);
- return S_OK;
+ return S_OK;
}
Void::Void(MatroskaWriter::QWORD len, DWORD id)
- : CID(id)
- , m_len(len)
+ : CID(id)
+ , m_len(len)
{
}
MatroskaWriter::QWORD Void::Size(bool fWithHeader)
{
- MatroskaWriter::QWORD len = 0;
- len += m_len;
- if(fWithHeader) len += HeaderSize(len);
- return len;
+ MatroskaWriter::QWORD len = 0;
+ len += m_len;
+ if(fWithHeader) len += HeaderSize(len);
+ return len;
}
HRESULT Void::Write(IStream* pStream)
{
- HeaderWrite(pStream);
- BYTE buff[64];
- memset(buff, 0x80, sizeof(buff));
- for(int len = (int)m_len; len > 0; len -= sizeof(buff))
- pStream->Write(buff, (ULONG)min(sizeof(buff), len), NULL);
- return S_OK;
+ HeaderWrite(pStream);
+ BYTE buff[64];
+ memset(buff, 0x80, sizeof(buff));
+ for(int len = (int)m_len; len > 0; len -= sizeof(buff))
+ pStream->Write(buff, (ULONG)min(sizeof(buff), len), NULL);
+ return S_OK;
}
diff --git a/src/filters/muxer/MatroskaMuxer/MatroskaFile.h b/src/filters/muxer/MatroskaMuxer/MatroskaFile.h
index 3965ac6d8..80273dd76 100644
--- a/src/filters/muxer/MatroskaMuxer/MatroskaFile.h
+++ b/src/filters/muxer/MatroskaMuxer/MatroskaFile.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -26,304 +26,264 @@
namespace MatroskaWriter
{
-typedef unsigned __int64 QWORD;
-
-class CID
-{
-protected:
- DWORD m_id;
- QWORD HeaderSize(QWORD len);
- HRESULT HeaderWrite(IStream* pStream);
-
-public:
- CID(DWORD id);
- DWORD GetID() const
- {
- return m_id;
- }
- virtual QWORD Size(bool fWithHeader = true);
- virtual HRESULT Write(IStream* pStream);
-};
-
-class CLength : public CID
-{
- UINT64 m_len;
-public:
- CLength(UINT64 len = 0) : CID(0), m_len(len) {}
- operator UINT64()
- {
- return m_len;
- }
- QWORD Size(bool fWithHeader = false);
- HRESULT Write(IStream* pStream);
-};
-
-class CBinary : public CAtlArray<BYTE>, public CID
-{
-public:
- CBinary(DWORD id) : CID(id) {}
- CBinary& operator = (const CBinary& b)
- {
- Copy(b);
- return(*this);
- }
- operator BYTE*()
- {
- return (BYTE*)GetData();
- }
- CBinary& Set(CStringA str)
- {
- SetCount(str.GetLength() + 1);
- strcpy((char*)GetData(), str);
- return(*this);
- }
+ typedef unsigned __int64 QWORD;
+
+ class CID
+ {
+ protected:
+ DWORD m_id;
+ QWORD HeaderSize(QWORD len);
+ HRESULT HeaderWrite(IStream* pStream);
+
+ public:
+ CID(DWORD id);
+ DWORD GetID() const {return m_id;}
+ virtual QWORD Size(bool fWithHeader = true);
+ virtual HRESULT Write(IStream* pStream);
+ };
+
+ class CLength : public CID
+ {
+ UINT64 m_len;
+ public:
+ CLength(UINT64 len = 0) : CID(0), m_len(len) {}
+ operator UINT64() {return m_len;}
+ QWORD Size(bool fWithHeader = false);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CBinary : public CAtlArray<BYTE>, public CID
+ {
+ public:
+ CBinary(DWORD id) : CID(id) {}
+ CBinary& operator = (const CBinary& b) {Copy(b); return(*this);}
+ operator BYTE*() {return (BYTE*)GetData();}
+ CBinary& Set(CStringA str) {SetCount(str.GetLength()+1); strcpy((char*)GetData(), str); return(*this);}
// CBinary& Set(CStringA str) {SetCount(str.GetLength()); memcpy((char*)GetData(), str, str.GetLength()); return(*this);}
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CANSI : public CStringA, public CID
-{
-public:
- CANSI(DWORD id) : CID(id) {}
- CANSI& Set(CStringA str)
- {
- CStringA::operator = (str);
- return(*this);
- }
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CUTF8 : public CStringW, public CID
-{
-public:
- CUTF8(DWORD id) : CID(id) {}
- CUTF8& Set(CStringW str)
- {
- CStringW::operator = (str);
- return(*this);
- }
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-template<class T, class BASE>
-class CSimpleVar : public CID
-{
-protected:
- T m_val;
- bool m_fSet;
-public:
- explicit CSimpleVar(DWORD id, T val = 0) : CID(id), m_val(val)
- {
- m_fSet = !!val;
- }
- operator T()
- {
- return m_val;
- }
- BASE& Set(T val)
- {
- m_val = val;
- m_fSet = true;
- return(*(BASE*)this);
- }
- void UnSet()
- {
- m_fSet = false;
- }
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CUInt : public CSimpleVar<UINT64, CUInt>
-{
-public:
- explicit CUInt(DWORD id, UINT64 val = 0) : CSimpleVar<UINT64, CUInt>(id, val) {}
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CInt : public CSimpleVar<INT64, CInt>
-{
-public:
- explicit CInt(DWORD id, INT64 val = 0) : CSimpleVar<INT64, CInt>(id, val) {}
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CByte : public CSimpleVar<BYTE, CByte>
-{
-public:
- explicit CByte(DWORD id, BYTE val = 0) : CSimpleVar<BYTE, CByte>(id, val) {}
-};
-
-class CShort : public CSimpleVar<short, CShort>
-{
-public:
- explicit CShort(DWORD id, short val = 0) : CSimpleVar<short, CShort>(id, val) {}
-};
-
-class CFloat : public CSimpleVar<float, CFloat>
-{
-public:
- explicit CFloat(DWORD id, float val = 0) : CSimpleVar<float, CFloat>(id, val) {}
-};
-
-template<class T>
-class CNode : public CAutoPtrList<T>
-{
-public:
- QWORD Size(bool fWithHeader = true)
- {
- QWORD len = 0;
- POSITION pos = GetHeadPosition();
- while(pos) len += GetNext(pos)->Size(fWithHeader);
- return len;
- }
- HRESULT Write(IStream* pStream)
- {
- HRESULT hr;
- POSITION pos = GetHeadPosition();
- while(pos) if(FAILED(hr = GetNext(pos)->Write(pStream))) return hr;
- return S_OK;
- }
-};
-
-class EBML : public CID
-{
-public:
- CUInt EBMLVersion, EBMLReadVersion;
- CUInt EBMLMaxIDLength, EBMLMaxSizeLength;
- CANSI DocType;
- CUInt DocTypeVersion, DocTypeReadVersion;
-
- EBML(DWORD id = 0x1A45DFA3);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Info : public CID
-{
-public:
- CBinary SegmentUID, PrevUID, NextUID;
- CUTF8 SegmentFilename, PrevFilename, NextFilename;
- CUInt TimeCodeScale; // [ns], default: 1.000.000
- CFloat Duration;
- CInt DateUTC;
- CUTF8 Title, MuxingApp, WritingApp;
-
- Info(DWORD id = 0x1549A966);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Video : public CID
-{
-public:
- CUInt FlagInterlaced, StereoMode;
- CUInt PixelWidth, PixelHeight, DisplayWidth, DisplayHeight, DisplayUnit;
- CUInt AspectRatioType;
- CUInt ColourSpace;
- CFloat GammaValue;
- CFloat FramePerSec;
-
- Video(DWORD id = 0xE0);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Audio : public CID
-{
-public:
- CFloat SamplingFrequency;
- CFloat OutputSamplingFrequency;
- CUInt Channels;
- CBinary ChannelPositions;
- CUInt BitDepth;
-
- Audio(DWORD id = 0xE1);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class TrackEntry : public CID
-{
-public:
- enum {TypeVideo = 1, TypeAudio = 2, TypeComplex = 3, TypeLogo = 0x10, TypeSubtitle = 0x11, TypeControl = 0x20};
- CUInt TrackNumber, TrackUID, TrackType;
- CUInt FlagEnabled, FlagDefault, FlagLacing;
- CUInt MinCache, MaxCache;
- CUTF8 Name;
- CANSI Language;
- CBinary CodecID;
- CBinary CodecPrivate;
- CUTF8 CodecName;
- CUTF8 CodecSettings;
- CANSI CodecInfoURL;
- CANSI CodecDownloadURL;
- CUInt CodecDecodeAll;
- CUInt TrackOverlay;
- CUInt DefaultDuration;
- enum {NoDesc = 0, DescVideo = 1, DescAudio = 2};
- int DescType;
- Video v;
- Audio a;
-
- TrackEntry(DWORD id = 0xAE);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Track : public CID
-{
-public:
- CNode<TrackEntry> TrackEntries;
-
- Track(DWORD id = 0x1654AE6B);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CBlock : public CID
-{
-public:
- CLength TrackNumber;
- REFERENCE_TIME TimeCode, TimeCodeStop;
- CNode<CBinary> BlockData;
-
- CBlock(DWORD id = 0xA1);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class BlockGroup : public CID
-{
-public:
- CUInt BlockDuration;
- CUInt ReferencePriority;
- CInt ReferenceBlock;
- CInt ReferenceVirtual;
- CBinary CodecState;
- CBlock Block;
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CANSI : public CStringA, public CID
+ {
+ public:
+ CANSI(DWORD id) : CID(id) {}
+ CANSI& Set(CStringA str) {CStringA::operator = (str); return(*this);}
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CUTF8 : public CStringW, public CID
+ {
+ public:
+ CUTF8(DWORD id) : CID(id) {}
+ CUTF8& Set(CStringW str) {CStringW::operator = (str); return(*this);}
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ template<class T, class BASE>
+ class CSimpleVar : public CID
+ {
+ protected:
+ T m_val;
+ bool m_fSet;
+ public:
+ explicit CSimpleVar(DWORD id, T val = 0) : CID(id), m_val(val) {m_fSet = !!val;}
+ operator T() {return m_val;}
+ BASE& Set(T val) {m_val = val; m_fSet = true; return(*(BASE*)this);}
+ void UnSet() {m_fSet = false;}
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CUInt : public CSimpleVar<UINT64, CUInt>
+ {
+ public:
+ explicit CUInt(DWORD id, UINT64 val = 0) : CSimpleVar<UINT64, CUInt>(id, val) {}
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CInt : public CSimpleVar<INT64, CInt>
+ {
+ public:
+ explicit CInt(DWORD id, INT64 val = 0) : CSimpleVar<INT64, CInt>(id, val) {}
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CByte : public CSimpleVar<BYTE, CByte>
+ {
+ public:
+ explicit CByte(DWORD id, BYTE val = 0) : CSimpleVar<BYTE, CByte>(id, val) {}
+ };
+
+ class CShort : public CSimpleVar<short, CShort>
+ {
+ public:
+ explicit CShort(DWORD id, short val = 0) : CSimpleVar<short, CShort>(id, val) {}
+ };
+
+ class CFloat : public CSimpleVar<float, CFloat>
+ {
+ public:
+ explicit CFloat(DWORD id, float val = 0) : CSimpleVar<float, CFloat>(id, val) {}
+ };
+
+ template<class T>
+ class CNode : public CAutoPtrList<T>
+ {
+ public:
+ QWORD Size(bool fWithHeader = true)
+ {
+ QWORD len = 0;
+ POSITION pos = GetHeadPosition();
+ while(pos) len += GetNext(pos)->Size(fWithHeader);
+ return len;
+ }
+ HRESULT Write(IStream* pStream)
+ {
+ HRESULT hr;
+ POSITION pos = GetHeadPosition();
+ while(pos) if(FAILED(hr = GetNext(pos)->Write(pStream))) return hr;
+ return S_OK;
+ }
+ };
+
+ class EBML : public CID
+ {
+ public:
+ CUInt EBMLVersion, EBMLReadVersion;
+ CUInt EBMLMaxIDLength, EBMLMaxSizeLength;
+ CANSI DocType;
+ CUInt DocTypeVersion, DocTypeReadVersion;
+
+ EBML(DWORD id = 0x1A45DFA3);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Info : public CID
+ {
+ public:
+ CBinary SegmentUID, PrevUID, NextUID;
+ CUTF8 SegmentFilename, PrevFilename, NextFilename;
+ CUInt TimeCodeScale; // [ns], default: 1.000.000
+ CFloat Duration;
+ CInt DateUTC;
+ CUTF8 Title, MuxingApp, WritingApp;
+
+ Info(DWORD id = 0x1549A966);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Video : public CID
+ {
+ public:
+ CUInt FlagInterlaced, StereoMode;
+ CUInt PixelWidth, PixelHeight, DisplayWidth, DisplayHeight, DisplayUnit;
+ CUInt AspectRatioType;
+ CUInt ColourSpace;
+ CFloat GammaValue;
+ CFloat FramePerSec;
+
+ Video(DWORD id = 0xE0);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Audio : public CID
+ {
+ public:
+ CFloat SamplingFrequency;
+ CFloat OutputSamplingFrequency;
+ CUInt Channels;
+ CBinary ChannelPositions;
+ CUInt BitDepth;
+
+ Audio(DWORD id = 0xE1);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class TrackEntry : public CID
+ {
+ public:
+ enum {TypeVideo = 1, TypeAudio = 2, TypeComplex = 3, TypeLogo = 0x10, TypeSubtitle = 0x11, TypeControl = 0x20};
+ CUInt TrackNumber, TrackUID, TrackType;
+ CUInt FlagEnabled, FlagDefault, FlagLacing;
+ CUInt MinCache, MaxCache;
+ CUTF8 Name;
+ CANSI Language;
+ CBinary CodecID;
+ CBinary CodecPrivate;
+ CUTF8 CodecName;
+ CUTF8 CodecSettings;
+ CANSI CodecInfoURL;
+ CANSI CodecDownloadURL;
+ CUInt CodecDecodeAll;
+ CUInt TrackOverlay;
+ CUInt DefaultDuration;
+ enum {NoDesc = 0, DescVideo = 1, DescAudio = 2};
+ int DescType;
+ Video v;
+ Audio a;
+
+ TrackEntry(DWORD id = 0xAE);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Track : public CID
+ {
+ public:
+ CNode<TrackEntry> TrackEntries;
+
+ Track(DWORD id = 0x1654AE6B);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CBlock : public CID
+ {
+ public:
+ CLength TrackNumber;
+ REFERENCE_TIME TimeCode, TimeCodeStop;
+ CNode<CBinary> BlockData;
+
+ CBlock(DWORD id = 0xA1);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class BlockGroup : public CID
+ {
+ public:
+ CUInt BlockDuration;
+ CUInt ReferencePriority;
+ CInt ReferenceBlock;
+ CInt ReferenceVirtual;
+ CBinary CodecState;
+ CBlock Block;
// CNode<TimeSlice> TimeSlices;
- BlockGroup(DWORD id = 0xA0);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
+ BlockGroup(DWORD id = 0xA0);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
-class Cluster : public CID
-{
-public:
- CUInt TimeCode, Position, PrevSize;
- CNode<BlockGroup> BlockGroups;
+ class Cluster : public CID
+ {
+ public:
+ CUInt TimeCode, Position, PrevSize;
+ CNode<BlockGroup> BlockGroups;
- Cluster(DWORD id = 0x1F43B675);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
+ Cluster(DWORD id = 0x1F43B675);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
/* class CueReference : public CID
{
@@ -335,96 +295,93 @@ public:
HRESULT Write(IStream* pStream);
};
*/
-class CueTrackPosition : public CID
-{
-public:
- CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
+ class CueTrackPosition : public CID
+ {
+ public:
+ CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
// CNode<CueReference> CueReferences;
- CueTrackPosition(DWORD id = 0xB7);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class CuePoint : public CID
-{
-public:
- CUInt CueTime;
- CNode<CueTrackPosition> CueTrackPositions;
-
- CuePoint(DWORD id = 0xBB);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Cue : public CID
-{
-public:
- CNode<CuePoint> CuePoints;
-
- Cue(DWORD id = 0x1C53BB6B);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class SeekID : public CID
-{
- CID m_id;
-public:
- SeekID(DWORD id = 0x53AB);
- void Set(DWORD id)
- {
- m_id = id;
- }
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class SeekHead : public CID
-{
-public:
- SeekID ID;
- CUInt Position;
-
- SeekHead(DWORD id = 0x4DBB);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Seek : public CID
-{
-public:
- CNode<SeekHead> SeekHeads;
-
- Seek(DWORD id = 0x114D9B74);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Segment : public CID
-{
-public:
- Segment(DWORD id = 0x18538067);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Tags : public CID
-{
-public:
- // TODO
-
- Tags(DWORD id = 0x1254C367);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
-
-class Void : public CID
-{
- QWORD m_len;
-public:
- Void(QWORD len, DWORD id = 0xEC);
- QWORD Size(bool fWithHeader = true);
- HRESULT Write(IStream* pStream);
-};
+ CueTrackPosition(DWORD id = 0xB7);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class CuePoint : public CID
+ {
+ public:
+ CUInt CueTime;
+ CNode<CueTrackPosition> CueTrackPositions;
+
+ CuePoint(DWORD id = 0xBB);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Cue : public CID
+ {
+ public:
+ CNode<CuePoint> CuePoints;
+
+ Cue(DWORD id = 0x1C53BB6B);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class SeekID : public CID
+ {
+ CID m_id;
+ public:
+ SeekID(DWORD id = 0x53AB);
+ void Set(DWORD id) {m_id = id;}
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class SeekHead : public CID
+ {
+ public:
+ SeekID ID;
+ CUInt Position;
+
+ SeekHead(DWORD id = 0x4DBB);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Seek : public CID
+ {
+ public:
+ CNode<SeekHead> SeekHeads;
+
+ Seek(DWORD id = 0x114D9B74);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Segment : public CID
+ {
+ public:
+ Segment(DWORD id = 0x18538067);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Tags : public CID
+ {
+ public:
+ // TODO
+
+ Tags(DWORD id = 0x1254C367);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
+
+ class Void : public CID
+ {
+ QWORD m_len;
+ public:
+ Void(QWORD len, DWORD id = 0xEC);
+ QWORD Size(bool fWithHeader = true);
+ HRESULT Write(IStream* pStream);
+ };
}
diff --git a/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.cpp b/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.cpp
index fd353c4fa..c4fff1a35 100644
--- a/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.cpp
+++ b/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -33,7 +33,7 @@ using namespace MatroskaWriter;
const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
{
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_Matroska}
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_Matroska}
};
const AMOVIESETUP_PIN sudpPins[] =
@@ -44,24 +44,24 @@ const AMOVIESETUP_PIN sudpPins[] =
const AMOVIESETUP_FILTER sudFilter[] =
{
- {&__uuidof(CMatroskaMuxerFilter), L"MPC - Matroska Muxer", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory}
+ {&__uuidof(CMatroskaMuxerFilter), L"MPC - Matroska Muxer", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory}
};
CFactoryTemplate g_Templates[] =
{
- {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CMatroskaMuxerFilter>, NULL, &sudFilter[0]}
+ {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CMatroskaMuxerFilter>, NULL, &sudFilter[0]}
};
int g_cTemplates = countof(g_Templates);
STDAPI DllRegisterServer()
{
- return AMovieDllRegisterServer2(TRUE);
+ return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
- return AMovieDllRegisterServer2(FALSE);
+ return AMovieDllRegisterServer2(FALSE);
}
#include "../../FilterApp.h"
@@ -75,627 +75,576 @@ CFilterApp theApp;
//
CMatroskaMuxerFilter::CMatroskaMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CBaseFilter(NAME("CMatroskaMuxerFilter"), pUnk, this, __uuidof(this))
- , m_rtCurrent(0)
- , m_fNegative(true), m_fPositive(false)
+ : CBaseFilter(NAME("CMatroskaMuxerFilter"), pUnk, this, __uuidof(this))
+ , m_rtCurrent(0)
+ , m_fNegative(true), m_fPositive(false)
{
- if(phr) *phr = S_OK;
+ if(phr) *phr = S_OK;
- m_pOutput.Attach(DNew CMatroskaMuxerOutputPin(NAME("CMatroskaMuxerOutputPin"), this, this, phr));
+ m_pOutput.Attach(DNew CMatroskaMuxerOutputPin(NAME("CMatroskaMuxerOutputPin"), this, this, phr));
- AddInput();
+ AddInput();
- srand(clock());
+ srand(clock());
}
CMatroskaMuxerFilter::~CMatroskaMuxerFilter()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
}
STDMETHODIMP CMatroskaMuxerFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- *ppv = NULL;
+ *ppv = NULL;
- return
+ return
// QI(IAMFilterMiscFlags)
- QI(IMediaSeeking)
- QI(IMatroskaMuxer)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ QI(IMediaSeeking)
+ QI(IMatroskaMuxer)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
UINT CMatroskaMuxerFilter::GetTrackNumber(CBasePin* pPin)
{
- UINT nTrackNumber = 0;
+ UINT nTrackNumber = 0;
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- nTrackNumber++;
- if(m_pInputs.GetNext(pos) == pPin)
- return nTrackNumber;
- }
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos)
+ {
+ nTrackNumber++;
+ if(m_pInputs.GetNext(pos) == pPin)
+ return nTrackNumber;
+ }
- return 0;
+ return 0;
}
void CMatroskaMuxerFilter::AddInput()
{
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- CBasePin* pPin = m_pInputs.GetNext(pos);
- if(!pPin->IsConnected()) return;
- }
-
- CStringW name;
- name.Format(L"Track %d", m_pInputs.GetCount() + 1);
-
- HRESULT hr;
- CAutoPtr<CMatroskaMuxerInputPin> pPin(DNew CMatroskaMuxerInputPin(name, this, this, &hr));
- m_pInputs.AddTail(pPin);
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos)
+ {
+ CBasePin* pPin = m_pInputs.GetNext(pos);
+ if(!pPin->IsConnected()) return;
+ }
+
+ CStringW name;
+ name.Format(L"Track %d", m_pInputs.GetCount()+1);
+
+ HRESULT hr;
+ CAutoPtr<CMatroskaMuxerInputPin> pPin(DNew CMatroskaMuxerInputPin(name, this, this, &hr));
+ m_pInputs.AddTail(pPin);
}
int CMatroskaMuxerFilter::GetPinCount()
{
- return m_pInputs.GetCount() + (m_pOutput ? 1 : 0);
+ return m_pInputs.GetCount() + (m_pOutput ? 1 : 0);
}
CBasePin* CMatroskaMuxerFilter::GetPin(int n)
{
CAutoLock cAutoLock(this);
- if(n >= 0 && n < (int)m_pInputs.GetCount())
- {
- if(POSITION pos = m_pInputs.FindIndex(n))
- return m_pInputs.GetAt(pos);
- }
+ if(n >= 0 && n < (int)m_pInputs.GetCount())
+ {
+ if(POSITION pos = m_pInputs.FindIndex(n))
+ return m_pInputs.GetAt(pos);
+ }
- if(n == m_pInputs.GetCount() && m_pOutput)
- {
- return m_pOutput;
- }
+ if(n == m_pInputs.GetCount() && m_pOutput)
+ {
+ return m_pOutput;
+ }
- return NULL;
+ return NULL;
}
STDMETHODIMP CMatroskaMuxerFilter::Stop()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- HRESULT hr;
+ HRESULT hr;
+
+ if(FAILED(hr = __super::Stop()))
+ return hr;
- if(FAILED(hr = __super::Stop()))
- return hr;
+ CallWorker(CMD_EXIT);
- CallWorker(CMD_EXIT);
-
- return hr;
+ return hr;
}
STDMETHODIMP CMatroskaMuxerFilter::Pause()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- FILTER_STATE fs = m_State;
+ FILTER_STATE fs = m_State;
- HRESULT hr;
+ HRESULT hr;
- if(FAILED(hr = __super::Pause()))
- return hr;
+ if(FAILED(hr = __super::Pause()))
+ return hr;
- if(fs == State_Stopped && m_pOutput)
- {
- CAMThread::Create();
- CallWorker(CMD_RUN);
- }
+ if(fs == State_Stopped && m_pOutput)
+ {
+ CAMThread::Create();
+ CallWorker(CMD_RUN);
+ }
- return hr;
+ return hr;
}
STDMETHODIMP CMatroskaMuxerFilter::Run(REFERENCE_TIME tStart)
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- HRESULT hr;
+ HRESULT hr;
- if(FAILED(hr = __super::Run(tStart)))
- return hr;
+ if(FAILED(hr = __super::Run(tStart)))
+ return hr;
- return hr;
+ return hr;
}
// IAMFilterMiscFlags
STDMETHODIMP_(ULONG) CMatroskaMuxerFilter::GetMiscFlags()
{
- return AM_FILTER_MISC_FLAGS_IS_RENDERER;
+ return AM_FILTER_MISC_FLAGS_IS_RENDERER;
}
// IMediaSeeking
STDMETHODIMP CMatroskaMuxerFilter::GetCapabilities(DWORD* pCapabilities)
{
- return pCapabilities ? *pCapabilities =
- AM_SEEKING_CanGetDuration |
- AM_SEEKING_CanGetCurrentPos, S_OK : E_POINTER;
+ return pCapabilities ? *pCapabilities =
+ AM_SEEKING_CanGetDuration|
+ AM_SEEKING_CanGetCurrentPos, S_OK : E_POINTER;
}
STDMETHODIMP CMatroskaMuxerFilter::CheckCapabilities(DWORD* pCapabilities)
{
- CheckPointer(pCapabilities, E_POINTER);
- if(*pCapabilities == 0) return S_OK;
- DWORD caps;
- GetCapabilities(&caps);
- caps &= *pCapabilities;
- return caps == 0 ? E_FAIL : caps == *pCapabilities ? S_OK : S_FALSE;
-}
-STDMETHODIMP CMatroskaMuxerFilter::IsFormatSupported(const GUID* pFormat)
-{
- return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
-}
-STDMETHODIMP CMatroskaMuxerFilter::QueryPreferredFormat(GUID* pFormat)
-{
- return GetTimeFormat(pFormat);
-}
-STDMETHODIMP CMatroskaMuxerFilter::GetTimeFormat(GUID* pFormat)
-{
- return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;
-}
-STDMETHODIMP CMatroskaMuxerFilter::IsUsingTimeFormat(const GUID* pFormat)
-{
- return IsFormatSupported(pFormat);
-}
-STDMETHODIMP CMatroskaMuxerFilter::SetTimeFormat(const GUID* pFormat)
-{
- return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;
+ CheckPointer(pCapabilities, E_POINTER);
+ if(*pCapabilities == 0) return S_OK;
+ DWORD caps;
+ GetCapabilities(&caps);
+ caps &= *pCapabilities;
+ return caps == 0 ? E_FAIL : caps == *pCapabilities ? S_OK : S_FALSE;
}
+STDMETHODIMP CMatroskaMuxerFilter::IsFormatSupported(const GUID* pFormat) {return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;}
+STDMETHODIMP CMatroskaMuxerFilter::QueryPreferredFormat(GUID* pFormat) {return GetTimeFormat(pFormat);}
+STDMETHODIMP CMatroskaMuxerFilter::GetTimeFormat(GUID* pFormat) {return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;}
+STDMETHODIMP CMatroskaMuxerFilter::IsUsingTimeFormat(const GUID* pFormat) {return IsFormatSupported(pFormat);}
+STDMETHODIMP CMatroskaMuxerFilter::SetTimeFormat(const GUID* pFormat) {return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;}
STDMETHODIMP CMatroskaMuxerFilter::GetDuration(LONGLONG* pDuration)
{
- CheckPointer(pDuration, E_POINTER);
- *pDuration = 0;
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- REFERENCE_TIME rt = m_pInputs.GetNext(pos)->m_rtDur;
- if(rt > *pDuration) *pDuration = rt;
- }
- return S_OK;
-}
-STDMETHODIMP CMatroskaMuxerFilter::GetStopPosition(LONGLONG* pStop)
-{
- return E_NOTIMPL;
+ CheckPointer(pDuration, E_POINTER);
+ *pDuration = 0;
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos) {REFERENCE_TIME rt = m_pInputs.GetNext(pos)->m_rtDur; if(rt > *pDuration) *pDuration = rt;}
+ return S_OK;
}
+STDMETHODIMP CMatroskaMuxerFilter::GetStopPosition(LONGLONG* pStop) {return E_NOTIMPL;}
STDMETHODIMP CMatroskaMuxerFilter::GetCurrentPosition(LONGLONG* pCurrent)
{
- CheckPointer(pCurrent, E_POINTER);
- *pCurrent = m_rtCurrent;
- return S_OK;
-}
-STDMETHODIMP CMatroskaMuxerFilter::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CMatroskaMuxerFilter::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CMatroskaMuxerFilter::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CMatroskaMuxerFilter::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CMatroskaMuxerFilter::SetRate(double dRate)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CMatroskaMuxerFilter::GetRate(double* pdRate)
-{
- return E_NOTIMPL;
-}
-STDMETHODIMP CMatroskaMuxerFilter::GetPreroll(LONGLONG* pllPreroll)
-{
- return E_NOTIMPL;
+ CheckPointer(pCurrent, E_POINTER);
+ *pCurrent = m_rtCurrent;
+ return S_OK;
}
+STDMETHODIMP CMatroskaMuxerFilter::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat) {return E_NOTIMPL;}
+STDMETHODIMP CMatroskaMuxerFilter::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags) {return E_NOTIMPL;}
+STDMETHODIMP CMatroskaMuxerFilter::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop) {return E_NOTIMPL;}
+STDMETHODIMP CMatroskaMuxerFilter::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest) {return E_NOTIMPL;}
+STDMETHODIMP CMatroskaMuxerFilter::SetRate(double dRate) {return E_NOTIMPL;}
+STDMETHODIMP CMatroskaMuxerFilter::GetRate(double* pdRate) {return E_NOTIMPL;}
+STDMETHODIMP CMatroskaMuxerFilter::GetPreroll(LONGLONG* pllPreroll) {return E_NOTIMPL;}
-// IMatroskaMuxer
+// IMatroskaMuxer
STDMETHODIMP CMatroskaMuxerFilter::CorrectTimeOffset(bool fNegative, bool fPositive)
{
- m_fNegative = fNegative;
- m_fPositive = fPositive;
- return S_OK;
+ m_fNegative = fNegative;
+ m_fPositive = fPositive;
+ return S_OK;
}
//
ULONGLONG GetStreamPosition(IStream* pStream)
{
- ULARGE_INTEGER pos = {0, 0};
- pStream->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_CUR, &pos);
- return pos.QuadPart;
+ ULARGE_INTEGER pos = {0, 0};
+ pStream->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_CUR, &pos);
+ return pos.QuadPart;
}
ULONGLONG SetStreamPosition(IStream* pStream, ULONGLONG seekpos)
{
- LARGE_INTEGER pos;
- pos.QuadPart = seekpos;
- ULARGE_INTEGER posnew;
- posnew.QuadPart = GetStreamPosition(pStream);
- pStream->Seek(pos, STREAM_SEEK_SET, &posnew);
- return posnew.QuadPart;
+ LARGE_INTEGER pos;
+ pos.QuadPart = seekpos;
+ ULARGE_INTEGER posnew;
+ posnew.QuadPart = GetStreamPosition(pStream);
+ pStream->Seek(pos, STREAM_SEEK_SET, &posnew);
+ return posnew.QuadPart;
}
DWORD CMatroskaMuxerFilter::ThreadProc()
{
- CComQIPtr<IStream> pStream;
-
- if(!m_pOutput || !(pStream = m_pOutput->GetConnected()))
- {
- while(1)
- {
- DWORD cmd = GetRequest();
- if(cmd == CMD_EXIT) CAMThread::m_hThread = NULL;
- Reply(S_OK);
- if(cmd == CMD_EXIT) return 0;
- }
- }
-
- REFERENCE_TIME rtDur = 0;
- GetDuration(&rtDur);
-
- SetStreamPosition(pStream, 0);
-
- ULARGE_INTEGER uli = {0};
- pStream->SetSize(uli);
-
- EBML hdr;
- hdr.DocType.Set("matroska");
- hdr.DocTypeVersion.Set(1);
- hdr.DocTypeReadVersion.Set(1);
- hdr.Write(pStream);
-
- Segment().Write(pStream);
- ULONGLONG segpos = GetStreamPosition(pStream);
-
- // TODO
- MatroskaWriter::QWORD voidlen = 100;
- if(rtDur > 0) voidlen += int(1.0 * rtDur / MAXCLUSTERTIME / 10000 + 0.5) * 20;
- else voidlen += int(1.0 * 1000 * 60 * 60 * 24 / MAXCLUSTERTIME + 0.5) * 20; // when no duration is known, allocate for 24 hours (~340k)
- ULONGLONG voidpos = GetStreamPosition(pStream);
- {
- Void v(voidlen);
- voidlen = v.Size();
- v.Write(pStream);
- }
-
- // Meta Seek
-
- Seek seek;
- CAutoPtr<SeekHead> sh;
-
- // Segment Info
-
- sh.Attach(DNew SeekHead());
- sh->ID.Set(0x1549A966);
- sh->Position.Set(GetStreamPosition(pStream) - segpos);
- seek.SeekHeads.AddTail(sh);
-
- ULONGLONG infopos = GetStreamPosition(pStream);
- Info info;
- info.MuxingApp.Set(L"DirectShow Matroska Muxer");
- info.TimeCodeScale.Set(1000000);
- info.Duration.Set((float)rtDur / 10000);
- struct tm _2001 = {0, 0, 0, 1, 0, 101, 0, 0, 1};
- info.DateUTC.Set((_time64(NULL) - _mktime64(&_2001)) * 1000000000);
- info.Write(pStream);
-
- // Tracks
-
- sh.Attach(DNew SeekHead());
- sh->ID.Set(0x1654AE6B);
- sh->Position.Set(GetStreamPosition(pStream) - segpos);
- seek.SeekHeads.AddTail(sh);
-
- UINT64 TrackNumber = 0;
- /*
- CNode<Track> Tracks;
- CAutoPtr<Track> pT(DNew Track());
- POSITION pos = m_pInputs.GetHeadPosition();
- for(int i = 1; pos; i++)
- {
- CMatroskaMuxerInputPin* pPin = m_pInputs.GetNext(pos);
- if(!pPin->IsConnected()) continue;
-
- CAutoPtr<TrackEntry> pTE(DNew TrackEntry());
- *pTE = *pPin->GetTrackEntry();
- if(TrackNumber == 0 && pTE->TrackType == TrackEntry::TypeVideo)
- TrackNumber = pTE->TrackNumber;
- pT->TrackEntries.AddTail(pTE);
- }
- Tracks.AddTail(pT);
- Tracks.Write(pStream);
-
- if(TrackNumber == 0) TrackNumber = 1;
- */
- bool fTracksWritten = false;
-
- //
-
- Cluster c;
- c.TimeCode.Set(0);
-
- bool fFirstBlock = true;
- INT64 firstTimeCode = 0;
-
- CAtlList<CMatroskaMuxerInputPin*> pActivePins;
-
- POSITION pos = m_pInputs.GetHeadPosition();
- while(pos)
- {
- CMatroskaMuxerInputPin* pPin = m_pInputs.GetNext(pos);
- if(pPin->IsConnected()) pActivePins.AddTail(pPin);
- }
-
- while(1)
- {
- DWORD cmd = GetRequest();
-
- switch(cmd)
- {
- default:
- case CMD_EXIT:
- CAMThread::m_hThread = NULL;
- Reply(S_OK);
- return 0;
-
- case CMD_RUN:
- Reply(S_OK);
-
- Cue cue;
- ULONGLONG lastcueclusterpos = -1;
- INT64 lastcuetimecode = -1;
- UINT64 nBlocksInCueTrack = 0;
-
- while(!CheckRequest(NULL))
- {
- if(m_State == State_Paused)
- {
- Sleep(10);
- continue;
- }
-
- int nPinsGotSomething = 0, nPinsNeeded = 0;
- CMatroskaMuxerInputPin* pPin = NULL;
- REFERENCE_TIME rtMin = _I64_MAX;
-
- pos = pActivePins.GetHeadPosition();
- while(pos)
- {
- CMatroskaMuxerInputPin* pTmp = pActivePins.GetNext(pos);
-
- CAutoLock cAutoLock(&pTmp->m_csQueue);
-
- if(pTmp->m_blocks.GetCount() == 0 && pTmp->m_fEndOfStreamReceived)
- {
- pActivePins.RemoveAt(pActivePins.Find(pTmp));
- continue;
- }
-
- if(pTmp->GetTrackEntry()->TrackType != TrackEntry::TypeSubtitle)
- nPinsNeeded++;
-
- if(pTmp->m_blocks.GetCount() > 0)
- {
- if(pTmp->GetTrackEntry()->TrackType != TrackEntry::TypeSubtitle)
- nPinsGotSomething++;
-
- if(pTmp->m_blocks.GetCount() > 0)
- {
- REFERENCE_TIME rt = pTmp->m_blocks.GetHead()->Block.TimeCode;
- if(rt < rtMin)
- {
- rtMin = rt;
- pPin = pTmp;
- }
- }
- }
- }
-
- if(pActivePins.GetCount() == 0)
- {
- break;
- }
-
- if(!pPin || nPinsNeeded > nPinsGotSomething || !pPin && nPinsGotSomething == 0)
- {
- Sleep(1);
- continue;
- }
-
- if(!fTracksWritten)
- {
- CNode<Track> Tracks;
- CAutoPtr<Track> pT(DNew Track());
- POSITION pos = pActivePins.GetHeadPosition();
- for(int i = 1; pos; i++)
- {
- CMatroskaMuxerInputPin* pPin = pActivePins.GetNext(pos);
-
- CAutoPtr<TrackEntry> pTE(DNew TrackEntry());
- *pTE = *pPin->GetTrackEntry();
- if(TrackNumber == 0 && pTE->TrackType == TrackEntry::TypeVideo)
- TrackNumber = pTE->TrackNumber;
- pT->TrackEntries.AddTail(pTE);
- }
- Tracks.AddTail(pT);
- Tracks.Write(pStream);
-
- if(TrackNumber == 0) TrackNumber = 1;
-
- fTracksWritten = true;
- }
-
- ASSERT(pPin);
-
- CAutoPtr<BlockGroup> b;
-
- {
- CAutoLock cAutoLock(&pPin->m_csQueue);
- b = pPin->m_blocks.RemoveHead();
- }
-
- if(b)
- {
- if(fFirstBlock)
- {
- if(b->Block.TimeCode < 0 && m_fNegative || b->Block.TimeCode > 0 && m_fPositive)
- firstTimeCode = b->Block.TimeCode;
- fFirstBlock = false;
- }
-
- b->Block.TimeCode -= firstTimeCode;
- b->Block.TimeCodeStop -= firstTimeCode;
-
- /*
- TRACE(_T("Muxing (%d): %I64d-%I64d dur=%I64d (c=%d, co=%dms), cnt=%d, ref=%d\n"),
- GetTrackNumber(pPin),
- (INT64)b->Block.TimeCode, (INT64)b->Block.TimeCodeStop, (UINT64)b->BlockDuration,
- (int)((b->Block.TimeCode)/MAXCLUSTERTIME), (int)(b->Block.TimeCode%MAXCLUSTERTIME),
- b->Block.BlockData.GetCount(), (int)b->ReferenceBlock);
- */
- if(b->Block.TimeCode < SHRT_MIN /*0*/)
- {
- ASSERT(0);
- continue;
- }
-
- while((INT64)(c.TimeCode + MAXCLUSTERTIME) < b->Block.TimeCode)
- {
- if(!c.BlockGroups.IsEmpty())
- {
- sh.Attach(DNew SeekHead());
- sh->ID.Set(c.GetID()/*0x1F43B675*/);
- sh->Position.Set(GetStreamPosition(pStream) - segpos);
- seek.SeekHeads.AddTail(sh);
-
- c.Write(pStream); // TODO: write blocks
- }
-
- c.TimeCode.Set(c.TimeCode + MAXCLUSTERTIME);
- c.BlockGroups.RemoveAll();
- nBlocksInCueTrack = 0;
- }
-
- if(b->Block.TrackNumber == TrackNumber)
- {
- nBlocksInCueTrack++;
- }
-
- if(b->ReferenceBlock == 0 && b->Block.TrackNumber == TrackNumber)
- {
- ULONGLONG clusterpos = GetStreamPosition(pStream) - segpos;
- if(lastcueclusterpos != clusterpos || lastcuetimecode + 1000 < b->Block.TimeCode)
- {
- CAutoPtr<CueTrackPosition> ctp(DNew CueTrackPosition());
- ctp->CueTrack.Set(b->Block.TrackNumber);
- ctp->CueClusterPosition.Set(clusterpos);
- if(c.BlockGroups.GetCount() > 0) ctp->CueBlockNumber.Set(nBlocksInCueTrack);
- CAutoPtr<CuePoint> cp(DNew CuePoint());
- cp->CueTime.Set(b->Block.TimeCode);
- cp->CueTrackPositions.AddTail(ctp);
- cue.CuePoints.AddTail(cp);
- lastcueclusterpos = clusterpos;
- lastcuetimecode = b->Block.TimeCode;
- }
- }
-
- info.Duration.Set(max(info.Duration, (float)b->Block.TimeCodeStop));
-
- m_rtCurrent = b->Block.TimeCode * 10000;
-
- b->Block.TimeCode -= c.TimeCode;
- c.BlockGroups.AddTail(b);
- }
- }
-
- if(!c.BlockGroups.IsEmpty())
- {
- sh.Attach(DNew SeekHead());
- sh->ID.Set(c.GetID()/*0x1F43B675*/);
- sh->Position.Set(GetStreamPosition(pStream) - segpos);
- seek.SeekHeads.AddTail(sh);
-
- c.Write(pStream);
- }
-
- ULONGLONG cuepos = 0;
- if(!cue.CuePoints.IsEmpty())
- {
- sh.Attach(DNew SeekHead());
- sh->ID.Set(cue.GetID()/*0x1C53BB6B*/);
- sh->Position.Set(GetStreamPosition(pStream) - segpos);
- seek.SeekHeads.AddTail(sh);
-
- cue.Write(pStream);
- }
-
- {
- Tags tags;
-
- sh.Attach(DNew SeekHead());
- sh->ID.Set(tags.GetID());
- sh->Position.Set(GetStreamPosition(pStream) - segpos);
- seek.SeekHeads.AddTail(sh);
-
- tags.Write(pStream);
- }
-
- SetStreamPosition(pStream, voidpos);
- int len = (int)(voidlen - seek.Size());
- ASSERT(len >= 0 && len != 1);
- seek.Write(pStream);
-
- if(len == 0)
- {
- // nothing to do
- }
- else if(len >= 2)
- {
- for(int i = 0; i < 8; i++)
- {
- if(len >= (1 << i * 7) - 2 && len <= (1 << (i + 1) * 7) - 2)
- {
- Void(len - 2 - i).Write(pStream);
- break;
- }
- }
- }
-
- if(abs(m_rtCurrent - (REFERENCE_TIME)info.Duration * 10000) > 10000000i64)
- {
- info.Duration.Set(m_rtCurrent / 10000 + 1);
- }
-
- SetStreamPosition(pStream, infopos);
- info.Write(pStream);
-
- // TODO: write some tags
-
- m_pOutput->DeliverEndOfStream();
-
- break;
- }
- }
-
- ASSERT(0); // we should only exit via CMD_EXIT
-
- CAMThread::m_hThread = NULL;
- return 0;
+ CComQIPtr<IStream> pStream;
+
+ if(!m_pOutput || !(pStream = m_pOutput->GetConnected()))
+ {
+ while(1)
+ {
+ DWORD cmd = GetRequest();
+ if(cmd == CMD_EXIT) CAMThread::m_hThread = NULL;
+ Reply(S_OK);
+ if(cmd == CMD_EXIT) return 0;
+ }
+ }
+
+ REFERENCE_TIME rtDur = 0;
+ GetDuration(&rtDur);
+
+ SetStreamPosition(pStream, 0);
+
+ ULARGE_INTEGER uli = {0};
+ pStream->SetSize(uli);
+
+ EBML hdr;
+ hdr.DocType.Set("matroska");
+ hdr.DocTypeVersion.Set(1);
+ hdr.DocTypeReadVersion.Set(1);
+ hdr.Write(pStream);
+
+ Segment().Write(pStream);
+ ULONGLONG segpos = GetStreamPosition(pStream);
+
+ // TODO
+ MatroskaWriter::QWORD voidlen = 100;
+ if(rtDur > 0) voidlen += int(1.0 * rtDur / MAXCLUSTERTIME / 10000 + 0.5) * 20;
+ else voidlen += int(1.0 * 1000*60*60*24 / MAXCLUSTERTIME + 0.5) * 20; // when no duration is known, allocate for 24 hours (~340k)
+ ULONGLONG voidpos = GetStreamPosition(pStream);
+ {
+ Void v(voidlen);
+ voidlen = v.Size();
+ v.Write(pStream);
+ }
+
+ // Meta Seek
+
+ Seek seek;
+ CAutoPtr<SeekHead> sh;
+
+ // Segment Info
+
+ sh.Attach(DNew SeekHead());
+ sh->ID.Set(0x1549A966);
+ sh->Position.Set(GetStreamPosition(pStream) - segpos);
+ seek.SeekHeads.AddTail(sh);
+
+ ULONGLONG infopos = GetStreamPosition(pStream);
+ Info info;
+ info.MuxingApp.Set(L"DirectShow Matroska Muxer");
+ info.TimeCodeScale.Set(1000000);
+ info.Duration.Set((float)rtDur / 10000);
+ struct tm _2001 = {0, 0, 0, 1, 0, 101, 0, 0, 1};
+ info.DateUTC.Set((_time64(NULL) - _mktime64(&_2001)) * 1000000000);
+ info.Write(pStream);
+
+ // Tracks
+
+ sh.Attach(DNew SeekHead());
+ sh->ID.Set(0x1654AE6B);
+ sh->Position.Set(GetStreamPosition(pStream) - segpos);
+ seek.SeekHeads.AddTail(sh);
+
+ UINT64 TrackNumber = 0;
+/*
+ CNode<Track> Tracks;
+ CAutoPtr<Track> pT(DNew Track());
+ POSITION pos = m_pInputs.GetHeadPosition();
+ for(int i = 1; pos; i++)
+ {
+ CMatroskaMuxerInputPin* pPin = m_pInputs.GetNext(pos);
+ if(!pPin->IsConnected()) continue;
+
+ CAutoPtr<TrackEntry> pTE(DNew TrackEntry());
+ *pTE = *pPin->GetTrackEntry();
+ if(TrackNumber == 0 && pTE->TrackType == TrackEntry::TypeVideo)
+ TrackNumber = pTE->TrackNumber;
+ pT->TrackEntries.AddTail(pTE);
+ }
+ Tracks.AddTail(pT);
+ Tracks.Write(pStream);
+
+ if(TrackNumber == 0) TrackNumber = 1;
+*/
+ bool fTracksWritten = false;
+
+ //
+
+ Cluster c;
+ c.TimeCode.Set(0);
+
+ bool fFirstBlock = true;
+ INT64 firstTimeCode = 0;
+
+ CAtlList<CMatroskaMuxerInputPin*> pActivePins;
+
+ POSITION pos = m_pInputs.GetHeadPosition();
+ while(pos)
+ {
+ CMatroskaMuxerInputPin* pPin = m_pInputs.GetNext(pos);
+ if(pPin->IsConnected()) pActivePins.AddTail(pPin);
+ }
+
+ while(1)
+ {
+ DWORD cmd = GetRequest();
+
+ switch(cmd)
+ {
+ default:
+ case CMD_EXIT:
+ CAMThread::m_hThread = NULL;
+ Reply(S_OK);
+ return 0;
+
+ case CMD_RUN:
+ Reply(S_OK);
+
+ Cue cue;
+ ULONGLONG lastcueclusterpos = -1;
+ INT64 lastcuetimecode = -1;
+ UINT64 nBlocksInCueTrack = 0;
+
+ while(!CheckRequest(NULL))
+ {
+ if(m_State == State_Paused)
+ {
+ Sleep(10);
+ continue;
+ }
+
+ int nPinsGotSomething = 0, nPinsNeeded = 0;
+ CMatroskaMuxerInputPin* pPin = NULL;
+ REFERENCE_TIME rtMin = _I64_MAX;
+
+ pos = pActivePins.GetHeadPosition();
+ while(pos)
+ {
+ CMatroskaMuxerInputPin* pTmp = pActivePins.GetNext(pos);
+
+ CAutoLock cAutoLock(&pTmp->m_csQueue);
+
+ if(pTmp->m_blocks.GetCount() == 0 && pTmp->m_fEndOfStreamReceived)
+ {
+ pActivePins.RemoveAt(pActivePins.Find(pTmp));
+ continue;
+ }
+
+ if(pTmp->GetTrackEntry()->TrackType != TrackEntry::TypeSubtitle)
+ nPinsNeeded++;
+
+ if(pTmp->m_blocks.GetCount() > 0)
+ {
+ if(pTmp->GetTrackEntry()->TrackType != TrackEntry::TypeSubtitle)
+ nPinsGotSomething++;
+
+ if(pTmp->m_blocks.GetCount() > 0)
+ {
+ REFERENCE_TIME rt = pTmp->m_blocks.GetHead()->Block.TimeCode;
+ if(rt < rtMin) {rtMin = rt; pPin = pTmp;}
+ }
+ }
+ }
+
+ if(pActivePins.GetCount() == 0)
+ {
+ break;
+ }
+
+ if(!pPin || nPinsNeeded > nPinsGotSomething || !pPin && nPinsGotSomething == 0)
+ {
+ Sleep(1);
+ continue;
+ }
+
+ if(!fTracksWritten)
+ {
+ CNode<Track> Tracks;
+ CAutoPtr<Track> pT(DNew Track());
+ POSITION pos = pActivePins.GetHeadPosition();
+ for(int i = 1; pos; i++)
+ {
+ CMatroskaMuxerInputPin* pPin = pActivePins.GetNext(pos);
+
+ CAutoPtr<TrackEntry> pTE(DNew TrackEntry());
+ *pTE = *pPin->GetTrackEntry();
+ if(TrackNumber == 0 && pTE->TrackType == TrackEntry::TypeVideo)
+ TrackNumber = pTE->TrackNumber;
+ pT->TrackEntries.AddTail(pTE);
+ }
+ Tracks.AddTail(pT);
+ Tracks.Write(pStream);
+
+ if(TrackNumber == 0) TrackNumber = 1;
+
+ fTracksWritten = true;
+ }
+
+ ASSERT(pPin);
+
+ CAutoPtr<BlockGroup> b;
+
+ {
+ CAutoLock cAutoLock(&pPin->m_csQueue);
+ b = pPin->m_blocks.RemoveHead();
+ }
+
+ if(b)
+ {
+ if(fFirstBlock)
+ {
+ if(b->Block.TimeCode < 0 && m_fNegative || b->Block.TimeCode > 0 && m_fPositive)
+ firstTimeCode = b->Block.TimeCode;
+ fFirstBlock = false;
+ }
+
+ b->Block.TimeCode -= firstTimeCode;
+ b->Block.TimeCodeStop -= firstTimeCode;
+
+/*
+TRACE(_T("Muxing (%d): %I64d-%I64d dur=%I64d (c=%d, co=%dms), cnt=%d, ref=%d\n"),
+ GetTrackNumber(pPin),
+ (INT64)b->Block.TimeCode, (INT64)b->Block.TimeCodeStop, (UINT64)b->BlockDuration,
+ (int)((b->Block.TimeCode)/MAXCLUSTERTIME), (int)(b->Block.TimeCode%MAXCLUSTERTIME),
+ b->Block.BlockData.GetCount(), (int)b->ReferenceBlock);
+*/
+ if(b->Block.TimeCode < SHRT_MIN /*0*/) {ASSERT(0); continue;}
+
+ while((INT64)(c.TimeCode + MAXCLUSTERTIME) < b->Block.TimeCode)
+ {
+ if(!c.BlockGroups.IsEmpty())
+ {
+ sh.Attach(DNew SeekHead());
+ sh->ID.Set(c.GetID()/*0x1F43B675*/);
+ sh->Position.Set(GetStreamPosition(pStream) - segpos);
+ seek.SeekHeads.AddTail(sh);
+
+ c.Write(pStream); // TODO: write blocks
+ }
+
+ c.TimeCode.Set(c.TimeCode + MAXCLUSTERTIME);
+ c.BlockGroups.RemoveAll();
+ nBlocksInCueTrack = 0;
+ }
+
+ if(b->Block.TrackNumber == TrackNumber)
+ {
+ nBlocksInCueTrack++;
+ }
+
+ if(b->ReferenceBlock == 0 && b->Block.TrackNumber == TrackNumber)
+ {
+ ULONGLONG clusterpos = GetStreamPosition(pStream) - segpos;
+ if(lastcueclusterpos != clusterpos || lastcuetimecode + 1000 < b->Block.TimeCode)
+ {
+ CAutoPtr<CueTrackPosition> ctp(DNew CueTrackPosition());
+ ctp->CueTrack.Set(b->Block.TrackNumber);
+ ctp->CueClusterPosition.Set(clusterpos);
+ if(c.BlockGroups.GetCount() > 0) ctp->CueBlockNumber.Set(nBlocksInCueTrack);
+ CAutoPtr<CuePoint> cp(DNew CuePoint());
+ cp->CueTime.Set(b->Block.TimeCode);
+ cp->CueTrackPositions.AddTail(ctp);
+ cue.CuePoints.AddTail(cp);
+ lastcueclusterpos = clusterpos;
+ lastcuetimecode = b->Block.TimeCode;
+ }
+ }
+
+ info.Duration.Set(max(info.Duration, (float)b->Block.TimeCodeStop));
+
+ m_rtCurrent = b->Block.TimeCode*10000;
+
+ b->Block.TimeCode -= c.TimeCode;
+ c.BlockGroups.AddTail(b);
+ }
+ }
+
+ if(!c.BlockGroups.IsEmpty())
+ {
+ sh.Attach(DNew SeekHead());
+ sh->ID.Set(c.GetID()/*0x1F43B675*/);
+ sh->Position.Set(GetStreamPosition(pStream) - segpos);
+ seek.SeekHeads.AddTail(sh);
+
+ c.Write(pStream);
+ }
+
+ ULONGLONG cuepos = 0;
+ if(!cue.CuePoints.IsEmpty())
+ {
+ sh.Attach(DNew SeekHead());
+ sh->ID.Set(cue.GetID()/*0x1C53BB6B*/);
+ sh->Position.Set(GetStreamPosition(pStream) - segpos);
+ seek.SeekHeads.AddTail(sh);
+
+ cue.Write(pStream);
+ }
+
+ {
+ Tags tags;
+
+ sh.Attach(DNew SeekHead());
+ sh->ID.Set(tags.GetID());
+ sh->Position.Set(GetStreamPosition(pStream) - segpos);
+ seek.SeekHeads.AddTail(sh);
+
+ tags.Write(pStream);
+ }
+
+ SetStreamPosition(pStream, voidpos);
+ int len = (int)(voidlen - seek.Size());
+ ASSERT(len >= 0 && len != 1);
+ seek.Write(pStream);
+
+ if(len == 0)
+ {
+ // nothing to do
+ }
+ else if(len >= 2)
+ {
+ for(int i = 0; i < 8; i++)
+ {
+ if(len >= (1<<i*7)-2 && len <= (1<<(i+1)*7)-2)
+ {
+ Void(len-2-i).Write(pStream);
+ break;
+ }
+ }
+ }
+
+ if(abs(m_rtCurrent - (REFERENCE_TIME)info.Duration*10000) > 10000000i64)
+ {
+ info.Duration.Set(m_rtCurrent / 10000 + 1);
+ }
+
+ SetStreamPosition(pStream, infopos);
+ info.Write(pStream);
+
+ // TODO: write some tags
+
+ m_pOutput->DeliverEndOfStream();
+
+ break;
+ }
+ }
+
+ ASSERT(0); // we should only exit via CMD_EXIT
+
+ CAMThread::m_hThread = NULL;
+ return 0;
}
//
@@ -703,10 +652,10 @@ DWORD CMatroskaMuxerFilter::ThreadProc()
//
CMatroskaMuxerInputPin::CMatroskaMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseInputPin(NAME("CMatroskaMuxerInputPin"), pFilter, pLock, phr, pName)
- , m_fActive(false)
- , m_fEndOfStreamReceived(false)
- , m_rtDur(0)
+ : CBaseInputPin(NAME("CMatroskaMuxerInputPin"), pFilter, pLock, phr, pName)
+ , m_fActive(false)
+ , m_fEndOfStreamReceived(false)
+ , m_rtDur(0)
{
}
@@ -716,644 +665,631 @@ CMatroskaMuxerInputPin::~CMatroskaMuxerInputPin()
STDMETHODIMP CMatroskaMuxerInputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- return
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
HRESULT CMatroskaMuxerInputPin::CheckMediaType(const CMediaType* pmt)
{
- return pmt->majortype == MEDIATYPE_Video && (pmt->formattype == FORMAT_VideoInfo
- || pmt->formattype == FORMAT_VideoInfo2)
+ return pmt->majortype == MEDIATYPE_Video && (pmt->formattype == FORMAT_VideoInfo
+ || pmt->formattype == FORMAT_VideoInfo2)
// || pmt->majortype == MEDIATYPE_Video && pmt->subtype == MEDIASUBTYPE_MPEG1Payload && pmt->formattype == FORMAT_MPEGVideo
// || pmt->majortype == MEDIATYPE_Video && pmt->subtype == MEDIASUBTYPE_MPEG2_VIDEO && pmt->formattype == FORMAT_MPEG2_VIDEO
- || pmt->majortype == MEDIATYPE_Video && pmt->subtype == MEDIASUBTYPE_DiracVideo && pmt->formattype == FORMAT_DiracVideoInfo
- || pmt->majortype == MEDIATYPE_Audio && pmt->formattype == FORMAT_WaveFormatEx && pmt->subtype == FOURCCMap(((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag)
- || pmt->majortype == MEDIATYPE_Audio && pmt->subtype == MEDIASUBTYPE_Vorbis && pmt->formattype == FORMAT_VorbisFormat
- || pmt->majortype == MEDIATYPE_Audio && pmt->subtype == MEDIASUBTYPE_Vorbis2 && pmt->formattype == FORMAT_VorbisFormat2
- || pmt->majortype == MEDIATYPE_Audio && (pmt->subtype == MEDIASUBTYPE_14_4
- || pmt->subtype == MEDIASUBTYPE_28_8
- || pmt->subtype == MEDIASUBTYPE_ATRC
- || pmt->subtype == MEDIASUBTYPE_COOK
- || pmt->subtype == MEDIASUBTYPE_DNET
- || pmt->subtype == MEDIASUBTYPE_SIPR) && pmt->formattype == FORMAT_WaveFormatEx
- || pmt->majortype == MEDIATYPE_Text && pmt->subtype == MEDIASUBTYPE_NULL && pmt->formattype == FORMAT_None
- || pmt->majortype == MEDIATYPE_Subtitle && pmt->formattype == FORMAT_SubtitleInfo
- ? S_OK
- : E_INVALIDARG;
+ || pmt->majortype == MEDIATYPE_Video && pmt->subtype == MEDIASUBTYPE_DiracVideo && pmt->formattype == FORMAT_DiracVideoInfo
+ || pmt->majortype == MEDIATYPE_Audio && pmt->formattype == FORMAT_WaveFormatEx && pmt->subtype == FOURCCMap(((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag)
+ || pmt->majortype == MEDIATYPE_Audio && pmt->subtype == MEDIASUBTYPE_Vorbis && pmt->formattype == FORMAT_VorbisFormat
+ || pmt->majortype == MEDIATYPE_Audio && pmt->subtype == MEDIASUBTYPE_Vorbis2 && pmt->formattype == FORMAT_VorbisFormat2
+ || pmt->majortype == MEDIATYPE_Audio && (pmt->subtype == MEDIASUBTYPE_14_4
+ || pmt->subtype == MEDIASUBTYPE_28_8
+ || pmt->subtype == MEDIASUBTYPE_ATRC
+ || pmt->subtype == MEDIASUBTYPE_COOK
+ || pmt->subtype == MEDIASUBTYPE_DNET
+ || pmt->subtype == MEDIASUBTYPE_SIPR) && pmt->formattype == FORMAT_WaveFormatEx
+ || pmt->majortype == MEDIATYPE_Text && pmt->subtype == MEDIASUBTYPE_NULL && pmt->formattype == FORMAT_None
+ || pmt->majortype == MEDIATYPE_Subtitle && pmt->formattype == FORMAT_SubtitleInfo
+ ? S_OK
+ : E_INVALIDARG;
}
HRESULT CMatroskaMuxerInputPin::BreakConnect()
{
- HRESULT hr;
+ HRESULT hr;
- if(FAILED(hr = __super::BreakConnect()))
- return hr;
+ if(FAILED(hr = __super::BreakConnect()))
+ return hr;
- m_pTE.Free();
+ m_pTE.Free();
- return hr;
+ return hr;
}
HRESULT CMatroskaMuxerInputPin::CompleteConnect(IPin* pPin)
{
- HRESULT hr;
-
- if(FAILED(hr = __super::CompleteConnect(pPin)))
- return hr;
-
- m_rtDur = 0;
- CComQIPtr<IMediaSeeking> pMS;
- if((pMS = GetFilterFromPin(pPin)) || (pMS = pPin))
- pMS->GetDuration(&m_rtDur);
-
- m_pTE.Free();
- m_pTE.Attach(DNew TrackEntry());
-
- m_pTE->TrackUID.Set(rand());
- m_pTE->MinCache.Set(1);
- m_pTE->MaxCache.Set(1);
- m_pTE->TrackNumber.Set((static_cast<CMatroskaMuxerFilter*>(m_pFilter))->GetTrackNumber(this));
-
- hr = E_FAIL;
-
- if(m_mt.majortype == MEDIATYPE_Video)
- {
- m_pTE->TrackType.Set(TrackEntry::TypeVideo);
-
- if(m_mt.formattype == FORMAT_VideoInfo
- && m_mt.subtype == MEDIASUBTYPE_RV10 || m_mt.subtype == MEDIASUBTYPE_RV20
- || m_mt.subtype == MEDIASUBTYPE_RV30 || m_mt.subtype == MEDIASUBTYPE_RV40)
- {
- m_pTE->CodecID.Set("V_REAL/RV00");
- m_pTE->CodecID.SetAt(9, (BYTE)(m_mt.subtype.Data1 >> 16));
-
- if(m_mt.formattype == FORMAT_VideoInfo)
- {
- VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_mt.pbFormat;
- if(m_mt.cbFormat > sizeof(VIDEOINFOHEADER))
- {
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - sizeof(VIDEOINFOHEADER));
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + sizeof(VIDEOINFOHEADER), m_pTE->CodecPrivate.GetCount());
- }
- m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame * 100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
- if(vih->AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
- }
- else if(m_mt.formattype == FORMAT_VideoInfo2)
- {
- VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)m_mt.pbFormat;
- if(m_mt.cbFormat > sizeof(VIDEOINFOHEADER2))
- {
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - sizeof(VIDEOINFOHEADER2));
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + sizeof(VIDEOINFOHEADER2), m_pTE->CodecPrivate.GetCount());
- }
- m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame * 100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
- if(vih->AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
- m_pTE->v.DisplayWidth.Set(vih->dwPictAspectRatioX);
- m_pTE->v.DisplayHeight.Set(vih->dwPictAspectRatioY);
- }
- else
- {
- ASSERT(0);
- return hr;
- }
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_VideoInfo)
- {
- m_pTE->CodecID.Set("V_MS/VFW/FOURCC");
-
- VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_mt.pbFormat;
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader));
- memcpy(m_pTE->CodecPrivate, &vih->bmiHeader, m_pTE->CodecPrivate.GetCount());
- m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame * 100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
- if(vih->AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_VideoInfo2)
- {
- m_pTE->CodecID.Set("V_MS/VFW/FOURCC");
-
- VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)m_mt.pbFormat;
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader));
- memcpy(m_pTE->CodecPrivate, &vih->bmiHeader, m_pTE->CodecPrivate.GetCount());
- m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame * 100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
- m_pTE->v.DisplayWidth.Set(vih->dwPictAspectRatioX);
- m_pTE->v.DisplayHeight.Set(vih->dwPictAspectRatioY);
- if(vih->AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_DiracVideoInfo)
- {
- m_pTE->CodecID.Set("V_DIRAC");
-
- DIRACINFOHEADER* vih = (DIRACINFOHEADER*)m_mt.pbFormat;
- m_pTE->CodecPrivate.SetCount(vih->cbSequenceHeader);
- memcpy(m_pTE->CodecPrivate, (BYTE*)&vih->dwSequenceHeader[0], m_pTE->CodecPrivate.GetCount());
- m_pTE->DefaultDuration.Set(vih->hdr.AvgTimePerFrame * 100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(vih->hdr.bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(vih->hdr.bmiHeader.biHeight));
- // m_pTE->v.DisplayWidth.Set(vih->dwPictAspectRatioX);
- // m_pTE->v.DisplayHeight.Set(vih->dwPictAspectRatioY);
- if(vih->hdr.AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->hdr.AvgTimePerFrame));
-
- hr = S_OK;
- }
- /*
- else if(m_mt.formattype == FORMAT_MPEGVideo)
- {
- m_pTE->CodecID.Set("V_DSHOW/MPEG1VIDEO"); // V_MPEG1
-
- MPEG1VIDEOINFO* pm1vi = (MPEG1VIDEOINFO*)m_mt.pbFormat;
- m_pTE->CodecPrivate.SetCount(m_mt.FormatLength());
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat, m_pTE->CodecPrivate.GetCount());
- m_pTE->DefaultDuration.Set(pm1vi->hdr.AvgTimePerFrame*100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(pm1vi->hdr.bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(pm1vi->hdr.bmiHeader.biHeight));
- if(pm1vi->hdr.AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / pm1vi->hdr.AvgTimePerFrame));
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_MPEG2_VIDEO)
- {
- m_pTE->CodecID.Set("V_DSHOW/MPEG2VIDEO"); // V_MPEG2
-
- MPEG2VIDEOINFO* pm2vi = (MPEG2VIDEOINFO*)m_mt.pbFormat;
- m_pTE->CodecPrivate.SetCount(m_mt.FormatLength());
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat, m_pTE->CodecPrivate.GetCount());
- m_pTE->DefaultDuration.Set(pm2vi->hdr.AvgTimePerFrame*100);
- m_pTE->DescType = TrackEntry::DescVideo;
- m_pTE->v.PixelWidth.Set(pm2vi->hdr.bmiHeader.biWidth);
- m_pTE->v.PixelHeight.Set(abs(pm2vi->hdr.bmiHeader.biHeight));
- if(pm2vi->hdr.AvgTimePerFrame > 0)
- m_pTE->v.FramePerSec.Set((float)(10000000.0 / pm2vi->hdr.AvgTimePerFrame));
-
- hr = S_OK;
- }
- */
- }
- else if(m_mt.majortype == MEDIATYPE_Audio)
- {
- m_pTE->TrackType.Set(TrackEntry::TypeAudio);
-
- if(m_mt.formattype == FORMAT_WaveFormatEx
- && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_AAC
- && m_mt.cbFormat >= sizeof(WAVEFORMATEX) + 2)
- {
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- BYTE* p = (BYTE*)(wfe + 1);
-
- DWORD nSamplesPerSec = wfe->nSamplesPerSec;
-
- int profile = (p[0] >> 3) - 1;
- int rate1 = ((p[0] & 7) << 1) | (p[1] >> 7);
- int channels = ((p[1] >> 3) & 15);
- int exttype = 0;
- int rate2 = rate1;
-
- if(wfe->cbSize >= 5)
- {
- profile = 4;
-
- exttype = (p[2] << 3) | (p[3] >> 5);
- ASSERT(exttype == 0x2B7);
- ASSERT((p[3] & 31) == 5);
- ASSERT((p[4] >> 7) == 1);
- rate2 = ((p[4] >> 3) & 15);
-
- if(rate2 < rate1)
- {
- m_pTE->a.OutputSamplingFrequency.Set((float)nSamplesPerSec);
- nSamplesPerSec /= 2;
- }
- }
-
- switch(profile)
- {
- default:
- case 0:
- m_pTE->CodecID.Set("A_AAC/MPEG2/MAIN");
- break;
- case 1:
- m_pTE->CodecID.Set("A_AAC/MPEG2/LC");
- break;
- case 2:
- m_pTE->CodecID.Set("A_AAC/MPEG2/SSR");
- break;
- case 3:
- m_pTE->CodecID.Set("A_AAC/MPEG4/LTP");
- break;
- case 4:
- m_pTE->CodecID.Set("A_AAC/MPEG4/LC/SBR");
- break;
- }
-
- ASSERT(channels == wfe->nChannels);
-
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)nSamplesPerSec);
- m_pTE->a.Channels.Set(channels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_WaveFormatEx
- && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3)
- {
- m_pTE->CodecID.Set("A_AC3");
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
- m_pTE->a.Channels.Set(wfe->nChannels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_WaveFormatEx
- && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_DVD_DTS)
- {
- m_pTE->CodecID.Set("A_DTS");
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
- m_pTE->a.Channels.Set(wfe->nChannels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_WaveFormatEx
- && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_FLAC)
- {
- m_pTE->CodecID.Set("A_FLAC");
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
- m_pTE->a.Channels.Set(wfe->nChannels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- if(wfe->cbSize)
- {
- m_pTE->CodecPrivate.SetCount(wfe->cbSize);
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + sizeof(WAVEFORMATEX), wfe->cbSize);
- }
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_WaveFormatEx
- && (m_mt.subtype == MEDIASUBTYPE_14_4
- || m_mt.subtype == MEDIASUBTYPE_28_8
- || m_mt.subtype == MEDIASUBTYPE_ATRC
- || m_mt.subtype == MEDIASUBTYPE_COOK
- || m_mt.subtype == MEDIASUBTYPE_DNET
- || m_mt.subtype == MEDIASUBTYPE_SIPR))
- {
- CStringA id;
- id.Format("A_REAL/%c%c%c%c",
- (char)((m_mt.subtype.Data1 >> 0) & 0xff),
- (char)((m_mt.subtype.Data1 >> 8) & 0xff),
- (char)((m_mt.subtype.Data1 >> 16) & 0xff),
- (char)((m_mt.subtype.Data1 >> 24) & 0xff));
-
- m_pTE->CodecID.Set(id);
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- DWORD cbSize = sizeof(WAVEFORMATEX) + wfe->cbSize;
- if(m_mt.cbFormat > cbSize)
- {
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - cbSize);
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + cbSize, m_pTE->CodecPrivate.GetCount());
- }
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
- m_pTE->a.Channels.Set(wfe->nChannels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_WaveFormatEx
- && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_PCM)
- {
- m_pTE->CodecID.Set("A_PCM/INT/LIT");
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
- m_pTE->a.Channels.Set(wfe->nChannels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_WaveFormatEx)
- {
- m_pTE->CodecID.Set("A_MS/ACM");
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat);
- memcpy(m_pTE->CodecPrivate, wfe, m_pTE->CodecPrivate.GetCount());
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
- m_pTE->a.Channels.Set(wfe->nChannels);
- m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_VorbisFormat)
- {
- m_pTE->CodecID.Set("A_VORBIS");
-
- VORBISFORMAT* pvf = (VORBISFORMAT*)m_mt.pbFormat;
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)pvf->nSamplesPerSec);
- m_pTE->a.Channels.Set(pvf->nChannels);
-
- // m_pTE->CodecPrivate will be filled later
-
- hr = S_OK;
- }
- else if(m_mt.formattype == FORMAT_VorbisFormat2)
- {
- m_pTE->CodecID.Set("A_VORBIS");
-
- VORBISFORMAT2* pvf2 = (VORBISFORMAT2*)m_mt.pbFormat;
- m_pTE->DescType = TrackEntry::DescAudio;
- m_pTE->a.SamplingFrequency.Set((float)pvf2->SamplesPerSec);
- m_pTE->a.Channels.Set(pvf2->Channels);
- m_pTE->a.BitDepth.Set(pvf2->BitsPerSample);
-
- int len = 1;
- for(int i = 0; i < 2; i++) len += pvf2->HeaderSize[i] / 255 + 1;
- for(int i = 0; i < 3; i++) len += pvf2->HeaderSize[i];
- m_pTE->CodecPrivate.SetCount(len);
-
- BYTE* src = (BYTE*)m_mt.pbFormat + sizeof(VORBISFORMAT2);
- BYTE* dst = m_pTE->CodecPrivate.GetData();
-
- *dst++ = 2;
- for(int i = 0; i < 2; i++)
- for(int len = pvf2->HeaderSize[i]; len >= 0; len -= 255)
- * dst++ = min(len, 255);
-
- memcpy(dst, src, pvf2->HeaderSize[0]);
- dst += pvf2->HeaderSize[0];
- src += pvf2->HeaderSize[0];
- memcpy(dst, src, pvf2->HeaderSize[1]);
- dst += pvf2->HeaderSize[1];
- src += pvf2->HeaderSize[1];
- memcpy(dst, src, pvf2->HeaderSize[2]);
- dst += pvf2->HeaderSize[2];
- src += pvf2->HeaderSize[2];
-
- ASSERT(src <= m_mt.pbFormat + m_mt.cbFormat);
- ASSERT(dst <= m_pTE->CodecPrivate.GetData() + m_pTE->CodecPrivate.GetCount());
-
- hr = S_OK;
- }
- }
- else if(m_mt.majortype == MEDIATYPE_Text)
- {
- m_pTE->TrackType.Set(TrackEntry::TypeSubtitle);
-
- if(m_mt.formattype == FORMAT_None)
- {
- m_pTE->CodecID.Set("S_TEXT/ASCII");
- hr = S_OK;
- }
- }
- else if(m_mt.majortype == MEDIATYPE_Subtitle)
- {
- m_pTE->TrackType.Set(TrackEntry::TypeSubtitle);
-
- m_pTE->CodecID.Set(
- m_mt.subtype == MEDIASUBTYPE_UTF8 ? "S_TEXT/UTF8" :
- m_mt.subtype == MEDIASUBTYPE_SSA ? "S_TEXT/SSA" :
- m_mt.subtype == MEDIASUBTYPE_ASS ? "S_TEXT/ASS" :
- m_mt.subtype == MEDIASUBTYPE_USF ? "S_TEXT/USF" :
- m_mt.subtype == MEDIASUBTYPE_VOBSUB ? "S_VOBSUB" :
- "");
-
- if(!m_pTE->CodecID.IsEmpty())
- {
- hr = S_OK;
-
- SUBTITLEINFO* psi = (SUBTITLEINFO*)m_mt.pbFormat;
- if(psi->dwOffset)
- {
- m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - psi->dwOffset);
- memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + psi->dwOffset, m_pTE->CodecPrivate.GetCount());
- }
- }
- }
-
- if(S_OK == hr)
- {
- (static_cast<CMatroskaMuxerFilter*>(m_pFilter))->AddInput();
- }
-
- return hr;
+ HRESULT hr;
+
+ if(FAILED(hr = __super::CompleteConnect(pPin)))
+ return hr;
+
+ m_rtDur = 0;
+ CComQIPtr<IMediaSeeking> pMS;
+ if((pMS = GetFilterFromPin(pPin)) || (pMS = pPin))
+ pMS->GetDuration(&m_rtDur);
+
+ m_pTE.Free();
+ m_pTE.Attach(DNew TrackEntry());
+
+ m_pTE->TrackUID.Set(rand());
+ m_pTE->MinCache.Set(1);
+ m_pTE->MaxCache.Set(1);
+ m_pTE->TrackNumber.Set((static_cast<CMatroskaMuxerFilter*>(m_pFilter))->GetTrackNumber(this));
+
+ hr = E_FAIL;
+
+ if(m_mt.majortype == MEDIATYPE_Video)
+ {
+ m_pTE->TrackType.Set(TrackEntry::TypeVideo);
+
+ if(m_mt.formattype == FORMAT_VideoInfo
+ && m_mt.subtype == MEDIASUBTYPE_RV10 || m_mt.subtype == MEDIASUBTYPE_RV20
+ || m_mt.subtype == MEDIASUBTYPE_RV30 || m_mt.subtype == MEDIASUBTYPE_RV40)
+ {
+ m_pTE->CodecID.Set("V_REAL/RV00");
+ m_pTE->CodecID.SetAt(9, (BYTE)(m_mt.subtype.Data1>>16));
+
+ if(m_mt.formattype == FORMAT_VideoInfo)
+ {
+ VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_mt.pbFormat;
+ if(m_mt.cbFormat > sizeof(VIDEOINFOHEADER))
+ {
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - sizeof(VIDEOINFOHEADER));
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + sizeof(VIDEOINFOHEADER), m_pTE->CodecPrivate.GetCount());
+ }
+ m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
+ if(vih->AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
+ }
+ else if(m_mt.formattype == FORMAT_VideoInfo2)
+ {
+ VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)m_mt.pbFormat;
+ if(m_mt.cbFormat > sizeof(VIDEOINFOHEADER2))
+ {
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - sizeof(VIDEOINFOHEADER2));
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + sizeof(VIDEOINFOHEADER2), m_pTE->CodecPrivate.GetCount());
+ }
+ m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
+ if(vih->AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
+ m_pTE->v.DisplayWidth.Set(vih->dwPictAspectRatioX);
+ m_pTE->v.DisplayHeight.Set(vih->dwPictAspectRatioY);
+ }
+ else
+ {
+ ASSERT(0);
+ return hr;
+ }
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_VideoInfo)
+ {
+ m_pTE->CodecID.Set("V_MS/VFW/FOURCC");
+
+ VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_mt.pbFormat;
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader));
+ memcpy(m_pTE->CodecPrivate, &vih->bmiHeader, m_pTE->CodecPrivate.GetCount());
+ m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
+ if(vih->AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_VideoInfo2)
+ {
+ m_pTE->CodecID.Set("V_MS/VFW/FOURCC");
+
+ VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)m_mt.pbFormat;
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader));
+ memcpy(m_pTE->CodecPrivate, &vih->bmiHeader, m_pTE->CodecPrivate.GetCount());
+ m_pTE->DefaultDuration.Set(vih->AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(vih->bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(vih->bmiHeader.biHeight));
+ m_pTE->v.DisplayWidth.Set(vih->dwPictAspectRatioX);
+ m_pTE->v.DisplayHeight.Set(vih->dwPictAspectRatioY);
+ if(vih->AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->AvgTimePerFrame));
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_DiracVideoInfo)
+ {
+ m_pTE->CodecID.Set("V_DIRAC");
+
+ DIRACINFOHEADER* vih = (DIRACINFOHEADER*)m_mt.pbFormat;
+ m_pTE->CodecPrivate.SetCount(vih->cbSequenceHeader);
+ memcpy(m_pTE->CodecPrivate, (BYTE*)&vih->dwSequenceHeader[0], m_pTE->CodecPrivate.GetCount());
+ m_pTE->DefaultDuration.Set(vih->hdr.AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(vih->hdr.bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(vih->hdr.bmiHeader.biHeight));
+ // m_pTE->v.DisplayWidth.Set(vih->dwPictAspectRatioX);
+ // m_pTE->v.DisplayHeight.Set(vih->dwPictAspectRatioY);
+ if(vih->hdr.AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / vih->hdr.AvgTimePerFrame));
+
+ hr = S_OK;
+ }
+/*
+ else if(m_mt.formattype == FORMAT_MPEGVideo)
+ {
+ m_pTE->CodecID.Set("V_DSHOW/MPEG1VIDEO"); // V_MPEG1
+
+ MPEG1VIDEOINFO* pm1vi = (MPEG1VIDEOINFO*)m_mt.pbFormat;
+ m_pTE->CodecPrivate.SetCount(m_mt.FormatLength());
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat, m_pTE->CodecPrivate.GetCount());
+ m_pTE->DefaultDuration.Set(pm1vi->hdr.AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(pm1vi->hdr.bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(pm1vi->hdr.bmiHeader.biHeight));
+ if(pm1vi->hdr.AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / pm1vi->hdr.AvgTimePerFrame));
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_MPEG2_VIDEO)
+ {
+ m_pTE->CodecID.Set("V_DSHOW/MPEG2VIDEO"); // V_MPEG2
+
+ MPEG2VIDEOINFO* pm2vi = (MPEG2VIDEOINFO*)m_mt.pbFormat;
+ m_pTE->CodecPrivate.SetCount(m_mt.FormatLength());
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat, m_pTE->CodecPrivate.GetCount());
+ m_pTE->DefaultDuration.Set(pm2vi->hdr.AvgTimePerFrame*100);
+ m_pTE->DescType = TrackEntry::DescVideo;
+ m_pTE->v.PixelWidth.Set(pm2vi->hdr.bmiHeader.biWidth);
+ m_pTE->v.PixelHeight.Set(abs(pm2vi->hdr.bmiHeader.biHeight));
+ if(pm2vi->hdr.AvgTimePerFrame > 0)
+ m_pTE->v.FramePerSec.Set((float)(10000000.0 / pm2vi->hdr.AvgTimePerFrame));
+
+ hr = S_OK;
+ }
+*/
+ }
+ else if(m_mt.majortype == MEDIATYPE_Audio)
+ {
+ m_pTE->TrackType.Set(TrackEntry::TypeAudio);
+
+ if(m_mt.formattype == FORMAT_WaveFormatEx
+ && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_AAC
+ && m_mt.cbFormat >= sizeof(WAVEFORMATEX)+2)
+ {
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ BYTE* p = (BYTE*)(wfe+1);
+
+ DWORD nSamplesPerSec = wfe->nSamplesPerSec;
+
+ int profile = (p[0]>>3)-1;
+ int rate1 = ((p[0]&7)<<1)|(p[1]>>7);
+ int channels = ((p[1]>>3)&15);
+ int exttype = 0;
+ int rate2 = rate1;
+
+ if(wfe->cbSize >= 5)
+ {
+ profile = 4;
+
+ exttype = (p[2]<<3)|(p[3]>>5);
+ ASSERT(exttype == 0x2B7);
+ ASSERT((p[3]&31) == 5);
+ ASSERT((p[4]>>7) == 1);
+ rate2 = ((p[4]>>3)&15);
+
+ if(rate2 < rate1)
+ {
+ m_pTE->a.OutputSamplingFrequency.Set((float)nSamplesPerSec);
+ nSamplesPerSec /= 2;
+ }
+ }
+
+ switch(profile)
+ {
+ default:
+ case 0: m_pTE->CodecID.Set("A_AAC/MPEG2/MAIN"); break;
+ case 1: m_pTE->CodecID.Set("A_AAC/MPEG2/LC"); break;
+ case 2: m_pTE->CodecID.Set("A_AAC/MPEG2/SSR"); break;
+ case 3: m_pTE->CodecID.Set("A_AAC/MPEG4/LTP"); break;
+ case 4: m_pTE->CodecID.Set("A_AAC/MPEG4/LC/SBR"); break;
+ }
+
+ ASSERT(channels == wfe->nChannels);
+
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)nSamplesPerSec);
+ m_pTE->a.Channels.Set(channels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_WaveFormatEx
+ && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3)
+ {
+ m_pTE->CodecID.Set("A_AC3");
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
+ m_pTE->a.Channels.Set(wfe->nChannels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_WaveFormatEx
+ && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_DVD_DTS)
+ {
+ m_pTE->CodecID.Set("A_DTS");
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
+ m_pTE->a.Channels.Set(wfe->nChannels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_WaveFormatEx
+ && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_FLAC)
+ {
+ m_pTE->CodecID.Set("A_FLAC");
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
+ m_pTE->a.Channels.Set(wfe->nChannels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ if(wfe->cbSize)
+ {
+ m_pTE->CodecPrivate.SetCount(wfe->cbSize);
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + sizeof(WAVEFORMATEX), wfe->cbSize);
+ }
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_WaveFormatEx
+ && (m_mt.subtype == MEDIASUBTYPE_14_4
+ || m_mt.subtype == MEDIASUBTYPE_28_8
+ || m_mt.subtype == MEDIASUBTYPE_ATRC
+ || m_mt.subtype == MEDIASUBTYPE_COOK
+ || m_mt.subtype == MEDIASUBTYPE_DNET
+ || m_mt.subtype == MEDIASUBTYPE_SIPR))
+ {
+ CStringA id;
+ id.Format("A_REAL/%c%c%c%c",
+ (char)((m_mt.subtype.Data1>>0)&0xff),
+ (char)((m_mt.subtype.Data1>>8)&0xff),
+ (char)((m_mt.subtype.Data1>>16)&0xff),
+ (char)((m_mt.subtype.Data1>>24)&0xff));
+
+ m_pTE->CodecID.Set(id);
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ DWORD cbSize = sizeof(WAVEFORMATEX) + wfe->cbSize;
+ if(m_mt.cbFormat > cbSize)
+ {
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - cbSize);
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + cbSize, m_pTE->CodecPrivate.GetCount());
+ }
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
+ m_pTE->a.Channels.Set(wfe->nChannels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_WaveFormatEx
+ && ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_PCM)
+ {
+ m_pTE->CodecID.Set("A_PCM/INT/LIT");
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
+ m_pTE->a.Channels.Set(wfe->nChannels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_WaveFormatEx)
+ {
+ m_pTE->CodecID.Set("A_MS/ACM");
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat);
+ memcpy(m_pTE->CodecPrivate, wfe, m_pTE->CodecPrivate.GetCount());
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)wfe->nSamplesPerSec);
+ m_pTE->a.Channels.Set(wfe->nChannels);
+ m_pTE->a.BitDepth.Set(wfe->wBitsPerSample);
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_VorbisFormat)
+ {
+ m_pTE->CodecID.Set("A_VORBIS");
+
+ VORBISFORMAT* pvf = (VORBISFORMAT*)m_mt.pbFormat;
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)pvf->nSamplesPerSec);
+ m_pTE->a.Channels.Set(pvf->nChannels);
+
+ // m_pTE->CodecPrivate will be filled later
+
+ hr = S_OK;
+ }
+ else if(m_mt.formattype == FORMAT_VorbisFormat2)
+ {
+ m_pTE->CodecID.Set("A_VORBIS");
+
+ VORBISFORMAT2* pvf2 = (VORBISFORMAT2*)m_mt.pbFormat;
+ m_pTE->DescType = TrackEntry::DescAudio;
+ m_pTE->a.SamplingFrequency.Set((float)pvf2->SamplesPerSec);
+ m_pTE->a.Channels.Set(pvf2->Channels);
+ m_pTE->a.BitDepth.Set(pvf2->BitsPerSample);
+
+ int len = 1;
+ for(int i = 0; i < 2; i++) len += pvf2->HeaderSize[i]/255 + 1;
+ for(int i = 0; i < 3; i++) len += pvf2->HeaderSize[i];
+ m_pTE->CodecPrivate.SetCount(len);
+
+ BYTE* src = (BYTE*)m_mt.pbFormat + sizeof(VORBISFORMAT2);
+ BYTE* dst = m_pTE->CodecPrivate.GetData();
+
+ *dst++ = 2;
+ for(int i = 0; i < 2; i++)
+ for(int len = pvf2->HeaderSize[i]; len >= 0; len -= 255)
+ *dst++ = min(len, 255);
+
+ memcpy(dst, src, pvf2->HeaderSize[0]);
+ dst += pvf2->HeaderSize[0];
+ src += pvf2->HeaderSize[0];
+ memcpy(dst, src, pvf2->HeaderSize[1]);
+ dst += pvf2->HeaderSize[1];
+ src += pvf2->HeaderSize[1];
+ memcpy(dst, src, pvf2->HeaderSize[2]);
+ dst += pvf2->HeaderSize[2];
+ src += pvf2->HeaderSize[2];
+
+ ASSERT(src <= m_mt.pbFormat + m_mt.cbFormat);
+ ASSERT(dst <= m_pTE->CodecPrivate.GetData() + m_pTE->CodecPrivate.GetCount());
+
+ hr = S_OK;
+ }
+ }
+ else if(m_mt.majortype == MEDIATYPE_Text)
+ {
+ m_pTE->TrackType.Set(TrackEntry::TypeSubtitle);
+
+ if(m_mt.formattype == FORMAT_None)
+ {
+ m_pTE->CodecID.Set("S_TEXT/ASCII");
+ hr = S_OK;
+ }
+ }
+ else if(m_mt.majortype == MEDIATYPE_Subtitle)
+ {
+ m_pTE->TrackType.Set(TrackEntry::TypeSubtitle);
+
+ m_pTE->CodecID.Set(
+ m_mt.subtype == MEDIASUBTYPE_UTF8 ? "S_TEXT/UTF8" :
+ m_mt.subtype == MEDIASUBTYPE_SSA ? "S_TEXT/SSA" :
+ m_mt.subtype == MEDIASUBTYPE_ASS ? "S_TEXT/ASS" :
+ m_mt.subtype == MEDIASUBTYPE_USF ? "S_TEXT/USF" :
+ m_mt.subtype == MEDIASUBTYPE_VOBSUB ? "S_VOBSUB" :
+ "");
+
+ if(!m_pTE->CodecID.IsEmpty())
+ {
+ hr = S_OK;
+
+ SUBTITLEINFO* psi = (SUBTITLEINFO*)m_mt.pbFormat;
+ if(psi->dwOffset)
+ {
+ m_pTE->CodecPrivate.SetCount(m_mt.cbFormat - psi->dwOffset);
+ memcpy(m_pTE->CodecPrivate, m_mt.pbFormat + psi->dwOffset, m_pTE->CodecPrivate.GetCount());
+ }
+ }
+ }
+
+ if(S_OK == hr)
+ {
+ (static_cast<CMatroskaMuxerFilter*>(m_pFilter))->AddInput();
+ }
+
+ return hr;
}
HRESULT CMatroskaMuxerInputPin::Active()
{
- m_fActive = true;
- m_rtLastStart = m_rtLastStop = -1;
- m_fEndOfStreamReceived = false;
- return __super::Active();
+ m_fActive = true;
+ m_rtLastStart = m_rtLastStop = -1;
+ m_fEndOfStreamReceived = false;
+ return __super::Active();
}
HRESULT CMatroskaMuxerInputPin::Inactive()
{
- m_fActive = false;
- CAutoLock cAutoLock(&m_csQueue);
- m_blocks.RemoveAll();
- m_pVorbisHdrs.RemoveAll();
- return __super::Inactive();
+ m_fActive = false;
+ CAutoLock cAutoLock(&m_csQueue);
+ m_blocks.RemoveAll();
+ m_pVorbisHdrs.RemoveAll();
+ return __super::Inactive();
}
STDMETHODIMP CMatroskaMuxerInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- CAutoLock cAutoLock(&m_csReceive);
- return __super::NewSegment(tStart, tStop, dRate);
+ CAutoLock cAutoLock(&m_csReceive);
+ return __super::NewSegment(tStart, tStop, dRate);
}
STDMETHODIMP CMatroskaMuxerInputPin::BeginFlush()
{
- return __super::BeginFlush();
+ return __super::BeginFlush();
}
STDMETHODIMP CMatroskaMuxerInputPin::EndFlush()
{
- return __super::EndFlush();
+ return __super::EndFlush();
}
STDMETHODIMP CMatroskaMuxerInputPin::Receive(IMediaSample* pSample)
{
- if(m_fEndOfStreamReceived)
- {
- /*ASSERT(0);*/ return S_FALSE;
- }
+ if(m_fEndOfStreamReceived) {/*ASSERT(0);*/ return S_FALSE;}
- CAutoLock cAutoLock(&m_csReceive);
+ CAutoLock cAutoLock(&m_csReceive);
- while(m_fActive)
- {
- {
- CAutoLock cAutoLock2(&m_csQueue);
- if(m_blocks.GetCount() < MAXBLOCKS)
- break;
- }
+ while(m_fActive)
+ {
+ {
+ CAutoLock cAutoLock2(&m_csQueue);
+ if(m_blocks.GetCount() < MAXBLOCKS)
+ break;
+ }
- Sleep(1);
- }
+ Sleep(1);
+ }
- if(!m_fActive) return S_FALSE;
+ if(!m_fActive) return S_FALSE;
- HRESULT hr;
+ HRESULT hr;
- if(FAILED(hr = __super::Receive(pSample)))
- return hr;
+ if(FAILED(hr = __super::Receive(pSample)))
+ return hr;
- BYTE* pData = NULL;
- pSample->GetPointer(&pData);
+ BYTE* pData = NULL;
+ pSample->GetPointer(&pData);
- long len = pSample->GetActualDataLength();
+ long len = pSample->GetActualDataLength();
- REFERENCE_TIME rtStart = -1, rtStop = -1;
- hr = pSample->GetTime(&rtStart, &rtStop);
+ REFERENCE_TIME rtStart = -1, rtStop = -1;
+ hr = pSample->GetTime(&rtStart, &rtStop);
- if(FAILED(hr) || rtStart == -1 || rtStop == -1)
- {
- TRACE(_T("No timestamp was set on the sample!!!"));
- m_pFilter->NotifyEvent(EC_ERRORABORT, VFW_E_SAMPLE_TIME_NOT_SET, 0);
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
+ if(FAILED(hr) || rtStart == -1 || rtStop == -1)
+ {
+ TRACE(_T("No timestamp was set on the sample!!!"));
+ m_pFilter->NotifyEvent(EC_ERRORABORT, VFW_E_SAMPLE_TIME_NOT_SET, 0);
+ return VFW_E_SAMPLE_TIME_NOT_SET;
+ }
// rtStart += m_tStart;
// rtStop += m_tStart;
- /**/
- TRACE(_T("Received (%d): %I64d-%I64d (c=%d, co=%dms), len=%d, d%d p%d s%d\n"),
- (static_cast<CMatroskaMuxerFilter*>(m_pFilter))->GetTrackNumber(this),
- rtStart, rtStop, (int)((rtStart / 10000) / MAXCLUSTERTIME), (int)((rtStart / 10000) % MAXCLUSTERTIME),
- len,
- pSample->IsDiscontinuity() == S_OK ? 1 : 0,
- pSample->IsPreroll() == S_OK ? 1 : 0,
- pSample->IsSyncPoint() == S_OK ? 1 : 0);
-
- if(m_mt.subtype == MEDIASUBTYPE_Vorbis && m_pVorbisHdrs.GetCount() < 3)
- {
- CAutoPtr<CBinary> data(DNew CBinary(0));
- data->SetCount(len);
- memcpy(data->GetData(), pData, len);
- m_pVorbisHdrs.Add(data);
-
- if(m_pVorbisHdrs.GetCount() == 3)
- {
- int len = 1;
- for(int i = 0; i < 2; i++) len += m_pVorbisHdrs[i]->GetCount() / 255 + 1;
- for(int i = 0; i < 3; i++) len += m_pVorbisHdrs[i]->GetCount();
- m_pTE->CodecPrivate.SetCount(len);
-
- BYTE* dst = m_pTE->CodecPrivate.GetData();
-
- *dst++ = 2;
- for(int i = 0; i < 2; i++)
- for(int len = m_pVorbisHdrs[i]->GetCount(); len >= 0; len -= 255)
- * dst++ = min(len, 255);
-
- for(int i = 0; i < 3; i++)
- {
- memcpy(dst, m_pVorbisHdrs[i]->GetData(), m_pVorbisHdrs[i]->GetCount());
- dst += m_pVorbisHdrs[i]->GetCount();
- }
- }
-
- return S_OK;
- }
-
- if(m_mt.formattype == FORMAT_WaveFormatEx
- && (((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_PCM
- || ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_MPEGLAYER3))
- pSample->SetSyncPoint(TRUE); // HACK: some capture filters don't set this
-
- CAutoPtr<BlockGroup> b(DNew BlockGroup());
- /*
- // TODO: test this with a longer capture (pcm, mp3)
- if(S_OK == pSample->IsSyncPoint() && rtStart < m_rtLastStart)
- {
- TRACE(_T("!!! timestamp went backwards, dropping this frame !!! rtStart (%I64) < m_rtLastStart (%I64)"), rtStart, m_rtLastStart);
- return S_OK;
- }
- */
- if((S_OK != pSample->IsSyncPoint() || m_rtLastStart == rtStart) && m_rtLastStart >= 0 /*&& m_rtLastStart < rtStart*/)
- {
- ASSERT(m_rtLastStart - rtStart <= 0);
- REFERENCE_TIME rtDiff = m_rtLastStart - rtStart;
- b->ReferenceBlock.Set((rtDiff + (rtDiff >= 0 ? 5000 : -5000)) / 10000);
- }
-
- b->Block.TrackNumber = (static_cast<CMatroskaMuxerFilter*>(m_pFilter))->GetTrackNumber(this);
-
- b->Block.TimeCode = (rtStart + 5000) / 10000;
- b->Block.TimeCodeStop = (rtStop + 5000) / 10000;
-
- if(m_pTE->TrackType == TrackEntry::TypeSubtitle)
- {
- b->BlockDuration.Set((rtStop - rtStart + 5000) / 10000);
- }
-
- CAutoPtr<CBinary> data(DNew CBinary(0));
- data->SetCount(len);
- memcpy(data->GetData(), pData, len);
- b->Block.BlockData.AddTail(data);
-
- CAutoLock cAutoLock2(&m_csQueue);
- m_blocks.AddTail(b); // TODO: lacing for audio
-
- m_rtLastStart = rtStart;
- m_rtLastStop = rtStop;
-
- return S_OK;
+/**/
+ TRACE(_T("Received (%d): %I64d-%I64d (c=%d, co=%dms), len=%d, d%d p%d s%d\n"),
+ (static_cast<CMatroskaMuxerFilter*>(m_pFilter))->GetTrackNumber(this),
+ rtStart, rtStop, (int)((rtStart/10000)/MAXCLUSTERTIME), (int)((rtStart/10000)%MAXCLUSTERTIME),
+ len,
+ pSample->IsDiscontinuity() == S_OK ? 1 : 0,
+ pSample->IsPreroll() == S_OK ? 1 : 0,
+ pSample->IsSyncPoint() == S_OK ? 1 : 0);
+
+ if(m_mt.subtype == MEDIASUBTYPE_Vorbis && m_pVorbisHdrs.GetCount() < 3)
+ {
+ CAutoPtr<CBinary> data(DNew CBinary(0));
+ data->SetCount(len);
+ memcpy(data->GetData(), pData, len);
+ m_pVorbisHdrs.Add(data);
+
+ if(m_pVorbisHdrs.GetCount() == 3)
+ {
+ int len = 1;
+ for(int i = 0; i < 2; i++) len += m_pVorbisHdrs[i]->GetCount()/255 + 1;
+ for(int i = 0; i < 3; i++) len += m_pVorbisHdrs[i]->GetCount();
+ m_pTE->CodecPrivate.SetCount(len);
+
+ BYTE* dst = m_pTE->CodecPrivate.GetData();
+
+ *dst++ = 2;
+ for(int i = 0; i < 2; i++)
+ for(int len = m_pVorbisHdrs[i]->GetCount(); len >= 0; len -= 255)
+ *dst++ = min(len, 255);
+
+ for(int i = 0; i < 3; i++)
+ {
+ memcpy(dst, m_pVorbisHdrs[i]->GetData(), m_pVorbisHdrs[i]->GetCount());
+ dst += m_pVorbisHdrs[i]->GetCount();
+ }
+ }
+
+ return S_OK;
+ }
+
+ if(m_mt.formattype == FORMAT_WaveFormatEx
+ && (((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_PCM
+ || ((WAVEFORMATEX*)m_mt.pbFormat)->wFormatTag == WAVE_FORMAT_MPEGLAYER3))
+ pSample->SetSyncPoint(TRUE); // HACK: some capture filters don't set this
+
+ CAutoPtr<BlockGroup> b(DNew BlockGroup());
+/*
+ // TODO: test this with a longer capture (pcm, mp3)
+ if(S_OK == pSample->IsSyncPoint() && rtStart < m_rtLastStart)
+ {
+ TRACE(_T("!!! timestamp went backwards, dropping this frame !!! rtStart (%I64) < m_rtLastStart (%I64)"), rtStart, m_rtLastStart);
+ return S_OK;
+ }
+*/
+ if((S_OK != pSample->IsSyncPoint() || m_rtLastStart == rtStart) && m_rtLastStart >= 0 /*&& m_rtLastStart < rtStart*/)
+ {
+ ASSERT(m_rtLastStart - rtStart <= 0);
+ REFERENCE_TIME rtDiff = m_rtLastStart - rtStart;
+ b->ReferenceBlock.Set((rtDiff + (rtDiff >= 0 ? 5000 : -5000)) / 10000);
+ }
+
+ b->Block.TrackNumber = (static_cast<CMatroskaMuxerFilter*>(m_pFilter))->GetTrackNumber(this);
+
+ b->Block.TimeCode = (rtStart + 5000) / 10000;
+ b->Block.TimeCodeStop = (rtStop + 5000) / 10000;
+
+ if(m_pTE->TrackType == TrackEntry::TypeSubtitle)
+ {
+ b->BlockDuration.Set((rtStop - rtStart + 5000) / 10000);
+ }
+
+ CAutoPtr<CBinary> data(DNew CBinary(0));
+ data->SetCount(len);
+ memcpy(data->GetData(), pData, len);
+ b->Block.BlockData.AddTail(data);
+
+ CAutoLock cAutoLock2(&m_csQueue);
+ m_blocks.AddTail(b); // TODO: lacing for audio
+
+ m_rtLastStart = rtStart;
+ m_rtLastStop = rtStop;
+
+ return S_OK;
}
STDMETHODIMP CMatroskaMuxerInputPin::EndOfStream()
{
- HRESULT hr;
+ HRESULT hr;
- if(FAILED(hr = __super::EndOfStream()))
- return hr;
+ if(FAILED(hr = __super::EndOfStream()))
+ return hr;
- CAutoLock cAutoLock(&m_csQueue);
+ CAutoLock cAutoLock(&m_csQueue);
- m_fEndOfStreamReceived = true;
+ m_fEndOfStreamReceived = true;
- return hr;
+ return hr;
}
//
@@ -1361,7 +1297,7 @@ STDMETHODIMP CMatroskaMuxerInputPin::EndOfStream()
//
CMatroskaMuxerOutputPin::CMatroskaMuxerOutputPin(TCHAR* pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseOutputPin(pName, pFilter, pLock, phr, L"Output")
+ : CBaseOutputPin(pName, pFilter, pLock, phr, L"Output")
{
}
@@ -1371,10 +1307,10 @@ CMatroskaMuxerOutputPin::~CMatroskaMuxerOutputPin()
STDMETHODIMP CMatroskaMuxerOutputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- return
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
HRESULT CMatroskaMuxerOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
@@ -1384,8 +1320,8 @@ HRESULT CMatroskaMuxerOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCAT
HRESULT hr = NOERROR;
- pProperties->cBuffers = 1;
- pProperties->cbBuffer = 1;
+ pProperties->cBuffers = 1;
+ pProperties->cbBuffer = 1;
ALLOCATOR_PROPERTIES Actual;
if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
@@ -1398,30 +1334,30 @@ HRESULT CMatroskaMuxerOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCAT
HRESULT CMatroskaMuxerOutputPin::CheckMediaType(const CMediaType* pmt)
{
- return pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_Matroska
- ? S_OK
- : E_INVALIDARG;
+ return pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_Matroska
+ ? S_OK
+ : E_INVALIDARG;
}
HRESULT CMatroskaMuxerOutputPin::GetMediaType(int iPosition, CMediaType* pmt)
{
CAutoLock cAutoLock(m_pLock);
- if(iPosition < 0) return E_INVALIDARG;
- if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
+ if(iPosition < 0) return E_INVALIDARG;
+ if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
- pmt->ResetFormatBuffer();
- pmt->InitMediaType();
- pmt->majortype = MEDIATYPE_Stream;
- pmt->subtype = MEDIASUBTYPE_Matroska;
- pmt->formattype = FORMAT_None;
+ pmt->ResetFormatBuffer();
+ pmt->InitMediaType();
+ pmt->majortype = MEDIATYPE_Stream;
+ pmt->subtype = MEDIASUBTYPE_Matroska;
+ pmt->formattype = FORMAT_None;
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CMatroskaMuxerOutputPin::Notify(IBaseFilter* pSender, Quality q)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
diff --git a/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.h b/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.h
index b89e92f02..68bcdd2e0 100644
--- a/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.h
+++ b/src/filters/muxer/MatroskaMuxer/MatroskaMuxer.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -30,52 +30,49 @@
class CMatroskaMuxerInputPin : public CBaseInputPin
{
- CAutoPtr<MatroskaWriter::TrackEntry> m_pTE;
- CAutoPtrArray<MatroskaWriter::CBinary> m_pVorbisHdrs;
+ CAutoPtr<MatroskaWriter::TrackEntry> m_pTE;
+ CAutoPtrArray<MatroskaWriter::CBinary> m_pVorbisHdrs;
- bool m_fActive;
- CCritSec m_csReceive;
+ bool m_fActive;
+ CCritSec m_csReceive;
- REFERENCE_TIME m_rtLastStart, m_rtLastStop;
+ REFERENCE_TIME m_rtLastStart, m_rtLastStop;
public:
- CMatroskaMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CMatroskaMuxerInputPin();
+ CMatroskaMuxerInputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CMatroskaMuxerInputPin();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- MatroskaWriter::TrackEntry* GetTrackEntry()
- {
- return m_pTE;
- }
+ MatroskaWriter::TrackEntry* GetTrackEntry() {return m_pTE;}
- REFERENCE_TIME m_rtDur;
+ REFERENCE_TIME m_rtDur;
- CCritSec m_csQueue;
- CAutoPtrList<MatroskaWriter::BlockGroup> m_blocks;
- bool m_fEndOfStreamReceived;
+ CCritSec m_csQueue;
+ CAutoPtrList<MatroskaWriter::BlockGroup> m_blocks;
+ bool m_fEndOfStreamReceived;
HRESULT CheckMediaType(const CMediaType* pmt);
HRESULT BreakConnect();
HRESULT CompleteConnect(IPin* pPin);
- HRESULT Active(), Inactive();
+ HRESULT Active(), Inactive();
STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
- STDMETHODIMP BeginFlush();
- STDMETHODIMP EndFlush();
+ STDMETHODIMP BeginFlush();
+ STDMETHODIMP EndFlush();
- STDMETHODIMP Receive(IMediaSample* pSample);
+ STDMETHODIMP Receive(IMediaSample* pSample);
STDMETHODIMP EndOfStream();
};
class CMatroskaMuxerOutputPin : public CBaseOutputPin
{
public:
- CMatroskaMuxerOutputPin(TCHAR* pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CMatroskaMuxerOutputPin();
+ CMatroskaMuxerOutputPin(TCHAR* pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CMatroskaMuxerOutputPin();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
@@ -83,80 +80,79 @@ public:
HRESULT CheckMediaType(const CMediaType* pmt);
HRESULT GetMediaType(int iPosition, CMediaType* pmt);
- STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
+ STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
};
[uuid("38E2D43D-915D-493C-B373-888DB16EE3DC")]
-interface IMatroskaMuxer :
-public IUnknown
+interface IMatroskaMuxer : public IUnknown
{
- STDMETHOD(CorrectTimeOffset)(bool fNegative, bool fPositive) = 0;
- // TODO: chapters
+ STDMETHOD (CorrectTimeOffset) (bool fNegative, bool fPositive) = 0;
+ // TODO: chapters
};
[uuid("1E1299A2-9D42-4F12-8791-D79E376F4143")]
class CMatroskaMuxerFilter
- : public CBaseFilter
- , public CCritSec
- , public CAMThread
- , public IAMFilterMiscFlags
- , public IMediaSeeking
- , public IMatroskaMuxer
+ : public CBaseFilter
+ , public CCritSec
+ , public CAMThread
+ , public IAMFilterMiscFlags
+ , public IMediaSeeking
+ , public IMatroskaMuxer
{
protected:
- CAutoPtrList<CMatroskaMuxerInputPin> m_pInputs;
- CAutoPtr<CMatroskaMuxerOutputPin> m_pOutput;
+ CAutoPtrList<CMatroskaMuxerInputPin> m_pInputs;
+ CAutoPtr<CMatroskaMuxerOutputPin> m_pOutput;
- REFERENCE_TIME m_rtCurrent;
+ REFERENCE_TIME m_rtCurrent;
- bool m_fNegative, m_fPositive;
+ bool m_fNegative, m_fPositive;
- enum {CMD_EXIT, CMD_RUN};
- DWORD ThreadProc();
+ enum {CMD_EXIT, CMD_RUN};
+ DWORD ThreadProc();
public:
- CMatroskaMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr);
- virtual ~CMatroskaMuxerFilter();
+ CMatroskaMuxerFilter(LPUNKNOWN pUnk, HRESULT* phr);
+ virtual ~CMatroskaMuxerFilter();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- void AddInput();
- UINT GetTrackNumber(CBasePin* pPin);
+ void AddInput();
+ UINT GetTrackNumber(CBasePin* pPin);
- int GetPinCount();
- CBasePin* GetPin(int n);
+ int GetPinCount();
+ CBasePin* GetPin(int n);
- STDMETHODIMP Stop();
- STDMETHODIMP Pause();
- STDMETHODIMP Run(REFERENCE_TIME tStart);
+ STDMETHODIMP Stop();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Run(REFERENCE_TIME tStart);
- // IAMFilterMiscFlags
+ // IAMFilterMiscFlags
- STDMETHODIMP_(ULONG) GetMiscFlags();
+ STDMETHODIMP_(ULONG) GetMiscFlags();
- // IMediaSeeking
+ // IMediaSeeking
- STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* pFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
- STDMETHODIMP GetTimeFormat(GUID* pFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
- STDMETHODIMP SetTimeFormat(const GUID* pFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
- STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
- STDMETHODIMP SetRate(double dRate);
- STDMETHODIMP GetRate(double* pdRate);
- STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+ STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+ STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+ STDMETHODIMP GetTimeFormat(GUID* pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+ STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+ STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+ STDMETHODIMP SetRate(double dRate);
+ STDMETHODIMP GetRate(double* pdRate);
+ STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
- // IMatroskaMuxer
+ // IMatroskaMuxer
- STDMETHODIMP CorrectTimeOffset(bool fNegative, bool fPositive);
+ STDMETHODIMP CorrectTimeOffset(bool fNegative, bool fPositive);
};
diff --git a/src/filters/muxer/MatroskaMuxer/resource.h b/src/filters/muxer/MatroskaMuxer/resource.h
index 22bd5aaf8..cfa5a212d 100644
--- a/src/filters/muxer/MatroskaMuxer/resource.h
+++ b/src/filters/muxer/MatroskaMuxer/resource.h
@@ -3,7 +3,7 @@
// Used by MatroskaMuxer.rc
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
diff --git a/src/filters/muxer/MatroskaMuxer/stdafx.cpp b/src/filters/muxer/MatroskaMuxer/stdafx.cpp
index 7f32a5e45..6927dbf9c 100644
--- a/src/filters/muxer/MatroskaMuxer/stdafx.cpp
+++ b/src/filters/muxer/MatroskaMuxer/stdafx.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/MatroskaMuxer/stdafx.h b/src/filters/muxer/MatroskaMuxer/stdafx.h
index 2bec11afc..22cb54295 100644
--- a/src/filters/muxer/MatroskaMuxer/stdafx.h
+++ b/src/filters/muxer/MatroskaMuxer/stdafx.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/WavDest/WavDest.cpp b/src/filters/muxer/WavDest/WavDest.cpp
index 5819b2cb8..ff3085f24 100644
--- a/src/filters/muxer/WavDest/WavDest.cpp
+++ b/src/filters/muxer/WavDest/WavDest.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -29,12 +29,12 @@
const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
{
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE},
};
const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
{
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
};
const AMOVIESETUP_PIN sudpPins[] =
@@ -45,7 +45,7 @@ const AMOVIESETUP_PIN sudpPins[] =
const AMOVIESETUP_FILTER sudFilter[] =
{
- {&__uuidof(CWavDestFilter), L"MPC - WavDest", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory}
+ {&__uuidof(CWavDestFilter), L"MPC - WavDest", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory}
};
CFactoryTemplate g_Templates[] =
@@ -57,12 +57,12 @@ int g_cTemplates = countof(g_Templates);
STDAPI DllRegisterServer()
{
- return AMovieDllRegisterServer2(TRUE);
+ return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
- return AMovieDllRegisterServer2(FALSE);
+ return AMovieDllRegisterServer2(FALSE);
}
#include "../../FilterApp.h"
@@ -76,7 +76,7 @@ CFilterApp theApp;
//
CWavDestFilter::CWavDestFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CTransformFilter(NAME("WavDest filter"), pUnk, __uuidof(this))
+ : CTransformFilter(NAME("WavDest filter"), pUnk, __uuidof(this))
{
if(SUCCEEDED(*phr))
{
@@ -88,10 +88,10 @@ CWavDestFilter::CWavDestFilter(LPUNKNOWN pUnk, HRESULT* phr)
else
{
*phr = E_OUTOFMEMORY;
- return;
+ return;
}
- if(CTransformInputPin* pIn = DNew CTransformInputPin(NAME("Transform input pin"), this, phr, L"In"))
+ if(CTransformInputPin* pIn = DNew CTransformInputPin(NAME("Transform input pin"), this, phr, L"In"))
{
if(SUCCEEDED(*phr)) m_pInput = pIn;
else delete pIn;
@@ -99,7 +99,7 @@ CWavDestFilter::CWavDestFilter(LPUNKNOWN pUnk, HRESULT* phr)
else
{
*phr = E_OUTOFMEMORY;
- return;
+ return;
}
}
}
@@ -120,7 +120,7 @@ HRESULT CWavDestFilter::Receive(IMediaSample* pSample)
// don't update the count if Deliver() downstream fails.
if(hr != S_OK)
- m_cbWavData = cbOld;
+ m_cbWavData = cbOld;
return hr;
}
@@ -128,15 +128,15 @@ HRESULT CWavDestFilter::Receive(IMediaSample* pSample)
HRESULT CWavDestFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
{
REFERENCE_TIME rtStart, rtEnd;
-
+
HRESULT hr = Copy(pIn, pOut);
if(FAILED(hr))
- return hr;
+ return hr;
// Prepare it for writing
LONG lActual = pOut->GetActualDataLength();
- if(m_cbWavData + m_cbHeader + lActual < m_cbWavData + m_cbHeader) // overflow
+ if(m_cbWavData + m_cbHeader + lActual < m_cbWavData + m_cbHeader ) // overflow
return E_FAIL;
rtStart = m_cbWavData + m_cbHeader;
@@ -144,7 +144,7 @@ HRESULT CWavDestFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
m_cbWavData += lActual;
EXECUTE_ASSERT(pOut->SetTime(&rtStart, &rtEnd) == S_OK);
-
+
return S_OK;
}
@@ -157,7 +157,7 @@ HRESULT CWavDestFilter::Copy(IMediaSample* pSource, IMediaSample* pDest) const
long lDestSize = pDest->GetSize();
ASSERT(lDestSize >= lSourceSize);
#endif
-
+
pSource->GetPointer(&pSourceBuffer);
pDest->GetPointer(&pDestBuffer);
@@ -167,11 +167,11 @@ HRESULT CWavDestFilter::Copy(IMediaSample* pSource, IMediaSample* pDest) const
REFERENCE_TIME TimeStart, TimeEnd;
if(NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
- pDest->SetTime(&TimeStart, &TimeEnd);
+ pDest->SetTime(&TimeStart, &TimeEnd);
LONGLONG MediaStart, MediaEnd;
if(pSource->GetMediaTime(&MediaStart, &MediaEnd) == NOERROR)
- pDest->SetMediaTime(&MediaStart, &MediaEnd);
+ pDest->SetMediaTime(&MediaStart, &MediaEnd);
// Copy the media type
AM_MEDIA_TYPE* pMediaType;
@@ -183,20 +183,20 @@ HRESULT CWavDestFilter::Copy(IMediaSample* pSource, IMediaSample* pDest) const
long lDataLength = pSource->GetActualDataLength();
pDest->SetActualDataLength(lDataLength);
- return NOERROR;
+ return NOERROR;
}
HRESULT CWavDestFilter::CheckInputType(const CMediaType* mtIn)
{
- return mtIn->formattype == FORMAT_WaveFormatEx ? S_OK : S_FALSE;
+ return mtIn->formattype == FORMAT_WaveFormatEx ? S_OK : S_FALSE;
}
HRESULT CWavDestFilter::GetMediaType(int iPosition, CMediaType* pMediaType)
{
ASSERT(iPosition == 0 || iPosition == 1);
- if(iPosition == 0)
- {
+ if(iPosition == 0)
+ {
pMediaType->SetType(&MEDIATYPE_Stream);
pMediaType->SetSubtype(&MEDIASUBTYPE_WAVE);
return S_OK;
@@ -208,40 +208,40 @@ HRESULT CWavDestFilter::GetMediaType(int iPosition, CMediaType* pMediaType)
HRESULT CWavDestFilter::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
{
if(m_pInput->IsConnected() == FALSE)
- return E_UNEXPECTED;
+ return E_UNEXPECTED;
ASSERT(pAlloc);
ASSERT(pProperties);
- HRESULT hr = NOERROR;
+ HRESULT hr = NOERROR;
pProperties->cBuffers = 1;
pProperties->cbAlign = 1;
-
+
CComPtr<IMemAllocator> pInAlloc;
ALLOCATOR_PROPERTIES InProps;
if(SUCCEEDED(hr = m_pInput->GetAllocator(&pInAlloc))
- && SUCCEEDED(hr = pInAlloc->GetProperties(&InProps)))
+ && SUCCEEDED(hr = pInAlloc->GetProperties(&InProps)))
{
- pProperties->cbBuffer = InProps.cbBuffer;
- }
- else
- {
- return hr;
+ pProperties->cbBuffer = InProps.cbBuffer;
}
+ else
+ {
+ return hr;
+ }
ASSERT(pProperties->cbBuffer);
ALLOCATOR_PROPERTIES Actual;
- if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual)))
- return hr;
+ if(FAILED(hr = pAlloc->SetProperties(pProperties,&Actual)))
+ return hr;
ASSERT(Actual.cBuffers == 1);
if(pProperties->cBuffers > Actual.cBuffers
- || pProperties->cbBuffer > Actual.cbBuffer)
- {
- return E_FAIL;
+ || pProperties->cbBuffer > Actual.cbBuffer)
+ {
+ return E_FAIL;
}
return NOERROR;
@@ -258,11 +258,11 @@ HRESULT CWavDestFilter::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPER
HRESULT CWavDestFilter::StartStreaming()
{
// leave space for the header
- m_cbHeader = sizeof(RIFFLIST) +
- sizeof(RIFFCHUNK) +
- m_pInput->CurrentMediaType().FormatLength() +
+ m_cbHeader = sizeof(RIFFLIST) +
+ sizeof(RIFFCHUNK) +
+ m_pInput->CurrentMediaType().FormatLength() +
sizeof(RIFFCHUNK);
-
+
m_cbWavData = 0;
return S_OK;
@@ -271,12 +271,12 @@ HRESULT CWavDestFilter::StartStreaming()
HRESULT CWavDestFilter::StopStreaming()
{
IStream* pStream;
- if(m_pOutput->IsConnected() == FALSE)
+ if (m_pOutput->IsConnected() == FALSE)
return E_FAIL;
IPin* pDwnstrmInputPin = m_pOutput->GetConnected();
- if(!pDwnstrmInputPin)
+ if (!pDwnstrmInputPin)
return E_FAIL;
HRESULT hr = ((IMemInputPin *) pDwnstrmInputPin)->QueryInterface(IID_IStream, (void **)&pStream);
@@ -301,10 +301,9 @@ HRESULT CWavDestFilter::StopStreaming()
LARGE_INTEGER li;
ZeroMemory(&li, sizeof(li));
-
+
hr = pStream->Seek(li, STREAM_SEEK_SET, 0);
- if(SUCCEEDED(hr))
- {
+ if(SUCCEEDED(hr)) {
hr = pStream->Write(pb, m_cbHeader, 0);
}
pStream->Release();
@@ -314,7 +313,7 @@ HRESULT CWavDestFilter::StopStreaming()
}
CWavDestOutputPin::CWavDestOutputPin(CTransformFilter* pFilter, HRESULT* phr)
- : CTransformOutputPin(NAME("WavDest output pin"), pFilter, phr, L"Out")
+ : CTransformOutputPin(NAME("WavDest output pin"), pFilter, phr, L"Out")
{
}
diff --git a/src/filters/muxer/WavDest/WavDest.h b/src/filters/muxer/WavDest/WavDest.h
index 2c1cb569a..84b054d32 100644
--- a/src/filters/muxer/WavDest/WavDest.h
+++ b/src/filters/muxer/WavDest/WavDest.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -39,7 +39,7 @@ public:
CWavDestFilter(LPUNKNOWN pUnk, HRESULT* pHr);
~CWavDestFilter();
- DECLARE_IUNKNOWN;
+ DECLARE_IUNKNOWN;
HRESULT Transform(IMediaSample* pIn, IMediaSample* pOut);
HRESULT Receive(IMediaSample* pSample);
diff --git a/src/filters/muxer/WavDest/stdafx.cpp b/src/filters/muxer/WavDest/stdafx.cpp
index c21a39cec..e9267f937 100644
--- a/src/filters/muxer/WavDest/stdafx.cpp
+++ b/src/filters/muxer/WavDest/stdafx.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/muxer/WavDest/stdafx.h b/src/filters/muxer/WavDest/stdafx.h
index 1d4063afa..2b6b600ac 100644
--- a/src/filters/muxer/WavDest/stdafx.h
+++ b/src/filters/muxer/WavDest/stdafx.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/