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:
authortetsuo55 <tetsuo55@users.sourceforge.net>2010-04-09 01:14:58 +0400
committertetsuo55 <tetsuo55@users.sourceforge.net>2010-04-09 01:14:58 +0400
commita9b7bf3fb3e1334d8defd05ca4cfae870b4912e5 (patch)
tree2dab453d94d5e003379a6cc895eceb84c80e23ec /src/filters/parser/MpegSplitter
parentaafd49a91f7c2fa9c7103971c16fa6e1b29e8bfd (diff)
astyle formatting cleanup to make the sourcecode more accessible
switch used: astyle --style=ansi --min-conditional-indent=0 --pad=oper --unpad=paren http://astyle.sourceforge.net/ git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1783 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser/MpegSplitter')
-rw-r--r--src/filters/parser/MpegSplitter/MpegSplitter.cpp2790
-rw-r--r--src/filters/parser/MpegSplitter/MpegSplitter.h78
-rw-r--r--src/filters/parser/MpegSplitter/MpegSplitterFile.cpp1400
-rw-r--r--src/filters/parser/MpegSplitter/MpegSplitterFile.h215
-rw-r--r--src/filters/parser/MpegSplitter/resource.h2
-rw-r--r--src/filters/parser/MpegSplitter/stdafx.cpp8
-rw-r--r--src/filters/parser/MpegSplitter/stdafx.h8
7 files changed, 2289 insertions, 2212 deletions
diff --git a/src/filters/parser/MpegSplitter/MpegSplitter.cpp b/src/filters/parser/MpegSplitter/MpegSplitter.cpp
index 732f23068..52021c8af 100644
--- a/src/filters/parser/MpegSplitter/MpegSplitter.cpp
+++ b/src/filters/parser/MpegSplitter/MpegSplitter.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* (C) 2003-2006 Gabest
* (C) 2006-2010 see AUTHORS
* http://www.gabest.org
@@ -7,15 +7,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,12 +33,12 @@
const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
{
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
// {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD}, // cdxa filter should take care of this
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG2_PROGRAM},
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG2_TRANSPORT},
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG2_PVA},
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG2_PROGRAM},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG2_TRANSPORT},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG2_PVA},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL},
};
const AMOVIESETUP_PIN sudpPins[] =
@@ -49,33 +49,33 @@ const AMOVIESETUP_PIN sudpPins[] =
const AMOVIESETUP_FILTER sudFilter[] =
{
- {&__uuidof(CMpegSplitterFilter), L"MPC - Mpeg Splitter (Gabest)", MERIT_NORMAL+1, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory},
- {&__uuidof(CMpegSourceFilter), L"MPC - Mpeg Source (Gabest)", MERIT_UNLIKELY, 0, NULL, CLSID_LegacyAmFilterCategory},
+ {&__uuidof(CMpegSplitterFilter), L"MPC - Mpeg Splitter (Gabest)", MERIT_NORMAL + 1, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory},
+ {&__uuidof(CMpegSourceFilter), L"MPC - Mpeg Source (Gabest)", MERIT_UNLIKELY, 0, NULL, CLSID_LegacyAmFilterCategory},
};
CFactoryTemplate g_Templates[] =
{
- {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CMpegSplitterFilter>, NULL, &sudFilter[0]},
- {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CMpegSourceFilter>, NULL, &sudFilter[1]},
+ {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CMpegSplitterFilter>, NULL, &sudFilter[0]},
+ {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CMpegSourceFilter>, NULL, &sudFilter[1]},
};
int g_cTemplates = countof(g_Templates);
STDAPI DllRegisterServer()
{
- DeleteRegKey(_T("Media Type\\Extensions\\"), _T(".ts"));
+ DeleteRegKey(_T("Media Type\\Extensions\\"), _T(".ts"));
- RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG1System, _T("0,16,FFFFFFFFF100010001800001FFFFFFFF,000001BA2100010001800001000001BB"), NULL);
- RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG2_PROGRAM, _T("0,5,FFFFFFFFC0,000001BA40"), NULL);
- RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG2_PVA, _T("0,8,fffffc00ffe00000,4156000055000000"), NULL);
+ RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG1System, _T("0,16,FFFFFFFFF100010001800001FFFFFFFF,000001BA2100010001800001000001BB"), NULL);
+ RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG2_PROGRAM, _T("0,5,FFFFFFFFC0,000001BA40"), NULL);
+ RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG2_PVA, _T("0,8,fffffc00ffe00000,4156000055000000"), NULL);
- CAtlList<CString> chkbytes;
- chkbytes.AddTail(_T("0,1,,47,188,1,,47,376,1,,47"));
- chkbytes.AddTail(_T("4,1,,47,196,1,,47,388,1,,47"));
- chkbytes.AddTail(_T("0,4,,54467263,1660,1,,47")); // TFrc
- RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG2_TRANSPORT, chkbytes, NULL);
+ CAtlList<CString> chkbytes;
+ chkbytes.AddTail(_T("0,1,,47,188,1,,47,376,1,,47"));
+ chkbytes.AddTail(_T("4,1,,47,196,1,,47,388,1,,47"));
+ chkbytes.AddTail(_T("0,4,,54467263,1660,1,,47")); // TFrc
+ RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_MPEG2_TRANSPORT, chkbytes, NULL);
- return AMovieDllRegisterServer2(TRUE);
+ return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
@@ -83,7 +83,7 @@ STDAPI DllUnregisterServer()
// UnRegisterSourceFilter(MEDIASUBTYPE_MPEG1System);
// UnRegisterSourceFilter(MEDIASUBTYPE_MPEG2_PROGRAM);
- return AMovieDllRegisterServer2(FALSE);
+ return AMovieDllRegisterServer2(FALSE);
}
#include "../../FilterApp.h"
@@ -97,8 +97,8 @@ CFilterApp theApp;
//
CMpegSplitterFilter::CMpegSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid)
- : CBaseSplitterFilter(NAME("CMpegSplitterFilter"), pUnk, phr, clsid)
- , m_pPipoBimbo(false)
+ : CBaseSplitterFilter(NAME("CMpegSplitterFilter"), pUnk, phr, clsid)
+ , m_pPipoBimbo(false)
{
}
@@ -106,1014 +106,1050 @@ STDMETHODIMP CMpegSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void*
{
CheckPointer(ppv, E_POINTER);
- return
- QI(IAMStreamSelect)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ QI(IAMStreamSelect)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
STDMETHODIMP CMpegSplitterFilter::GetClassID(CLSID* pClsID)
{
- CheckPointer (pClsID, E_POINTER);
-
- if (m_pPipoBimbo)
- {
- memcpy (pClsID, &CLSID_WMAsfReader, sizeof (GUID));
- return S_OK;
- }
- else
- return __super::GetClassID(pClsID);
+ CheckPointer(pClsID, E_POINTER);
+
+ if(m_pPipoBimbo)
+ {
+ memcpy(pClsID, &CLSID_WMAsfReader, sizeof(GUID));
+ return S_OK;
+ }
+ else
+ return __super::GetClassID(pClsID);
}
void CMpegSplitterFilter::ReadClipInfo(LPCOLESTR pszFileName)
{
- if (wcslen (pszFileName) > 0)
- {
- WCHAR Drive[_MAX_DRIVE];
- WCHAR Dir[_MAX_PATH];
- WCHAR Filename[_MAX_PATH];
- WCHAR Ext[_MAX_EXT];
-
- if (_wsplitpath_s (pszFileName, Drive, countof(Drive), Dir, countof(Dir), Filename, countof(Filename), Ext, countof(Ext)) == 0)
- {
- CString strClipInfo;
-
- if (Drive[0])
- strClipInfo.Format (_T("%s\\%s\\..\\CLIPINF\\%s.clpi"), Drive, Dir, Filename);
- else
- strClipInfo.Format (_T("%s\\..\\CLIPINF\\%s.clpi"), Dir, Filename);
-
- m_ClipInfo.ReadInfo (strClipInfo);
- }
- }
+ if(wcslen(pszFileName) > 0)
+ {
+ WCHAR Drive[_MAX_DRIVE];
+ WCHAR Dir[_MAX_PATH];
+ WCHAR Filename[_MAX_PATH];
+ WCHAR Ext[_MAX_EXT];
+
+ if(_wsplitpath_s(pszFileName, Drive, countof(Drive), Dir, countof(Dir), Filename, countof(Filename), Ext, countof(Ext)) == 0)
+ {
+ CString strClipInfo;
+
+ if(Drive[0])
+ strClipInfo.Format(_T("%s\\%s\\..\\CLIPINF\\%s.clpi"), Drive, Dir, Filename);
+ else
+ strClipInfo.Format(_T("%s\\..\\CLIPINF\\%s.clpi"), Dir, Filename);
+
+ m_ClipInfo.ReadInfo(strClipInfo);
+ }
+ }
}
STDMETHODIMP CMpegSplitterFilter::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt)
{
- HRESULT hr;
-
- return __super::Load (pszFileName, pmt);
+ HRESULT hr;
+
+ return __super::Load(pszFileName, pmt);
}
HRESULT CMpegSplitterFilter::DemuxNextPacket(REFERENCE_TIME rtStartOffset)
{
- HRESULT hr;
- BYTE b;
-
- if(m_pFile->m_type == CMpegSplitterFile::ps || m_pFile->m_type == CMpegSplitterFile::es)
- {
- if(!m_pFile->NextMpegStartCode(b))
- return S_FALSE;
-
- if(b == 0xba) // program stream header
- {
- CMpegSplitterFile::pshdr h;
- if(!m_pFile->Read(h))
- return S_FALSE;
- }
- else if(b == 0xbb) // program stream system header
- {
- CMpegSplitterFile::pssyshdr h;
- if(!m_pFile->Read(h))
- return S_FALSE;
- }
+ HRESULT hr;
+ BYTE b;
+
+ if(m_pFile->m_type == CMpegSplitterFile::ps || m_pFile->m_type == CMpegSplitterFile::es)
+ {
+ if(!m_pFile->NextMpegStartCode(b))
+ return S_FALSE;
+
+ if(b == 0xba) // program stream header
+ {
+ CMpegSplitterFile::pshdr h;
+ if(!m_pFile->Read(h))
+ return S_FALSE;
+ }
+ else if(b == 0xbb) // program stream system header
+ {
+ CMpegSplitterFile::pssyshdr h;
+ if(!m_pFile->Read(h))
+ return S_FALSE;
+ }
#if (EVO_SUPPORT == 0)
- else if(b >= 0xbd && b < 0xf0) // pes packet
+ else if(b >= 0xbd && b < 0xf0) // pes packet
#else
- else if((b >= 0xbd && b < 0xf0) || (b == 0xfd)) // pes packet
+ else if((b >= 0xbd && b < 0xf0) || (b == 0xfd)) // pes packet
#endif
- {
- CMpegSplitterFile::peshdr h;
-
- if(!m_pFile->Read(h, b) || !h.len) return S_FALSE;
-
- if(h.type == CMpegSplitterFile::mpeg2 && h.scrambling)
- {
- ASSERT(0);
- return E_FAIL;
- }
-
- __int64 pos = m_pFile->GetPos();
-
- DWORD TrackNumber = m_pFile->AddStream(0, b, h.len);
-
- if(GetOutputPin(TrackNumber))
- {
- CAutoPtr<Packet> p(DNew Packet());
-
- p->TrackNumber = TrackNumber;
- p->bSyncPoint = !!h.fpts;
- p->bAppendable = !h.fpts;
- p->rtStart = h.fpts ? (h.pts - rtStartOffset) : Packet::INVALID_TIME;
- p->rtStop = p->rtStart+1;
- p->SetCount(h.len - (size_t)(m_pFile->GetPos() - pos));
-
- m_pFile->ByteRead(p->GetData(), h.len - (m_pFile->GetPos() - pos));
-
- hr = DeliverPacket(p);
- }
- m_pFile->Seek(pos + h.len);
- }
- }
- else if(m_pFile->m_type == CMpegSplitterFile::ts)
- {
- CMpegSplitterFile::trhdr h;
-
- if(!m_pFile->Read(h))
- return S_FALSE;
-
-
- __int64 pos = m_pFile->GetPos();
-
- if(h.payload && h.payloadstart)
- m_pFile->UpdatePrograms(h);
-
- if(h.payload && h.pid >= 16 && h.pid < 0x1fff && !h.scrambling)
- {
- DWORD TrackNumber = h.pid;
-
- CMpegSplitterFile::peshdr h2;
-
- if(h.payloadstart && m_pFile->NextMpegStartCode(b, 4) && m_pFile->Read(h2, b)) // pes packet
- {
- if(h2.type == CMpegSplitterFile::mpeg2 && h2.scrambling)
- {
- ASSERT(0);
- return E_FAIL;
- }
- TrackNumber = m_pFile->AddStream(h.pid, b, h.bytes - (DWORD)(m_pFile->GetPos() - pos));
- }
-
- if(GetOutputPin(TrackNumber))
- {
- CAutoPtr<Packet> p(DNew Packet());
-
- p->TrackNumber = TrackNumber;
- p->bSyncPoint = !!h2.fpts;
- p->bAppendable = !h2.fpts;
-
- if (h.fPCR)
- {
- CRefTime rtNow;
- StreamTime(rtNow);
- TRACE ("Now=%S PCR=%S\n", ReftimeToString(rtNow.m_time), ReftimeToString(h.PCR));
- }
- if (h2.fpts && h.pid == 241)
- {
- TRACE ("Sub=%S\n", ReftimeToString(h2.pts - rtStartOffset));
- }
-
- p->rtStart = h2.fpts ? (h2.pts - rtStartOffset) : Packet::INVALID_TIME;
- p->rtStop = p->rtStart+1;
- p->SetCount(h.bytes - (size_t)(m_pFile->GetPos() - pos));
-
- int nBytes = int(h.bytes - (m_pFile->GetPos() - pos));
- m_pFile->ByteRead(p->GetData(), nBytes);
-
- hr = DeliverPacket(p);
- }
- }
-
- m_pFile->Seek(h.next);
- }
- else if(m_pFile->m_type == CMpegSplitterFile::pva)
- {
- CMpegSplitterFile::pvahdr h;
- if(!m_pFile->Read(h))
- return S_FALSE;
-
- DWORD TrackNumber = h.streamid;
-
- __int64 pos = m_pFile->GetPos();
-
- if(GetOutputPin(TrackNumber))
- {
- CAutoPtr<Packet> p(DNew Packet());
-
- p->TrackNumber = TrackNumber;
- p->bSyncPoint = !!h.fpts;
- p->bAppendable = !h.fpts;
- p->rtStart = h.fpts ? (h.pts - rtStartOffset) : Packet::INVALID_TIME;
- p->rtStop = p->rtStart+1;
- p->SetCount(h.length);
-
- m_pFile->ByteRead(p->GetData(), h.length);
- hr = DeliverPacket(p);
- }
-
- m_pFile->Seek(pos + h.length);
- }
-
- return S_OK;
+ {
+ CMpegSplitterFile::peshdr h;
+
+ if(!m_pFile->Read(h, b) || !h.len) return S_FALSE;
+
+ if(h.type == CMpegSplitterFile::mpeg2 && h.scrambling)
+ {
+ ASSERT(0);
+ return E_FAIL;
+ }
+
+ __int64 pos = m_pFile->GetPos();
+
+ DWORD TrackNumber = m_pFile->AddStream(0, b, h.len);
+
+ if(GetOutputPin(TrackNumber))
+ {
+ CAutoPtr<Packet> p(DNew Packet());
+
+ p->TrackNumber = TrackNumber;
+ p->bSyncPoint = !!h.fpts;
+ p->bAppendable = !h.fpts;
+ p->rtStart = h.fpts ? (h.pts - rtStartOffset) : Packet::INVALID_TIME;
+ p->rtStop = p->rtStart + 1;
+ p->SetCount(h.len - (size_t)(m_pFile->GetPos() - pos));
+
+ m_pFile->ByteRead(p->GetData(), h.len - (m_pFile->GetPos() - pos));
+
+ hr = DeliverPacket(p);
+ }
+ m_pFile->Seek(pos + h.len);
+ }
+ }
+ else if(m_pFile->m_type == CMpegSplitterFile::ts)
+ {
+ CMpegSplitterFile::trhdr h;
+
+ if(!m_pFile->Read(h))
+ return S_FALSE;
+
+
+ __int64 pos = m_pFile->GetPos();
+
+ if(h.payload && h.payloadstart)
+ m_pFile->UpdatePrograms(h);
+
+ if(h.payload && h.pid >= 16 && h.pid < 0x1fff && !h.scrambling)
+ {
+ DWORD TrackNumber = h.pid;
+
+ CMpegSplitterFile::peshdr h2;
+
+ if(h.payloadstart && m_pFile->NextMpegStartCode(b, 4) && m_pFile->Read(h2, b)) // pes packet
+ {
+ if(h2.type == CMpegSplitterFile::mpeg2 && h2.scrambling)
+ {
+ ASSERT(0);
+ return E_FAIL;
+ }
+ TrackNumber = m_pFile->AddStream(h.pid, b, h.bytes - (DWORD)(m_pFile->GetPos() - pos));
+ }
+
+ if(GetOutputPin(TrackNumber))
+ {
+ CAutoPtr<Packet> p(DNew Packet());
+
+ p->TrackNumber = TrackNumber;
+ p->bSyncPoint = !!h2.fpts;
+ p->bAppendable = !h2.fpts;
+
+ if(h.fPCR)
+ {
+ CRefTime rtNow;
+ StreamTime(rtNow);
+ TRACE("Now=%S PCR=%S\n", ReftimeToString(rtNow.m_time), ReftimeToString(h.PCR));
+ }
+ if(h2.fpts && h.pid == 241)
+ {
+ TRACE("Sub=%S\n", ReftimeToString(h2.pts - rtStartOffset));
+ }
+
+ p->rtStart = h2.fpts ? (h2.pts - rtStartOffset) : Packet::INVALID_TIME;
+ p->rtStop = p->rtStart + 1;
+ p->SetCount(h.bytes - (size_t)(m_pFile->GetPos() - pos));
+
+ int nBytes = int(h.bytes - (m_pFile->GetPos() - pos));
+ m_pFile->ByteRead(p->GetData(), nBytes);
+
+ hr = DeliverPacket(p);
+ }
+ }
+
+ m_pFile->Seek(h.next);
+ }
+ else if(m_pFile->m_type == CMpegSplitterFile::pva)
+ {
+ CMpegSplitterFile::pvahdr h;
+ if(!m_pFile->Read(h))
+ return S_FALSE;
+
+ DWORD TrackNumber = h.streamid;
+
+ __int64 pos = m_pFile->GetPos();
+
+ if(GetOutputPin(TrackNumber))
+ {
+ CAutoPtr<Packet> p(DNew Packet());
+
+ p->TrackNumber = TrackNumber;
+ p->bSyncPoint = !!h.fpts;
+ p->bAppendable = !h.fpts;
+ p->rtStart = h.fpts ? (h.pts - rtStartOffset) : Packet::INVALID_TIME;
+ p->rtStop = p->rtStart + 1;
+ p->SetCount(h.length);
+
+ m_pFile->ByteRead(p->GetData(), h.length);
+ hr = DeliverPacket(p);
+ }
+
+ m_pFile->Seek(pos + h.length);
+ }
+
+ return S_OK;
}
//
HRESULT CMpegSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
{
- CheckPointer(pAsyncReader, E_POINTER);
-
- HRESULT hr = E_FAIL;
-
- m_pFile.Free();
-
- ReadClipInfo (GetPartFilename(pAsyncReader));
- m_pFile.Attach(DNew CMpegSplitterFile(pAsyncReader, hr, m_ClipInfo.IsHdmv(), m_ClipInfo));
-
- if(!m_pFile) return E_OUTOFMEMORY;
-
- if(FAILED(hr))
- {
- m_pFile.Free();
- return hr;
- }
-
- // Create
- if (m_ClipInfo.IsHdmv())
- {
- for (int i=0; i<m_ClipInfo.GetStreamNumber(); i++)
- {
- CHdmvClipInfo::Stream* stream = m_ClipInfo.GetStreamByIndex (i);
- if (stream->m_Type == PRESENTATION_GRAPHICS_STREAM)
- {
- m_pFile->AddHdmvPGStream (stream->m_PID, stream->m_LanguageCode);
- }
- }
- }
-
- m_rtNewStart = m_rtCurrent = 0;
- m_rtNewStop = m_rtStop = m_rtDuration = 0;
-
- for(int i = 0; i < countof(m_pFile->m_streams); i++)
- {
- POSITION pos = m_pFile->m_streams[i].GetHeadPosition();
- while(pos)
- {
- CMpegSplitterFile::stream& s = m_pFile->m_streams[i].GetNext(pos);
-
- CAtlArray<CMediaType> mts;
- mts.Add(s.mt);
-
- CStringW name = CMpegSplitterFile::CStreamList::ToString(i);
-
- CAutoPtr<CBaseSplitterOutputPin> pPinOut(DNew CMpegSplitterOutputPin(mts, name, this, this, &hr));
- if (i == CMpegSplitterFile::subpic)
- (static_cast<CMpegSplitterOutputPin*>(pPinOut.m_p))->SetMaxShift (_I64_MAX);
- if(S_OK == AddOutputPin(s, pPinOut))
- break;
- }
- }
-
- if(m_pFile->IsRandomAccess() && m_pFile->m_rate)
- {
- m_rtNewStop = m_rtStop = m_rtDuration = 10000000i64 * m_pFile->GetLength() / m_pFile->m_rate;
- }
-
- return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
+ CheckPointer(pAsyncReader, E_POINTER);
+
+ HRESULT hr = E_FAIL;
+
+ m_pFile.Free();
+
+ ReadClipInfo(GetPartFilename(pAsyncReader));
+ m_pFile.Attach(DNew CMpegSplitterFile(pAsyncReader, hr, m_ClipInfo.IsHdmv(), m_ClipInfo));
+
+ if(!m_pFile) return E_OUTOFMEMORY;
+
+ if(FAILED(hr))
+ {
+ m_pFile.Free();
+ return hr;
+ }
+
+ // Create
+ if(m_ClipInfo.IsHdmv())
+ {
+ for(int i = 0; i < m_ClipInfo.GetStreamNumber(); i++)
+ {
+ CHdmvClipInfo::Stream* stream = m_ClipInfo.GetStreamByIndex(i);
+ if(stream->m_Type == PRESENTATION_GRAPHICS_STREAM)
+ {
+ m_pFile->AddHdmvPGStream(stream->m_PID, stream->m_LanguageCode);
+ }
+ }
+ }
+
+ m_rtNewStart = m_rtCurrent = 0;
+ m_rtNewStop = m_rtStop = m_rtDuration = 0;
+
+ for(int i = 0; i < countof(m_pFile->m_streams); i++)
+ {
+ POSITION pos = m_pFile->m_streams[i].GetHeadPosition();
+ while(pos)
+ {
+ CMpegSplitterFile::stream& s = m_pFile->m_streams[i].GetNext(pos);
+
+ CAtlArray<CMediaType> mts;
+ mts.Add(s.mt);
+
+ CStringW name = CMpegSplitterFile::CStreamList::ToString(i);
+
+ CAutoPtr<CBaseSplitterOutputPin> pPinOut(DNew CMpegSplitterOutputPin(mts, name, this, this, &hr));
+ if(i == CMpegSplitterFile::subpic)
+ (static_cast<CMpegSplitterOutputPin*>(pPinOut.m_p))->SetMaxShift(_I64_MAX);
+ if(S_OK == AddOutputPin(s, pPinOut))
+ break;
+ }
+ }
+
+ if(m_pFile->IsRandomAccess() && m_pFile->m_rate)
+ {
+ m_rtNewStop = m_rtStop = m_rtDuration = 10000000i64 * m_pFile->GetLength() / m_pFile->m_rate;
+ }
+
+ return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
}
bool CMpegSplitterFilter::DemuxInit()
{
- if(!m_pFile) return(false);
+ if(!m_pFile) return(false);
- m_rtStartOffset = 0;
+ m_rtStartOffset = 0;
- return(true);
+ return(true);
}
void CMpegSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
{
- CAtlList<CMpegSplitterFile::stream>* pMasterStream = m_pFile->GetMasterStream();
-
- if(!pMasterStream)
- {
- ASSERT(0);
- return;
- }
-
- if(m_pFile->IsStreaming())
- {
- m_pFile->Seek(max(0, m_pFile->GetLength() - 100*1024));
- m_rtStartOffset = m_pFile->m_rtMin + m_pFile->NextPTS(pMasterStream->GetHead());
- return;
- }
-
- REFERENCE_TIME rtPreroll = 10000000;
-
- if(rt <= rtPreroll || m_rtDuration <= 0)
- {
- m_pFile->Seek(0);
- }
- else
- {
- __int64 len = m_pFile->GetLength();
- __int64 seekpos = (__int64)(1.0*rt/m_rtDuration*len);
- __int64 minseekpos = _I64_MAX;
-
- REFERENCE_TIME rtmax = rt - rtPreroll;
- REFERENCE_TIME rtmin = rtmax - 5000000;
-
- if(m_rtStartOffset == 0)
- for(int i = 0; i < countof(m_pFile->m_streams)-1; i++)
- {
- POSITION pos = m_pFile->m_streams[i].GetHeadPosition();
- while(pos)
- {
- DWORD TrackNum = m_pFile->m_streams[i].GetNext(pos);
-
- CBaseSplitterOutputPin* pPin = GetOutputPin(TrackNum);
- if(pPin && pPin->IsConnected())
- {
- m_pFile->Seek(seekpos);
-
- REFERENCE_TIME pdt = _I64_MIN;
-
- for(int j = 0; j < 10; j++)
- {
- REFERENCE_TIME rt = m_pFile->NextPTS(TrackNum);
-
- if(rt < 0) break;
-
- REFERENCE_TIME dt = rt - rtmax;
- if(dt > 0 && dt == pdt) dt = 10000000i64;
-
-
- if(rtmin <= rt && rt <= rtmax || pdt > 0 && dt < 0)
- {
- minseekpos = min(minseekpos, m_pFile->GetPos());
- break;
- }
-
- m_pFile->Seek(m_pFile->GetPos() - (__int64)(1.0*dt/m_rtDuration*len));
-
- pdt = dt;
- }
- }
- }
- }
-
- if(minseekpos != _I64_MAX)
- {
- seekpos = minseekpos;
- }
- else
- {
- // this file is probably screwed up, try plan B, seek simply by bitrate
-
- rt -= rtPreroll;
- seekpos = (__int64)(1.0*rt/m_rtDuration*len);
- m_pFile->Seek(seekpos);
- m_rtStartOffset = m_pFile->m_rtMin + m_pFile->NextPTS(pMasterStream->GetHead()) - rt;
- }
-
- m_pFile->Seek(seekpos);
- }
+ CAtlList<CMpegSplitterFile::stream>* pMasterStream = m_pFile->GetMasterStream();
+
+ if(!pMasterStream)
+ {
+ ASSERT(0);
+ return;
+ }
+
+ if(m_pFile->IsStreaming())
+ {
+ m_pFile->Seek(max(0, m_pFile->GetLength() - 100 * 1024));
+ m_rtStartOffset = m_pFile->m_rtMin + m_pFile->NextPTS(pMasterStream->GetHead());
+ return;
+ }
+
+ REFERENCE_TIME rtPreroll = 10000000;
+
+ if(rt <= rtPreroll || m_rtDuration <= 0)
+ {
+ m_pFile->Seek(0);
+ }
+ else
+ {
+ __int64 len = m_pFile->GetLength();
+ __int64 seekpos = (__int64)(1.0 * rt / m_rtDuration * len);
+ __int64 minseekpos = _I64_MAX;
+
+ REFERENCE_TIME rtmax = rt - rtPreroll;
+ REFERENCE_TIME rtmin = rtmax - 5000000;
+
+ if(m_rtStartOffset == 0)
+ for(int i = 0; i < countof(m_pFile->m_streams) - 1; i++)
+ {
+ POSITION pos = m_pFile->m_streams[i].GetHeadPosition();
+ while(pos)
+ {
+ DWORD TrackNum = m_pFile->m_streams[i].GetNext(pos);
+
+ CBaseSplitterOutputPin* pPin = GetOutputPin(TrackNum);
+ if(pPin && pPin->IsConnected())
+ {
+ m_pFile->Seek(seekpos);
+
+ REFERENCE_TIME pdt = _I64_MIN;
+
+ for(int j = 0; j < 10; j++)
+ {
+ REFERENCE_TIME rt = m_pFile->NextPTS(TrackNum);
+
+ if(rt < 0) break;
+
+ REFERENCE_TIME dt = rt - rtmax;
+ if(dt > 0 && dt == pdt) dt = 10000000i64;
+
+
+ if(rtmin <= rt && rt <= rtmax || pdt > 0 && dt < 0)
+ {
+ minseekpos = min(minseekpos, m_pFile->GetPos());
+ break;
+ }
+
+ m_pFile->Seek(m_pFile->GetPos() - (__int64)(1.0 * dt / m_rtDuration * len));
+
+ pdt = dt;
+ }
+ }
+ }
+ }
+
+ if(minseekpos != _I64_MAX)
+ {
+ seekpos = minseekpos;
+ }
+ else
+ {
+ // this file is probably screwed up, try plan B, seek simply by bitrate
+
+ rt -= rtPreroll;
+ seekpos = (__int64)(1.0 * rt / m_rtDuration * len);
+ m_pFile->Seek(seekpos);
+ m_rtStartOffset = m_pFile->m_rtMin + m_pFile->NextPTS(pMasterStream->GetHead()) - rt;
+ }
+
+ m_pFile->Seek(seekpos);
+ }
}
bool CMpegSplitterFilter::DemuxLoop()
{
- REFERENCE_TIME rtStartOffset = m_rtStartOffset ? m_rtStartOffset : m_pFile->m_rtMin;
+ REFERENCE_TIME rtStartOffset = m_rtStartOffset ? m_rtStartOffset : m_pFile->m_rtMin;
- HRESULT hr = S_OK;
- while(SUCCEEDED(hr) && !CheckRequest(NULL))
- {
- if((hr = m_pFile->HasMoreData(1024*500)) == S_OK)
- if((hr = DemuxNextPacket(rtStartOffset)) == S_FALSE)
- Sleep(1);
- }
+ HRESULT hr = S_OK;
+ while(SUCCEEDED(hr) && !CheckRequest(NULL))
+ {
+ if((hr = m_pFile->HasMoreData(1024 * 500)) == S_OK)
+ if((hr = DemuxNextPacket(rtStartOffset)) == S_FALSE)
+ Sleep(1);
+ }
- return(true);
+ return(true);
}
bool CMpegSplitterFilter::BuildPlaylist(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& Items)
{
- REFERENCE_TIME rtDuration;
- return SUCCEEDED (m_ClipInfo.ReadPlaylist (pszFileName, rtDuration, Items)) ? true : false;
+ REFERENCE_TIME rtDuration;
+ return SUCCEEDED(m_ClipInfo.ReadPlaylist(pszFileName, rtDuration, Items)) ? true : false;
}
// IAMStreamSelect
STDMETHODIMP CMpegSplitterFilter::Count(DWORD* pcStreams)
{
- CheckPointer(pcStreams, E_POINTER);
+ CheckPointer(pcStreams, E_POINTER);
- *pcStreams = 0;
+ *pcStreams = 0;
- for(int i = 0; i < countof(m_pFile->m_streams); i++)
- (*pcStreams) += m_pFile->m_streams[i].GetCount();
+ for(int i = 0; i < countof(m_pFile->m_streams); i++)
+ (*pcStreams) += m_pFile->m_streams[i].GetCount();
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CMpegSplitterFilter::Enable(long lIndex, DWORD dwFlags)
{
- if(!(dwFlags & AMSTREAMSELECTENABLE_ENABLE))
- return E_NOTIMPL;
-
- for(int i = 0, j = 0; i < countof(m_pFile->m_streams); i++)
- {
- int cnt = m_pFile->m_streams[i].GetCount();
-
- if(lIndex >= j && lIndex < j+cnt)
- {
- lIndex -= j;
-
- POSITION pos = m_pFile->m_streams[i].FindIndex(lIndex);
- if(!pos) return E_UNEXPECTED;
-
- CMpegSplitterFile::stream& to = m_pFile->m_streams[i].GetAt(pos);
-
- pos = m_pFile->m_streams[i].GetHeadPosition();
- while(pos)
- {
- CMpegSplitterFile::stream& from = m_pFile->m_streams[i].GetNext(pos);
- if(!GetOutputPin(from)) continue;
-
- HRESULT hr;
- if(FAILED(hr = RenameOutputPin(from, to, &to.mt)))
- return hr;
-
- // Don't rename other pin for Hdmv!
- int iProgram;
- const CHdmvClipInfo::Stream *pClipInfo;
- const CMpegSplitterFile::program* p = m_pFile->FindProgram(to.pid, iProgram, pClipInfo);
-
- if(p!=NULL && !m_ClipInfo.IsHdmv() && !m_pFile->IsHdmv())
- {
- for(int k = 0; k < countof(m_pFile->m_streams); k++)
- {
- if(k == i) continue;
-
- pos = m_pFile->m_streams[k].GetHeadPosition();
- while(pos)
- {
- CMpegSplitterFile::stream& from = m_pFile->m_streams[k].GetNext(pos);
- if(!GetOutputPin(from)) continue;
-
- for(int l = 0; l < countof(p->streams); l++)
- {
- if(const CMpegSplitterFile::stream* s = m_pFile->m_streams[k].FindStream(p->streams[l].pid))
- {
- if(from != *s)
- hr = RenameOutputPin(from, *s, &s->mt);
- break;
- }
- }
- }
- }
- }
-
- return S_OK;
- }
- }
-
- j += cnt;
- }
-
- return S_FALSE;
+ if(!(dwFlags & AMSTREAMSELECTENABLE_ENABLE))
+ return E_NOTIMPL;
+
+ for(int i = 0, j = 0; i < countof(m_pFile->m_streams); i++)
+ {
+ int cnt = m_pFile->m_streams[i].GetCount();
+
+ if(lIndex >= j && lIndex < j + cnt)
+ {
+ lIndex -= j;
+
+ POSITION pos = m_pFile->m_streams[i].FindIndex(lIndex);
+ if(!pos) return E_UNEXPECTED;
+
+ CMpegSplitterFile::stream& to = m_pFile->m_streams[i].GetAt(pos);
+
+ pos = m_pFile->m_streams[i].GetHeadPosition();
+ while(pos)
+ {
+ CMpegSplitterFile::stream& from = m_pFile->m_streams[i].GetNext(pos);
+ if(!GetOutputPin(from)) continue;
+
+ HRESULT hr;
+ if(FAILED(hr = RenameOutputPin(from, to, &to.mt)))
+ return hr;
+
+ // Don't rename other pin for Hdmv!
+ int iProgram;
+ const CHdmvClipInfo::Stream *pClipInfo;
+ const CMpegSplitterFile::program* p = m_pFile->FindProgram(to.pid, iProgram, pClipInfo);
+
+ if(p != NULL && !m_ClipInfo.IsHdmv() && !m_pFile->IsHdmv())
+ {
+ for(int k = 0; k < countof(m_pFile->m_streams); k++)
+ {
+ if(k == i) continue;
+
+ pos = m_pFile->m_streams[k].GetHeadPosition();
+ while(pos)
+ {
+ CMpegSplitterFile::stream& from = m_pFile->m_streams[k].GetNext(pos);
+ if(!GetOutputPin(from)) continue;
+
+ for(int l = 0; l < countof(p->streams); l++)
+ {
+ if(const CMpegSplitterFile::stream* s = m_pFile->m_streams[k].FindStream(p->streams[l].pid))
+ {
+ if(from != *s)
+ hr = RenameOutputPin(from, *s, &s->mt);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return S_OK;
+ }
+ }
+
+ j += cnt;
+ }
+
+ return S_FALSE;
}
template <typename t_CType>
t_CType GetFormatHelper(t_CType &_pInfo, const CMediaType *_pFormat)
{
- ASSERT(_pFormat->cbFormat >= sizeof(*_pInfo));
- _pInfo = (t_CType)_pFormat->pbFormat;
- return _pInfo;
+ ASSERT(_pFormat->cbFormat >= sizeof(*_pInfo));
+ _pInfo = (t_CType)_pFormat->pbFormat;
+ return _pInfo;
}
static int GetHighestBitSet32(unsigned long _Value)
{
- unsigned long Ret;
- unsigned char bNonZero = _BitScanReverse(&Ret, _Value);
- if (bNonZero)
- return Ret;
- else
- return -1;
+ unsigned long Ret;
+ unsigned char bNonZero = _BitScanReverse(&Ret, _Value);
+ if(bNonZero)
+ return Ret;
+ else
+ return -1;
}
CString FormatBitrate(double _Bitrate)
{
- CString Temp;
- if (_Bitrate > 20000000) // More than 2 mbit
- Temp.Format(L"%.2f mbit/s", double(_Bitrate)/1000000.0);
- else
- Temp.Format(L"%.1f kbit/s", double(_Bitrate)/1000.0);
+ CString Temp;
+ if(_Bitrate > 20000000) // More than 2 mbit
+ Temp.Format(L"%.2f mbit/s", double(_Bitrate) / 1000000.0);
+ else
+ Temp.Format(L"%.1f kbit/s", double(_Bitrate) / 1000.0);
- return Temp;
+ return Temp;
}
-CString FormatString(const wchar_t *pszFormat, ... )
+CString FormatString(const wchar_t *pszFormat, ...)
{
- CString Temp;
- ATLASSERT( AtlIsValidString( pszFormat ) );
+ CString Temp;
+ ATLASSERT(AtlIsValidString(pszFormat));
- va_list argList;
- va_start( argList, pszFormat );
- Temp.FormatV( pszFormat, argList );
- va_end( argList );
+ va_list argList;
+ va_start(argList, pszFormat);
+ Temp.FormatV(pszFormat, argList);
+ va_end(argList);
- return Temp;
+ return Temp;
}
LONGLONG GetMediaTypeQuality(const CMediaType *_pMediaType, int _PresentationFormat)
{
- if (_pMediaType->formattype == FORMAT_WaveFormatEx)
- {
- __int64 Ret = 0;
-
- const WAVEFORMATEX *pInfo = GetFormatHelper(pInfo, _pMediaType);
- int TypePriority = 0;
-
- if (_pMediaType->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
- {
- TypePriority = 12;
- }
- else if (_pMediaType->subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
- {
- TypePriority = 12;
- }
- else
- {
- if (_PresentationFormat == AUDIO_STREAM_DTS_HD_MASTER_AUDIO)
- TypePriority = 12;
- else if (_PresentationFormat == AUDIO_STREAM_DTS_HD)
- TypePriority = 11;
- else if (_PresentationFormat == AUDIO_STREAM_AC3_TRUE_HD)
- TypePriority = 12;
- else if (_PresentationFormat == AUDIO_STREAM_AC3_PLUS)
- TypePriority = 10;
- else
- {
- switch (pInfo->wFormatTag)
- {
- case WAVE_FORMAT_PS2_PCM:
- {
- TypePriority = 12;
- }
- break;
- case WAVE_FORMAT_PS2_ADPCM:
- {
- TypePriority = 4;
- }
- break;
- case WAVE_FORMAT_DVD_DTS:
- {
- TypePriority = 9;
- }
- break;
- case WAVE_FORMAT_DOLBY_AC3:
- {
- TypePriority = 8;
- }
- break;
- case WAVE_FORMAT_AAC:
- {
- TypePriority = 7;
- }
- break;
- case WAVE_FORMAT_MP3:
- {
- TypePriority = 6;
- }
- break;
- case WAVE_FORMAT_MPEG:
- {
- TypePriority = 5;
- }
- break;
- }
- }
- }
-
- Ret += __int64(TypePriority) * 100000000i64 * 1000000000i64;
-
- Ret += __int64(pInfo->nChannels) * 1000000i64 * 1000000000i64;
- Ret += __int64(pInfo->nSamplesPerSec) * 10i64 * 1000000000i64;
- Ret += __int64(pInfo->wBitsPerSample) * 10000000i64;
- Ret += __int64(pInfo->nAvgBytesPerSec);
-
- return Ret;
- }
-
- return 0;
+ if(_pMediaType->formattype == FORMAT_WaveFormatEx)
+ {
+ __int64 Ret = 0;
+
+ const WAVEFORMATEX *pInfo = GetFormatHelper(pInfo, _pMediaType);
+ int TypePriority = 0;
+
+ if(_pMediaType->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
+ {
+ TypePriority = 12;
+ }
+ else if(_pMediaType->subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
+ {
+ TypePriority = 12;
+ }
+ else
+ {
+ if(_PresentationFormat == AUDIO_STREAM_DTS_HD_MASTER_AUDIO)
+ TypePriority = 12;
+ else if(_PresentationFormat == AUDIO_STREAM_DTS_HD)
+ TypePriority = 11;
+ else if(_PresentationFormat == AUDIO_STREAM_AC3_TRUE_HD)
+ TypePriority = 12;
+ else if(_PresentationFormat == AUDIO_STREAM_AC3_PLUS)
+ TypePriority = 10;
+ else
+ {
+ switch(pInfo->wFormatTag)
+ {
+ case WAVE_FORMAT_PS2_PCM:
+ {
+ TypePriority = 12;
+ }
+ break;
+ case WAVE_FORMAT_PS2_ADPCM:
+ {
+ TypePriority = 4;
+ }
+ break;
+ case WAVE_FORMAT_DVD_DTS:
+ {
+ TypePriority = 9;
+ }
+ break;
+ case WAVE_FORMAT_DOLBY_AC3:
+ {
+ TypePriority = 8;
+ }
+ break;
+ case WAVE_FORMAT_AAC:
+ {
+ TypePriority = 7;
+ }
+ break;
+ case WAVE_FORMAT_MP3:
+ {
+ TypePriority = 6;
+ }
+ break;
+ case WAVE_FORMAT_MPEG:
+ {
+ TypePriority = 5;
+ }
+ break;
+ }
+ }
+ }
+
+ Ret += __int64(TypePriority) * 100000000i64 * 1000000000i64;
+
+ Ret += __int64(pInfo->nChannels) * 1000000i64 * 1000000000i64;
+ Ret += __int64(pInfo->nSamplesPerSec) * 10i64 * 1000000000i64;
+ Ret += __int64(pInfo->wBitsPerSample) * 10000000i64;
+ Ret += __int64(pInfo->nAvgBytesPerSec);
+
+ return Ret;
+ }
+
+ return 0;
}
bool CMpegSplitterFile::stream::operator < (const stream &_Other) const
{
- if (mt.majortype == MEDIATYPE_Audio && _Other.mt.majortype == MEDIATYPE_Audio)
- {
- int iProgram0;
- const CHdmvClipInfo::Stream *pClipInfo0;
- const CMpegSplitterFile::program * pProgram0 = m_pFile->FindProgram(pid, iProgram0, pClipInfo0);
- int StreamType0 = pClipInfo0 ? pClipInfo0->m_Type : pProgram0 ? pProgram0->streams[iProgram0].type : 0;
- int iProgram1;
- const CHdmvClipInfo::Stream *pClipInfo1;
- const CMpegSplitterFile::program * pProgram1 = m_pFile->FindProgram(_Other.pid, iProgram1, pClipInfo1);
- int StreamType1 = pClipInfo1 ? pClipInfo1->m_Type : pProgram1 ? pProgram1->streams[iProgram1].type : 0;
-
- if (mt.formattype == FORMAT_WaveFormatEx && _Other.mt.formattype != FORMAT_WaveFormatEx)
- return true;
- if (mt.formattype != FORMAT_WaveFormatEx && _Other.mt.formattype == FORMAT_WaveFormatEx)
- return false;
-
- LONGLONG Quality0 = GetMediaTypeQuality(&mt, StreamType0);
- LONGLONG Quality1 = GetMediaTypeQuality(&_Other.mt, StreamType1);
- if (Quality0 > Quality1)
- return true;
- if (Quality0 < Quality1)
- return false;
- }
- DWORD DefaultFirst = *this;
- DWORD DefaultSecond = _Other;
- return DefaultFirst < DefaultSecond;
+ if(mt.majortype == MEDIATYPE_Audio && _Other.mt.majortype == MEDIATYPE_Audio)
+ {
+ int iProgram0;
+ const CHdmvClipInfo::Stream *pClipInfo0;
+ const CMpegSplitterFile::program * pProgram0 = m_pFile->FindProgram(pid, iProgram0, pClipInfo0);
+ int StreamType0 = pClipInfo0 ? pClipInfo0->m_Type : pProgram0 ? pProgram0->streams[iProgram0].type : 0;
+ int iProgram1;
+ const CHdmvClipInfo::Stream *pClipInfo1;
+ const CMpegSplitterFile::program * pProgram1 = m_pFile->FindProgram(_Other.pid, iProgram1, pClipInfo1);
+ int StreamType1 = pClipInfo1 ? pClipInfo1->m_Type : pProgram1 ? pProgram1->streams[iProgram1].type : 0;
+
+ if(mt.formattype == FORMAT_WaveFormatEx && _Other.mt.formattype != FORMAT_WaveFormatEx)
+ return true;
+ if(mt.formattype != FORMAT_WaveFormatEx && _Other.mt.formattype == FORMAT_WaveFormatEx)
+ return false;
+
+ LONGLONG Quality0 = GetMediaTypeQuality(&mt, StreamType0);
+ LONGLONG Quality1 = GetMediaTypeQuality(&_Other.mt, StreamType1);
+ if(Quality0 > Quality1)
+ return true;
+ if(Quality0 < Quality1)
+ return false;
+ }
+ DWORD DefaultFirst = *this;
+ DWORD DefaultSecond = _Other;
+ return DefaultFirst < DefaultSecond;
}
CString GetMediaTypeDesc(const CMediaType *_pMediaType, const CHdmvClipInfo::Stream *pClipInfo, int _PresentationType)
{
- const WCHAR *pPresentationDesc = NULL;
-
- if (pClipInfo)
- pPresentationDesc = StreamTypeToName(pClipInfo->m_Type);
- else
- pPresentationDesc = StreamTypeToName((PES_STREAM_TYPE)_PresentationType);
-
- CString MajorType;
- CAtlList<CString> Infos;
-
- if (_pMediaType->majortype == MEDIATYPE_Video)
- {
- MajorType = "Video";
-
- if (pClipInfo)
- {
- CString name = ISO6392ToLanguage(pClipInfo->m_LanguageCode);
-
- if (!name.IsEmpty())
- Infos.AddTail(name);
- }
-
- const VIDEOINFOHEADER *pVideoInfo = NULL;
- const VIDEOINFOHEADER2 *pVideoInfo2 = NULL;
-
- if (_pMediaType->formattype == FORMAT_MPEGVideo)
- {
- Infos.AddTail(L"MPEG");
-
- const MPEG1VIDEOINFO *pInfo = GetFormatHelper(pInfo, _pMediaType);
-
- pVideoInfo = &pInfo->hdr;
-
- }
- else if (_pMediaType->formattype == FORMAT_MPEG2_VIDEO)
- {
- const MPEG2VIDEOINFO *pInfo = GetFormatHelper(pInfo, _pMediaType);
-
- pVideoInfo2 = &pInfo->hdr;
-
- bool bIsAVC = false;
-
- if (pInfo->hdr.bmiHeader.biCompression == '1CVA')
- {
- bIsAVC = true;
- Infos.AddTail(L"AVC (H.264)");
- }
- else if (pInfo->hdr.bmiHeader.biCompression == 0)
- Infos.AddTail(L"MPEG2");
- else
- {
- WCHAR Temp[5];
- memset(Temp, 0, sizeof(Temp));
- Temp[0] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
- Temp[1] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
- Temp[2] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
- Temp[3] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
- Infos.AddTail(Temp);
- }
-
- switch (pInfo->dwProfile)
- {
- case AM_MPEG2Profile_Simple: Infos.AddTail(L"Simple Profile"); break;
- case AM_MPEG2Profile_Main: Infos.AddTail(L"Main Profile"); break;
- case AM_MPEG2Profile_SNRScalable: Infos.AddTail(L"SNR Scalable Profile"); break;
- case AM_MPEG2Profile_SpatiallyScalable: Infos.AddTail(L"Spatially Scalable Profile"); break;
- case AM_MPEG2Profile_High: Infos.AddTail(L"High Profile"); break;
- default:
- if (pInfo->dwProfile)
- {
- if (bIsAVC)
- {
- switch (pInfo->dwProfile)
- {
- case 44: Infos.AddTail(L"CAVLC Profile"); break;
- case 66: Infos.AddTail(L"Baseline Profile"); break;
- case 77: Infos.AddTail(L"Main Profile"); break;
- case 88: Infos.AddTail(L"Extended Profile"); break;
- case 100: Infos.AddTail(L"High Profile"); break;
- case 110: Infos.AddTail(L"High 10 Profile"); break;
- case 122: Infos.AddTail(L"High 4:2:2 Profile"); break;
- case 244: Infos.AddTail(L"High 4:4:4 Profile"); break;
-
- default: Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile)); break;
- }
- }
- else
- Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile));
- }
- break;
- }
-
- switch (pInfo->dwLevel)
- {
- case AM_MPEG2Level_Low: Infos.AddTail(L"Low Level"); break;
- case AM_MPEG2Level_Main: Infos.AddTail(L"Main Level"); break;
- case AM_MPEG2Level_High1440: Infos.AddTail(L"High1440 Level"); break;
- case AM_MPEG2Level_High: Infos.AddTail(L"High Level"); break;
- default:
- if (pInfo->dwLevel)
- {
- if (bIsAVC)
- Infos.AddTail(FormatString(L"Level %1.1f", double(pInfo->dwLevel)/10.0));
- else
- Infos.AddTail(FormatString(L"Level %d", pInfo->dwLevel));
- }
- break;
- }
- }
- else if (_pMediaType->formattype == FORMAT_VIDEOINFO2)
- {
- const VIDEOINFOHEADER2 *pInfo = GetFormatHelper(pInfo, _pMediaType);
-
- pVideoInfo2 = pInfo;
- bool bIsVC1 = false;
-
- DWORD CodecType = pInfo->bmiHeader.biCompression;
- if (CodecType == '1CVW')
- {
- bIsVC1 = true;
- Infos.AddTail(L"VC-1");
- }
- else if (CodecType)
- {
- WCHAR Temp[5];
- memset(Temp, 0, sizeof(Temp));
- Temp[0] = (CodecType >> 0) & 0xFF;
- Temp[1] = (CodecType >> 0) & 0xFF;
- Temp[2] = (CodecType >> 0) & 0xFF;
- Temp[3] = (CodecType >> 0) & 0xFF;
- Infos.AddTail(Temp);
- }
- }
- else if (_pMediaType->subtype == MEDIASUBTYPE_DVD_SUBPICTURE)
- {
- Infos.AddTail(L"DVD Sub Picture");
- }
- else if (_pMediaType->subtype == MEDIASUBTYPE_SVCD_SUBPICTURE)
- {
- Infos.AddTail(L"SVCD Sub Picture");
- }
- else if (_pMediaType->subtype == MEDIASUBTYPE_CVD_SUBPICTURE)
- {
- Infos.AddTail(L"CVD Sub Picture");
- }
-
- if (pVideoInfo2)
- {
- if (pVideoInfo2->bmiHeader.biWidth && pVideoInfo2->bmiHeader.biHeight)
- Infos.AddTail(FormatString(L"%dx%d", pVideoInfo2->bmiHeader.biWidth, pVideoInfo2->bmiHeader.biHeight));
- if (pVideoInfo2->AvgTimePerFrame)
- Infos.AddTail(FormatString(L"%.3f fps", 10000000.0/double(pVideoInfo2->AvgTimePerFrame)));
- if (pVideoInfo2->dwBitRate)
- Infos.AddTail(FormatBitrate(pVideoInfo2->dwBitRate));
- }
- else if (pVideoInfo)
- {
- if (pVideoInfo->bmiHeader.biWidth && pVideoInfo->bmiHeader.biHeight)
- Infos.AddTail(FormatString(L"%dx%d", pVideoInfo->bmiHeader.biWidth, pVideoInfo->bmiHeader.biHeight));
- if (pVideoInfo->AvgTimePerFrame)
- Infos.AddTail(FormatString(L"%.3f fps", 10000000.0/double(pVideoInfo->AvgTimePerFrame)));
- if (pVideoInfo->dwBitRate)
- Infos.AddTail(FormatBitrate(pVideoInfo->dwBitRate));
- }
-
- }
- else if (_pMediaType->majortype == MEDIATYPE_Audio)
- {
- MajorType = "Audio";
- if (pClipInfo)
- {
- CString name = ISO6392ToLanguage(pClipInfo->m_LanguageCode);
- if (!name.IsEmpty())
- Infos.AddTail(name);
- }
- if (_pMediaType->formattype == FORMAT_WaveFormatEx)
- {
- const WAVEFORMATEX *pInfo = GetFormatHelper(pInfo, _pMediaType);
-
- if (_pMediaType->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
- {
- Infos.AddTail(L"DVD LPCM");
- }
- else if (_pMediaType->subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
- {
- const WAVEFORMATEX_HDMV_LPCM *pInfoHDMV = GetFormatHelper(pInfoHDMV, _pMediaType);
- Infos.AddTail(L"HDMV LPCM");
- }
- else
- {
- switch (pInfo->wFormatTag)
- {
- case WAVE_FORMAT_PS2_PCM:
- {
- Infos.AddTail(L"PS2 PCM");
- }
- break;
- case WAVE_FORMAT_PS2_ADPCM:
- {
- Infos.AddTail(L"PS2 ADPCM");
- }
- break;
- case WAVE_FORMAT_DVD_DTS:
- {
- if (pPresentationDesc)
- Infos.AddTail(pPresentationDesc);
- else
- Infos.AddTail(L"DTS");
- }
- break;
- case WAVE_FORMAT_DOLBY_AC3:
- {
- if (pPresentationDesc)
- Infos.AddTail(pPresentationDesc);
- else
- Infos.AddTail(L"Dolby Digital");
- }
- break;
- case WAVE_FORMAT_AAC:
- {
- Infos.AddTail(L"AAC");
- }
- break;
- case WAVE_FORMAT_MP3:
- {
- Infos.AddTail(L"MP3");
- }
- break;
- case WAVE_FORMAT_MPEG:
- {
- const MPEG1WAVEFORMAT* pInfoMPEG1 = GetFormatHelper(pInfoMPEG1, _pMediaType);
-
- int layer = GetHighestBitSet32(pInfoMPEG1->fwHeadLayer) + 1;
- Infos.AddTail(FormatString(L"MPEG1 - Layer %d", layer));
- }
- break;
- }
- }
-
- if (pClipInfo && (pClipInfo->m_SampleRate == BDVM_SampleRate_48_192 || pClipInfo->m_SampleRate == BDVM_SampleRate_48_96))
- {
- switch (pClipInfo->m_SampleRate)
- {
- case BDVM_SampleRate_48_192:
- Infos.AddTail(FormatString(L"192(48) kHz"));
- break;
- case BDVM_SampleRate_48_96:
- Infos.AddTail(FormatString(L"96(48) kHz"));
- break;
- }
- }
- else if (pInfo->nSamplesPerSec)
- Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->nSamplesPerSec)/1000.0));
- if (pInfo->nChannels)
- Infos.AddTail(FormatString(L"%d chn", pInfo->nChannels));
- if (pInfo->wBitsPerSample)
- Infos.AddTail(FormatString(L"%d bit", pInfo->wBitsPerSample));
- if (pInfo->nAvgBytesPerSec)
- Infos.AddTail(FormatBitrate(pInfo->nAvgBytesPerSec * 8));
-
- }
- }
- else if (_pMediaType->majortype == MEDIATYPE_Subtitle)
- {
- MajorType = "Subtitle";
-
- if (pPresentationDesc)
- Infos.AddTail(pPresentationDesc);
-
- if (_pMediaType->cbFormat == sizeof(SUBTITLEINFO))
- {
- const SUBTITLEINFO *pInfo = GetFormatHelper(pInfo, _pMediaType);
- CString name = ISO6392ToLanguage(pInfo->IsoLang);
-
- if (pInfo->TrackName[0])
- Infos.AddHead(pInfo->TrackName);
- if (!name.IsEmpty())
- Infos.AddHead(name);
- }
- else
- {
- if (pClipInfo)
- {
- CString name = ISO6392ToLanguage(pClipInfo->m_LanguageCode);
- if (!name.IsEmpty())
- Infos.AddHead(name);
- }
- }
- }
-
- if (!Infos.IsEmpty())
- {
- CString Ret;
-
- Ret += MajorType;
- Ret += " - ";
-
- bool bFirst = true;
-
- for(POSITION pos = Infos.GetHeadPosition(); pos; Infos.GetNext(pos))
- {
- CString& String = Infos.GetAt(pos);
-
- if (bFirst)
- Ret += String;
- else
- Ret += L", " + String;
-
- bFirst = false;
- }
-
- return Ret;
- }
- return CString();
+ const WCHAR *pPresentationDesc = NULL;
+
+ if(pClipInfo)
+ pPresentationDesc = StreamTypeToName(pClipInfo->m_Type);
+ else
+ pPresentationDesc = StreamTypeToName((PES_STREAM_TYPE)_PresentationType);
+
+ CString MajorType;
+ CAtlList<CString> Infos;
+
+ if(_pMediaType->majortype == MEDIATYPE_Video)
+ {
+ MajorType = "Video";
+
+ if(pClipInfo)
+ {
+ CString name = ISO6392ToLanguage(pClipInfo->m_LanguageCode);
+
+ if(!name.IsEmpty())
+ Infos.AddTail(name);
+ }
+
+ const VIDEOINFOHEADER *pVideoInfo = NULL;
+ const VIDEOINFOHEADER2 *pVideoInfo2 = NULL;
+
+ if(_pMediaType->formattype == FORMAT_MPEGVideo)
+ {
+ Infos.AddTail(L"MPEG");
+
+ const MPEG1VIDEOINFO *pInfo = GetFormatHelper(pInfo, _pMediaType);
+
+ pVideoInfo = &pInfo->hdr;
+
+ }
+ else if(_pMediaType->formattype == FORMAT_MPEG2_VIDEO)
+ {
+ const MPEG2VIDEOINFO *pInfo = GetFormatHelper(pInfo, _pMediaType);
+
+ pVideoInfo2 = &pInfo->hdr;
+
+ bool bIsAVC = false;
+
+ if(pInfo->hdr.bmiHeader.biCompression == '1CVA')
+ {
+ bIsAVC = true;
+ Infos.AddTail(L"AVC (H.264)");
+ }
+ else if(pInfo->hdr.bmiHeader.biCompression == 0)
+ Infos.AddTail(L"MPEG2");
+ else
+ {
+ WCHAR Temp[5];
+ memset(Temp, 0, sizeof(Temp));
+ Temp[0] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
+ Temp[1] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
+ Temp[2] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
+ Temp[3] = (pInfo->hdr.bmiHeader.biCompression >> 0) & 0xFF;
+ Infos.AddTail(Temp);
+ }
+
+ switch(pInfo->dwProfile)
+ {
+ case AM_MPEG2Profile_Simple:
+ Infos.AddTail(L"Simple Profile");
+ break;
+ case AM_MPEG2Profile_Main:
+ Infos.AddTail(L"Main Profile");
+ break;
+ case AM_MPEG2Profile_SNRScalable:
+ Infos.AddTail(L"SNR Scalable Profile");
+ break;
+ case AM_MPEG2Profile_SpatiallyScalable:
+ Infos.AddTail(L"Spatially Scalable Profile");
+ break;
+ case AM_MPEG2Profile_High:
+ Infos.AddTail(L"High Profile");
+ break;
+ default:
+ if(pInfo->dwProfile)
+ {
+ if(bIsAVC)
+ {
+ switch(pInfo->dwProfile)
+ {
+ case 44:
+ Infos.AddTail(L"CAVLC Profile");
+ break;
+ case 66:
+ Infos.AddTail(L"Baseline Profile");
+ break;
+ case 77:
+ Infos.AddTail(L"Main Profile");
+ break;
+ case 88:
+ Infos.AddTail(L"Extended Profile");
+ break;
+ case 100:
+ Infos.AddTail(L"High Profile");
+ break;
+ case 110:
+ Infos.AddTail(L"High 10 Profile");
+ break;
+ case 122:
+ Infos.AddTail(L"High 4:2:2 Profile");
+ break;
+ case 244:
+ Infos.AddTail(L"High 4:4:4 Profile");
+ break;
+
+ default:
+ Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile));
+ break;
+ }
+ }
+ else
+ Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile));
+ }
+ break;
+ }
+
+ switch(pInfo->dwLevel)
+ {
+ case AM_MPEG2Level_Low:
+ Infos.AddTail(L"Low Level");
+ break;
+ case AM_MPEG2Level_Main:
+ Infos.AddTail(L"Main Level");
+ break;
+ case AM_MPEG2Level_High1440:
+ Infos.AddTail(L"High1440 Level");
+ break;
+ case AM_MPEG2Level_High:
+ Infos.AddTail(L"High Level");
+ break;
+ default:
+ if(pInfo->dwLevel)
+ {
+ if(bIsAVC)
+ Infos.AddTail(FormatString(L"Level %1.1f", double(pInfo->dwLevel) / 10.0));
+ else
+ Infos.AddTail(FormatString(L"Level %d", pInfo->dwLevel));
+ }
+ break;
+ }
+ }
+ else if(_pMediaType->formattype == FORMAT_VIDEOINFO2)
+ {
+ const VIDEOINFOHEADER2 *pInfo = GetFormatHelper(pInfo, _pMediaType);
+
+ pVideoInfo2 = pInfo;
+ bool bIsVC1 = false;
+
+ DWORD CodecType = pInfo->bmiHeader.biCompression;
+ if(CodecType == '1CVW')
+ {
+ bIsVC1 = true;
+ Infos.AddTail(L"VC-1");
+ }
+ else if(CodecType)
+ {
+ WCHAR Temp[5];
+ memset(Temp, 0, sizeof(Temp));
+ Temp[0] = (CodecType >> 0) & 0xFF;
+ Temp[1] = (CodecType >> 0) & 0xFF;
+ Temp[2] = (CodecType >> 0) & 0xFF;
+ Temp[3] = (CodecType >> 0) & 0xFF;
+ Infos.AddTail(Temp);
+ }
+ }
+ else if(_pMediaType->subtype == MEDIASUBTYPE_DVD_SUBPICTURE)
+ {
+ Infos.AddTail(L"DVD Sub Picture");
+ }
+ else if(_pMediaType->subtype == MEDIASUBTYPE_SVCD_SUBPICTURE)
+ {
+ Infos.AddTail(L"SVCD Sub Picture");
+ }
+ else if(_pMediaType->subtype == MEDIASUBTYPE_CVD_SUBPICTURE)
+ {
+ Infos.AddTail(L"CVD Sub Picture");
+ }
+
+ if(pVideoInfo2)
+ {
+ if(pVideoInfo2->bmiHeader.biWidth && pVideoInfo2->bmiHeader.biHeight)
+ Infos.AddTail(FormatString(L"%dx%d", pVideoInfo2->bmiHeader.biWidth, pVideoInfo2->bmiHeader.biHeight));
+ if(pVideoInfo2->AvgTimePerFrame)
+ Infos.AddTail(FormatString(L"%.3f fps", 10000000.0 / double(pVideoInfo2->AvgTimePerFrame)));
+ if(pVideoInfo2->dwBitRate)
+ Infos.AddTail(FormatBitrate(pVideoInfo2->dwBitRate));
+ }
+ else if(pVideoInfo)
+ {
+ if(pVideoInfo->bmiHeader.biWidth && pVideoInfo->bmiHeader.biHeight)
+ Infos.AddTail(FormatString(L"%dx%d", pVideoInfo->bmiHeader.biWidth, pVideoInfo->bmiHeader.biHeight));
+ if(pVideoInfo->AvgTimePerFrame)
+ Infos.AddTail(FormatString(L"%.3f fps", 10000000.0 / double(pVideoInfo->AvgTimePerFrame)));
+ if(pVideoInfo->dwBitRate)
+ Infos.AddTail(FormatBitrate(pVideoInfo->dwBitRate));
+ }
+
+ }
+ else if(_pMediaType->majortype == MEDIATYPE_Audio)
+ {
+ MajorType = "Audio";
+ if(pClipInfo)
+ {
+ CString name = ISO6392ToLanguage(pClipInfo->m_LanguageCode);
+ if(!name.IsEmpty())
+ Infos.AddTail(name);
+ }
+ if(_pMediaType->formattype == FORMAT_WaveFormatEx)
+ {
+ const WAVEFORMATEX *pInfo = GetFormatHelper(pInfo, _pMediaType);
+
+ if(_pMediaType->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
+ {
+ Infos.AddTail(L"DVD LPCM");
+ }
+ else if(_pMediaType->subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
+ {
+ const WAVEFORMATEX_HDMV_LPCM *pInfoHDMV = GetFormatHelper(pInfoHDMV, _pMediaType);
+ Infos.AddTail(L"HDMV LPCM");
+ }
+ else
+ {
+ switch(pInfo->wFormatTag)
+ {
+ case WAVE_FORMAT_PS2_PCM:
+ {
+ Infos.AddTail(L"PS2 PCM");
+ }
+ break;
+ case WAVE_FORMAT_PS2_ADPCM:
+ {
+ Infos.AddTail(L"PS2 ADPCM");
+ }
+ break;
+ case WAVE_FORMAT_DVD_DTS:
+ {
+ if(pPresentationDesc)
+ Infos.AddTail(pPresentationDesc);
+ else
+ Infos.AddTail(L"DTS");
+ }
+ break;
+ case WAVE_FORMAT_DOLBY_AC3:
+ {
+ if(pPresentationDesc)
+ Infos.AddTail(pPresentationDesc);
+ else
+ Infos.AddTail(L"Dolby Digital");
+ }
+ break;
+ case WAVE_FORMAT_AAC:
+ {
+ Infos.AddTail(L"AAC");
+ }
+ break;
+ case WAVE_FORMAT_MP3:
+ {
+ Infos.AddTail(L"MP3");
+ }
+ break;
+ case WAVE_FORMAT_MPEG:
+ {
+ const MPEG1WAVEFORMAT* pInfoMPEG1 = GetFormatHelper(pInfoMPEG1, _pMediaType);
+
+ int layer = GetHighestBitSet32(pInfoMPEG1->fwHeadLayer) + 1;
+ Infos.AddTail(FormatString(L"MPEG1 - Layer %d", layer));
+ }
+ break;
+ }
+ }
+
+ if(pClipInfo && (pClipInfo->m_SampleRate == BDVM_SampleRate_48_192 || pClipInfo->m_SampleRate == BDVM_SampleRate_48_96))
+ {
+ switch(pClipInfo->m_SampleRate)
+ {
+ case BDVM_SampleRate_48_192:
+ Infos.AddTail(FormatString(L"192(48) kHz"));
+ break;
+ case BDVM_SampleRate_48_96:
+ Infos.AddTail(FormatString(L"96(48) kHz"));
+ break;
+ }
+ }
+ else if(pInfo->nSamplesPerSec)
+ Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->nSamplesPerSec) / 1000.0));
+ if(pInfo->nChannels)
+ Infos.AddTail(FormatString(L"%d chn", pInfo->nChannels));
+ if(pInfo->wBitsPerSample)
+ Infos.AddTail(FormatString(L"%d bit", pInfo->wBitsPerSample));
+ if(pInfo->nAvgBytesPerSec)
+ Infos.AddTail(FormatBitrate(pInfo->nAvgBytesPerSec * 8));
+
+ }
+ }
+ else if(_pMediaType->majortype == MEDIATYPE_Subtitle)
+ {
+ MajorType = "Subtitle";
+
+ if(pPresentationDesc)
+ Infos.AddTail(pPresentationDesc);
+
+ if(_pMediaType->cbFormat == sizeof(SUBTITLEINFO))
+ {
+ const SUBTITLEINFO *pInfo = GetFormatHelper(pInfo, _pMediaType);
+ CString name = ISO6392ToLanguage(pInfo->IsoLang);
+
+ if(pInfo->TrackName[0])
+ Infos.AddHead(pInfo->TrackName);
+ if(!name.IsEmpty())
+ Infos.AddHead(name);
+ }
+ else
+ {
+ if(pClipInfo)
+ {
+ CString name = ISO6392ToLanguage(pClipInfo->m_LanguageCode);
+ if(!name.IsEmpty())
+ Infos.AddHead(name);
+ }
+ }
+ }
+
+ if(!Infos.IsEmpty())
+ {
+ CString Ret;
+
+ Ret += MajorType;
+ Ret += " - ";
+
+ bool bFirst = true;
+
+ for(POSITION pos = Infos.GetHeadPosition(); pos; Infos.GetNext(pos))
+ {
+ CString& String = Infos.GetAt(pos);
+
+ if(bFirst)
+ Ret += String;
+ else
+ Ret += L", " + String;
+
+ bFirst = false;
+ }
+
+ return Ret;
+ }
+ return CString();
}
STDMETHODIMP CMpegSplitterFilter::Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk)
{
- for(int i = 0, j = 0; i < countof(m_pFile->m_streams); i++)
- {
- int cnt = m_pFile->m_streams[i].GetCount();
-
- if(lIndex >= j && lIndex < j+cnt)
- {
- lIndex -= j;
-
- POSITION pos = m_pFile->m_streams[i].FindIndex(lIndex);
- if(!pos) return E_UNEXPECTED;
-
- CMpegSplitterFile::stream& s = m_pFile->m_streams[i].GetAt(pos);
- CHdmvClipInfo::Stream* pStream = m_ClipInfo.FindStream (s.pid);
-
- if(ppmt) *ppmt = CreateMediaType(&s.mt);
- if(pdwFlags) *pdwFlags = GetOutputPin(s) ? (AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE) : 0;
- if(plcid) *plcid = pStream ? pStream->m_LCID : 0;
- if(pdwGroup) *pdwGroup = i;
- if(ppObject) *ppObject = NULL;
- if(ppUnk) *ppUnk = NULL;
-
-
- if(ppszName)
- {
- CStringW name = CMpegSplitterFile::CStreamList::ToString(i);
-
- CStringW str;
-
- if (i == CMpegSplitterFile::subpic && s.pid == NO_SUBTITLE_PID)
- {
- str = _T("No subtitles");
- *plcid = LCID_NOSUBTITLES;
- }
- else
- {
- int iProgram;
- const CHdmvClipInfo::Stream *pClipInfo;
- const CMpegSplitterFile::program * pProgram = m_pFile->FindProgram(s.pid, iProgram, pClipInfo);
- const wchar_t *pStreamName = NULL;
- int StreamType = pClipInfo ? pClipInfo->m_Type : pProgram ? pProgram->streams[iProgram].type : 0;
- pStreamName = StreamTypeToName((PES_STREAM_TYPE)StreamType);
-
- CString FormatDesc = GetMediaTypeDesc(&s.mt, pClipInfo, StreamType);
-
- if (!FormatDesc.IsEmpty())
- str.Format(L"%s (%04x,%02x,%02x)", FormatDesc.GetString(), s.pid, s.pesid, s.ps1id); // TODO: make this nicer
- else if (pStreamName)
- str.Format(L"%s - %s (%04x,%02x,%02x)", name, pStreamName, s.pid, s.pesid, s.ps1id); // TODO: make this nicer
- else
- str.Format(L"%s (%04x,%02x,%02x)", name, s.pid, s.pesid, s.ps1id); // TODO: make this nicer
- }
-
- *ppszName = (WCHAR*)CoTaskMemAlloc((str.GetLength()+1)*sizeof(WCHAR));
- if(*ppszName == NULL) return E_OUTOFMEMORY;
-
- wcscpy_s(*ppszName, str.GetLength()+1, str);
- }
- }
-
- j += cnt;
- }
-
- return S_OK;
+ for(int i = 0, j = 0; i < countof(m_pFile->m_streams); i++)
+ {
+ int cnt = m_pFile->m_streams[i].GetCount();
+
+ if(lIndex >= j && lIndex < j + cnt)
+ {
+ lIndex -= j;
+
+ POSITION pos = m_pFile->m_streams[i].FindIndex(lIndex);
+ if(!pos) return E_UNEXPECTED;
+
+ CMpegSplitterFile::stream& s = m_pFile->m_streams[i].GetAt(pos);
+ CHdmvClipInfo::Stream* pStream = m_ClipInfo.FindStream(s.pid);
+
+ if(ppmt) *ppmt = CreateMediaType(&s.mt);
+ if(pdwFlags) *pdwFlags = GetOutputPin(s) ? (AMSTREAMSELECTINFO_ENABLED | AMSTREAMSELECTINFO_EXCLUSIVE) : 0;
+ if(plcid) *plcid = pStream ? pStream->m_LCID : 0;
+ if(pdwGroup) *pdwGroup = i;
+ if(ppObject) *ppObject = NULL;
+ if(ppUnk) *ppUnk = NULL;
+
+
+ if(ppszName)
+ {
+ CStringW name = CMpegSplitterFile::CStreamList::ToString(i);
+
+ CStringW str;
+
+ if(i == CMpegSplitterFile::subpic && s.pid == NO_SUBTITLE_PID)
+ {
+ str = _T("No subtitles");
+ *plcid = LCID_NOSUBTITLES;
+ }
+ else
+ {
+ int iProgram;
+ const CHdmvClipInfo::Stream *pClipInfo;
+ const CMpegSplitterFile::program * pProgram = m_pFile->FindProgram(s.pid, iProgram, pClipInfo);
+ const wchar_t *pStreamName = NULL;
+ int StreamType = pClipInfo ? pClipInfo->m_Type : pProgram ? pProgram->streams[iProgram].type : 0;
+ pStreamName = StreamTypeToName((PES_STREAM_TYPE)StreamType);
+
+ CString FormatDesc = GetMediaTypeDesc(&s.mt, pClipInfo, StreamType);
+
+ if(!FormatDesc.IsEmpty())
+ str.Format(L"%s (%04x,%02x,%02x)", FormatDesc.GetString(), s.pid, s.pesid, s.ps1id); // TODO: make this nicer
+ else if(pStreamName)
+ str.Format(L"%s - %s (%04x,%02x,%02x)", name, pStreamName, s.pid, s.pesid, s.ps1id); // TODO: make this nicer
+ else
+ str.Format(L"%s (%04x,%02x,%02x)", name, s.pid, s.pesid, s.ps1id); // TODO: make this nicer
+ }
+
+ *ppszName = (WCHAR*)CoTaskMemAlloc((str.GetLength() + 1) * sizeof(WCHAR));
+ if(*ppszName == NULL) return E_OUTOFMEMORY;
+
+ wcscpy_s(*ppszName, str.GetLength() + 1, str);
+ }
+ }
+
+ j += cnt;
+ }
+
+ return S_OK;
}
//
@@ -1121,9 +1157,9 @@ STDMETHODIMP CMpegSplitterFilter::Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD*
//
CMpegSourceFilter::CMpegSourceFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid)
- : CMpegSplitterFilter(pUnk, phr, clsid)
+ : CMpegSplitterFilter(pUnk, phr, clsid)
{
- m_pInput.Free();
+ m_pInput.Free();
}
//
@@ -1131,9 +1167,9 @@ CMpegSourceFilter::CMpegSourceFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID&
//
CMpegSplitterOutputPin::CMpegSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseSplitterOutputPin(mts, pName, pFilter, pLock, phr)
- , m_fHasAccessUnitDelimiters(false)
- , m_rtMaxShift(50000000)
+ : CBaseSplitterOutputPin(mts, pName, pFilter, pLock, phr)
+ , m_fHasAccessUnitDelimiters(false)
+ , m_rtMaxShift(50000000)
{
}
@@ -1143,456 +1179,460 @@ CMpegSplitterOutputPin::~CMpegSplitterOutputPin()
HRESULT CMpegSplitterOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- {
- CAutoLock cAutoLock(this);
- m_rtPrev = Packet::INVALID_TIME;
- m_rtOffset = 0;
- }
+ {
+ CAutoLock cAutoLock(this);
+ m_rtPrev = Packet::INVALID_TIME;
+ m_rtOffset = 0;
+ }
- return __super::DeliverNewSegment(tStart, tStop, dRate);
+ return __super::DeliverNewSegment(tStart, tStop, dRate);
}
HRESULT CMpegSplitterOutputPin::DeliverEndFlush()
{
- {
- CAutoLock cAutoLock(this);
- m_p.Free();
- m_pl.RemoveAll();
- }
+ {
+ CAutoLock cAutoLock(this);
+ m_p.Free();
+ m_pl.RemoveAll();
+ }
- return __super::DeliverEndFlush();
+ return __super::DeliverEndFlush();
}
HRESULT CMpegSplitterOutputPin::DeliverPacket(CAutoPtr<Packet> p)
{
- CAutoLock cAutoLock(this);
-
- if(p->rtStart != Packet::INVALID_TIME)
- {
- REFERENCE_TIME rt = p->rtStart + m_rtOffset;
-
- // Filter invalid PTS (if too different from previous packet)
- if(m_rtPrev != Packet::INVALID_TIME)
- if(_abs64(rt - m_rtPrev) > m_rtMaxShift)
- m_rtOffset += m_rtPrev - rt;
-
- p->rtStart += m_rtOffset;
- p->rtStop += m_rtOffset;
-
- m_rtPrev = p->rtStart;
- }
-
-
- if (p->pmt)
- {
- if (*((CMediaType *)p->pmt) != m_mt)
- SetMediaType ((CMediaType*)p->pmt);
- }
-
-
- if(m_mt.subtype == MEDIASUBTYPE_AAC) // special code for aac, the currently available decoders only like whole frame samples
- {
- if(m_p && m_p->GetCount() == 1 && m_p->GetAt(0) == 0xff && !(!p->IsEmpty() && (p->GetAt(0) & 0xf6) == 0xf0))
- m_p.Free();
-
- if(!m_p)
- {
- BYTE* base = p->GetData();
- BYTE* s = base;
- BYTE* e = s + p->GetCount();
-
- for(; s < e; s++)
- {
- if(*s != 0xff) continue;
-
- if(s == e-1 || (s[1]&0xf6) == 0xf0)
- {
- memmove(base, s, e - s);
- p->SetCount(e - s);
- m_p = p;
- break;
- }
- }
- }
- else
- {
- m_p->Append(*p);
- }
-
- while(m_p && m_p->GetCount() > 9)
- {
- BYTE* base = m_p->GetData();
- BYTE* s = base;
- BYTE* e = s + m_p->GetCount();
- int len = ((s[3]&3)<<11)|(s[4]<<3)|(s[5]>>5);
- bool crc = !(s[1]&1);
- s += 7; len -= 7;
- if(crc) s += 2, len -= 2;
-
- if(e - s < len)
- {
- break;
- }
-
- if(len <= 0 || e - s >= len + 2 && (s[len] != 0xff || (s[len+1]&0xf6) != 0xf0))
- {
- m_p.Free();
- break;
- }
-
- CAutoPtr<Packet> p2(DNew Packet());
-
- p2->TrackNumber = m_p->TrackNumber;
- p2->bDiscontinuity |= m_p->bDiscontinuity;
- m_p->bDiscontinuity = false;
-
- p2->bSyncPoint = m_p->rtStart != Packet::INVALID_TIME;
- p2->rtStart = m_p->rtStart;
- m_p->rtStart = Packet::INVALID_TIME;
-
- p2->rtStop = m_p->rtStop;
- m_p->rtStop = Packet::INVALID_TIME;
- p2->pmt = m_p->pmt; m_p->pmt = NULL;
- p2->SetData(s, len);
-
- s += len;
- memmove(base, s, e - s);
- m_p->SetCount(e - s);
-
- HRESULT hr = __super::DeliverPacket(p2);
- if(hr != S_OK) return hr;
- }
-
- if(m_p && p)
- {
- if(!m_p->bDiscontinuity) m_p->bDiscontinuity = p->bDiscontinuity;
- if(!m_p->bSyncPoint) m_p->bSyncPoint = p->bSyncPoint;
- if(m_p->rtStart == Packet::INVALID_TIME) m_p->rtStart = p->rtStart, m_p->rtStop = p->rtStop;
- if(m_p->pmt) DeleteMediaType(m_p->pmt);
-
- m_p->pmt = p->pmt;
- p->pmt = NULL;
- }
-
- return S_OK;
- }
- else if(m_mt.subtype == FOURCCMap('1CVA') || m_mt.subtype == FOURCCMap('1cva')) // just like aac, this has to be starting nalus, more can be packed together
- {
- if(!m_p)
- {
- m_p.Attach(DNew Packet());
- m_p->TrackNumber = p->TrackNumber;
- m_p->bDiscontinuity = p->bDiscontinuity;
- p->bDiscontinuity = FALSE;
-
- m_p->bSyncPoint = p->bSyncPoint;
- p->bSyncPoint = FALSE;
-
- m_p->rtStart = p->rtStart;
- p->rtStart = Packet::INVALID_TIME;
-
- m_p->rtStop = p->rtStop;
- p->rtStop = Packet::INVALID_TIME;
- }
-
- m_p->Append(*p);
-
- BYTE* start = m_p->GetData();
- BYTE* end = start + m_p->GetCount();
-
- while(start <= end-4 && *(DWORD*)start != 0x01000000) start++;
-
- while(start <= end-4)
- {
- BYTE* next = start+1;
-
- while(next <= end-4 && *(DWORD*)next != 0x01000000) next++;
-
- if(next >= end-4) break;
-
- int size = next - start;
-
- CH264Nalu Nalu;
- Nalu.SetBuffer (start, size, 0);
-
- CAutoPtr<Packet> p2;
-
- while (Nalu.ReadNext())
- {
- DWORD dwNalLength =
- ((Nalu.GetDataLength() >> 24) & 0x000000ff) |
- ((Nalu.GetDataLength() >> 8) & 0x0000ff00) |
- ((Nalu.GetDataLength() << 8) & 0x00ff0000) |
- ((Nalu.GetDataLength() << 24) & 0xff000000);
-
- CAutoPtr<Packet> p3(DNew Packet());
-
- p3->SetCount (Nalu.GetDataLength()+sizeof(dwNalLength));
- memcpy (p3->GetData(), &dwNalLength, sizeof(dwNalLength));
- memcpy (p3->GetData()+sizeof(dwNalLength), Nalu.GetDataBuffer(), Nalu.GetDataLength());
-
- if (p2 == NULL)
- p2 = p3;
- else
- p2->Append(*p3);
- }
-
- p2->TrackNumber = m_p->TrackNumber;
- p2->bDiscontinuity = m_p->bDiscontinuity;
- m_p->bDiscontinuity = FALSE;
-
- p2->bSyncPoint = m_p->bSyncPoint;
- m_p->bSyncPoint = FALSE;
-
- p2->rtStart = m_p->rtStart; m_p->rtStart = Packet::INVALID_TIME;
- p2->rtStop = m_p->rtStop;
- m_p->rtStop = Packet::INVALID_TIME;
-
- p2->pmt = m_p->pmt; m_p->pmt = NULL;
-
- m_pl.AddTail(p2);
-
- if(p->rtStart != Packet::INVALID_TIME)
- {
- m_p->rtStart = p->rtStart;
- m_p->rtStop = p->rtStop;
- p->rtStart = Packet::INVALID_TIME;
- }
- if(p->bDiscontinuity)
- {
- m_p->bDiscontinuity = p->bDiscontinuity;
- p->bDiscontinuity = FALSE;
- }
- if(p->bSyncPoint)
- {
- m_p->bSyncPoint = p->bSyncPoint;
- p->bSyncPoint = FALSE;
- }
- if(m_p->pmt)
- DeleteMediaType(m_p->pmt);
-
- m_p->pmt = p->pmt;
- p->pmt = NULL;
-
- start = next;
- }
- if(start > m_p->GetData())
- {
- m_p->RemoveAt(0, start - m_p->GetData());
- }
-
- for(POSITION pos = m_pl.GetHeadPosition(); pos; m_pl.GetNext(pos))
- {
- if(pos == m_pl.GetHeadPosition())
- continue;
-
- Packet* pPacket = m_pl.GetAt(pos);
- BYTE* pData = pPacket->GetData();
-
- if((pData[4]&0x1f) == 0x09) m_fHasAccessUnitDelimiters = true;
-
- if((pData[4]&0x1f) == 0x09 || !m_fHasAccessUnitDelimiters && pPacket->rtStart != Packet::INVALID_TIME)
- {
- p = m_pl.RemoveHead();
-
- while(pos != m_pl.GetHeadPosition())
- {
- CAutoPtr<Packet> p2 = m_pl.RemoveHead();
- p->Append(*p2);
- }
-
- HRESULT hr = __super::DeliverPacket(p);
- if(hr != S_OK) return hr;
- }
- }
-
- return S_OK;
- }
- else if(m_mt.subtype == FOURCCMap('1CVW') || m_mt.subtype == FOURCCMap('1cvw')) // just like aac, this has to be starting nalus, more can be packed together
- {
- if(!m_p)
- {
- m_p.Attach(DNew Packet());
- m_p->TrackNumber = p->TrackNumber;
- m_p->bDiscontinuity = p->bDiscontinuity;
- p->bDiscontinuity = FALSE;
-
- m_p->bSyncPoint = p->bSyncPoint;
- p->bSyncPoint = FALSE;
-
- m_p->rtStart = p->rtStart;
- p->rtStart = Packet::INVALID_TIME;
-
- m_p->rtStop = p->rtStop;
- p->rtStop = Packet::INVALID_TIME;
- }
-
- m_p->Append(*p);
-
- BYTE* start = m_p->GetData();
- BYTE* end = start + m_p->GetCount();
-
- bool bSeqFound = false;
- while(start <= end-4)
- {
- if (*(DWORD*)start == 0x0D010000)
- {
- bSeqFound = true;
- break;
- }
- else if (*(DWORD*)start == 0x0F010000)
- break;
- start++;
- }
-
- while(start <= end-4)
- {
- BYTE* next = start+1;
-
- while(next <= end-4)
- {
- if (*(DWORD*)next == 0x0D010000)
- {
- if (bSeqFound) break;
- bSeqFound = true;
- }
- else if (*(DWORD*)next == 0x0F010000)
- break;
- next++;
- }
-
- if(next >= end-4) break;
-
- int size = next - start - 4;
-
-
- CAutoPtr<Packet> p2(DNew Packet());
- p2->TrackNumber = m_p->TrackNumber;
- p2->bDiscontinuity = m_p->bDiscontinuity;
- m_p->bDiscontinuity = FALSE;
-
- p2->bSyncPoint = m_p->bSyncPoint;
- m_p->bSyncPoint = FALSE;
-
- p2->rtStart = m_p->rtStart;
- m_p->rtStart = Packet::INVALID_TIME;
-
- p2->rtStop = m_p->rtStop;
- m_p->rtStop = Packet::INVALID_TIME;
-
- p2->pmt = m_p->pmt;
- m_p->pmt = NULL;
-
- p2->SetData(start, next - start);
-
- HRESULT hr = __super::DeliverPacket(p2);
- if(hr != S_OK) return hr;
-
- if(p->rtStart != Packet::INVALID_TIME)
- {
- m_p->rtStart = p->rtStart;
- m_p->rtStop = p->rtStop;
- p->rtStart = Packet::INVALID_TIME;
- }
- if(p->bDiscontinuity)
- {
- m_p->bDiscontinuity = p->bDiscontinuity;
- p->bDiscontinuity = FALSE;
- }
- if(p->bSyncPoint)
- {
- m_p->bSyncPoint = p->bSyncPoint;
- p->bSyncPoint = FALSE;
- }
- if(m_p->pmt)
- DeleteMediaType(m_p->pmt);
-
- m_p->pmt = p->pmt;
- p->pmt = NULL;
-
- start = next;
- bSeqFound = (*(DWORD*)start == 0x0D010000);
- }
-
- if(start > m_p->GetData())
- {
- m_p->RemoveAt(0, start - m_p->GetData());
- }
-
- return S_OK;
- }
- else if (m_mt.subtype == MEDIASUBTYPE_DTS || m_mt.subtype == MEDIASUBTYPE_WAVE_DTS) // DTS HD MA data is causing trouble, lets just remove it
- {
+ CAutoLock cAutoLock(this);
+
+ if(p->rtStart != Packet::INVALID_TIME)
+ {
+ REFERENCE_TIME rt = p->rtStart + m_rtOffset;
+
+ // Filter invalid PTS (if too different from previous packet)
+ if(m_rtPrev != Packet::INVALID_TIME)
+ if(_abs64(rt - m_rtPrev) > m_rtMaxShift)
+ m_rtOffset += m_rtPrev - rt;
+
+ p->rtStart += m_rtOffset;
+ p->rtStop += m_rtOffset;
+
+ m_rtPrev = p->rtStart;
+ }
+
+
+ if(p->pmt)
+ {
+ if(*((CMediaType *)p->pmt) != m_mt)
+ SetMediaType((CMediaType*)p->pmt);
+ }
+
+
+ if(m_mt.subtype == MEDIASUBTYPE_AAC) // special code for aac, the currently available decoders only like whole frame samples
+ {
+ if(m_p && m_p->GetCount() == 1 && m_p->GetAt(0) == 0xff && !(!p->IsEmpty() && (p->GetAt(0) & 0xf6) == 0xf0))
+ m_p.Free();
+
+ if(!m_p)
+ {
+ BYTE* base = p->GetData();
+ BYTE* s = base;
+ BYTE* e = s + p->GetCount();
+
+ for(; s < e; s++)
+ {
+ if(*s != 0xff) continue;
+
+ if(s == e - 1 || (s[1] & 0xf6) == 0xf0)
+ {
+ memmove(base, s, e - s);
+ p->SetCount(e - s);
+ m_p = p;
+ break;
+ }
+ }
+ }
+ else
+ {
+ m_p->Append(*p);
+ }
+
+ while(m_p && m_p->GetCount() > 9)
+ {
+ BYTE* base = m_p->GetData();
+ BYTE* s = base;
+ BYTE* e = s + m_p->GetCount();
+ int len = ((s[3] & 3) << 11) | (s[4] << 3) | (s[5] >> 5);
+ bool crc = !(s[1] & 1);
+ s += 7;
+ len -= 7;
+ if(crc) s += 2, len -= 2;
+
+ if(e - s < len)
+ {
+ break;
+ }
+
+ if(len <= 0 || e - s >= len + 2 && (s[len] != 0xff || (s[len+1] & 0xf6) != 0xf0))
+ {
+ m_p.Free();
+ break;
+ }
+
+ CAutoPtr<Packet> p2(DNew Packet());
+
+ p2->TrackNumber = m_p->TrackNumber;
+ p2->bDiscontinuity |= m_p->bDiscontinuity;
+ m_p->bDiscontinuity = false;
+
+ p2->bSyncPoint = m_p->rtStart != Packet::INVALID_TIME;
+ p2->rtStart = m_p->rtStart;
+ m_p->rtStart = Packet::INVALID_TIME;
+
+ p2->rtStop = m_p->rtStop;
+ m_p->rtStop = Packet::INVALID_TIME;
+ p2->pmt = m_p->pmt;
+ m_p->pmt = NULL;
+ p2->SetData(s, len);
+
+ s += len;
+ memmove(base, s, e - s);
+ m_p->SetCount(e - s);
+
+ HRESULT hr = __super::DeliverPacket(p2);
+ if(hr != S_OK) return hr;
+ }
+
+ if(m_p && p)
+ {
+ if(!m_p->bDiscontinuity) m_p->bDiscontinuity = p->bDiscontinuity;
+ if(!m_p->bSyncPoint) m_p->bSyncPoint = p->bSyncPoint;
+ if(m_p->rtStart == Packet::INVALID_TIME) m_p->rtStart = p->rtStart, m_p->rtStop = p->rtStop;
+ if(m_p->pmt) DeleteMediaType(m_p->pmt);
+
+ m_p->pmt = p->pmt;
+ p->pmt = NULL;
+ }
+
+ return S_OK;
+ }
+ else if(m_mt.subtype == FOURCCMap('1CVA') || m_mt.subtype == FOURCCMap('1cva')) // just like aac, this has to be starting nalus, more can be packed together
+ {
+ if(!m_p)
+ {
+ m_p.Attach(DNew Packet());
+ m_p->TrackNumber = p->TrackNumber;
+ m_p->bDiscontinuity = p->bDiscontinuity;
+ p->bDiscontinuity = FALSE;
+
+ m_p->bSyncPoint = p->bSyncPoint;
+ p->bSyncPoint = FALSE;
+
+ m_p->rtStart = p->rtStart;
+ p->rtStart = Packet::INVALID_TIME;
+
+ m_p->rtStop = p->rtStop;
+ p->rtStop = Packet::INVALID_TIME;
+ }
+
+ m_p->Append(*p);
+
+ BYTE* start = m_p->GetData();
+ BYTE* end = start + m_p->GetCount();
+
+ while(start <= end - 4 && *(DWORD*)start != 0x01000000) start++;
+
+ while(start <= end - 4)
+ {
+ BYTE* next = start + 1;
+
+ while(next <= end - 4 && *(DWORD*)next != 0x01000000) next++;
+
+ if(next >= end - 4) break;
+
+ int size = next - start;
+
+ CH264Nalu Nalu;
+ Nalu.SetBuffer(start, size, 0);
+
+ CAutoPtr<Packet> p2;
+
+ while(Nalu.ReadNext())
+ {
+ DWORD dwNalLength =
+ ((Nalu.GetDataLength() >> 24) & 0x000000ff) |
+ ((Nalu.GetDataLength() >> 8) & 0x0000ff00) |
+ ((Nalu.GetDataLength() << 8) & 0x00ff0000) |
+ ((Nalu.GetDataLength() << 24) & 0xff000000);
+
+ CAutoPtr<Packet> p3(DNew Packet());
+
+ p3->SetCount(Nalu.GetDataLength() + sizeof(dwNalLength));
+ memcpy(p3->GetData(), &dwNalLength, sizeof(dwNalLength));
+ memcpy(p3->GetData() + sizeof(dwNalLength), Nalu.GetDataBuffer(), Nalu.GetDataLength());
+
+ if(p2 == NULL)
+ p2 = p3;
+ else
+ p2->Append(*p3);
+ }
+
+ p2->TrackNumber = m_p->TrackNumber;
+ p2->bDiscontinuity = m_p->bDiscontinuity;
+ m_p->bDiscontinuity = FALSE;
+
+ p2->bSyncPoint = m_p->bSyncPoint;
+ m_p->bSyncPoint = FALSE;
+
+ p2->rtStart = m_p->rtStart;
+ m_p->rtStart = Packet::INVALID_TIME;
+ p2->rtStop = m_p->rtStop;
+ m_p->rtStop = Packet::INVALID_TIME;
+
+ p2->pmt = m_p->pmt;
+ m_p->pmt = NULL;
+
+ m_pl.AddTail(p2);
+
+ if(p->rtStart != Packet::INVALID_TIME)
+ {
+ m_p->rtStart = p->rtStart;
+ m_p->rtStop = p->rtStop;
+ p->rtStart = Packet::INVALID_TIME;
+ }
+ if(p->bDiscontinuity)
+ {
+ m_p->bDiscontinuity = p->bDiscontinuity;
+ p->bDiscontinuity = FALSE;
+ }
+ if(p->bSyncPoint)
+ {
+ m_p->bSyncPoint = p->bSyncPoint;
+ p->bSyncPoint = FALSE;
+ }
+ if(m_p->pmt)
+ DeleteMediaType(m_p->pmt);
+
+ m_p->pmt = p->pmt;
+ p->pmt = NULL;
+
+ start = next;
+ }
+ if(start > m_p->GetData())
+ {
+ m_p->RemoveAt(0, start - m_p->GetData());
+ }
+
+ for(POSITION pos = m_pl.GetHeadPosition(); pos; m_pl.GetNext(pos))
+ {
+ if(pos == m_pl.GetHeadPosition())
+ continue;
+
+ Packet* pPacket = m_pl.GetAt(pos);
+ BYTE* pData = pPacket->GetData();
+
+ if((pData[4] & 0x1f) == 0x09) m_fHasAccessUnitDelimiters = true;
+
+ if((pData[4] & 0x1f) == 0x09 || !m_fHasAccessUnitDelimiters && pPacket->rtStart != Packet::INVALID_TIME)
+ {
+ p = m_pl.RemoveHead();
+
+ while(pos != m_pl.GetHeadPosition())
+ {
+ CAutoPtr<Packet> p2 = m_pl.RemoveHead();
+ p->Append(*p2);
+ }
+
+ HRESULT hr = __super::DeliverPacket(p);
+ if(hr != S_OK) return hr;
+ }
+ }
+
+ return S_OK;
+ }
+ else if(m_mt.subtype == FOURCCMap('1CVW') || m_mt.subtype == FOURCCMap('1cvw')) // just like aac, this has to be starting nalus, more can be packed together
+ {
+ if(!m_p)
+ {
+ m_p.Attach(DNew Packet());
+ m_p->TrackNumber = p->TrackNumber;
+ m_p->bDiscontinuity = p->bDiscontinuity;
+ p->bDiscontinuity = FALSE;
+
+ m_p->bSyncPoint = p->bSyncPoint;
+ p->bSyncPoint = FALSE;
+
+ m_p->rtStart = p->rtStart;
+ p->rtStart = Packet::INVALID_TIME;
+
+ m_p->rtStop = p->rtStop;
+ p->rtStop = Packet::INVALID_TIME;
+ }
+
+ m_p->Append(*p);
+
+ BYTE* start = m_p->GetData();
+ BYTE* end = start + m_p->GetCount();
+
+ bool bSeqFound = false;
+ while(start <= end - 4)
+ {
+ if(*(DWORD*)start == 0x0D010000)
+ {
+ bSeqFound = true;
+ break;
+ }
+ else if(*(DWORD*)start == 0x0F010000)
+ break;
+ start++;
+ }
+
+ while(start <= end - 4)
+ {
+ BYTE* next = start + 1;
+
+ while(next <= end - 4)
+ {
+ if(*(DWORD*)next == 0x0D010000)
+ {
+ if(bSeqFound) break;
+ bSeqFound = true;
+ }
+ else if(*(DWORD*)next == 0x0F010000)
+ break;
+ next++;
+ }
+
+ if(next >= end - 4) break;
+
+ int size = next - start - 4;
+
+
+ CAutoPtr<Packet> p2(DNew Packet());
+ p2->TrackNumber = m_p->TrackNumber;
+ p2->bDiscontinuity = m_p->bDiscontinuity;
+ m_p->bDiscontinuity = FALSE;
+
+ p2->bSyncPoint = m_p->bSyncPoint;
+ m_p->bSyncPoint = FALSE;
+
+ p2->rtStart = m_p->rtStart;
+ m_p->rtStart = Packet::INVALID_TIME;
+
+ p2->rtStop = m_p->rtStop;
+ m_p->rtStop = Packet::INVALID_TIME;
+
+ p2->pmt = m_p->pmt;
+ m_p->pmt = NULL;
+
+ p2->SetData(start, next - start);
+
+ HRESULT hr = __super::DeliverPacket(p2);
+ if(hr != S_OK) return hr;
+
+ if(p->rtStart != Packet::INVALID_TIME)
+ {
+ m_p->rtStart = p->rtStart;
+ m_p->rtStop = p->rtStop;
+ p->rtStart = Packet::INVALID_TIME;
+ }
+ if(p->bDiscontinuity)
+ {
+ m_p->bDiscontinuity = p->bDiscontinuity;
+ p->bDiscontinuity = FALSE;
+ }
+ if(p->bSyncPoint)
+ {
+ m_p->bSyncPoint = p->bSyncPoint;
+ p->bSyncPoint = FALSE;
+ }
+ if(m_p->pmt)
+ DeleteMediaType(m_p->pmt);
+
+ m_p->pmt = p->pmt;
+ p->pmt = NULL;
+
+ start = next;
+ bSeqFound = (*(DWORD*)start == 0x0D010000);
+ }
+
+ if(start > m_p->GetData())
+ {
+ m_p->RemoveAt(0, start - m_p->GetData());
+ }
+
+ return S_OK;
+ }
+ else if(m_mt.subtype == MEDIASUBTYPE_DTS || m_mt.subtype == MEDIASUBTYPE_WAVE_DTS) // DTS HD MA data is causing trouble, lets just remove it
+ {
#if 0
- BYTE* start = p->GetData();
- BYTE* end = start + p->GetCount();
- if (end - start < 4 && !p->pmt)
- return S_OK; // Should be invalid packet
-
- BYTE* hdr = start;
-
-
- int Type;
- // 16 bits big endian bitstream
- if (hdr[0] == 0x7f && hdr[1] == 0xfe &&
- hdr[2] == 0x80 && hdr[3] == 0x01)
- Type = 16 + 32;
-
- // 16 bits low endian bitstream
- else if (hdr[0] == 0xfe && hdr[1] == 0x7f &&
- hdr[2] == 0x01 && hdr[3] == 0x80)
- Type = 16;
-
- // 14 bits big endian bitstream
- else if (hdr[0] == 0x1f && hdr[1] == 0xff &&
- hdr[2] == 0xe8 && hdr[3] == 0x00 &&
- hdr[4] == 0x07 && (hdr[5] & 0xf0) == 0xf0)
- Type = 14 + 32;
-
- // 14 bits low endian bitstream
- else if (hdr[0] == 0xff && hdr[1] == 0x1f &&
- hdr[2] == 0x00 && hdr[3] == 0xe8 &&
- (hdr[4] & 0xf0) == 0xf0 && hdr[5] == 0x07)
- Type = 14;
-
- // no sync
- else if (!p->pmt)
- {
- return S_OK;
- }
+ BYTE* start = p->GetData();
+ BYTE* end = start + p->GetCount();
+ if(end - start < 4 && !p->pmt)
+ return S_OK; // Should be invalid packet
+
+ BYTE* hdr = start;
+
+
+ int Type;
+ // 16 bits big endian bitstream
+ if(hdr[0] == 0x7f && hdr[1] == 0xfe &&
+ hdr[2] == 0x80 && hdr[3] == 0x01)
+ Type = 16 + 32;
+
+ // 16 bits low endian bitstream
+ else if(hdr[0] == 0xfe && hdr[1] == 0x7f &&
+ hdr[2] == 0x01 && hdr[3] == 0x80)
+ Type = 16;
+
+ // 14 bits big endian bitstream
+ else if(hdr[0] == 0x1f && hdr[1] == 0xff &&
+ hdr[2] == 0xe8 && hdr[3] == 0x00 &&
+ hdr[4] == 0x07 && (hdr[5] & 0xf0) == 0xf0)
+ Type = 14 + 32;
+
+ // 14 bits low endian bitstream
+ else if(hdr[0] == 0xff && hdr[1] == 0x1f &&
+ hdr[2] == 0x00 && hdr[3] == 0xe8 &&
+ (hdr[4] & 0xf0) == 0xf0 && hdr[5] == 0x07)
+ Type = 14;
+
+ // no sync
+ else if(!p->pmt)
+ {
+ return S_OK;
+ }
#endif
- }
- else if (m_mt.subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
- {
- BYTE* start = p->GetData();
- p->SetData(start + 4, p->GetCount() - 4);
- }
- else
- {
- m_p.Free();
- m_pl.RemoveAll();
- }
-
- return __super::DeliverPacket(p);
+ }
+ else if(m_mt.subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
+ {
+ BYTE* start = p->GetData();
+ p->SetData(start + 4, p->GetCount() - 4);
+ }
+ else
+ {
+ m_p.Free();
+ m_pl.RemoveAll();
+ }
+
+ return __super::DeliverPacket(p);
}
STDMETHODIMP CMpegSplitterOutputPin::Connect(IPin* pReceivePin, const AM_MEDIA_TYPE* pmt)
{
- HRESULT hr;
- PIN_INFO PinInfo;
- GUID FilterClsid;
-
- if (SUCCEEDED (pReceivePin->QueryPinInfo (&PinInfo)))
- {
- if (SUCCEEDED (PinInfo.pFilter->GetClassID(&FilterClsid)) && (FilterClsid == CLSID_DMOWrapperFilter))
- (static_cast<CMpegSplitterFilter*>(m_pFilter))->SetPipo(true);
- PinInfo.pFilter->Release();
- }
-
- hr = __super::Connect (pReceivePin, pmt);
- (static_cast<CMpegSplitterFilter*>(m_pFilter))->SetPipo(false);
- return hr;
+ HRESULT hr;
+ PIN_INFO PinInfo;
+ GUID FilterClsid;
+
+ if(SUCCEEDED(pReceivePin->QueryPinInfo(&PinInfo)))
+ {
+ if(SUCCEEDED(PinInfo.pFilter->GetClassID(&FilterClsid)) && (FilterClsid == CLSID_DMOWrapperFilter))
+ (static_cast<CMpegSplitterFilter*>(m_pFilter))->SetPipo(true);
+ PinInfo.pFilter->Release();
+ }
+
+ hr = __super::Connect(pReceivePin, pmt);
+ (static_cast<CMpegSplitterFilter*>(m_pFilter))->SetPipo(false);
+ return hr;
}
diff --git a/src/filters/parser/MpegSplitter/MpegSplitter.h b/src/filters/parser/MpegSplitter/MpegSplitter.h
index fb20de487..c99aa20a5 100644
--- a/src/filters/parser/MpegSplitter/MpegSplitter.h
+++ b/src/filters/parser/MpegSplitter/MpegSplitter.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,60 +27,66 @@
[uuid("DC257063-045F-4BE2-BD5B-E12279C464F0")]
class CMpegSplitterFilter : public CBaseSplitterFilter, public IAMStreamSelect
{
- REFERENCE_TIME m_rtStartOffset;
- bool m_pPipoBimbo;
- CHdmvClipInfo m_ClipInfo;
+ REFERENCE_TIME m_rtStartOffset;
+ bool m_pPipoBimbo;
+ CHdmvClipInfo m_ClipInfo;
protected:
- CAutoPtr<CMpegSplitterFile> m_pFile;
- HRESULT CreateOutputs(IAsyncReader* pAsyncReader);
- void ReadClipInfo(LPCOLESTR pszFileName);
+ CAutoPtr<CMpegSplitterFile> m_pFile;
+ HRESULT CreateOutputs(IAsyncReader* pAsyncReader);
+ void ReadClipInfo(LPCOLESTR pszFileName);
- bool DemuxInit();
- void DemuxSeek(REFERENCE_TIME rt);
- bool DemuxLoop();
- bool BuildPlaylist(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& files);
+ bool DemuxInit();
+ void DemuxSeek(REFERENCE_TIME rt);
+ bool DemuxLoop();
+ bool BuildPlaylist(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& files);
- HRESULT DemuxNextPacket(REFERENCE_TIME rtStartOffset);
+ HRESULT DemuxNextPacket(REFERENCE_TIME rtStartOffset);
public:
- CMpegSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid = __uuidof(CMpegSplitterFilter));
- void SetPipo(bool bPipo) { m_pPipoBimbo = bPipo; };
+ CMpegSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid = __uuidof(CMpegSplitterFilter));
+ void SetPipo(bool bPipo)
+ {
+ m_pPipoBimbo = bPipo;
+ };
- DECLARE_IUNKNOWN
+ DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- STDMETHODIMP GetClassID(CLSID* pClsID);
- STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP GetClassID(CLSID* pClsID);
+ STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
- // IAMStreamSelect
+ // IAMStreamSelect
- STDMETHODIMP Count(DWORD* pcStreams);
- STDMETHODIMP Enable(long lIndex, DWORD dwFlags);
- STDMETHODIMP Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk);
+ STDMETHODIMP Count(DWORD* pcStreams);
+ STDMETHODIMP Enable(long lIndex, DWORD dwFlags);
+ STDMETHODIMP Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk);
};
[uuid("1365BE7A-C86A-473C-9A41-C0A6E82C9FA3")]
class CMpegSourceFilter : public CMpegSplitterFilter
{
public:
- CMpegSourceFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid = __uuidof(CMpegSourceFilter));
+ CMpegSourceFilter(LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid = __uuidof(CMpegSourceFilter));
};
class CMpegSplitterOutputPin : public CBaseSplitterOutputPin, protected CCritSec
{
- CAutoPtr<Packet> m_p;
- CAutoPtrList<Packet> m_pl;
- REFERENCE_TIME m_rtPrev, m_rtOffset, m_rtMaxShift;
- bool m_fHasAccessUnitDelimiters;
+ CAutoPtr<Packet> m_p;
+ CAutoPtrList<Packet> m_pl;
+ REFERENCE_TIME m_rtPrev, m_rtOffset, m_rtMaxShift;
+ bool m_fHasAccessUnitDelimiters;
protected:
- HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
- HRESULT DeliverPacket(CAutoPtr<Packet> p);
- HRESULT DeliverEndFlush();
+ HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+ HRESULT DeliverPacket(CAutoPtr<Packet> p);
+ HRESULT DeliverEndFlush();
public:
- CMpegSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CMpegSplitterOutputPin();
- STDMETHODIMP Connect(IPin* pReceivePin, const AM_MEDIA_TYPE* pmt);
- void SetMaxShift(REFERENCE_TIME rtMaxShift) { m_rtMaxShift = rtMaxShift; };
+ CMpegSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CMpegSplitterOutputPin();
+ STDMETHODIMP Connect(IPin* pReceivePin, const AM_MEDIA_TYPE* pmt);
+ void SetMaxShift(REFERENCE_TIME rtMaxShift)
+ {
+ m_rtMaxShift = rtMaxShift;
+ };
};
diff --git a/src/filters/parser/MpegSplitter/MpegSplitterFile.cpp b/src/filters/parser/MpegSplitter/MpegSplitterFile.cpp
index a955a54f7..07ef13d37 100644
--- a/src/filters/parser/MpegSplitter/MpegSplitterFile.cpp
+++ b/src/filters/parser/MpegSplitter/MpegSplitterFile.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
*
*/
@@ -30,777 +30,789 @@
#define ISVALIDPID(pid) (pid >= 0x10 && pid < 0x1fff)
CMpegSplitterFile::CMpegSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr, bool bIsHdmv, CHdmvClipInfo &ClipInfo)
- : CBaseSplitterFileEx(pAsyncReader, hr, DEFAULT_CACHE_LENGTH, false, true)
- , m_type(us)
- , m_rate(0)
- , m_rtMin(0), m_rtMax(0)
- , m_posMin(0), m_posMax(0)
- , m_bIsHdmv(bIsHdmv)
- , m_ClipInfo(ClipInfo)
+ : CBaseSplitterFileEx(pAsyncReader, hr, DEFAULT_CACHE_LENGTH, false, true)
+ , m_type(us)
+ , m_rate(0)
+ , m_rtMin(0), m_rtMax(0)
+ , m_posMin(0), m_posMax(0)
+ , m_bIsHdmv(bIsHdmv)
+ , m_ClipInfo(ClipInfo)
{
- // Ugly code : to support BRD seamless playback, CMultiFiles need to update m_rtPTSOffset variable
- // each time a new part is open...
- CComQIPtr<ISyncReader> pReader = pAsyncReader;
- if (pReader) pReader->SetPTSOffset (&m_rtPTSOffset);
+ // Ugly code : to support BRD seamless playback, CMultiFiles need to update m_rtPTSOffset variable
+ // each time a new part is open...
+ CComQIPtr<ISyncReader> pReader = pAsyncReader;
+ if(pReader) pReader->SetPTSOffset(&m_rtPTSOffset);
- if(SUCCEEDED(hr)) hr = Init();
+ if(SUCCEEDED(hr)) hr = Init();
}
HRESULT CMpegSplitterFile::Init()
{
- HRESULT hr;
-
- // get the type first
-
- m_type = us;
-
- Seek(0);
-
- if(m_type == us)
- {
- if(BitRead(32, true) == 'TFrc') Seek(0x67c);
- int cnt = 0, limit = 4;
- for(trhdr h; cnt < limit && Read(h); cnt++) Seek(h.next);
- if(cnt >= limit) m_type = ts;
- }
-
- Seek(0);
-
- if(m_type == us)
- {
- int cnt = 0, limit = 4;
- for(pvahdr h; cnt < limit && Read(h); cnt++) Seek(GetPos() + h.length);
- if(cnt >= limit) m_type = pva;
- }
-
- Seek(0);
-
- if(m_type == us)
- {
- BYTE b;
- for(int i = 0; (i < 4 || GetPos() < 65536) && m_type == us && NextMpegStartCode(b); i++)
- {
- if(b == 0xba)
- {
- pshdr h;
- if(Read(h))
- {
- m_type = ps;
- m_rate = int(h.bitrate/8);
- break;
- }
- }
- else if((b&0xe0) == 0xc0 // audio, 110xxxxx, mpeg1/2/3
- || (b&0xf0) == 0xe0 // video, 1110xxxx, mpeg1/2
- // || (b&0xbd) == 0xbd) // private stream 1, 0xbd, ac3/dts/lpcm/subpic
- || b == 0xbd) // private stream 1, 0xbd, ac3/dts/lpcm/subpic
- {
- peshdr h;
- if(Read(h, b) && BitRead(24, true) == 0x000001)
- m_type = es;
- }
- }
- }
-
- Seek(0);
-
- if(m_type == us)
- return E_FAIL;
-
- // min/max pts & bitrate
- m_rtMin = m_posMin = _I64_MAX;
- m_rtMax = m_posMax = 0;
-
- if(IsRandomAccess() || IsStreaming())
- {
- if(IsStreaming())
- {
- for(int i = 0; i < 20 || i < 50 && S_OK != HasMoreData(1024*100, 100); i++);
- }
-
- CAtlList<__int64> fps;
- for(int i = 0, j = 5; i <= j; i++)
- fps.AddTail(i*GetLength()/j);
-
- for(__int64 pfp = 0; fps.GetCount(); )
- {
- __int64 fp = fps.RemoveHead();
- fp = min(GetLength() - MEGABYTE/8, fp);
- fp = max(pfp, fp);
- __int64 nfp = fp + (pfp == 0 ? 5*MEGABYTE : MEGABYTE/8);
- if(FAILED(hr = SearchStreams(fp, nfp)))
- return hr;
- pfp = nfp;
- }
- }
- else
- {
- if(FAILED(hr = SearchStreams(0, MEGABYTE/8)))
- return hr;
- }
-
- if(m_posMax - m_posMin <= 0 || m_rtMax - m_rtMin <= 0)
- return E_FAIL;
-
- int indicated_rate = m_rate;
- int detected_rate = int(10000000i64 * (m_posMax - m_posMin) / (m_rtMax - m_rtMin));
- // normally "detected" should always be less than "indicated", but sometimes it can be a few percent higher (+10% is allowed here)
- // (update: also allowing +/-50k/s)
- if(indicated_rate == 0 || ((float)detected_rate / indicated_rate) < 1.1 || abs(detected_rate - indicated_rate) < 50*1024)
- m_rate = detected_rate;
- else ; // TODO: in this case disable seeking, or try doing something less drastical...
-
- if(m_streams[video].GetCount())
- {
- if (!m_bIsHdmv && m_streams[subpic].GetCount())
- {
+ HRESULT hr;
+
+ // get the type first
+
+ m_type = us;
+
+ Seek(0);
+
+ if(m_type == us)
+ {
+ if(BitRead(32, true) == 'TFrc') Seek(0x67c);
+ int cnt = 0, limit = 4;
+ for(trhdr h; cnt < limit && Read(h); cnt++) Seek(h.next);
+ if(cnt >= limit) m_type = ts;
+ }
+
+ Seek(0);
+
+ if(m_type == us)
+ {
+ int cnt = 0, limit = 4;
+ for(pvahdr h; cnt < limit && Read(h); cnt++) Seek(GetPos() + h.length);
+ if(cnt >= limit) m_type = pva;
+ }
+
+ Seek(0);
+
+ if(m_type == us)
+ {
+ BYTE b;
+ for(int i = 0; (i < 4 || GetPos() < 65536) && m_type == us && NextMpegStartCode(b); i++)
+ {
+ if(b == 0xba)
+ {
+ pshdr h;
+ if(Read(h))
+ {
+ m_type = ps;
+ m_rate = int(h.bitrate / 8);
+ break;
+ }
+ }
+ else if((b & 0xe0) == 0xc0 // audio, 110xxxxx, mpeg1/2/3
+ || (b & 0xf0) == 0xe0 // video, 1110xxxx, mpeg1/2
+ // || (b&0xbd) == 0xbd) // private stream 1, 0xbd, ac3/dts/lpcm/subpic
+ || b == 0xbd) // private stream 1, 0xbd, ac3/dts/lpcm/subpic
+ {
+ peshdr h;
+ if(Read(h, b) && BitRead(24, true) == 0x000001)
+ m_type = es;
+ }
+ }
+ }
+
+ Seek(0);
+
+ if(m_type == us)
+ return E_FAIL;
+
+ // min/max pts & bitrate
+ m_rtMin = m_posMin = _I64_MAX;
+ m_rtMax = m_posMax = 0;
+
+ if(IsRandomAccess() || IsStreaming())
+ {
+ if(IsStreaming())
+ {
+ for(int i = 0; i < 20 || i < 50 && S_OK != HasMoreData(1024 * 100, 100); i++);
+ }
+
+ CAtlList<__int64> fps;
+ for(int i = 0, j = 5; i <= j; i++)
+ fps.AddTail(i * GetLength() / j);
+
+ for(__int64 pfp = 0; fps.GetCount();)
+ {
+ __int64 fp = fps.RemoveHead();
+ fp = min(GetLength() - MEGABYTE / 8, fp);
+ fp = max(pfp, fp);
+ __int64 nfp = fp + (pfp == 0 ? 5 * MEGABYTE : MEGABYTE / 8);
+ if(FAILED(hr = SearchStreams(fp, nfp)))
+ return hr;
+ pfp = nfp;
+ }
+ }
+ else
+ {
+ if(FAILED(hr = SearchStreams(0, MEGABYTE / 8)))
+ return hr;
+ }
+
+ if(m_posMax - m_posMin <= 0 || m_rtMax - m_rtMin <= 0)
+ return E_FAIL;
+
+ int indicated_rate = m_rate;
+ int detected_rate = int(10000000i64 * (m_posMax - m_posMin) / (m_rtMax - m_rtMin));
+ // normally "detected" should always be less than "indicated", but sometimes it can be a few percent higher (+10% is allowed here)
+ // (update: also allowing +/-50k/s)
+ if(indicated_rate == 0 || ((float)detected_rate / indicated_rate) < 1.1 || abs(detected_rate - indicated_rate) < 50 * 1024)
+ m_rate = detected_rate;
+ else ; // TODO: in this case disable seeking, or try doing something less drastical...
+
+ if(m_streams[video].GetCount())
+ {
+ if(!m_bIsHdmv && m_streams[subpic].GetCount())
+ {
#ifndef DEBUG
- stream s;
- s.mt.majortype = m_streams[subpic].GetHead().mt.majortype;
- s.mt.subtype = m_streams[subpic].GetHead().mt.subtype;
- s.mt.formattype = m_streams[subpic].GetHead().mt.formattype;
- m_streams[subpic].Insert(s, this);
+ stream s;
+ s.mt.majortype = m_streams[subpic].GetHead().mt.majortype;
+ s.mt.subtype = m_streams[subpic].GetHead().mt.subtype;
+ s.mt.formattype = m_streams[subpic].GetHead().mt.formattype;
+ m_streams[subpic].Insert(s, this);
#endif
- }
- else
- {
- // Add fake stream for "No subtitle"
- AddHdmvPGStream (NO_SUBTITLE_PID, "---");
- }
- }
+ }
+ else
+ {
+ // Add fake stream for "No subtitle"
+ AddHdmvPGStream(NO_SUBTITLE_PID, "---");
+ }
+ }
- Seek(0);
+ Seek(0);
- return S_OK;
+ return S_OK;
}
void CMpegSplitterFile::OnComplete()
{
- __int64 pos = GetPos();
-
- if(SUCCEEDED(SearchStreams(GetLength() - 500*1024, GetLength())))
- {
- int indicated_rate = m_rate;
- int detected_rate = int(m_rtMax > m_rtMin ? 10000000i64 * (m_posMax - m_posMin) / (m_rtMax - m_rtMin) : 0);
- // normally "detected" should always be less than "indicated", but sometimes it can be a few percent higher (+10% is allowed here)
- // (update: also allowing +/-50k/s)
- if(indicated_rate == 0 || ((float)detected_rate / indicated_rate) < 1.1 || abs(detected_rate - indicated_rate) < 50*1024)
- m_rate = detected_rate;
- else ; // TODO: in this case disable seeking, or try doing something less drastical...
- }
-
- Seek(pos);
+ __int64 pos = GetPos();
+
+ if(SUCCEEDED(SearchStreams(GetLength() - 500 * 1024, GetLength())))
+ {
+ int indicated_rate = m_rate;
+ int detected_rate = int(m_rtMax > m_rtMin ? 10000000i64 * (m_posMax - m_posMin) / (m_rtMax - m_rtMin) : 0);
+ // normally "detected" should always be less than "indicated", but sometimes it can be a few percent higher (+10% is allowed here)
+ // (update: also allowing +/-50k/s)
+ if(indicated_rate == 0 || ((float)detected_rate / indicated_rate) < 1.1 || abs(detected_rate - indicated_rate) < 50 * 1024)
+ m_rate = detected_rate;
+ else ; // TODO: in this case disable seeking, or try doing something less drastical...
+ }
+
+ Seek(pos);
}
REFERENCE_TIME CMpegSplitterFile::NextPTS(DWORD TrackNum)
{
- REFERENCE_TIME rt = -1;
- __int64 rtpos = -1;
+ REFERENCE_TIME rt = -1;
+ __int64 rtpos = -1;
- BYTE b;
+ BYTE b;
- while(GetRemaining())
- {
- if(m_type == ps || m_type == es)
- {
- if(!NextMpegStartCode(b)) // continue;
- {
- ASSERT(0);
- break;
- }
+ while(GetRemaining())
+ {
+ if(m_type == ps || m_type == es)
+ {
+ if(!NextMpegStartCode(b)) // continue;
+ {
+ ASSERT(0);
+ break;
+ }
- rtpos = GetPos()-4;
+ rtpos = GetPos() - 4;
#if (EVO_SUPPORT == 0)
- if(b >= 0xbd && b < 0xf0)
+ if(b >= 0xbd && b < 0xf0)
#else
- if((b >= 0xbd && b < 0xf0) || (b == 0xfd))
+ if((b >= 0xbd && b < 0xf0) || (b == 0xfd))
#endif
- {
- peshdr h;
- if(!Read(h, b) || !h.len) continue;
-
- __int64 pos = GetPos();
-
- if(h.fpts && AddStream(0, b, h.len) == TrackNum)
- {
- ASSERT(h.pts >= m_rtMin && h.pts <= m_rtMax);
- rt = h.pts;
- break;
- }
-
- Seek(pos + h.len);
- }
- }
- else if(m_type == ts)
- {
- trhdr h;
- if(!Read(h)) continue;
-
- rtpos = GetPos()-4;
-
- if(h.payload && h.payloadstart && ISVALIDPID(h.pid))
- {
- peshdr h2;
- if(NextMpegStartCode(b, 4) && Read(h2, b)) // pes packet
- {
- if(h2.fpts && AddStream(h.pid, b, DWORD(h.bytes - (GetPos() - rtpos)) == TrackNum))
- {
- ASSERT(h2.pts >= m_rtMin && h2.pts <= m_rtMax);
- rt = h2.pts;
- break;
- }
- }
- }
-
- Seek(h.next);
- }
- else if(m_type == pva)
- {
- pvahdr h;
- if(!Read(h)) continue;
-
- if(h.fpts)
- {
- rt = h.pts;
- break;
- }
- }
- }
-
- if(rtpos >= 0) Seek(rtpos);
- if(rt >= 0) rt -= m_rtMin;
-
- return rt;
+ {
+ peshdr h;
+ if(!Read(h, b) || !h.len) continue;
+
+ __int64 pos = GetPos();
+
+ if(h.fpts && AddStream(0, b, h.len) == TrackNum)
+ {
+ ASSERT(h.pts >= m_rtMin && h.pts <= m_rtMax);
+ rt = h.pts;
+ break;
+ }
+
+ Seek(pos + h.len);
+ }
+ }
+ else if(m_type == ts)
+ {
+ trhdr h;
+ if(!Read(h)) continue;
+
+ rtpos = GetPos() - 4;
+
+ if(h.payload && h.payloadstart && ISVALIDPID(h.pid))
+ {
+ peshdr h2;
+ if(NextMpegStartCode(b, 4) && Read(h2, b)) // pes packet
+ {
+ if(h2.fpts && AddStream(h.pid, b, DWORD(h.bytes - (GetPos() - rtpos)) == TrackNum))
+ {
+ ASSERT(h2.pts >= m_rtMin && h2.pts <= m_rtMax);
+ rt = h2.pts;
+ break;
+ }
+ }
+ }
+
+ Seek(h.next);
+ }
+ else if(m_type == pva)
+ {
+ pvahdr h;
+ if(!Read(h)) continue;
+
+ if(h.fpts)
+ {
+ rt = h.pts;
+ break;
+ }
+ }
+ }
+
+ if(rtpos >= 0) Seek(rtpos);
+ if(rt >= 0) rt -= m_rtMin;
+
+ return rt;
}
HRESULT CMpegSplitterFile::SearchStreams(__int64 start, __int64 stop)
{
- Seek(start);
- stop = min(stop, GetLength());
-
- while(GetPos() < stop)
- {
- BYTE b;
-
- if(m_type == ps || m_type == es)
- {
- if(!NextMpegStartCode(b)) continue;
-
- if(b == 0xba) // program stream header
- {
- pshdr h;
- if(!Read(h)) continue;
- }
- else if(b == 0xbb) // program stream system header
- {
- pssyshdr h;
- if(!Read(h)) continue;
- }
+ Seek(start);
+ stop = min(stop, GetLength());
+
+ while(GetPos() < stop)
+ {
+ BYTE b;
+
+ if(m_type == ps || m_type == es)
+ {
+ if(!NextMpegStartCode(b)) continue;
+
+ if(b == 0xba) // program stream header
+ {
+ pshdr h;
+ if(!Read(h)) continue;
+ }
+ else if(b == 0xbb) // program stream system header
+ {
+ pssyshdr h;
+ if(!Read(h)) continue;
+ }
#if (EVO_SUPPORT == 0)
- else if(b >= 0xbd && b < 0xf0) // pes packet
+ else if(b >= 0xbd && b < 0xf0) // pes packet
#else
- else if((b >= 0xbd && b < 0xf0) || (b == 0xfd)) // pes packet
+ else if((b >= 0xbd && b < 0xf0) || (b == 0xfd)) // pes packet
#endif
- {
- peshdr h;
- if(!Read(h, b)) continue;
-
- if(h.type == mpeg2 && h.scrambling) {ASSERT(0); return E_FAIL;}
-
- if(h.fpts)
- {
- if(m_rtMin == _I64_MAX) {m_rtMin = h.pts; m_posMin = GetPos();}
- if(m_rtMin < h.pts && m_rtMax < h.pts) {m_rtMax = h.pts; m_posMax = GetPos();}
- }
-
- __int64 pos = GetPos();
- AddStream(0, b, h.len);
- if(h.len) Seek(pos + h.len);
- }
- }
- else if(m_type == ts)
- {
- trhdr h;
- if(!Read(h)) continue;
-
- __int64 pos = GetPos();
-
- if(h.payload && h.payloadstart)
- UpdatePrograms(h);
-
- if(h.payload && ISVALIDPID(h.pid))
- {
- peshdr h2;
- if(h.payloadstart && NextMpegStartCode(b, 4) && Read(h2, b)) // pes packet
- {
- if(h2.type == mpeg2 && h2.scrambling)
- {
- ASSERT(0);
- return E_FAIL;
- }
-
- if(h2.fpts)
- {
- if(m_rtMin == _I64_MAX)
- {
- m_rtMin = h2.pts;
- m_posMin = GetPos();
- }
-
- if(m_rtMin < h2.pts && m_rtMax < h2.pts)
- {
- m_rtMax = h2.pts;
- m_posMax = GetPos();
- }
- }
- }
- else
- b = 0;
-
- AddStream(h.pid, b, DWORD(h.bytes - (GetPos() - pos)));
- }
-
- Seek(h.next);
- }
- else if(m_type == pva)
- {
- pvahdr h;
- if(!Read(h)) continue;
-
- if(h.fpts)
- {
- if(m_rtMin == _I64_MAX)
- {
- m_rtMin = h.pts;
- m_posMin = GetPos();
- }
-
- if(m_rtMin < h.pts && m_rtMax < h.pts)
- {
- m_rtMax = h.pts;
- m_posMax = GetPos();
- }
- }
-
- __int64 pos = GetPos();
-
- if(h.streamid == 1)
- AddStream(h.streamid, 0xe0, h.length);
- else if(h.streamid == 2)
- AddStream(h.streamid, 0xc0, h.length);
-
- if(h.length)
- Seek(pos + h.length);
- }
- }
-
- return S_OK;
+ {
+ peshdr h;
+ if(!Read(h, b)) continue;
+
+ if(h.type == mpeg2 && h.scrambling)
+ {
+ ASSERT(0);
+ return E_FAIL;
+ }
+
+ if(h.fpts)
+ {
+ if(m_rtMin == _I64_MAX)
+ {
+ m_rtMin = h.pts;
+ m_posMin = GetPos();
+ }
+ if(m_rtMin < h.pts && m_rtMax < h.pts)
+ {
+ m_rtMax = h.pts;
+ m_posMax = GetPos();
+ }
+ }
+
+ __int64 pos = GetPos();
+ AddStream(0, b, h.len);
+ if(h.len) Seek(pos + h.len);
+ }
+ }
+ else if(m_type == ts)
+ {
+ trhdr h;
+ if(!Read(h)) continue;
+
+ __int64 pos = GetPos();
+
+ if(h.payload && h.payloadstart)
+ UpdatePrograms(h);
+
+ if(h.payload && ISVALIDPID(h.pid))
+ {
+ peshdr h2;
+ if(h.payloadstart && NextMpegStartCode(b, 4) && Read(h2, b)) // pes packet
+ {
+ if(h2.type == mpeg2 && h2.scrambling)
+ {
+ ASSERT(0);
+ return E_FAIL;
+ }
+
+ if(h2.fpts)
+ {
+ if(m_rtMin == _I64_MAX)
+ {
+ m_rtMin = h2.pts;
+ m_posMin = GetPos();
+ }
+
+ if(m_rtMin < h2.pts && m_rtMax < h2.pts)
+ {
+ m_rtMax = h2.pts;
+ m_posMax = GetPos();
+ }
+ }
+ }
+ else
+ b = 0;
+
+ AddStream(h.pid, b, DWORD(h.bytes - (GetPos() - pos)));
+ }
+
+ Seek(h.next);
+ }
+ else if(m_type == pva)
+ {
+ pvahdr h;
+ if(!Read(h)) continue;
+
+ if(h.fpts)
+ {
+ if(m_rtMin == _I64_MAX)
+ {
+ m_rtMin = h.pts;
+ m_posMin = GetPos();
+ }
+
+ if(m_rtMin < h.pts && m_rtMax < h.pts)
+ {
+ m_rtMax = h.pts;
+ m_posMax = GetPos();
+ }
+ }
+
+ __int64 pos = GetPos();
+
+ if(h.streamid == 1)
+ AddStream(h.streamid, 0xe0, h.length);
+ else if(h.streamid == 2)
+ AddStream(h.streamid, 0xc0, h.length);
+
+ if(h.length)
+ Seek(pos + h.length);
+ }
+ }
+
+ return S_OK;
}
DWORD CMpegSplitterFile::AddStream(WORD pid, BYTE pesid, DWORD len)
{
- if(pid)
- {
- if(pesid) m_pid2pes[pid] = pesid;
- else m_pid2pes.Lookup(pid, pesid);
- }
+ if(pid)
+ {
+ if(pesid) m_pid2pes[pid] = pesid;
+ else m_pid2pes.Lookup(pid, pesid);
+ }
- stream s;
- s.pid = pid;
- s.pesid = pesid;
+ stream s;
+ s.pid = pid;
+ s.pesid = pesid;
- int type = unknown;
+ int type = unknown;
- if(pesid >= 0xe0 && pesid < 0xf0) // mpeg video
- {
- __int64 pos = GetPos();
+ if(pesid >= 0xe0 && pesid < 0xf0) // mpeg video
+ {
+ __int64 pos = GetPos();
- if(type == unknown)
- {
- CMpegSplitterFile::seqhdr h;
- if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
- type = video;
- }
+ if(type == unknown)
+ {
+ CMpegSplitterFile::seqhdr h;
+ if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
+ type = video;
+ }
- Seek(pos);
+ Seek(pos);
- if(type == unknown)
- {
+ if(type == unknown)
+ {
// CMpegSplitterFile::avchdr h; <= PPS and SPS can be present on differents packets !
- if(!m_streams[video].Find(s) && Read(avch, len, &s.mt))
- type = video;
- }
- }
- else if(pesid >= 0xc0 && pesid < 0xe0) // mpeg audio
- {
- __int64 pos = GetPos();
-
- if(type == unknown)
- {
- CMpegSplitterFile::mpahdr h;
- if(!m_streams[audio].Find(s) && Read(h, len, false, &s.mt))
- type = audio;
- }
-
- Seek(pos);
-
- if(type == unknown)
- {
- CMpegSplitterFile::aachdr h;
- if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
- type = audio;
- }
- }
- else if(pesid == 0xbd || pesid == 0xfd) // private stream 1
- {
- if(s.pid)
- {
- if(!m_streams[audio].Find(s) && !m_streams[video].Find(s))
- {
- __int64 pos = GetPos();
-
- // AC3
- if(type == unknown)
- {
- CMpegSplitterFile::ac3hdr h;
- if(Read(h, len, &s.mt))
- type = audio;
- }
-
- // DTS
- Seek(pos);
- if(type == unknown)
- {
- CMpegSplitterFile::dtshdr h;
- if(Read(h, len, &s.mt))
- type = audio;
- }
-
- // VC1
- Seek(pos);
- if(type == unknown)
- {
- CMpegSplitterFile::vc1hdr h;
- if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
- type = video;
- }
-
- // DVB subtitles
- Seek(pos);
- if(type == unknown)
- {
- CMpegSplitterFile::dvbsub h;
- if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
- type = subpic;
- }
-
- int iProgram;
- const CHdmvClipInfo::Stream *pClipInfo;
- const program* pProgram = FindProgram (s.pid, iProgram, pClipInfo);
- if((type == unknown) && (pProgram != NULL))
- {
- PES_STREAM_TYPE StreamType = INVALID;
-
- Seek(pos);
- StreamType = pProgram->streams[iProgram].type;
-
- switch (StreamType)
- {
- case AUDIO_STREAM_LPCM :
- {
- CMpegSplitterFile::hdmvlpcmhdr h;
- if(!m_streams[audio].Find(s) && Read(h, &s.mt))
- type = audio;
- }
- break;
- case PRESENTATION_GRAPHICS_STREAM :
- {
- CMpegSplitterFile::hdmvsubhdr h;
- if(!m_streams[subpic].Find(s) && Read(h, &s.mt, pClipInfo ? pClipInfo->m_LanguageCode : NULL))
- {
- m_bIsHdmv = true;
- type = subpic;
- }
- }
- break;
- }
- }
- }
- }
+ if(!m_streams[video].Find(s) && Read(avch, len, &s.mt))
+ type = video;
+ }
+ }
+ else if(pesid >= 0xc0 && pesid < 0xe0) // mpeg audio
+ {
+ __int64 pos = GetPos();
+
+ if(type == unknown)
+ {
+ CMpegSplitterFile::mpahdr h;
+ if(!m_streams[audio].Find(s) && Read(h, len, false, &s.mt))
+ type = audio;
+ }
+
+ Seek(pos);
+
+ if(type == unknown)
+ {
+ CMpegSplitterFile::aachdr h;
+ if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
+ type = audio;
+ }
+ }
+ else if(pesid == 0xbd || pesid == 0xfd) // private stream 1
+ {
+ if(s.pid)
+ {
+ if(!m_streams[audio].Find(s) && !m_streams[video].Find(s))
+ {
+ __int64 pos = GetPos();
+
+ // AC3
+ if(type == unknown)
+ {
+ CMpegSplitterFile::ac3hdr h;
+ if(Read(h, len, &s.mt))
+ type = audio;
+ }
+
+ // DTS
+ Seek(pos);
+ if(type == unknown)
+ {
+ CMpegSplitterFile::dtshdr h;
+ if(Read(h, len, &s.mt))
+ type = audio;
+ }
+
+ // VC1
+ Seek(pos);
+ if(type == unknown)
+ {
+ CMpegSplitterFile::vc1hdr h;
+ if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
+ type = video;
+ }
+
+ // DVB subtitles
+ Seek(pos);
+ if(type == unknown)
+ {
+ CMpegSplitterFile::dvbsub h;
+ if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
+ type = subpic;
+ }
+
+ int iProgram;
+ const CHdmvClipInfo::Stream *pClipInfo;
+ const program* pProgram = FindProgram(s.pid, iProgram, pClipInfo);
+ if((type == unknown) && (pProgram != NULL))
+ {
+ PES_STREAM_TYPE StreamType = INVALID;
+
+ Seek(pos);
+ StreamType = pProgram->streams[iProgram].type;
+
+ switch(StreamType)
+ {
+ case AUDIO_STREAM_LPCM :
+ {
+ CMpegSplitterFile::hdmvlpcmhdr h;
+ if(!m_streams[audio].Find(s) && Read(h, &s.mt))
+ type = audio;
+ }
+ break;
+ case PRESENTATION_GRAPHICS_STREAM :
+ {
+ CMpegSplitterFile::hdmvsubhdr h;
+ if(!m_streams[subpic].Find(s) && Read(h, &s.mt, pClipInfo ? pClipInfo->m_LanguageCode : NULL))
+ {
+ m_bIsHdmv = true;
+ type = subpic;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
#if (EVO_SUPPORT != 0)
- else if (pesid == 0xfd) // TODO EVO SUPPORT
- {
- CMpegSplitterFile::vc1hdr h;
- if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
- type = video;
- }
+ else if(pesid == 0xfd) // TODO EVO SUPPORT
+ {
+ CMpegSplitterFile::vc1hdr h;
+ if(!m_streams[video].Find(s) && Read(h, len, &s.mt))
+ type = video;
+ }
#endif
- else
- {
- BYTE b = (BYTE)BitRead(8, true);
- WORD w = (WORD)BitRead(16, true);
- DWORD dw = (DWORD)BitRead(32, true);
-
- if(b >= 0x80 && b < 0x88 || w == 0x0b77) // ac3
- {
- s.ps1id = (b >= 0x80 && b < 0x88) ? (BYTE)(BitRead(32) >> 24) : 0x80;
-
- CMpegSplitterFile::ac3hdr h;
- if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
- type = audio;
- }
- else if(b >= 0x88 && b < 0x90 || dw == 0x7ffe8001) // dts
- {
- s.ps1id = (b >= 0x88 && b < 0x90) ? (BYTE)(BitRead(32) >> 24) : 0x88;
-
- CMpegSplitterFile::dtshdr h;
- if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
- type = audio;
- }
- else if(b >= 0xa0 && b < 0xa8) // lpcm
- {
- s.ps1id = (b >= 0xa0 && b < 0xa8) ? (BYTE)(BitRead(32) >> 24) : 0xa0;
-
- CMpegSplitterFile::lpcmhdr h;
- if(Read(h, &s.mt) && !m_streams[audio].Find(s)) // note the reversed order, the header should be stripped always even if it's not a new stream
- type = audio;
- }
- else if(b >= 0x20 && b < 0x40) // DVD subpic
- {
- s.ps1id = (BYTE)BitRead(8);
-
- CMpegSplitterFile::dvdspuhdr h;
- if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
- type = subpic;
- }
- else if(b >= 0x70 && b < 0x80) // SVCD subpic
- {
- s.ps1id = (BYTE)BitRead(8);
-
- CMpegSplitterFile::svcdspuhdr h;
- if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
- type = subpic;
- }
- else if(b >= 0x00 && b < 0x10) // CVD subpic
- {
- s.ps1id = (BYTE)BitRead(8);
-
- CMpegSplitterFile::cvdspuhdr h;
- if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
- type = subpic;
- }
- else if(w == 0xffa0 || w == 0xffa1) // ps2-mpg audio
- {
- s.ps1id = (BYTE)BitRead(8);
- s.pid = (WORD)((BitRead(8) << 8) | BitRead(16)); // pid = 0xa000 | track id
-
- CMpegSplitterFile::ps2audhdr h;
- if(!m_streams[audio].Find(s) && Read(h, &s.mt))
- type = audio;
- }
- else if(w == 0xff90) // ps2-mpg ac3 or subtitles
- {
- s.ps1id = (BYTE)BitRead(8);
- s.pid = (WORD)((BitRead(8) << 8) | BitRead(16)); // pid = 0x9000 | track id
-
- w = (WORD)BitRead(16, true);
-
- if(w == 0x0b77)
- {
- CMpegSplitterFile::ac3hdr h;
- if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
- type = audio;
- }
- else if(w == 0x0000) // usually zero...
- {
- CMpegSplitterFile::ps2subhdr h;
- if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
- type = subpic;
- }
- }
+ else
+ {
+ BYTE b = (BYTE)BitRead(8, true);
+ WORD w = (WORD)BitRead(16, true);
+ DWORD dw = (DWORD)BitRead(32, true);
+
+ if(b >= 0x80 && b < 0x88 || w == 0x0b77) // ac3
+ {
+ s.ps1id = (b >= 0x80 && b < 0x88) ? (BYTE)(BitRead(32) >> 24) : 0x80;
+
+ CMpegSplitterFile::ac3hdr h;
+ if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
+ type = audio;
+ }
+ else if(b >= 0x88 && b < 0x90 || dw == 0x7ffe8001) // dts
+ {
+ s.ps1id = (b >= 0x88 && b < 0x90) ? (BYTE)(BitRead(32) >> 24) : 0x88;
+
+ CMpegSplitterFile::dtshdr h;
+ if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
+ type = audio;
+ }
+ else if(b >= 0xa0 && b < 0xa8) // lpcm
+ {
+ s.ps1id = (b >= 0xa0 && b < 0xa8) ? (BYTE)(BitRead(32) >> 24) : 0xa0;
+
+ CMpegSplitterFile::lpcmhdr h;
+ if(Read(h, &s.mt) && !m_streams[audio].Find(s)) // note the reversed order, the header should be stripped always even if it's not a new stream
+ type = audio;
+ }
+ else if(b >= 0x20 && b < 0x40) // DVD subpic
+ {
+ s.ps1id = (BYTE)BitRead(8);
+
+ CMpegSplitterFile::dvdspuhdr h;
+ if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
+ type = subpic;
+ }
+ else if(b >= 0x70 && b < 0x80) // SVCD subpic
+ {
+ s.ps1id = (BYTE)BitRead(8);
+
+ CMpegSplitterFile::svcdspuhdr h;
+ if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
+ type = subpic;
+ }
+ else if(b >= 0x00 && b < 0x10) // CVD subpic
+ {
+ s.ps1id = (BYTE)BitRead(8);
+
+ CMpegSplitterFile::cvdspuhdr h;
+ if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
+ type = subpic;
+ }
+ else if(w == 0xffa0 || w == 0xffa1) // ps2-mpg audio
+ {
+ s.ps1id = (BYTE)BitRead(8);
+ s.pid = (WORD)((BitRead(8) << 8) | BitRead(16)); // pid = 0xa000 | track id
+
+ CMpegSplitterFile::ps2audhdr h;
+ if(!m_streams[audio].Find(s) && Read(h, &s.mt))
+ type = audio;
+ }
+ else if(w == 0xff90) // ps2-mpg ac3 or subtitles
+ {
+ s.ps1id = (BYTE)BitRead(8);
+ s.pid = (WORD)((BitRead(8) << 8) | BitRead(16)); // pid = 0x9000 | track id
+
+ w = (WORD)BitRead(16, true);
+
+ if(w == 0x0b77)
+ {
+ CMpegSplitterFile::ac3hdr h;
+ if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
+ type = audio;
+ }
+ else if(w == 0x0000) // usually zero...
+ {
+ CMpegSplitterFile::ps2subhdr h;
+ if(!m_streams[subpic].Find(s) && Read(h, &s.mt))
+ type = subpic;
+ }
+ }
#if (EVO_SUPPORT != 0)
- else if(b >= 0xc0 && b < 0xc8) // dolby digital +
- {
- s.ps1id = (BYTE)BitRead(8);
- s.pid = (WORD)((BitRead(8) << 8) | BitRead(16)); // pid = 0x9000 | track id
-
- w = (WORD)BitRead(16, true);
-
- if(w == 0x0b77)
- {
- CMpegSplitterFile::ac3hdr h;
- if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
- type = audio;
- }
- }
+ else if(b >= 0xc0 && b < 0xc8) // dolby digital +
+ {
+ s.ps1id = (BYTE)BitRead(8);
+ s.pid = (WORD)((BitRead(8) << 8) | BitRead(16)); // pid = 0x9000 | track id
+
+ w = (WORD)BitRead(16, true);
+
+ if(w == 0x0b77)
+ {
+ CMpegSplitterFile::ac3hdr h;
+ if(!m_streams[audio].Find(s) && Read(h, len, &s.mt))
+ type = audio;
+ }
+ }
#endif
- }
- }
- else if(pesid == 0xbe) // padding
- {
- }
- else if(pesid == 0xbf) // private stream 2
- {
- }
-
- if(type != unknown && !m_streams[type].Find(s))
- {
- if(s.pid)
- {
- for(int i = 0; i < unknown; i++)
- {
- if(m_streams[i].Find(s))
- {
- /*ASSERT(0);*/
- return s;
- }
- }
- }
-
- m_streams[type].Insert(s, this);
- }
-
- return s;
+ }
+ }
+ else if(pesid == 0xbe) // padding
+ {
+ }
+ else if(pesid == 0xbf) // private stream 2
+ {
+ }
+
+ if(type != unknown && !m_streams[type].Find(s))
+ {
+ if(s.pid)
+ {
+ for(int i = 0; i < unknown; i++)
+ {
+ if(m_streams[i].Find(s))
+ {
+ /*ASSERT(0);*/
+ return s;
+ }
+ }
+ }
+
+ m_streams[type].Insert(s, this);
+ }
+
+ return s;
}
void CMpegSplitterFile::AddHdmvPGStream(WORD pid, const char* language_code)
{
- stream s;
+ stream s;
- s.pid = pid;
- s.pesid = 0xbd;
+ s.pid = pid;
+ s.pesid = 0xbd;
- CMpegSplitterFile::hdmvsubhdr h;
- if(!m_streams[subpic].Find(s) && Read(h, &s.mt, language_code))
- {
- m_streams[subpic].Insert(s, this);
- }
+ CMpegSplitterFile::hdmvsubhdr h;
+ if(!m_streams[subpic].Find(s) && Read(h, &s.mt, language_code))
+ {
+ m_streams[subpic].Insert(s, this);
+ }
}
CAtlList<CMpegSplitterFile::stream>* CMpegSplitterFile::GetMasterStream()
{
- return
- !m_streams[video].IsEmpty() ? &m_streams[video] :
- !m_streams[audio].IsEmpty() ? &m_streams[audio] :
- !m_streams[subpic].IsEmpty() ? &m_streams[subpic] :
- NULL;
+ return
+ !m_streams[video].IsEmpty() ? &m_streams[video] :
+ !m_streams[audio].IsEmpty() ? &m_streams[audio] :
+ !m_streams[subpic].IsEmpty() ? &m_streams[subpic] :
+ NULL;
}
void CMpegSplitterFile::UpdatePrograms(const trhdr& h)
{
- CAutoLock cAutoLock(&m_csProps);
-
- if(h.pid == 0)
- {
- trsechdr h2;
- if(Read(h2) && h2.table_id == 0)
- {
- CAtlMap<WORD, bool> newprograms;
-
- int len = h2.section_length;
- len -= 5+4;
-
- for(int i = len/4; i > 0; i--)
- {
- WORD program_number = (WORD)BitRead(16);
- BYTE reserved = (BYTE)BitRead(3);
- WORD pid = (WORD)BitRead(13);
- if(program_number != 0)
- {
- m_programs[pid].program_number = program_number;
- newprograms[program_number] = true;
- }
- }
-
- POSITION pos = m_programs.GetStartPosition();
- while(pos)
- {
- const CAtlMap<WORD, program>::CPair* pPair = m_programs.GetNext(pos);
-
- if(!newprograms.Lookup(pPair->m_value.program_number))
- {
- m_programs.RemoveKey(pPair->m_key);
- }
- }
- }
- }
- else if(CAtlMap<WORD, program>::CPair* pPair = m_programs.Lookup(h.pid))
- {
- trsechdr h2;
- if(Read(h2) && h2.table_id == 2)
- {
- memset(pPair->m_value.streams, 0, sizeof(pPair->m_value.streams));
-
- int len = h2.section_length;
- len -= 5+4;
-
- BYTE reserved1 = (BYTE)BitRead(3);
- WORD PCR_PID = (WORD)BitRead(13);
- BYTE reserved2 = (BYTE)BitRead(4);
- WORD program_info_length = (WORD)BitRead(12);
-
- len -= 4+program_info_length;
-
- while(program_info_length-- > 0)
- BitRead(8);
-
- for(int i = 0; i < countof(pPair->m_value.streams) && len >= 5; i++)
- {
- BYTE stream_type = (BYTE)BitRead(8);
- BYTE nreserved1 = (BYTE)BitRead(3);
- WORD pid = (WORD)BitRead(13);
- BYTE nreserved2 = (BYTE)BitRead(4);
- WORD ES_info_length = (WORD)BitRead(12);
-
- len -= 5+ES_info_length;
-
- while(ES_info_length-- > 0)
- BitRead(8);
-
- pPair->m_value.streams[i].pid = pid;
- pPair->m_value.streams[i].type = (PES_STREAM_TYPE)stream_type;
- }
- }
- }
+ CAutoLock cAutoLock(&m_csProps);
+
+ if(h.pid == 0)
+ {
+ trsechdr h2;
+ if(Read(h2) && h2.table_id == 0)
+ {
+ CAtlMap<WORD, bool> newprograms;
+
+ int len = h2.section_length;
+ len -= 5 + 4;
+
+ for(int i = len / 4; i > 0; i--)
+ {
+ WORD program_number = (WORD)BitRead(16);
+ BYTE reserved = (BYTE)BitRead(3);
+ WORD pid = (WORD)BitRead(13);
+ if(program_number != 0)
+ {
+ m_programs[pid].program_number = program_number;
+ newprograms[program_number] = true;
+ }
+ }
+
+ POSITION pos = m_programs.GetStartPosition();
+ while(pos)
+ {
+ const CAtlMap<WORD, program>::CPair* pPair = m_programs.GetNext(pos);
+
+ if(!newprograms.Lookup(pPair->m_value.program_number))
+ {
+ m_programs.RemoveKey(pPair->m_key);
+ }
+ }
+ }
+ }
+ else if(CAtlMap<WORD, program>::CPair* pPair = m_programs.Lookup(h.pid))
+ {
+ trsechdr h2;
+ if(Read(h2) && h2.table_id == 2)
+ {
+ memset(pPair->m_value.streams, 0, sizeof(pPair->m_value.streams));
+
+ int len = h2.section_length;
+ len -= 5 + 4;
+
+ BYTE reserved1 = (BYTE)BitRead(3);
+ WORD PCR_PID = (WORD)BitRead(13);
+ BYTE reserved2 = (BYTE)BitRead(4);
+ WORD program_info_length = (WORD)BitRead(12);
+
+ len -= 4 + program_info_length;
+
+ while(program_info_length-- > 0)
+ BitRead(8);
+
+ for(int i = 0; i < countof(pPair->m_value.streams) && len >= 5; i++)
+ {
+ BYTE stream_type = (BYTE)BitRead(8);
+ BYTE nreserved1 = (BYTE)BitRead(3);
+ WORD pid = (WORD)BitRead(13);
+ BYTE nreserved2 = (BYTE)BitRead(4);
+ WORD ES_info_length = (WORD)BitRead(12);
+
+ len -= 5 + ES_info_length;
+
+ while(ES_info_length-- > 0)
+ BitRead(8);
+
+ pPair->m_value.streams[i].pid = pid;
+ pPair->m_value.streams[i].type = (PES_STREAM_TYPE)stream_type;
+ }
+ }
+ }
}
uint32 SwapLE(const uint32 &_Value)
{
- return (_Value & 0xFF) << 24 | ((_Value>>8) & 0xFF) << 16 | ((_Value>>16) & 0xFF) << 8 | ((_Value>>24) & 0xFF) << 0;
+ return (_Value & 0xFF) << 24 | ((_Value >> 8) & 0xFF) << 16 | ((_Value >> 16) & 0xFF) << 8 | ((_Value >> 24) & 0xFF) << 0;
}
uint16 SwapLE(const uint16 &_Value)
{
- return (_Value & 0xFF) << 8 | ((_Value>>8) & 0xFF) << 0;
+ return (_Value & 0xFF) << 8 | ((_Value >> 8) & 0xFF) << 0;
}
const CMpegSplitterFile::program* CMpegSplitterFile::FindProgram(WORD pid, int &iStream, const CHdmvClipInfo::Stream * &_pClipInfo)
{
- _pClipInfo = m_ClipInfo.FindStream(pid);
+ _pClipInfo = m_ClipInfo.FindStream(pid);
- iStream = -1;
+ iStream = -1;
- POSITION pos = m_programs.GetStartPosition();
+ POSITION pos = m_programs.GetStartPosition();
- while(pos)
- {
- program* p = &m_programs.GetNextValue(pos);
+ while(pos)
+ {
+ program* p = &m_programs.GetNextValue(pos);
- for(int i = 0; i < countof(p->streams); i++)
- {
- if(p->streams[i].pid == pid)
- {
- iStream = i;
- return p;
- }
- }
- }
+ for(int i = 0; i < countof(p->streams); i++)
+ {
+ if(p->streams[i].pid == pid)
+ {
+ iStream = i;
+ return p;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
diff --git a/src/filters/parser/MpegSplitter/MpegSplitterFile.h b/src/filters/parser/MpegSplitter/MpegSplitterFile.h
index d9bee0f42..237beb3e6 100644
--- a/src/filters/parser/MpegSplitter/MpegSplitterFile.h
+++ b/src/filters/parser/MpegSplitter/MpegSplitterFile.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,103 +30,122 @@
class CMpegSplitterFile : public CBaseSplitterFileEx
{
- CAtlMap<WORD, BYTE> m_pid2pes;
- CMpegSplitterFile::avchdr avch;
- bool m_bIsHdmv;
+ CAtlMap<WORD, BYTE> m_pid2pes;
+ CMpegSplitterFile::avchdr avch;
+ bool m_bIsHdmv;
- HRESULT Init();
+ HRESULT Init();
- void OnComplete();
+ void OnComplete();
public:
- CHdmvClipInfo &m_ClipInfo;
- CMpegSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr, bool bIsHdmv, CHdmvClipInfo &ClipInfo);
-
- REFERENCE_TIME NextPTS(DWORD TrackNum);
-
- CCritSec m_csProps;
-
- enum {us, ps, ts, es, pva} m_type;
-
- REFERENCE_TIME m_rtMin, m_rtMax;
- __int64 m_posMin, m_posMax;
- int m_rate; // byte/sec
-
- struct stream
- {
- CMpegSplitterFile *m_pFile;
- CMediaType mt;
- WORD pid;
- BYTE pesid, ps1id;
- bool operator < (const stream &_Other) const;
- struct stream() {pid = pesid = ps1id = 0;}
- operator DWORD() const {return pid ? pid : ((pesid<<8)|ps1id);}
- bool operator == (const struct stream& s) const {return (DWORD)*this == (DWORD)s;}
- };
-
- enum {video, audio, subpic, unknown};
-
- class CStreamList : public CAtlList<stream>
- {
- public:
- void Insert(stream& s, CMpegSplitterFile *_pFile)
- {
- s.m_pFile = _pFile;
- for(POSITION pos = GetHeadPosition(); pos; GetNext(pos))
- {
- stream& s2 = GetAt(pos);
- if(s < s2) {InsertBefore(pos, s); return;}
- }
-
- AddTail(s);
- }
-
- static CStringW ToString(int type)
- {
- return
- type == video ? L"Video" :
- type == audio ? L"Audio" :
- type == subpic ? L"Subtitle" :
- L"Unknown";
- }
-
- const stream* FindStream(int pid)
- {
- for(POSITION pos = GetHeadPosition(); pos; GetNext(pos))
- {
- const stream& s = GetAt(pos);
- if(s.pid == pid) return &s;
- }
-
- return NULL;
- }
-
- } m_streams[unknown];
-
- HRESULT SearchStreams(__int64 start, __int64 stop);
- DWORD AddStream(WORD pid, BYTE pesid, DWORD len);
- void AddHdmvPGStream(WORD pid, const char* language_code);
- CAtlList<stream>* GetMasterStream();
- bool IsHdmv() { return m_bIsHdmv; };
-
- struct program
- {
- WORD program_number;
- struct stream
- {
- WORD pid;
- PES_STREAM_TYPE type;
-
- };
- stream streams[64];
- struct program() {memset(this, 0, sizeof(*this));}
- };
-
- CAtlMap<WORD, program> m_programs;
-
- void UpdatePrograms(const trhdr& h);
- const program* FindProgram(WORD pid, int &iStream, const CHdmvClipInfo::Stream * &_pClipInfo);
-
-
+ CHdmvClipInfo &m_ClipInfo;
+ CMpegSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr, bool bIsHdmv, CHdmvClipInfo &ClipInfo);
+
+ REFERENCE_TIME NextPTS(DWORD TrackNum);
+
+ CCritSec m_csProps;
+
+ enum {us, ps, ts, es, pva} m_type;
+
+ REFERENCE_TIME m_rtMin, m_rtMax;
+ __int64 m_posMin, m_posMax;
+ int m_rate; // byte/sec
+
+ struct stream
+ {
+ CMpegSplitterFile *m_pFile;
+ CMediaType mt;
+ WORD pid;
+ BYTE pesid, ps1id;
+ bool operator < (const stream &_Other) const;
+ struct stream()
+ {
+ pid = pesid = ps1id = 0;
+ }
+ operator DWORD() const
+ {
+ return pid ? pid : ((pesid << 8) | ps1id);
+ }
+ bool operator == (const struct stream& s) const
+ {
+ return (DWORD) * this == (DWORD)s;
+ }
+ };
+
+ enum {video, audio, subpic, unknown};
+
+ class CStreamList : public CAtlList<stream>
+ {
+ public:
+ void Insert(stream& s, CMpegSplitterFile *_pFile)
+ {
+ s.m_pFile = _pFile;
+ for(POSITION pos = GetHeadPosition(); pos; GetNext(pos))
+ {
+ stream& s2 = GetAt(pos);
+ if(s < s2)
+ {
+ InsertBefore(pos, s);
+ return;
+ }
+ }
+
+ AddTail(s);
+ }
+
+ static CStringW ToString(int type)
+ {
+ return
+ type == video ? L"Video" :
+ type == audio ? L"Audio" :
+ type == subpic ? L"Subtitle" :
+ L"Unknown";
+ }
+
+ const stream* FindStream(int pid)
+ {
+ for(POSITION pos = GetHeadPosition(); pos; GetNext(pos))
+ {
+ const stream& s = GetAt(pos);
+ if(s.pid == pid) return &s;
+ }
+
+ return NULL;
+ }
+
+ } m_streams[unknown];
+
+ HRESULT SearchStreams(__int64 start, __int64 stop);
+ DWORD AddStream(WORD pid, BYTE pesid, DWORD len);
+ void AddHdmvPGStream(WORD pid, const char* language_code);
+ CAtlList<stream>* GetMasterStream();
+ bool IsHdmv()
+ {
+ return m_bIsHdmv;
+ };
+
+ struct program
+ {
+ WORD program_number;
+ struct stream
+ {
+ WORD pid;
+ PES_STREAM_TYPE type;
+
+ };
+ stream streams[64];
+ struct program()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+ };
+
+ CAtlMap<WORD, program> m_programs;
+
+ void UpdatePrograms(const trhdr& h);
+ const program* FindProgram(WORD pid, int &iStream, const CHdmvClipInfo::Stream * &_pClipInfo);
+
+
};
diff --git a/src/filters/parser/MpegSplitter/resource.h b/src/filters/parser/MpegSplitter/resource.h
index 1ae4564c5..51170d5ba 100644
--- a/src/filters/parser/MpegSplitter/resource.h
+++ b/src/filters/parser/MpegSplitter/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/parser/MpegSplitter/stdafx.cpp b/src/filters/parser/MpegSplitter/stdafx.cpp
index 4284c08d9..e1ec5adac 100644
--- a/src/filters/parser/MpegSplitter/stdafx.cpp
+++ b/src/filters/parser/MpegSplitter/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/parser/MpegSplitter/stdafx.h b/src/filters/parser/MpegSplitter/stdafx.h
index aefacf4f0..c0b16b75c 100644
--- a/src/filters/parser/MpegSplitter/stdafx.h
+++ b/src/filters/parser/MpegSplitter/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
*
*/