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

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@users.sourceforge.net>2012-06-13 13:05:30 +0400
committerXhmikosR <xhmikosr@users.sourceforge.net>2012-06-13 13:05:30 +0400
commit0b9ec9a361f62ce15fc58763ca8b533afe405973 (patch)
tree02fb318875748db7e28f0b303d9907e58d69ca8c /src/filters/parser/BaseSplitter
parentd3b052fb035d8b242e4b328722f4ed7ac84ee20c (diff)
apply the new astyle command; use 4 spaces for indentation and k&r style
Note: if you have any local patches just run astyle.bat git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@5110 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser/BaseSplitter')
-rw-r--r--src/filters/parser/BaseSplitter/AsyncReader.cpp290
-rw-r--r--src/filters/parser/BaseSplitter/AsyncReader.h128
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitter.cpp1937
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitter.h656
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitterFile.cpp304
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitterFile.h52
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp3933
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitterFileEx.h802
-rw-r--r--src/filters/parser/BaseSplitter/MultiFiles.cpp238
-rw-r--r--src/filters/parser/BaseSplitter/MultiFiles.h108
10 files changed, 4218 insertions, 4230 deletions
diff --git a/src/filters/parser/BaseSplitter/AsyncReader.cpp b/src/filters/parser/BaseSplitter/AsyncReader.cpp
index 1a14a52b2..7ae1455af 100644
--- a/src/filters/parser/BaseSplitter/AsyncReader.cpp
+++ b/src/filters/parser/BaseSplitter/AsyncReader.cpp
@@ -33,110 +33,110 @@
//
CAsyncFileReader::CAsyncFileReader(CString fn, HRESULT& hr)
- : CUnknown(NAME("CAsyncFileReader"), NULL, &hr)
- , m_len((ULONGLONG)-1)
- , m_hBreakEvent(NULL)
- , m_lOsError(0)
+ : CUnknown(NAME("CAsyncFileReader"), NULL, &hr)
+ , m_len((ULONGLONG) - 1)
+ , m_hBreakEvent(NULL)
+ , m_lOsError(0)
{
- hr = Open(fn, modeRead|shareDenyNone|typeBinary|osSequentialScan) ? S_OK : E_FAIL;
- if (SUCCEEDED(hr)) {
- m_len = GetLength();
- }
+ hr = Open(fn, modeRead | shareDenyNone | typeBinary | osSequentialScan) ? S_OK : E_FAIL;
+ if (SUCCEEDED(hr)) {
+ m_len = GetLength();
+ }
}
CAsyncFileReader::CAsyncFileReader(CAtlList<CHdmvClipInfo::PlaylistItem>& Items, HRESULT& hr)
- : CUnknown(NAME("CAsyncFileReader"), NULL, &hr)
- , m_len((ULONGLONG)-1)
- , m_hBreakEvent(NULL)
- , m_lOsError(0)
+ : CUnknown(NAME("CAsyncFileReader"), NULL, &hr)
+ , m_len((ULONGLONG) - 1)
+ , m_hBreakEvent(NULL)
+ , m_lOsError(0)
{
- hr = OpenFiles(Items, modeRead|shareDenyNone|typeBinary|osSequentialScan) ? S_OK : E_FAIL;
- if (SUCCEEDED(hr)) {
- m_len = GetLength();
- }
+ hr = OpenFiles(Items, modeRead | shareDenyNone | typeBinary | osSequentialScan) ? S_OK : E_FAIL;
+ if (SUCCEEDED(hr)) {
+ m_len = GetLength();
+ }
}
STDMETHODIMP CAsyncFileReader::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- return
- QI(IAsyncReader)
- QI(ISyncReader)
- QI(IFileHandle)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ QI(IAsyncReader)
+ QI(ISyncReader)
+ QI(IFileHandle)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
// IAsyncReader
STDMETHODIMP CAsyncFileReader::SyncRead(LONGLONG llPosition, LONG lLength, BYTE* pBuffer)
{
- do {
- try {
- if ((ULONGLONG)llPosition+lLength > GetLength()) {
- return E_FAIL; // strange, but the Seek below can return llPosition even if the file is not that big (?)
- }
- if ((ULONGLONG)llPosition != Seek(llPosition, begin)) {
- return E_FAIL;
- }
- if ((UINT)lLength < Read(pBuffer, lLength)) {
- return E_FAIL;
- }
+ do {
+ try {
+ if ((ULONGLONG)llPosition + lLength > GetLength()) {
+ return E_FAIL; // strange, but the Seek below can return llPosition even if the file is not that big (?)
+ }
+ if ((ULONGLONG)llPosition != Seek(llPosition, begin)) {
+ return E_FAIL;
+ }
+ if ((UINT)lLength < Read(pBuffer, lLength)) {
+ return E_FAIL;
+ }
#if 0 // def DEBUG
- static __int64 s_total = 0, s_laststoppos = 0;
- s_total += lLength;
- if (s_laststoppos > llPosition) {
- TRACE(_T("[%I64d - %I64d] %d (%I64d)\n"), llPosition, llPosition + lLength, lLength, s_total);
- }
- s_laststoppos = llPosition + lLength;
+ static __int64 s_total = 0, s_laststoppos = 0;
+ s_total += lLength;
+ if (s_laststoppos > llPosition) {
+ TRACE(_T("[%I64d - %I64d] %d (%I64d)\n"), llPosition, llPosition + lLength, lLength, s_total);
+ }
+ s_laststoppos = llPosition + lLength;
#endif
- return S_OK;
- } catch (CFileException* e) {
- m_lOsError = e->m_lOsError;
- e->Delete();
- Sleep(1);
- CString fn = m_strFileName;
- try {
- Close();
- } catch (CFileException* e) {
- e->Delete();
- }
- try {
- Open(fn, modeRead|shareDenyNone|typeBinary|osSequentialScan);
- } catch (CFileException* e) {
- e->Delete();
- }
- m_strFileName = fn;
- }
- } while (m_hBreakEvent && WaitForSingleObject(m_hBreakEvent, 0) == WAIT_TIMEOUT);
-
- return E_FAIL;
+ return S_OK;
+ } catch (CFileException* e) {
+ m_lOsError = e->m_lOsError;
+ e->Delete();
+ Sleep(1);
+ CString fn = m_strFileName;
+ try {
+ Close();
+ } catch (CFileException* e) {
+ e->Delete();
+ }
+ try {
+ Open(fn, modeRead | shareDenyNone | typeBinary | osSequentialScan);
+ } catch (CFileException* e) {
+ e->Delete();
+ }
+ m_strFileName = fn;
+ }
+ } while (m_hBreakEvent && WaitForSingleObject(m_hBreakEvent, 0) == WAIT_TIMEOUT);
+
+ return E_FAIL;
}
STDMETHODIMP CAsyncFileReader::Length(LONGLONG* pTotal, LONGLONG* pAvailable)
{
- LONGLONG len = m_len >= 0 ? m_len : GetLength();
- if (pTotal) {
- *pTotal = len;
- }
- if (pAvailable) {
- *pAvailable = len;
- }
- return S_OK;
+ LONGLONG len = m_len >= 0 ? m_len : GetLength();
+ if (pTotal) {
+ *pTotal = len;
+ }
+ if (pAvailable) {
+ *pAvailable = len;
+ }
+ return S_OK;
}
// IFileHandle
STDMETHODIMP_(HANDLE) CAsyncFileReader::GetFileHandle()
{
- return m_hFile;
+ return m_hFile;
}
STDMETHODIMP_(LPCTSTR) CAsyncFileReader::GetFileName()
{
- return m_nCurPart != -1 ? m_strFiles[m_nCurPart] : m_strFiles[0];
+ return m_nCurPart != -1 ? m_strFiles[m_nCurPart] : m_strFiles[0];
}
//
@@ -144,99 +144,99 @@ STDMETHODIMP_(LPCTSTR) CAsyncFileReader::GetFileName()
//
CAsyncUrlReader::CAsyncUrlReader(CString url, HRESULT& hr)
- : CAsyncFileReader(url, hr)
+ : CAsyncFileReader(url, hr)
{
- if (SUCCEEDED(hr)) {
- return;
- }
+ if (SUCCEEDED(hr)) {
+ return;
+ }
- m_url = url;
+ m_url = url;
- if (CAMThread::Create()) {
- CallWorker(CMD_INIT);
- }
+ if (CAMThread::Create()) {
+ CallWorker(CMD_INIT);
+ }
- hr = Open(m_fn, modeRead|shareDenyRead|typeBinary|osSequentialScan) ? S_OK : E_FAIL;
- m_len = (ULONGLONG)-1; // force GetLength() return actual length always
+ hr = Open(m_fn, modeRead | shareDenyRead | typeBinary | osSequentialScan) ? S_OK : E_FAIL;
+ m_len = (ULONGLONG) - 1; // force GetLength() return actual length always
}
CAsyncUrlReader::~CAsyncUrlReader()
{
- if (ThreadExists()) {
- CallWorker(CMD_EXIT);
- }
-
- if (!m_fn.IsEmpty()) {
- CMultiFiles::Close();
- DeleteFile(m_fn);
- }
+ if (ThreadExists()) {
+ CallWorker(CMD_EXIT);
+ }
+
+ if (!m_fn.IsEmpty()) {
+ CMultiFiles::Close();
+ DeleteFile(m_fn);
+ }
}
// IAsyncReader
STDMETHODIMP CAsyncUrlReader::Length(LONGLONG* pTotal, LONGLONG* pAvailable)
{
- if (pTotal) {
- *pTotal = 0;
- }
- return __super::Length(NULL, pAvailable);
+ if (pTotal) {
+ *pTotal = 0;
+ }
+ return __super::Length(NULL, pAvailable);
}
// CAMThread
DWORD CAsyncUrlReader::ThreadProc()
{
- AfxSocketInit(NULL);
-
- DWORD cmd = GetRequest();
- if (cmd != CMD_INIT) {
- Reply((DWORD)E_FAIL);
- return (DWORD)-1;
- }
-
- try {
- CInternetSession is;
- CAutoPtr<CStdioFile> fin(is.OpenURL(m_url, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_CACHE_WRITE));
-
- TCHAR path[_MAX_PATH], fn[_MAX_PATH];
- CFile fout;
- if (GetTempPath(_MAX_PATH, path) && GetTempFileName(path, _T("mpc_http"), 0, fn)
- && fout.Open(fn, modeCreate|modeWrite|shareDenyWrite|typeBinary)) {
- m_fn = fn;
-
- char buff[1024];
- int len = fin->Read(buff, sizeof(buff));
- if (len > 0) {
- fout.Write(buff, len);
- }
-
- Reply(S_OK);
-
- while (!CheckRequest(&cmd)) {
- int len = fin->Read(buff, sizeof(buff));
- if (len > 0) {
- fout.Write(buff, len);
- }
- }
- } else {
- Reply((DWORD)E_FAIL);
- }
-
- fin->Close(); // must close it because the destructor doesn't seem to do it and we will get an exception when "is" is destroying
- } catch (CInternetException* ie) {
- ie->Delete();
- Reply((DWORD)E_FAIL);
- }
-
- //
-
- cmd = GetRequest();
- ASSERT(cmd == CMD_EXIT);
- Reply(S_OK);
-
- //
-
- m_hThread = NULL;
-
- return S_OK;
+ AfxSocketInit(NULL);
+
+ DWORD cmd = GetRequest();
+ if (cmd != CMD_INIT) {
+ Reply((DWORD)E_FAIL);
+ return (DWORD) - 1;
+ }
+
+ try {
+ CInternetSession is;
+ CAutoPtr<CStdioFile> fin(is.OpenURL(m_url, 1, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_CACHE_WRITE));
+
+ TCHAR path[_MAX_PATH], fn[_MAX_PATH];
+ CFile fout;
+ if (GetTempPath(_MAX_PATH, path) && GetTempFileName(path, _T("mpc_http"), 0, fn)
+ && fout.Open(fn, modeCreate | modeWrite | shareDenyWrite | typeBinary)) {
+ m_fn = fn;
+
+ char buff[1024];
+ int len = fin->Read(buff, sizeof(buff));
+ if (len > 0) {
+ fout.Write(buff, len);
+ }
+
+ Reply(S_OK);
+
+ while (!CheckRequest(&cmd)) {
+ int len = fin->Read(buff, sizeof(buff));
+ if (len > 0) {
+ fout.Write(buff, len);
+ }
+ }
+ } else {
+ Reply((DWORD)E_FAIL);
+ }
+
+ fin->Close(); // must close it because the destructor doesn't seem to do it and we will get an exception when "is" is destroying
+ } catch (CInternetException* ie) {
+ ie->Delete();
+ Reply((DWORD)E_FAIL);
+ }
+
+ //
+
+ cmd = GetRequest();
+ ASSERT(cmd == CMD_EXIT);
+ Reply(S_OK);
+
+ //
+
+ m_hThread = NULL;
+
+ return S_OK;
}
diff --git a/src/filters/parser/BaseSplitter/AsyncReader.h b/src/filters/parser/BaseSplitter/AsyncReader.h
index c41223421..3bac9b034 100644
--- a/src/filters/parser/BaseSplitter/AsyncReader.h
+++ b/src/filters/parser/BaseSplitter/AsyncReader.h
@@ -28,91 +28,91 @@
interface __declspec(uuid("6DDB4EE7-45A0-4459-A508-BD77B32C91B2"))
ISyncReader :
public IUnknown {
- STDMETHOD_(void, SetBreakEvent) (HANDLE hBreakEvent) = 0;
- STDMETHOD_(bool, HasErrors) () = 0;
- STDMETHOD_(void, ClearErrors) () = 0;
- STDMETHOD_(void, SetPTSOffset) (REFERENCE_TIME* rtPTSOffset) = 0;
+ STDMETHOD_(void, SetBreakEvent)(HANDLE hBreakEvent) = 0;
+ STDMETHOD_(bool, HasErrors)() = 0;
+ STDMETHOD_(void, ClearErrors)() = 0;
+ STDMETHOD_(void, SetPTSOffset)(REFERENCE_TIME * rtPTSOffset) = 0;
};
interface __declspec(uuid("7D55F67A-826E-40B9-8A7D-3DF0CBBD272D"))
IFileHandle :
public IUnknown {
- STDMETHOD_(HANDLE, GetFileHandle)() = 0;
- STDMETHOD_(LPCTSTR, GetFileName)() = 0;
+ STDMETHOD_(HANDLE, GetFileHandle)() = 0;
+ STDMETHOD_(LPCTSTR, GetFileName)() = 0;
};
class CAsyncFileReader : public CUnknown, public CMultiFiles, public IAsyncReader, public ISyncReader, public IFileHandle
{
protected:
- ULONGLONG m_len;
- HANDLE m_hBreakEvent;
- LONG m_lOsError; // CFileException::m_lOsError
+ ULONGLONG m_len;
+ HANDLE m_hBreakEvent;
+ LONG m_lOsError; // CFileException::m_lOsError
public:
- CAsyncFileReader(CString fn, HRESULT& hr);
- CAsyncFileReader(CAtlList<CHdmvClipInfo::PlaylistItem>& Items, HRESULT& hr);
-
- DECLARE_IUNKNOWN;
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
-
- // IAsyncReader
-
- STDMETHODIMP RequestAllocator(IMemAllocator* pPreferred, ALLOCATOR_PROPERTIES* pProps, IMemAllocator** ppActual) {
- return E_NOTIMPL;
- }
- STDMETHODIMP Request(IMediaSample* pSample, DWORD_PTR dwUser) {
- return E_NOTIMPL;
- }
- STDMETHODIMP WaitForNext(DWORD dwTimeout, IMediaSample** ppSample, DWORD_PTR* pdwUser) {
- return E_NOTIMPL;
- }
- STDMETHODIMP SyncReadAligned(IMediaSample* pSample) {
- return E_NOTIMPL;
- }
- STDMETHODIMP SyncRead(LONGLONG llPosition, LONG lLength, BYTE* pBuffer);
- STDMETHODIMP Length(LONGLONG* pTotal, LONGLONG* pAvailable);
- STDMETHODIMP BeginFlush() {
- return E_NOTIMPL;
- }
- STDMETHODIMP EndFlush() {
- return E_NOTIMPL;
- }
-
- // ISyncReader
-
- STDMETHODIMP_(void) SetBreakEvent(HANDLE hBreakEvent) {
- m_hBreakEvent = hBreakEvent;
- }
- STDMETHODIMP_(bool) HasErrors() {
- return m_lOsError != 0;
- }
- STDMETHODIMP_(void) ClearErrors() {
- m_lOsError = 0;
- }
- STDMETHODIMP_(void) SetPTSOffset (REFERENCE_TIME* rtPTSOffset) {
- m_pCurrentPTSOffset = rtPTSOffset;
- };
-
- // IFileHandle
-
- STDMETHODIMP_(HANDLE) GetFileHandle();
- STDMETHODIMP_(LPCTSTR) GetFileName();
+ CAsyncFileReader(CString fn, HRESULT& hr);
+ CAsyncFileReader(CAtlList<CHdmvClipInfo::PlaylistItem>& Items, HRESULT& hr);
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IAsyncReader
+
+ STDMETHODIMP RequestAllocator(IMemAllocator* pPreferred, ALLOCATOR_PROPERTIES* pProps, IMemAllocator** ppActual) {
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP Request(IMediaSample* pSample, DWORD_PTR dwUser) {
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP WaitForNext(DWORD dwTimeout, IMediaSample** ppSample, DWORD_PTR* pdwUser) {
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP SyncReadAligned(IMediaSample* pSample) {
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP SyncRead(LONGLONG llPosition, LONG lLength, BYTE* pBuffer);
+ STDMETHODIMP Length(LONGLONG* pTotal, LONGLONG* pAvailable);
+ STDMETHODIMP BeginFlush() {
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP EndFlush() {
+ return E_NOTIMPL;
+ }
+
+ // ISyncReader
+
+ STDMETHODIMP_(void) SetBreakEvent(HANDLE hBreakEvent) {
+ m_hBreakEvent = hBreakEvent;
+ }
+ STDMETHODIMP_(bool) HasErrors() {
+ return m_lOsError != 0;
+ }
+ STDMETHODIMP_(void) ClearErrors() {
+ m_lOsError = 0;
+ }
+ STDMETHODIMP_(void) SetPTSOffset(REFERENCE_TIME* rtPTSOffset) {
+ m_pCurrentPTSOffset = rtPTSOffset;
+ };
+
+ // IFileHandle
+
+ STDMETHODIMP_(HANDLE) GetFileHandle();
+ STDMETHODIMP_(LPCTSTR) GetFileName();
};
class CAsyncUrlReader : public CAsyncFileReader, protected CAMThread
{
- CString m_url, m_fn;
+ CString m_url, m_fn;
protected:
- enum {CMD_EXIT, CMD_INIT};
- DWORD ThreadProc();
+ enum {CMD_EXIT, CMD_INIT};
+ DWORD ThreadProc();
public:
- CAsyncUrlReader(CString url, HRESULT& hr);
- virtual ~CAsyncUrlReader();
+ CAsyncUrlReader(CString url, HRESULT& hr);
+ virtual ~CAsyncUrlReader();
- // IAsyncReader
+ // IAsyncReader
- STDMETHODIMP Length(LONGLONG* pTotal, LONGLONG* pAvailable);
+ STDMETHODIMP Length(LONGLONG* pTotal, LONGLONG* pAvailable);
};
diff --git a/src/filters/parser/BaseSplitter/BaseSplitter.cpp b/src/filters/parser/BaseSplitter/BaseSplitter.cpp
index 4787c6222..4e71285e0 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitter.cpp
+++ b/src/filters/parser/BaseSplitter/BaseSplitter.cpp
@@ -39,57 +39,57 @@ CPacketQueue::CPacketQueue() : m_size(0)
void CPacketQueue::Add(CAutoPtr<Packet> p)
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- if (p) {
- m_size += p->GetDataSize();
+ if (p) {
+ m_size += p->GetDataSize();
- if (p->bAppendable && !p->bDiscontinuity && !p->pmt
- && p->rtStart == Packet::INVALID_TIME
- && !IsEmpty() && GetTail()->rtStart != Packet::INVALID_TIME) {
- Packet* tail = GetTail();
- size_t oldsize = tail->GetCount();
- size_t newsize = tail->GetCount() + p->GetCount();
- tail->SetCount(newsize, max(1024, (int)newsize)); // doubles the reserved buffer size
- memcpy(tail->GetData() + oldsize, p->GetData(), p->GetCount());
- /*
- GetTail()->Append(*p); // too slow
- */
- return;
- }
- }
+ if (p->bAppendable && !p->bDiscontinuity && !p->pmt
+ && p->rtStart == Packet::INVALID_TIME
+ && !IsEmpty() && GetTail()->rtStart != Packet::INVALID_TIME) {
+ Packet* tail = GetTail();
+ size_t oldsize = tail->GetCount();
+ size_t newsize = tail->GetCount() + p->GetCount();
+ tail->SetCount(newsize, max(1024, (int)newsize)); // doubles the reserved buffer size
+ memcpy(tail->GetData() + oldsize, p->GetData(), p->GetCount());
+ /*
+ GetTail()->Append(*p); // too slow
+ */
+ return;
+ }
+ }
- AddTail(p);
+ AddTail(p);
}
CAutoPtr<Packet> CPacketQueue::Remove()
{
- CAutoLock cAutoLock(this);
- ASSERT(__super::GetCount() > 0);
- CAutoPtr<Packet> p = RemoveHead();
- if (p) {
- m_size -= p->GetDataSize();
- }
- return p;
+ CAutoLock cAutoLock(this);
+ ASSERT(__super::GetCount() > 0);
+ CAutoPtr<Packet> p = RemoveHead();
+ if (p) {
+ m_size -= p->GetDataSize();
+ }
+ return p;
}
void CPacketQueue::RemoveAll()
{
- CAutoLock cAutoLock(this);
- m_size = 0;
- __super::RemoveAll();
+ CAutoLock cAutoLock(this);
+ m_size = 0;
+ __super::RemoveAll();
}
int CPacketQueue::GetCount()
{
- CAutoLock cAutoLock(this);
- return (int)__super::GetCount();
+ CAutoLock cAutoLock(this);
+ return (int)__super::GetCount();
}
int CPacketQueue::GetSize()
{
- CAutoLock cAutoLock(this);
- return m_size;
+ CAutoLock cAutoLock(this);
+ return m_size;
}
//
@@ -97,7 +97,7 @@ int CPacketQueue::GetSize()
//
CBaseSplitterInputPin::CBaseSplitterInputPin(TCHAR* pName, CBaseSplitterFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBasePin(pName, pFilter, pLock, phr, L"Input", PINDIR_INPUT)
+ : CBasePin(pName, pFilter, pLock, phr, L"Input", PINDIR_INPUT)
{
}
@@ -107,85 +107,85 @@ CBaseSplitterInputPin::~CBaseSplitterInputPin()
HRESULT CBaseSplitterInputPin::GetAsyncReader(IAsyncReader** ppAsyncReader)
{
- CheckPointer(ppAsyncReader, E_POINTER);
- *ppAsyncReader = NULL;
- CheckPointer(m_pAsyncReader, VFW_E_NOT_CONNECTED);
- (*ppAsyncReader = m_pAsyncReader)->AddRef();
- return S_OK;
+ CheckPointer(ppAsyncReader, E_POINTER);
+ *ppAsyncReader = NULL;
+ CheckPointer(m_pAsyncReader, VFW_E_NOT_CONNECTED);
+ (*ppAsyncReader = m_pAsyncReader)->AddRef();
+ return S_OK;
}
STDMETHODIMP CBaseSplitterInputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- return
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
HRESULT CBaseSplitterInputPin::CheckMediaType(const CMediaType* pmt)
{
- return S_OK;
- /*
- return pmt->majortype == MEDIATYPE_Stream
- ? S_OK
- : E_INVALIDARG;
- */
+ return S_OK;
+ /*
+ return pmt->majortype == MEDIATYPE_Stream
+ ? S_OK
+ : E_INVALIDARG;
+ */
}
HRESULT CBaseSplitterInputPin::CheckConnect(IPin* pPin)
{
- HRESULT hr;
- if (FAILED(hr = __super::CheckConnect(pPin))) {
- return hr;
- }
+ HRESULT hr;
+ if (FAILED(hr = __super::CheckConnect(pPin))) {
+ return hr;
+ }
- return CComQIPtr<IAsyncReader>(pPin) ? S_OK : E_NOINTERFACE;
+ return CComQIPtr<IAsyncReader>(pPin) ? S_OK : E_NOINTERFACE;
}
HRESULT CBaseSplitterInputPin::BreakConnect()
{
- HRESULT hr;
+ HRESULT hr;
- if (FAILED(hr = __super::BreakConnect())) {
- return hr;
- }
+ if (FAILED(hr = __super::BreakConnect())) {
+ return hr;
+ }
- if (FAILED(hr = (static_cast<CBaseSplitterFilter*>(m_pFilter))->BreakConnect(PINDIR_INPUT, this))) {
- return hr;
- }
+ if (FAILED(hr = (static_cast<CBaseSplitterFilter*>(m_pFilter))->BreakConnect(PINDIR_INPUT, this))) {
+ return hr;
+ }
- m_pAsyncReader.Release();
+ m_pAsyncReader.Release();
- return S_OK;
+ return S_OK;
}
HRESULT CBaseSplitterInputPin::CompleteConnect(IPin* pPin)
{
- HRESULT hr;
+ HRESULT hr;
- if (FAILED(hr = __super::CompleteConnect(pPin))) {
- return hr;
- }
+ if (FAILED(hr = __super::CompleteConnect(pPin))) {
+ return hr;
+ }
- CheckPointer(pPin, E_POINTER);
- m_pAsyncReader = pPin;
- CheckPointer(m_pAsyncReader, E_NOINTERFACE);
+ CheckPointer(pPin, E_POINTER);
+ m_pAsyncReader = pPin;
+ CheckPointer(m_pAsyncReader, E_NOINTERFACE);
- if (FAILED(hr = (static_cast<CBaseSplitterFilter*>(m_pFilter))->CompleteConnect(PINDIR_INPUT, this))) {
- return hr;
- }
+ if (FAILED(hr = (static_cast<CBaseSplitterFilter*>(m_pFilter))->CompleteConnect(PINDIR_INPUT, this))) {
+ return hr;
+ }
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterInputPin::BeginFlush()
{
- return E_UNEXPECTED;
+ return E_UNEXPECTED;
}
STDMETHODIMP CBaseSplitterInputPin::EndFlush()
{
- return E_UNEXPECTED;
+ return E_UNEXPECTED;
}
//
@@ -193,28 +193,28 @@ STDMETHODIMP CBaseSplitterInputPin::EndFlush()
//
CBaseSplitterOutputPin::CBaseSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers, int QueueMaxPackets)
- : CBaseOutputPin(NAME("CBaseSplitterOutputPin"), pFilter, pLock, phr, pName)
- , m_hrDeliver(S_OK) // just in case it were asked before the worker thread could be created and reset it
- , m_fFlushing(false)
- , m_eEndFlush(TRUE)
- , m_QueueMaxPackets(QueueMaxPackets)
+ : CBaseOutputPin(NAME("CBaseSplitterOutputPin"), pFilter, pLock, phr, pName)
+ , m_hrDeliver(S_OK) // just in case it were asked before the worker thread could be created and reset it
+ , m_fFlushing(false)
+ , m_eEndFlush(TRUE)
+ , m_QueueMaxPackets(QueueMaxPackets)
{
- m_mts.Copy(mts);
- m_nBuffers = max(nBuffers, 1);
- memset(&m_brs, 0, sizeof(m_brs));
- m_brs.rtLastDeliverTime = Packet::INVALID_TIME;
+ m_mts.Copy(mts);
+ m_nBuffers = max(nBuffers, 1);
+ memset(&m_brs, 0, sizeof(m_brs));
+ m_brs.rtLastDeliverTime = Packet::INVALID_TIME;
}
CBaseSplitterOutputPin::CBaseSplitterOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers, int QueueMaxPackets)
- : CBaseOutputPin(NAME("CBaseSplitterOutputPin"), pFilter, pLock, phr, pName)
- , m_hrDeliver(S_OK) // just in case it were asked before the worker thread could be created and reset it
- , m_fFlushing(false)
- , m_eEndFlush(TRUE)
- , m_QueueMaxPackets(QueueMaxPackets)
+ : CBaseOutputPin(NAME("CBaseSplitterOutputPin"), pFilter, pLock, phr, pName)
+ , m_hrDeliver(S_OK) // just in case it were asked before the worker thread could be created and reset it
+ , m_fFlushing(false)
+ , m_eEndFlush(TRUE)
+ , m_QueueMaxPackets(QueueMaxPackets)
{
- m_nBuffers = max(nBuffers, 1);
- memset(&m_brs, 0, sizeof(m_brs));
- m_brs.rtLastDeliverTime = Packet::INVALID_TIME;
+ m_nBuffers = max(nBuffers, 1);
+ memset(&m_brs, 0, sizeof(m_brs));
+ m_brs.rtLastDeliverTime = Packet::INVALID_TIME;
}
CBaseSplitterOutputPin::~CBaseSplitterOutputPin()
@@ -223,549 +223,549 @@ CBaseSplitterOutputPin::~CBaseSplitterOutputPin()
STDMETHODIMP CBaseSplitterOutputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- return
- // riid == __uuidof(IMediaSeeking) ? m_pFilter->QueryInterface(riid, ppv) :
- QI(IMediaSeeking)
- QI(IPropertyBag)
- QI(IPropertyBag2)
- QI(IDSMPropertyBag)
- QI(IBitRateInfo)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ // riid == __uuidof(IMediaSeeking) ? m_pFilter->QueryInterface(riid, ppv) :
+ QI(IMediaSeeking)
+ QI(IPropertyBag)
+ QI(IPropertyBag2)
+ QI(IDSMPropertyBag)
+ QI(IBitRateInfo)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
HRESULT CBaseSplitterOutputPin::SetName(LPCWSTR pName)
{
- CheckPointer(pName, E_POINTER);
- if (m_pName) {
- delete [] m_pName;
- }
- m_pName = DNew WCHAR[wcslen(pName)+1];
- CheckPointer(m_pName, E_OUTOFMEMORY);
- wcscpy_s(m_pName, wcslen(pName) + 1, pName);
- return S_OK;
+ CheckPointer(pName, E_POINTER);
+ if (m_pName) {
+ delete [] m_pName;
+ }
+ m_pName = DNew WCHAR[wcslen(pName) + 1];
+ CheckPointer(m_pName, E_OUTOFMEMORY);
+ wcscpy_s(m_pName, wcslen(pName) + 1, pName);
+ return S_OK;
}
HRESULT CBaseSplitterOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
{
- ASSERT(pAlloc);
- ASSERT(pProperties);
+ ASSERT(pAlloc);
+ ASSERT(pProperties);
- HRESULT hr = NOERROR;
+ HRESULT hr = NOERROR;
- pProperties->cBuffers = max(pProperties->cBuffers, m_nBuffers);
- pProperties->cbBuffer = max(m_mt.lSampleSize, 1);
+ pProperties->cBuffers = max(pProperties->cBuffers, m_nBuffers);
+ pProperties->cbBuffer = max(m_mt.lSampleSize, 1);
- // TODO: is this still needed ?
- if (m_mt.subtype == MEDIASUBTYPE_Vorbis && m_mt.formattype == FORMAT_VorbisFormat) {
- // oh great, the oggds vorbis decoder assumes there will be two at least, stupid thing...
- pProperties->cBuffers = max(pProperties->cBuffers, 2);
- }
+ // TODO: is this still needed ?
+ if (m_mt.subtype == MEDIASUBTYPE_Vorbis && m_mt.formattype == FORMAT_VorbisFormat) {
+ // oh great, the oggds vorbis decoder assumes there will be two at least, stupid thing...
+ pProperties->cBuffers = max(pProperties->cBuffers, 2);
+ }
- ALLOCATOR_PROPERTIES Actual;
- if (FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) {
- return hr;
- }
+ ALLOCATOR_PROPERTIES Actual;
+ if (FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) {
+ return hr;
+ }
- if (Actual.cbBuffer < pProperties->cbBuffer) {
- return E_FAIL;
- }
- ASSERT(Actual.cBuffers == pProperties->cBuffers);
+ if (Actual.cbBuffer < pProperties->cbBuffer) {
+ return E_FAIL;
+ }
+ ASSERT(Actual.cBuffers == pProperties->cBuffers);
- return NOERROR;
+ return NOERROR;
}
HRESULT CBaseSplitterOutputPin::CheckMediaType(const CMediaType* pmt)
{
- for (size_t i = 0; i < m_mts.GetCount(); i++) {
- if (*pmt == m_mts[i]) {
- return S_OK;
- }
- }
+ for (size_t i = 0; i < m_mts.GetCount(); i++) {
+ if (*pmt == m_mts[i]) {
+ return S_OK;
+ }
+ }
- return E_INVALIDARG;
+ return E_INVALIDARG;
}
HRESULT CBaseSplitterOutputPin::GetMediaType(int iPosition, CMediaType* pmt)
{
- CAutoLock cAutoLock(m_pLock);
+ CAutoLock cAutoLock(m_pLock);
- if (iPosition < 0) {
- return E_INVALIDARG;
- }
- if ((size_t)iPosition >= m_mts.GetCount()) {
- return VFW_S_NO_MORE_ITEMS;
- }
+ if (iPosition < 0) {
+ return E_INVALIDARG;
+ }
+ if ((size_t)iPosition >= m_mts.GetCount()) {
+ return VFW_S_NO_MORE_ITEMS;
+ }
- *pmt = m_mts[iPosition];
+ *pmt = m_mts[iPosition];
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterOutputPin::Notify(IBaseFilter* pSender, Quality q)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
//
HRESULT CBaseSplitterOutputPin::Active()
{
- CAutoLock cAutoLock(m_pLock);
+ CAutoLock cAutoLock(m_pLock);
- if (m_Connected) {
- Create();
- }
+ if (m_Connected) {
+ Create();
+ }
- return __super::Active();
+ return __super::Active();
}
HRESULT CBaseSplitterOutputPin::Inactive()
{
- CAutoLock cAutoLock(m_pLock);
+ CAutoLock cAutoLock(m_pLock);
- if (ThreadExists()) {
- CallWorker(CMD_EXIT);
- }
+ if (ThreadExists()) {
+ CallWorker(CMD_EXIT);
+ }
- return __super::Inactive();
+ return __super::Inactive();
}
HRESULT CBaseSplitterOutputPin::DeliverBeginFlush()
{
- m_eEndFlush.Reset();
- m_fFlushed = false;
- m_fFlushing = true;
- m_hrDeliver = S_FALSE;
- m_queue.RemoveAll();
- HRESULT hr = IsConnected() ? GetConnected()->BeginFlush() : S_OK;
- if (S_OK != hr) {
- m_eEndFlush.Set();
- }
- return hr;
+ m_eEndFlush.Reset();
+ m_fFlushed = false;
+ m_fFlushing = true;
+ m_hrDeliver = S_FALSE;
+ m_queue.RemoveAll();
+ HRESULT hr = IsConnected() ? GetConnected()->BeginFlush() : S_OK;
+ if (S_OK != hr) {
+ m_eEndFlush.Set();
+ }
+ return hr;
}
HRESULT CBaseSplitterOutputPin::DeliverEndFlush()
{
- if (!ThreadExists()) {
- return S_FALSE;
- }
- HRESULT hr = IsConnected() ? GetConnected()->EndFlush() : S_OK;
- m_hrDeliver = S_OK;
- m_fFlushing = false;
- m_fFlushed = true;
- m_eEndFlush.Set();
- return hr;
+ if (!ThreadExists()) {
+ return S_FALSE;
+ }
+ HRESULT hr = IsConnected() ? GetConnected()->EndFlush() : S_OK;
+ m_hrDeliver = S_OK;
+ m_fFlushing = false;
+ m_fFlushed = true;
+ m_eEndFlush.Set();
+ return hr;
}
HRESULT CBaseSplitterOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- m_brs.rtLastDeliverTime = Packet::INVALID_TIME;
- if (m_fFlushing) {
- return S_FALSE;
- }
- m_rtStart = tStart;
- if (!ThreadExists()) {
- return S_FALSE;
- }
- HRESULT hr = __super::DeliverNewSegment(tStart, tStop, dRate);
- if (S_OK != hr) {
- return hr;
- }
- MakeISCRHappy();
- return hr;
+ m_brs.rtLastDeliverTime = Packet::INVALID_TIME;
+ if (m_fFlushing) {
+ return S_FALSE;
+ }
+ m_rtStart = tStart;
+ if (!ThreadExists()) {
+ return S_FALSE;
+ }
+ HRESULT hr = __super::DeliverNewSegment(tStart, tStop, dRate);
+ if (S_OK != hr) {
+ return hr;
+ }
+ MakeISCRHappy();
+ return hr;
}
int CBaseSplitterOutputPin::QueueCount()
{
- return m_queue.GetCount();
+ return m_queue.GetCount();
}
int CBaseSplitterOutputPin::QueueSize()
{
- return m_queue.GetSize();
+ return m_queue.GetSize();
}
HRESULT CBaseSplitterOutputPin::QueueEndOfStream()
{
- return QueuePacket(CAutoPtr<Packet>()); // NULL means EndOfStream
+ return QueuePacket(CAutoPtr<Packet>()); // NULL means EndOfStream
}
HRESULT CBaseSplitterOutputPin::QueuePacket(CAutoPtr<Packet> p)
{
- if (!ThreadExists()) {
- return S_FALSE;
- }
+ if (!ThreadExists()) {
+ return S_FALSE;
+ }
- while (S_OK == m_hrDeliver
- && ((m_queue.GetCount() > (m_QueueMaxPackets*3/2) || m_queue.GetSize() > (MAXPACKETSIZE*3/2))
- || ((m_queue.GetCount() > m_QueueMaxPackets || m_queue.GetSize() > MAXPACKETSIZE) && !(static_cast<CBaseSplitterFilter*>(m_pFilter))->IsAnyPinDrying()))) {
- Sleep(10);
- }
+ while (S_OK == m_hrDeliver
+ && ((m_queue.GetCount() > (m_QueueMaxPackets * 3 / 2) || m_queue.GetSize() > (MAXPACKETSIZE * 3 / 2))
+ || ((m_queue.GetCount() > m_QueueMaxPackets || m_queue.GetSize() > MAXPACKETSIZE) && !(static_cast<CBaseSplitterFilter*>(m_pFilter))->IsAnyPinDrying()))) {
+ Sleep(10);
+ }
- if (S_OK != m_hrDeliver) {
- return m_hrDeliver;
- }
+ if (S_OK != m_hrDeliver) {
+ return m_hrDeliver;
+ }
- m_queue.Add(p);
+ m_queue.Add(p);
- return m_hrDeliver;
+ return m_hrDeliver;
}
bool CBaseSplitterOutputPin::IsDiscontinuous()
{
- return m_mt.majortype == MEDIATYPE_Text
- || m_mt.majortype == MEDIATYPE_ScriptCommand
- || m_mt.majortype == MEDIATYPE_Subtitle
- || m_mt.subtype == MEDIASUBTYPE_DVD_SUBPICTURE
- || m_mt.subtype == MEDIASUBTYPE_CVD_SUBPICTURE
- || m_mt.subtype == MEDIASUBTYPE_SVCD_SUBPICTURE;
+ return m_mt.majortype == MEDIATYPE_Text
+ || m_mt.majortype == MEDIATYPE_ScriptCommand
+ || m_mt.majortype == MEDIATYPE_Subtitle
+ || m_mt.subtype == MEDIASUBTYPE_DVD_SUBPICTURE
+ || m_mt.subtype == MEDIASUBTYPE_CVD_SUBPICTURE
+ || m_mt.subtype == MEDIASUBTYPE_SVCD_SUBPICTURE;
}
bool CBaseSplitterOutputPin::IsActive()
{
- CComPtr<IPin> pPin = this;
- do {
- CComPtr<IPin> pPinTo;
- CComQIPtr<IStreamSwitcherInputPin> pSSIP;
- if (S_OK == pPin->ConnectedTo(&pPinTo) && (pSSIP = pPinTo) && !pSSIP->IsActive()) {
- return false;
- }
- pPin = GetFirstPin(GetFilterFromPin(pPinTo), PINDIR_OUTPUT);
- } while (pPin);
+ CComPtr<IPin> pPin = this;
+ do {
+ CComPtr<IPin> pPinTo;
+ CComQIPtr<IStreamSwitcherInputPin> pSSIP;
+ if (S_OK == pPin->ConnectedTo(&pPinTo) && (pSSIP = pPinTo) && !pSSIP->IsActive()) {
+ return false;
+ }
+ pPin = GetFirstPin(GetFilterFromPin(pPinTo), PINDIR_OUTPUT);
+ } while (pPin);
- return true;
+ return true;
}
DWORD CBaseSplitterOutputPin::ThreadProc()
{
- SetThreadName((DWORD)-1, "CBaseSplitterOutputPin");
- m_hrDeliver = S_OK;
- m_fFlushing = m_fFlushed = false;
- m_eEndFlush.Set();
-
- // fix for Microsoft DTV-DVD Video Decoder - video freeze after STOP/PLAY
- bool iHaaliRenderConnect = false;
- CComPtr<IPin> pPinTo = this, pTmp;
- while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) {
- pTmp = NULL;
- CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo);
- if (GetCLSID(pBF) == CLSID_DXR) { // Haali Renderer
- iHaaliRenderConnect = true;
- break;
- }
- pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT);
- }
- if (IsConnected() && !iHaaliRenderConnect) {
- GetConnected()->BeginFlush();
- GetConnected()->EndFlush();
- }
-
- for (;;) {
- Sleep(1);
-
- DWORD cmd;
- if (CheckRequest(&cmd)) {
- m_hThread = NULL;
- cmd = GetRequest();
- Reply(S_OK);
- ASSERT(cmd == CMD_EXIT);
- return 0;
- }
-
- int cnt = 0;
- do {
- CAutoPtr<Packet> p;
-
- {
- CAutoLock cAutoLock(&m_queue);
- if ((cnt = m_queue.GetCount()) > 0) {
- p = m_queue.Remove();
- }
- }
-
- if (S_OK == m_hrDeliver && cnt > 0) {
- ASSERT(!m_fFlushing);
-
- m_fFlushed = false;
-
- // flushing can still start here, to release a blocked deliver call
-
- HRESULT hr = p
- ? DeliverPacket(p)
- : DeliverEndOfStream();
-
- m_eEndFlush.Wait(); // .. so we have to wait until it is done
-
- if (hr != S_OK && !m_fFlushed) { // and only report the error in m_hrDeliver if we didn't flush the stream
- // CAutoLock cAutoLock(&m_csQueueLock);
- m_hrDeliver = hr;
- break;
- }
- }
- } while (--cnt > 0);
- }
+ SetThreadName((DWORD) - 1, "CBaseSplitterOutputPin");
+ m_hrDeliver = S_OK;
+ m_fFlushing = m_fFlushed = false;
+ m_eEndFlush.Set();
+
+ // fix for Microsoft DTV-DVD Video Decoder - video freeze after STOP/PLAY
+ bool iHaaliRenderConnect = false;
+ CComPtr<IPin> pPinTo = this, pTmp;
+ while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) {
+ pTmp = NULL;
+ CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo);
+ if (GetCLSID(pBF) == CLSID_DXR) { // Haali Renderer
+ iHaaliRenderConnect = true;
+ break;
+ }
+ pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT);
+ }
+ if (IsConnected() && !iHaaliRenderConnect) {
+ GetConnected()->BeginFlush();
+ GetConnected()->EndFlush();
+ }
+
+ for (;;) {
+ Sleep(1);
+
+ DWORD cmd;
+ if (CheckRequest(&cmd)) {
+ m_hThread = NULL;
+ cmd = GetRequest();
+ Reply(S_OK);
+ ASSERT(cmd == CMD_EXIT);
+ return 0;
+ }
+
+ int cnt = 0;
+ do {
+ CAutoPtr<Packet> p;
+
+ {
+ CAutoLock cAutoLock(&m_queue);
+ if ((cnt = m_queue.GetCount()) > 0) {
+ p = m_queue.Remove();
+ }
+ }
+
+ if (S_OK == m_hrDeliver && cnt > 0) {
+ ASSERT(!m_fFlushing);
+
+ m_fFlushed = false;
+
+ // flushing can still start here, to release a blocked deliver call
+
+ HRESULT hr = p
+ ? DeliverPacket(p)
+ : DeliverEndOfStream();
+
+ m_eEndFlush.Wait(); // .. so we have to wait until it is done
+
+ if (hr != S_OK && !m_fFlushed) { // and only report the error in m_hrDeliver if we didn't flush the stream
+ // CAutoLock cAutoLock(&m_csQueueLock);
+ m_hrDeliver = hr;
+ break;
+ }
+ }
+ } while (--cnt > 0);
+ }
}
HRESULT CBaseSplitterOutputPin::DeliverPacket(CAutoPtr<Packet> p)
{
- HRESULT hr;
-
- long nBytes = (long)p->GetCount();
-
- if (nBytes == 0) {
- return S_OK;
- }
-
- m_brs.nBytesSinceLastDeliverTime += nBytes;
-
- if (p->rtStart != Packet::INVALID_TIME) {
- if (m_brs.rtLastDeliverTime == Packet::INVALID_TIME) {
- m_brs.rtLastDeliverTime = p->rtStart;
- m_brs.nBytesSinceLastDeliverTime = 0;
- }
-
- if (m_brs.rtLastDeliverTime + 10000000 < p->rtStart) {
- REFERENCE_TIME rtDiff = p->rtStart - m_brs.rtLastDeliverTime;
-
- double secs, bits;
-
- secs = (double)rtDiff / 10000000;
- bits = 8.0 * m_brs.nBytesSinceLastDeliverTime;
- m_brs.nCurrentBitRate = (DWORD)(bits / secs);
-
- m_brs.rtTotalTimeDelivered += rtDiff;
- m_brs.nTotalBytesDelivered += m_brs.nBytesSinceLastDeliverTime;
-
- secs = (double)m_brs.rtTotalTimeDelivered / 10000000;
- bits = 8.0 * m_brs.nTotalBytesDelivered;
- m_brs.nAverageBitRate = (DWORD)(bits / secs);
-
- m_brs.rtLastDeliverTime = p->rtStart;
- m_brs.nBytesSinceLastDeliverTime = 0;
- /*
- TRACE(_T("[%d] c: %d kbps, a: %d kbps\n"),
- p->TrackNumber,
- (m_brs.nCurrentBitRate+500)/1000,
- (m_brs.nAverageBitRate+500)/1000);
- */
- }
-
- double dRate = 1.0;
- if (SUCCEEDED((static_cast<CBaseSplitterFilter*>(m_pFilter))->GetRate(&dRate))) {
- p->rtStart = (REFERENCE_TIME)((double)p->rtStart / dRate);
- p->rtStop = (REFERENCE_TIME)((double)p->rtStop / dRate);
- }
- }
-
- do {
- CComPtr<IMediaSample> pSample;
- if (S_OK != (hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0))) {
- break;
- }
-
- if (nBytes > pSample->GetSize()) {
- pSample.Release();
-
- ALLOCATOR_PROPERTIES props, actual;
- if (S_OK != (hr = m_pAllocator->GetProperties(&props))) {
- break;
- }
- props.cbBuffer = nBytes*3/2;
-
- if (props.cBuffers > 1) {
- if (S_OK != (hr = __super::DeliverBeginFlush())) {
- break;
- }
- if (S_OK != (hr = __super::DeliverEndFlush())) {
- break;
- }
- }
-
- if (S_OK != (hr = m_pAllocator->Decommit())) {
- break;
- }
- if (S_OK != (hr = m_pAllocator->SetProperties(&props, &actual))) {
- break;
- }
- if (S_OK != (hr = m_pAllocator->Commit())) {
- break;
- }
- if (S_OK != (hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0))) {
- break;
- }
- }
-
- if (p->pmt) {
- pSample->SetMediaType(p->pmt);
- p->bDiscontinuity = true;
-
- CAutoLock cAutoLock(m_pLock);
- m_mts.RemoveAll();
- m_mts.Add(*p->pmt);
- }
-
- bool fTimeValid = p->rtStart != Packet::INVALID_TIME;
+ HRESULT hr;
+
+ long nBytes = (long)p->GetCount();
+
+ if (nBytes == 0) {
+ return S_OK;
+ }
+
+ m_brs.nBytesSinceLastDeliverTime += nBytes;
+
+ if (p->rtStart != Packet::INVALID_TIME) {
+ if (m_brs.rtLastDeliverTime == Packet::INVALID_TIME) {
+ m_brs.rtLastDeliverTime = p->rtStart;
+ m_brs.nBytesSinceLastDeliverTime = 0;
+ }
+
+ if (m_brs.rtLastDeliverTime + 10000000 < p->rtStart) {
+ REFERENCE_TIME rtDiff = p->rtStart - m_brs.rtLastDeliverTime;
+
+ double secs, bits;
+
+ secs = (double)rtDiff / 10000000;
+ bits = 8.0 * m_brs.nBytesSinceLastDeliverTime;
+ m_brs.nCurrentBitRate = (DWORD)(bits / secs);
+
+ m_brs.rtTotalTimeDelivered += rtDiff;
+ m_brs.nTotalBytesDelivered += m_brs.nBytesSinceLastDeliverTime;
+
+ secs = (double)m_brs.rtTotalTimeDelivered / 10000000;
+ bits = 8.0 * m_brs.nTotalBytesDelivered;
+ m_brs.nAverageBitRate = (DWORD)(bits / secs);
+
+ m_brs.rtLastDeliverTime = p->rtStart;
+ m_brs.nBytesSinceLastDeliverTime = 0;
+ /*
+ TRACE(_T("[%d] c: %d kbps, a: %d kbps\n"),
+ p->TrackNumber,
+ (m_brs.nCurrentBitRate+500)/1000,
+ (m_brs.nAverageBitRate+500)/1000);
+ */
+ }
+
+ double dRate = 1.0;
+ if (SUCCEEDED((static_cast<CBaseSplitterFilter*>(m_pFilter))->GetRate(&dRate))) {
+ p->rtStart = (REFERENCE_TIME)((double)p->rtStart / dRate);
+ p->rtStop = (REFERENCE_TIME)((double)p->rtStop / dRate);
+ }
+ }
+
+ do {
+ CComPtr<IMediaSample> pSample;
+ if (S_OK != (hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0))) {
+ break;
+ }
+
+ if (nBytes > pSample->GetSize()) {
+ pSample.Release();
+
+ ALLOCATOR_PROPERTIES props, actual;
+ if (S_OK != (hr = m_pAllocator->GetProperties(&props))) {
+ break;
+ }
+ props.cbBuffer = nBytes * 3 / 2;
+
+ if (props.cBuffers > 1) {
+ if (S_OK != (hr = __super::DeliverBeginFlush())) {
+ break;
+ }
+ if (S_OK != (hr = __super::DeliverEndFlush())) {
+ break;
+ }
+ }
+
+ if (S_OK != (hr = m_pAllocator->Decommit())) {
+ break;
+ }
+ if (S_OK != (hr = m_pAllocator->SetProperties(&props, &actual))) {
+ break;
+ }
+ if (S_OK != (hr = m_pAllocator->Commit())) {
+ break;
+ }
+ if (S_OK != (hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0))) {
+ break;
+ }
+ }
+
+ if (p->pmt) {
+ pSample->SetMediaType(p->pmt);
+ p->bDiscontinuity = true;
+
+ CAutoLock cAutoLock(m_pLock);
+ m_mts.RemoveAll();
+ m_mts.Add(*p->pmt);
+ }
+
+ bool fTimeValid = p->rtStart != Packet::INVALID_TIME;
#if defined(_DEBUG) && 0
- TRACE(_T("[%d]: d%d s%d p%d, b=%d, [%20I64d - %20I64d]\n"),
- p->TrackNumber,
- p->bDiscontinuity, p->bSyncPoint, fTimeValid && p->rtStart < 0,
- nBytes, p->rtStart, p->rtStop);
+ TRACE(_T("[%d]: d%d s%d p%d, b=%d, [%20I64d - %20I64d]\n"),
+ p->TrackNumber,
+ p->bDiscontinuity, p->bSyncPoint, fTimeValid && p->rtStart < 0,
+ nBytes, p->rtStart, p->rtStop);
#endif
- ASSERT(!p->bSyncPoint || fTimeValid);
-
- BYTE* pData = NULL;
- if (S_OK != (hr = pSample->GetPointer(&pData)) || !pData) {
- break;
- }
- memcpy(pData, p->GetData(), nBytes);
- if (S_OK != (hr = pSample->SetActualDataLength(nBytes))) {
- break;
- }
- if (S_OK != (hr = pSample->SetTime(fTimeValid ? &p->rtStart : NULL, fTimeValid ? &p->rtStop : NULL))) {
- break;
- }
- if (S_OK != (hr = pSample->SetMediaTime(NULL, NULL))) {
- break;
- }
- if (S_OK != (hr = pSample->SetDiscontinuity(p->bDiscontinuity))) {
- break;
- }
- if (S_OK != (hr = pSample->SetSyncPoint(p->bSyncPoint))) {
- break;
- }
- if (S_OK != (hr = pSample->SetPreroll(fTimeValid && p->rtStart < 0))) {
- break;
- }
- if (S_OK != (hr = Deliver(pSample))) {
- break;
- }
- } while (false);
-
- return hr;
+ ASSERT(!p->bSyncPoint || fTimeValid);
+
+ BYTE* pData = NULL;
+ if (S_OK != (hr = pSample->GetPointer(&pData)) || !pData) {
+ break;
+ }
+ memcpy(pData, p->GetData(), nBytes);
+ if (S_OK != (hr = pSample->SetActualDataLength(nBytes))) {
+ break;
+ }
+ if (S_OK != (hr = pSample->SetTime(fTimeValid ? &p->rtStart : NULL, fTimeValid ? &p->rtStop : NULL))) {
+ break;
+ }
+ if (S_OK != (hr = pSample->SetMediaTime(NULL, NULL))) {
+ break;
+ }
+ if (S_OK != (hr = pSample->SetDiscontinuity(p->bDiscontinuity))) {
+ break;
+ }
+ if (S_OK != (hr = pSample->SetSyncPoint(p->bSyncPoint))) {
+ break;
+ }
+ if (S_OK != (hr = pSample->SetPreroll(fTimeValid && p->rtStart < 0))) {
+ break;
+ }
+ if (S_OK != (hr = Deliver(pSample))) {
+ break;
+ }
+ } while (false);
+
+ return hr;
}
void CBaseSplitterOutputPin::MakeISCRHappy()
{
- CComPtr<IPin> pPinTo = this, pTmp;
- while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) {
- pTmp = NULL;
+ CComPtr<IPin> pPinTo = this, pTmp;
+ while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) {
+ pTmp = NULL;
- CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo);
+ CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo);
- if (GetCLSID(pBF) == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) { // ISCR
- CAutoPtr<Packet> p(DNew Packet());
- p->TrackNumber = (DWORD)-1;
- p->rtStart = -1;
- p->rtStop = 0;
- p->bSyncPoint = FALSE;
- p->SetData(" ", 2);
- QueuePacket(p);
- break;
- }
+ if (GetCLSID(pBF) == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) { // ISCR
+ CAutoPtr<Packet> p(DNew Packet());
+ p->TrackNumber = (DWORD) - 1;
+ p->rtStart = -1;
+ p->rtStop = 0;
+ p->bSyncPoint = FALSE;
+ p->SetData(" ", 2);
+ QueuePacket(p);
+ break;
+ }
- pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT);
- }
+ pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT);
+ }
}
HRESULT CBaseSplitterOutputPin::GetDeliveryBuffer(IMediaSample** ppSample, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags)
{
- return __super::GetDeliveryBuffer(ppSample, pStartTime, pEndTime, dwFlags);
+ return __super::GetDeliveryBuffer(ppSample, pStartTime, pEndTime, dwFlags);
}
HRESULT CBaseSplitterOutputPin::Deliver(IMediaSample* pSample)
{
- return __super::Deliver(pSample);
+ return __super::Deliver(pSample);
}
// IMediaSeeking
STDMETHODIMP CBaseSplitterOutputPin::GetCapabilities(DWORD* pCapabilities)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetCapabilities(pCapabilities);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetCapabilities(pCapabilities);
}
STDMETHODIMP CBaseSplitterOutputPin::CheckCapabilities(DWORD* pCapabilities)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->CheckCapabilities(pCapabilities);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->CheckCapabilities(pCapabilities);
}
STDMETHODIMP CBaseSplitterOutputPin::IsFormatSupported(const GUID* pFormat)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->IsFormatSupported(pFormat);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->IsFormatSupported(pFormat);
}
STDMETHODIMP CBaseSplitterOutputPin::QueryPreferredFormat(GUID* pFormat)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->QueryPreferredFormat(pFormat);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->QueryPreferredFormat(pFormat);
}
STDMETHODIMP CBaseSplitterOutputPin::GetTimeFormat(GUID* pFormat)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetTimeFormat(pFormat);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetTimeFormat(pFormat);
}
STDMETHODIMP CBaseSplitterOutputPin::IsUsingTimeFormat(const GUID* pFormat)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->IsUsingTimeFormat(pFormat);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->IsUsingTimeFormat(pFormat);
}
STDMETHODIMP CBaseSplitterOutputPin::SetTimeFormat(const GUID* pFormat)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->SetTimeFormat(pFormat);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->SetTimeFormat(pFormat);
}
STDMETHODIMP CBaseSplitterOutputPin::GetDuration(LONGLONG* pDuration)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetDuration(pDuration);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetDuration(pDuration);
}
STDMETHODIMP CBaseSplitterOutputPin::GetStopPosition(LONGLONG* pStop)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetStopPosition(pStop);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetStopPosition(pStop);
}
STDMETHODIMP CBaseSplitterOutputPin::GetCurrentPosition(LONGLONG* pCurrent)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetCurrentPosition(pCurrent);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetCurrentPosition(pCurrent);
}
STDMETHODIMP CBaseSplitterOutputPin::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
}
STDMETHODIMP CBaseSplitterOutputPin::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->SetPositionsInternal(this, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->SetPositionsInternal(this, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
}
STDMETHODIMP CBaseSplitterOutputPin::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetPositions(pCurrent, pStop);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetPositions(pCurrent, pStop);
}
STDMETHODIMP CBaseSplitterOutputPin::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetAvailable(pEarliest, pLatest);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetAvailable(pEarliest, pLatest);
}
STDMETHODIMP CBaseSplitterOutputPin::SetRate(double dRate)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->SetRate(dRate);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->SetRate(dRate);
}
STDMETHODIMP CBaseSplitterOutputPin::GetRate(double* pdRate)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetRate(pdRate);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetRate(pdRate);
}
STDMETHODIMP CBaseSplitterOutputPin::GetPreroll(LONGLONG* pllPreroll)
{
- return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetPreroll(pllPreroll);
+ return (static_cast<CBaseSplitterFilter*>(m_pFilter))->GetPreroll(pllPreroll);
}
//
@@ -773,845 +773,842 @@ STDMETHODIMP CBaseSplitterOutputPin::GetPreroll(LONGLONG* pllPreroll)
//
CBaseSplitterFilter::CBaseSplitterFilter(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid, int QueueMaxPackets)
- : CBaseFilter(pName, pUnk, this, clsid)
- , m_rtDuration(0), m_rtStart(0), m_rtStop(0), m_rtCurrent(0)
- , m_dRate(1.0)
- , m_nOpenProgress(100)
- , m_fAbort(false)
- , m_rtLastStart(_I64_MIN)
- , m_rtLastStop(_I64_MIN)
- , m_priority(THREAD_PRIORITY_NORMAL)
- , m_QueueMaxPackets(QueueMaxPackets)
+ : CBaseFilter(pName, pUnk, this, clsid)
+ , m_rtDuration(0), m_rtStart(0), m_rtStop(0), m_rtCurrent(0)
+ , m_dRate(1.0)
+ , m_nOpenProgress(100)
+ , m_fAbort(false)
+ , m_rtLastStart(_I64_MIN)
+ , m_rtLastStop(_I64_MIN)
+ , m_priority(THREAD_PRIORITY_NORMAL)
+ , m_QueueMaxPackets(QueueMaxPackets)
{
- if (phr) {
- *phr = S_OK;
- }
+ if (phr) {
+ *phr = S_OK;
+ }
- m_pInput.Attach(DNew CBaseSplitterInputPin(NAME("CBaseSplitterInputPin"), this, this, phr));
+ m_pInput.Attach(DNew CBaseSplitterInputPin(NAME("CBaseSplitterInputPin"), this, this, phr));
}
CBaseSplitterFilter::~CBaseSplitterFilter()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- CAMThread::CallWorker(CMD_EXIT);
- CAMThread::Close();
+ CAMThread::CallWorker(CMD_EXIT);
+ CAMThread::Close();
}
STDMETHODIMP CBaseSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- CheckPointer(ppv, E_POINTER);
+ CheckPointer(ppv, E_POINTER);
- *ppv = NULL;
+ *ppv = NULL;
- if (m_pInput && riid == __uuidof(IFileSourceFilter)) {
- return E_NOINTERFACE;
- }
+ if (m_pInput && riid == __uuidof(IFileSourceFilter)) {
+ return E_NOINTERFACE;
+ }
- return
- QI(IFileSourceFilter)
- QI(IMediaSeeking)
- QI(IAMOpenProgress)
- QI2(IAMMediaContent)
- QI2(IAMExtendedSeeking)
- QI(IKeyFrameInfo)
- QI(IBufferInfo)
- QI(IPropertyBag)
- QI(IPropertyBag2)
- QI(IDSMPropertyBag)
- QI(IDSMResourceBag)
- QI(IDSMChapterBag)
- __super::NonDelegatingQueryInterface(riid, ppv);
+ return
+ QI(IFileSourceFilter)
+ QI(IMediaSeeking)
+ QI(IAMOpenProgress)
+ QI2(IAMMediaContent)
+ QI2(IAMExtendedSeeking)
+ QI(IKeyFrameInfo)
+ QI(IBufferInfo)
+ QI(IPropertyBag)
+ QI(IPropertyBag2)
+ QI(IDSMPropertyBag)
+ QI(IDSMResourceBag)
+ QI(IDSMChapterBag)
+ __super::NonDelegatingQueryInterface(riid, ppv);
}
CBaseSplitterOutputPin* CBaseSplitterFilter::GetOutputPin(DWORD TrackNum)
{
- CAutoLock cAutoLock(&m_csPinMap);
+ CAutoLock cAutoLock(&m_csPinMap);
- CBaseSplitterOutputPin* pPin = NULL;
- m_pPinMap.Lookup(TrackNum, pPin);
- return pPin;
+ CBaseSplitterOutputPin* pPin = NULL;
+ m_pPinMap.Lookup(TrackNum, pPin);
+ return pPin;
}
DWORD CBaseSplitterFilter::GetOutputTrackNum(CBaseSplitterOutputPin* pPin)
{
- CAutoLock cAutoLock(&m_csPinMap);
+ CAutoLock cAutoLock(&m_csPinMap);
- POSITION pos = m_pPinMap.GetStartPosition();
- while (pos) {
- DWORD TrackNum;
- CBaseSplitterOutputPin* pPinTmp;
- m_pPinMap.GetNextAssoc(pos, TrackNum, pPinTmp);
- if (pPinTmp == pPin) {
- return TrackNum;
- }
- }
+ POSITION pos = m_pPinMap.GetStartPosition();
+ while (pos) {
+ DWORD TrackNum;
+ CBaseSplitterOutputPin* pPinTmp;
+ m_pPinMap.GetNextAssoc(pos, TrackNum, pPinTmp);
+ if (pPinTmp == pPin) {
+ return TrackNum;
+ }
+ }
- return (DWORD)-1;
+ return (DWORD) - 1;
}
HRESULT CBaseSplitterFilter::RenameOutputPin(DWORD TrackNumSrc, DWORD TrackNumDst, const AM_MEDIA_TYPE* pmt)
{
- CAutoLock cAutoLock(&m_csPinMap);
+ CAutoLock cAutoLock(&m_csPinMap);
- CBaseSplitterOutputPin* pPin;
- if (m_pPinMap.Lookup(TrackNumSrc, pPin)) {
- if (CComQIPtr<IPin> pPinTo = pPin->GetConnected()) {
- if (pmt && S_OK != pPinTo->QueryAccept(pmt)) {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- }
+ CBaseSplitterOutputPin* pPin;
+ if (m_pPinMap.Lookup(TrackNumSrc, pPin)) {
+ if (CComQIPtr<IPin> pPinTo = pPin->GetConnected()) {
+ if (pmt && S_OK != pPinTo->QueryAccept(pmt)) {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+ }
- m_pPinMap.RemoveKey(TrackNumSrc);
- m_pPinMap[TrackNumDst] = pPin;
+ m_pPinMap.RemoveKey(TrackNumSrc);
+ m_pPinMap[TrackNumDst] = pPin;
- if (pmt) {
- CAutoLock cAutoLock(&m_csmtnew);
- m_mtnew[TrackNumDst] = *pmt;
- }
+ if (pmt) {
+ CAutoLock cAutoLock(&m_csmtnew);
+ m_mtnew[TrackNumDst] = *pmt;
+ }
- return S_OK;
- }
+ return S_OK;
+ }
- return E_FAIL;
+ return E_FAIL;
}
HRESULT CBaseSplitterFilter::AddOutputPin(DWORD TrackNum, CAutoPtr<CBaseSplitterOutputPin> pPin)
{
- CAutoLock cAutoLock(&m_csPinMap);
+ CAutoLock cAutoLock(&m_csPinMap);
- if (!pPin) {
- return E_INVALIDARG;
- }
- m_pPinMap[TrackNum] = pPin;
- m_pOutputs.AddTail(pPin);
- return S_OK;
+ if (!pPin) {
+ return E_INVALIDARG;
+ }
+ m_pPinMap[TrackNum] = pPin;
+ m_pOutputs.AddTail(pPin);
+ return S_OK;
}
HRESULT CBaseSplitterFilter::DeleteOutputs()
{
- m_rtDuration = 0;
+ m_rtDuration = 0;
- m_pRetiredOutputs.RemoveAll();
+ m_pRetiredOutputs.RemoveAll();
- CAutoLock cAutoLockF(this);
- if (m_State != State_Stopped) {
- return VFW_E_NOT_STOPPED;
- }
+ CAutoLock cAutoLockF(this);
+ if (m_State != State_Stopped) {
+ return VFW_E_NOT_STOPPED;
+ }
- while (m_pOutputs.GetCount()) {
- CAutoPtr<CBaseSplitterOutputPin> pPin = m_pOutputs.RemoveHead();
- if (IPin* pPinTo = pPin->GetConnected()) {
- pPinTo->Disconnect();
- }
- pPin->Disconnect();
- // we can't just let it be deleted now, something might have AddRefed on it (graphedit...)
- m_pRetiredOutputs.AddTail(pPin);
- }
+ while (m_pOutputs.GetCount()) {
+ CAutoPtr<CBaseSplitterOutputPin> pPin = m_pOutputs.RemoveHead();
+ if (IPin* pPinTo = pPin->GetConnected()) {
+ pPinTo->Disconnect();
+ }
+ pPin->Disconnect();
+ // we can't just let it be deleted now, something might have AddRefed on it (graphedit...)
+ m_pRetiredOutputs.AddTail(pPin);
+ }
- CAutoLock cAutoLockPM(&m_csPinMap);
- m_pPinMap.RemoveAll();
+ CAutoLock cAutoLockPM(&m_csPinMap);
+ m_pPinMap.RemoveAll();
- CAutoLock cAutoLockMT(&m_csmtnew);
- m_mtnew.RemoveAll();
+ CAutoLock cAutoLockMT(&m_csmtnew);
+ m_mtnew.RemoveAll();
- RemoveAll();
- ResRemoveAll();
- ChapRemoveAll();
+ RemoveAll();
+ ResRemoveAll();
+ ChapRemoveAll();
- m_fontinst.UninstallFonts();
+ m_fontinst.UninstallFonts();
- m_pSyncReader.Release();
+ m_pSyncReader.Release();
- return S_OK;
+ return S_OK;
}
void CBaseSplitterFilter::DeliverBeginFlush()
{
- m_fFlushing = true;
- POSITION pos = m_pOutputs.GetHeadPosition();
- while (pos) {
- m_pOutputs.GetNext(pos)->DeliverBeginFlush();
- }
+ m_fFlushing = true;
+ POSITION pos = m_pOutputs.GetHeadPosition();
+ while (pos) {
+ m_pOutputs.GetNext(pos)->DeliverBeginFlush();
+ }
}
void CBaseSplitterFilter::DeliverEndFlush()
{
- POSITION pos = m_pOutputs.GetHeadPosition();
- while (pos) {
- m_pOutputs.GetNext(pos)->DeliverEndFlush();
- }
- m_fFlushing = false;
- m_eEndFlush.Set();
+ POSITION pos = m_pOutputs.GetHeadPosition();
+ while (pos) {
+ m_pOutputs.GetNext(pos)->DeliverEndFlush();
+ }
+ m_fFlushing = false;
+ m_eEndFlush.Set();
}
DWORD CBaseSplitterFilter::ThreadProc()
{
- if (m_pSyncReader) {
- m_pSyncReader->SetBreakEvent(GetRequestHandle());
- }
+ if (m_pSyncReader) {
+ m_pSyncReader->SetBreakEvent(GetRequestHandle());
+ }
- if (!DemuxInit()) {
- for (;;) {
- DWORD cmd = GetRequest();
- if (cmd == CMD_EXIT) {
- CAMThread::m_hThread = NULL;
- }
- Reply(S_OK);
- if (cmd == CMD_EXIT) {
- return 0;
- }
- }
- }
+ if (!DemuxInit()) {
+ for (;;) {
+ DWORD cmd = GetRequest();
+ if (cmd == CMD_EXIT) {
+ CAMThread::m_hThread = NULL;
+ }
+ Reply(S_OK);
+ if (cmd == CMD_EXIT) {
+ return 0;
+ }
+ }
+ }
- m_eEndFlush.Set();
- m_fFlushing = false;
+ m_eEndFlush.Set();
+ m_fFlushing = false;
- for (DWORD cmd = (DWORD)-1; ; cmd = GetRequest()) {
- if (cmd == CMD_EXIT) {
- m_hThread = NULL;
- Reply(S_OK);
- return 0;
- }
+ for (DWORD cmd = (DWORD) - 1; ; cmd = GetRequest()) {
+ if (cmd == CMD_EXIT) {
+ m_hThread = NULL;
+ Reply(S_OK);
+ return 0;
+ }
- SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_NORMAL);
+ SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_NORMAL);
- m_rtStart = m_rtNewStart;
- m_rtStop = m_rtNewStop;
+ m_rtStart = m_rtNewStart;
+ m_rtStop = m_rtNewStop;
- DemuxSeek(m_rtStart);
+ DemuxSeek(m_rtStart);
- if (cmd != (DWORD)-1) {
- Reply(S_OK);
- }
+ if (cmd != (DWORD) - 1) {
+ Reply(S_OK);
+ }
- m_eEndFlush.Wait();
+ m_eEndFlush.Wait();
- m_pActivePins.RemoveAll();
+ m_pActivePins.RemoveAll();
- POSITION pos = m_pOutputs.GetHeadPosition();
- while (pos && !m_fFlushing) {
- CBaseSplitterOutputPin* pPin = m_pOutputs.GetNext(pos);
- if (pPin->IsConnected() && pPin->IsActive()) {
- m_pActivePins.AddTail(pPin);
- pPin->DeliverNewSegment(m_rtStart, m_rtStop, m_dRate);
- }
- }
+ POSITION pos = m_pOutputs.GetHeadPosition();
+ while (pos && !m_fFlushing) {
+ CBaseSplitterOutputPin* pPin = m_pOutputs.GetNext(pos);
+ if (pPin->IsConnected() && pPin->IsActive()) {
+ m_pActivePins.AddTail(pPin);
+ pPin->DeliverNewSegment(m_rtStart, m_rtStop, m_dRate);
+ }
+ }
- do {
- m_bDiscontinuitySent.RemoveAll();
- } while (!DemuxLoop());
+ do {
+ m_bDiscontinuitySent.RemoveAll();
+ } while (!DemuxLoop());
- pos = m_pActivePins.GetHeadPosition();
- while (pos && !CheckRequest(&cmd)) {
- m_pActivePins.GetNext(pos)->QueueEndOfStream();
- }
- }
+ pos = m_pActivePins.GetHeadPosition();
+ while (pos && !CheckRequest(&cmd)) {
+ m_pActivePins.GetNext(pos)->QueueEndOfStream();
+ }
+ }
- ASSERT(0); // we should only exit via CMD_EXIT
+ ASSERT(0); // we should only exit via CMD_EXIT
- m_hThread = NULL;
- return 0;
+ m_hThread = NULL;
+ return 0;
}
HRESULT CBaseSplitterFilter::DeliverPacket(CAutoPtr<Packet> p)
{
- HRESULT hr = S_FALSE;
+ HRESULT hr = S_FALSE;
- CBaseSplitterOutputPin* pPin = GetOutputPin(p->TrackNumber);
- if (!pPin || !pPin->IsConnected() || !m_pActivePins.Find(pPin)) {
- return S_FALSE;
- }
+ CBaseSplitterOutputPin* pPin = GetOutputPin(p->TrackNumber);
+ if (!pPin || !pPin->IsConnected() || !m_pActivePins.Find(pPin)) {
+ return S_FALSE;
+ }
- if (p->rtStart != Packet::INVALID_TIME) {
- m_rtCurrent = p->rtStart;
+ if (p->rtStart != Packet::INVALID_TIME) {
+ m_rtCurrent = p->rtStart;
- p->rtStart -= m_rtStart;
- p->rtStop -= m_rtStart;
+ p->rtStart -= m_rtStart;
+ p->rtStop -= m_rtStart;
- ASSERT(p->rtStart <= p->rtStop);
- }
+ ASSERT(p->rtStart <= p->rtStop);
+ }
- {
- CAutoLock cAutoLock(&m_csmtnew);
+ {
+ CAutoLock cAutoLock(&m_csmtnew);
- CMediaType mt;
- if (m_mtnew.Lookup(p->TrackNumber, mt)) {
- p->pmt = CreateMediaType(&mt);
- m_mtnew.RemoveKey(p->TrackNumber);
- }
- }
+ CMediaType mt;
+ if (m_mtnew.Lookup(p->TrackNumber, mt)) {
+ p->pmt = CreateMediaType(&mt);
+ m_mtnew.RemoveKey(p->TrackNumber);
+ }
+ }
- if (!m_bDiscontinuitySent.Find(p->TrackNumber)) {
- p->bDiscontinuity = TRUE;
- }
+ if (!m_bDiscontinuitySent.Find(p->TrackNumber)) {
+ p->bDiscontinuity = TRUE;
+ }
- DWORD TrackNumber = p->TrackNumber;
- BOOL bDiscontinuity = p->bDiscontinuity;
+ DWORD TrackNumber = p->TrackNumber;
+ BOOL bDiscontinuity = p->bDiscontinuity;
#if defined(_DEBUG) && 0
- TRACE(_T("[%d]: d%d s%d p%d, b=%d, [%20I64d - %20I64d]\n"),
- p->TrackNumber,
- p->bDiscontinuity, p->bSyncPoint, p->rtStart != Packet::INVALID_TIME && p->rtStart < 0,
- p->GetCount(), p->rtStart, p->rtStop);
+ TRACE(_T("[%d]: d%d s%d p%d, b=%d, [%20I64d - %20I64d]\n"),
+ p->TrackNumber,
+ p->bDiscontinuity, p->bSyncPoint, p->rtStart != Packet::INVALID_TIME && p->rtStart < 0,
+ p->GetCount(), p->rtStart, p->rtStop);
#endif
- hr = pPin->QueuePacket(p);
+ hr = pPin->QueuePacket(p);
- if (S_OK != hr) {
- if (POSITION pos = m_pActivePins.Find(pPin)) {
- m_pActivePins.RemoveAt(pos);
- }
+ if (S_OK != hr) {
+ if (POSITION pos = m_pActivePins.Find(pPin)) {
+ m_pActivePins.RemoveAt(pos);
+ }
- if (!m_pActivePins.IsEmpty()) { // only die when all pins are down
- hr = S_OK;
- }
+ if (!m_pActivePins.IsEmpty()) { // only die when all pins are down
+ hr = S_OK;
+ }
- return hr;
- }
+ return hr;
+ }
- if (bDiscontinuity) {
- m_bDiscontinuitySent.AddTail(TrackNumber);
- }
+ if (bDiscontinuity) {
+ m_bDiscontinuitySent.AddTail(TrackNumber);
+ }
- return hr;
+ return hr;
}
bool CBaseSplitterFilter::IsAnyPinDrying()
{
- int totalcount = 0, totalsize = 0;
-
- POSITION pos = m_pActivePins.GetHeadPosition();
- while (pos) {
- CBaseSplitterOutputPin* pPin = m_pActivePins.GetNext(pos);
- int count = pPin->QueueCount();
- int size = pPin->QueueSize();
- if (!pPin->IsDiscontinuous() && (count < MINPACKETS || size < MINPACKETSIZE)) {
- // if (m_priority != THREAD_PRIORITY_ABOVE_NORMAL && (count < MINPACKETS/3 || size < MINPACKETSIZE/3))
- if (m_priority != THREAD_PRIORITY_BELOW_NORMAL && (count < MINPACKETS/3 || size < MINPACKETSIZE/3)) {
- // SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_ABOVE_NORMAL);
- POSITION pos = m_pOutputs.GetHeadPosition();
- while (pos) {
- m_pOutputs.GetNext(pos)->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
- }
- m_priority = THREAD_PRIORITY_BELOW_NORMAL;
- }
- return true;
- }
- totalcount += count;
- totalsize += size;
- }
-
- if (m_priority != THREAD_PRIORITY_NORMAL && (totalcount > m_QueueMaxPackets*2/3 || totalsize > MAXPACKETSIZE*2/3)) {
- // SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_NORMAL);
- POSITION pos = m_pOutputs.GetHeadPosition();
- while (pos) {
- m_pOutputs.GetNext(pos)->SetThreadPriority(THREAD_PRIORITY_NORMAL);
- }
- m_priority = THREAD_PRIORITY_NORMAL;
- }
-
- if (totalcount < MAXPACKETS && totalsize < MAXPACKETSIZE) {
- return true;
- }
-
- return false;
+ int totalcount = 0, totalsize = 0;
+
+ POSITION pos = m_pActivePins.GetHeadPosition();
+ while (pos) {
+ CBaseSplitterOutputPin* pPin = m_pActivePins.GetNext(pos);
+ int count = pPin->QueueCount();
+ int size = pPin->QueueSize();
+ if (!pPin->IsDiscontinuous() && (count < MINPACKETS || size < MINPACKETSIZE)) {
+ // if (m_priority != THREAD_PRIORITY_ABOVE_NORMAL && (count < MINPACKETS/3 || size < MINPACKETSIZE/3))
+ if (m_priority != THREAD_PRIORITY_BELOW_NORMAL && (count < MINPACKETS / 3 || size < MINPACKETSIZE / 3)) {
+ // SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_ABOVE_NORMAL);
+ POSITION pos = m_pOutputs.GetHeadPosition();
+ while (pos) {
+ m_pOutputs.GetNext(pos)->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
+ }
+ m_priority = THREAD_PRIORITY_BELOW_NORMAL;
+ }
+ return true;
+ }
+ totalcount += count;
+ totalsize += size;
+ }
+
+ if (m_priority != THREAD_PRIORITY_NORMAL && (totalcount > m_QueueMaxPackets * 2 / 3 || totalsize > MAXPACKETSIZE * 2 / 3)) {
+ // SetThreadPriority(m_hThread, m_priority = THREAD_PRIORITY_NORMAL);
+ POSITION pos = m_pOutputs.GetHeadPosition();
+ while (pos) {
+ m_pOutputs.GetNext(pos)->SetThreadPriority(THREAD_PRIORITY_NORMAL);
+ }
+ m_priority = THREAD_PRIORITY_NORMAL;
+ }
+
+ if (totalcount < MAXPACKETS && totalsize < MAXPACKETSIZE) {
+ return true;
+ }
+
+ return false;
}
HRESULT CBaseSplitterFilter::BreakConnect(PIN_DIRECTION dir, CBasePin* pPin)
{
- CheckPointer(pPin, E_POINTER);
+ CheckPointer(pPin, E_POINTER);
- if (dir == PINDIR_INPUT) {
- DeleteOutputs();
- } else if (dir == PINDIR_OUTPUT) {
- } else {
- return E_UNEXPECTED;
- }
+ if (dir == PINDIR_INPUT) {
+ DeleteOutputs();
+ } else if (dir == PINDIR_OUTPUT) {
+ } else {
+ return E_UNEXPECTED;
+ }
- return S_OK;
+ return S_OK;
}
HRESULT CBaseSplitterFilter::CompleteConnect(PIN_DIRECTION dir, CBasePin* pPin)
{
- CheckPointer(pPin, E_POINTER);
+ CheckPointer(pPin, E_POINTER);
- if (dir == PINDIR_INPUT) {
- CBaseSplitterInputPin* pIn = static_cast<CBaseSplitterInputPin*>(pPin);
+ if (dir == PINDIR_INPUT) {
+ CBaseSplitterInputPin* pIn = static_cast<CBaseSplitterInputPin*>(pPin);
- HRESULT hr;
+ HRESULT hr;
- CComPtr<IAsyncReader> pAsyncReader;
- if (FAILED(hr = pIn->GetAsyncReader(&pAsyncReader))
- || FAILED(hr = DeleteOutputs())
- || FAILED(hr = CreateOutputs(pAsyncReader))) {
- return hr;
- }
+ CComPtr<IAsyncReader> pAsyncReader;
+ if (FAILED(hr = pIn->GetAsyncReader(&pAsyncReader))
+ || FAILED(hr = DeleteOutputs())
+ || FAILED(hr = CreateOutputs(pAsyncReader))) {
+ return hr;
+ }
- ChapSort();
+ ChapSort();
- m_pSyncReader = pAsyncReader;
- } else if (dir == PINDIR_OUTPUT) {
- m_pRetiredOutputs.RemoveAll();
- } else {
- return E_UNEXPECTED;
- }
+ m_pSyncReader = pAsyncReader;
+ } else if (dir == PINDIR_OUTPUT) {
+ m_pRetiredOutputs.RemoveAll();
+ } else {
+ return E_UNEXPECTED;
+ }
- return S_OK;
+ return S_OK;
}
int CBaseSplitterFilter::GetPinCount()
{
- return (m_pInput ? 1 : 0) + (int)m_pOutputs.GetCount();
+ return (m_pInput ? 1 : 0) + (int)m_pOutputs.GetCount();
}
CBasePin* CBaseSplitterFilter::GetPin(int n)
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- if (n >= 0 && n < (int)m_pOutputs.GetCount()) {
- if (POSITION pos = m_pOutputs.FindIndex(n)) {
- return m_pOutputs.GetAt(pos);
- }
- }
+ if (n >= 0 && n < (int)m_pOutputs.GetCount()) {
+ if (POSITION pos = m_pOutputs.FindIndex(n)) {
+ return m_pOutputs.GetAt(pos);
+ }
+ }
- if (n == (int)m_pOutputs.GetCount() && m_pInput) {
- return m_pInput;
- }
+ if (n == (int)m_pOutputs.GetCount() && m_pInput) {
+ return m_pInput;
+ }
- return NULL;
+ return NULL;
}
STDMETHODIMP CBaseSplitterFilter::Stop()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- DeliverBeginFlush();
- CallWorker(CMD_EXIT);
- DeliverEndFlush();
+ DeliverBeginFlush();
+ CallWorker(CMD_EXIT);
+ DeliverEndFlush();
- HRESULT hr;
- if (FAILED(hr = __super::Stop())) {
- return hr;
- }
+ HRESULT hr;
+ if (FAILED(hr = __super::Stop())) {
+ return hr;
+ }
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::Pause()
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- FILTER_STATE fs = m_State;
+ FILTER_STATE fs = m_State;
- HRESULT hr;
- if (FAILED(hr = __super::Pause())) {
- return hr;
- }
+ HRESULT hr;
+ if (FAILED(hr = __super::Pause())) {
+ return hr;
+ }
- if (fs == State_Stopped) {
- Create();
- }
+ if (fs == State_Stopped) {
+ Create();
+ }
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::Run(REFERENCE_TIME tStart)
{
- CAutoLock cAutoLock(this);
+ CAutoLock cAutoLock(this);
- HRESULT hr;
- if (FAILED(hr = __super::Run(tStart))) {
- return hr;
- }
+ HRESULT hr;
+ if (FAILED(hr = __super::Run(tStart))) {
+ return hr;
+ }
- return S_OK;
+ return S_OK;
}
// IFileSourceFilter
STDMETHODIMP CBaseSplitterFilter::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt)
{
- CheckPointer(pszFileName, E_POINTER);
-
- m_fn = pszFileName;
- HRESULT hr = E_FAIL;
- CComPtr<IAsyncReader> pAsyncReader;
- CAtlList<CHdmvClipInfo::PlaylistItem> Items;
- CAtlList<CHdmvClipInfo::PlaylistChapter> Chapters;
-
- if (BuildPlaylist (pszFileName, Items))
- pAsyncReader = (IAsyncReader*)DNew CAsyncFileReader(Items, hr);
- else
- pAsyncReader = (IAsyncReader*)DNew CAsyncFileReader(CString(pszFileName), hr);
-
- if (FAILED(hr)
- || FAILED(hr = DeleteOutputs())
- || FAILED(hr = CreateOutputs(pAsyncReader)))
- {
- m_fn = "";
- return hr;
- }
-
- if (BuildChapters (pszFileName, Items, Chapters))
- {
- POSITION pos = Chapters.GetHeadPosition();
- int i = 1;
- while (pos)
- {
- CString str;
- CHdmvClipInfo::PlaylistChapter& chap = Chapters.GetNext(pos);
- if (chap.m_nMarkType == CHdmvClipInfo::EntryMark)
- {
- str.Format (_T("Chapter %d"), i);
- ChapAppend (chap.m_rtTimestamp, str);
- i++;
- }
- }
- }
-
- ChapSort();
-
- m_pSyncReader = pAsyncReader;
-
- return S_OK;
+ CheckPointer(pszFileName, E_POINTER);
+
+ m_fn = pszFileName;
+ HRESULT hr = E_FAIL;
+ CComPtr<IAsyncReader> pAsyncReader;
+ CAtlList<CHdmvClipInfo::PlaylistItem> Items;
+ CAtlList<CHdmvClipInfo::PlaylistChapter> Chapters;
+
+ if (BuildPlaylist(pszFileName, Items)) {
+ pAsyncReader = (IAsyncReader*)DNew CAsyncFileReader(Items, hr);
+ } else {
+ pAsyncReader = (IAsyncReader*)DNew CAsyncFileReader(CString(pszFileName), hr);
+ }
+
+ if (FAILED(hr)
+ || FAILED(hr = DeleteOutputs())
+ || FAILED(hr = CreateOutputs(pAsyncReader))) {
+ m_fn = "";
+ return hr;
+ }
+
+ if (BuildChapters(pszFileName, Items, Chapters)) {
+ POSITION pos = Chapters.GetHeadPosition();
+ int i = 1;
+ while (pos) {
+ CString str;
+ CHdmvClipInfo::PlaylistChapter& chap = Chapters.GetNext(pos);
+ if (chap.m_nMarkType == CHdmvClipInfo::EntryMark) {
+ str.Format(_T("Chapter %d"), i);
+ ChapAppend(chap.m_rtTimestamp, str);
+ i++;
+ }
+ }
+ }
+
+ ChapSort();
+
+ m_pSyncReader = pAsyncReader;
+
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt)
{
- CheckPointer(ppszFileName, E_POINTER);
- *ppszFileName = (LPOLESTR)CoTaskMemAlloc((m_fn.GetLength()+1)*sizeof(WCHAR));
- if (!(*ppszFileName)) {
- return E_OUTOFMEMORY;
- }
- wcscpy_s(*ppszFileName, m_fn.GetLength() + 1, m_fn);
- return S_OK;
+ CheckPointer(ppszFileName, E_POINTER);
+ *ppszFileName = (LPOLESTR)CoTaskMemAlloc((m_fn.GetLength() + 1) * sizeof(WCHAR));
+ if (!(*ppszFileName)) {
+ return E_OUTOFMEMORY;
+ }
+ wcscpy_s(*ppszFileName, m_fn.GetLength() + 1, m_fn);
+ return S_OK;
}
LPCTSTR CBaseSplitterFilter::GetPartFilename(IAsyncReader* pAsyncReader)
{
- CComQIPtr<IFileHandle> pFH = pAsyncReader;
- return pFH ? pFH->GetFileName() : m_fn;
+ CComQIPtr<IFileHandle> pFH = pAsyncReader;
+ return pFH ? pFH->GetFileName() : m_fn;
}
// IMediaSeeking
STDMETHODIMP CBaseSplitterFilter::GetCapabilities(DWORD* pCapabilities)
{
- return pCapabilities ? *pCapabilities =
- AM_SEEKING_CanGetStopPos|
- AM_SEEKING_CanGetDuration|
- AM_SEEKING_CanSeekAbsolute|
- AM_SEEKING_CanSeekForwards|
- AM_SEEKING_CanSeekBackwards, S_OK : E_POINTER;
+ return pCapabilities ? *pCapabilities =
+ AM_SEEKING_CanGetStopPos |
+ AM_SEEKING_CanGetDuration |
+ AM_SEEKING_CanSeekAbsolute |
+ AM_SEEKING_CanSeekForwards |
+ AM_SEEKING_CanSeekBackwards, S_OK : E_POINTER;
}
STDMETHODIMP CBaseSplitterFilter::CheckCapabilities(DWORD* pCapabilities)
{
- CheckPointer(pCapabilities, E_POINTER);
- if (*pCapabilities == 0) {
- return S_OK;
- }
- DWORD caps;
- GetCapabilities(&caps);
- if ((caps&*pCapabilities) == 0) {
- return E_FAIL;
- }
- if (caps == *pCapabilities) {
- return S_OK;
- }
- return S_FALSE;
+ CheckPointer(pCapabilities, E_POINTER);
+ if (*pCapabilities == 0) {
+ return S_OK;
+ }
+ DWORD caps;
+ GetCapabilities(&caps);
+ if ((caps&*pCapabilities) == 0) {
+ return E_FAIL;
+ }
+ if (caps == *pCapabilities) {
+ return S_OK;
+ }
+ return S_FALSE;
}
STDMETHODIMP CBaseSplitterFilter::IsFormatSupported(const GUID* pFormat)
{
- return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
+ return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
}
STDMETHODIMP CBaseSplitterFilter::QueryPreferredFormat(GUID* pFormat)
{
- return GetTimeFormat(pFormat);
+ return GetTimeFormat(pFormat);
}
STDMETHODIMP CBaseSplitterFilter::GetTimeFormat(GUID* pFormat)
{
- return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;
+ return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;
}
STDMETHODIMP CBaseSplitterFilter::IsUsingTimeFormat(const GUID* pFormat)
{
- return IsFormatSupported(pFormat);
+ return IsFormatSupported(pFormat);
}
STDMETHODIMP CBaseSplitterFilter::SetTimeFormat(const GUID* pFormat)
{
- return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;
+ return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;
}
STDMETHODIMP CBaseSplitterFilter::GetDuration(LONGLONG* pDuration)
{
- CheckPointer(pDuration, E_POINTER);
- *pDuration = m_rtDuration;
- return S_OK;
+ CheckPointer(pDuration, E_POINTER);
+ *pDuration = m_rtDuration;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::GetStopPosition(LONGLONG* pStop)
{
- return GetDuration(pStop);
+ return GetDuration(pStop);
}
STDMETHODIMP CBaseSplitterFilter::GetCurrentPosition(LONGLONG* pCurrent)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
STDMETHODIMP CBaseSplitterFilter::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
STDMETHODIMP CBaseSplitterFilter::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
{
- return SetPositionsInternal(this, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
+ return SetPositionsInternal(this, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
}
STDMETHODIMP CBaseSplitterFilter::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop)
{
- if (pCurrent) {
- *pCurrent = m_rtCurrent;
- }
- if (pStop) {
- *pStop = m_rtStop;
- }
- return S_OK;
+ if (pCurrent) {
+ *pCurrent = m_rtCurrent;
+ }
+ if (pStop) {
+ *pStop = m_rtStop;
+ }
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest)
{
- if (pEarliest) {
- *pEarliest = 0;
- }
- return GetDuration(pLatest);
+ if (pEarliest) {
+ *pEarliest = 0;
+ }
+ return GetDuration(pLatest);
}
STDMETHODIMP CBaseSplitterFilter::SetRate(double dRate)
{
- return dRate > 0 ? m_dRate = dRate, S_OK : E_INVALIDARG;
+ return dRate > 0 ? m_dRate = dRate, S_OK : E_INVALIDARG;
}
STDMETHODIMP CBaseSplitterFilter::GetRate(double* pdRate)
{
- return pdRate ? *pdRate = m_dRate, S_OK : E_POINTER;
+ return pdRate ? *pdRate = m_dRate, S_OK : E_POINTER;
}
STDMETHODIMP CBaseSplitterFilter::GetPreroll(LONGLONG* pllPreroll)
{
- return pllPreroll ? *pllPreroll = 0, S_OK : E_POINTER;
+ return pllPreroll ? *pllPreroll = 0, S_OK : E_POINTER;
}
HRESULT CBaseSplitterFilter::SetPositionsInternal(void* id, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
{
- CAutoLock cAutoLock(this);
-
- if (!pCurrent && !pStop
- || (dwCurrentFlags&AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning
- && (dwStopFlags&AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning) {
- return S_OK;
- }
-
- REFERENCE_TIME
- rtCurrent = m_rtCurrent,
- rtStop = m_rtStop;
-
- if (pCurrent)
- switch (dwCurrentFlags&AM_SEEKING_PositioningBitsMask) {
- case AM_SEEKING_NoPositioning:
- break;
- case AM_SEEKING_AbsolutePositioning:
- rtCurrent = *pCurrent;
- break;
- case AM_SEEKING_RelativePositioning:
- rtCurrent = rtCurrent + *pCurrent;
- break;
- case AM_SEEKING_IncrementalPositioning:
- rtCurrent = rtCurrent + *pCurrent;
- break;
- }
-
- if (pStop)
- switch (dwStopFlags&AM_SEEKING_PositioningBitsMask) {
- case AM_SEEKING_NoPositioning:
- break;
- case AM_SEEKING_AbsolutePositioning:
- rtStop = *pStop;
- break;
- case AM_SEEKING_RelativePositioning:
- rtStop += *pStop;
- break;
- case AM_SEEKING_IncrementalPositioning:
- rtStop = rtCurrent + *pStop;
- break;
- }
-
- if (m_rtCurrent == rtCurrent && m_rtStop == rtStop) {
- return S_OK;
- }
-
- if (m_rtLastStart == rtCurrent && m_rtLastStop == rtStop && !m_LastSeekers.Find(id)) {
- m_LastSeekers.AddTail(id);
- return S_OK;
- }
-
- m_rtLastStart = rtCurrent;
- m_rtLastStop = rtStop;
- m_LastSeekers.RemoveAll();
- m_LastSeekers.AddTail(id);
-
- DbgLog((LOG_TRACE, 0, _T("Seek Started %I64d"), rtCurrent));
-
- m_rtNewStart = m_rtCurrent = rtCurrent;
- m_rtNewStop = rtStop;
-
- if (ThreadExists()) {
- DeliverBeginFlush();
- CallWorker(CMD_SEEK);
- DeliverEndFlush();
- }
-
- DbgLog((LOG_TRACE, 0, _T("Seek Ended")));
-
- return S_OK;
+ CAutoLock cAutoLock(this);
+
+ if (!pCurrent && !pStop
+ || (dwCurrentFlags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning
+ && (dwStopFlags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning) {
+ return S_OK;
+ }
+
+ REFERENCE_TIME
+ rtCurrent = m_rtCurrent,
+ rtStop = m_rtStop;
+
+ if (pCurrent)
+ switch (dwCurrentFlags & AM_SEEKING_PositioningBitsMask) {
+ case AM_SEEKING_NoPositioning:
+ break;
+ case AM_SEEKING_AbsolutePositioning:
+ rtCurrent = *pCurrent;
+ break;
+ case AM_SEEKING_RelativePositioning:
+ rtCurrent = rtCurrent + *pCurrent;
+ break;
+ case AM_SEEKING_IncrementalPositioning:
+ rtCurrent = rtCurrent + *pCurrent;
+ break;
+ }
+
+ if (pStop)
+ switch (dwStopFlags & AM_SEEKING_PositioningBitsMask) {
+ case AM_SEEKING_NoPositioning:
+ break;
+ case AM_SEEKING_AbsolutePositioning:
+ rtStop = *pStop;
+ break;
+ case AM_SEEKING_RelativePositioning:
+ rtStop += *pStop;
+ break;
+ case AM_SEEKING_IncrementalPositioning:
+ rtStop = rtCurrent + *pStop;
+ break;
+ }
+
+ if (m_rtCurrent == rtCurrent && m_rtStop == rtStop) {
+ return S_OK;
+ }
+
+ if (m_rtLastStart == rtCurrent && m_rtLastStop == rtStop && !m_LastSeekers.Find(id)) {
+ m_LastSeekers.AddTail(id);
+ return S_OK;
+ }
+
+ m_rtLastStart = rtCurrent;
+ m_rtLastStop = rtStop;
+ m_LastSeekers.RemoveAll();
+ m_LastSeekers.AddTail(id);
+
+ DbgLog((LOG_TRACE, 0, _T("Seek Started %I64d"), rtCurrent));
+
+ m_rtNewStart = m_rtCurrent = rtCurrent;
+ m_rtNewStop = rtStop;
+
+ if (ThreadExists()) {
+ DeliverBeginFlush();
+ CallWorker(CMD_SEEK);
+ DeliverEndFlush();
+ }
+
+ DbgLog((LOG_TRACE, 0, _T("Seek Ended")));
+
+ return S_OK;
}
// IAMOpenProgress
STDMETHODIMP CBaseSplitterFilter::QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent)
{
- CheckPointer(pllTotal, E_POINTER);
- CheckPointer(pllCurrent, E_POINTER);
+ CheckPointer(pllTotal, E_POINTER);
+ CheckPointer(pllCurrent, E_POINTER);
- *pllTotal = 100;
- *pllCurrent = m_nOpenProgress;
+ *pllTotal = 100;
+ *pllCurrent = m_nOpenProgress;
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::AbortOperation()
{
- m_fAbort = true;
- return S_OK;
+ m_fAbort = true;
+ return S_OK;
}
// IAMMediaContent
STDMETHODIMP CBaseSplitterFilter::get_AuthorName(BSTR* pbstrAuthorName)
{
- return GetProperty(L"AUTH", pbstrAuthorName);
+ return GetProperty(L"AUTH", pbstrAuthorName);
}
STDMETHODIMP CBaseSplitterFilter::get_Title(BSTR* pbstrTitle)
{
- return GetProperty(L"TITL", pbstrTitle);
+ return GetProperty(L"TITL", pbstrTitle);
}
STDMETHODIMP CBaseSplitterFilter::get_Rating(BSTR* pbstrRating)
{
- return GetProperty(L"RTNG", pbstrRating);
+ return GetProperty(L"RTNG", pbstrRating);
}
STDMETHODIMP CBaseSplitterFilter::get_Description(BSTR* pbstrDescription)
{
- return GetProperty(L"DESC", pbstrDescription);
+ return GetProperty(L"DESC", pbstrDescription);
}
STDMETHODIMP CBaseSplitterFilter::get_Copyright(BSTR* pbstrCopyright)
{
- return GetProperty(L"CPYR", pbstrCopyright);
+ return GetProperty(L"CPYR", pbstrCopyright);
}
// IAMExtendedSeeking
STDMETHODIMP CBaseSplitterFilter::get_ExSeekCapabilities(long* pExCapabilities)
{
- CheckPointer(pExCapabilities, E_POINTER);
- *pExCapabilities = AM_EXSEEK_CANSEEK;
- if (ChapGetCount()) {
- *pExCapabilities |= AM_EXSEEK_MARKERSEEK;
- }
- return S_OK;
+ CheckPointer(pExCapabilities, E_POINTER);
+ *pExCapabilities = AM_EXSEEK_CANSEEK;
+ if (ChapGetCount()) {
+ *pExCapabilities |= AM_EXSEEK_MARKERSEEK;
+ }
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::get_MarkerCount(long* pMarkerCount)
{
- CheckPointer(pMarkerCount, E_POINTER);
- *pMarkerCount = (long)ChapGetCount();
- return S_OK;
+ CheckPointer(pMarkerCount, E_POINTER);
+ *pMarkerCount = (long)ChapGetCount();
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::get_CurrentMarker(long* pCurrentMarker)
{
- CheckPointer(pCurrentMarker, E_POINTER);
- REFERENCE_TIME rt = m_rtCurrent;
- long i = ChapLookup(&rt);
- if (i < 0) {
- return E_FAIL;
- }
- *pCurrentMarker = i+1;
- return S_OK;
+ CheckPointer(pCurrentMarker, E_POINTER);
+ REFERENCE_TIME rt = m_rtCurrent;
+ long i = ChapLookup(&rt);
+ if (i < 0) {
+ return E_FAIL;
+ }
+ *pCurrentMarker = i + 1;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::GetMarkerTime(long MarkerNum, double* pMarkerTime)
{
- CheckPointer(pMarkerTime, E_POINTER);
- REFERENCE_TIME rt;
- if (FAILED(ChapGet((int)MarkerNum-1, &rt))) {
- return E_FAIL;
- }
- *pMarkerTime = (double)rt / 10000000;
- return S_OK;
+ CheckPointer(pMarkerTime, E_POINTER);
+ REFERENCE_TIME rt;
+ if (FAILED(ChapGet((int)MarkerNum - 1, &rt))) {
+ return E_FAIL;
+ }
+ *pMarkerTime = (double)rt / 10000000;
+ return S_OK;
}
STDMETHODIMP CBaseSplitterFilter::GetMarkerName(long MarkerNum, BSTR* pbstrMarkerName)
{
- return ChapGet((int)MarkerNum-1, NULL, pbstrMarkerName);
+ return ChapGet((int)MarkerNum - 1, NULL, pbstrMarkerName);
}
// IKeyFrameInfo
STDMETHODIMP CBaseSplitterFilter::GetKeyFrameCount(UINT& nKFs)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
STDMETHODIMP CBaseSplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
// IBufferInfo
STDMETHODIMP_(int) CBaseSplitterFilter::GetCount()
{
- CAutoLock cAutoLock(m_pLock);
+ CAutoLock cAutoLock(m_pLock);
- return (int)m_pOutputs.GetCount();
+ return (int)m_pOutputs.GetCount();
}
STDMETHODIMP CBaseSplitterFilter::GetStatus(int i, int& samples, int& size)
{
- CAutoLock cAutoLock(m_pLock);
+ CAutoLock cAutoLock(m_pLock);
- if (POSITION pos = m_pOutputs.FindIndex(i)) {
- CBaseSplitterOutputPin* pPin = m_pOutputs.GetAt(pos);
- samples = pPin->QueueCount();
- size = pPin->QueueSize();
- return pPin->IsConnected() ? S_OK : S_FALSE;
- }
+ if (POSITION pos = m_pOutputs.FindIndex(i)) {
+ CBaseSplitterOutputPin* pPin = m_pOutputs.GetAt(pos);
+ samples = pPin->QueueCount();
+ size = pPin->QueueSize();
+ return pPin->IsConnected() ? S_OK : S_FALSE;
+ }
- return E_INVALIDARG;
+ return E_INVALIDARG;
}
STDMETHODIMP_(DWORD) CBaseSplitterFilter::GetPriority()
{
- return m_priority;
+ return m_priority;
}
diff --git a/src/filters/parser/BaseSplitter/BaseSplitter.h b/src/filters/parser/BaseSplitter/BaseSplitter.h
index 0cd998dd4..b4dfce18f 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitter.h
+++ b/src/filters/parser/BaseSplitter/BaseSplitter.h
@@ -34,432 +34,432 @@
#include "../../../DSUtil/DSMPropertyBag.h"
#include "../../../DSUtil/FontInstaller.h"
-#define MINPACKETS 100 // Beliyaal: Changed the min number of packets to allow Bluray playback over network
-#define MINPACKETSIZE 256*1024 // Beliyaal: Changed the min packet size to allow Bluray playback over network
+#define MINPACKETS 100 // Beliyaal: Changed the min number of packets to allow Bluray playback over network
+#define MINPACKETSIZE 256*1024 // Beliyaal: Changed the min packet size to allow Bluray playback over network
#define MAXPACKETS 1000
#define MAXPACKETSIZE 1024*1024*128
enum {
- /* various PCM "codecs" */
- FF_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
- FF_CODEC_ID_PCM_S16LE= 0x10000,
- FF_CODEC_ID_PCM_S16BE,
- FF_CODEC_ID_PCM_U16LE,
- FF_CODEC_ID_PCM_U16BE,
- FF_CODEC_ID_PCM_S8,
- FF_CODEC_ID_PCM_U8,
- FF_CODEC_ID_PCM_MULAW,
- FF_CODEC_ID_PCM_ALAW,
- FF_CODEC_ID_PCM_S32LE,
- FF_CODEC_ID_PCM_S32BE,
- FF_CODEC_ID_PCM_U32LE,
- FF_CODEC_ID_PCM_U32BE,
- FF_CODEC_ID_PCM_S24LE,
- FF_CODEC_ID_PCM_S24BE,
- FF_CODEC_ID_PCM_U24LE,
- FF_CODEC_ID_PCM_U24BE,
- FF_CODEC_ID_PCM_S24DAUD,
- FF_CODEC_ID_PCM_ZORK,
- FF_CODEC_ID_PCM_S16LE_PLANAR,
- FF_CODEC_ID_PCM_DVD,
- FF_CODEC_ID_PCM_F32BE,
- FF_CODEC_ID_PCM_F32LE,
- FF_CODEC_ID_PCM_F64BE,
- FF_CODEC_ID_PCM_F64LE,
- FF_CODEC_ID_PCM_BLURAY,
- FF_CODEC_ID_PCM_LXF,
- FF_CODEC_ID_S302M,
-
- /* various ADPCM codecs */
- FF_CODEC_ID_ADPCM_IMA_QT= 0x11000,
- FF_CODEC_ID_ADPCM_IMA_WAV,
- FF_CODEC_ID_ADPCM_IMA_DK3,
- FF_CODEC_ID_ADPCM_IMA_DK4,
- FF_CODEC_ID_ADPCM_IMA_WS,
- FF_CODEC_ID_ADPCM_IMA_SMJPEG,
- FF_CODEC_ID_ADPCM_MS,
- FF_CODEC_ID_ADPCM_4XM,
- FF_CODEC_ID_ADPCM_XA,
- FF_CODEC_ID_ADPCM_ADX,
- FF_CODEC_ID_ADPCM_EA,
- FF_CODEC_ID_ADPCM_G726,
- FF_CODEC_ID_ADPCM_CT,
- FF_CODEC_ID_ADPCM_SWF,
- FF_CODEC_ID_ADPCM_YAMAHA,
- FF_CODEC_ID_ADPCM_SBPRO_4,
- FF_CODEC_ID_ADPCM_SBPRO_3,
- FF_CODEC_ID_ADPCM_SBPRO_2,
- FF_CODEC_ID_ADPCM_THP,
- FF_CODEC_ID_ADPCM_IMA_AMV,
- FF_CODEC_ID_ADPCM_EA_R1,
- FF_CODEC_ID_ADPCM_EA_R3,
- FF_CODEC_ID_ADPCM_EA_R2,
- FF_CODEC_ID_ADPCM_IMA_EA_SEAD,
- FF_CODEC_ID_ADPCM_IMA_EA_EACS,
- FF_CODEC_ID_ADPCM_EA_XAS,
- FF_CODEC_ID_ADPCM_EA_MAXIS_XA,
- FF_CODEC_ID_ADPCM_IMA_ISS,
- FF_CODEC_ID_ADPCM_G722,
+ /* various PCM "codecs" */
+ FF_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
+ FF_CODEC_ID_PCM_S16LE = 0x10000,
+ FF_CODEC_ID_PCM_S16BE,
+ FF_CODEC_ID_PCM_U16LE,
+ FF_CODEC_ID_PCM_U16BE,
+ FF_CODEC_ID_PCM_S8,
+ FF_CODEC_ID_PCM_U8,
+ FF_CODEC_ID_PCM_MULAW,
+ FF_CODEC_ID_PCM_ALAW,
+ FF_CODEC_ID_PCM_S32LE,
+ FF_CODEC_ID_PCM_S32BE,
+ FF_CODEC_ID_PCM_U32LE,
+ FF_CODEC_ID_PCM_U32BE,
+ FF_CODEC_ID_PCM_S24LE,
+ FF_CODEC_ID_PCM_S24BE,
+ FF_CODEC_ID_PCM_U24LE,
+ FF_CODEC_ID_PCM_U24BE,
+ FF_CODEC_ID_PCM_S24DAUD,
+ FF_CODEC_ID_PCM_ZORK,
+ FF_CODEC_ID_PCM_S16LE_PLANAR,
+ FF_CODEC_ID_PCM_DVD,
+ FF_CODEC_ID_PCM_F32BE,
+ FF_CODEC_ID_PCM_F32LE,
+ FF_CODEC_ID_PCM_F64BE,
+ FF_CODEC_ID_PCM_F64LE,
+ FF_CODEC_ID_PCM_BLURAY,
+ FF_CODEC_ID_PCM_LXF,
+ FF_CODEC_ID_S302M,
+
+ /* various ADPCM codecs */
+ FF_CODEC_ID_ADPCM_IMA_QT = 0x11000,
+ FF_CODEC_ID_ADPCM_IMA_WAV,
+ FF_CODEC_ID_ADPCM_IMA_DK3,
+ FF_CODEC_ID_ADPCM_IMA_DK4,
+ FF_CODEC_ID_ADPCM_IMA_WS,
+ FF_CODEC_ID_ADPCM_IMA_SMJPEG,
+ FF_CODEC_ID_ADPCM_MS,
+ FF_CODEC_ID_ADPCM_4XM,
+ FF_CODEC_ID_ADPCM_XA,
+ FF_CODEC_ID_ADPCM_ADX,
+ FF_CODEC_ID_ADPCM_EA,
+ FF_CODEC_ID_ADPCM_G726,
+ FF_CODEC_ID_ADPCM_CT,
+ FF_CODEC_ID_ADPCM_SWF,
+ FF_CODEC_ID_ADPCM_YAMAHA,
+ FF_CODEC_ID_ADPCM_SBPRO_4,
+ FF_CODEC_ID_ADPCM_SBPRO_3,
+ FF_CODEC_ID_ADPCM_SBPRO_2,
+ FF_CODEC_ID_ADPCM_THP,
+ FF_CODEC_ID_ADPCM_IMA_AMV,
+ FF_CODEC_ID_ADPCM_EA_R1,
+ FF_CODEC_ID_ADPCM_EA_R3,
+ FF_CODEC_ID_ADPCM_EA_R2,
+ FF_CODEC_ID_ADPCM_IMA_EA_SEAD,
+ FF_CODEC_ID_ADPCM_IMA_EA_EACS,
+ FF_CODEC_ID_ADPCM_EA_XAS,
+ FF_CODEC_ID_ADPCM_EA_MAXIS_XA,
+ FF_CODEC_ID_ADPCM_IMA_ISS,
+ FF_CODEC_ID_ADPCM_G722,
};
class Packet : public CAtlArray<BYTE>
{
public:
- DWORD TrackNumber;
- BOOL bDiscontinuity, bSyncPoint, bAppendable;
- static const REFERENCE_TIME INVALID_TIME = _I64_MIN;
- REFERENCE_TIME rtStart, rtStop;
- AM_MEDIA_TYPE* pmt;
- Packet() {
- pmt = NULL;
- bDiscontinuity = bAppendable = FALSE;
- }
- virtual ~Packet() {
- if (pmt) {
- DeleteMediaType(pmt);
- }
- }
- virtual int GetDataSize() {return (int)GetCount();}
- void SetData(const void* ptr, DWORD len) {
- SetCount(len);
- memcpy(GetData(), ptr, len);
- }
+ DWORD TrackNumber;
+ BOOL bDiscontinuity, bSyncPoint, bAppendable;
+ static const REFERENCE_TIME INVALID_TIME = _I64_MIN;
+ REFERENCE_TIME rtStart, rtStop;
+ AM_MEDIA_TYPE* pmt;
+ Packet() {
+ pmt = NULL;
+ bDiscontinuity = bAppendable = FALSE;
+ }
+ virtual ~Packet() {
+ if (pmt) {
+ DeleteMediaType(pmt);
+ }
+ }
+ virtual int GetDataSize() {return (int)GetCount();}
+ void SetData(const void* ptr, DWORD len) {
+ SetCount(len);
+ memcpy(GetData(), ptr, len);
+ }
};
class CPacketQueue
- : public CCritSec
- , protected CAutoPtrList<Packet>
+ : public CCritSec
+ , protected CAutoPtrList<Packet>
{
- int m_size;
+ int m_size;
public:
- CPacketQueue();
- void Add(CAutoPtr<Packet> p);
- CAutoPtr<Packet> Remove();
- void RemoveAll();
- int GetCount(), GetSize();
+ CPacketQueue();
+ void Add(CAutoPtr<Packet> p);
+ CAutoPtr<Packet> Remove();
+ void RemoveAll();
+ int GetCount(), GetSize();
};
class CBaseSplitterFilter;
class CBaseSplitterInputPin
- : public CBasePin
+ : public CBasePin
{
protected:
- CComQIPtr<IAsyncReader> m_pAsyncReader;
+ CComQIPtr<IAsyncReader> m_pAsyncReader;
public:
- CBaseSplitterInputPin(TCHAR* pName, CBaseSplitterFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CBaseSplitterInputPin();
+ CBaseSplitterInputPin(TCHAR* pName, CBaseSplitterFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CBaseSplitterInputPin();
- HRESULT GetAsyncReader(IAsyncReader** ppAsyncReader);
+ HRESULT GetAsyncReader(IAsyncReader** ppAsyncReader);
- DECLARE_IUNKNOWN;
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- HRESULT CheckMediaType(const CMediaType* pmt);
+ HRESULT CheckMediaType(const CMediaType* pmt);
- HRESULT CheckConnect(IPin* pPin);
- HRESULT BreakConnect();
- HRESULT CompleteConnect(IPin* pPin);
+ HRESULT CheckConnect(IPin* pPin);
+ HRESULT BreakConnect();
+ HRESULT CompleteConnect(IPin* pPin);
- STDMETHODIMP BeginFlush();
- STDMETHODIMP EndFlush();
+ STDMETHODIMP BeginFlush();
+ STDMETHODIMP EndFlush();
};
class CBaseSplitterOutputPin
- : public CBaseOutputPin
- , public IDSMPropertyBagImpl
- , protected CAMThread
- , public IMediaSeeking
- , public IBitRateInfo
+ : public CBaseOutputPin
+ , public IDSMPropertyBagImpl
+ , protected CAMThread
+ , public IMediaSeeking
+ , public IBitRateInfo
{
protected:
- CAtlArray<CMediaType> m_mts;
- int m_nBuffers;
+ CAtlArray<CMediaType> m_mts;
+ int m_nBuffers;
private:
- CPacketQueue m_queue;
+ CPacketQueue m_queue;
- HRESULT m_hrDeliver;
+ HRESULT m_hrDeliver;
- bool m_fFlushing, m_fFlushed;
- CAMEvent m_eEndFlush;
+ bool m_fFlushing, m_fFlushed;
+ CAMEvent m_eEndFlush;
- enum {CMD_EXIT};
- DWORD ThreadProc();
+ enum {CMD_EXIT};
+ DWORD ThreadProc();
- void MakeISCRHappy();
+ void MakeISCRHappy();
- // please only use DeliverPacket from the derived class
- HRESULT GetDeliveryBuffer(IMediaSample** ppSample, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags);
- HRESULT Deliver(IMediaSample* pSample);
+ // please only use DeliverPacket from the derived class
+ HRESULT GetDeliveryBuffer(IMediaSample** ppSample, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags);
+ HRESULT Deliver(IMediaSample* pSample);
- // bitrate stats
+ // bitrate stats
- struct {
- UINT64 nTotalBytesDelivered;
- REFERENCE_TIME rtTotalTimeDelivered;
- UINT64 nBytesSinceLastDeliverTime;
- REFERENCE_TIME rtLastDeliverTime;
- DWORD nCurrentBitRate;
- DWORD nAverageBitRate;
- } m_brs;
+ struct {
+ UINT64 nTotalBytesDelivered;
+ REFERENCE_TIME rtTotalTimeDelivered;
+ UINT64 nBytesSinceLastDeliverTime;
+ REFERENCE_TIME rtLastDeliverTime;
+ DWORD nCurrentBitRate;
+ DWORD nAverageBitRate;
+ } m_brs;
- int m_QueueMaxPackets;
+ int m_QueueMaxPackets;
protected:
- REFERENCE_TIME m_rtStart;
-
- // override this if you need some second level stream specific demuxing (optional)
- // the default implementation will send the sample as is
- virtual HRESULT DeliverPacket(CAutoPtr<Packet> p);
-
- // IMediaSeeking
-
- STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* pFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
- STDMETHODIMP GetTimeFormat(GUID* pFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
- STDMETHODIMP SetTimeFormat(const GUID* pFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
- STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
- STDMETHODIMP SetRate(double dRate);
- STDMETHODIMP GetRate(double* pdRate);
- STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+ REFERENCE_TIME m_rtStart;
+
+ // override this if you need some second level stream specific demuxing (optional)
+ // the default implementation will send the sample as is
+ virtual HRESULT DeliverPacket(CAutoPtr<Packet> p);
+
+ // IMediaSeeking
+
+ STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+ STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+ STDMETHODIMP GetTimeFormat(GUID* pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+ STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+ STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+ STDMETHODIMP SetRate(double dRate);
+ STDMETHODIMP GetRate(double* pdRate);
+ STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
public:
- CBaseSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0, int QueueMaxPackets = MAXPACKETS);
- CBaseSplitterOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0, int QueueMaxPackets = MAXPACKETS);
- virtual ~CBaseSplitterOutputPin();
+ CBaseSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0, int QueueMaxPackets = MAXPACKETS);
+ CBaseSplitterOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0, int QueueMaxPackets = MAXPACKETS);
+ virtual ~CBaseSplitterOutputPin();
- DECLARE_IUNKNOWN;
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- HRESULT SetName(LPCWSTR pName);
+ HRESULT SetName(LPCWSTR pName);
- HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
- HRESULT CheckMediaType(const CMediaType* pmt);
- HRESULT GetMediaType(int iPosition, CMediaType* pmt);
- CMediaType& CurrentMediaType() {return m_mt;}
+ HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
+ HRESULT CheckMediaType(const CMediaType* pmt);
+ HRESULT GetMediaType(int iPosition, CMediaType* pmt);
+ CMediaType& CurrentMediaType() {return m_mt;}
- STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
+ STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
- // Queueing
+ // Queueing
- HANDLE GetThreadHandle() {
- ASSERT(m_hThread != NULL);
- return m_hThread;
- }
- void SetThreadPriority(int nPriority) {
- if (m_hThread) {
- ::SetThreadPriority(m_hThread, nPriority);
- }
- }
+ HANDLE GetThreadHandle() {
+ ASSERT(m_hThread != NULL);
+ return m_hThread;
+ }
+ void SetThreadPriority(int nPriority) {
+ if (m_hThread) {
+ ::SetThreadPriority(m_hThread, nPriority);
+ }
+ }
- HRESULT Active();
- HRESULT Inactive();
+ HRESULT Active();
+ HRESULT Inactive();
- HRESULT DeliverBeginFlush();
- HRESULT DeliverEndFlush();
- HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+ HRESULT DeliverBeginFlush();
+ HRESULT DeliverEndFlush();
+ HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
- int QueueCount();
- int QueueSize();
- HRESULT QueueEndOfStream();
- HRESULT QueuePacket(CAutoPtr<Packet> p);
+ int QueueCount();
+ int QueueSize();
+ HRESULT QueueEndOfStream();
+ HRESULT QueuePacket(CAutoPtr<Packet> p);
- // returns true for everything which (the lack of) would not block other streams (subtitle streams, basically)
- virtual bool IsDiscontinuous();
+ // returns true for everything which (the lack of) would not block other streams (subtitle streams, basically)
+ virtual bool IsDiscontinuous();
- // returns IStreamsSwitcherInputPin::IsActive(), when it can find one downstream
- bool IsActive();
+ // returns IStreamsSwitcherInputPin::IsActive(), when it can find one downstream
+ bool IsActive();
- // IBitRateInfo
+ // IBitRateInfo
- STDMETHODIMP_(DWORD) GetCurrentBitRate() {return m_brs.nCurrentBitRate;}
- STDMETHODIMP_(DWORD) GetAverageBitRate() {return m_brs.nAverageBitRate;}
+ STDMETHODIMP_(DWORD) GetCurrentBitRate() {return m_brs.nCurrentBitRate;}
+ STDMETHODIMP_(DWORD) GetAverageBitRate() {return m_brs.nAverageBitRate;}
};
class CBaseSplitterFilter
- : public CBaseFilter
- , public CCritSec
- , public IDSMPropertyBagImpl
- , public IDSMResourceBagImpl
- , public IDSMChapterBagImpl
- , protected CAMThread
- , public IFileSourceFilter
- , public IMediaSeeking
- , public IAMOpenProgress
- , public IAMMediaContent
- , public IAMExtendedSeeking
- , public IKeyFrameInfo
- , public IBufferInfo
+ : public CBaseFilter
+ , public CCritSec
+ , public IDSMPropertyBagImpl
+ , public IDSMResourceBagImpl
+ , public IDSMChapterBagImpl
+ , protected CAMThread
+ , public IFileSourceFilter
+ , public IMediaSeeking
+ , public IAMOpenProgress
+ , public IAMMediaContent
+ , public IAMExtendedSeeking
+ , public IKeyFrameInfo
+ , public IBufferInfo
{
- CCritSec m_csPinMap;
- CAtlMap<DWORD, CBaseSplitterOutputPin*> m_pPinMap;
+ CCritSec m_csPinMap;
+ CAtlMap<DWORD, CBaseSplitterOutputPin*> m_pPinMap;
- CCritSec m_csmtnew;
- CAtlMap<DWORD, CMediaType> m_mtnew;
+ CCritSec m_csmtnew;
+ CAtlMap<DWORD, CMediaType> m_mtnew;
- CAutoPtrList<CBaseSplitterOutputPin> m_pRetiredOutputs;
+ CAutoPtrList<CBaseSplitterOutputPin> m_pRetiredOutputs;
- CComQIPtr<ISyncReader> m_pSyncReader;
+ CComQIPtr<ISyncReader> m_pSyncReader;
protected:
- CStringW m_fn;
+ CStringW m_fn;
- CAutoPtr<CBaseSplitterInputPin> m_pInput;
- CAutoPtrList<CBaseSplitterOutputPin> m_pOutputs;
+ CAutoPtr<CBaseSplitterInputPin> m_pInput;
+ CAutoPtrList<CBaseSplitterOutputPin> m_pOutputs;
- CBaseSplitterOutputPin* GetOutputPin(DWORD TrackNum);
- DWORD GetOutputTrackNum(CBaseSplitterOutputPin* pPin);
- HRESULT AddOutputPin(DWORD TrackNum, CAutoPtr<CBaseSplitterOutputPin> pPin);
- HRESULT RenameOutputPin(DWORD TrackNumSrc, DWORD TrackNumDst, const AM_MEDIA_TYPE* pmt);
- virtual HRESULT DeleteOutputs();
- virtual HRESULT CreateOutputs(IAsyncReader* pAsyncReader) = 0; // override this ...
- virtual LPCTSTR GetPartFilename(IAsyncReader* pAsyncReader);
+ CBaseSplitterOutputPin* GetOutputPin(DWORD TrackNum);
+ DWORD GetOutputTrackNum(CBaseSplitterOutputPin* pPin);
+ HRESULT AddOutputPin(DWORD TrackNum, CAutoPtr<CBaseSplitterOutputPin> pPin);
+ HRESULT RenameOutputPin(DWORD TrackNumSrc, DWORD TrackNumDst, const AM_MEDIA_TYPE* pmt);
+ virtual HRESULT DeleteOutputs();
+ virtual HRESULT CreateOutputs(IAsyncReader* pAsyncReader) = 0; // override this ...
+ virtual LPCTSTR GetPartFilename(IAsyncReader* pAsyncReader);
- LONGLONG m_nOpenProgress;
- bool m_fAbort;
+ LONGLONG m_nOpenProgress;
+ bool m_fAbort;
- REFERENCE_TIME m_rtDuration; // derived filter should set this at the end of CreateOutputs
- REFERENCE_TIME m_rtStart, m_rtStop, m_rtCurrent, m_rtNewStart, m_rtNewStop;
- double m_dRate;
+ REFERENCE_TIME m_rtDuration; // derived filter should set this at the end of CreateOutputs
+ REFERENCE_TIME m_rtStart, m_rtStop, m_rtCurrent, m_rtNewStart, m_rtNewStop;
+ double m_dRate;
- CAtlList<UINT64> m_bDiscontinuitySent;
- CAtlList<CBaseSplitterOutputPin*> m_pActivePins;
+ CAtlList<UINT64> m_bDiscontinuitySent;
+ CAtlList<CBaseSplitterOutputPin*> m_pActivePins;
- CAMEvent m_eEndFlush;
- bool m_fFlushing;
+ CAMEvent m_eEndFlush;
+ bool m_fFlushing;
- void DeliverBeginFlush();
- void DeliverEndFlush();
- HRESULT DeliverPacket(CAutoPtr<Packet> p);
+ void DeliverBeginFlush();
+ void DeliverEndFlush();
+ HRESULT DeliverPacket(CAutoPtr<Packet> p);
- int m_priority;
+ int m_priority;
- CFontInstaller m_fontinst;
+ CFontInstaller m_fontinst;
- int m_QueueMaxPackets;
+ int m_QueueMaxPackets;
protected:
- enum {CMD_EXIT, CMD_SEEK};
- DWORD ThreadProc();
+ enum {CMD_EXIT, CMD_SEEK};
+ DWORD ThreadProc();
- // ... and also override all these too
- virtual bool DemuxInit() = 0;
- virtual void DemuxSeek(REFERENCE_TIME rt) = 0;
- virtual bool DemuxLoop() = 0;
- virtual bool BuildPlaylist(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& Items) { return false; };
- virtual bool BuildChapters(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& PlaylistItems, CAtlList<CHdmvClipInfo::PlaylistChapter>& Items) { return false; };
+ // ... and also override all these too
+ virtual bool DemuxInit() = 0;
+ virtual void DemuxSeek(REFERENCE_TIME rt) = 0;
+ virtual bool DemuxLoop() = 0;
+ virtual bool BuildPlaylist(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& Items) { return false; };
+ virtual bool BuildChapters(LPCTSTR pszFileName, CAtlList<CHdmvClipInfo::PlaylistItem>& PlaylistItems, CAtlList<CHdmvClipInfo::PlaylistChapter>& Items) { return false; };
public:
- CBaseSplitterFilter(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid, int QueueMaxPackets = MAXPACKETS);
- virtual ~CBaseSplitterFilter();
+ CBaseSplitterFilter(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid, int QueueMaxPackets = MAXPACKETS);
+ virtual ~CBaseSplitterFilter();
- DECLARE_IUNKNOWN;
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
- bool IsAnyPinDrying();
+ bool IsAnyPinDrying();
- HRESULT BreakConnect(PIN_DIRECTION dir, CBasePin* pPin);
- HRESULT CompleteConnect(PIN_DIRECTION dir, CBasePin* pPin);
+ HRESULT BreakConnect(PIN_DIRECTION dir, CBasePin* pPin);
+ HRESULT CompleteConnect(PIN_DIRECTION dir, CBasePin* pPin);
- int GetPinCount();
- CBasePin* GetPin(int n);
+ int GetPinCount();
+ CBasePin* GetPin(int n);
- STDMETHODIMP Stop();
- STDMETHODIMP Pause();
- STDMETHODIMP Run(REFERENCE_TIME tStart);
+ STDMETHODIMP Stop();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Run(REFERENCE_TIME tStart);
- // IFileSourceFilter
+ // IFileSourceFilter
- STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
- STDMETHODIMP GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt);
- // IMediaSeeking
+ // IMediaSeeking
- STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* pFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
- STDMETHODIMP GetTimeFormat(GUID* pFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
- STDMETHODIMP SetTimeFormat(const GUID* pFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
- STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
- STDMETHODIMP SetRate(double dRate);
- STDMETHODIMP GetRate(double* pdRate);
- STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+ STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+ STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+ STDMETHODIMP GetTimeFormat(GUID* pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+ STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+ STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+ STDMETHODIMP SetRate(double dRate);
+ STDMETHODIMP GetRate(double* pdRate);
+ STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
protected:
- friend class CBaseSplitterOutputPin;
- virtual HRESULT SetPositionsInternal(void* id, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ friend class CBaseSplitterOutputPin;
+ virtual HRESULT SetPositionsInternal(void* id, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
private:
- REFERENCE_TIME m_rtLastStart, m_rtLastStop;
- CAtlList<void*> m_LastSeekers;
+ REFERENCE_TIME m_rtLastStart, m_rtLastStop;
+ CAtlList<void*> m_LastSeekers;
public:
- // IAMOpenProgress
-
- STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
- STDMETHODIMP AbortOperation();
-
- // IDispatch
-
- STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
- STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {return E_NOTIMPL;}
- STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) {return E_NOTIMPL;}
- STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) {return E_NOTIMPL;}
-
- // IAMMediaContent
-
- STDMETHODIMP get_AuthorName(BSTR* pbstrAuthorName);
- STDMETHODIMP get_Title(BSTR* pbstrTitle);
- STDMETHODIMP get_Rating(BSTR* pbstrRating);
- STDMETHODIMP get_Description(BSTR* pbstrDescription);
- STDMETHODIMP get_Copyright(BSTR* pbstrCopyright);
- STDMETHODIMP get_BaseURL(BSTR* pbstrBaseURL) {return E_NOTIMPL;}
- STDMETHODIMP get_LogoURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
- STDMETHODIMP get_LogoIconURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
- STDMETHODIMP get_WatermarkURL(BSTR* pbstrWatermarkURL) {return E_NOTIMPL;}
- STDMETHODIMP get_MoreInfoURL(BSTR* pbstrMoreInfoURL) {return E_NOTIMPL;}
- STDMETHODIMP get_MoreInfoBannerImage(BSTR* pbstrMoreInfoBannerImage) {return E_NOTIMPL;}
- STDMETHODIMP get_MoreInfoBannerURL(BSTR* pbstrMoreInfoBannerURL) {return E_NOTIMPL;}
- STDMETHODIMP get_MoreInfoText(BSTR* pbstrMoreInfoText) {return E_NOTIMPL;}
-
- // IAMExtendedSeeking
-
- STDMETHODIMP get_ExSeekCapabilities(long* pExCapabilities);
- STDMETHODIMP get_MarkerCount(long* pMarkerCount);
- STDMETHODIMP get_CurrentMarker(long* pCurrentMarker);
- STDMETHODIMP GetMarkerTime(long MarkerNum, double* pMarkerTime);
- STDMETHODIMP GetMarkerName(long MarkerNum, BSTR* pbstrMarkerName);
- STDMETHODIMP put_PlaybackSpeed(double Speed) {return E_NOTIMPL;}
- STDMETHODIMP get_PlaybackSpeed(double* pSpeed) {return E_NOTIMPL;}
-
- // IKeyFrameInfo
-
- STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
- STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
-
- // IBufferInfo
-
- STDMETHODIMP_(int) GetCount();
- STDMETHODIMP GetStatus(int i, int& samples, int& size);
- STDMETHODIMP_(DWORD) GetPriority();
+ // IAMOpenProgress
+
+ STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
+ STDMETHODIMP AbortOperation();
+
+ // IDispatch
+
+ STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
+ STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {return E_NOTIMPL;}
+ STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) {return E_NOTIMPL;}
+ STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) {return E_NOTIMPL;}
+
+ // IAMMediaContent
+
+ STDMETHODIMP get_AuthorName(BSTR* pbstrAuthorName);
+ STDMETHODIMP get_Title(BSTR* pbstrTitle);
+ STDMETHODIMP get_Rating(BSTR* pbstrRating);
+ STDMETHODIMP get_Description(BSTR* pbstrDescription);
+ STDMETHODIMP get_Copyright(BSTR* pbstrCopyright);
+ STDMETHODIMP get_BaseURL(BSTR* pbstrBaseURL) {return E_NOTIMPL;}
+ STDMETHODIMP get_LogoURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
+ STDMETHODIMP get_LogoIconURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
+ STDMETHODIMP get_WatermarkURL(BSTR* pbstrWatermarkURL) {return E_NOTIMPL;}
+ STDMETHODIMP get_MoreInfoURL(BSTR* pbstrMoreInfoURL) {return E_NOTIMPL;}
+ STDMETHODIMP get_MoreInfoBannerImage(BSTR* pbstrMoreInfoBannerImage) {return E_NOTIMPL;}
+ STDMETHODIMP get_MoreInfoBannerURL(BSTR* pbstrMoreInfoBannerURL) {return E_NOTIMPL;}
+ STDMETHODIMP get_MoreInfoText(BSTR* pbstrMoreInfoText) {return E_NOTIMPL;}
+
+ // IAMExtendedSeeking
+
+ STDMETHODIMP get_ExSeekCapabilities(long* pExCapabilities);
+ STDMETHODIMP get_MarkerCount(long* pMarkerCount);
+ STDMETHODIMP get_CurrentMarker(long* pCurrentMarker);
+ STDMETHODIMP GetMarkerTime(long MarkerNum, double* pMarkerTime);
+ STDMETHODIMP GetMarkerName(long MarkerNum, BSTR* pbstrMarkerName);
+ STDMETHODIMP put_PlaybackSpeed(double Speed) {return E_NOTIMPL;}
+ STDMETHODIMP get_PlaybackSpeed(double* pSpeed) {return E_NOTIMPL;}
+
+ // IKeyFrameInfo
+
+ STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
+ STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
+
+ // IBufferInfo
+
+ STDMETHODIMP_(int) GetCount();
+ STDMETHODIMP GetStatus(int i, int& samples, int& size);
+ STDMETHODIMP_(DWORD) GetPriority();
};
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFile.cpp b/src/filters/parser/BaseSplitter/BaseSplitterFile.cpp
index 3db0849e2..08a117b8c 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitterFile.cpp
+++ b/src/filters/parser/BaseSplitter/BaseSplitterFile.cpp
@@ -30,222 +30,222 @@
//
CBaseSplitterFile::CBaseSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr, int cachelen, bool fRandomAccess, bool fStreaming)
- : m_pAsyncReader(pAsyncReader)
- , m_fStreaming(false)
- , m_fRandomAccess(false)
- , m_pos(0), m_len(0)
- , m_bitbuff(0), m_bitlen(0)
- , m_cachepos(0), m_cachelen(0)
+ : m_pAsyncReader(pAsyncReader)
+ , m_fStreaming(false)
+ , m_fRandomAccess(false)
+ , m_pos(0), m_len(0)
+ , m_bitbuff(0), m_bitlen(0)
+ , m_cachepos(0), m_cachelen(0)
{
- if (!m_pAsyncReader) {
- hr = E_UNEXPECTED;
- return;
- }
+ if (!m_pAsyncReader) {
+ hr = E_UNEXPECTED;
+ return;
+ }
- LONGLONG total = 0, available;
- hr = m_pAsyncReader->Length(&total, &available);
+ LONGLONG total = 0, available;
+ hr = m_pAsyncReader->Length(&total, &available);
- m_fStreaming = total == 0 && available > 0;
- m_fRandomAccess = total > 0 && total == available;
- m_len = total;
+ m_fStreaming = total == 0 && available > 0;
+ m_fRandomAccess = total > 0 && total == available;
+ m_len = total;
- if (FAILED(hr) || fRandomAccess && !m_fRandomAccess || !fStreaming && m_fStreaming || m_len < 0) {
- hr = E_FAIL;
- return;
- }
+ if (FAILED(hr) || fRandomAccess && !m_fRandomAccess || !fStreaming && m_fStreaming || m_len < 0) {
+ hr = E_FAIL;
+ return;
+ }
- if (!SetCacheSize(cachelen)) {
- hr = E_OUTOFMEMORY;
- return;
- }
+ if (!SetCacheSize(cachelen)) {
+ hr = E_OUTOFMEMORY;
+ return;
+ }
- hr = S_OK;
+ hr = S_OK;
}
bool CBaseSplitterFile::SetCacheSize(int cachelen)
{
- m_pCache.Free();
- m_cachetotal = 0;
- m_pCache.Allocate((size_t)cachelen);
- if (!m_pCache) {
- return false;
- }
- m_cachetotal = cachelen;
- m_cachelen = 0;
- return true;
+ m_pCache.Free();
+ m_cachetotal = 0;
+ m_pCache.Allocate((size_t)cachelen);
+ if (!m_pCache) {
+ return false;
+ }
+ m_cachetotal = cachelen;
+ m_cachelen = 0;
+ return true;
}
__int64 CBaseSplitterFile::GetPos()
{
- return m_pos - (m_bitlen>>3);
+ return m_pos - (m_bitlen >> 3);
}
__int64 CBaseSplitterFile::GetAvailable()
{
- LONGLONG total, available = 0;
- m_pAsyncReader->Length(&total, &available);
- return available;
+ LONGLONG total, available = 0;
+ m_pAsyncReader->Length(&total, &available);
+ return available;
}
__int64 CBaseSplitterFile::GetLength(bool fUpdate)
{
- if (m_fStreaming) {
- m_len = GetAvailable();
- } else if (fUpdate) {
- LONGLONG total = 0, available;
- m_pAsyncReader->Length(&total, &available);
- m_len = total;
- }
-
- return m_len;
+ if (m_fStreaming) {
+ m_len = GetAvailable();
+ } else if (fUpdate) {
+ LONGLONG total = 0, available;
+ m_pAsyncReader->Length(&total, &available);
+ m_len = total;
+ }
+
+ return m_len;
}
void CBaseSplitterFile::Seek(__int64 pos)
{
- __int64 len = GetLength();
- m_pos = min(max(pos, 0), len);
- BitFlush();
+ __int64 len = GetLength();
+ m_pos = min(max(pos, 0), len);
+ BitFlush();
}
HRESULT CBaseSplitterFile::Read(BYTE* pData, __int64 len)
{
- CheckPointer(m_pAsyncReader, E_NOINTERFACE);
-
- HRESULT hr = S_OK;
-
- if (!m_fRandomAccess) {
- LONGLONG total = 0, available = -1;
- m_pAsyncReader->Length(&total, &available);
- if (total == available) {
- m_fRandomAccess = true;
- OnComplete();
- }
- }
-
- if (m_cachetotal == 0 || !m_pCache) {
- hr = m_pAsyncReader->SyncRead(m_pos, (long)len, pData);
- m_pos += len;
- return hr;
- }
-
- BYTE* pCache = m_pCache;
-
- if (m_cachepos <= m_pos && m_pos < m_cachepos + m_cachelen) {
- __int64 minlen = min(len, m_cachelen - (m_pos - m_cachepos));
-
- memcpy(pData, &pCache[m_pos - m_cachepos], (size_t)minlen);
-
- len -= minlen;
- m_pos += minlen;
- pData += minlen;
- }
-
- while (len > m_cachetotal) {
- hr = m_pAsyncReader->SyncRead(m_pos, (long)m_cachetotal, pData);
- if (S_OK != hr) {
- return hr;
- }
-
- len -= m_cachetotal;
- m_pos += m_cachetotal;
- pData += m_cachetotal;
- }
-
- while (len > 0) {
- __int64 tmplen = GetLength();
- __int64 maxlen = min(tmplen - m_pos, m_cachetotal);
- __int64 minlen = min(len, maxlen);
- if (minlen <= 0) {
- return S_FALSE;
- }
-
- hr = m_pAsyncReader->SyncRead(m_pos, (long)maxlen, pCache);
- if (S_OK != hr) {
- return hr;
- }
-
- m_cachepos = m_pos;
- m_cachelen = maxlen;
-
- memcpy(pData, pCache, (size_t)minlen);
-
- len -= minlen;
- m_pos += minlen;
- pData += minlen;
- }
-
- return hr;
+ CheckPointer(m_pAsyncReader, E_NOINTERFACE);
+
+ HRESULT hr = S_OK;
+
+ if (!m_fRandomAccess) {
+ LONGLONG total = 0, available = -1;
+ m_pAsyncReader->Length(&total, &available);
+ if (total == available) {
+ m_fRandomAccess = true;
+ OnComplete();
+ }
+ }
+
+ if (m_cachetotal == 0 || !m_pCache) {
+ hr = m_pAsyncReader->SyncRead(m_pos, (long)len, pData);
+ m_pos += len;
+ return hr;
+ }
+
+ BYTE* pCache = m_pCache;
+
+ if (m_cachepos <= m_pos && m_pos < m_cachepos + m_cachelen) {
+ __int64 minlen = min(len, m_cachelen - (m_pos - m_cachepos));
+
+ memcpy(pData, &pCache[m_pos - m_cachepos], (size_t)minlen);
+
+ len -= minlen;
+ m_pos += minlen;
+ pData += minlen;
+ }
+
+ while (len > m_cachetotal) {
+ hr = m_pAsyncReader->SyncRead(m_pos, (long)m_cachetotal, pData);
+ if (S_OK != hr) {
+ return hr;
+ }
+
+ len -= m_cachetotal;
+ m_pos += m_cachetotal;
+ pData += m_cachetotal;
+ }
+
+ while (len > 0) {
+ __int64 tmplen = GetLength();
+ __int64 maxlen = min(tmplen - m_pos, m_cachetotal);
+ __int64 minlen = min(len, maxlen);
+ if (minlen <= 0) {
+ return S_FALSE;
+ }
+
+ hr = m_pAsyncReader->SyncRead(m_pos, (long)maxlen, pCache);
+ if (S_OK != hr) {
+ return hr;
+ }
+
+ m_cachepos = m_pos;
+ m_cachelen = maxlen;
+
+ memcpy(pData, pCache, (size_t)minlen);
+
+ len -= minlen;
+ m_pos += minlen;
+ pData += minlen;
+ }
+
+ return hr;
}
UINT64 CBaseSplitterFile::BitRead(int nBits, bool fPeek)
{
- ASSERT(nBits >= 0 && nBits <= 64);
+ ASSERT(nBits >= 0 && nBits <= 64);
- while (m_bitlen < nBits) {
- m_bitbuff <<= 8;
- if (S_OK != Read((BYTE*)&m_bitbuff, 1)) {
- return 0; // EOF? // ASSERT(0);
- }
- m_bitlen += 8;
- }
+ while (m_bitlen < nBits) {
+ m_bitbuff <<= 8;
+ if (S_OK != Read((BYTE*)&m_bitbuff, 1)) {
+ return 0; // EOF? // ASSERT(0);
+ }
+ m_bitlen += 8;
+ }
- int bitlen = m_bitlen - nBits;
+ int bitlen = m_bitlen - nBits;
- UINT64 ret = (m_bitbuff >> bitlen) & ((1ui64 << nBits) - 1);
+ UINT64 ret = (m_bitbuff >> bitlen) & ((1ui64 << nBits) - 1);
- if (!fPeek) {
- m_bitbuff &= ((1ui64 << bitlen) - 1);
- m_bitlen = bitlen;
- }
+ if (!fPeek) {
+ m_bitbuff &= ((1ui64 << bitlen) - 1);
+ m_bitlen = bitlen;
+ }
- return ret;
+ return ret;
}
void CBaseSplitterFile::BitByteAlign()
{
- m_bitlen &= ~7;
+ m_bitlen &= ~7;
}
void CBaseSplitterFile::BitFlush()
{
- m_bitlen = 0;
+ m_bitlen = 0;
}
HRESULT CBaseSplitterFile::ByteRead(BYTE* pData, __int64 len)
{
- Seek(GetPos());
- return Read(pData, len);
+ Seek(GetPos());
+ return Read(pData, len);
}
UINT64 CBaseSplitterFile::UExpGolombRead()
{
- int n = -1;
- for (BYTE b = 0; !b; n++) {
- b = (BYTE)BitRead(1);
- }
- return (1ui64 << n) - 1 + BitRead(n);
+ int n = -1;
+ for (BYTE b = 0; !b; n++) {
+ b = (BYTE)BitRead(1);
+ }
+ return (1ui64 << n) - 1 + BitRead(n);
}
INT64 CBaseSplitterFile::SExpGolombRead()
{
- UINT64 k = UExpGolombRead();
- return ((k&1) ? 1 : -1) * ((k + 1) >> 1);
+ UINT64 k = UExpGolombRead();
+ return ((k & 1) ? 1 : -1) * ((k + 1) >> 1);
}
HRESULT CBaseSplitterFile::HasMoreData(__int64 len, DWORD ms)
{
- __int64 available = GetLength() - GetPos();
+ __int64 available = GetLength() - GetPos();
- if (!m_fStreaming) {
- return available < 1 ? E_FAIL : S_OK;
- }
+ if (!m_fStreaming) {
+ return available < 1 ? E_FAIL : S_OK;
+ }
- if (available < len) {
- if (ms > 0) {
- Sleep(ms);
- }
- return S_FALSE;
- }
+ if (available < len) {
+ if (ms > 0) {
+ Sleep(ms);
+ }
+ return S_FALSE;
+ }
- return S_OK;
+ return S_OK;
}
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFile.h b/src/filters/parser/BaseSplitter/BaseSplitterFile.h
index 54533140a..59cae090f 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitterFile.h
+++ b/src/filters/parser/BaseSplitter/BaseSplitterFile.h
@@ -25,46 +25,46 @@
#include <atlcoll.h>
-#define DEFAULT_CACHE_LENGTH 64*1024 // Beliyaal: Changed the default cache length to allow Bluray playback over network
+#define DEFAULT_CACHE_LENGTH 64*1024 // Beliyaal: Changed the default cache length to allow Bluray playback over network
class CBaseSplitterFile
{
- CComPtr<IAsyncReader> m_pAsyncReader;
- CAutoVectorPtr<BYTE> m_pCache;
- __int64 m_cachepos, m_cachelen, m_cachetotal;
+ CComPtr<IAsyncReader> m_pAsyncReader;
+ CAutoVectorPtr<BYTE> m_pCache;
+ __int64 m_cachepos, m_cachelen, m_cachetotal;
- bool m_fStreaming, m_fRandomAccess;
- __int64 m_pos, m_len;
+ bool m_fStreaming, m_fRandomAccess;
+ __int64 m_pos, m_len;
- virtual HRESULT Read(BYTE* pData, __int64 len); // use ByteRead
+ virtual HRESULT Read(BYTE* pData, __int64 len); // use ByteRead
protected:
- UINT64 m_bitbuff;
- int m_bitlen;
+ UINT64 m_bitbuff;
+ int m_bitlen;
- virtual void OnComplete() {}
+ virtual void OnComplete() {}
public:
- CBaseSplitterFile(IAsyncReader* pReader, HRESULT& hr, int cachelen = DEFAULT_CACHE_LENGTH, bool fRandomAccess = true, bool fStreaming = false);
- virtual ~CBaseSplitterFile() {}
+ CBaseSplitterFile(IAsyncReader* pReader, HRESULT& hr, int cachelen = DEFAULT_CACHE_LENGTH, bool fRandomAccess = true, bool fStreaming = false);
+ virtual ~CBaseSplitterFile() {}
- bool SetCacheSize(int cachelen = DEFAULT_CACHE_LENGTH);
+ bool SetCacheSize(int cachelen = DEFAULT_CACHE_LENGTH);
- __int64 GetPos();
- __int64 GetAvailable();
- __int64 GetLength(bool fUpdate = false);
- __int64 GetRemaining() {return max(0, GetLength() - GetPos());}
- virtual void Seek(__int64 pos);
+ __int64 GetPos();
+ __int64 GetAvailable();
+ __int64 GetLength(bool fUpdate = false);
+ __int64 GetRemaining() {return max(0, GetLength() - GetPos());}
+ virtual void Seek(__int64 pos);
- UINT64 UExpGolombRead();
- INT64 SExpGolombRead();
+ UINT64 UExpGolombRead();
+ INT64 SExpGolombRead();
- UINT64 BitRead(int nBits, bool fPeek = false);
- void BitByteAlign(), BitFlush();
- HRESULT ByteRead(BYTE* pData, __int64 len);
+ UINT64 BitRead(int nBits, bool fPeek = false);
+ void BitByteAlign(), BitFlush();
+ HRESULT ByteRead(BYTE* pData, __int64 len);
- bool IsStreaming() const {return m_fStreaming;}
- bool IsRandomAccess() const {return m_fRandomAccess;}
+ bool IsStreaming() const {return m_fStreaming;}
+ bool IsRandomAccess() const {return m_fRandomAccess;}
- HRESULT HasMoreData(__int64 len = 1, DWORD ms = 1);
+ HRESULT HasMoreData(__int64 len = 1, DWORD ms = 1);
};
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp
index e4129fd58..490d2aab5 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp
+++ b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp
@@ -35,9 +35,9 @@
//
CBaseSplitterFileEx::CBaseSplitterFileEx(IAsyncReader* pReader, HRESULT& hr, int cachelen, bool fRandomAccess, bool fStreaming)
- : CBaseSplitterFile(pReader, hr, cachelen, fRandomAccess, fStreaming)
- , m_tslen(0)
- ,m_rtPTSOffset(0)
+ : CBaseSplitterFile(pReader, hr, cachelen, fRandomAccess, fStreaming)
+ , m_tslen(0)
+ , m_rtPTSOffset(0)
{
}
@@ -49,16 +49,16 @@ CBaseSplitterFileEx::~CBaseSplitterFileEx()
bool CBaseSplitterFileEx::NextMpegStartCode(BYTE& code, __int64 len)
{
- BitByteAlign();
- DWORD dw = (DWORD)-1;
- do {
- if (len-- == 0 || !GetRemaining()) {
- return false;
- }
- dw = (dw << 8) | (BYTE)BitRead(8);
- } while ((dw&0xffffff00) != 0x00000100);
- code = (BYTE)(dw&0xff);
- return true;
+ BitByteAlign();
+ DWORD dw = (DWORD) - 1;
+ do {
+ if (len-- == 0 || !GetRemaining()) {
+ return false;
+ }
+ dw = (dw << 8) | (BYTE)BitRead(8);
+ } while ((dw & 0xffffff00) != 0x00000100);
+ code = (BYTE)(dw & 0xff);
+ return true;
}
//
@@ -67,2098 +67,2111 @@ bool CBaseSplitterFileEx::NextMpegStartCode(BYTE& code, __int64 len)
bool CBaseSplitterFileEx::Read(pshdr& h)
{
- memset(&h, 0, sizeof(h));
-
- BYTE b = (BYTE)BitRead(8, true);
-
- if ((b&0xf1) == 0x21) {
- h.type = mpeg1;
-
- EXECUTE_ASSERT(BitRead(4) == 2);
-
- h.scr = 0;
- h.scr |= BitRead(3) << 30;
- MARKER; // 32..30
- h.scr |= BitRead(15) << 15;
- MARKER; // 29..15
- h.scr |= BitRead(15);
- MARKER;
- MARKER; // 14..0
- h.bitrate = BitRead(22);
- MARKER;
- } else if ((b&0xc4) == 0x44) {
- h.type = mpeg2;
-
- EXECUTE_ASSERT(BitRead(2) == 1);
-
- h.scr = 0;
- h.scr |= BitRead(3) << 30;
- MARKER; // 32..30
- h.scr |= BitRead(15) << 15;
- MARKER; // 29..15
- h.scr |= BitRead(15);
- MARKER; // 14..0
- h.scr = (h.scr*300 + BitRead(9)) * 10 / 27;
- MARKER;
- h.bitrate = BitRead(22);
- MARKER;
- MARKER;
- BitRead(5); // reserved
- UINT64 stuffing = BitRead(3);
- while (stuffing-- > 0) {
- EXECUTE_ASSERT(BitRead(8) == 0xff);
- }
- } else {
- return false;
- }
-
- h.bitrate *= 400;
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ BYTE b = (BYTE)BitRead(8, true);
+
+ if ((b & 0xf1) == 0x21) {
+ h.type = mpeg1;
+
+ EXECUTE_ASSERT(BitRead(4) == 2);
+
+ h.scr = 0;
+ h.scr |= BitRead(3) << 30;
+ MARKER; // 32..30
+ h.scr |= BitRead(15) << 15;
+ MARKER; // 29..15
+ h.scr |= BitRead(15);
+ MARKER;
+ MARKER; // 14..0
+ h.bitrate = BitRead(22);
+ MARKER;
+ } else if ((b & 0xc4) == 0x44) {
+ h.type = mpeg2;
+
+ EXECUTE_ASSERT(BitRead(2) == 1);
+
+ h.scr = 0;
+ h.scr |= BitRead(3) << 30;
+ MARKER; // 32..30
+ h.scr |= BitRead(15) << 15;
+ MARKER; // 29..15
+ h.scr |= BitRead(15);
+ MARKER; // 14..0
+ h.scr = (h.scr * 300 + BitRead(9)) * 10 / 27;
+ MARKER;
+ h.bitrate = BitRead(22);
+ MARKER;
+ MARKER;
+ BitRead(5); // reserved
+ UINT64 stuffing = BitRead(3);
+ while (stuffing-- > 0) {
+ EXECUTE_ASSERT(BitRead(8) == 0xff);
+ }
+ } else {
+ return false;
+ }
+
+ h.bitrate *= 400;
+
+ return true;
}
bool CBaseSplitterFileEx::Read(pssyshdr& h)
{
- memset(&h, 0, sizeof(h));
-
- WORD len = (WORD)BitRead(16);
- MARKER;
- h.rate_bound = (DWORD)BitRead(22);
- MARKER;
- h.audio_bound = (BYTE)BitRead(6);
- h.fixed_rate = !!BitRead(1);
- h.csps = !!BitRead(1);
- h.sys_audio_loc_flag = !!BitRead(1);
- h.sys_video_loc_flag = !!BitRead(1);
- MARKER;
- h.video_bound = (BYTE)BitRead(5);
-
- EXECUTE_ASSERT((BitRead(8)&0x7f) == 0x7f); // reserved (should be 0xff, but not in reality)
-
- for (len -= 6; len > 3; len -= 3) { // TODO: also store these, somewhere, if needed
- UINT64 stream_id = BitRead(8);
- UNREFERENCED_PARAMETER(stream_id);
- EXECUTE_ASSERT(BitRead(2) == 3);
- UINT64 p_std_buff_size_bound = (BitRead(1)?1024:128)*BitRead(13);
- UNREFERENCED_PARAMETER(p_std_buff_size_bound);
- }
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ WORD len = (WORD)BitRead(16);
+ MARKER;
+ h.rate_bound = (DWORD)BitRead(22);
+ MARKER;
+ h.audio_bound = (BYTE)BitRead(6);
+ h.fixed_rate = !!BitRead(1);
+ h.csps = !!BitRead(1);
+ h.sys_audio_loc_flag = !!BitRead(1);
+ h.sys_video_loc_flag = !!BitRead(1);
+ MARKER;
+ h.video_bound = (BYTE)BitRead(5);
+
+ EXECUTE_ASSERT((BitRead(8) & 0x7f) == 0x7f); // reserved (should be 0xff, but not in reality)
+
+ for (len -= 6; len > 3; len -= 3) { // TODO: also store these, somewhere, if needed
+ UINT64 stream_id = BitRead(8);
+ UNREFERENCED_PARAMETER(stream_id);
+ EXECUTE_ASSERT(BitRead(2) == 3);
+ UINT64 p_std_buff_size_bound = (BitRead(1) ? 1024 : 128) * BitRead(13);
+ UNREFERENCED_PARAMETER(p_std_buff_size_bound);
+ }
+
+ return true;
}
bool CBaseSplitterFileEx::Read(peshdr& h, BYTE code)
{
- memset(&h, 0, sizeof(h));
-
- if (!(code >= 0xbd && code < 0xf0 || code == 0xfd)) { // 0xfd => blu-ray (.m2ts)
- return false;
- }
-
- h.len = (WORD)BitRead(16);
-
- if (code == 0xbe || code == 0xbf) {
- return true;
- }
-
- // mpeg1 stuffing (ff ff .. , max 16x)
- for (int i = 0; i < 16 && BitRead(8, true) == 0xff; i++) {
- BitRead(8);
- if (h.len) {
- h.len--;
- }
- }
-
- h.type = (BYTE)BitRead(2, true) == mpeg2 ? mpeg2 : mpeg1;
-
- if (h.type == mpeg1) {
- BYTE b = (BYTE)BitRead(2);
-
- if (b == 1) {
- h.std_buff_size = (BitRead(1)?1024:128)*BitRead(13);
- if (h.len) {
- h.len -= 2;
- }
- b = (BYTE)BitRead(2);
- }
-
- if (b == 0) {
- h.fpts = (BYTE)BitRead(1);
- h.fdts = (BYTE)BitRead(1);
- }
- } else if (h.type == mpeg2) {
- EXECUTE_ASSERT(BitRead(2) == mpeg2);
- h.scrambling = (BYTE)BitRead(2);
- h.priority = (BYTE)BitRead(1);
- h.alignment = (BYTE)BitRead(1);
- h.copyright = (BYTE)BitRead(1);
- h.original = (BYTE)BitRead(1);
- h.fpts = (BYTE)BitRead(1);
- h.fdts = (BYTE)BitRead(1);
- h.escr = (BYTE)BitRead(1);
- h.esrate = (BYTE)BitRead(1);
- h.dsmtrickmode = (BYTE)BitRead(1);
- h.morecopyright = (BYTE)BitRead(1);
- h.crc = (BYTE)BitRead(1);
- h.extension = (BYTE)BitRead(1);
- h.hdrlen = (BYTE)BitRead(8);
- } else {
- if (h.len) while (h.len-- > 0) {
- BitRead(8);
- }
- return false;
- }
-
- if (h.fpts) {
- if (h.type == mpeg2) {
- BYTE b = (BYTE)BitRead(4);
- if (!(h.fdts && b == 3 || !h.fdts && b == 2)) {/*ASSERT(0); */return false;}
- }
-
- h.pts = 0;
- h.pts |= BitRead(3) << 30;
- MARKER; // 32..30
- h.pts |= BitRead(15) << 15;
- MARKER; // 29..15
- h.pts |= BitRead(15);
- MARKER; // 14..0
- h.pts = 10000*h.pts/90 + m_rtPTSOffset;
- }
-
- if (h.fdts) {
- if ((BYTE)BitRead(4) != 1) {/*ASSERT(0); */return false;}
-
- h.dts = 0;
- h.dts |= BitRead(3) << 30;
- MARKER; // 32..30
- h.dts |= BitRead(15) << 15;
- MARKER; // 29..15
- h.dts |= BitRead(15);
- MARKER; // 14..0
- h.dts = 10000*h.dts/90 + m_rtPTSOffset;
- }
-
- // skip to the end of header
-
- if (h.type == mpeg1) {
- if (!h.fpts && !h.fdts && BitRead(4) != 0xf) {
- /*ASSERT(0);*/ return false;
- }
-
- if (h.len) {
- h.len--;
- if (h.pts) {
- h.len -= 4;
- }
- if (h.dts) {
- h.len -= 5;
- }
- }
- }
-
- if (h.type == mpeg2) {
- if (h.len) {
- h.len -= 3+h.hdrlen;
- }
-
- int left = h.hdrlen;
- if (h.fpts) {
- left -= 5;
- }
- if (h.fdts) {
- left -= 5;
- }
-
- if (h.extension) { /* PES extension */
- BYTE pes_ext = (BYTE)BitRead(8);
- left--;
- BYTE skip = (pes_ext >> 4) & 0xb;
- skip += skip & 0x9;
- if (pes_ext & 0x40 || skip > left) {
- TRACE(_T("pes_ext %X is invalid\n"), pes_ext);
- pes_ext = skip = 0;
- }
- for (int i=0; i<skip; i++) {
- BitRead(8);
- }
- left -= skip;
- if (pes_ext & 0x01) { /* PES extension 2 */
- BYTE ext2_len = (BYTE)BitRead(8);
- left--;
- if ((ext2_len & 0x7f) > 0) {
- BYTE id_ext = (BYTE)BitRead(8);
- if ((id_ext & 0x80) == 0) {
- h.id_ext = id_ext;
- }
- left--;
- }
- }
- }
- while (left-- > 0) {
- BitRead(8);
- }
- }
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ if (!(code >= 0xbd && code < 0xf0 || code == 0xfd)) { // 0xfd => blu-ray (.m2ts)
+ return false;
+ }
+
+ h.len = (WORD)BitRead(16);
+
+ if (code == 0xbe || code == 0xbf) {
+ return true;
+ }
+
+ // mpeg1 stuffing (ff ff .. , max 16x)
+ for (int i = 0; i < 16 && BitRead(8, true) == 0xff; i++) {
+ BitRead(8);
+ if (h.len) {
+ h.len--;
+ }
+ }
+
+ h.type = (BYTE)BitRead(2, true) == mpeg2 ? mpeg2 : mpeg1;
+
+ if (h.type == mpeg1) {
+ BYTE b = (BYTE)BitRead(2);
+
+ if (b == 1) {
+ h.std_buff_size = (BitRead(1) ? 1024 : 128) * BitRead(13);
+ if (h.len) {
+ h.len -= 2;
+ }
+ b = (BYTE)BitRead(2);
+ }
+
+ if (b == 0) {
+ h.fpts = (BYTE)BitRead(1);
+ h.fdts = (BYTE)BitRead(1);
+ }
+ } else if (h.type == mpeg2) {
+ EXECUTE_ASSERT(BitRead(2) == mpeg2);
+ h.scrambling = (BYTE)BitRead(2);
+ h.priority = (BYTE)BitRead(1);
+ h.alignment = (BYTE)BitRead(1);
+ h.copyright = (BYTE)BitRead(1);
+ h.original = (BYTE)BitRead(1);
+ h.fpts = (BYTE)BitRead(1);
+ h.fdts = (BYTE)BitRead(1);
+ h.escr = (BYTE)BitRead(1);
+ h.esrate = (BYTE)BitRead(1);
+ h.dsmtrickmode = (BYTE)BitRead(1);
+ h.morecopyright = (BYTE)BitRead(1);
+ h.crc = (BYTE)BitRead(1);
+ h.extension = (BYTE)BitRead(1);
+ h.hdrlen = (BYTE)BitRead(8);
+ } else {
+ if (h.len) while (h.len-- > 0) {
+ BitRead(8);
+ }
+ return false;
+ }
+
+ if (h.fpts) {
+ if (h.type == mpeg2) {
+ BYTE b = (BYTE)BitRead(4);
+ if (!(h.fdts && b == 3 || !h.fdts && b == 2)) {/*ASSERT(0); */return false;}
+ }
+
+ h.pts = 0;
+ h.pts |= BitRead(3) << 30;
+ MARKER; // 32..30
+ h.pts |= BitRead(15) << 15;
+ MARKER; // 29..15
+ h.pts |= BitRead(15);
+ MARKER; // 14..0
+ h.pts = 10000 * h.pts / 90 + m_rtPTSOffset;
+ }
+
+ if (h.fdts) {
+ if ((BYTE)BitRead(4) != 1) {/*ASSERT(0); */return false;}
+
+ h.dts = 0;
+ h.dts |= BitRead(3) << 30;
+ MARKER; // 32..30
+ h.dts |= BitRead(15) << 15;
+ MARKER; // 29..15
+ h.dts |= BitRead(15);
+ MARKER; // 14..0
+ h.dts = 10000 * h.dts / 90 + m_rtPTSOffset;
+ }
+
+ // skip to the end of header
+
+ if (h.type == mpeg1) {
+ if (!h.fpts && !h.fdts && BitRead(4) != 0xf) {
+ /*ASSERT(0);*/ return false;
+ }
+
+ if (h.len) {
+ h.len--;
+ if (h.pts) {
+ h.len -= 4;
+ }
+ if (h.dts) {
+ h.len -= 5;
+ }
+ }
+ }
+
+ if (h.type == mpeg2) {
+ if (h.len) {
+ h.len -= 3 + h.hdrlen;
+ }
+
+ int left = h.hdrlen;
+ if (h.fpts) {
+ left -= 5;
+ }
+ if (h.fdts) {
+ left -= 5;
+ }
+
+ if (h.extension) { /* PES extension */
+ BYTE pes_ext = (BYTE)BitRead(8);
+ left--;
+ BYTE skip = (pes_ext >> 4) & 0xb;
+ skip += skip & 0x9;
+ if (pes_ext & 0x40 || skip > left) {
+ TRACE(_T("pes_ext %X is invalid\n"), pes_ext);
+ pes_ext = skip = 0;
+ }
+ for (int i = 0; i < skip; i++) {
+ BitRead(8);
+ }
+ left -= skip;
+ if (pes_ext & 0x01) { /* PES extension 2 */
+ BYTE ext2_len = (BYTE)BitRead(8);
+ left--;
+ if ((ext2_len & 0x7f) > 0) {
+ BYTE id_ext = (BYTE)BitRead(8);
+ if ((id_ext & 0x80) == 0) {
+ h.id_ext = id_ext;
+ }
+ left--;
+ }
+ }
+ }
+ while (left-- > 0) {
+ BitRead(8);
+ }
+ }
+
+ return true;
}
bool CBaseSplitterFileEx::Read(seqhdr& h, int len, CMediaType* pmt)
{
- __int64 endpos = GetPos() + len; // - sequence header length
-
- BYTE id = 0;
-
- while (GetPos() < endpos && id != 0xb3) {
- if (!NextMpegStartCode(id, len)) {
- return false;
- }
- }
-
- if (id != 0xb3) {
- return false;
- }
-
- __int64 shpos = GetPos() - 4;
-
- h.width = (WORD)BitRead(12);
- h.height = (WORD)BitRead(12);
- h.ar = BitRead(4);
- static int ifps[16] = {0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000, 0, 0, 0, 0, 0, 0, 0};
- h.ifps = ifps[BitRead(4)];
- h.bitrate = (DWORD)BitRead(18);
- MARKER;
- h.vbv = (DWORD)BitRead(10);
- h.constrained = BitRead(1);
-
- h.fiqm = BitRead(1);
- if (h.fiqm)
- for (int i = 0; i < _countof(h.iqm); i++) {
- h.iqm[i] = (BYTE)BitRead(8);
- }
-
- h.fniqm = BitRead(1);
- if (h.fniqm)
- for (int i = 0; i < _countof(h.niqm); i++) {
- h.niqm[i] = (BYTE)BitRead(8);
- }
-
- __int64 shlen = GetPos() - shpos;
-
- static float ar[] = {
- 1.0000f,1.0000f,0.6735f,0.7031f,0.7615f,0.8055f,0.8437f,0.8935f,
- 0.9157f,0.9815f,1.0255f,1.0695f,1.0950f,1.1575f,1.2015f,1.0000f
- };
-
- h.arx = (int)((float)h.width / ar[h.ar] + 0.5);
- h.ary = h.height;
-
- mpeg_t type = mpeg1;
-
- __int64 shextpos = 0, shextlen = 0;
-
- if (NextMpegStartCode(id, 8) && id == 0xb5) { // sequence header ext
- shextpos = GetPos() - 4;
-
- h.startcodeid = BitRead(4);
- h.profile_levelescape = BitRead(1); // reserved, should be 0
- h.profile = BitRead(3);
- h.level = BitRead(4);
- h.progressive = BitRead(1);
- h.chroma = BitRead(2);
- h.width |= (BitRead(2)<<12);
- h.height |= (BitRead(2)<<12);
- h.bitrate |= (BitRead(12)<<18);
- MARKER;
- h.vbv |= (BitRead(8)<<10);
- h.lowdelay = BitRead(1);
- h.ifps = (DWORD)(h.ifps * (BitRead(2)+1) / (BitRead(5)+1));
-
- shextlen = GetPos() - shextpos;
-
- struct {
- DWORD x, y;
- } ar[] = {{h.width,h.height},{4,3},{16,9},{221,100},{h.width,h.height}};
- int i = min(max(h.ar, 1), 5)-1;
- h.arx = ar[i].x;
- h.ary = ar[i].y;
-
- type = mpeg2;
- }
-
- h.ifps = 10 * h.ifps / 27;
- h.bitrate = h.bitrate == (1<<30)-1 ? 0 : h.bitrate * 400;
-
- DWORD a = h.arx, b = h.ary;
- while (a) {
- DWORD tmp = a;
- a = b % tmp;
- b = tmp;
- }
- if (b) {
- h.arx /= b, h.ary /= b;
- }
-
- if (!pmt) {
- return true;
- }
-
- pmt->majortype = MEDIATYPE_Video;
-
- if (type == mpeg1) {
- pmt->subtype = MEDIASUBTYPE_MPEG1Payload;
- pmt->formattype = FORMAT_MPEGVideo;
- int len = FIELD_OFFSET(MPEG1VIDEOINFO, bSequenceHeader) + int(shlen + shextlen);
- MPEG1VIDEOINFO* vi = (MPEG1VIDEOINFO*)DNew BYTE[len];
- memset(vi, 0, len);
- vi->hdr.dwBitRate = h.bitrate;
- vi->hdr.AvgTimePerFrame = h.ifps;
- vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
- vi->hdr.bmiHeader.biWidth = h.width;
- vi->hdr.bmiHeader.biHeight = h.height;
- vi->hdr.bmiHeader.biXPelsPerMeter = h.width * h.ary;
- vi->hdr.bmiHeader.biYPelsPerMeter = h.height * h.arx;
- vi->cbSequenceHeader = DWORD(shlen + shextlen);
- Seek(shpos);
- ByteRead((BYTE*)&vi->bSequenceHeader[0], shlen);
- if (shextpos && shextlen) {
- Seek(shextpos);
- }
- ByteRead((BYTE*)&vi->bSequenceHeader[0] + shlen, shextlen);
- pmt->SetFormat((BYTE*)vi, len);
- delete [] vi;
- } else if (type == mpeg2) {
- pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
- pmt->formattype = FORMAT_MPEG2_VIDEO;
- int len = FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + int(shlen + shextlen);
- MPEG2VIDEOINFO* vi = (MPEG2VIDEOINFO*)DNew BYTE[len];
- memset(vi, 0, len);
- vi->hdr.dwBitRate = h.bitrate;
- vi->hdr.AvgTimePerFrame = h.ifps;
- vi->hdr.dwPictAspectRatioX = h.arx;
- vi->hdr.dwPictAspectRatioY = h.ary;
- vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
- vi->hdr.bmiHeader.biWidth = h.width;
- vi->hdr.bmiHeader.biHeight = h.height;
- vi->dwProfile = h.profile;
- vi->dwLevel = h.level;
- vi->cbSequenceHeader = DWORD(shlen + shextlen);
- Seek(shpos);
- ByteRead((BYTE*)&vi->dwSequenceHeader[0], shlen);
- if (shextpos && shextlen) {
- Seek(shextpos);
- }
- ByteRead((BYTE*)&vi->dwSequenceHeader[0] + shlen, shextlen);
- pmt->SetFormat((BYTE*)vi, len);
- delete [] vi;
- } else {
- return false;
- }
-
- return true;
+ __int64 endpos = GetPos() + len; // - sequence header length
+
+ BYTE id = 0;
+
+ while (GetPos() < endpos && id != 0xb3) {
+ if (!NextMpegStartCode(id, len)) {
+ return false;
+ }
+ }
+
+ if (id != 0xb3) {
+ return false;
+ }
+
+ __int64 shpos = GetPos() - 4;
+
+ h.width = (WORD)BitRead(12);
+ h.height = (WORD)BitRead(12);
+ h.ar = BitRead(4);
+ static int ifps[16] = {0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000, 0, 0, 0, 0, 0, 0, 0};
+ h.ifps = ifps[BitRead(4)];
+ h.bitrate = (DWORD)BitRead(18);
+ MARKER;
+ h.vbv = (DWORD)BitRead(10);
+ h.constrained = BitRead(1);
+
+ h.fiqm = BitRead(1);
+ if (h.fiqm)
+ for (int i = 0; i < _countof(h.iqm); i++) {
+ h.iqm[i] = (BYTE)BitRead(8);
+ }
+
+ h.fniqm = BitRead(1);
+ if (h.fniqm)
+ for (int i = 0; i < _countof(h.niqm); i++) {
+ h.niqm[i] = (BYTE)BitRead(8);
+ }
+
+ __int64 shlen = GetPos() - shpos;
+
+ static float ar[] = {
+ 1.0000f, 1.0000f, 0.6735f, 0.7031f, 0.7615f, 0.8055f, 0.8437f, 0.8935f,
+ 0.9157f, 0.9815f, 1.0255f, 1.0695f, 1.0950f, 1.1575f, 1.2015f, 1.0000f
+ };
+
+ h.arx = (int)((float)h.width / ar[h.ar] + 0.5);
+ h.ary = h.height;
+
+ mpeg_t type = mpeg1;
+
+ __int64 shextpos = 0, shextlen = 0;
+
+ if (NextMpegStartCode(id, 8) && id == 0xb5) { // sequence header ext
+ shextpos = GetPos() - 4;
+
+ h.startcodeid = BitRead(4);
+ h.profile_levelescape = BitRead(1); // reserved, should be 0
+ h.profile = BitRead(3);
+ h.level = BitRead(4);
+ h.progressive = BitRead(1);
+ h.chroma = BitRead(2);
+ h.width |= (BitRead(2) << 12);
+ h.height |= (BitRead(2) << 12);
+ h.bitrate |= (BitRead(12) << 18);
+ MARKER;
+ h.vbv |= (BitRead(8) << 10);
+ h.lowdelay = BitRead(1);
+ h.ifps = (DWORD)(h.ifps * (BitRead(2) + 1) / (BitRead(5) + 1));
+
+ shextlen = GetPos() - shextpos;
+
+ struct {
+ DWORD x, y;
+ } ar[] = {{h.width, h.height}, {4, 3}, {16, 9}, {221, 100}, {h.width, h.height}};
+ int i = min(max(h.ar, 1), 5) - 1;
+ h.arx = ar[i].x;
+ h.ary = ar[i].y;
+
+ type = mpeg2;
+ }
+
+ h.ifps = 10 * h.ifps / 27;
+ h.bitrate = h.bitrate == (1 << 30) - 1 ? 0 : h.bitrate * 400;
+
+ DWORD a = h.arx, b = h.ary;
+ while (a) {
+ DWORD tmp = a;
+ a = b % tmp;
+ b = tmp;
+ }
+ if (b) {
+ h.arx /= b, h.ary /= b;
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ pmt->majortype = MEDIATYPE_Video;
+
+ if (type == mpeg1) {
+ pmt->subtype = MEDIASUBTYPE_MPEG1Payload;
+ pmt->formattype = FORMAT_MPEGVideo;
+ int len = FIELD_OFFSET(MPEG1VIDEOINFO, bSequenceHeader) + int(shlen + shextlen);
+ MPEG1VIDEOINFO* vi = (MPEG1VIDEOINFO*)DNew BYTE[len];
+ memset(vi, 0, len);
+ vi->hdr.dwBitRate = h.bitrate;
+ vi->hdr.AvgTimePerFrame = h.ifps;
+ vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
+ vi->hdr.bmiHeader.biWidth = h.width;
+ vi->hdr.bmiHeader.biHeight = h.height;
+ vi->hdr.bmiHeader.biXPelsPerMeter = h.width * h.ary;
+ vi->hdr.bmiHeader.biYPelsPerMeter = h.height * h.arx;
+ vi->cbSequenceHeader = DWORD(shlen + shextlen);
+ Seek(shpos);
+ ByteRead((BYTE*)&vi->bSequenceHeader[0], shlen);
+ if (shextpos && shextlen) {
+ Seek(shextpos);
+ }
+ ByteRead((BYTE*)&vi->bSequenceHeader[0] + shlen, shextlen);
+ pmt->SetFormat((BYTE*)vi, len);
+ delete [] vi;
+ } else if (type == mpeg2) {
+ pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
+ pmt->formattype = FORMAT_MPEG2_VIDEO;
+ int len = FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + int(shlen + shextlen);
+ MPEG2VIDEOINFO* vi = (MPEG2VIDEOINFO*)DNew BYTE[len];
+ memset(vi, 0, len);
+ vi->hdr.dwBitRate = h.bitrate;
+ vi->hdr.AvgTimePerFrame = h.ifps;
+ vi->hdr.dwPictAspectRatioX = h.arx;
+ vi->hdr.dwPictAspectRatioY = h.ary;
+ vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
+ vi->hdr.bmiHeader.biWidth = h.width;
+ vi->hdr.bmiHeader.biHeight = h.height;
+ vi->dwProfile = h.profile;
+ vi->dwLevel = h.level;
+ vi->cbSequenceHeader = DWORD(shlen + shextlen);
+ Seek(shpos);
+ ByteRead((BYTE*)&vi->dwSequenceHeader[0], shlen);
+ if (shextpos && shextlen) {
+ Seek(shextpos);
+ }
+ ByteRead((BYTE*)&vi->dwSequenceHeader[0] + shlen, shextlen);
+ pmt->SetFormat((BYTE*)vi, len);
+ delete [] vi;
+ } else {
+ return false;
+ }
+
+ return true;
}
bool CBaseSplitterFileEx::Read(mpahdr& h, int len, bool fAllowV25, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
-
- int syncbits = fAllowV25 ? 11 : 12;
-
- for (; len >= 4 && BitRead(syncbits, true) != (1<<syncbits) - 1; len--) {
- BitRead(8);
- }
-
- if (len < 4) {
- return false;
- }
-
- h.sync = BitRead(11);
- h.version = BitRead(2);
- h.layer = BitRead(2);
- h.crc = BitRead(1);
- h.bitrate = BitRead(4);
- h.freq = BitRead(2);
- h.padding = BitRead(1);
- h.privatebit = BitRead(1);
- h.channels = BitRead(2);
- h.modeext = BitRead(2);
- h.copyright = BitRead(1);
- h.original = BitRead(1);
- h.emphasis = BitRead(2);
-
- if (h.version == 1 || h.layer == 0 || h.freq == 3 || h.bitrate == 15 || h.emphasis == 2) {
- return false;
- }
-
- if (h.version == 3 && h.layer == 2) {
- if ((h.bitrate == 1 || h.bitrate == 2 || h.bitrate == 3 || h.bitrate == 5) && h.channels != 3
- && (h.bitrate >= 11 && h.bitrate <= 14) && h.channels == 3) {
- return false;
- }
- }
-
- h.layer = 4 - h.layer;
-
- //
-
- static int brtbl[][5] = {
- {0,0,0,0,0},
- {32,32,32,32,8},
- {64,48,40,48,16},
- {96,56,48,56,24},
- {128,64,56,64,32},
- {160,80,64,80,40},
- {192,96,80,96,48},
- {224,112,96,112,56},
- {256,128,112,128,64},
- {288,160,128,144,80},
- {320,192,160,160,96},
- {352,224,192,176,112},
- {384,256,224,192,128},
- {416,320,256,224,144},
- {448,384,320,256,160},
- {0,0,0,0,0},
- };
-
- static int brtblcol[][4] = {{0,3,4,4},{0,0,1,2}};
- int bitrate = 1000*brtbl[h.bitrate][brtblcol[h.version&1][h.layer]];
- if (bitrate == 0) {
- return false;
- }
-
- static int freq[][4] = {{11025,0,22050,44100},{12000,0,24000,48000},{8000,0,16000,32000}};
-
- bool l3ext = h.layer == 3 && !(h.version&1);
-
- h.nSamplesPerSec = freq[h.freq][h.version];
- h.FrameSize = h.layer == 1
- ? (12 * bitrate / h.nSamplesPerSec + h.padding) * 4
- : (l3ext ? 72 : 144) * bitrate / h.nSamplesPerSec + h.padding;
- h.rtDuration = 10000000i64 * (h.layer == 1 ? 384 : l3ext ? 576 : 1152) / h.nSamplesPerSec;// / (h.channels == 3 ? 1 : 2);
- h.nBytesPerSec = bitrate / 8;
-
- if (!pmt) {
- return true;
- }
-
- size_t size = h.layer == 3
- ? sizeof(WAVEFORMATEX/*MPEGLAYER3WAVEFORMAT*/) // no need to overcomplicate this...
- : sizeof(MPEG1WAVEFORMAT);
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)DNew BYTE[size];
- memset(wfe, 0, size);
- wfe->cbSize = WORD(size - sizeof(WAVEFORMATEX));
-
- if (h.layer == 3) {
- wfe->wFormatTag = WAVE_FORMAT_MP3;
-
- /* MPEGLAYER3WAVEFORMAT* f = (MPEGLAYER3WAVEFORMAT*)wfe;
- f->wfx.wFormatTag = WAVE_FORMAT_MP3;
- f->wID = MPEGLAYER3_ID_UNKNOWN;
- f->fdwFlags = h.padding ? MPEGLAYER3_FLAG_PADDING_ON : MPEGLAYER3_FLAG_PADDING_OFF; // _OFF or _ISO ?
- */
- } else {
- MPEG1WAVEFORMAT* f = (MPEG1WAVEFORMAT*)wfe;
- f->wfx.wFormatTag = WAVE_FORMAT_MPEG;
- f->fwHeadMode = 1 << h.channels;
- f->fwHeadModeExt = 1 << h.modeext;
- f->wHeadEmphasis = h.emphasis+1;
- if (h.privatebit) {
- f->fwHeadFlags |= ACM_MPEG_PRIVATEBIT;
- }
- if (h.copyright) {
- f->fwHeadFlags |= ACM_MPEG_COPYRIGHT;
- }
- if (h.original) {
- f->fwHeadFlags |= ACM_MPEG_ORIGINALHOME;
- }
- if (h.crc == 0) {
- f->fwHeadFlags |= ACM_MPEG_PROTECTIONBIT;
- }
- if (h.version == 3) {
- f->fwHeadFlags |= ACM_MPEG_ID_MPEG1;
- }
- f->fwHeadLayer = 1 << (h.layer-1);
- f->dwHeadBitrate = bitrate;
- }
-
- wfe->nChannels = h.channels == 3 ? 1 : 2;
- wfe->nSamplesPerSec = h.nSamplesPerSec;
- wfe->nBlockAlign = h.FrameSize;
- wfe->nAvgBytesPerSec = h.nBytesPerSec;
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = FOURCCMap(wfe->wFormatTag);
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)wfe, sizeof(WAVEFORMATEX) + wfe->cbSize);
-
- delete [] wfe;
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ int syncbits = fAllowV25 ? 11 : 12;
+
+ for (; len >= 4 && BitRead(syncbits, true) != (1 << syncbits) - 1; len--) {
+ BitRead(8);
+ }
+
+ if (len < 4) {
+ return false;
+ }
+
+ h.sync = BitRead(11);
+ h.version = BitRead(2);
+ h.layer = BitRead(2);
+ h.crc = BitRead(1);
+ h.bitrate = BitRead(4);
+ h.freq = BitRead(2);
+ h.padding = BitRead(1);
+ h.privatebit = BitRead(1);
+ h.channels = BitRead(2);
+ h.modeext = BitRead(2);
+ h.copyright = BitRead(1);
+ h.original = BitRead(1);
+ h.emphasis = BitRead(2);
+
+ if (h.version == 1 || h.layer == 0 || h.freq == 3 || h.bitrate == 15 || h.emphasis == 2) {
+ return false;
+ }
+
+ if (h.version == 3 && h.layer == 2) {
+ if ((h.bitrate == 1 || h.bitrate == 2 || h.bitrate == 3 || h.bitrate == 5) && h.channels != 3
+ && (h.bitrate >= 11 && h.bitrate <= 14) && h.channels == 3) {
+ return false;
+ }
+ }
+
+ h.layer = 4 - h.layer;
+
+ //
+
+ static int brtbl[][5] = {
+ {0, 0, 0, 0, 0},
+ {32, 32, 32, 32, 8},
+ {64, 48, 40, 48, 16},
+ {96, 56, 48, 56, 24},
+ {128, 64, 56, 64, 32},
+ {160, 80, 64, 80, 40},
+ {192, 96, 80, 96, 48},
+ {224, 112, 96, 112, 56},
+ {256, 128, 112, 128, 64},
+ {288, 160, 128, 144, 80},
+ {320, 192, 160, 160, 96},
+ {352, 224, 192, 176, 112},
+ {384, 256, 224, 192, 128},
+ {416, 320, 256, 224, 144},
+ {448, 384, 320, 256, 160},
+ {0, 0, 0, 0, 0},
+ };
+
+ static int brtblcol[][4] = {{0, 3, 4, 4}, {0, 0, 1, 2}};
+ int bitrate = 1000 * brtbl[h.bitrate][brtblcol[h.version & 1][h.layer]];
+ if (bitrate == 0) {
+ return false;
+ }
+
+ static int freq[][4] = {{11025, 0, 22050, 44100}, {12000, 0, 24000, 48000}, {8000, 0, 16000, 32000}};
+
+ bool l3ext = h.layer == 3 && !(h.version & 1);
+
+ h.nSamplesPerSec = freq[h.freq][h.version];
+ h.FrameSize = h.layer == 1
+ ? (12 * bitrate / h.nSamplesPerSec + h.padding) * 4
+ : (l3ext ? 72 : 144) * bitrate / h.nSamplesPerSec + h.padding;
+ h.rtDuration = 10000000i64 * (h.layer == 1 ? 384 : l3ext ? 576 : 1152) / h.nSamplesPerSec;// / (h.channels == 3 ? 1 : 2);
+ h.nBytesPerSec = bitrate / 8;
+
+ if (!pmt) {
+ return true;
+ }
+
+ size_t size = h.layer == 3
+ ? sizeof(WAVEFORMATEX/*MPEGLAYER3WAVEFORMAT*/) // no need to overcomplicate this...
+ : sizeof(MPEG1WAVEFORMAT);
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)DNew BYTE[size];
+ memset(wfe, 0, size);
+ wfe->cbSize = WORD(size - sizeof(WAVEFORMATEX));
+
+ if (h.layer == 3) {
+ wfe->wFormatTag = WAVE_FORMAT_MP3;
+
+ /* MPEGLAYER3WAVEFORMAT* f = (MPEGLAYER3WAVEFORMAT*)wfe;
+ f->wfx.wFormatTag = WAVE_FORMAT_MP3;
+ f->wID = MPEGLAYER3_ID_UNKNOWN;
+ f->fdwFlags = h.padding ? MPEGLAYER3_FLAG_PADDING_ON : MPEGLAYER3_FLAG_PADDING_OFF; // _OFF or _ISO ?
+ */
+ } else {
+ MPEG1WAVEFORMAT* f = (MPEG1WAVEFORMAT*)wfe;
+ f->wfx.wFormatTag = WAVE_FORMAT_MPEG;
+ f->fwHeadMode = 1 << h.channels;
+ f->fwHeadModeExt = 1 << h.modeext;
+ f->wHeadEmphasis = h.emphasis + 1;
+ if (h.privatebit) {
+ f->fwHeadFlags |= ACM_MPEG_PRIVATEBIT;
+ }
+ if (h.copyright) {
+ f->fwHeadFlags |= ACM_MPEG_COPYRIGHT;
+ }
+ if (h.original) {
+ f->fwHeadFlags |= ACM_MPEG_ORIGINALHOME;
+ }
+ if (h.crc == 0) {
+ f->fwHeadFlags |= ACM_MPEG_PROTECTIONBIT;
+ }
+ if (h.version == 3) {
+ f->fwHeadFlags |= ACM_MPEG_ID_MPEG1;
+ }
+ f->fwHeadLayer = 1 << (h.layer - 1);
+ f->dwHeadBitrate = bitrate;
+ }
+
+ wfe->nChannels = h.channels == 3 ? 1 : 2;
+ wfe->nSamplesPerSec = h.nSamplesPerSec;
+ wfe->nBlockAlign = h.FrameSize;
+ wfe->nAvgBytesPerSec = h.nBytesPerSec;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = FOURCCMap(wfe->wFormatTag);
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)wfe, sizeof(WAVEFORMATEX) + wfe->cbSize);
+
+ delete [] wfe;
+
+ return true;
}
bool CBaseSplitterFileEx::Read(latm_aachdr& h, int len, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- for (; len >= 3 && BitRead(11, true) != 0x2b7; len--) {
- BitRead(8);
- }
+ for (; len >= 3 && BitRead(11, true) != 0x2b7; len--) {
+ BitRead(8);
+ }
- if (len < 3) {
- return false;
- }
+ if (len < 3) {
+ return false;
+ }
- // Disable AAC latm stream support until make correct header parsing ...
- return true;
+ // Disable AAC latm stream support until make correct header parsing ...
+ return true;
}
bool CBaseSplitterFileEx::Read(aachdr& h, int len, CMediaType* pmt, MPEG_TYPES m_type)
{
- memset(&h, 0, sizeof(h));
-
- __int64 pos = 0;
- int found_fake_sync = m_type == mpeg_ts ? 0 : 1;
-
- for (;;) {
- for (; len >= 7 && BitRead(12, true) != 0xfff; len--) {
- BitRead(8);
- }
-
- if (len < 7) {
- return false;
- }
-
- pos = GetPos();
-
- h.sync = BitRead(12);
- h.version = BitRead(1);
- h.layer = BitRead(2);
- h.fcrc = BitRead(1);
- h.profile = BitRead(2);
- h.freq = BitRead(4);
- h.privatebit = BitRead(1);
- h.channels = BitRead(3);
- h.original = BitRead(1);
- h.home = BitRead(1);
-
- h.copyright_id_bit = BitRead(1);
- h.copyright_id_start = BitRead(1);
- h.aac_frame_length = BitRead(13);
- h.adts_buffer_fullness = BitRead(11);
- h.no_raw_data_blocks_in_frame = BitRead(2);
-
- if (h.fcrc == 0) {
- h.crc = (WORD)BitRead(16);
- }
-
- if (h.layer != 0 || h.freq >= 12 || h.aac_frame_length <= (h.fcrc == 0 ? 9 : 7)) {
- if (found_fake_sync) // skip only one "fake" sync. TODO - find better way to detect and skip "fake" sync
- return false;
- found_fake_sync++;
- Seek(pos + 1);
- len--;
- continue;
- }
-
- h.FrameSize = h.aac_frame_length - (h.fcrc == 0 ? 9 : 7);
- static int freq[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
- h.nBytesPerSec = h.aac_frame_length * freq[h.freq] / 1024; // ok?
- h.rtDuration = 10000000i64 * 1024 / freq[h.freq]; // ok?
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)DNew BYTE[sizeof(WAVEFORMATEX)+5];
- memset(wfe, 0, sizeof(WAVEFORMATEX)+5);
- wfe->wFormatTag = WAVE_FORMAT_AAC;
- wfe->nChannels = h.channels <= 6 ? h.channels : 2;
- wfe->nSamplesPerSec = freq[h.freq];
- wfe->nBlockAlign = h.aac_frame_length;
- wfe->nAvgBytesPerSec = h.nBytesPerSec;
- wfe->cbSize = MakeAACInitData((BYTE*)(wfe+1), h.profile, wfe->nSamplesPerSec, wfe->nChannels);
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_AAC;
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)wfe, sizeof(WAVEFORMATEX)+wfe->cbSize);
-
- delete [] wfe;
-
- return true;
- }
+ memset(&h, 0, sizeof(h));
+
+ __int64 pos = 0;
+ int found_fake_sync = m_type == mpeg_ts ? 0 : 1;
+
+ for (;;) {
+ for (; len >= 7 && BitRead(12, true) != 0xfff; len--) {
+ BitRead(8);
+ }
+
+ if (len < 7) {
+ return false;
+ }
+
+ pos = GetPos();
+
+ h.sync = BitRead(12);
+ h.version = BitRead(1);
+ h.layer = BitRead(2);
+ h.fcrc = BitRead(1);
+ h.profile = BitRead(2);
+ h.freq = BitRead(4);
+ h.privatebit = BitRead(1);
+ h.channels = BitRead(3);
+ h.original = BitRead(1);
+ h.home = BitRead(1);
+
+ h.copyright_id_bit = BitRead(1);
+ h.copyright_id_start = BitRead(1);
+ h.aac_frame_length = BitRead(13);
+ h.adts_buffer_fullness = BitRead(11);
+ h.no_raw_data_blocks_in_frame = BitRead(2);
+
+ if (h.fcrc == 0) {
+ h.crc = (WORD)BitRead(16);
+ }
+
+ if (h.layer != 0 || h.freq >= 12 || h.aac_frame_length <= (h.fcrc == 0 ? 9 : 7)) {
+ if (found_fake_sync) { // skip only one "fake" sync. TODO - find better way to detect and skip "fake" sync
+ return false;
+ }
+ found_fake_sync++;
+ Seek(pos + 1);
+ len--;
+ continue;
+ }
+
+ h.FrameSize = h.aac_frame_length - (h.fcrc == 0 ? 9 : 7);
+ static int freq[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
+ h.nBytesPerSec = h.aac_frame_length * freq[h.freq] / 1024; // ok?
+ h.rtDuration = 10000000i64 * 1024 / freq[h.freq]; // ok?
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)DNew BYTE[sizeof(WAVEFORMATEX) + 5];
+ memset(wfe, 0, sizeof(WAVEFORMATEX) + 5);
+ wfe->wFormatTag = WAVE_FORMAT_AAC;
+ wfe->nChannels = h.channels <= 6 ? h.channels : 2;
+ wfe->nSamplesPerSec = freq[h.freq];
+ wfe->nBlockAlign = h.aac_frame_length;
+ wfe->nAvgBytesPerSec = h.nBytesPerSec;
+ wfe->cbSize = MakeAACInitData((BYTE*)(wfe + 1), h.profile, wfe->nSamplesPerSec, wfe->nChannels);
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_AAC;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)wfe, sizeof(WAVEFORMATEX) + wfe->cbSize);
+
+ delete [] wfe;
+
+ return true;
+ }
}
bool CBaseSplitterFileEx::Read(ac3hdr& h, int len, CMediaType* pmt, bool find_sync, bool AC3CoreOnly)
{
- static int freq[] = {48000, 44100, 32000, 0};
-
- bool e_ac3 = false;
-
- __int64 startpos = GetPos();
-
- memset(&h, 0, sizeof(h));
-
- // Parse TrueHD and MLP header
- if (!AC3CoreOnly) {
- BYTE buf[20];
- int channels;
- int samplerate;
- int framelength;
- WORD bitdepth;
- bool isTrueHD;
-
- int fsize = 0;
- ByteRead(buf, 20);
-
- fsize = ParseMLPHeader(buf, &samplerate, &channels, &framelength, &bitdepth, &isTrueHD);
- if (fsize) {
-
- if (!pmt) {
- return true;
- }
-
- int bitrate = (int)(fsize * 8i64 * samplerate / framelength); // inaccurate, because fsize is not constant
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = isTrueHD ? MEDIASUBTYPE_DOLBY_TRUEHD : MEDIASUBTYPE_MLP;
- pmt->formattype = FORMAT_WaveFormatEx;
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));
- wfe->wFormatTag = WAVE_FORMAT_UNKNOWN;
- wfe->nChannels = channels;
- wfe->nSamplesPerSec = samplerate;
- wfe->nAvgBytesPerSec = (bitrate + 4) /8;
- wfe->nBlockAlign = fsize < WORD_MAX ? fsize : WORD_MAX;
- wfe->wBitsPerSample = bitdepth;
- wfe->cbSize = 0;
-
- pmt->SetSampleSize(0);
-
- return true;
- }
- }
-
- Seek(startpos);
-
- if (find_sync) {
- for (; len >= 7 && BitRead(16, true) != 0x0b77; len--) {
- BitRead(8);
- }
- }
-
- if (len < 7) {
- return false;
- }
-
- h.sync = (WORD)BitRead(16);
- if (h.sync != 0x0B77) {
- return false;
- }
-
- _int64 pos = GetPos();
- h.crc1 = (WORD)BitRead(16);
- h.fscod = BitRead(2);
- h.frmsizecod = BitRead(6);
- h.bsid = BitRead(5);
- if (h.bsid > 16) {
- return false;
- }
- if (h.bsid <= 10) {
- /* Normal AC-3 */
- if (h.fscod == 3) {
- return false;
- }
- if (h.frmsizecod > 37) {
- return false;
- }
- h.bsmod = BitRead(3);
- h.acmod = BitRead(3);
- if (h.acmod == 2) {
- h.dsurmod = BitRead(2);
- }
- if ((h.acmod & 1) && h.acmod != 1) {
- h.cmixlev = BitRead(2);
- }
- if (h.acmod & 4) {
- h.surmixlev = BitRead(2);
- }
- h.lfeon = BitRead(1);
- h.sr_shift = max(h.bsid, 8) - 8;
- } else {
- /* Enhanced AC-3 */
- e_ac3 = true;
- Seek(pos);
- h.frame_type = (BYTE)BitRead(2);
- h.substreamid = (BYTE)BitRead(3);
- if (h.frame_type || h.substreamid) {
- return false;
- }
- h.frame_size = ((WORD)BitRead(11) + 1) << 1;
- if (h.frame_size < 7) {
- return false;
- }
- h.sr_code = (BYTE)BitRead(2);
- if (h.sr_code == 3) {
- BYTE sr_code2 = (BYTE)BitRead(2);
- if (sr_code2 == 3) {
- return false;
- }
- h.sample_rate = freq[sr_code2] / 2;
- h.sr_shift = 1;
- } else {
- static int eac3_blocks[4] = {1, 2, 3, 6};
- h.num_blocks = eac3_blocks[BitRead(2)];
- h.sample_rate = freq[h.sr_code];
- h.sr_shift = 0;
- }
- h.acmod = BitRead(3);
- h.lfeon = BitRead(1);
- }
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEX wfe;
- memset(&wfe, 0, sizeof(wfe));
- wfe.wFormatTag = WAVE_FORMAT_DOLBY_AC3;
-
- static int channels[] = {2, 1, 2, 3, 3, 4, 4, 5};
- wfe.nChannels = channels[h.acmod] + h.lfeon;
-
- if (!e_ac3) {
- wfe.nSamplesPerSec = freq[h.fscod] >> h.sr_shift;
- static int rate[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 768, 896, 1024, 1152, 1280};
- wfe.nAvgBytesPerSec = ((rate[h.frmsizecod>>1] * 1000) >> h.sr_shift) / 8;
- } else {
- wfe.nSamplesPerSec = h.sample_rate;
- wfe.nAvgBytesPerSec = h.frame_size * h.sample_rate / (h.num_blocks * 256);
- }
-
- wfe.nBlockAlign = (WORD)(1536 * wfe.nAvgBytesPerSec / wfe.nSamplesPerSec);
-
- pmt->majortype = MEDIATYPE_Audio;
- if (e_ac3) {
- pmt->subtype = MEDIASUBTYPE_DOLBY_DDPLUS;
- } else {
- pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
- }
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
-
- return true;
+ static int freq[] = {48000, 44100, 32000, 0};
+
+ bool e_ac3 = false;
+
+ __int64 startpos = GetPos();
+
+ memset(&h, 0, sizeof(h));
+
+ // Parse TrueHD and MLP header
+ if (!AC3CoreOnly) {
+ BYTE buf[20];
+ int channels;
+ int samplerate;
+ int framelength;
+ WORD bitdepth;
+ bool isTrueHD;
+
+ int fsize = 0;
+ ByteRead(buf, 20);
+
+ fsize = ParseMLPHeader(buf, &samplerate, &channels, &framelength, &bitdepth, &isTrueHD);
+ if (fsize) {
+
+ if (!pmt) {
+ return true;
+ }
+
+ int bitrate = (int)(fsize * 8i64 * samplerate / framelength); // inaccurate, because fsize is not constant
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = isTrueHD ? MEDIASUBTYPE_DOLBY_TRUEHD : MEDIASUBTYPE_MLP;
+ pmt->formattype = FORMAT_WaveFormatEx;
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));
+ wfe->wFormatTag = WAVE_FORMAT_UNKNOWN;
+ wfe->nChannels = channels;
+ wfe->nSamplesPerSec = samplerate;
+ wfe->nAvgBytesPerSec = (bitrate + 4) / 8;
+ wfe->nBlockAlign = fsize < WORD_MAX ? fsize : WORD_MAX;
+ wfe->wBitsPerSample = bitdepth;
+ wfe->cbSize = 0;
+
+ pmt->SetSampleSize(0);
+
+ return true;
+ }
+ }
+
+ Seek(startpos);
+
+ if (find_sync) {
+ for (; len >= 7 && BitRead(16, true) != 0x0b77; len--) {
+ BitRead(8);
+ }
+ }
+
+ if (len < 7) {
+ return false;
+ }
+
+ h.sync = (WORD)BitRead(16);
+ if (h.sync != 0x0B77) {
+ return false;
+ }
+
+ _int64 pos = GetPos();
+ h.crc1 = (WORD)BitRead(16);
+ h.fscod = BitRead(2);
+ h.frmsizecod = BitRead(6);
+ h.bsid = BitRead(5);
+ if (h.bsid > 16) {
+ return false;
+ }
+ if (h.bsid <= 10) {
+ /* Normal AC-3 */
+ if (h.fscod == 3) {
+ return false;
+ }
+ if (h.frmsizecod > 37) {
+ return false;
+ }
+ h.bsmod = BitRead(3);
+ h.acmod = BitRead(3);
+ if (h.acmod == 2) {
+ h.dsurmod = BitRead(2);
+ }
+ if ((h.acmod & 1) && h.acmod != 1) {
+ h.cmixlev = BitRead(2);
+ }
+ if (h.acmod & 4) {
+ h.surmixlev = BitRead(2);
+ }
+ h.lfeon = BitRead(1);
+ h.sr_shift = max(h.bsid, 8) - 8;
+ } else {
+ /* Enhanced AC-3 */
+ e_ac3 = true;
+ Seek(pos);
+ h.frame_type = (BYTE)BitRead(2);
+ h.substreamid = (BYTE)BitRead(3);
+ if (h.frame_type || h.substreamid) {
+ return false;
+ }
+ h.frame_size = ((WORD)BitRead(11) + 1) << 1;
+ if (h.frame_size < 7) {
+ return false;
+ }
+ h.sr_code = (BYTE)BitRead(2);
+ if (h.sr_code == 3) {
+ BYTE sr_code2 = (BYTE)BitRead(2);
+ if (sr_code2 == 3) {
+ return false;
+ }
+ h.sample_rate = freq[sr_code2] / 2;
+ h.sr_shift = 1;
+ } else {
+ static int eac3_blocks[4] = {1, 2, 3, 6};
+ h.num_blocks = eac3_blocks[BitRead(2)];
+ h.sample_rate = freq[h.sr_code];
+ h.sr_shift = 0;
+ }
+ h.acmod = BitRead(3);
+ h.lfeon = BitRead(1);
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX wfe;
+ memset(&wfe, 0, sizeof(wfe));
+ wfe.wFormatTag = WAVE_FORMAT_DOLBY_AC3;
+
+ static int channels[] = {2, 1, 2, 3, 3, 4, 4, 5};
+ wfe.nChannels = channels[h.acmod] + h.lfeon;
+
+ if (!e_ac3) {
+ wfe.nSamplesPerSec = freq[h.fscod] >> h.sr_shift;
+ static int rate[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 768, 896, 1024, 1152, 1280};
+ wfe.nAvgBytesPerSec = ((rate[h.frmsizecod >> 1] * 1000) >> h.sr_shift) / 8;
+ } else {
+ wfe.nSamplesPerSec = h.sample_rate;
+ wfe.nAvgBytesPerSec = h.frame_size * h.sample_rate / (h.num_blocks * 256);
+ }
+
+ wfe.nBlockAlign = (WORD)(1536 * wfe.nAvgBytesPerSec / wfe.nSamplesPerSec);
+
+ pmt->majortype = MEDIATYPE_Audio;
+ if (e_ac3) {
+ pmt->subtype = MEDIASUBTYPE_DOLBY_DDPLUS;
+ } else {
+ pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
+ }
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+
+ return true;
}
bool CBaseSplitterFileEx::Read(dtshdr& h, int len, CMediaType* pmt, bool find_sync)
{
- memset(&h, 0, sizeof(h));
-
- if (find_sync) {
- for (; len >= 10 && BitRead(32, true) != 0x7ffe8001; len--) {
- BitRead(8);
- }
- }
-
- if (len < 10) {
- return false;
- }
-
- h.sync = (DWORD)BitRead(32);
- if (h.sync != 0x7ffe8001) {
- return false;
- }
-
- h.frametype = BitRead(1);
- h.deficitsamplecount = BitRead(5);
- h.fcrc = BitRead(1);
- h.nblocks = BitRead(7)+1;
- h.framebytes = (WORD)BitRead(14)+1;
- h.amode = BitRead(6);
- h.sfreq = BitRead(4);
- h.rate = BitRead(5);
-
- h.downmix = BitRead(1);
- h.dynrange = BitRead(1);
- h.timestamp = BitRead(1);
- h.aux_data = BitRead(1);
- h.hdcd = BitRead(1);
- h.ext_descr = BitRead(3);
- h.ext_coding = BitRead(1);
- h.aspf = BitRead(1);
- h.lfe = BitRead(2);
- h.predictor_history = BitRead(1);
-
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEX wfe;
- memset(&wfe, 0, sizeof(wfe));
- wfe.wFormatTag = WAVE_FORMAT_DVD_DTS;
-
- static int channels[] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8};
-
- if (h.amode < _countof(channels)) {
- wfe.nChannels = channels[h.amode];
- if (h.lfe > 0) {
- ++wfe.nChannels;
- }
- }
-
- static int freq[] = {0,8000,16000,32000,0,0,11025,22050,44100,0,0,12000,24000,48000,0,0};
- wfe.nSamplesPerSec = freq[h.sfreq];
-
- /*static int rate[] = {
- 32000, 56000, 64000, 96000,
- 112000, 128000, 192000, 224000,
- 256000, 320000, 384000, 448000,
- 512000, 576000, 640000, 768000,
- 960000, 1024000, 1152000, 1280000,
- 1344000, 1408000, 1411200, 1472000,
- 1536000, 1920000, 2048000, 3072000,
- 3840000, 0, 0, 0 //open, variable, lossless
- };
- int nom_bitrate = rate[h.rate];*/
-
- unsigned int bitrate = (unsigned int)(8ui64 * h.framebytes * wfe.nSamplesPerSec / (h.nblocks*32));
-
- wfe.nAvgBytesPerSec = (bitrate + 4) / 8;
- wfe.nBlockAlign = h.framebytes;
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_DTS;
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ if (find_sync) {
+ for (; len >= 10 && BitRead(32, true) != 0x7ffe8001; len--) {
+ BitRead(8);
+ }
+ }
+
+ if (len < 10) {
+ return false;
+ }
+
+ h.sync = (DWORD)BitRead(32);
+ if (h.sync != 0x7ffe8001) {
+ return false;
+ }
+
+ h.frametype = BitRead(1);
+ h.deficitsamplecount = BitRead(5);
+ h.fcrc = BitRead(1);
+ h.nblocks = BitRead(7) + 1;
+ h.framebytes = (WORD)BitRead(14) + 1;
+ h.amode = BitRead(6);
+ h.sfreq = BitRead(4);
+ h.rate = BitRead(5);
+
+ h.downmix = BitRead(1);
+ h.dynrange = BitRead(1);
+ h.timestamp = BitRead(1);
+ h.aux_data = BitRead(1);
+ h.hdcd = BitRead(1);
+ h.ext_descr = BitRead(3);
+ h.ext_coding = BitRead(1);
+ h.aspf = BitRead(1);
+ h.lfe = BitRead(2);
+ h.predictor_history = BitRead(1);
+
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX wfe;
+ memset(&wfe, 0, sizeof(wfe));
+ wfe.wFormatTag = WAVE_FORMAT_DVD_DTS;
+
+ static int channels[] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8};
+
+ if (h.amode < _countof(channels)) {
+ wfe.nChannels = channels[h.amode];
+ if (h.lfe > 0) {
+ ++wfe.nChannels;
+ }
+ }
+
+ static int freq[] = {0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 0, 0};
+ wfe.nSamplesPerSec = freq[h.sfreq];
+
+ /*static int rate[] = {
+ 32000, 56000, 64000, 96000,
+ 112000, 128000, 192000, 224000,
+ 256000, 320000, 384000, 448000,
+ 512000, 576000, 640000, 768000,
+ 960000, 1024000, 1152000, 1280000,
+ 1344000, 1408000, 1411200, 1472000,
+ 1536000, 1920000, 2048000, 3072000,
+ 3840000, 0, 0, 0 //open, variable, lossless
+ };
+ int nom_bitrate = rate[h.rate];*/
+
+ unsigned int bitrate = (unsigned int)(8ui64 * h.framebytes * wfe.nSamplesPerSec / (h.nblocks * 32));
+
+ wfe.nAvgBytesPerSec = (bitrate + 4) / 8;
+ wfe.nBlockAlign = h.framebytes;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_DTS;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+
+ return true;
}
bool CBaseSplitterFileEx::Read(lpcmhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
-
- h.emphasis = BitRead(1);
- h.mute = BitRead(1);
- h.reserved1 = BitRead(1);
- h.framenum = BitRead(5);
- h.quantwordlen = BitRead(2);
- h.freq = BitRead(2);
- h.reserved2 = BitRead(1);
- h.channels = BitRead(3);
- h.drc = (BYTE)BitRead(8);
-
- if (h.quantwordlen == 3 || h.reserved1 || h.reserved2) {
- return false;
- }
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEX wfe;
- memset(&wfe, 0, sizeof(wfe));
- wfe.wFormatTag = WAVE_FORMAT_PCM;
- wfe.nChannels = h.channels+1;
- static int freq[] = {48000, 96000, 44100, 32000};
- wfe.nSamplesPerSec = freq[h.freq];
- switch (h.quantwordlen) {
- case 0:
- wfe.wBitsPerSample = 16;
- break;
- case 1:
- wfe.wBitsPerSample = 20;
- break;
- case 2:
- wfe.wBitsPerSample = 24;
- break;
- }
- wfe.nBlockAlign = (wfe.nChannels*2*wfe.wBitsPerSample) / 8;
- wfe.nAvgBytesPerSec = (wfe.nBlockAlign*wfe.nSamplesPerSec) / 2;
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_DVD_LPCM_AUDIO;
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ h.emphasis = BitRead(1);
+ h.mute = BitRead(1);
+ h.reserved1 = BitRead(1);
+ h.framenum = BitRead(5);
+ h.quantwordlen = BitRead(2);
+ h.freq = BitRead(2);
+ h.reserved2 = BitRead(1);
+ h.channels = BitRead(3);
+ h.drc = (BYTE)BitRead(8);
+
+ if (h.quantwordlen == 3 || h.reserved1 || h.reserved2) {
+ return false;
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX wfe;
+ memset(&wfe, 0, sizeof(wfe));
+ wfe.wFormatTag = WAVE_FORMAT_PCM;
+ wfe.nChannels = h.channels + 1;
+ static int freq[] = {48000, 96000, 44100, 32000};
+ wfe.nSamplesPerSec = freq[h.freq];
+ switch (h.quantwordlen) {
+ case 0:
+ wfe.wBitsPerSample = 16;
+ break;
+ case 1:
+ wfe.wBitsPerSample = 20;
+ break;
+ case 2:
+ wfe.wBitsPerSample = 24;
+ break;
+ }
+ wfe.nBlockAlign = (wfe.nChannels * 2 * wfe.wBitsPerSample) / 8;
+ wfe.nAvgBytesPerSec = (wfe.nBlockAlign * wfe.nSamplesPerSec) / 2;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_DVD_LPCM_AUDIO;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+
+ return true;
}
bool CBaseSplitterFileEx::Read(dvdalpcmhdr& h, int len, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
- if (len < 8) return false;
-
- h.firstaudioframe = (WORD)BitRead(16);// Byte pointer to start of first audio frame.
- h.unknown1 = (BYTE)BitRead(8); // Unknown - e.g. 0x10 for stereo, 0x00 for surround
- if (h.unknown1!= 0x10 && h.unknown1!= 0x00)
- return false; // this is not the aob. maybe this is a vob.
-
- h.bitpersample1 = (BYTE)BitRead(4);
- h.bitpersample2 = (BYTE)BitRead(4);
- h.samplerate1 = (BYTE)BitRead(4);
- h.samplerate2 = (BYTE)BitRead(4);
- h.unknown2 = (BYTE)BitRead(8); // Unknown - e.g. 0x00
- h.groupassignment = (BYTE)BitRead(8); // Channel Group Assignment
- h.unknown3 = (BYTE)BitRead(8); // Unknown - e.g. 0x80
-
- if (h.bitpersample1 > 2 || (h.samplerate1&7) > 2 || h.groupassignment > 20 ||
- h.unknown2 != 0x00 || h.unknown3 != 0x80) {
- return false; // poor parameters or this is a vob.
- }
- // decoder limitations
- if (h.groupassignment > 1 && (h.bitpersample2 != h.bitpersample1 || h.samplerate2 != h.samplerate1)) {
- return false; // decoder does not support different bit depth and frequency.
- }
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEX wfe;
- memset(&wfe, 0, sizeof(wfe));
- wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
- static const WORD depth[] = {16, 20, 24};
- static const DWORD freq[] = {48000, 96000, 192000, 0, 0, 0, 0, 0, 44100, 88200, 1764000};
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
- static const WORD channels1[] = {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4};
- static const WORD channels2[] = {0, 0, 1, 2, 1, 2, 3, 1, 2, 3, 2, 3, 4, 1, 2, 1, 2, 3, 1, 1, 2};
- wfe.wBitsPerSample = depth[h.bitpersample1];
- wfe.nSamplesPerSec = freq[h.samplerate1];
- wfe.nChannels = channels1[h.groupassignment]+channels2[h.groupassignment];
-
- if (wfe.nChannels > 2) {
- wfe.nBlockAlign = (depth[h.bitpersample1] * channels1[h.groupassignment] * (WORD)(freq[h.samplerate1] / freq[h.samplerate2]) +
- depth[h.bitpersample2] * channels2[h.groupassignment]) * 2 / 8;
- } else {
- wfe.nBlockAlign = depth[h.bitpersample1] * channels1[h.groupassignment] * 2 / 8;
- }
- wfe.nAvgBytesPerSec = wfe.nBlockAlign * wfe.nSamplesPerSec / 2;
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_DVD_LPCM_AUDIO;
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
-
- return true;
+ memset(&h, 0, sizeof(h));
+ if (len < 8) { return false; }
+
+ h.firstaudioframe = (WORD)BitRead(16);// Byte pointer to start of first audio frame.
+ h.unknown1 = (BYTE)BitRead(8); // Unknown - e.g. 0x10 for stereo, 0x00 for surround
+ if (h.unknown1 != 0x10 && h.unknown1 != 0x00) {
+ return false; // this is not the aob. maybe this is a vob.
+ }
+
+ h.bitpersample1 = (BYTE)BitRead(4);
+ h.bitpersample2 = (BYTE)BitRead(4);
+ h.samplerate1 = (BYTE)BitRead(4);
+ h.samplerate2 = (BYTE)BitRead(4);
+ h.unknown2 = (BYTE)BitRead(8); // Unknown - e.g. 0x00
+ h.groupassignment = (BYTE)BitRead(8); // Channel Group Assignment
+ h.unknown3 = (BYTE)BitRead(8); // Unknown - e.g. 0x80
+
+ if (h.bitpersample1 > 2 || (h.samplerate1 & 7) > 2 || h.groupassignment > 20 ||
+ h.unknown2 != 0x00 || h.unknown3 != 0x80) {
+ return false; // poor parameters or this is a vob.
+ }
+ // decoder limitations
+ if (h.groupassignment > 1 && (h.bitpersample2 != h.bitpersample1 || h.samplerate2 != h.samplerate1)) {
+ return false; // decoder does not support different bit depth and frequency.
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX wfe;
+ memset(&wfe, 0, sizeof(wfe));
+ wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
+ static const WORD depth[] = {16, 20, 24};
+ static const DWORD freq[] = {48000, 96000, 192000, 0, 0, 0, 0, 0, 44100, 88200, 1764000};
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+ static const WORD channels1[] = {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4};
+ static const WORD channels2[] = {0, 0, 1, 2, 1, 2, 3, 1, 2, 3, 2, 3, 4, 1, 2, 1, 2, 3, 1, 1, 2};
+ wfe.wBitsPerSample = depth[h.bitpersample1];
+ wfe.nSamplesPerSec = freq[h.samplerate1];
+ wfe.nChannels = channels1[h.groupassignment] + channels2[h.groupassignment];
+
+ if (wfe.nChannels > 2) {
+ wfe.nBlockAlign = (depth[h.bitpersample1] * channels1[h.groupassignment] * (WORD)(freq[h.samplerate1] / freq[h.samplerate2]) +
+ depth[h.bitpersample2] * channels2[h.groupassignment]) * 2 / 8;
+ } else {
+ wfe.nBlockAlign = depth[h.bitpersample1] * channels1[h.groupassignment] * 2 / 8;
+ }
+ wfe.nAvgBytesPerSec = wfe.nBlockAlign * wfe.nSamplesPerSec / 2;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_DVD_LPCM_AUDIO;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+
+ return true;
}
bool CBaseSplitterFileEx::Read(hdmvlpcmhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- h.size = (WORD)BitRead(16);
- h.channels = (BYTE)BitRead(4);
- h.samplerate = (BYTE)BitRead(4);
- h.bitpersample = (BYTE)BitRead(2);
+ h.size = (WORD)BitRead(16);
+ h.channels = (BYTE)BitRead(4);
+ h.samplerate = (BYTE)BitRead(4);
+ h.bitpersample = (BYTE)BitRead(2);
- if (h.channels==0 || h.channels==2 ||
- (h.samplerate != 1 && h.samplerate!= 4 && h.samplerate!= 5) ||
- h.bitpersample<0 || h.bitpersample>3) {
- return false;
- }
+ if (h.channels == 0 || h.channels == 2 ||
+ (h.samplerate != 1 && h.samplerate != 4 && h.samplerate != 5) ||
+ h.bitpersample < 0 || h.bitpersample > 3) {
+ return false;
+ }
- if (!pmt) {
- return true;
- }
+ if (!pmt) {
+ return true;
+ }
- WAVEFORMATEX_HDMV_LPCM wfe;
- wfe.wFormatTag = WAVE_FORMAT_PCM;
+ WAVEFORMATEX_HDMV_LPCM wfe;
+ wfe.wFormatTag = WAVE_FORMAT_PCM;
- static int channels[] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8};
- wfe.nChannels = channels[h.channels];
- wfe.channel_conf = h.channels;
+ static int channels[] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8};
+ wfe.nChannels = channels[h.channels];
+ wfe.channel_conf = h.channels;
- static int freq[] = {0, 48000, 0, 0, 96000, 192000};
- wfe.nSamplesPerSec = freq[h.samplerate];
+ static int freq[] = {0, 48000, 0, 0, 96000, 192000};
+ wfe.nSamplesPerSec = freq[h.samplerate];
- static int bitspersample[] = {0, 16, 20, 24};
- wfe.wBitsPerSample = bitspersample[h.bitpersample];
+ static int bitspersample[] = {0, 16, 20, 24};
+ wfe.wBitsPerSample = bitspersample[h.bitpersample];
- wfe.nBlockAlign = wfe.nChannels*wfe.wBitsPerSample>>3;
- wfe.nAvgBytesPerSec = wfe.nBlockAlign*wfe.nSamplesPerSec;
+ wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample >> 3;
+ wfe.nAvgBytesPerSec = wfe.nBlockAlign * wfe.nSamplesPerSec;
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_HDMV_LPCM_AUDIO;
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_HDMV_LPCM_AUDIO;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
- return true;
+ return true;
}
bool CBaseSplitterFileEx::Read(mlphdr& h, int len, CMediaType* pmt, bool find_sync)
{
- memset(&h, 0, sizeof(h));
- if (len < 20) return false;
-
- __int64 startpos = GetPos();
-
- int samplerate, channels, framelength;
- WORD bitdepth;
- bool isTrueHD;
- int fsize = 0;
-
- BYTE buf[20];
- int k = find_sync ? len - 20 : 1;
- int i = 0;
- while (i < k) {
- Seek(startpos+i);
- ByteRead(buf, 20);
- if (GetMLPFrameSize(buf)) {
- fsize = ParseMLPHeader(buf, &samplerate, &channels, &framelength, &bitdepth, &isTrueHD);
- break;
- }
- ++i;
- }
-
- if (fsize && !isTrueHD) {
- h.size = fsize;
-
- if (!pmt) {
- return true;
- }
-
- int bitrate = (int)(fsize * 8i64 * samplerate / framelength); // inaccurate, because fsize is not constant
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_MLP;
- pmt->formattype = FORMAT_WaveFormatEx;
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));
- wfe->wFormatTag = WAVE_FORMAT_UNKNOWN;
- wfe->nChannels = channels;
- wfe->nSamplesPerSec = samplerate;
- wfe->nAvgBytesPerSec = (bitrate + 4) /8;
- wfe->nBlockAlign = fsize < WORD_MAX ? fsize : WORD_MAX;
- wfe->wBitsPerSample = bitdepth;
- wfe->cbSize = 0;
-
- pmt->SetSampleSize(0);
-
- Seek(startpos+i);
- return true;
- }
-
- return false;
+ memset(&h, 0, sizeof(h));
+ if (len < 20) { return false; }
+
+ __int64 startpos = GetPos();
+
+ int samplerate, channels, framelength;
+ WORD bitdepth;
+ bool isTrueHD;
+ int fsize = 0;
+
+ BYTE buf[20];
+ int k = find_sync ? len - 20 : 1;
+ int i = 0;
+ while (i < k) {
+ Seek(startpos + i);
+ ByteRead(buf, 20);
+ if (GetMLPFrameSize(buf)) {
+ fsize = ParseMLPHeader(buf, &samplerate, &channels, &framelength, &bitdepth, &isTrueHD);
+ break;
+ }
+ ++i;
+ }
+
+ if (fsize && !isTrueHD) {
+ h.size = fsize;
+
+ if (!pmt) {
+ return true;
+ }
+
+ int bitrate = (int)(fsize * 8i64 * samplerate / framelength); // inaccurate, because fsize is not constant
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_MLP;
+ pmt->formattype = FORMAT_WaveFormatEx;
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));
+ wfe->wFormatTag = WAVE_FORMAT_UNKNOWN;
+ wfe->nChannels = channels;
+ wfe->nSamplesPerSec = samplerate;
+ wfe->nAvgBytesPerSec = (bitrate + 4) / 8;
+ wfe->nBlockAlign = fsize < WORD_MAX ? fsize : WORD_MAX;
+ wfe->wBitsPerSample = bitdepth;
+ wfe->cbSize = 0;
+
+ pmt->SetSampleSize(0);
+
+ Seek(startpos + i);
+ return true;
+ }
+
+ return false;
}
bool CBaseSplitterFileEx::Read(dvdspuhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- if (!pmt) {
- return true;
- }
+ if (!pmt) {
+ return true;
+ }
- pmt->majortype = MEDIATYPE_Video;
- pmt->subtype = MEDIASUBTYPE_DVD_SUBPICTURE;
- pmt->formattype = FORMAT_None;
+ pmt->majortype = MEDIATYPE_Video;
+ pmt->subtype = MEDIASUBTYPE_DVD_SUBPICTURE;
+ pmt->formattype = FORMAT_None;
- return true;
+ return true;
}
bool CBaseSplitterFileEx::Read(hdmvsubhdr& h, CMediaType* pmt, const char* language_code)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- if (!pmt) {
- return true;
- }
+ if (!pmt) {
+ return true;
+ }
- pmt->majortype = MEDIATYPE_Subtitle;
- pmt->subtype = MEDIASUBTYPE_HDMVSUB;
- pmt->formattype = FORMAT_None;
+ pmt->majortype = MEDIATYPE_Subtitle;
+ pmt->subtype = MEDIASUBTYPE_HDMVSUB;
+ pmt->formattype = FORMAT_None;
- SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO));
- if (psi) {
- memset(psi, 0, pmt->FormatLength());
- strcpy_s(psi->IsoLang, language_code ? language_code : "eng");
- }
+ SUBTITLEINFO* psi = (SUBTITLEINFO*)pmt->AllocFormatBuffer(sizeof(SUBTITLEINFO));
+ if (psi) {
+ memset(psi, 0, pmt->FormatLength());
+ strcpy_s(psi->IsoLang, language_code ? language_code : "eng");
+ }
- return true;
+ return true;
}
bool CBaseSplitterFileEx::Read(svcdspuhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- if (!pmt) {
- return true;
- }
+ if (!pmt) {
+ return true;
+ }
- pmt->majortype = MEDIATYPE_Video;
- pmt->subtype = MEDIASUBTYPE_SVCD_SUBPICTURE;
- pmt->formattype = FORMAT_None;
+ pmt->majortype = MEDIATYPE_Video;
+ pmt->subtype = MEDIASUBTYPE_SVCD_SUBPICTURE;
+ pmt->formattype = FORMAT_None;
- return true;
+ return true;
}
bool CBaseSplitterFileEx::Read(cvdspuhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- if (!pmt) {
- return true;
- }
+ if (!pmt) {
+ return true;
+ }
- pmt->majortype = MEDIATYPE_Video;
- pmt->subtype = MEDIASUBTYPE_CVD_SUBPICTURE;
- pmt->formattype = FORMAT_None;
+ pmt->majortype = MEDIATYPE_Video;
+ pmt->subtype = MEDIASUBTYPE_CVD_SUBPICTURE;
+ pmt->formattype = FORMAT_None;
- return true;
+ return true;
}
bool CBaseSplitterFileEx::Read(ps2audhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
-
- if (BitRead(16, true) != 'SS') {
- return false;
- }
-
- __int64 pos = GetPos();
-
- while (BitRead(16, true) == 'SS') {
- DWORD tag = (DWORD)BitRead(32, true);
- DWORD size = 0;
-
- if (tag == 'SShd') {
- BitRead(32);
- ByteRead((BYTE*)&size, sizeof(size));
- ASSERT(size == 0x18);
- Seek(GetPos());
- ByteRead((BYTE*)&h, sizeof(h));
- } else if (tag == 'SSbd') {
- BitRead(32);
- ByteRead((BYTE*)&size, sizeof(size));
- break;
- }
- }
-
- Seek(pos);
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEXPS2 wfe;
- wfe.wFormatTag =
- h.unk1 == 0x01 ? WAVE_FORMAT_PS2_PCM :
- h.unk1 == 0x10 ? WAVE_FORMAT_PS2_ADPCM :
- WAVE_FORMAT_UNKNOWN;
- wfe.nChannels = (WORD)h.channels;
- wfe.nSamplesPerSec = h.freq;
- wfe.wBitsPerSample = 16; // always?
- wfe.nBlockAlign = wfe.nChannels*wfe.wBitsPerSample>>3;
- wfe.nAvgBytesPerSec = wfe.nBlockAlign*wfe.nSamplesPerSec;
- wfe.dwInterleave = h.interleave;
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = FOURCCMap(wfe.wFormatTag);
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ if (BitRead(16, true) != 'SS') {
+ return false;
+ }
+
+ __int64 pos = GetPos();
+
+ while (BitRead(16, true) == 'SS') {
+ DWORD tag = (DWORD)BitRead(32, true);
+ DWORD size = 0;
+
+ if (tag == 'SShd') {
+ BitRead(32);
+ ByteRead((BYTE*)&size, sizeof(size));
+ ASSERT(size == 0x18);
+ Seek(GetPos());
+ ByteRead((BYTE*)&h, sizeof(h));
+ } else if (tag == 'SSbd') {
+ BitRead(32);
+ ByteRead((BYTE*)&size, sizeof(size));
+ break;
+ }
+ }
+
+ Seek(pos);
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEXPS2 wfe;
+ wfe.wFormatTag =
+ h.unk1 == 0x01 ? WAVE_FORMAT_PS2_PCM :
+ h.unk1 == 0x10 ? WAVE_FORMAT_PS2_ADPCM :
+ WAVE_FORMAT_UNKNOWN;
+ wfe.nChannels = (WORD)h.channels;
+ wfe.nSamplesPerSec = h.freq;
+ wfe.wBitsPerSample = 16; // always?
+ wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample >> 3;
+ wfe.nAvgBytesPerSec = wfe.nBlockAlign * wfe.nSamplesPerSec;
+ wfe.dwInterleave = h.interleave;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = FOURCCMap(wfe.wFormatTag);
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+
+ return true;
}
bool CBaseSplitterFileEx::Read(ps2subhdr& h, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- if (!pmt) {
- return true;
- }
+ if (!pmt) {
+ return true;
+ }
- pmt->majortype = MEDIATYPE_Subtitle;
- pmt->subtype = MEDIASUBTYPE_PS2_SUB;
- pmt->formattype = FORMAT_None;
+ pmt->majortype = MEDIATYPE_Subtitle;
+ pmt->subtype = MEDIASUBTYPE_PS2_SUB;
+ pmt->formattype = FORMAT_None;
- return true;
+ return true;
}
bool CBaseSplitterFileEx::Read(trhdr& h, bool fSync)
{
- memset(&h, 0, sizeof(h));
-
- BitByteAlign();
-
- if (m_tslen == 0) {
- __int64 pos = GetPos();
- int count = 0;
-
- for (int i = 0; i < 192; i++) {
- if (BitRead(8, true) == 0x47) {
- __int64 pos = GetPos();
- Seek(pos + 188);
- if (BitRead(8, true) == 0x47) {
- if (m_tslen != 188) {
- count = 0;
- }
- m_tslen = 188; // TS stream
- if (count > 1) {
- break;
- }
- count++;
- } else {
- Seek(pos + 192);
- if (BitRead(8, true) == 0x47) {
- if (m_tslen != 192) {
- count = 0;
- }
- m_tslen = 192; // M2TS stream
- if (count > 1) {
- break;
- }
- count++;
- }
- }
- } else {
- BitRead(8);
- }
- }
-
- Seek(pos);
-
- if (m_tslen == 0) {
- return false;
- }
- }
-
- if (fSync) {
- for (int i = 0; i < m_tslen; i++) {
- if (BitRead(8, true) == 0x47) {
- if (i == 0) {
- break;
- }
- Seek(GetPos()+m_tslen);
- if (BitRead(8, true) == 0x47) {
- Seek(GetPos()-m_tslen);
- break;
- }
- }
-
- BitRead(8);
-
- if (i == m_tslen-1) {
- return false;
- }
- }
- }
-
- if (BitRead(8, true) != 0x47) {
- return false;
- }
-
- h.next = GetPos() + m_tslen;
-
- h.sync = (BYTE)BitRead(8);
- h.error = BitRead(1);
- h.payloadstart = BitRead(1);
- h.transportpriority = BitRead(1);
- h.pid = BitRead(13);
- h.scrambling = BitRead(2);
- h.adapfield = BitRead(1);
- h.payload = BitRead(1);
- h.counter = BitRead(4);
-
- h.bytes = 188 - 4;
-
- if (h.adapfield) {
- h.length = (BYTE)BitRead(8);
-
- if (h.length > 0) {
- h.discontinuity = BitRead(1);
- h.randomaccess = BitRead(1);
- h.priority = BitRead(1);
- h.fPCR = BitRead(1);
- h.OPCR = BitRead(1);
- h.splicingpoint = BitRead(1);
- h.privatedata = BitRead(1);
- h.extension = BitRead(1);
-
- int i = 1;
-
- if (h.fPCR && h.length>6) {
- h.PCR = BitRead(33);
- BitRead(6);
- UINT64 PCRExt = BitRead(9);
- h.PCR = (h.PCR*300 + PCRExt) * 10 / 27;
- i += 6;
- }
-
- h.length = min(h.length, h.bytes-1);
- for (; i < h.length; i++) {
- BitRead(8);
- }
- }
-
- h.bytes -= h.length+1;
-
- if (h.bytes < 0) {
- ASSERT(0);
- return false;
- }
- }
- return true;
+ memset(&h, 0, sizeof(h));
+
+ BitByteAlign();
+
+ if (m_tslen == 0) {
+ __int64 pos = GetPos();
+ int count = 0;
+
+ for (int i = 0; i < 192; i++) {
+ if (BitRead(8, true) == 0x47) {
+ __int64 pos = GetPos();
+ Seek(pos + 188);
+ if (BitRead(8, true) == 0x47) {
+ if (m_tslen != 188) {
+ count = 0;
+ }
+ m_tslen = 188; // TS stream
+ if (count > 1) {
+ break;
+ }
+ count++;
+ } else {
+ Seek(pos + 192);
+ if (BitRead(8, true) == 0x47) {
+ if (m_tslen != 192) {
+ count = 0;
+ }
+ m_tslen = 192; // M2TS stream
+ if (count > 1) {
+ break;
+ }
+ count++;
+ }
+ }
+ } else {
+ BitRead(8);
+ }
+ }
+
+ Seek(pos);
+
+ if (m_tslen == 0) {
+ return false;
+ }
+ }
+
+ if (fSync) {
+ for (int i = 0; i < m_tslen; i++) {
+ if (BitRead(8, true) == 0x47) {
+ if (i == 0) {
+ break;
+ }
+ Seek(GetPos() + m_tslen);
+ if (BitRead(8, true) == 0x47) {
+ Seek(GetPos() - m_tslen);
+ break;
+ }
+ }
+
+ BitRead(8);
+
+ if (i == m_tslen - 1) {
+ return false;
+ }
+ }
+ }
+
+ if (BitRead(8, true) != 0x47) {
+ return false;
+ }
+
+ h.next = GetPos() + m_tslen;
+
+ h.sync = (BYTE)BitRead(8);
+ h.error = BitRead(1);
+ h.payloadstart = BitRead(1);
+ h.transportpriority = BitRead(1);
+ h.pid = BitRead(13);
+ h.scrambling = BitRead(2);
+ h.adapfield = BitRead(1);
+ h.payload = BitRead(1);
+ h.counter = BitRead(4);
+
+ h.bytes = 188 - 4;
+
+ if (h.adapfield) {
+ h.length = (BYTE)BitRead(8);
+
+ if (h.length > 0) {
+ h.discontinuity = BitRead(1);
+ h.randomaccess = BitRead(1);
+ h.priority = BitRead(1);
+ h.fPCR = BitRead(1);
+ h.OPCR = BitRead(1);
+ h.splicingpoint = BitRead(1);
+ h.privatedata = BitRead(1);
+ h.extension = BitRead(1);
+
+ int i = 1;
+
+ if (h.fPCR && h.length > 6) {
+ h.PCR = BitRead(33);
+ BitRead(6);
+ UINT64 PCRExt = BitRead(9);
+ h.PCR = (h.PCR * 300 + PCRExt) * 10 / 27;
+ i += 6;
+ }
+
+ h.length = min(h.length, h.bytes - 1);
+ for (; i < h.length; i++) {
+ BitRead(8);
+ }
+ }
+
+ h.bytes -= h.length + 1;
+
+ if (h.bytes < 0) {
+ ASSERT(0);
+ return false;
+ }
+ }
+ return true;
}
bool CBaseSplitterFileEx::Read(trsechdr& h)
{
- memset(&h, 0, sizeof(h));
-
- BYTE pointer_field = (BYTE)BitRead(8);
- while (pointer_field-- > 0) {
- BitRead(8);
- }
- h.table_id = (BYTE)BitRead(8);
- h.section_syntax_indicator = (WORD)BitRead(1);
- h.zero = (WORD)BitRead(1);
- h.reserved1 = (WORD)BitRead(2);
- h.section_length = (WORD)BitRead(12);
- h.transport_stream_id = (WORD)BitRead(16);
- h.reserved2 = (BYTE)BitRead(2);
- h.version_number = (BYTE)BitRead(5);
- h.current_next_indicator = (BYTE)BitRead(1);
- h.section_number = (BYTE)BitRead(8);
- h.last_section_number = (BYTE)BitRead(8);
-
- return h.section_syntax_indicator == 1 && h.zero == 0;
+ memset(&h, 0, sizeof(h));
+
+ BYTE pointer_field = (BYTE)BitRead(8);
+ while (pointer_field-- > 0) {
+ BitRead(8);
+ }
+ h.table_id = (BYTE)BitRead(8);
+ h.section_syntax_indicator = (WORD)BitRead(1);
+ h.zero = (WORD)BitRead(1);
+ h.reserved1 = (WORD)BitRead(2);
+ h.section_length = (WORD)BitRead(12);
+ h.transport_stream_id = (WORD)BitRead(16);
+ h.reserved2 = (BYTE)BitRead(2);
+ h.version_number = (BYTE)BitRead(5);
+ h.current_next_indicator = (BYTE)BitRead(1);
+ h.section_number = (BYTE)BitRead(8);
+ h.last_section_number = (BYTE)BitRead(8);
+
+ return h.section_syntax_indicator == 1 && h.zero == 0;
}
bool CBaseSplitterFileEx::Read(pvahdr& h, bool fSync)
{
- memset(&h, 0, sizeof(h));
-
- BitByteAlign();
-
- if (fSync) {
- for (int i = 0; i < 65536; i++) {
- if ((BitRead(64, true)&0xfffffc00ffe00000i64) == 0x4156000055000000i64) {
- break;
- }
- BitRead(8);
- }
- }
-
- if ((BitRead(64, true)&0xfffffc00ffe00000i64) != 0x4156000055000000i64) {
- return false;
- }
-
- h.sync = (WORD)BitRead(16);
- h.streamid = (BYTE)BitRead(8);
- h.counter = (BYTE)BitRead(8);
- h.res1 = (BYTE)BitRead(8);
- h.res2 = BitRead(3);
- h.fpts = BitRead(1);
- h.postbytes = BitRead(2);
- h.prebytes = BitRead(2);
- h.length = (WORD)BitRead(16);
-
- if (h.length > 6136) {
- return false;
- }
-
- __int64 pos = GetPos();
-
- if (h.streamid == 1 && h.fpts) {
- h.pts = 10000*BitRead(32)/90 + m_rtPTSOffset;
- } else if (h.streamid == 2 && (h.fpts || (BitRead(32, true)&0xffffffe0) == 0x000001c0)) {
- BYTE b;
- if (!NextMpegStartCode(b, 4)) {
- return false;
- }
- peshdr h2;
- if (!Read(h2, b)) {
- return false;
- }
- // Maybe bug, code before: if (h.fpts = h2.fpts) h.pts = h2.pts;
- h.fpts = h2.fpts;
- if (h.fpts) {
- h.pts = h2.pts;
- }
- }
-
- BitRead(8*h.prebytes);
-
- h.length -= (WORD)(GetPos() - pos);
-
- return true;
+ memset(&h, 0, sizeof(h));
+
+ BitByteAlign();
+
+ if (fSync) {
+ for (int i = 0; i < 65536; i++) {
+ if ((BitRead(64, true) & 0xfffffc00ffe00000i64) == 0x4156000055000000i64) {
+ break;
+ }
+ BitRead(8);
+ }
+ }
+
+ if ((BitRead(64, true) & 0xfffffc00ffe00000i64) != 0x4156000055000000i64) {
+ return false;
+ }
+
+ h.sync = (WORD)BitRead(16);
+ h.streamid = (BYTE)BitRead(8);
+ h.counter = (BYTE)BitRead(8);
+ h.res1 = (BYTE)BitRead(8);
+ h.res2 = BitRead(3);
+ h.fpts = BitRead(1);
+ h.postbytes = BitRead(2);
+ h.prebytes = BitRead(2);
+ h.length = (WORD)BitRead(16);
+
+ if (h.length > 6136) {
+ return false;
+ }
+
+ __int64 pos = GetPos();
+
+ if (h.streamid == 1 && h.fpts) {
+ h.pts = 10000 * BitRead(32) / 90 + m_rtPTSOffset;
+ } else if (h.streamid == 2 && (h.fpts || (BitRead(32, true) & 0xffffffe0) == 0x000001c0)) {
+ BYTE b;
+ if (!NextMpegStartCode(b, 4)) {
+ return false;
+ }
+ peshdr h2;
+ if (!Read(h2, b)) {
+ return false;
+ }
+ // Maybe bug, code before: if (h.fpts = h2.fpts) h.pts = h2.pts;
+ h.fpts = h2.fpts;
+ if (h.fpts) {
+ h.pts = h2.pts;
+ }
+ }
+
+ BitRead(8 * h.prebytes);
+
+ h.length -= (WORD)(GetPos() - pos);
+
+ return true;
}
int CBaseSplitterFileEx::HrdParameters(CGolombBuffer& gb)
{
- UINT64 cnt = gb.UExpGolombRead(); // cpb_cnt_minus1
- if (cnt > 32U)
- return -1;
- gb.BitRead(4); // bit_rate_scale
- gb.BitRead(4); // cpb_size_scale
-
- for (unsigned int i = 0; i <= cnt; i++ ) {
- gb.UExpGolombRead(); // bit_rate_value_minus1
- gb.UExpGolombRead(); // cpb_size_value_minus1
- gb.BitRead(1); // cbr_flag
- }
-
- gb.BitRead(5); // initial_cpb_removal_delay_length_minus1
- gb.BitRead(5); // cpb_removal_delay_length_minus1
- gb.BitRead(5); // dpb_output_delay_length_minus1
- gb.BitRead(5); // time_offset_length
-
- return 0;
+ UINT64 cnt = gb.UExpGolombRead(); // cpb_cnt_minus1
+ if (cnt > 32U) {
+ return -1;
+ }
+ gb.BitRead(4); // bit_rate_scale
+ gb.BitRead(4); // cpb_size_scale
+
+ for (unsigned int i = 0; i <= cnt; i++) {
+ gb.UExpGolombRead(); // bit_rate_value_minus1
+ gb.UExpGolombRead(); // cpb_size_value_minus1
+ gb.BitRead(1); // cbr_flag
+ }
+
+ gb.BitRead(5); // initial_cpb_removal_delay_length_minus1
+ gb.BitRead(5); // cpb_removal_delay_length_minus1
+ gb.BitRead(5); // dpb_output_delay_length_minus1
+ gb.BitRead(5); // time_offset_length
+
+ return 0;
}
void CBaseSplitterFileEx::RemoveMpegEscapeCode(BYTE* dst, BYTE* src, int length)
{
- int si=0;
- int di=0;
- while (si+2<length) {
- //remove escapes (very rare 1:2^22)
- if (src[si+2]>3) {
- dst[di++]= src[si++];
- dst[di++]= src[si++];
- } else if (src[si]==0 && src[si+1]==0) {
- if (src[si+2]==3) { //escape
- dst[di++]= 0;
- dst[di++]= 0;
- si+=3;
- continue;
- } else { //next start code
- return;
- }
- }
-
- dst[di++]= src[si++];
- }
+ int si = 0;
+ int di = 0;
+ while (si + 2 < length) {
+ //remove escapes (very rare 1:2^22)
+ if (src[si + 2] > 3) {
+ dst[di++] = src[si++];
+ dst[di++] = src[si++];
+ } else if (src[si] == 0 && src[si + 1] == 0) {
+ if (src[si + 2] == 3) { //escape
+ dst[di++] = 0;
+ dst[di++] = 0;
+ si += 3;
+ continue;
+ } else { //next start code
+ return;
+ }
+ }
+
+ dst[di++] = src[si++];
+ }
}
bool CBaseSplitterFileEx::Read(avchdr& h, int len, CMediaType* pmt)
{
- __int64 endpos = GetPos() + len;
- __int64 nalstartpos = GetPos();
- //__int64 nalendpos;
- bool repeat = false;
-
- // First try search for the start code
- DWORD _dwStartCode = (DWORD)BitRead(32, true);
- while (GetPos() < endpos+4 &&
- (_dwStartCode & 0xFFFFFF1F) != 0x101 && // Coded slide of a non-IDR
- (_dwStartCode & 0xFFFFFF1F) != 0x105 && // Coded slide of an IDR
- (_dwStartCode & 0xFFFFFF1F) != 0x107 && // Sequence Parameter Set
- (_dwStartCode & 0xFFFFFF1F) != 0x108 && // Picture Parameter Set
- (_dwStartCode & 0xFFFFFF1F) != 0x109 && // Access Unit Delimiter
- (_dwStartCode & 0xFFFFFF1F) != 0x10f // Subset Sequence Parameter Set (MVC)
- ) {
- BitRead(8);
- _dwStartCode = (DWORD)BitRead(32, true);
- }
- if (GetPos() >= endpos+4) {
- return false;
- }
-
- // At least a SPS (normal or subset) and a PPS is required
- while (GetPos() < endpos+4 && (!(h.spspps[index_sps].complete || h.spspps[index_subsetsps].complete) || !h.spspps[index_pps1].complete || repeat))
- {
- BYTE id = h.lastid;
- repeat = false;
-
- // Get array index from NAL unit type
- spsppsindex index = index_unknown;
-
- if ((id&0x60) != 0) {
- if ((id&0x9f) == 0x07) {
- index = index_sps;
- } else if ((id&0x9f) == 0x0F) {
- index = index_subsetsps;
- } else if ((id&0x9f) == 0x08) {
- index = h.spspps[index_pps1].complete ? index_pps2 : index_pps1;
- }
- }
-
- // Search for next start code
- DWORD dwStartCode = (DWORD)BitRead(32, true);
- while (GetPos() < endpos+4 && (dwStartCode != 0x00000001) && (dwStartCode & 0xFFFFFF00) != 0x00000100) {
- BitRead(8);
- dwStartCode = (DWORD)BitRead(32, true);
- }
-
- //nalendpos = GetPos();
-
- // Skip start code
- __int64 pos;
- if (GetPos() < endpos+4) {
- if (dwStartCode == 0x00000001)
- BitRead(32);
- else
- BitRead(24);
-
- pos = GetPos();
- h.lastid = (BYTE)BitRead(8);
- } else {
- pos = GetPos()-4;
- }
-
- // The SPS or PPS might be fragmented, copy data into buffer until NAL is complete
- if (index >= 0) {
- if (h.spspps[index].complete) {
- // Don't handle SPS/PPS twice
- continue;
- } else if (pos > nalstartpos) {
- // Copy into buffer
- Seek(nalstartpos);
- unsigned int bufsize = _countof(h.spspps[index].buffer);
- int len = min(int(bufsize - h.spspps[index].size), int(pos - nalstartpos));
- ByteRead(h.spspps[index].buffer+h.spspps[index].size, len);
- Seek(pos);
- h.spspps[index].size += len;
-
- //ASSERT(h.spspps[index].size < bufsize); // disable for better debug ...
-
- if (h.spspps[index].size >= bufsize || dwStartCode == 0x00000001 || (dwStartCode & 0xFFFFFF00) == 0x00000100) {
- if (Read(h, index)) {
- h.spspps[index].complete = true;
- h.spspps[index].size -= 4;
- } else {
- h.spspps[index].size = 0;
- }
- }
-
- repeat = true;
- }
- }
-
- nalstartpos = pos;
- }
-
- // Exit and wait for next packet if there is no SPS and PPS yet
- if ((!h.spspps[index_sps].complete && !h.spspps[index_subsetsps].complete) || !h.spspps[index_pps1].complete || repeat) {
-
- return false;
- }
-
- if (!pmt) {
- return true;
- }
-
- {
- // Calculate size of extra data
- int extra = 0;
- for (int i = 0; i < 4; i++) {
- if (h.spspps[i].complete)
- extra += 2+(h.spspps[i].size);
- }
-
- pmt->majortype = MEDIATYPE_Video;
- if (h.spspps[index_subsetsps].complete && !h.spspps[index_sps].complete) {
- pmt->subtype = FOURCCMap('CVME'); // MVC stream without base view
- } else if (h.spspps[index_subsetsps].complete && h.spspps[index_sps].complete) {
- pmt->subtype = FOURCCMap('CVMA'); // MVC stream with base view
- } else {
- pmt->subtype = FOURCCMap('1CVA'); // AVC stream
- }
- //pmt->subtype = MEDIASUBTYPE_H264; // TODO : put MEDIASUBTYPE_H264 to support Windows 7 decoder !
- pmt->formattype = FORMAT_MPEG2_VIDEO;
- int len = FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + extra;
- MPEG2VIDEOINFO* vi = (MPEG2VIDEOINFO*)DNew BYTE[len];
- memset(vi, 0, len);
- // vi->hdr.dwBitRate = ;
- vi->hdr.AvgTimePerFrame = h.AvgTimePerFrame;
- if (!h.sar.num) h.sar.num = 1;
- if (!h.sar.den) h.sar.den = 1;
- CSize aspect(h.width * h.sar.num, h.height * h.sar.den);
- int lnko = LNKO(aspect.cx, aspect.cy);
- if (lnko > 1) {
- aspect.cx /= lnko, aspect.cy /= lnko;
- }
-
- if (aspect.cx * 2 < aspect.cy) {
- delete[] vi;
- return false;
- }
-
- vi->hdr.dwPictAspectRatioX = aspect.cx;
- vi->hdr.dwPictAspectRatioY = aspect.cy;
- vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
- vi->hdr.bmiHeader.biWidth = h.width;
- vi->hdr.bmiHeader.biHeight = h.height;
- if (h.spspps[index_subsetsps].complete && !h.spspps[index_sps].complete) {
- vi->hdr.bmiHeader.biCompression = 'CVME';
- } else if (h.spspps[index_subsetsps].complete && h.spspps[index_sps].complete) {
- vi->hdr.bmiHeader.biCompression = 'CVMA';
- } else {
- vi->hdr.bmiHeader.biCompression = '1CVA';
- }
- vi->dwProfile = h.profile;
- vi->dwFlags = 4; // ?
- vi->dwLevel = h.level;
- vi->cbSequenceHeader = extra;
-
- // Copy extra data
- BYTE* p = (BYTE*)&vi->dwSequenceHeader[0];
- for (int i = 0; i < 4; i++) {
- if (h.spspps[i].complete) {
- *p++ = (h.spspps[i].size) >> 8;
- *p++ = (h.spspps[i].size) & 0xff;
- memcpy(p, h.spspps[i].buffer, h.spspps[i].size);
- p += h.spspps[i].size;
- }
- }
-
- pmt->SetFormat((BYTE*)vi, len);
- delete [] vi;
- }
-
- return true;
+ __int64 endpos = GetPos() + len;
+ __int64 nalstartpos = GetPos();
+ //__int64 nalendpos;
+ bool repeat = false;
+
+ // First try search for the start code
+ DWORD _dwStartCode = (DWORD)BitRead(32, true);
+ while (GetPos() < endpos + 4 &&
+ (_dwStartCode & 0xFFFFFF1F) != 0x101 && // Coded slide of a non-IDR
+ (_dwStartCode & 0xFFFFFF1F) != 0x105 && // Coded slide of an IDR
+ (_dwStartCode & 0xFFFFFF1F) != 0x107 && // Sequence Parameter Set
+ (_dwStartCode & 0xFFFFFF1F) != 0x108 && // Picture Parameter Set
+ (_dwStartCode & 0xFFFFFF1F) != 0x109 && // Access Unit Delimiter
+ (_dwStartCode & 0xFFFFFF1F) != 0x10f // Subset Sequence Parameter Set (MVC)
+ ) {
+ BitRead(8);
+ _dwStartCode = (DWORD)BitRead(32, true);
+ }
+ if (GetPos() >= endpos + 4) {
+ return false;
+ }
+
+ // At least a SPS (normal or subset) and a PPS is required
+ while (GetPos() < endpos + 4 && (!(h.spspps[index_sps].complete || h.spspps[index_subsetsps].complete) || !h.spspps[index_pps1].complete || repeat)) {
+ BYTE id = h.lastid;
+ repeat = false;
+
+ // Get array index from NAL unit type
+ spsppsindex index = index_unknown;
+
+ if ((id & 0x60) != 0) {
+ if ((id & 0x9f) == 0x07) {
+ index = index_sps;
+ } else if ((id & 0x9f) == 0x0F) {
+ index = index_subsetsps;
+ } else if ((id & 0x9f) == 0x08) {
+ index = h.spspps[index_pps1].complete ? index_pps2 : index_pps1;
+ }
+ }
+
+ // Search for next start code
+ DWORD dwStartCode = (DWORD)BitRead(32, true);
+ while (GetPos() < endpos + 4 && (dwStartCode != 0x00000001) && (dwStartCode & 0xFFFFFF00) != 0x00000100) {
+ BitRead(8);
+ dwStartCode = (DWORD)BitRead(32, true);
+ }
+
+ //nalendpos = GetPos();
+
+ // Skip start code
+ __int64 pos;
+ if (GetPos() < endpos + 4) {
+ if (dwStartCode == 0x00000001) {
+ BitRead(32);
+ } else {
+ BitRead(24);
+ }
+
+ pos = GetPos();
+ h.lastid = (BYTE)BitRead(8);
+ } else {
+ pos = GetPos() - 4;
+ }
+
+ // The SPS or PPS might be fragmented, copy data into buffer until NAL is complete
+ if (index >= 0) {
+ if (h.spspps[index].complete) {
+ // Don't handle SPS/PPS twice
+ continue;
+ } else if (pos > nalstartpos) {
+ // Copy into buffer
+ Seek(nalstartpos);
+ unsigned int bufsize = _countof(h.spspps[index].buffer);
+ int len = min(int(bufsize - h.spspps[index].size), int(pos - nalstartpos));
+ ByteRead(h.spspps[index].buffer + h.spspps[index].size, len);
+ Seek(pos);
+ h.spspps[index].size += len;
+
+ //ASSERT(h.spspps[index].size < bufsize); // disable for better debug ...
+
+ if (h.spspps[index].size >= bufsize || dwStartCode == 0x00000001 || (dwStartCode & 0xFFFFFF00) == 0x00000100) {
+ if (Read(h, index)) {
+ h.spspps[index].complete = true;
+ h.spspps[index].size -= 4;
+ } else {
+ h.spspps[index].size = 0;
+ }
+ }
+
+ repeat = true;
+ }
+ }
+
+ nalstartpos = pos;
+ }
+
+ // Exit and wait for next packet if there is no SPS and PPS yet
+ if ((!h.spspps[index_sps].complete && !h.spspps[index_subsetsps].complete) || !h.spspps[index_pps1].complete || repeat) {
+
+ return false;
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ {
+ // Calculate size of extra data
+ int extra = 0;
+ for (int i = 0; i < 4; i++) {
+ if (h.spspps[i].complete) {
+ extra += 2 + (h.spspps[i].size);
+ }
+ }
+
+ pmt->majortype = MEDIATYPE_Video;
+ if (h.spspps[index_subsetsps].complete && !h.spspps[index_sps].complete) {
+ pmt->subtype = FOURCCMap('CVME'); // MVC stream without base view
+ } else if (h.spspps[index_subsetsps].complete && h.spspps[index_sps].complete) {
+ pmt->subtype = FOURCCMap('CVMA'); // MVC stream with base view
+ } else {
+ pmt->subtype = FOURCCMap('1CVA'); // AVC stream
+ }
+ //pmt->subtype = MEDIASUBTYPE_H264; // TODO : put MEDIASUBTYPE_H264 to support Windows 7 decoder !
+ pmt->formattype = FORMAT_MPEG2_VIDEO;
+ int len = FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + extra;
+ MPEG2VIDEOINFO* vi = (MPEG2VIDEOINFO*)DNew BYTE[len];
+ memset(vi, 0, len);
+ // vi->hdr.dwBitRate = ;
+ vi->hdr.AvgTimePerFrame = h.AvgTimePerFrame;
+ if (!h.sar.num) { h.sar.num = 1; }
+ if (!h.sar.den) { h.sar.den = 1; }
+ CSize aspect(h.width * h.sar.num, h.height * h.sar.den);
+ int lnko = LNKO(aspect.cx, aspect.cy);
+ if (lnko > 1) {
+ aspect.cx /= lnko, aspect.cy /= lnko;
+ }
+
+ if (aspect.cx * 2 < aspect.cy) {
+ delete[] vi;
+ return false;
+ }
+
+ vi->hdr.dwPictAspectRatioX = aspect.cx;
+ vi->hdr.dwPictAspectRatioY = aspect.cy;
+ vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
+ vi->hdr.bmiHeader.biWidth = h.width;
+ vi->hdr.bmiHeader.biHeight = h.height;
+ if (h.spspps[index_subsetsps].complete && !h.spspps[index_sps].complete) {
+ vi->hdr.bmiHeader.biCompression = 'CVME';
+ } else if (h.spspps[index_subsetsps].complete && h.spspps[index_sps].complete) {
+ vi->hdr.bmiHeader.biCompression = 'CVMA';
+ } else {
+ vi->hdr.bmiHeader.biCompression = '1CVA';
+ }
+ vi->dwProfile = h.profile;
+ vi->dwFlags = 4; // ?
+ vi->dwLevel = h.level;
+ vi->cbSequenceHeader = extra;
+
+ // Copy extra data
+ BYTE* p = (BYTE*)&vi->dwSequenceHeader[0];
+ for (int i = 0; i < 4; i++) {
+ if (h.spspps[i].complete) {
+ *p++ = (h.spspps[i].size) >> 8;
+ *p++ = (h.spspps[i].size) & 0xff;
+ memcpy(p, h.spspps[i].buffer, h.spspps[i].size);
+ p += h.spspps[i].size;
+ }
+ }
+
+ pmt->SetFormat((BYTE*)vi, len);
+ delete [] vi;
+ }
+
+ return true;
}
bool CBaseSplitterFileEx::Read(avchdr& h, spsppsindex index)
{
- static BYTE profiles[] = {44, 66, 77, 88, 100, 110, 118, 122, 128, 144, 244};
- static BYTE levels[] = {10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51};
-
- // Only care about SPS and subset SPS
- if (index != index_sps && index != index_subsetsps)
- return true;
-
- // Manage escape codes
- BYTE buffer[MAX_SPSPPS];
- RemoveMpegEscapeCode(buffer, h.spspps[index].buffer, MAX_SPSPPS);
- CGolombBuffer gb(buffer, MAX_SPSPPS);
-
- gb.BitRead(8); // nal_unit_type
- h.profile = (BYTE)gb.BitRead(8);
- bool b_ident = false;
- for (int i = 0; i<sizeof(profiles); i++) {
- if (h.profile == profiles[i]) {
- b_ident = true;
- break;
- }
- }
- if (!b_ident)
- return false;
-
- gb.BitRead(8);
- h.level = (BYTE)gb.BitRead(8);
- b_ident = false;
- for (int i = 0; i<sizeof(levels); i++) {
- if (h.level == levels[i]) {
- b_ident = true;
- break;
- }
- }
- if (!b_ident)
- return false;
-
- UINT64 sps_id = gb.UExpGolombRead(); // seq_parameter_set_id
- if (sps_id >= 32)
- return false;
-
- UINT64 chroma_format_idc = 0;
- if (h.profile >= 100) { // high profile
- chroma_format_idc = gb.UExpGolombRead();
- if (chroma_format_idc == 3) { // chroma_format_idc
- gb.BitRead(1); // residue_transform_flag
- }
-
- gb.UExpGolombRead(); // bit_depth_luma_minus8
- gb.UExpGolombRead(); // bit_depth_chroma_minus8
-
- gb.BitRead(1); // qpprime_y_zero_transform_bypass_flag
-
- if (gb.BitRead(1)) { // seq_scaling_matrix_present_flag
- for (int i = 0; i < 8; i++) {
- if (gb.BitRead(1)) { // seq_scaling_list_present_flag
- for (int j = 0, size = i < 6 ? 16 : 64, next = 8; j < size && next != 0; ++j) {
- next = (next + gb.SExpGolombRead() + 256) & 255;
- }
- }
- }
- }
- }
-
- gb.UExpGolombRead(); // log2_max_frame_num_minus4
-
- UINT64 pic_order_cnt_type = gb.UExpGolombRead();
-
- if (pic_order_cnt_type == 0) {
- gb.UExpGolombRead(); // log2_max_pic_order_cnt_lsb_minus4
- } else if (pic_order_cnt_type == 1) {
- gb.BitRead(1); // delta_pic_order_always_zero_flag
- gb.SExpGolombRead(); // offset_for_non_ref_pic
- gb.SExpGolombRead(); // offset_for_top_to_bottom_field
- UINT64 num_ref_frames_in_pic_order_cnt_cycle = gb.UExpGolombRead();
- if (num_ref_frames_in_pic_order_cnt_cycle >= 256)
- return false;
- for (int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
- gb.SExpGolombRead(); // offset_for_ref_frame[i]
- }
- } else if (pic_order_cnt_type != 2) {
- return false;
- }
-
- UINT64 ref_frame_count = gb.UExpGolombRead(); // num_ref_frames
- if (ref_frame_count > 30)
- return false;
- gb.BitRead(1); // gaps_in_frame_num_value_allowed_flag
-
- UINT64 pic_width_in_mbs_minus1 = gb.UExpGolombRead();
- UINT64 pic_height_in_map_units_minus1 = gb.UExpGolombRead();
- BYTE frame_mbs_only_flag = (BYTE)gb.BitRead(1);
-
- if (!frame_mbs_only_flag) {
- gb.BitRead(1); // mb_adaptive_frame_field_flag
- }
-
- BYTE direct_8x8_inference_flag = (BYTE)gb.BitRead(1); // direct_8x8_inference_flag
- if (!frame_mbs_only_flag && !direct_8x8_inference_flag) {
- return false;
- }
-
- if (gb.BitRead(1)) { // frame_cropping_flag
- h.crop_left = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_left_offset
- h.crop_right = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_right_offset
- h.crop_top = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_top_offset
- h.crop_bottom = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_bottom_offset
- }
-
- if (gb.BitRead(1)) { // vui_parameters_present_flag
- if (gb.BitRead(1)) { // aspect_ratio_info_present_flag
- BYTE aspect_ratio_idc = (BYTE)gb.BitRead(8); // aspect_ratio_idc
- if (255 == aspect_ratio_idc) {
- h.sar.num = (WORD)gb.BitRead(16); // sar_width
- h.sar.den = (WORD)gb.BitRead(16); // sar_height
- } else if (aspect_ratio_idc < 17) {
- h.sar.num = pixel_aspect[aspect_ratio_idc][0];
- h.sar.den = pixel_aspect[aspect_ratio_idc][1];
- } else {
- return false;
- }
- } else {
- h.sar.num = 1;
- h.sar.den = 1;
- }
-
- if (gb.BitRead(1)) { // overscan_info_present_flag
- gb.BitRead(1); // overscan_appropriate_flag
- }
-
- if (gb.BitRead(1)) { // video_signal_type_present_flag
- gb.BitRead(3); // video_format
- gb.BitRead(1); // video_full_range_flag
- if (gb.BitRead(1)) { // colour_description_present_flag
- gb.BitRead(8); // colour_primaries
- gb.BitRead(8); // transfer_characteristics
- gb.BitRead(8); // matrix_coefficients
- }
- }
- if (gb.BitRead(1)) { // chroma_location_info_present_flag
- gb.UExpGolombRead(); // chroma_sample_loc_type_top_field
- gb.UExpGolombRead(); // chroma_sample_loc_type_bottom_field
- }
- if (gb.BitRead(1)) { // timing_info_present_flag
- __int64 num_units_in_tick = gb.BitRead(32);
- __int64 time_scale = gb.BitRead(32);
- /*long fixed_frame_rate_flag = */gb.BitRead(1);
-
- // Trick for weird parameters
- if ((num_units_in_tick < 1000) || (num_units_in_tick > 1001)) {
- if ((time_scale % num_units_in_tick != 0) && ((time_scale*1001) % num_units_in_tick == 0)) {
- time_scale = (time_scale * 1001) / num_units_in_tick;
- num_units_in_tick = 1001;
- } else {
- time_scale = (time_scale * 1000) / num_units_in_tick;
- num_units_in_tick = 1000;
- }
- }
- time_scale = time_scale / 2; // VUI consider fields even for progressive stream : divide by 2!
-
- if (time_scale) {
- h.AvgTimePerFrame = (10000000I64*num_units_in_tick)/time_scale;
- }
- }
-
- bool nalflag = !!gb.BitRead(1); // nal_hrd_parameters_present_flag
- if (nalflag) {
- if (HrdParameters(gb)<0)
- return false;
- }
- bool vlcflag = !!gb.BitRead(1); // vlc_hrd_parameters_present_flag
- if (vlcflag) {
- if (HrdParameters(gb)<0)
- return false;
- }
- if (nalflag || vlcflag) {
- gb.BitRead(1); // low_delay_hrd_flag
- }
-
- gb.BitRead(1); // pic_struct_present_flag
- if (gb.BitRead(1)) { // bitstream_restriction_flag
- gb.BitRead(1); // motion_vectors_over_pic_boundaries_flag
- gb.UExpGolombRead(); // max_bytes_per_pic_denom
- gb.UExpGolombRead(); // max_bits_per_mb_denom
- gb.UExpGolombRead(); // log2_max_mv_length_horizontal
- gb.UExpGolombRead(); // log2_max_mv_length_vertical
- UINT64 num_reorder_frames = gb.UExpGolombRead(); // num_reorder_frames
- gb.UExpGolombRead(); // max_dec_frame_buffering
-
- if (gb.GetSize() < gb.GetPos()) {
- num_reorder_frames = 0;
- }
- if (num_reorder_frames > 16U)
- return false;
- }
- }
-
- if (index == index_subsetsps) {
- if (h.profile == 83 || h.profile == 86) {
- // TODO: SVC extensions
- return false;
- } else if (h.profile == 118 || h.profile == 128) {
- gb.BitRead(1); // bit_equal_to_one
-
- // seq_parameter_set_mvc_extension
- h.views = (unsigned int) gb.UExpGolombRead()+1;
-
- /*
- for (unsigned int i = 0; i < h.views; i++) {
- gb.UExpGolombRead(); // view_id
- }
-
- for (unsigned int i = 1; i < h.views; i++) {
- for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_anchor_refs_l0
- gb.UExpGolombRead(); // anchor_refs_l0
- }
- for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_anchor_refs_l1
- gb.UExpGolombRead(); // anchor_refs_l1
- }
- }
-
- for (unsigned int i = 1; i < h.views; i++) {
- for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_non_anchor_refs_l0
- gb.UExpGolombRead(); // non_anchor_refs_l0
- }
- for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_non_anchor_refs_l1
- gb.UExpGolombRead(); // non_anchor_refs_l1
- }
- }
-
- for (unsigned int i = 0; i <= gb.UExpGolombRead(); i++) { // num_level_values_signalled_minus1
- gb.BitRead(8); // level_idc
- for (int j = 0; j <= gb.UExpGolombRead(); j++) { // num_applicable_ops_minus1
- gb.BitRead(3); // applicable_op_temporal_id
- for (int k = 0; k <= gb.UExpGolombRead(); k++) { // applicable_op_num_target_views_minus1
- gb.UExpGolombRead(); // applicable_op_traget_view_id
- }
- gb.UExpGolombRead(); // applicable_op_num_views_minus1
- }
- }
-
- if (gb.BitRead(1)) { // mvc_vui_parameters_present_flag
- // mvc_vui_parameters_extension
- for (unsigned int i = 0; i <= gb.UExpGolombRead(); i++) { // vui_mvc_num_ops_minus1
- gb.BitRead(3);
- for (unsigned int j = 0; j <= gb.UExpGolombRead(); j++) { // vui_mvc_num_target_output_views_minus1
- gb.UExpGolombRead(); // vui_mvc_view_id
- }
- if (gb.BitRead(1)) { // vui_mvc_timing_info_present_flag
- gb.BitRead(32); // vui_mvc_num_units_in_tick
- gb.BitRead(32); // vui_mvc_time_scale
- gb.BitRead(1); // vui_mvc_fixed_frame_rate_flag
- }
- bool nalflag = gb.BitRead(1); // vui_mvc_nal_hrd_parameters_present_flag
- if (nalflag) {
- HrdParameters(gb);
- }
- bool vclflag = gb.BitRead(1); // vui_mvc_vcl_hrd_parameters_present_flag
- if (vclflag) {
- HrdParameters(gb);
- }
- if (nalflag || vclflag) {
- gb.BitRead(1); // vui_mvc_low_delay_hrd_flag
- }
- gb.BitRead(1); // vui_mvc_pic_struct_present_flag
- }
- }
- */
- }
- }
-
- unsigned int mb_Width = (unsigned int)pic_width_in_mbs_minus1 + 1;
- unsigned int mb_Height = ((unsigned int)pic_height_in_map_units_minus1 + 1) * (2 - frame_mbs_only_flag);
- BYTE CHROMA444 = (chroma_format_idc == 3);
-
- h.width = 16 * mb_Width - (2u>>CHROMA444) * min(h.crop_right, (8u<<CHROMA444)-1);
- if (frame_mbs_only_flag) {
- h.height = 16 * mb_Height - (2u>>CHROMA444) * min(h.crop_bottom, (8u<<CHROMA444)-1);
- } else {
- h.height = 16 * mb_Height - (4u>>CHROMA444) * min(h.crop_bottom, (8u<<CHROMA444)-1);
- }
-
- if (h.height<100 || h.width<100) {
- return false;
- }
-
- if (h.height == 1088) {
- h.height = 1080; // Prevent blur lines
- }
-
- return true;
+ static BYTE profiles[] = {44, 66, 77, 88, 100, 110, 118, 122, 128, 144, 244};
+ static BYTE levels[] = {10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51};
+
+ // Only care about SPS and subset SPS
+ if (index != index_sps && index != index_subsetsps) {
+ return true;
+ }
+
+ // Manage escape codes
+ BYTE buffer[MAX_SPSPPS];
+ RemoveMpegEscapeCode(buffer, h.spspps[index].buffer, MAX_SPSPPS);
+ CGolombBuffer gb(buffer, MAX_SPSPPS);
+
+ gb.BitRead(8); // nal_unit_type
+ h.profile = (BYTE)gb.BitRead(8);
+ bool b_ident = false;
+ for (int i = 0; i < sizeof(profiles); i++) {
+ if (h.profile == profiles[i]) {
+ b_ident = true;
+ break;
+ }
+ }
+ if (!b_ident) {
+ return false;
+ }
+
+ gb.BitRead(8);
+ h.level = (BYTE)gb.BitRead(8);
+ b_ident = false;
+ for (int i = 0; i < sizeof(levels); i++) {
+ if (h.level == levels[i]) {
+ b_ident = true;
+ break;
+ }
+ }
+ if (!b_ident) {
+ return false;
+ }
+
+ UINT64 sps_id = gb.UExpGolombRead(); // seq_parameter_set_id
+ if (sps_id >= 32) {
+ return false;
+ }
+
+ UINT64 chroma_format_idc = 0;
+ if (h.profile >= 100) { // high profile
+ chroma_format_idc = gb.UExpGolombRead();
+ if (chroma_format_idc == 3) { // chroma_format_idc
+ gb.BitRead(1); // residue_transform_flag
+ }
+
+ gb.UExpGolombRead(); // bit_depth_luma_minus8
+ gb.UExpGolombRead(); // bit_depth_chroma_minus8
+
+ gb.BitRead(1); // qpprime_y_zero_transform_bypass_flag
+
+ if (gb.BitRead(1)) { // seq_scaling_matrix_present_flag
+ for (int i = 0; i < 8; i++) {
+ if (gb.BitRead(1)) { // seq_scaling_list_present_flag
+ for (int j = 0, size = i < 6 ? 16 : 64, next = 8; j < size && next != 0; ++j) {
+ next = (next + gb.SExpGolombRead() + 256) & 255;
+ }
+ }
+ }
+ }
+ }
+
+ gb.UExpGolombRead(); // log2_max_frame_num_minus4
+
+ UINT64 pic_order_cnt_type = gb.UExpGolombRead();
+
+ if (pic_order_cnt_type == 0) {
+ gb.UExpGolombRead(); // log2_max_pic_order_cnt_lsb_minus4
+ } else if (pic_order_cnt_type == 1) {
+ gb.BitRead(1); // delta_pic_order_always_zero_flag
+ gb.SExpGolombRead(); // offset_for_non_ref_pic
+ gb.SExpGolombRead(); // offset_for_top_to_bottom_field
+ UINT64 num_ref_frames_in_pic_order_cnt_cycle = gb.UExpGolombRead();
+ if (num_ref_frames_in_pic_order_cnt_cycle >= 256) {
+ return false;
+ }
+ for (int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
+ gb.SExpGolombRead(); // offset_for_ref_frame[i]
+ }
+ } else if (pic_order_cnt_type != 2) {
+ return false;
+ }
+
+ UINT64 ref_frame_count = gb.UExpGolombRead(); // num_ref_frames
+ if (ref_frame_count > 30) {
+ return false;
+ }
+ gb.BitRead(1); // gaps_in_frame_num_value_allowed_flag
+
+ UINT64 pic_width_in_mbs_minus1 = gb.UExpGolombRead();
+ UINT64 pic_height_in_map_units_minus1 = gb.UExpGolombRead();
+ BYTE frame_mbs_only_flag = (BYTE)gb.BitRead(1);
+
+ if (!frame_mbs_only_flag) {
+ gb.BitRead(1); // mb_adaptive_frame_field_flag
+ }
+
+ BYTE direct_8x8_inference_flag = (BYTE)gb.BitRead(1); // direct_8x8_inference_flag
+ if (!frame_mbs_only_flag && !direct_8x8_inference_flag) {
+ return false;
+ }
+
+ if (gb.BitRead(1)) { // frame_cropping_flag
+ h.crop_left = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_left_offset
+ h.crop_right = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_right_offset
+ h.crop_top = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_top_offset
+ h.crop_bottom = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_bottom_offset
+ }
+
+ if (gb.BitRead(1)) { // vui_parameters_present_flag
+ if (gb.BitRead(1)) { // aspect_ratio_info_present_flag
+ BYTE aspect_ratio_idc = (BYTE)gb.BitRead(8); // aspect_ratio_idc
+ if (255 == aspect_ratio_idc) {
+ h.sar.num = (WORD)gb.BitRead(16); // sar_width
+ h.sar.den = (WORD)gb.BitRead(16); // sar_height
+ } else if (aspect_ratio_idc < 17) {
+ h.sar.num = pixel_aspect[aspect_ratio_idc][0];
+ h.sar.den = pixel_aspect[aspect_ratio_idc][1];
+ } else {
+ return false;
+ }
+ } else {
+ h.sar.num = 1;
+ h.sar.den = 1;
+ }
+
+ if (gb.BitRead(1)) { // overscan_info_present_flag
+ gb.BitRead(1); // overscan_appropriate_flag
+ }
+
+ if (gb.BitRead(1)) { // video_signal_type_present_flag
+ gb.BitRead(3); // video_format
+ gb.BitRead(1); // video_full_range_flag
+ if (gb.BitRead(1)) { // colour_description_present_flag
+ gb.BitRead(8); // colour_primaries
+ gb.BitRead(8); // transfer_characteristics
+ gb.BitRead(8); // matrix_coefficients
+ }
+ }
+ if (gb.BitRead(1)) { // chroma_location_info_present_flag
+ gb.UExpGolombRead(); // chroma_sample_loc_type_top_field
+ gb.UExpGolombRead(); // chroma_sample_loc_type_bottom_field
+ }
+ if (gb.BitRead(1)) { // timing_info_present_flag
+ __int64 num_units_in_tick = gb.BitRead(32);
+ __int64 time_scale = gb.BitRead(32);
+ /*long fixed_frame_rate_flag = */gb.BitRead(1);
+
+ // Trick for weird parameters
+ if ((num_units_in_tick < 1000) || (num_units_in_tick > 1001)) {
+ if ((time_scale % num_units_in_tick != 0) && ((time_scale * 1001) % num_units_in_tick == 0)) {
+ time_scale = (time_scale * 1001) / num_units_in_tick;
+ num_units_in_tick = 1001;
+ } else {
+ time_scale = (time_scale * 1000) / num_units_in_tick;
+ num_units_in_tick = 1000;
+ }
+ }
+ time_scale = time_scale / 2; // VUI consider fields even for progressive stream : divide by 2!
+
+ if (time_scale) {
+ h.AvgTimePerFrame = (10000000I64 * num_units_in_tick) / time_scale;
+ }
+ }
+
+ bool nalflag = !!gb.BitRead(1); // nal_hrd_parameters_present_flag
+ if (nalflag) {
+ if (HrdParameters(gb) < 0) {
+ return false;
+ }
+ }
+ bool vlcflag = !!gb.BitRead(1); // vlc_hrd_parameters_present_flag
+ if (vlcflag) {
+ if (HrdParameters(gb) < 0) {
+ return false;
+ }
+ }
+ if (nalflag || vlcflag) {
+ gb.BitRead(1); // low_delay_hrd_flag
+ }
+
+ gb.BitRead(1); // pic_struct_present_flag
+ if (gb.BitRead(1)) { // bitstream_restriction_flag
+ gb.BitRead(1); // motion_vectors_over_pic_boundaries_flag
+ gb.UExpGolombRead(); // max_bytes_per_pic_denom
+ gb.UExpGolombRead(); // max_bits_per_mb_denom
+ gb.UExpGolombRead(); // log2_max_mv_length_horizontal
+ gb.UExpGolombRead(); // log2_max_mv_length_vertical
+ UINT64 num_reorder_frames = gb.UExpGolombRead(); // num_reorder_frames
+ gb.UExpGolombRead(); // max_dec_frame_buffering
+
+ if (gb.GetSize() < gb.GetPos()) {
+ num_reorder_frames = 0;
+ }
+ if (num_reorder_frames > 16U) {
+ return false;
+ }
+ }
+ }
+
+ if (index == index_subsetsps) {
+ if (h.profile == 83 || h.profile == 86) {
+ // TODO: SVC extensions
+ return false;
+ } else if (h.profile == 118 || h.profile == 128) {
+ gb.BitRead(1); // bit_equal_to_one
+
+ // seq_parameter_set_mvc_extension
+ h.views = (unsigned int) gb.UExpGolombRead() + 1;
+
+ /*
+ for (unsigned int i = 0; i < h.views; i++) {
+ gb.UExpGolombRead(); // view_id
+ }
+
+ for (unsigned int i = 1; i < h.views; i++) {
+ for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_anchor_refs_l0
+ gb.UExpGolombRead(); // anchor_refs_l0
+ }
+ for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_anchor_refs_l1
+ gb.UExpGolombRead(); // anchor_refs_l1
+ }
+ }
+
+ for (unsigned int i = 1; i < h.views; i++) {
+ for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_non_anchor_refs_l0
+ gb.UExpGolombRead(); // non_anchor_refs_l0
+ }
+ for (int j = 0; j < gb.UExpGolombRead(); j++) { // num_non_anchor_refs_l1
+ gb.UExpGolombRead(); // non_anchor_refs_l1
+ }
+ }
+
+ for (unsigned int i = 0; i <= gb.UExpGolombRead(); i++) { // num_level_values_signalled_minus1
+ gb.BitRead(8); // level_idc
+ for (int j = 0; j <= gb.UExpGolombRead(); j++) { // num_applicable_ops_minus1
+ gb.BitRead(3); // applicable_op_temporal_id
+ for (int k = 0; k <= gb.UExpGolombRead(); k++) { // applicable_op_num_target_views_minus1
+ gb.UExpGolombRead(); // applicable_op_traget_view_id
+ }
+ gb.UExpGolombRead(); // applicable_op_num_views_minus1
+ }
+ }
+
+ if (gb.BitRead(1)) { // mvc_vui_parameters_present_flag
+ // mvc_vui_parameters_extension
+ for (unsigned int i = 0; i <= gb.UExpGolombRead(); i++) { // vui_mvc_num_ops_minus1
+ gb.BitRead(3);
+ for (unsigned int j = 0; j <= gb.UExpGolombRead(); j++) { // vui_mvc_num_target_output_views_minus1
+ gb.UExpGolombRead(); // vui_mvc_view_id
+ }
+ if (gb.BitRead(1)) { // vui_mvc_timing_info_present_flag
+ gb.BitRead(32); // vui_mvc_num_units_in_tick
+ gb.BitRead(32); // vui_mvc_time_scale
+ gb.BitRead(1); // vui_mvc_fixed_frame_rate_flag
+ }
+ bool nalflag = gb.BitRead(1); // vui_mvc_nal_hrd_parameters_present_flag
+ if (nalflag) {
+ HrdParameters(gb);
+ }
+ bool vclflag = gb.BitRead(1); // vui_mvc_vcl_hrd_parameters_present_flag
+ if (vclflag) {
+ HrdParameters(gb);
+ }
+ if (nalflag || vclflag) {
+ gb.BitRead(1); // vui_mvc_low_delay_hrd_flag
+ }
+ gb.BitRead(1); // vui_mvc_pic_struct_present_flag
+ }
+ }
+ */
+ }
+ }
+
+ unsigned int mb_Width = (unsigned int)pic_width_in_mbs_minus1 + 1;
+ unsigned int mb_Height = ((unsigned int)pic_height_in_map_units_minus1 + 1) * (2 - frame_mbs_only_flag);
+ BYTE CHROMA444 = (chroma_format_idc == 3);
+
+ h.width = 16 * mb_Width - (2u >> CHROMA444) * min(h.crop_right, (8u << CHROMA444) - 1);
+ if (frame_mbs_only_flag) {
+ h.height = 16 * mb_Height - (2u >> CHROMA444) * min(h.crop_bottom, (8u << CHROMA444) - 1);
+ } else {
+ h.height = 16 * mb_Height - (4u >> CHROMA444) * min(h.crop_bottom, (8u << CHROMA444) - 1);
+ }
+
+ if (h.height < 100 || h.width < 100) {
+ return false;
+ }
+
+ if (h.height == 1088) {
+ h.height = 1080; // Prevent blur lines
+ }
+
+ return true;
}
bool CBaseSplitterFileEx::Read(vc1hdr& h, int len, CMediaType* pmt, int guid_flag)
{
- memset(&h, 0, sizeof(h));
-
- __int64 endpos = GetPos() + len; // - sequence header length
- __int64 extrapos = 0, extralen = 0;
- int nFrameRateNum = 0, nFrameRateDen = 1;
-
- if (GetPos() < endpos+4 && BitRead(32, true) == 0x0000010F) {
- extrapos = GetPos();
-
- BitRead(32);
-
- h.profile = (BYTE)BitRead(2);
-
- // Check if advanced profile
- if (h.profile != 3) {
- return false;
- }
-
- h.level = (BYTE)BitRead(3);
- h.chromaformat = (BYTE)BitRead(2);
-
- // (fps-2)/4 (->30)
- h.frmrtq_postproc = (BYTE)BitRead(3); //common
- // (bitrate-32kbps)/64kbps
- h.bitrtq_postproc = (BYTE)BitRead(5); //common
- h.postprocflag = (BYTE)BitRead(1); //common
-
- h.width = ((unsigned int)BitRead(12) + 1) << 1;
- h.height = ((unsigned int)BitRead(12) + 1) << 1;
-
- h.broadcast = (BYTE)BitRead(1);
- h.interlace = (BYTE)BitRead(1);
- h.tfcntrflag = (BYTE)BitRead(1);
- h.finterpflag = (BYTE)BitRead(1);
- BitRead(1); // reserved
- h.psf = (BYTE)BitRead(1);
- if (BitRead(1)) {
- int ar = 0;
- BitRead(14);
- BitRead(14);
- if (BitRead(1)) {
- ar = (int)BitRead(4);
- }
- if (ar && ar < 14) {
- h.sar.num = pixel_aspect[ar][0];
- h.sar.den = pixel_aspect[ar][1];
- } else if (ar == 15) {
- h.sar.num = (BYTE)BitRead(8);
- h.sar.den = (BYTE)BitRead(8);
- }
-
- // Read framerate
- const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 };
- const int ff_vc1_fps_dr[2] = { 1000, 1001 };
-
- if (BitRead(1)) {
- if (BitRead(1)) {
- nFrameRateNum = 32;
- nFrameRateDen = (int)BitRead(16) + 1;
- } else {
- int nr, dr;
- nr = (int)BitRead(8);
- dr = (int)BitRead(4);
- if (nr && nr < 8 && dr && dr < 3) {
- nFrameRateNum = ff_vc1_fps_dr[dr - 1];
- nFrameRateDen = ff_vc1_fps_nr[nr - 1] * 1000;
- }
- }
- }
-
- }
-
- Seek(extrapos+4);
- extralen = 0;
- int parse = 0; // really need a signed type? may be unsigned will be better
-
- while (GetPos() < endpos+4 && ((parse == 0x0000010E) || (parse & 0xFFFFFF00) != 0x00000100)) {
- parse = (parse<<8) | (int)BitRead(8);
- extralen++;
- }
- }
-
- if (!extrapos || !extralen) {
- return false;
- }
-
- if (!pmt) {
- return true;
- }
-
- {
- pmt->majortype = MEDIATYPE_Video;
- switch (guid_flag) {
- case 1: pmt->subtype = FOURCCMap('1CVW');
- break;
- case 2: pmt->subtype = MEDIASUBTYPE_WVC1_CYBERLINK;
- break;
- case 3: pmt->subtype = MEDIASUBTYPE_WVC1_ARCSOFT;
- break;
- }
- pmt->formattype = FORMAT_VIDEOINFO2;
- int vi_len = sizeof(VIDEOINFOHEADER2) + (int)extralen + 1;
- VIDEOINFOHEADER2* vi = (VIDEOINFOHEADER2*)DNew BYTE[vi_len];
- memset(vi, 0, vi_len);
- vi->AvgTimePerFrame = (10000000I64*nFrameRateNum)/nFrameRateDen;
-
- if (!h.sar.num) h.sar.num = 1;
- if (!h.sar.den) h.sar.den = 1;
- CSize aspect = CSize(h.width * h.sar.num, h.height * h.sar.den);
- if (h.width == h.sar.num && h.height == h.sar.den) {
- aspect = CSize(h.width, h.height);
- }
- int lnko = LNKO(aspect.cx, aspect.cy);
- if (lnko > 1) {
- aspect.cx /= lnko, aspect.cy /= lnko;
- }
-
- vi->dwPictAspectRatioX = aspect.cx;
- vi->dwPictAspectRatioY = aspect.cy;
- vi->bmiHeader.biSize = sizeof(vi->bmiHeader);
- vi->bmiHeader.biWidth = h.width;
- vi->bmiHeader.biHeight = h.height;
- vi->bmiHeader.biCompression = '1CVW';
- BYTE* p = (BYTE*)vi + sizeof(VIDEOINFOHEADER2);
- *p++ = 0;
- Seek(extrapos);
- ByteRead(p, extralen);
- pmt->SetFormat((BYTE*)vi, vi_len);
- delete [] vi;
- }
- return true;
+ memset(&h, 0, sizeof(h));
+
+ __int64 endpos = GetPos() + len; // - sequence header length
+ __int64 extrapos = 0, extralen = 0;
+ int nFrameRateNum = 0, nFrameRateDen = 1;
+
+ if (GetPos() < endpos + 4 && BitRead(32, true) == 0x0000010F) {
+ extrapos = GetPos();
+
+ BitRead(32);
+
+ h.profile = (BYTE)BitRead(2);
+
+ // Check if advanced profile
+ if (h.profile != 3) {
+ return false;
+ }
+
+ h.level = (BYTE)BitRead(3);
+ h.chromaformat = (BYTE)BitRead(2);
+
+ // (fps-2)/4 (->30)
+ h.frmrtq_postproc = (BYTE)BitRead(3); //common
+ // (bitrate-32kbps)/64kbps
+ h.bitrtq_postproc = (BYTE)BitRead(5); //common
+ h.postprocflag = (BYTE)BitRead(1); //common
+
+ h.width = ((unsigned int)BitRead(12) + 1) << 1;
+ h.height = ((unsigned int)BitRead(12) + 1) << 1;
+
+ h.broadcast = (BYTE)BitRead(1);
+ h.interlace = (BYTE)BitRead(1);
+ h.tfcntrflag = (BYTE)BitRead(1);
+ h.finterpflag = (BYTE)BitRead(1);
+ BitRead(1); // reserved
+ h.psf = (BYTE)BitRead(1);
+ if (BitRead(1)) {
+ int ar = 0;
+ BitRead(14);
+ BitRead(14);
+ if (BitRead(1)) {
+ ar = (int)BitRead(4);
+ }
+ if (ar && ar < 14) {
+ h.sar.num = pixel_aspect[ar][0];
+ h.sar.den = pixel_aspect[ar][1];
+ } else if (ar == 15) {
+ h.sar.num = (BYTE)BitRead(8);
+ h.sar.den = (BYTE)BitRead(8);
+ }
+
+ // Read framerate
+ const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 };
+ const int ff_vc1_fps_dr[2] = { 1000, 1001 };
+
+ if (BitRead(1)) {
+ if (BitRead(1)) {
+ nFrameRateNum = 32;
+ nFrameRateDen = (int)BitRead(16) + 1;
+ } else {
+ int nr, dr;
+ nr = (int)BitRead(8);
+ dr = (int)BitRead(4);
+ if (nr && nr < 8 && dr && dr < 3) {
+ nFrameRateNum = ff_vc1_fps_dr[dr - 1];
+ nFrameRateDen = ff_vc1_fps_nr[nr - 1] * 1000;
+ }
+ }
+ }
+
+ }
+
+ Seek(extrapos + 4);
+ extralen = 0;
+ int parse = 0; // really need a signed type? may be unsigned will be better
+
+ while (GetPos() < endpos + 4 && ((parse == 0x0000010E) || (parse & 0xFFFFFF00) != 0x00000100)) {
+ parse = (parse << 8) | (int)BitRead(8);
+ extralen++;
+ }
+ }
+
+ if (!extrapos || !extralen) {
+ return false;
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ {
+ pmt->majortype = MEDIATYPE_Video;
+ switch (guid_flag) {
+ case 1: pmt->subtype = FOURCCMap('1CVW');
+ break;
+ case 2: pmt->subtype = MEDIASUBTYPE_WVC1_CYBERLINK;
+ break;
+ case 3: pmt->subtype = MEDIASUBTYPE_WVC1_ARCSOFT;
+ break;
+ }
+ pmt->formattype = FORMAT_VIDEOINFO2;
+ int vi_len = sizeof(VIDEOINFOHEADER2) + (int)extralen + 1;
+ VIDEOINFOHEADER2* vi = (VIDEOINFOHEADER2*)DNew BYTE[vi_len];
+ memset(vi, 0, vi_len);
+ vi->AvgTimePerFrame = (10000000I64 * nFrameRateNum) / nFrameRateDen;
+
+ if (!h.sar.num) { h.sar.num = 1; }
+ if (!h.sar.den) { h.sar.den = 1; }
+ CSize aspect = CSize(h.width * h.sar.num, h.height * h.sar.den);
+ if (h.width == h.sar.num && h.height == h.sar.den) {
+ aspect = CSize(h.width, h.height);
+ }
+ int lnko = LNKO(aspect.cx, aspect.cy);
+ if (lnko > 1) {
+ aspect.cx /= lnko, aspect.cy /= lnko;
+ }
+
+ vi->dwPictAspectRatioX = aspect.cx;
+ vi->dwPictAspectRatioY = aspect.cy;
+ vi->bmiHeader.biSize = sizeof(vi->bmiHeader);
+ vi->bmiHeader.biWidth = h.width;
+ vi->bmiHeader.biHeight = h.height;
+ vi->bmiHeader.biCompression = '1CVW';
+ BYTE* p = (BYTE*)vi + sizeof(VIDEOINFOHEADER2);
+ *p++ = 0;
+ Seek(extrapos);
+ ByteRead(p, extralen);
+ pmt->SetFormat((BYTE*)vi, vi_len);
+ delete [] vi;
+ }
+ return true;
}
bool CBaseSplitterFileEx::Read(dvbsub& h, int len, CMediaType* pmt)
{
- memset(&h, 0, sizeof(h));
+ memset(&h, 0, sizeof(h));
- if ((BitRead(32, true) & 0xFFFFFF00) == 0x20000f00) {
- static const SUBTITLEINFO SubFormat = { 0, "", L"" };
+ if ((BitRead(32, true) & 0xFFFFFF00) == 0x20000f00) {
+ static const SUBTITLEINFO SubFormat = { 0, "", L"" };
- pmt->majortype = MEDIATYPE_Subtitle;
- pmt->subtype = MEDIASUBTYPE_DVB_SUBTITLES;
- pmt->formattype = FORMAT_None;
- pmt->SetFormat ((BYTE*)&SubFormat, sizeof(SUBTITLEINFO));
+ pmt->majortype = MEDIATYPE_Subtitle;
+ pmt->subtype = MEDIASUBTYPE_DVB_SUBTITLES;
+ pmt->formattype = FORMAT_None;
+ pmt->SetFormat((BYTE*)&SubFormat, sizeof(SUBTITLEINFO));
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/*
To see working buffer in debugger, look :
- - m_pCache.m_p for the cached buffer
- - m_pos for current read position
+ - m_pCache.m_p for the cached buffer
+ - m_pos for current read position
*/
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h
index a42d54b8c..285a9a008 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h
+++ b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h
@@ -26,434 +26,412 @@
#include "BaseSplitterFile.h"
#include "../../../DSUtil/Mpeg2Def.h"
-#define MAX_SPSPPS 256 // Max size for a SPS/PPS packet
+#define MAX_SPSPPS 256 // Max size for a SPS/PPS packet
class CGolombBuffer;
-static const byte pixel_aspect[17][2]= {
- {0, 1},
- {1, 1},
- {12, 11},
- {10, 11},
- {16, 11},
- {40, 33},
- {24, 11},
- {20, 11},
- {32, 11},
- {80, 33},
- {18, 11},
- {15, 11},
- {64, 33},
- {160,99},
- {4, 3},
- {3, 2},
- {2, 1},
+static const byte pixel_aspect[17][2] = {
+ {0, 1},
+ {1, 1},
+ {12, 11},
+ {10, 11},
+ {16, 11},
+ {40, 33},
+ {24, 11},
+ {20, 11},
+ {32, 11},
+ {80, 33},
+ {18, 11},
+ {15, 11},
+ {64, 33},
+ {160, 99},
+ {4, 3},
+ {3, 2},
+ {2, 1},
};
class CBaseSplitterFileEx : public CBaseSplitterFile
{
- int m_tslen; // transport stream packet length (188 or 192 bytes, auto-detected)
+ int m_tslen; // transport stream packet length (188 or 192 bytes, auto-detected)
protected :
- REFERENCE_TIME m_rtPTSOffset;
+ REFERENCE_TIME m_rtPTSOffset;
public:
- CBaseSplitterFileEx(IAsyncReader* pReader, HRESULT& hr, int cachelen = DEFAULT_CACHE_LENGTH, bool fRandomAccess = true, bool fStreaming = false);
- virtual ~CBaseSplitterFileEx();
+ CBaseSplitterFileEx(IAsyncReader* pReader, HRESULT& hr, int cachelen = DEFAULT_CACHE_LENGTH, bool fRandomAccess = true, bool fStreaming = false);
+ virtual ~CBaseSplitterFileEx();
- // using CBaseSplitterFile::Read;
+ // using CBaseSplitterFile::Read;
- bool NextMpegStartCode(BYTE& b, __int64 len = 65536);
+ bool NextMpegStartCode(BYTE& b, __int64 len = 65536);
#pragma pack(push, 1)
- enum mpeg_t {mpegunk, mpeg1, mpeg2};
-
- struct pshdr {
- mpeg_t type;
- UINT64 scr, bitrate;
- };
-
- struct pssyshdr {
- DWORD rate_bound;
- BYTE video_bound, audio_bound;
- bool fixed_rate, csps;
- bool sys_video_loc_flag, sys_audio_loc_flag;
- };
-
- struct peshdr {
- WORD len;
-
- BYTE type:2, fpts:1, fdts:1;
- REFERENCE_TIME pts, dts;
-
- // mpeg1 stuff
- UINT64 std_buff_size;
-
- // mpeg2 stuff
- BYTE scrambling:2, priority:1, alignment:1, copyright:1, original:1;
- BYTE escr:1, esrate:1, dsmtrickmode:1, morecopyright:1, crc:1, extension:1;
- BYTE hdrlen;
-
- BYTE id_ext;
-
- struct peshdr() {
- memset(this, 0, sizeof(*this));
- }
- };
-
- struct seqhdr {
- WORD width;
- WORD height;
- BYTE ar:4;
- DWORD ifps;
- DWORD bitrate;
- DWORD vbv;
- BYTE constrained:1;
- BYTE fiqm:1;
- BYTE iqm[64];
- BYTE fniqm:1;
- BYTE niqm[64];
- // ext
- BYTE startcodeid:4;
- BYTE profile_levelescape:1;
- BYTE profile:3;
- BYTE level:4;
- BYTE progressive:1;
- BYTE chroma:2;
- BYTE lowdelay:1;
- // misc
- int arx, ary;
- };
-
- struct mpahdr
- {
- WORD sync:11;
- WORD version:2;
- WORD layer:2;
- WORD crc:1;
- WORD bitrate:4;
- WORD freq:2;
- WORD padding:1;
- WORD privatebit:1;
- WORD channels:2;
- WORD modeext:2;
- WORD copyright:1;
- WORD original:1;
- WORD emphasis:2;
-
- int nSamplesPerSec, FrameSize, nBytesPerSec;
- REFERENCE_TIME rtDuration;
- };
-
- struct aachdr
- {
- WORD sync:12;
- WORD version:1;
- WORD layer:2;
- WORD fcrc:1;
- WORD profile:2;
- WORD freq:4;
- WORD privatebit:1;
- WORD channels:3;
- WORD original:1;
- WORD home:1; // ?
-
- WORD copyright_id_bit:1;
- WORD copyright_id_start:1;
- WORD aac_frame_length:13;
- WORD adts_buffer_fullness:11;
- WORD no_raw_data_blocks_in_frame:2;
-
- WORD crc;
-
- int FrameSize, nBytesPerSec;
- REFERENCE_TIME rtDuration;
- };
-
- struct latm_aachdr
- {
- // nothing ;)
- };
-
- struct ac3hdr
- {
- WORD sync;
- WORD crc1;
- BYTE fscod:2;
- BYTE frmsizecod:6;
- BYTE bsid:5;
- BYTE bsmod:3;
- BYTE acmod:3;
- BYTE cmixlev:2;
- BYTE surmixlev:2;
- BYTE dsurmod:2;
- BYTE lfeon:1;
- BYTE sr_shift;
- // E-AC3 header
- BYTE frame_type;
- BYTE substreamid;
- WORD frame_size;
- BYTE sr_code;
- WORD sample_rate;
- BYTE num_blocks;
- // the rest is unimportant for us
- };
-
- struct dtshdr
- {
- DWORD sync;
- BYTE frametype:1;
- BYTE deficitsamplecount:5;
- BYTE fcrc:1;
- BYTE nblocks:7;
- WORD framebytes;
- BYTE amode:6;
- BYTE sfreq:4;
- BYTE rate:5;
-
- BYTE downmix:1;
- BYTE dynrange:1;
- BYTE timestamp:1;
- BYTE aux_data:1;
- BYTE hdcd:1;
- BYTE ext_descr:3;
- BYTE ext_coding:1;
- BYTE aspf:1;
- BYTE lfe:2;
- BYTE predictor_history:1;
- };
-
- struct lpcmhdr
- {
- BYTE emphasis:1;
- BYTE mute:1;
- BYTE reserved1:1;
- BYTE framenum:5;
- BYTE quantwordlen:2;
- BYTE freq:2; // 48, 96, 44.1, 32
- BYTE reserved2:1;
- BYTE channels:3; // +1
- BYTE drc; // 0x80: off
- };
-
- struct dvdalpcmhdr
- {
- // http://dvd-audio.sourceforge.net/spec/aob.shtml
- WORD firstaudioframe;
- BYTE unknown1;
- BYTE bitpersample1:4;
- BYTE bitpersample2:4;
- BYTE samplerate1:4;
- BYTE samplerate2:4;
- BYTE unknown2;
- BYTE groupassignment;
- BYTE unknown3;
- };
-
- struct hdmvlpcmhdr
- {
- WORD size;
- BYTE channels:4;
- BYTE samplerate:4;
- BYTE bitpersample:2;
- };
-
- struct mlphdr
- {
- DWORD size;
- //DWORD samplerate;
- //WORD bitdepth;
- //WORD channels;
- };
-
- struct dvdspuhdr
- {
- // nothing ;)
- };
-
- struct hdmvsubhdr
- {
- // nothing ;)
- };
-
- struct svcdspuhdr
- {
- // nothing ;)
- };
-
- struct cvdspuhdr
- {
- // nothing ;)
- };
-
- struct ps2audhdr
- {
- // 'SShd' + len (0x18)
- DWORD unk1;
- DWORD freq;
- DWORD channels;
- DWORD interleave; // bytes per channel
- // padding: FF .. FF
- // 'SSbd' + len
- // pcm or adpcm data
- };
-
- struct ps2subhdr
- {
- // nothing ;)
- };
-
- struct trhdr
- {
- BYTE sync; // 0x47
- BYTE error:1;
- BYTE payloadstart:1;
- BYTE transportpriority:1;
- WORD pid:13;
- BYTE scrambling:2;
- BYTE adapfield:1;
- BYTE payload:1;
- BYTE counter:4;
- // if adapfield set
- BYTE length;
- BYTE discontinuity:1;
- BYTE randomaccess:1;
- BYTE priority:1;
- BYTE fPCR:1;
- BYTE OPCR:1;
- BYTE splicingpoint:1;
- BYTE privatedata:1;
- BYTE extension:1;
- // TODO: add more fields here when the flags above are set (they aren't very interesting...)
- __int64 PCR;
-
- int bytes;
- __int64 next;
- };
-
- struct trsechdr
- {
- BYTE table_id;
- WORD section_syntax_indicator:1;
- WORD zero:1;
- WORD reserved1:2;
- WORD section_length:12;
- WORD transport_stream_id;
- BYTE reserved2:2;
- BYTE version_number:5;
- BYTE current_next_indicator:1;
- BYTE section_number;
- BYTE last_section_number;
- };
-
- // http://multimedia.cx/mirror/av_format_v1.pdf
- struct pvahdr
- {
- WORD sync; // 'VA'
- BYTE streamid; // 1 - video, 2 - audio
- BYTE counter;
- BYTE res1; // 0x55
- BYTE res2:3;
- BYTE fpts:1;
- BYTE postbytes:2;
- BYTE prebytes:2;
- WORD length;
- REFERENCE_TIME pts;
- };
-
- enum spsppsindex {
- index_unknown = -1,
- index_subsetsps = 0,
- index_sps = 1,
- index_pps1 = 2,
- index_pps2 = 3,
- };
-
- struct spsppsdata
- {
- BYTE buffer[MAX_SPSPPS];
- unsigned int size;
- bool complete;
- };
-
- struct avchdr
- {
- BYTE profile, level;
- unsigned int width, height;
- unsigned int views;
- unsigned int crop_left, crop_right, crop_top, crop_bottom;
- __int64 AvgTimePerFrame;
-
- struct sar {
- WORD num;
- WORD den;
- } sar;
-
- spsppsdata spspps[4];
- BYTE lastid;
-
- avchdr() {
- memset(spspps, 0, sizeof(spspps));
- lastid = 0;
- views = 1;
- AvgTimePerFrame = 0;
- }
- };
-
- struct vc1hdr
- {
- BYTE profile;
- BYTE level;
- BYTE chromaformat;
- BYTE frmrtq_postproc;
- BYTE bitrtq_postproc;
- BYTE postprocflag;
- BYTE broadcast;
- BYTE interlace;
- BYTE tfcntrflag;
- BYTE finterpflag;
- BYTE psf;
- unsigned int width, height;
- struct sar {
- BYTE num;
- BYTE den;
- } sar;
- };
-
- struct dvbsub
- {
- // nothing ;)
- };
+ enum mpeg_t {mpegunk, mpeg1, mpeg2};
+
+ struct pshdr {
+ mpeg_t type;
+ UINT64 scr, bitrate;
+ };
+
+ struct pssyshdr {
+ DWORD rate_bound;
+ BYTE video_bound, audio_bound;
+ bool fixed_rate, csps;
+ bool sys_video_loc_flag, sys_audio_loc_flag;
+ };
+
+ struct peshdr {
+ WORD len;
+
+ BYTE type: 2, fpts: 1, fdts: 1;
+ REFERENCE_TIME pts, dts;
+
+ // mpeg1 stuff
+ UINT64 std_buff_size;
+
+ // mpeg2 stuff
+ BYTE scrambling: 2, priority: 1, alignment: 1, copyright: 1, original: 1;
+ BYTE escr: 1, esrate: 1, dsmtrickmode: 1, morecopyright: 1, crc: 1, extension: 1;
+ BYTE hdrlen;
+
+ BYTE id_ext;
+
+ struct peshdr() {
+ memset(this, 0, sizeof(*this));
+ }
+ };
+
+ struct seqhdr {
+ WORD width;
+ WORD height;
+ BYTE ar: 4;
+ DWORD ifps;
+ DWORD bitrate;
+ DWORD vbv;
+ BYTE constrained: 1;
+ BYTE fiqm: 1;
+ BYTE iqm[64];
+ BYTE fniqm: 1;
+ BYTE niqm[64];
+ // ext
+ BYTE startcodeid: 4;
+ BYTE profile_levelescape: 1;
+ BYTE profile: 3;
+ BYTE level: 4;
+ BYTE progressive: 1;
+ BYTE chroma: 2;
+ BYTE lowdelay: 1;
+ // misc
+ int arx, ary;
+ };
+
+ struct mpahdr {
+ WORD sync: 11;
+ WORD version: 2;
+ WORD layer: 2;
+ WORD crc: 1;
+ WORD bitrate: 4;
+ WORD freq: 2;
+ WORD padding: 1;
+ WORD privatebit: 1;
+ WORD channels: 2;
+ WORD modeext: 2;
+ WORD copyright: 1;
+ WORD original: 1;
+ WORD emphasis: 2;
+
+ int nSamplesPerSec, FrameSize, nBytesPerSec;
+ REFERENCE_TIME rtDuration;
+ };
+
+ struct aachdr {
+ WORD sync: 12;
+ WORD version: 1;
+ WORD layer: 2;
+ WORD fcrc: 1;
+ WORD profile: 2;
+ WORD freq: 4;
+ WORD privatebit: 1;
+ WORD channels: 3;
+ WORD original: 1;
+ WORD home: 1; // ?
+
+ WORD copyright_id_bit: 1;
+ WORD copyright_id_start: 1;
+ WORD aac_frame_length: 13;
+ WORD adts_buffer_fullness: 11;
+ WORD no_raw_data_blocks_in_frame: 2;
+
+ WORD crc;
+
+ int FrameSize, nBytesPerSec;
+ REFERENCE_TIME rtDuration;
+ };
+
+ struct latm_aachdr {
+ // nothing ;)
+ };
+
+ struct ac3hdr {
+ WORD sync;
+ WORD crc1;
+ BYTE fscod: 2;
+ BYTE frmsizecod: 6;
+ BYTE bsid: 5;
+ BYTE bsmod: 3;
+ BYTE acmod: 3;
+ BYTE cmixlev: 2;
+ BYTE surmixlev: 2;
+ BYTE dsurmod: 2;
+ BYTE lfeon: 1;
+ BYTE sr_shift;
+ // E-AC3 header
+ BYTE frame_type;
+ BYTE substreamid;
+ WORD frame_size;
+ BYTE sr_code;
+ WORD sample_rate;
+ BYTE num_blocks;
+ // the rest is unimportant for us
+ };
+
+ struct dtshdr {
+ DWORD sync;
+ BYTE frametype: 1;
+ BYTE deficitsamplecount: 5;
+ BYTE fcrc: 1;
+ BYTE nblocks: 7;
+ WORD framebytes;
+ BYTE amode: 6;
+ BYTE sfreq: 4;
+ BYTE rate: 5;
+
+ BYTE downmix: 1;
+ BYTE dynrange: 1;
+ BYTE timestamp: 1;
+ BYTE aux_data: 1;
+ BYTE hdcd: 1;
+ BYTE ext_descr: 3;
+ BYTE ext_coding: 1;
+ BYTE aspf: 1;
+ BYTE lfe: 2;
+ BYTE predictor_history: 1;
+ };
+
+ struct lpcmhdr {
+ BYTE emphasis: 1;
+ BYTE mute: 1;
+ BYTE reserved1: 1;
+ BYTE framenum: 5;
+ BYTE quantwordlen: 2;
+ BYTE freq: 2; // 48, 96, 44.1, 32
+ BYTE reserved2: 1;
+ BYTE channels: 3; // +1
+ BYTE drc; // 0x80: off
+ };
+
+ struct dvdalpcmhdr {
+ // http://dvd-audio.sourceforge.net/spec/aob.shtml
+ WORD firstaudioframe;
+ BYTE unknown1;
+ BYTE bitpersample1: 4;
+ BYTE bitpersample2: 4;
+ BYTE samplerate1: 4;
+ BYTE samplerate2: 4;
+ BYTE unknown2;
+ BYTE groupassignment;
+ BYTE unknown3;
+ };
+
+ struct hdmvlpcmhdr {
+ WORD size;
+ BYTE channels: 4;
+ BYTE samplerate: 4;
+ BYTE bitpersample: 2;
+ };
+
+ struct mlphdr {
+ DWORD size;
+ //DWORD samplerate;
+ //WORD bitdepth;
+ //WORD channels;
+ };
+
+ struct dvdspuhdr {
+ // nothing ;)
+ };
+
+ struct hdmvsubhdr {
+ // nothing ;)
+ };
+
+ struct svcdspuhdr {
+ // nothing ;)
+ };
+
+ struct cvdspuhdr {
+ // nothing ;)
+ };
+
+ struct ps2audhdr {
+ // 'SShd' + len (0x18)
+ DWORD unk1;
+ DWORD freq;
+ DWORD channels;
+ DWORD interleave; // bytes per channel
+ // padding: FF .. FF
+ // 'SSbd' + len
+ // pcm or adpcm data
+ };
+
+ struct ps2subhdr {
+ // nothing ;)
+ };
+
+ struct trhdr {
+ BYTE sync; // 0x47
+ BYTE error: 1;
+ BYTE payloadstart: 1;
+ BYTE transportpriority: 1;
+ WORD pid: 13;
+ BYTE scrambling: 2;
+ BYTE adapfield: 1;
+ BYTE payload: 1;
+ BYTE counter: 4;
+ // if adapfield set
+ BYTE length;
+ BYTE discontinuity: 1;
+ BYTE randomaccess: 1;
+ BYTE priority: 1;
+ BYTE fPCR: 1;
+ BYTE OPCR: 1;
+ BYTE splicingpoint: 1;
+ BYTE privatedata: 1;
+ BYTE extension: 1;
+ // TODO: add more fields here when the flags above are set (they aren't very interesting...)
+ __int64 PCR;
+
+ int bytes;
+ __int64 next;
+ };
+
+ struct trsechdr {
+ BYTE table_id;
+ WORD section_syntax_indicator: 1;
+ WORD zero: 1;
+ WORD reserved1: 2;
+ WORD section_length: 12;
+ WORD transport_stream_id;
+ BYTE reserved2: 2;
+ BYTE version_number: 5;
+ BYTE current_next_indicator: 1;
+ BYTE section_number;
+ BYTE last_section_number;
+ };
+
+ // http://multimedia.cx/mirror/av_format_v1.pdf
+ struct pvahdr {
+ WORD sync; // 'VA'
+ BYTE streamid; // 1 - video, 2 - audio
+ BYTE counter;
+ BYTE res1; // 0x55
+ BYTE res2: 3;
+ BYTE fpts: 1;
+ BYTE postbytes: 2;
+ BYTE prebytes: 2;
+ WORD length;
+ REFERENCE_TIME pts;
+ };
+
+ enum spsppsindex {
+ index_unknown = -1,
+ index_subsetsps = 0,
+ index_sps = 1,
+ index_pps1 = 2,
+ index_pps2 = 3,
+ };
+
+ struct spsppsdata {
+ BYTE buffer[MAX_SPSPPS];
+ unsigned int size;
+ bool complete;
+ };
+
+ struct avchdr {
+ BYTE profile, level;
+ unsigned int width, height;
+ unsigned int views;
+ unsigned int crop_left, crop_right, crop_top, crop_bottom;
+ __int64 AvgTimePerFrame;
+
+ struct sar {
+ WORD num;
+ WORD den;
+ } sar;
+
+ spsppsdata spspps[4];
+ BYTE lastid;
+
+ avchdr() {
+ memset(spspps, 0, sizeof(spspps));
+ lastid = 0;
+ views = 1;
+ AvgTimePerFrame = 0;
+ }
+ };
+
+ struct vc1hdr {
+ BYTE profile;
+ BYTE level;
+ BYTE chromaformat;
+ BYTE frmrtq_postproc;
+ BYTE bitrtq_postproc;
+ BYTE postprocflag;
+ BYTE broadcast;
+ BYTE interlace;
+ BYTE tfcntrflag;
+ BYTE finterpflag;
+ BYTE psf;
+ unsigned int width, height;
+ struct sar {
+ BYTE num;
+ BYTE den;
+ } sar;
+ };
+
+ struct dvbsub {
+ // nothing ;)
+ };
#pragma pack(pop)
- bool Read(pshdr& h);
- bool Read(pssyshdr& h);
- bool Read(peshdr& h, BYTE code);
- bool Read(seqhdr& h, int len, CMediaType* pmt = NULL);
- bool Read(mpahdr& h, int len, bool fAllowV25, CMediaType* pmt = NULL);
- bool Read(aachdr& h, int len, CMediaType* pmt = NULL, MPEG_TYPES m_type = mpeg_es);
- bool Read(latm_aachdr& h, int len, CMediaType* pmt = NULL);
- bool Read(ac3hdr& h, int len, CMediaType* pmt = NULL, bool find_sync = true, bool AC3CoreOnly = true);
- bool Read(dtshdr& h, int len, CMediaType* pmt = NULL, bool find_sync = true);
- bool Read(lpcmhdr& h, CMediaType* pmt = NULL);
- bool Read(dvdalpcmhdr& h, int len, CMediaType* pmt = NULL);
- bool Read(hdmvlpcmhdr& h, CMediaType* pmt = NULL);
- bool Read(mlphdr& h, int len, CMediaType* pmt = NULL, bool find_sync = false);
- bool Read(dvdspuhdr& h, CMediaType* pmt = NULL);
- bool Read(hdmvsubhdr& h, CMediaType* pmt = NULL, const char* language_code = NULL);
- bool Read(svcdspuhdr& h, CMediaType* pmt = NULL);
- bool Read(cvdspuhdr& h, CMediaType* pmt = NULL);
- bool Read(ps2audhdr& h, CMediaType* pmt = NULL);
- bool Read(ps2subhdr& h, CMediaType* pmt = NULL);
- bool Read(trhdr& h, bool fSync = true);
- bool Read(trsechdr& h);
- bool Read(pvahdr& h, bool fSync = true);
- bool Read(avchdr& h, int len, CMediaType* pmt = NULL);
- bool Read(vc1hdr& h, int len, CMediaType* pmt = NULL, int guid_flag = 1);
- bool Read(dvbsub& h, int len, CMediaType* pmt = NULL);
- bool Read(avchdr& h, spsppsindex index);
-
- int HrdParameters(CGolombBuffer& gb);
- void RemoveMpegEscapeCode(BYTE* dst, BYTE* src, int length);
+ bool Read(pshdr& h);
+ bool Read(pssyshdr& h);
+ bool Read(peshdr& h, BYTE code);
+ bool Read(seqhdr& h, int len, CMediaType* pmt = NULL);
+ bool Read(mpahdr& h, int len, bool fAllowV25, CMediaType* pmt = NULL);
+ bool Read(aachdr& h, int len, CMediaType* pmt = NULL, MPEG_TYPES m_type = mpeg_es);
+ bool Read(latm_aachdr& h, int len, CMediaType* pmt = NULL);
+ bool Read(ac3hdr& h, int len, CMediaType* pmt = NULL, bool find_sync = true, bool AC3CoreOnly = true);
+ bool Read(dtshdr& h, int len, CMediaType* pmt = NULL, bool find_sync = true);
+ bool Read(lpcmhdr& h, CMediaType* pmt = NULL);
+ bool Read(dvdalpcmhdr& h, int len, CMediaType* pmt = NULL);
+ bool Read(hdmvlpcmhdr& h, CMediaType* pmt = NULL);
+ bool Read(mlphdr& h, int len, CMediaType* pmt = NULL, bool find_sync = false);
+ bool Read(dvdspuhdr& h, CMediaType* pmt = NULL);
+ bool Read(hdmvsubhdr& h, CMediaType* pmt = NULL, const char* language_code = NULL);
+ bool Read(svcdspuhdr& h, CMediaType* pmt = NULL);
+ bool Read(cvdspuhdr& h, CMediaType* pmt = NULL);
+ bool Read(ps2audhdr& h, CMediaType* pmt = NULL);
+ bool Read(ps2subhdr& h, CMediaType* pmt = NULL);
+ bool Read(trhdr& h, bool fSync = true);
+ bool Read(trsechdr& h);
+ bool Read(pvahdr& h, bool fSync = true);
+ bool Read(avchdr& h, int len, CMediaType* pmt = NULL);
+ bool Read(vc1hdr& h, int len, CMediaType* pmt = NULL, int guid_flag = 1);
+ bool Read(dvbsub& h, int len, CMediaType* pmt = NULL);
+ bool Read(avchdr& h, spsppsindex index);
+
+ int HrdParameters(CGolombBuffer& gb);
+ void RemoveMpegEscapeCode(BYTE* dst, BYTE* src, int length);
};
diff --git a/src/filters/parser/BaseSplitter/MultiFiles.cpp b/src/filters/parser/BaseSplitter/MultiFiles.cpp
index 65a5b946c..d8d308131 100644
--- a/src/filters/parser/BaseSplitter/MultiFiles.cpp
+++ b/src/filters/parser/BaseSplitter/MultiFiles.cpp
@@ -28,173 +28,173 @@
IMPLEMENT_DYNAMIC(CMultiFiles, CObject)
CMultiFiles::CMultiFiles()
- : m_hFile(INVALID_HANDLE_VALUE)
- , m_llTotalLength(0)
- , m_nCurPart(-1)
- , m_pCurrentPTSOffset(NULL)
+ : m_hFile(INVALID_HANDLE_VALUE)
+ , m_llTotalLength(0)
+ , m_nCurPart(-1)
+ , m_pCurrentPTSOffset(NULL)
{
}
void CMultiFiles::Reset()
{
- m_strFiles.RemoveAll();
- m_FilesSize.RemoveAll();
- m_rtPtsOffsets.RemoveAll();
- m_llTotalLength = 0;
+ m_strFiles.RemoveAll();
+ m_FilesSize.RemoveAll();
+ m_rtPtsOffsets.RemoveAll();
+ m_llTotalLength = 0;
}
BOOL CMultiFiles::Open(LPCTSTR lpszFileName, UINT nOpenFlags)
{
- Reset();
- m_strFiles.Add (lpszFileName);
+ Reset();
+ m_strFiles.Add(lpszFileName);
- return OpenPart(0);
+ return OpenPart(0);
}
BOOL CMultiFiles::OpenFiles(CAtlList<CHdmvClipInfo::PlaylistItem>& files, UINT nOpenFlags)
{
- POSITION pos = files.GetHeadPosition();
- LARGE_INTEGER llSize;
- int nPos = 0;
- REFERENCE_TIME rtDur = 0;
-
- Reset();
- while (pos) {
- CHdmvClipInfo::PlaylistItem& s = files.GetNext(pos);
- m_strFiles.Add(s.m_strFileName);
- if (!OpenPart(nPos)) {
- return false;
- }
-
- llSize.QuadPart = 0;
- GetFileSizeEx (m_hFile, &llSize);
- m_llTotalLength += llSize.QuadPart;
- m_FilesSize.Add (llSize.QuadPart);
- m_rtPtsOffsets.Add (rtDur);
- rtDur += s.Duration();
- nPos++;
- }
-
- if (files.GetCount() > 1) {
- ClosePart();
- }
-
- return TRUE;
+ POSITION pos = files.GetHeadPosition();
+ LARGE_INTEGER llSize;
+ int nPos = 0;
+ REFERENCE_TIME rtDur = 0;
+
+ Reset();
+ while (pos) {
+ CHdmvClipInfo::PlaylistItem& s = files.GetNext(pos);
+ m_strFiles.Add(s.m_strFileName);
+ if (!OpenPart(nPos)) {
+ return false;
+ }
+
+ llSize.QuadPart = 0;
+ GetFileSizeEx(m_hFile, &llSize);
+ m_llTotalLength += llSize.QuadPart;
+ m_FilesSize.Add(llSize.QuadPart);
+ m_rtPtsOffsets.Add(rtDur);
+ rtDur += s.Duration();
+ nPos++;
+ }
+
+ if (files.GetCount() > 1) {
+ ClosePart();
+ }
+
+ return TRUE;
}
ULONGLONG CMultiFiles::Seek(LONGLONG lOff, UINT nFrom)
{
- LARGE_INTEGER llNewPos;
- LARGE_INTEGER llOff;
-
- if (m_strFiles.GetCount() == 1) {
- llOff.QuadPart = lOff;
- SetFilePointerEx (m_hFile, llOff, &llNewPos, nFrom);
-
- return llNewPos.QuadPart;
- } else {
- ULONGLONG lAbsolutePos = GetAbsolutePosition(lOff, nFrom);
- int nNewPart = 0;
- ULONGLONG llSum = 0;
-
- while (m_FilesSize[nNewPart]+llSum <= lAbsolutePos) {
- llSum += m_FilesSize[nNewPart];
- nNewPart++;
- }
-
- OpenPart (nNewPart);
- llOff.QuadPart = lAbsolutePos - llSum;
- SetFilePointerEx (m_hFile, llOff, &llNewPos, FILE_BEGIN);
-
- return llSum + llNewPos.QuadPart;
- }
+ LARGE_INTEGER llNewPos;
+ LARGE_INTEGER llOff;
+
+ if (m_strFiles.GetCount() == 1) {
+ llOff.QuadPart = lOff;
+ SetFilePointerEx(m_hFile, llOff, &llNewPos, nFrom);
+
+ return llNewPos.QuadPart;
+ } else {
+ ULONGLONG lAbsolutePos = GetAbsolutePosition(lOff, nFrom);
+ int nNewPart = 0;
+ ULONGLONG llSum = 0;
+
+ while (m_FilesSize[nNewPart] + llSum <= lAbsolutePos) {
+ llSum += m_FilesSize[nNewPart];
+ nNewPart++;
+ }
+
+ OpenPart(nNewPart);
+ llOff.QuadPart = lAbsolutePos - llSum;
+ SetFilePointerEx(m_hFile, llOff, &llNewPos, FILE_BEGIN);
+
+ return llSum + llNewPos.QuadPart;
+ }
}
ULONGLONG CMultiFiles::GetAbsolutePosition(LONGLONG lOff, UINT nFrom)
{
- LARGE_INTEGER llNoMove = {0, 0};
- LARGE_INTEGER llCurPos;
-
- switch (nFrom) {
- case begin :
- return lOff;
- case current :
- SetFilePointerEx (m_hFile, llNoMove, &llCurPos, FILE_CURRENT);
- return llCurPos.QuadPart + lOff;
- case end :
- return m_llTotalLength - lOff;
- default:
- return 0; // just used to quash "not all control paths return a value" warning
- }
+ LARGE_INTEGER llNoMove = {0, 0};
+ LARGE_INTEGER llCurPos;
+
+ switch (nFrom) {
+ case begin :
+ return lOff;
+ case current :
+ SetFilePointerEx(m_hFile, llNoMove, &llCurPos, FILE_CURRENT);
+ return llCurPos.QuadPart + lOff;
+ case end :
+ return m_llTotalLength - lOff;
+ default:
+ return 0; // just used to quash "not all control paths return a value" warning
+ }
}
ULONGLONG CMultiFiles::GetLength() const
{
- if (m_strFiles.GetCount() == 1) {
- LARGE_INTEGER llSize;
- GetFileSizeEx (m_hFile, &llSize);
- return llSize.QuadPart;
- } else {
- return m_llTotalLength;
- }
+ if (m_strFiles.GetCount() == 1) {
+ LARGE_INTEGER llSize;
+ GetFileSizeEx(m_hFile, &llSize);
+ return llSize.QuadPart;
+ } else {
+ return m_llTotalLength;
+ }
}
UINT CMultiFiles::Read(void* lpBuf, UINT nCount)
{
- DWORD dwRead;
- do {
- if (!ReadFile(m_hFile, lpBuf, nCount, &dwRead, NULL)) {
- break;
- }
-
- if (dwRead != nCount && (m_nCurPart < 0 || (size_t)m_nCurPart < m_strFiles.GetCount()-1)) {
- OpenPart (m_nCurPart+1);
- lpBuf = (void*)((BYTE*)lpBuf + dwRead);
- nCount -= dwRead;
- }
- } while (nCount != dwRead && (m_nCurPart < 0 || (size_t)m_nCurPart < m_strFiles.GetCount()-1));
- return dwRead;
+ DWORD dwRead;
+ do {
+ if (!ReadFile(m_hFile, lpBuf, nCount, &dwRead, NULL)) {
+ break;
+ }
+
+ if (dwRead != nCount && (m_nCurPart < 0 || (size_t)m_nCurPart < m_strFiles.GetCount() - 1)) {
+ OpenPart(m_nCurPart + 1);
+ lpBuf = (void*)((BYTE*)lpBuf + dwRead);
+ nCount -= dwRead;
+ }
+ } while (nCount != dwRead && (m_nCurPart < 0 || (size_t)m_nCurPart < m_strFiles.GetCount() - 1));
+ return dwRead;
}
void CMultiFiles::Close()
{
- ClosePart();
- Reset();
+ ClosePart();
+ Reset();
}
CMultiFiles::~CMultiFiles()
{
- Close();
+ Close();
}
BOOL CMultiFiles::OpenPart(int nPart)
{
- if (m_nCurPart == nPart) {
- return TRUE;
- } else {
- CString fn;
+ if (m_nCurPart == nPart) {
+ return TRUE;
+ } else {
+ CString fn;
- ClosePart();
+ ClosePart();
- fn = m_strFiles.GetAt(nPart);
- m_hFile = CreateFile (fn, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ fn = m_strFiles.GetAt(nPart);
+ m_hFile = CreateFile(fn, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
- if (m_hFile != INVALID_HANDLE_VALUE) {
- m_nCurPart = nPart;
- if (m_pCurrentPTSOffset != NULL) {
- *m_pCurrentPTSOffset = m_rtPtsOffsets[nPart];
- }
- }
+ if (m_hFile != INVALID_HANDLE_VALUE) {
+ m_nCurPart = nPart;
+ if (m_pCurrentPTSOffset != NULL) {
+ *m_pCurrentPTSOffset = m_rtPtsOffsets[nPart];
+ }
+ }
- return (m_hFile != INVALID_HANDLE_VALUE);
- }
+ return (m_hFile != INVALID_HANDLE_VALUE);
+ }
}
void CMultiFiles::ClosePart()
{
- if (m_hFile != INVALID_HANDLE_VALUE) {
- CloseHandle (m_hFile);
- m_hFile = INVALID_HANDLE_VALUE;
- m_nCurPart = -1;
- }
+ if (m_hFile != INVALID_HANDLE_VALUE) {
+ CloseHandle(m_hFile);
+ m_hFile = INVALID_HANDLE_VALUE;
+ m_nCurPart = -1;
+ }
}
diff --git a/src/filters/parser/BaseSplitter/MultiFiles.h b/src/filters/parser/BaseSplitter/MultiFiles.h
index 7df49c0fd..7f1ac0c42 100644
--- a/src/filters/parser/BaseSplitter/MultiFiles.h
+++ b/src/filters/parser/BaseSplitter/MultiFiles.h
@@ -27,73 +27,73 @@
class CMultiFiles : public CObject
{
- DECLARE_DYNAMIC(CMultiFiles)
+ DECLARE_DYNAMIC(CMultiFiles)
public:
- // Flag values
- enum OpenFlags {
- modeRead = (int) 0x00000,
- modeWrite = (int) 0x00001,
- modeReadWrite = (int) 0x00002,
- shareCompat = (int) 0x00000,
- shareExclusive = (int) 0x00010,
- shareDenyWrite = (int) 0x00020,
- shareDenyRead = (int) 0x00030,
- shareDenyNone = (int) 0x00040,
- modeNoInherit = (int) 0x00080,
- modeCreate = (int) 0x01000,
- modeNoTruncate = (int) 0x02000,
- typeText = (int) 0x04000, // typeText and typeBinary are
- typeBinary = (int) 0x08000, // used in derived classes only
- osNoBuffer = (int) 0x10000,
- osWriteThrough = (int) 0x20000,
- osRandomAccess = (int) 0x40000,
- osSequentialScan = (int) 0x80000,
- };
+ // Flag values
+ enum OpenFlags {
+ modeRead = (int) 0x00000,
+ modeWrite = (int) 0x00001,
+ modeReadWrite = (int) 0x00002,
+ shareCompat = (int) 0x00000,
+ shareExclusive = (int) 0x00010,
+ shareDenyWrite = (int) 0x00020,
+ shareDenyRead = (int) 0x00030,
+ shareDenyNone = (int) 0x00040,
+ modeNoInherit = (int) 0x00080,
+ modeCreate = (int) 0x01000,
+ modeNoTruncate = (int) 0x02000,
+ typeText = (int) 0x04000, // typeText and typeBinary are
+ typeBinary = (int) 0x08000, // used in derived classes only
+ osNoBuffer = (int) 0x10000,
+ osWriteThrough = (int) 0x20000,
+ osRandomAccess = (int) 0x40000,
+ osSequentialScan = (int) 0x80000,
+ };
- enum Attribute {
- normal = 0x00,
- readOnly = 0x01,
- hidden = 0x02,
- system = 0x04,
- volume = 0x08,
- directory = 0x10,
- archive = 0x20
- };
+ enum Attribute {
+ normal = 0x00,
+ readOnly = 0x01,
+ hidden = 0x02,
+ system = 0x04,
+ volume = 0x08,
+ directory = 0x10,
+ archive = 0x20
+ };
- enum SeekPosition { begin = 0x0, current = 0x1, end = 0x2 };
+ enum SeekPosition { begin = 0x0, current = 0x1, end = 0x2 };
- // Constructors
- CMultiFiles();
+ // Constructors
+ CMultiFiles();
- CString m_strFileName;
+ CString m_strFileName;
- // Operations
- virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);
- virtual BOOL OpenFiles(CAtlList<CHdmvClipInfo::PlaylistItem>& files, UINT nOpenFlags);
+ // Operations
+ virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);
+ virtual BOOL OpenFiles(CAtlList<CHdmvClipInfo::PlaylistItem>& files, UINT nOpenFlags);
- virtual ULONGLONG Seek(LONGLONG lOff, UINT nFrom);
- virtual ULONGLONG GetLength() const;
+ virtual ULONGLONG Seek(LONGLONG lOff, UINT nFrom);
+ virtual ULONGLONG GetLength() const;
- virtual UINT Read(void* lpBuf, UINT nCount);
- virtual void Close();
+ virtual UINT Read(void* lpBuf, UINT nCount);
+ virtual void Close();
- // Implementation
+ // Implementation
public:
- virtual ~CMultiFiles();
+ virtual ~CMultiFiles();
protected:
- REFERENCE_TIME* m_pCurrentPTSOffset;
- CAtlArray<CString> m_strFiles;
- CAtlArray<ULONGLONG> m_FilesSize;
- CAtlArray<REFERENCE_TIME> m_rtPtsOffsets;
- HANDLE m_hFile;
- int m_nCurPart;
- ULONGLONG m_llTotalLength;
+ REFERENCE_TIME* m_pCurrentPTSOffset;
+ CAtlArray<CString> m_strFiles;
+ CAtlArray<ULONGLONG> m_FilesSize;
+ CAtlArray<REFERENCE_TIME> m_rtPtsOffsets;
+ HANDLE m_hFile;
+ int m_nCurPart;
+ ULONGLONG m_llTotalLength;
- BOOL OpenPart(int nPart);
- void ClosePart();
- ULONGLONG GetAbsolutePosition(LONGLONG lOff, UINT nFrom);
- void Reset();
+ BOOL OpenPart(int nPart);
+ void ClosePart();
+ ULONGLONG GetAbsolutePosition(LONGLONG lOff, UINT nFrom);
+ void Reset();
};