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

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortetsuo55 <tetsuo55@users.sourceforge.net>2010-04-09 01:14:58 +0400
committertetsuo55 <tetsuo55@users.sourceforge.net>2010-04-09 01:14:58 +0400
commita9b7bf3fb3e1334d8defd05ca4cfae870b4912e5 (patch)
tree2dab453d94d5e003379a6cc895eceb84c80e23ec /src/filters/parser/RealMediaSplitter
parentaafd49a91f7c2fa9c7103971c16fa6e1b29e8bfd (diff)
astyle formatting cleanup to make the sourcecode more accessible
switch used: astyle --style=ansi --min-conditional-indent=0 --pad=oper --unpad=paren http://astyle.sourceforge.net/ git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1783 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser/RealMediaSplitter')
-rw-r--r--src/filters/parser/RealMediaSplitter/RealMediaSplitter.cpp3980
-rw-r--r--src/filters/parser/RealMediaSplitter/RealMediaSplitter.h452
-rw-r--r--src/filters/parser/RealMediaSplitter/resource.h2
-rw-r--r--src/filters/parser/RealMediaSplitter/stdafx.cpp8
-rw-r--r--src/filters/parser/RealMediaSplitter/stdafx.h8
5 files changed, 2305 insertions, 2145 deletions
diff --git a/src/filters/parser/RealMediaSplitter/RealMediaSplitter.cpp b/src/filters/parser/RealMediaSplitter/RealMediaSplitter.cpp
index e133b8435..306fc133b 100644
--- a/src/filters/parser/RealMediaSplitter/RealMediaSplitter.cpp
+++ b/src/filters/parser/RealMediaSplitter/RealMediaSplitter.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -38,45 +38,49 @@
template<typename T>
static void bswap(T& var)
{
- BYTE* s = (BYTE*)&var;
- for(BYTE* d = s + sizeof(var)-1; s < d; s++, d--)
- *s ^= *d, *d ^= *s, *s ^= *d;
+ BYTE* s = (BYTE*)&var;
+ for(BYTE* d = s + sizeof(var) - 1; s < d; s++, d--)
+ *s ^= *d, *d ^= *s, *s ^= *d;
}
void rvinfo::bswap()
{
- ::bswap(dwSize);
- ::bswap(w); ::bswap(h); ::bswap(bpp);
- ::bswap(unk1); ::bswap(fps);
- ::bswap(type1); ::bswap(type2);
+ ::bswap(dwSize);
+ ::bswap(w);
+ ::bswap(h);
+ ::bswap(bpp);
+ ::bswap(unk1);
+ ::bswap(fps);
+ ::bswap(type1);
+ ::bswap(type2);
}
void rainfo::bswap()
{
- ::bswap(version1);
- ::bswap(version2);
- ::bswap(header_size);
- ::bswap(flavor);
- ::bswap(coded_frame_size);
- ::bswap(sub_packet_h);
- ::bswap(frame_size);
- ::bswap(sub_packet_size);
+ ::bswap(version1);
+ ::bswap(version2);
+ ::bswap(header_size);
+ ::bswap(flavor);
+ ::bswap(coded_frame_size);
+ ::bswap(sub_packet_h);
+ ::bswap(frame_size);
+ ::bswap(sub_packet_size);
}
void rainfo4::bswap()
{
- __super::bswap();
- ::bswap(sample_rate);
- ::bswap(sample_size);
- ::bswap(channels);
+ __super::bswap();
+ ::bswap(sample_rate);
+ ::bswap(sample_size);
+ ::bswap(channels);
}
void rainfo5::bswap()
{
- __super::bswap();
- ::bswap(sample_rate);
- ::bswap(sample_size);
- ::bswap(channels);
+ __super::bswap();
+ ::bswap(sample_rate);
+ ::bswap(sample_size);
+ ::bswap(channels);
}
using namespace RMFF;
@@ -85,7 +89,7 @@ using namespace RMFF;
const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
{
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL},
+ {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL},
};
const AMOVIESETUP_PIN sudpPins[] =
@@ -96,15 +100,15 @@ const AMOVIESETUP_PIN sudpPins[] =
const AMOVIESETUP_MEDIATYPE sudPinTypesIn2[] =
{
- {&MEDIATYPE_Video, &MEDIASUBTYPE_RV20},
- {&MEDIATYPE_Video, &MEDIASUBTYPE_RV30},
- {&MEDIATYPE_Video, &MEDIASUBTYPE_RV40},
- {&MEDIATYPE_Video, &MEDIASUBTYPE_RV41},
+ {&MEDIATYPE_Video, &MEDIASUBTYPE_RV20},
+ {&MEDIATYPE_Video, &MEDIASUBTYPE_RV30},
+ {&MEDIATYPE_Video, &MEDIASUBTYPE_RV40},
+ {&MEDIATYPE_Video, &MEDIASUBTYPE_RV41},
};
const AMOVIESETUP_MEDIATYPE sudPinTypesOut2[] =
{
- {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
+ {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
};
const AMOVIESETUP_PIN sudpPins2[] =
@@ -115,20 +119,20 @@ const AMOVIESETUP_PIN sudpPins2[] =
const AMOVIESETUP_MEDIATYPE sudPinTypesIn3[] =
{
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_14_4},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_28_8},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_ATRC},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_COOK},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_DNET},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_SIPR},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_AAC},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_RAAC},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_RACP},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_14_4},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_28_8},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_ATRC},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_COOK},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_DNET},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_SIPR},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_AAC},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_RAAC},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_RACP},
};
const AMOVIESETUP_MEDIATYPE sudPinTypesOut3[] =
{
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM},
};
const AMOVIESETUP_PIN sudpPins3[] =
@@ -139,16 +143,16 @@ const AMOVIESETUP_PIN sudpPins3[] =
const AMOVIESETUP_FILTER sudFilter[] =
{
- {&__uuidof(CRealMediaSplitterFilter), L"MPC - RealMedia Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory},
- {&__uuidof(CRealMediaSourceFilter), L"MPC - RealMedia Source", MERIT_NORMAL, 0, NULL, CLSID_LegacyAmFilterCategory},
- {&__uuidof(CRealVideoDecoder), L"MPC - RealVideo Decoder", MERIT_NORMAL, countof(sudpPins2), sudpPins2, CLSID_LegacyAmFilterCategory},
- {&__uuidof(CRealAudioDecoder), L"MPC - RealAudio Decoder", MERIT_NORMAL, countof(sudpPins3), sudpPins3, CLSID_LegacyAmFilterCategory},
+ {&__uuidof(CRealMediaSplitterFilter), L"MPC - RealMedia Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins, CLSID_LegacyAmFilterCategory},
+ {&__uuidof(CRealMediaSourceFilter), L"MPC - RealMedia Source", MERIT_NORMAL, 0, NULL, CLSID_LegacyAmFilterCategory},
+ {&__uuidof(CRealVideoDecoder), L"MPC - RealVideo Decoder", MERIT_NORMAL, countof(sudpPins2), sudpPins2, CLSID_LegacyAmFilterCategory},
+ {&__uuidof(CRealAudioDecoder), L"MPC - RealAudio Decoder", MERIT_NORMAL, countof(sudpPins3), sudpPins3, CLSID_LegacyAmFilterCategory},
};
CFactoryTemplate g_Templates[] =
{
- {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CRealMediaSplitterFilter>, NULL, &sudFilter[0]},
- {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CRealMediaSourceFilter>, NULL, &sudFilter[1]},
+ {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CRealMediaSplitterFilter>, NULL, &sudFilter[0]},
+ {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CRealMediaSourceFilter>, NULL, &sudFilter[1]},
{sudFilter[2].strName, sudFilter[2].clsID, CreateInstance<CRealVideoDecoder>, NULL, &sudFilter[2]},
{sudFilter[3].strName, sudFilter[3].clsID, CreateInstance<CRealAudioDecoder>, NULL, &sudFilter[3]},
};
@@ -157,16 +161,16 @@ int g_cTemplates = countof(g_Templates);
STDAPI DllRegisterServer()
{
- RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_RealMedia, _T("0,4,,2E524D46"), _T(".rm"), _T(".rmvb"), _T(".ram"), NULL);
+ RegisterSourceFilter(CLSID_AsyncReader, MEDIASUBTYPE_RealMedia, _T("0,4,,2E524D46"), _T(".rm"), _T(".rmvb"), _T(".ram"), NULL);
- return AMovieDllRegisterServer2(TRUE);
+ return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
- UnRegisterSourceFilter(MEDIASUBTYPE_RealMedia);
+ UnRegisterSourceFilter(MEDIASUBTYPE_RealMedia);
- return AMovieDllRegisterServer2(FALSE);
+ return AMovieDllRegisterServer2(FALSE);
}
#include "../../FilterApp.h"
@@ -180,7 +184,7 @@ CFilterApp theApp;
//
CRealMediaSplitterFilter::CRealMediaSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CBaseSplitterFilter(NAME("CRealMediaSplitterFilter"), pUnk, phr, __uuidof(this))
+ : CBaseSplitterFilter(NAME("CRealMediaSplitterFilter"), pUnk, phr, __uuidof(this))
{
}
@@ -190,549 +194,592 @@ CRealMediaSplitterFilter::~CRealMediaSplitterFilter()
HRESULT CRealMediaSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
{
- CheckPointer(pAsyncReader, E_POINTER);
-
- {
- DWORD dw;
- if(FAILED(pAsyncReader->SyncRead(0, 4, (BYTE*)&dw)) || dw != 'FMR.')
- return E_FAIL;
- }
-
- HRESULT hr = E_FAIL;
-
- m_pFile.Free();
-
- m_pFile.Attach(DNew CRMFile(pAsyncReader, hr));
- if(!m_pFile) return E_OUTOFMEMORY;
- if(FAILED(hr)) {m_pFile.Free(); return hr;}
-
- m_rtNewStart = m_rtCurrent = 0;
- m_rtNewStop = m_rtStop = 0;
-
- m_rtStop = 10000i64*m_pFile->m_p.tDuration;
-
- POSITION pos = m_pFile->m_mps.GetHeadPosition();
- while(pos)
- {
- MediaProperies* pmp = m_pFile->m_mps.GetNext(pos);
-
- CStringW name;
- name.Format(L"Output %02d", pmp->stream);
- if(!pmp->name.IsEmpty()) name += L" (" + CStringW(pmp->name) + L")";
-
- CAtlArray<CMediaType> mts;
-
- CMediaType mt;
- mt.SetSampleSize(max(pmp->maxPacketSize*16/**/, 1));
-
- if(pmp->mime == "video/x-pn-realvideo")
- {
- mt.majortype = MEDIATYPE_Video;
- mt.formattype = FORMAT_VideoInfo;
-
- VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + pmp->typeSpecData.GetCount());
- memset(mt.Format(), 0, mt.FormatLength());
- memcpy(pvih + 1, pmp->typeSpecData.GetData(), pmp->typeSpecData.GetCount());
-
- rvinfo rvi = *(rvinfo*)pmp->typeSpecData.GetData();
- rvi.bswap();
-
- ASSERT(rvi.dwSize >= FIELD_OFFSET(rvinfo, morewh));
- ASSERT(rvi.fcc1 == 'ODIV');
-
- mt.subtype = FOURCCMap(rvi.fcc2);
- if(rvi.fps > 0x10000) pvih->AvgTimePerFrame = REFERENCE_TIME(10000000i64 / ((float)rvi.fps/0x10000));
- pvih->dwBitRate = pmp->avgBitRate;
- pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader);
- pvih->bmiHeader.biWidth = rvi.w;
- pvih->bmiHeader.biHeight = rvi.h;
- pvih->bmiHeader.biPlanes = 3;
- pvih->bmiHeader.biBitCount = rvi.bpp;
- pvih->bmiHeader.biCompression = rvi.fcc2;
- pvih->bmiHeader.biSizeImage = rvi.w*rvi.h*3/2;
-
- mts.Add(mt);
-
- if(pmp->width > 0 && pmp->height > 0)
- {
- BITMAPINFOHEADER bmi = pvih->bmiHeader;
- mt.formattype = FORMAT_VideoInfo2;
- VIDEOINFOHEADER2* pvih2 = (VIDEOINFOHEADER2*)mt.ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2) + pmp->typeSpecData.GetCount());
- memset(mt.Format() + FIELD_OFFSET(VIDEOINFOHEADER2, dwInterlaceFlags), 0, mt.FormatLength() - FIELD_OFFSET(VIDEOINFOHEADER2, dwInterlaceFlags));
- memcpy(pvih2 + 1, pmp->typeSpecData.GetData(), pmp->typeSpecData.GetCount());
- pvih2->bmiHeader = bmi;
- pvih2->bmiHeader.biWidth = (DWORD)pmp->width;
- pvih2->bmiHeader.biHeight = (DWORD)pmp->height;
- pvih2->dwPictAspectRatioX = rvi.w;
- pvih2->dwPictAspectRatioY = rvi.h;
-
- mts.InsertAt(0, mt);
- }
- }
- else if(pmp->mime == "audio/x-pn-realaudio")
- {
- mt.majortype = MEDIATYPE_Audio;
- mt.formattype = FORMAT_WaveFormatEx;
- mt.bTemporalCompression = 1;
-
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)mt.AllocFormatBuffer(sizeof(WAVEFORMATEX) + pmp->typeSpecData.GetCount());
- memset(mt.Format(), 0, mt.FormatLength());
- memcpy(pwfe + 1, pmp->typeSpecData.GetData(), pmp->typeSpecData.GetCount());
-
- union {
- DWORD fcc;
- char fccstr[5];
- };
-
- fcc = 0;
- fccstr[4] = 0;
-
- BYTE* fmt = pmp->typeSpecData.GetData();
- for(int i = 0; i < pmp->typeSpecData.GetCount()-4; i++, fmt++)
- {
- if(fmt[0] == '.' || fmt[1] == 'r' || fmt[2] == 'a')
- break;
- }
-
- rainfo rai = *(rainfo*)fmt;
- rai.bswap();
-
- BYTE* extra = NULL;
-
- if(rai.version2 == 4)
- {
- rainfo4 rai4 = *(rainfo4*)fmt;
- rai4.bswap();
- pwfe->nChannels = rai4.channels;
- pwfe->wBitsPerSample = rai4.sample_size;
- pwfe->nSamplesPerSec = rai4.sample_rate;
- pwfe->nBlockAlign = rai4.frame_size;
- BYTE* p = (BYTE*)((rainfo4*)fmt+1);
- int len = *p++; p += len; len = *p++; ASSERT(len == 4);
- if(len == 4)
- fcc = MAKEFOURCC(p[0],p[1],p[2],p[3]);
- extra = p + len + 3;
- }
- else if(rai.version2 == 5)
- {
- rainfo5 rai5 = *(rainfo5*)fmt;
- rai5.bswap();
- pwfe->nChannels = rai5.channels;
- pwfe->wBitsPerSample = rai5.sample_size;
- pwfe->nSamplesPerSec = rai5.sample_rate;
- pwfe->nBlockAlign = rai5.frame_size;
- fcc = rai5.fourcc3;
- extra = fmt + sizeof(rainfo5) + 4;
- }
- else
- {
- continue;
- }
-
- _strupr(fccstr);
-
- mt.subtype = FOURCCMap(fcc);
-
- bswap(fcc);
-
- switch(fcc)
- {
- case '14_4': pwfe->wFormatTag = WAVE_FORMAT_14_4; break;
- case '28_8': pwfe->wFormatTag = WAVE_FORMAT_28_8; break;
- case 'ATRC': pwfe->wFormatTag = WAVE_FORMAT_ATRC; break;
- case 'COOK': pwfe->wFormatTag = WAVE_FORMAT_COOK; break;
- case 'DNET': pwfe->wFormatTag = WAVE_FORMAT_DNET; break;
- case 'SIPR': pwfe->wFormatTag = WAVE_FORMAT_SIPR; break;
- case 'RAAC': pwfe->wFormatTag = WAVE_FORMAT_RAAC; break;
- case 'RACP': pwfe->wFormatTag = WAVE_FORMAT_RACP; break;
- }
-
- if(pwfe->wFormatTag)
- {
- mts.Add(mt);
-
- if(fcc == 'DNET')
- {
- mt.subtype = FOURCCMap(pwfe->wFormatTag = WAVE_FORMAT_DOLBY_AC3);
- mts.InsertAt(0, mt);
- }
- else if(fcc == 'RAAC' || fcc == 'RACP')
- {
- mt.subtype = FOURCCMap(pwfe->wFormatTag = WAVE_FORMAT_AAC);
- int extralen = *(DWORD*)extra; extra += 4;
- ::bswap(extralen);
- ASSERT(*extra == 2); // always 2? why? what does it mean?
- if(*extra == 2)
- {
- extra++; extralen--;
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)mt.ReallocFormatBuffer(sizeof(WAVEFORMATEX) + extralen);
- pwfe->cbSize = extralen;
- memcpy(pwfe + 1, extra, extralen);
- }
- else
- {
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)mt.ReallocFormatBuffer(sizeof(WAVEFORMATEX) + 5);
- pwfe->cbSize = MakeAACInitData((BYTE*)(pwfe+1), 0, pwfe->nSamplesPerSec, pwfe->nChannels);
- }
- mts.InsertAt(0, mt);
- }
- }
- }
- else if(pmp->mime == "logical-fileinfo")
- {
- CAtlMap<CStringA, CStringA, CStringElementTraits<CStringA> > lfi;
- CStringA key, value;
-
- BYTE* p = pmp->typeSpecData.GetData();
- BYTE* end = p + pmp->typeSpecData.GetCount();
- p += 8;
-
- DWORD cnt = p <= end-4 ? *(DWORD*)p : 0; bswap(cnt); p += 4;
-
- if(cnt > 0xffff) // different format?
- {
- p += 2;
- cnt = p <= end-4 ? *(DWORD*)p : 0; bswap(cnt); p += 4;
- }
-
- while(p < end-4 && cnt-- > 0)
- {
- BYTE* base = p;
- DWORD len = *(DWORD*)p; bswap(len); p += 4;
- if(base + len > end) break;
-
- p++;
- WORD keylen = *(WORD*)p; bswap(keylen); p += 2;
- memcpy(key.GetBufferSetLength(keylen), p, keylen);
- p += keylen;
-
- p+=4;
- WORD valuelen = *(WORD*)p; bswap(valuelen); p += 2;
- memcpy(value.GetBufferSetLength(valuelen), p, valuelen);
- p += valuelen;
-
- ASSERT(p == base + len);
- p = base + len;
-
- lfi[key] = value;
- }
-
- POSITION pos = lfi.GetStartPosition();
- while(pos)
- {
- lfi.GetNextAssoc(pos, key, value);
-
- int n;
- if(key.Find("CHAPTER") == 0 && key.Find("TIME") == key.GetLength()-4
- && (n = strtol(key.Mid(7), NULL, 10)) > 0)
- {
- int h, m, s, ms;
- char c;
- if(7 != sscanf(value, "%d%c%d%c%d%c%d", &h, &c, &m, &c, &s, &c, &ms))
- continue;
-
- key.Format("CHAPTER%02dNAME", n);
- if(!lfi.Lookup(key, value) || value.IsEmpty())
- value.Format("Chapter %d", n);
-
- ChapAppend(
- ((((REFERENCE_TIME)h*60+m)*60+s)*1000+ms)*10000,
- CStringW(CString(value)));
- }
- }
- }
-
- if(mts.IsEmpty())
- {
- TRACE(_T("Unsupported RealMedia stream (%d): %s\n"), pmp->stream, CString(pmp->mime));
- continue;
- }
-
- HRESULT hr;
-
- CAutoPtr<CBaseSplitterOutputPin> pPinOut(DNew CRealMediaSplitterOutputPin(mts, name, this, this, &hr));
- if(SUCCEEDED(AddOutputPin((DWORD)pmp->stream, pPinOut)))
- {
- if(!m_rtStop)
- m_pFile->m_p.tDuration = max(m_pFile->m_p.tDuration, pmp->tDuration);
- }
- }
-
- pos = m_pFile->m_subs.GetHeadPosition();
- for(DWORD stream = 0; pos; stream++)
- {
- CRMFile::subtitle& s = m_pFile->m_subs.GetNext(pos);
-
- CStringW name;
- name.Format(L"Subtitle %02d", stream);
- if(!s.name.IsEmpty()) name += L" (" + CStringW(CString(s.name)) + L")";
-
- CMediaType mt;
- mt.SetSampleSize(1);
- mt.majortype = MEDIATYPE_Text;
-
- CAtlArray<CMediaType> mts;
- mts.Add(mt);
-
- HRESULT hr;
-
- CAutoPtr<CBaseSplitterOutputPin> pPinOut(DNew CRealMediaSplitterOutputPin(mts, name, this, this, &hr));
- AddOutputPin((DWORD)~stream, pPinOut);
- }
-
- m_rtDuration = m_rtNewStop = m_rtStop = 10000i64*m_pFile->m_p.tDuration;
-
- SetProperty(L"TITL", CStringW(m_pFile->m_cd.title));
- SetProperty(L"AUTH", CStringW(m_pFile->m_cd.author));
- SetProperty(L"CPYR", CStringW(m_pFile->m_cd.copyright));
- SetProperty(L"DESC", CStringW(m_pFile->m_cd.comment));
-
- return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
-}
+ CheckPointer(pAsyncReader, E_POINTER);
+
+ {
+ DWORD dw;
+ if(FAILED(pAsyncReader->SyncRead(0, 4, (BYTE*)&dw)) || dw != 'FMR.')
+ return E_FAIL;
+ }
+
+ HRESULT hr = E_FAIL;
+
+ m_pFile.Free();
+
+ m_pFile.Attach(DNew CRMFile(pAsyncReader, hr));
+ if(!m_pFile) return E_OUTOFMEMORY;
+ if(FAILED(hr))
+ {
+ m_pFile.Free();
+ return hr;
+ }
+
+ m_rtNewStart = m_rtCurrent = 0;
+ m_rtNewStop = m_rtStop = 0;
+
+ m_rtStop = 10000i64 * m_pFile->m_p.tDuration;
+
+ POSITION pos = m_pFile->m_mps.GetHeadPosition();
+ while(pos)
+ {
+ MediaProperies* pmp = m_pFile->m_mps.GetNext(pos);
+
+ CStringW name;
+ name.Format(L"Output %02d", pmp->stream);
+ if(!pmp->name.IsEmpty()) name += L" (" + CStringW(pmp->name) + L")";
+
+ CAtlArray<CMediaType> mts;
+
+ CMediaType mt;
+ mt.SetSampleSize(max(pmp->maxPacketSize * 16/**/, 1));
+
+ if(pmp->mime == "video/x-pn-realvideo")
+ {
+ mt.majortype = MEDIATYPE_Video;
+ mt.formattype = FORMAT_VideoInfo;
+
+ VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + pmp->typeSpecData.GetCount());
+ memset(mt.Format(), 0, mt.FormatLength());
+ memcpy(pvih + 1, pmp->typeSpecData.GetData(), pmp->typeSpecData.GetCount());
+
+ rvinfo rvi = *(rvinfo*)pmp->typeSpecData.GetData();
+ rvi.bswap();
+
+ ASSERT(rvi.dwSize >= FIELD_OFFSET(rvinfo, morewh));
+ ASSERT(rvi.fcc1 == 'ODIV');
+
+ mt.subtype = FOURCCMap(rvi.fcc2);
+ if(rvi.fps > 0x10000) pvih->AvgTimePerFrame = REFERENCE_TIME(10000000i64 / ((float)rvi.fps / 0x10000));
+ pvih->dwBitRate = pmp->avgBitRate;
+ pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader);
+ pvih->bmiHeader.biWidth = rvi.w;
+ pvih->bmiHeader.biHeight = rvi.h;
+ pvih->bmiHeader.biPlanes = 3;
+ pvih->bmiHeader.biBitCount = rvi.bpp;
+ pvih->bmiHeader.biCompression = rvi.fcc2;
+ pvih->bmiHeader.biSizeImage = rvi.w * rvi.h * 3 / 2;
+
+ mts.Add(mt);
+
+ if(pmp->width > 0 && pmp->height > 0)
+ {
+ BITMAPINFOHEADER bmi = pvih->bmiHeader;
+ mt.formattype = FORMAT_VideoInfo2;
+ VIDEOINFOHEADER2* pvih2 = (VIDEOINFOHEADER2*)mt.ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2) + pmp->typeSpecData.GetCount());
+ memset(mt.Format() + FIELD_OFFSET(VIDEOINFOHEADER2, dwInterlaceFlags), 0, mt.FormatLength() - FIELD_OFFSET(VIDEOINFOHEADER2, dwInterlaceFlags));
+ memcpy(pvih2 + 1, pmp->typeSpecData.GetData(), pmp->typeSpecData.GetCount());
+ pvih2->bmiHeader = bmi;
+ pvih2->bmiHeader.biWidth = (DWORD)pmp->width;
+ pvih2->bmiHeader.biHeight = (DWORD)pmp->height;
+ pvih2->dwPictAspectRatioX = rvi.w;
+ pvih2->dwPictAspectRatioY = rvi.h;
+
+ mts.InsertAt(0, mt);
+ }
+ }
+ else if(pmp->mime == "audio/x-pn-realaudio")
+ {
+ mt.majortype = MEDIATYPE_Audio;
+ mt.formattype = FORMAT_WaveFormatEx;
+ mt.bTemporalCompression = 1;
+
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)mt.AllocFormatBuffer(sizeof(WAVEFORMATEX) + pmp->typeSpecData.GetCount());
+ memset(mt.Format(), 0, mt.FormatLength());
+ memcpy(pwfe + 1, pmp->typeSpecData.GetData(), pmp->typeSpecData.GetCount());
+
+ union
+ {
+ DWORD fcc;
+ char fccstr[5];
+ };
+
+ fcc = 0;
+ fccstr[4] = 0;
+
+ BYTE* fmt = pmp->typeSpecData.GetData();
+ for(int i = 0; i < pmp->typeSpecData.GetCount() - 4; i++, fmt++)
+ {
+ if(fmt[0] == '.' || fmt[1] == 'r' || fmt[2] == 'a')
+ break;
+ }
-bool CRealMediaSplitterFilter::DemuxInit()
-{
- if(!m_pFile) return(false);
+ rainfo rai = *(rainfo*)fmt;
+ rai.bswap();
+
+ BYTE* extra = NULL;
+
+ if(rai.version2 == 4)
+ {
+ rainfo4 rai4 = *(rainfo4*)fmt;
+ rai4.bswap();
+ pwfe->nChannels = rai4.channels;
+ pwfe->wBitsPerSample = rai4.sample_size;
+ pwfe->nSamplesPerSec = rai4.sample_rate;
+ pwfe->nBlockAlign = rai4.frame_size;
+ BYTE* p = (BYTE*)((rainfo4*)fmt + 1);
+ int len = *p++;
+ p += len;
+ len = *p++;
+ ASSERT(len == 4);
+ if(len == 4)
+ fcc = MAKEFOURCC(p[0], p[1], p[2], p[3]);
+ extra = p + len + 3;
+ }
+ else if(rai.version2 == 5)
+ {
+ rainfo5 rai5 = *(rainfo5*)fmt;
+ rai5.bswap();
+ pwfe->nChannels = rai5.channels;
+ pwfe->wBitsPerSample = rai5.sample_size;
+ pwfe->nSamplesPerSec = rai5.sample_rate;
+ pwfe->nBlockAlign = rai5.frame_size;
+ fcc = rai5.fourcc3;
+ extra = fmt + sizeof(rainfo5) + 4;
+ }
+ else
+ {
+ continue;
+ }
- // reindex if needed
+ _strupr(fccstr);
+
+ mt.subtype = FOURCCMap(fcc);
+
+ bswap(fcc);
+
+ switch(fcc)
+ {
+ case '14_4':
+ pwfe->wFormatTag = WAVE_FORMAT_14_4;
+ break;
+ case '28_8':
+ pwfe->wFormatTag = WAVE_FORMAT_28_8;
+ break;
+ case 'ATRC':
+ pwfe->wFormatTag = WAVE_FORMAT_ATRC;
+ break;
+ case 'COOK':
+ pwfe->wFormatTag = WAVE_FORMAT_COOK;
+ break;
+ case 'DNET':
+ pwfe->wFormatTag = WAVE_FORMAT_DNET;
+ break;
+ case 'SIPR':
+ pwfe->wFormatTag = WAVE_FORMAT_SIPR;
+ break;
+ case 'RAAC':
+ pwfe->wFormatTag = WAVE_FORMAT_RAAC;
+ break;
+ case 'RACP':
+ pwfe->wFormatTag = WAVE_FORMAT_RACP;
+ break;
+ }
- if(m_pFile->m_irs.GetCount() == 0)
- {
- m_nOpenProgress = 0;
- m_rtDuration = 0;
+ if(pwfe->wFormatTag)
+ {
+ mts.Add(mt);
+
+ if(fcc == 'DNET')
+ {
+ mt.subtype = FOURCCMap(pwfe->wFormatTag = WAVE_FORMAT_DOLBY_AC3);
+ mts.InsertAt(0, mt);
+ }
+ else if(fcc == 'RAAC' || fcc == 'RACP')
+ {
+ mt.subtype = FOURCCMap(pwfe->wFormatTag = WAVE_FORMAT_AAC);
+ int extralen = *(DWORD*)extra;
+ extra += 4;
+ ::bswap(extralen);
+ ASSERT(*extra == 2); // always 2? why? what does it mean?
+ if(*extra == 2)
+ {
+ extra++;
+ extralen--;
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)mt.ReallocFormatBuffer(sizeof(WAVEFORMATEX) + extralen);
+ pwfe->cbSize = extralen;
+ memcpy(pwfe + 1, extra, extralen);
+ }
+ else
+ {
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)mt.ReallocFormatBuffer(sizeof(WAVEFORMATEX) + 5);
+ pwfe->cbSize = MakeAACInitData((BYTE*)(pwfe + 1), 0, pwfe->nSamplesPerSec, pwfe->nChannels);
+ }
+ mts.InsertAt(0, mt);
+ }
+ }
+ }
+ else if(pmp->mime == "logical-fileinfo")
+ {
+ CAtlMap<CStringA, CStringA, CStringElementTraits<CStringA> > lfi;
+ CStringA key, value;
+
+ BYTE* p = pmp->typeSpecData.GetData();
+ BYTE* end = p + pmp->typeSpecData.GetCount();
+ p += 8;
+
+ DWORD cnt = p <= end - 4 ? *(DWORD*)p : 0;
+ bswap(cnt);
+ p += 4;
+
+ if(cnt > 0xffff) // different format?
+ {
+ p += 2;
+ cnt = p <= end - 4 ? *(DWORD*)p : 0;
+ bswap(cnt);
+ p += 4;
+ }
- int stream = m_pFile->GetMasterStream();
+ while(p < end - 4 && cnt-- > 0)
+ {
+ BYTE* base = p;
+ DWORD len = *(DWORD*)p;
+ bswap(len);
+ p += 4;
+ if(base + len > end) break;
+
+ p++;
+ WORD keylen = *(WORD*)p;
+ bswap(keylen);
+ p += 2;
+ memcpy(key.GetBufferSetLength(keylen), p, keylen);
+ p += keylen;
+
+ p += 4;
+ WORD valuelen = *(WORD*)p;
+ bswap(valuelen);
+ p += 2;
+ memcpy(value.GetBufferSetLength(valuelen), p, valuelen);
+ p += valuelen;
+
+ ASSERT(p == base + len);
+ p = base + len;
+
+ lfi[key] = value;
+ }
- UINT32 tLastStart = -1;
- UINT32 nPacket = 0;
+ POSITION pos = lfi.GetStartPosition();
+ while(pos)
+ {
+ lfi.GetNextAssoc(pos, key, value);
+
+ int n;
+ if(key.Find("CHAPTER") == 0 && key.Find("TIME") == key.GetLength() - 4
+ && (n = strtol(key.Mid(7), NULL, 10)) > 0)
+ {
+ int h, m, s, ms;
+ char c;
+ if(7 != sscanf(value, "%d%c%d%c%d%c%d", &h, &c, &m, &c, &s, &c, &ms))
+ continue;
+
+ key.Format("CHAPTER%02dNAME", n);
+ if(!lfi.Lookup(key, value) || value.IsEmpty())
+ value.Format("Chapter %d", n);
+
+ ChapAppend(
+ ((((REFERENCE_TIME)h * 60 + m) * 60 + s) * 1000 + ms) * 10000,
+ CStringW(CString(value)));
+ }
+ }
+ }
- POSITION pos = m_pFile->m_dcs.GetHeadPosition();
- while(pos && !m_fAbort)
- {
- DataChunk* pdc = m_pFile->m_dcs.GetNext(pos);
+ if(mts.IsEmpty())
+ {
+ TRACE(_T("Unsupported RealMedia stream (%d): %s\n"), pmp->stream, CString(pmp->mime));
+ continue;
+ }
- m_pFile->Seek(pdc->pos);
+ HRESULT hr;
- for(UINT32 i = 0; i < pdc->nPackets && !m_fAbort; i++, nPacket++)
- {
- UINT64 filepos = m_pFile->GetPos();
+ CAutoPtr<CBaseSplitterOutputPin> pPinOut(DNew CRealMediaSplitterOutputPin(mts, name, this, this, &hr));
+ if(SUCCEEDED(AddOutputPin((DWORD)pmp->stream, pPinOut)))
+ {
+ if(!m_rtStop)
+ m_pFile->m_p.tDuration = max(m_pFile->m_p.tDuration, pmp->tDuration);
+ }
+ }
- HRESULT hr;
+ pos = m_pFile->m_subs.GetHeadPosition();
+ for(DWORD stream = 0; pos; stream++)
+ {
+ CRMFile::subtitle& s = m_pFile->m_subs.GetNext(pos);
- MediaPacketHeader mph;
- if(S_OK != (hr = m_pFile->Read(mph, false)))
- break;
+ CStringW name;
+ name.Format(L"Subtitle %02d", stream);
+ if(!s.name.IsEmpty()) name += L" (" + CStringW(CString(s.name)) + L")";
- m_rtDuration = max((__int64)(10000i64*mph.tStart), m_rtDuration);
+ CMediaType mt;
+ mt.SetSampleSize(1);
+ mt.majortype = MEDIATYPE_Text;
- if(mph.stream == stream && (mph.flags&MediaPacketHeader::PN_KEYFRAME_FLAG) && tLastStart != mph.tStart)
- {
- CAutoPtr<IndexRecord> pir(DNew IndexRecord);
- pir->tStart = mph.tStart;
- pir->ptrFilePos = (UINT32)filepos;
- pir->packet = nPacket;
- m_pFile->m_irs.AddTail(pir);
+ CAtlArray<CMediaType> mts;
+ mts.Add(mt);
- tLastStart = mph.tStart;
- }
+ HRESULT hr;
- m_nOpenProgress = m_pFile->GetPos()*100/m_pFile->GetLength();
+ CAutoPtr<CBaseSplitterOutputPin> pPinOut(DNew CRealMediaSplitterOutputPin(mts, name, this, this, &hr));
+ AddOutputPin((DWORD)~stream, pPinOut);
+ }
- DWORD cmd;
- if(CheckRequest(&cmd))
- {
- if(cmd == CMD_EXIT) m_fAbort = true;
- else Reply(S_OK);
- }
- }
- }
+ m_rtDuration = m_rtNewStop = m_rtStop = 10000i64 * m_pFile->m_p.tDuration;
- m_nOpenProgress = 100;
+ SetProperty(L"TITL", CStringW(m_pFile->m_cd.title));
+ SetProperty(L"AUTH", CStringW(m_pFile->m_cd.author));
+ SetProperty(L"CPYR", CStringW(m_pFile->m_cd.copyright));
+ SetProperty(L"DESC", CStringW(m_pFile->m_cd.comment));
- if(m_fAbort) m_pFile->m_irs.RemoveAll();
+ return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
+}
- m_fAbort = false;
- }
+bool CRealMediaSplitterFilter::DemuxInit()
+{
+ if(!m_pFile) return(false);
- m_seekpos = NULL;
- m_seekpacket = 0;
- m_seekfilepos = 0;
+ // reindex if needed
- return(true);
-}
+ if(m_pFile->m_irs.GetCount() == 0)
+ {
+ m_nOpenProgress = 0;
+ m_rtDuration = 0;
-void CRealMediaSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
-{
- if(rt <= 0)
- {
- m_seekpos = m_pFile->m_dcs.GetHeadPosition();
- m_seekpacket = 0;
- m_seekfilepos = m_pFile->m_dcs.GetHead()->pos;
- }
- else
- {
- m_seekpos = NULL;
-
- POSITION pos = m_pFile->m_irs.GetTailPosition();
- while(pos && !m_seekpos)
- {
- IndexRecord* pir = m_pFile->m_irs.GetPrev(pos);
- if(pir->tStart <= rt/10000)
- {
- m_seekpacket = pir->packet;
-
- pos = m_pFile->m_dcs.GetTailPosition();
- while(pos && !m_seekpos)
- {
- POSITION tmp = pos;
-
- DataChunk* pdc = m_pFile->m_dcs.GetPrev(pos);
-
- if(pdc->pos <= pir->ptrFilePos)
- {
- m_seekpos = tmp;
- m_seekfilepos = pir->ptrFilePos;
-
- POSITION pos = m_pFile->m_dcs.GetHeadPosition();
- while(pos != m_seekpos)
- {
- m_seekpacket -= m_pFile->m_dcs.GetNext(pos)->nPackets;
- }
- }
- }
-
- // search the closest keyframe to the seek time (commented out 'cause rm seems to index all of its keyframes...)
-/*
- if(m_seekpos)
- {
- DataChunk* pdc = m_pFile->m_dcs.GetAt(m_seekpos);
-
- m_pFile->Seek(m_seekfilepos);
-
- REFERENCE_TIME seektime = -1;
- UINT32 seekstream = -1;
-
- for(UINT32 i = m_seekpacket; i < pdc->nPackets; i++)
- {
- UINT64 filepos = m_pFile->GetPos();
-
- MediaPacketHeader mph;
- if(S_OK != m_pFile->Read(mph, false))
- break;
-
- if(seekstream == -1) seekstream = mph.stream;
- if(seekstream != mph.stream) continue;
-
- if(seektime == 10000i64*mph.tStart) continue;
- if(rt < 10000i64*mph.tStart) break;
-
- if((mph.flags&MediaPacketHeader::PN_KEYFRAME_FLAG))
- {
- m_seekpacket = i;
- m_seekfilepos = filepos;
- seektime = 10000i64*mph.tStart;
- }
- }
- }
-*/
- }
- }
-
- if(!m_seekpos)
- {
- m_seekpos = m_pFile->m_dcs.GetHeadPosition();
- m_seekpacket = 0;
- m_seekfilepos = m_pFile->m_dcs.GetAt(m_seekpos)->pos;
- }
- }
-}
+ int stream = m_pFile->GetMasterStream();
-bool CRealMediaSplitterFilter::DemuxLoop()
-{
- HRESULT hr = S_OK;
- POSITION pos;
+ UINT32 tLastStart = -1;
+ UINT32 nPacket = 0;
- pos = m_pFile->m_subs.GetHeadPosition();
- for(DWORD stream = 0; pos && SUCCEEDED(hr) && !CheckRequest(NULL); stream++)
- {
- CRMFile::subtitle& s = m_pFile->m_subs.GetNext(pos);
+ POSITION pos = m_pFile->m_dcs.GetHeadPosition();
+ while(pos && !m_fAbort)
+ {
+ DataChunk* pdc = m_pFile->m_dcs.GetNext(pos);
- CAutoPtr<Packet> p(DNew Packet);
+ m_pFile->Seek(pdc->pos);
- p->TrackNumber = ~stream;
- p->bSyncPoint = TRUE;
- p->rtStart = 0;
- p->rtStop = 1;
+ for(UINT32 i = 0; i < pdc->nPackets && !m_fAbort; i++, nPacket++)
+ {
+ UINT64 filepos = m_pFile->GetPos();
- p->SetCount((4+1) + (2+4+(s.name.GetLength()+1)*2) + (2+4+s.data.GetLength()));
- BYTE* ptr = p->GetData();
+ HRESULT hr;
- strcpy((char*)ptr, "GAB2"); ptr += 4+1;
+ MediaPacketHeader mph;
+ if(S_OK != (hr = m_pFile->Read(mph, false)))
+ break;
- *(WORD*)ptr = 2; ptr += 2;
- *(DWORD*)ptr = (s.name.GetLength()+1)*2; ptr += 4;
- wcscpy((WCHAR*)ptr, CStringW(s.name)); ptr += (s.name.GetLength()+1)*2;
+ m_rtDuration = max((__int64)(10000i64 * mph.tStart), m_rtDuration);
- *(WORD*)ptr = 4; ptr += 2;
- *(DWORD*)ptr = s.data.GetLength(); ptr += 4;
- memcpy((char*)ptr, s.data, s.data.GetLength()); ptr += s.name.GetLength();
+ if(mph.stream == stream && (mph.flags & MediaPacketHeader::PN_KEYFRAME_FLAG) && tLastStart != mph.tStart)
+ {
+ CAutoPtr<IndexRecord> pir(DNew IndexRecord);
+ pir->tStart = mph.tStart;
+ pir->ptrFilePos = (UINT32)filepos;
+ pir->packet = nPacket;
+ m_pFile->m_irs.AddTail(pir);
- hr = DeliverPacket(p);
- }
+ tLastStart = mph.tStart;
+ }
+
+ m_nOpenProgress = m_pFile->GetPos() * 100 / m_pFile->GetLength();
+
+ DWORD cmd;
+ if(CheckRequest(&cmd))
+ {
+ if(cmd == CMD_EXIT) m_fAbort = true;
+ else Reply(S_OK);
+ }
+ }
+ }
- pos = m_seekpos;
- while(pos && SUCCEEDED(hr) && !CheckRequest(NULL))
- {
- DataChunk* pdc = m_pFile->m_dcs.GetNext(pos);
+ m_nOpenProgress = 100;
- m_pFile->Seek(m_seekfilepos > 0 ? m_seekfilepos : pdc->pos);
+ if(m_fAbort) m_pFile->m_irs.RemoveAll();
- for(UINT32 i = m_seekpacket; i < pdc->nPackets && SUCCEEDED(hr) && !CheckRequest(NULL); i++)
- {
- MediaPacketHeader mph;
- if(S_OK != (hr = m_pFile->Read(mph)))
- break;
+ m_fAbort = false;
+ }
- CAutoPtr<Packet> p(DNew Packet);
- p->TrackNumber = mph.stream;
- p->bSyncPoint = !!(mph.flags&MediaPacketHeader::PN_KEYFRAME_FLAG);
- p->rtStart = 10000i64*(mph.tStart);
- p->rtStop = p->rtStart+1;
- p->Copy(mph.pData);
- hr = DeliverPacket(p);
- }
+ m_seekpos = NULL;
+ m_seekpacket = 0;
+ m_seekfilepos = 0;
- m_seekpacket = 0;
- m_seekfilepos = 0;
- }
+ return(true);
+}
- return(true);
+void CRealMediaSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
+{
+ if(rt <= 0)
+ {
+ m_seekpos = m_pFile->m_dcs.GetHeadPosition();
+ m_seekpacket = 0;
+ m_seekfilepos = m_pFile->m_dcs.GetHead()->pos;
+ }
+ else
+ {
+ m_seekpos = NULL;
+
+ POSITION pos = m_pFile->m_irs.GetTailPosition();
+ while(pos && !m_seekpos)
+ {
+ IndexRecord* pir = m_pFile->m_irs.GetPrev(pos);
+ if(pir->tStart <= rt / 10000)
+ {
+ m_seekpacket = pir->packet;
+
+ pos = m_pFile->m_dcs.GetTailPosition();
+ while(pos && !m_seekpos)
+ {
+ POSITION tmp = pos;
+
+ DataChunk* pdc = m_pFile->m_dcs.GetPrev(pos);
+
+ if(pdc->pos <= pir->ptrFilePos)
+ {
+ m_seekpos = tmp;
+ m_seekfilepos = pir->ptrFilePos;
+
+ POSITION pos = m_pFile->m_dcs.GetHeadPosition();
+ while(pos != m_seekpos)
+ {
+ m_seekpacket -= m_pFile->m_dcs.GetNext(pos)->nPackets;
+ }
+ }
+ }
+
+ // search the closest keyframe to the seek time (commented out 'cause rm seems to index all of its keyframes...)
+ /*
+ if(m_seekpos)
+ {
+ DataChunk* pdc = m_pFile->m_dcs.GetAt(m_seekpos);
+
+ m_pFile->Seek(m_seekfilepos);
+
+ REFERENCE_TIME seektime = -1;
+ UINT32 seekstream = -1;
+
+ for(UINT32 i = m_seekpacket; i < pdc->nPackets; i++)
+ {
+ UINT64 filepos = m_pFile->GetPos();
+
+ MediaPacketHeader mph;
+ if(S_OK != m_pFile->Read(mph, false))
+ break;
+
+ if(seekstream == -1) seekstream = mph.stream;
+ if(seekstream != mph.stream) continue;
+
+ if(seektime == 10000i64*mph.tStart) continue;
+ if(rt < 10000i64*mph.tStart) break;
+
+ if((mph.flags&MediaPacketHeader::PN_KEYFRAME_FLAG))
+ {
+ m_seekpacket = i;
+ m_seekfilepos = filepos;
+ seektime = 10000i64*mph.tStart;
+ }
+ }
+ }
+ */
+ }
+ }
+
+ if(!m_seekpos)
+ {
+ m_seekpos = m_pFile->m_dcs.GetHeadPosition();
+ m_seekpacket = 0;
+ m_seekfilepos = m_pFile->m_dcs.GetAt(m_seekpos)->pos;
+ }
+ }
+}
+
+bool CRealMediaSplitterFilter::DemuxLoop()
+{
+ HRESULT hr = S_OK;
+ POSITION pos;
+
+ pos = m_pFile->m_subs.GetHeadPosition();
+ for(DWORD stream = 0; pos && SUCCEEDED(hr) && !CheckRequest(NULL); stream++)
+ {
+ CRMFile::subtitle& s = m_pFile->m_subs.GetNext(pos);
+
+ CAutoPtr<Packet> p(DNew Packet);
+
+ p->TrackNumber = ~stream;
+ p->bSyncPoint = TRUE;
+ p->rtStart = 0;
+ p->rtStop = 1;
+
+ p->SetCount((4 + 1) + (2 + 4 + (s.name.GetLength() + 1) * 2) + (2 + 4 + s.data.GetLength()));
+ BYTE* ptr = p->GetData();
+
+ strcpy((char*)ptr, "GAB2");
+ ptr += 4 + 1;
+
+ *(WORD*)ptr = 2;
+ ptr += 2;
+ *(DWORD*)ptr = (s.name.GetLength() + 1) * 2;
+ ptr += 4;
+ wcscpy((WCHAR*)ptr, CStringW(s.name));
+ ptr += (s.name.GetLength() + 1) * 2;
+
+ *(WORD*)ptr = 4;
+ ptr += 2;
+ *(DWORD*)ptr = s.data.GetLength();
+ ptr += 4;
+ memcpy((char*)ptr, s.data, s.data.GetLength());
+ ptr += s.name.GetLength();
+
+ hr = DeliverPacket(p);
+ }
+
+ pos = m_seekpos;
+ while(pos && SUCCEEDED(hr) && !CheckRequest(NULL))
+ {
+ DataChunk* pdc = m_pFile->m_dcs.GetNext(pos);
+
+ m_pFile->Seek(m_seekfilepos > 0 ? m_seekfilepos : pdc->pos);
+
+ for(UINT32 i = m_seekpacket; i < pdc->nPackets && SUCCEEDED(hr) && !CheckRequest(NULL); i++)
+ {
+ MediaPacketHeader mph;
+ if(S_OK != (hr = m_pFile->Read(mph)))
+ break;
+
+ CAutoPtr<Packet> p(DNew Packet);
+ p->TrackNumber = mph.stream;
+ p->bSyncPoint = !!(mph.flags & MediaPacketHeader::PN_KEYFRAME_FLAG);
+ p->rtStart = 10000i64 * (mph.tStart);
+ p->rtStop = p->rtStart + 1;
+ p->Copy(mph.pData);
+ hr = DeliverPacket(p);
+ }
+
+ m_seekpacket = 0;
+ m_seekfilepos = 0;
+ }
+
+ return(true);
}
// IKeyFrameInfo
STDMETHODIMP CRealMediaSplitterFilter::GetKeyFrameCount(UINT& nKFs)
{
- if(!m_pFile) return E_UNEXPECTED;
- nKFs = m_pFile->m_irs.GetCount();
- return S_OK;
+ if(!m_pFile) return E_UNEXPECTED;
+ nKFs = m_pFile->m_irs.GetCount();
+ return S_OK;
}
STDMETHODIMP CRealMediaSplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs)
{
- CheckPointer(pFormat, E_POINTER);
- CheckPointer(pKFs, E_POINTER);
+ CheckPointer(pFormat, E_POINTER);
+ CheckPointer(pKFs, E_POINTER);
- if(!m_pFile) return E_UNEXPECTED;
- if(*pFormat != TIME_FORMAT_MEDIA_TIME) return E_INVALIDARG;
+ if(!m_pFile) return E_UNEXPECTED;
+ if(*pFormat != TIME_FORMAT_MEDIA_TIME) return E_INVALIDARG;
- UINT nKFsTmp = 0;
- POSITION pos = m_pFile->m_irs.GetHeadPosition();
- for(int i = 0; pos && nKFsTmp < nKFs; i++)
- pKFs[nKFsTmp++] = 10000i64*m_pFile->m_irs.GetNext(pos)->tStart;
- nKFs = nKFsTmp;
+ UINT nKFsTmp = 0;
+ POSITION pos = m_pFile->m_irs.GetHeadPosition();
+ for(int i = 0; pos && nKFsTmp < nKFs; i++)
+ pKFs[nKFsTmp++] = 10000i64 * m_pFile->m_irs.GetNext(pos)->tStart;
+ nKFs = nKFsTmp;
- return S_OK;
+ return S_OK;
}
//
@@ -740,7 +787,7 @@ STDMETHODIMP CRealMediaSplitterFilter::GetKeyFrames(const GUID* pFormat, REFEREN
//
CRealMediaSplitterOutputPin::CRealMediaSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr)
- : CBaseSplitterOutputPin(mts, pName, pFilter, pLock, phr)
+ : CBaseSplitterOutputPin(mts, pName, pFilter, pLock, phr)
{
}
@@ -750,218 +797,230 @@ CRealMediaSplitterOutputPin::~CRealMediaSplitterOutputPin()
HRESULT CRealMediaSplitterOutputPin::DeliverEndFlush()
{
- {
- CAutoLock cAutoLock(&m_csQueue);
- m_segments.Clear();
- }
+ {
+ CAutoLock cAutoLock(&m_csQueue);
+ m_segments.Clear();
+ }
- return __super::DeliverEndFlush();
+ return __super::DeliverEndFlush();
}
HRESULT CRealMediaSplitterOutputPin::DeliverSegments()
{
- HRESULT hr;
-
- if(m_segments.GetCount() == 0)
- {
- m_segments.Clear();
- return S_OK;
- }
-
- CAutoPtr<Packet> p(DNew Packet());
-
- p->TrackNumber = -1;
- p->bDiscontinuity = m_segments.fDiscontinuity;
- p->bSyncPoint = m_segments.fSyncPoint;
- p->rtStart = m_segments.rtStart;
- p->rtStop = m_segments.rtStart+1;
-
- DWORD len = 0, total = 0;
- POSITION pos = m_segments.GetHeadPosition();
- while(pos)
- {
- segment* s = m_segments.GetNext(pos);
- len = max(len, s->offset + s->data.GetCount());
- total += s->data.GetCount();
- }
- ASSERT(len == total);
- len += 1 + 2*4*(!m_segments.fMerged ? m_segments.GetCount() : 1);
-
- p->SetCount(len);
-
- BYTE* pData = p->GetData();
-
- *pData++ = m_segments.fMerged ? 0 : m_segments.GetCount()-1;
-
- if(m_segments.fMerged)
- {
- *((DWORD*)pData) = 1; pData += 4;
- *((DWORD*)pData) = 0; pData += 4;
- }
- else
- {
- pos = m_segments.GetHeadPosition();
- while(pos)
- {
- *((DWORD*)pData) = 1; pData += 4;
- *((DWORD*)pData) = m_segments.GetNext(pos)->offset; pData += 4;
- }
- }
-
- pos = m_segments.GetHeadPosition();
- while(pos)
- {
- segment* s = m_segments.GetNext(pos);
- memcpy(pData + s->offset, s->data.GetData(), s->data.GetCount());
- }
-
- hr = __super::DeliverPacket(p);
-
- m_segments.Clear();
-
- return hr;
+ HRESULT hr;
+
+ if(m_segments.GetCount() == 0)
+ {
+ m_segments.Clear();
+ return S_OK;
+ }
+
+ CAutoPtr<Packet> p(DNew Packet());
+
+ p->TrackNumber = -1;
+ p->bDiscontinuity = m_segments.fDiscontinuity;
+ p->bSyncPoint = m_segments.fSyncPoint;
+ p->rtStart = m_segments.rtStart;
+ p->rtStop = m_segments.rtStart + 1;
+
+ DWORD len = 0, total = 0;
+ POSITION pos = m_segments.GetHeadPosition();
+ while(pos)
+ {
+ segment* s = m_segments.GetNext(pos);
+ len = max(len, s->offset + s->data.GetCount());
+ total += s->data.GetCount();
+ }
+ ASSERT(len == total);
+ len += 1 + 2 * 4 * (!m_segments.fMerged ? m_segments.GetCount() : 1);
+
+ p->SetCount(len);
+
+ BYTE* pData = p->GetData();
+
+ *pData++ = m_segments.fMerged ? 0 : m_segments.GetCount() - 1;
+
+ if(m_segments.fMerged)
+ {
+ *((DWORD*)pData) = 1;
+ pData += 4;
+ *((DWORD*)pData) = 0;
+ pData += 4;
+ }
+ else
+ {
+ pos = m_segments.GetHeadPosition();
+ while(pos)
+ {
+ *((DWORD*)pData) = 1;
+ pData += 4;
+ *((DWORD*)pData) = m_segments.GetNext(pos)->offset;
+ pData += 4;
+ }
+ }
+
+ pos = m_segments.GetHeadPosition();
+ while(pos)
+ {
+ segment* s = m_segments.GetNext(pos);
+ memcpy(pData + s->offset, s->data.GetData(), s->data.GetCount());
+ }
+
+ hr = __super::DeliverPacket(p);
+
+ m_segments.Clear();
+
+ return hr;
}
HRESULT CRealMediaSplitterOutputPin::DeliverPacket(CAutoPtr<Packet> p)
{
- HRESULT hr = S_OK;
-
- ASSERT(p->rtStart < p->rtStop);
-
- if(m_mt.subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3)
- {
- WORD* s = (WORD*)p->GetData();
- WORD* e = s + p->GetCount()/2;
- while(s < e) bswap(*s++);
- }
-
- if(m_mt.subtype == MEDIASUBTYPE_RV10 || m_mt.subtype == MEDIASUBTYPE_RV20
- || m_mt.subtype == MEDIASUBTYPE_RV30 || m_mt.subtype == MEDIASUBTYPE_RV40
- || m_mt.subtype == MEDIASUBTYPE_RV41)
- {
- CAutoLock cAutoLock(&m_csQueue);
-
- int len = p->GetCount();
- BYTE* pIn = p->GetData();
- BYTE* pInOrg = pIn;
-
- if(m_segments.rtStart != p->rtStart)
- {
- if(S_OK != (hr = DeliverSegments()))
- return hr;
- }
-
- if(!m_segments.fDiscontinuity && p->bDiscontinuity)
- m_segments.fDiscontinuity = true;
- m_segments.fSyncPoint = !!p->bSyncPoint;
- m_segments.rtStart = p->rtStart;
-
- while(pIn - pInOrg < len)
- {
- BYTE hdr = *pIn++, subseq = 0, seqnum = 0;
- DWORD packetlen = 0, packetoffset = 0;
-
- if((hdr&0xc0) == 0x40)
- {
- pIn++;
- packetlen = len - (pIn - pInOrg);
- }
- else
- {
- if((hdr&0x40) == 0)
- subseq = (*pIn++)&0x7f;
-
- #define GetWORD(var) \
+ HRESULT hr = S_OK;
+
+ ASSERT(p->rtStart < p->rtStop);
+
+ if(m_mt.subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3)
+ {
+ WORD* s = (WORD*)p->GetData();
+ WORD* e = s + p->GetCount() / 2;
+ while(s < e) bswap(*s++);
+ }
+
+ if(m_mt.subtype == MEDIASUBTYPE_RV10 || m_mt.subtype == MEDIASUBTYPE_RV20
+ || m_mt.subtype == MEDIASUBTYPE_RV30 || m_mt.subtype == MEDIASUBTYPE_RV40
+ || m_mt.subtype == MEDIASUBTYPE_RV41)
+ {
+ CAutoLock cAutoLock(&m_csQueue);
+
+ int len = p->GetCount();
+ BYTE* pIn = p->GetData();
+ BYTE* pInOrg = pIn;
+
+ if(m_segments.rtStart != p->rtStart)
+ {
+ if(S_OK != (hr = DeliverSegments()))
+ return hr;
+ }
+
+ if(!m_segments.fDiscontinuity && p->bDiscontinuity)
+ m_segments.fDiscontinuity = true;
+ m_segments.fSyncPoint = !!p->bSyncPoint;
+ m_segments.rtStart = p->rtStart;
+
+ while(pIn - pInOrg < len)
+ {
+ BYTE hdr = *pIn++, subseq = 0, seqnum = 0;
+ DWORD packetlen = 0, packetoffset = 0;
+
+ if((hdr & 0xc0) == 0x40)
+ {
+ pIn++;
+ packetlen = len - (pIn - pInOrg);
+ }
+ else
+ {
+ if((hdr & 0x40) == 0)
+ subseq = (*pIn++) & 0x7f;
+
+#define GetWORD(var) \
var = (var<<8)|(*pIn++); \
var = (var<<8)|(*pIn++); \
+
+ GetWORD(packetlen);
+ if(packetlen & 0x8000) m_segments.fMerged = true;
+ if((packetlen & 0x4000) == 0)
+ {
+ GetWORD(packetlen);
+ packetlen &= 0x3fffffff;
+ }
+ else packetlen &= 0x3fff;
+
+ GetWORD(packetoffset);
+ if((packetoffset & 0x4000) == 0)
+ {
+ GetWORD(packetoffset);
+ packetoffset &= 0x3fffffff;
+ }
+ else packetoffset &= 0x3fff;
+
+#undef GetWORD
+
+ if((hdr & 0xc0) == 0xc0)
+ m_segments.rtStart = 10000i64 * packetoffset - m_rtStart, packetoffset = 0;
+ else if((hdr & 0xc0) == 0x80)
+ packetoffset = packetlen - packetoffset;
+
+ seqnum = *pIn++;
+ }
- GetWORD(packetlen);
- if(packetlen&0x8000) m_segments.fMerged = true;
- if((packetlen&0x4000) == 0) {GetWORD(packetlen); packetlen &= 0x3fffffff;}
- else packetlen &= 0x3fff;
-
- GetWORD(packetoffset);
- if((packetoffset&0x4000) == 0) {GetWORD(packetoffset); packetoffset &= 0x3fffffff;}
- else packetoffset &= 0x3fff;
-
- #undef GetWORD
+ int len2 = min(len - (pIn - pInOrg), packetlen - packetoffset);
- if((hdr&0xc0) == 0xc0)
- m_segments.rtStart = 10000i64*packetoffset - m_rtStart, packetoffset = 0;
- else if((hdr&0xc0) == 0x80)
- packetoffset = packetlen - packetoffset;
+ CAutoPtr<segment> s(DNew segment);
+ s->offset = packetoffset;
+ s->data.SetCount(len2);
+ memcpy(s->data.GetData(), pIn, len2);
+ m_segments.AddTail(s);
- seqnum = *pIn++;
- }
+ pIn += len2;
- int len2 = min(len - (pIn - pInOrg), packetlen - packetoffset);
-
- CAutoPtr<segment> s(DNew segment);
- s->offset = packetoffset;
- s->data.SetCount(len2);
- memcpy(s->data.GetData(), pIn, len2);
- m_segments.AddTail(s);
-
- pIn += len2;
-
- if((hdr&0x80) || packetoffset+len2 >= packetlen)
- {
- if(S_OK != (hr = DeliverSegments()))
- return hr;
- }
- }
- }
- else if(m_mt.subtype == MEDIASUBTYPE_RAAC || m_mt.subtype == MEDIASUBTYPE_RACP
- || m_mt.subtype == MEDIASUBTYPE_AAC)
- {
- BYTE* ptr = p->GetData()+2;
-
- CAtlList<WORD> sizes;
- int total = 0;
- int remaining = p->GetCount()-2;
- int expected = *(ptr-1)>>4;
-
- while(total < remaining)
- {
- int size = (ptr[0]<<8)|(ptr[1]);
- sizes.AddTail(size);
- total += size;
- ptr += 2;
- remaining -= 2;
- expected--;
- }
-
- ASSERT(total == remaining);
- ASSERT(expected == 0);
-
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
- REFERENCE_TIME rtDur = 10240000000i64/wfe->nSamplesPerSec * (wfe->cbSize>2?2:1);
- REFERENCE_TIME rtStart = p->rtStart;
- BOOL bDiscontinuity = p->bDiscontinuity;
-
- POSITION pos = sizes.GetHeadPosition();
- while(pos)
- {
- WORD size = sizes.GetNext(pos);
-
- CAutoPtr<Packet> p(DNew Packet);
- p->bDiscontinuity = bDiscontinuity;
- p->bSyncPoint = true;
- p->rtStart = rtStart;
- p->rtStop = rtStart += rtDur;
- p->SetData(ptr, size);
- ptr += size;
- bDiscontinuity = false;
- if(S_OK != (hr = __super::DeliverPacket(p)))
- break;
- }
- }
- else
- {
- hr = __super::DeliverPacket(p);
- }
-
- return hr;
+ if((hdr & 0x80) || packetoffset + len2 >= packetlen)
+ {
+ if(S_OK != (hr = DeliverSegments()))
+ return hr;
+ }
+ }
+ }
+ else if(m_mt.subtype == MEDIASUBTYPE_RAAC || m_mt.subtype == MEDIASUBTYPE_RACP
+ || m_mt.subtype == MEDIASUBTYPE_AAC)
+ {
+ BYTE* ptr = p->GetData() + 2;
+
+ CAtlList<WORD> sizes;
+ int total = 0;
+ int remaining = p->GetCount() - 2;
+ int expected = *(ptr - 1) >> 4;
+
+ while(total < remaining)
+ {
+ int size = (ptr[0] << 8) | (ptr[1]);
+ sizes.AddTail(size);
+ total += size;
+ ptr += 2;
+ remaining -= 2;
+ expected--;
+ }
+
+ ASSERT(total == remaining);
+ ASSERT(expected == 0);
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_mt.pbFormat;
+ REFERENCE_TIME rtDur = 10240000000i64 / wfe->nSamplesPerSec * (wfe->cbSize > 2 ? 2 : 1);
+ REFERENCE_TIME rtStart = p->rtStart;
+ BOOL bDiscontinuity = p->bDiscontinuity;
+
+ POSITION pos = sizes.GetHeadPosition();
+ while(pos)
+ {
+ WORD size = sizes.GetNext(pos);
+
+ CAutoPtr<Packet> p(DNew Packet);
+ p->bDiscontinuity = bDiscontinuity;
+ p->bSyncPoint = true;
+ p->rtStart = rtStart;
+ p->rtStop = rtStart += rtDur;
+ p->SetData(ptr, size);
+ ptr += size;
+ bDiscontinuity = false;
+ if(S_OK != (hr = __super::DeliverPacket(p)))
+ break;
+ }
+ }
+ else
+ {
+ hr = __super::DeliverPacket(p);
+ }
+
+ return hr;
}
//
@@ -969,10 +1028,10 @@ HRESULT CRealMediaSplitterOutputPin::DeliverPacket(CAutoPtr<Packet> p)
//
CRealMediaSourceFilter::CRealMediaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CRealMediaSplitterFilter(pUnk, phr)
+ : CRealMediaSplitterFilter(pUnk, phr)
{
- m_clsid = __uuidof(this);
- m_pInput.Free();
+ m_clsid = __uuidof(this);
+ m_pInput.Free();
}
//
@@ -980,468 +1039,488 @@ CRealMediaSourceFilter::CRealMediaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
//
CRMFile::CRMFile(IAsyncReader* pAsyncReader, HRESULT& hr)
- : CBaseSplitterFile(pAsyncReader, hr)
+ : CBaseSplitterFile(pAsyncReader, hr)
{
- if(FAILED(hr)) return;
- hr = Init();
+ if(FAILED(hr)) return;
+ hr = Init();
}
-template<typename T>
+template<typename T>
HRESULT CRMFile::Read(T& var)
{
- HRESULT hr = ByteRead((BYTE*)&var, sizeof(var));
- bswap(var);
- return hr;
+ HRESULT hr = ByteRead((BYTE*)&var, sizeof(var));
+ bswap(var);
+ return hr;
}
HRESULT CRMFile::Read(ChunkHdr& hdr)
{
- memset(&hdr, 0, sizeof(hdr));
- HRESULT hr;
- if(S_OK != (hr = Read(hdr.object_id))
- || S_OK != (hr = Read(hdr.size))
- || S_OK != (hr = Read(hdr.object_version)))
- return hr;
- return S_OK;
+ memset(&hdr, 0, sizeof(hdr));
+ HRESULT hr;
+ if(S_OK != (hr = Read(hdr.object_id))
+ || S_OK != (hr = Read(hdr.size))
+ || S_OK != (hr = Read(hdr.object_version)))
+ return hr;
+ return S_OK;
}
HRESULT CRMFile::Read(MediaPacketHeader& mph, bool fFull)
{
- memset(&mph, 0, FIELD_OFFSET(MediaPacketHeader, pData));
- mph.stream = -1;
-
- HRESULT hr;
-
- UINT16 object_version;
- if(S_OK != (hr = Read(object_version))) return hr;
- if(object_version != 0 && object_version != 1) return S_OK;
-
- UINT8 flags;
- if(S_OK != (hr = Read(mph.len))
- || S_OK != (hr = Read(mph.stream))
- || S_OK != (hr = Read(mph.tStart))
- || S_OK != (hr = Read(mph.reserved))
- || S_OK != (hr = Read(flags)))
- return hr;
- mph.flags = (MediaPacketHeader::flag_t)flags;
-
- LONG len = mph.len;
- len -= sizeof(object_version);
- len -= FIELD_OFFSET(MediaPacketHeader, flags);
- len -= sizeof(flags);
- ASSERT(len >= 0);
- len = max(len, 0);
-
- if(fFull)
- {
- mph.pData.SetCount(len);
- if(mph.len > 0 && S_OK != (hr = ByteRead(mph.pData.GetData(), len)))
- return hr;
- }
- else
- {
- Seek(GetPos() + len);
- }
-
- return S_OK;
+ memset(&mph, 0, FIELD_OFFSET(MediaPacketHeader, pData));
+ mph.stream = -1;
+
+ HRESULT hr;
+
+ UINT16 object_version;
+ if(S_OK != (hr = Read(object_version))) return hr;
+ if(object_version != 0 && object_version != 1) return S_OK;
+
+ UINT8 flags;
+ if(S_OK != (hr = Read(mph.len))
+ || S_OK != (hr = Read(mph.stream))
+ || S_OK != (hr = Read(mph.tStart))
+ || S_OK != (hr = Read(mph.reserved))
+ || S_OK != (hr = Read(flags)))
+ return hr;
+ mph.flags = (MediaPacketHeader::flag_t)flags;
+
+ LONG len = mph.len;
+ len -= sizeof(object_version);
+ len -= FIELD_OFFSET(MediaPacketHeader, flags);
+ len -= sizeof(flags);
+ ASSERT(len >= 0);
+ len = max(len, 0);
+
+ if(fFull)
+ {
+ mph.pData.SetCount(len);
+ if(mph.len > 0 && S_OK != (hr = ByteRead(mph.pData.GetData(), len)))
+ return hr;
+ }
+ else
+ {
+ Seek(GetPos() + len);
+ }
+
+ return S_OK;
}
HRESULT CRMFile::Init()
{
- Seek(0);
-
- bool fFirstChunk = true;
-
- HRESULT hr;
-
- ChunkHdr hdr;
- while(GetRemaining() && S_OK == (hr = Read(hdr)))
- {
- __int64 pos = GetPos() - sizeof(hdr);
-
- if(fFirstChunk && hdr.object_id != '.RMF')
- return E_FAIL;
-
- fFirstChunk = false;
-
- if(pos + hdr.size > GetLength() && hdr.object_id != 'DATA') // truncated?
- break;
-
- if(hdr.object_id == 0x2E7261FD) // '.ra+0xFD'
- return E_FAIL;
-
- if(hdr.object_version == 0)
- {
- switch(hdr.object_id)
- {
- case '.RMF':
- if(S_OK != (hr = Read(m_fh.version))) return hr;
- if(hdr.size == 0x10) {WORD w = 0; if(S_OK != (hr = Read(w))) return hr; m_fh.nHeaders = w;}
- else if(S_OK != (hr = Read(m_fh.nHeaders))) return hr;
- break;
- case 'CONT':
- UINT16 slen;
- if(S_OK != (hr = Read(slen))) return hr;
- if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.title.GetBufferSetLength(slen), slen))) return hr;
- if(S_OK != (hr = Read(slen))) return hr;
- if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.author.GetBufferSetLength(slen), slen))) return hr;
- if(S_OK != (hr = Read(slen))) return hr;
- if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.copyright.GetBufferSetLength(slen), slen))) return hr;
- if(S_OK != (hr = Read(slen))) return hr;
- if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.comment.GetBufferSetLength(slen), slen))) return hr;
- break;
- case 'PROP':
- if(S_OK != (hr = Read(m_p.maxBitRate))) return hr;
- if(S_OK != (hr = Read(m_p.avgBitRate))) return hr;
- if(S_OK != (hr = Read(m_p.maxPacketSize))) return hr;
- if(S_OK != (hr = Read(m_p.avgPacketSize))) return hr;
- if(S_OK != (hr = Read(m_p.nPackets))) return hr;
- if(S_OK != (hr = Read(m_p.tDuration))) return hr;
- if(S_OK != (hr = Read(m_p.tPreroll))) return hr;
- if(S_OK != (hr = Read(m_p.ptrIndex))) return hr;
- if(S_OK != (hr = Read(m_p.ptrData))) return hr;
- if(S_OK != (hr = Read(m_p.nStreams))) return hr;
- UINT16 flags;
- if(S_OK != (hr = Read(flags))) return hr;
- m_p.flags = (Properies::flags_t)flags;
- break;
- case 'MDPR':
- {
- CAutoPtr<MediaProperies> mp(DNew MediaProperies);
- if(S_OK != (hr = Read(mp->stream))) return hr;
- if(S_OK != (hr = Read(mp->maxBitRate))) return hr;
- if(S_OK != (hr = Read(mp->avgBitRate))) return hr;
- if(S_OK != (hr = Read(mp->maxPacketSize))) return hr;
- if(S_OK != (hr = Read(mp->avgPacketSize))) return hr;
- if(S_OK != (hr = Read(mp->tStart))) return hr;
- if(S_OK != (hr = Read(mp->tPreroll))) return hr;
- if(S_OK != (hr = Read(mp->tDuration))) return hr;
- UINT8 slen;
- if(S_OK != (hr = Read(slen))) return hr;
- if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)mp->name.GetBufferSetLength(slen), slen))) return hr;
- if(S_OK != (hr = Read(slen))) return hr;
- if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)mp->mime.GetBufferSetLength(slen), slen))) return hr;
- UINT32 tsdlen;
- if(S_OK != (hr = Read(tsdlen))) return hr;
- mp->typeSpecData.SetCount(tsdlen);
- if(tsdlen > 0 && S_OK != (hr = ByteRead(mp->typeSpecData.GetData(), tsdlen))) return hr;
- mp->width = mp->height = 0;
- mp->interlaced = mp->top_field_first = false;
- m_mps.AddTail(mp);
- break;
- }
- case 'DATA':
- {
- CAutoPtr<DataChunk> dc(DNew DataChunk);
- if(S_OK != (hr = Read(dc->nPackets))) return hr;
- if(S_OK != (hr = Read(dc->ptrNext))) return hr;
- dc->pos = GetPos();
- m_dcs.AddTail(dc);
+ Seek(0);
+
+ bool fFirstChunk = true;
+
+ HRESULT hr;
+
+ ChunkHdr hdr;
+ while(GetRemaining() && S_OK == (hr = Read(hdr)))
+ {
+ __int64 pos = GetPos() - sizeof(hdr);
+
+ if(fFirstChunk && hdr.object_id != '.RMF')
+ return E_FAIL;
+
+ fFirstChunk = false;
+
+ if(pos + hdr.size > GetLength() && hdr.object_id != 'DATA') // truncated?
+ break;
+
+ if(hdr.object_id == 0x2E7261FD) // '.ra+0xFD'
+ return E_FAIL;
+
+ if(hdr.object_version == 0)
+ {
+ switch(hdr.object_id)
+ {
+ case '.RMF':
+ if(S_OK != (hr = Read(m_fh.version))) return hr;
+ if(hdr.size == 0x10)
+ {
+ WORD w = 0;
+ if(S_OK != (hr = Read(w))) return hr;
+ m_fh.nHeaders = w;
+ }
+ else if(S_OK != (hr = Read(m_fh.nHeaders))) return hr;
+ break;
+ case 'CONT':
+ UINT16 slen;
+ if(S_OK != (hr = Read(slen))) return hr;
+ if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.title.GetBufferSetLength(slen), slen))) return hr;
+ if(S_OK != (hr = Read(slen))) return hr;
+ if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.author.GetBufferSetLength(slen), slen))) return hr;
+ if(S_OK != (hr = Read(slen))) return hr;
+ if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.copyright.GetBufferSetLength(slen), slen))) return hr;
+ if(S_OK != (hr = Read(slen))) return hr;
+ if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)m_cd.comment.GetBufferSetLength(slen), slen))) return hr;
+ break;
+ case 'PROP':
+ if(S_OK != (hr = Read(m_p.maxBitRate))) return hr;
+ if(S_OK != (hr = Read(m_p.avgBitRate))) return hr;
+ if(S_OK != (hr = Read(m_p.maxPacketSize))) return hr;
+ if(S_OK != (hr = Read(m_p.avgPacketSize))) return hr;
+ if(S_OK != (hr = Read(m_p.nPackets))) return hr;
+ if(S_OK != (hr = Read(m_p.tDuration))) return hr;
+ if(S_OK != (hr = Read(m_p.tPreroll))) return hr;
+ if(S_OK != (hr = Read(m_p.ptrIndex))) return hr;
+ if(S_OK != (hr = Read(m_p.ptrData))) return hr;
+ if(S_OK != (hr = Read(m_p.nStreams))) return hr;
+ UINT16 flags;
+ if(S_OK != (hr = Read(flags))) return hr;
+ m_p.flags = (Properies::flags_t)flags;
+ break;
+ case 'MDPR':
+ {
+ CAutoPtr<MediaProperies> mp(DNew MediaProperies);
+ if(S_OK != (hr = Read(mp->stream))) return hr;
+ if(S_OK != (hr = Read(mp->maxBitRate))) return hr;
+ if(S_OK != (hr = Read(mp->avgBitRate))) return hr;
+ if(S_OK != (hr = Read(mp->maxPacketSize))) return hr;
+ if(S_OK != (hr = Read(mp->avgPacketSize))) return hr;
+ if(S_OK != (hr = Read(mp->tStart))) return hr;
+ if(S_OK != (hr = Read(mp->tPreroll))) return hr;
+ if(S_OK != (hr = Read(mp->tDuration))) return hr;
+ UINT8 slen;
+ if(S_OK != (hr = Read(slen))) return hr;
+ if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)mp->name.GetBufferSetLength(slen), slen))) return hr;
+ if(S_OK != (hr = Read(slen))) return hr;
+ if(slen > 0 && S_OK != (hr = ByteRead((BYTE*)mp->mime.GetBufferSetLength(slen), slen))) return hr;
+ UINT32 tsdlen;
+ if(S_OK != (hr = Read(tsdlen))) return hr;
+ mp->typeSpecData.SetCount(tsdlen);
+ if(tsdlen > 0 && S_OK != (hr = ByteRead(mp->typeSpecData.GetData(), tsdlen))) return hr;
+ mp->width = mp->height = 0;
+ mp->interlaced = mp->top_field_first = false;
+ m_mps.AddTail(mp);
+ break;
+ }
+ case 'DATA':
+ {
+ CAutoPtr<DataChunk> dc(DNew DataChunk);
+ if(S_OK != (hr = Read(dc->nPackets))) return hr;
+ if(S_OK != (hr = Read(dc->ptrNext))) return hr;
+ dc->pos = GetPos();
+ m_dcs.AddTail(dc);
GetDimensions();
- break;
- }
- case 'INDX':
- {
- IndexChunkHeader ich;
- if(S_OK != (hr = Read(ich.nIndices))) return hr;
- if(S_OK != (hr = Read(ich.stream))) return hr;
- if(S_OK != (hr = Read(ich.ptrNext))) return hr;
- int stream = GetMasterStream();
- while(ich.nIndices-- > 0)
- {
- UINT16 object_version;
- if(S_OK != (hr = Read(object_version))) return hr;
- if(object_version == 0)
- {
- CAutoPtr<IndexRecord> ir(DNew IndexRecord);
- if(S_OK != (hr = Read(ir->tStart))) return hr;
- if(S_OK != (hr = Read(ir->ptrFilePos))) return hr;
- if(S_OK != (hr = Read(ir->packet))) return hr;
- if(ich.stream == stream) m_irs.AddTail(ir);
- }
- }
- break;
- }
- case '.SUB':
- if(hdr.size > sizeof(hdr))
- {
- int size = hdr.size - sizeof(hdr);
- CAutoVectorPtr<char> buff;
- if(!buff.Allocate(size)) return E_OUTOFMEMORY;
- char* p = buff;
- if(S_OK != (hr = ByteRead((BYTE*)p, size))) return hr;
- for(char* end = p + size; p < end; )
- {
- subtitle s;
- s.name = p; p += s.name.GetLength()+1;
- CStringA len(p); p += len.GetLength()+1;
- s.data = CStringA(p, strtol(len, NULL, 10)); p += s.data.GetLength();
- m_subs.AddTail(s);
- }
- }
- break;
- }
- }
-
- if(hdr.object_id == 'CONT' && BitRead(32, true) == 'DATA')
- {
- hdr.size = GetPos() - pos;
- }
-
- ASSERT(hdr.object_id == 'DATA'
- || GetPos() == pos + hdr.size
- || GetPos() == pos + sizeof(hdr));
-
- pos += hdr.size;
- if(pos > GetPos())
- Seek(pos);
- }
-
- return S_OK;
+ break;
+ }
+ case 'INDX':
+ {
+ IndexChunkHeader ich;
+ if(S_OK != (hr = Read(ich.nIndices))) return hr;
+ if(S_OK != (hr = Read(ich.stream))) return hr;
+ if(S_OK != (hr = Read(ich.ptrNext))) return hr;
+ int stream = GetMasterStream();
+ while(ich.nIndices-- > 0)
+ {
+ UINT16 object_version;
+ if(S_OK != (hr = Read(object_version))) return hr;
+ if(object_version == 0)
+ {
+ CAutoPtr<IndexRecord> ir(DNew IndexRecord);
+ if(S_OK != (hr = Read(ir->tStart))) return hr;
+ if(S_OK != (hr = Read(ir->ptrFilePos))) return hr;
+ if(S_OK != (hr = Read(ir->packet))) return hr;
+ if(ich.stream == stream) m_irs.AddTail(ir);
+ }
+ }
+ break;
+ }
+ case '.SUB':
+ if(hdr.size > sizeof(hdr))
+ {
+ int size = hdr.size - sizeof(hdr);
+ CAutoVectorPtr<char> buff;
+ if(!buff.Allocate(size)) return E_OUTOFMEMORY;
+ char* p = buff;
+ if(S_OK != (hr = ByteRead((BYTE*)p, size))) return hr;
+ for(char* end = p + size; p < end;)
+ {
+ subtitle s;
+ s.name = p;
+ p += s.name.GetLength() + 1;
+ CStringA len(p);
+ p += len.GetLength() + 1;
+ s.data = CStringA(p, strtol(len, NULL, 10));
+ p += s.data.GetLength();
+ m_subs.AddTail(s);
+ }
+ }
+ break;
+ }
+ }
+
+ if(hdr.object_id == 'CONT' && BitRead(32, true) == 'DATA')
+ {
+ hdr.size = GetPos() - pos;
+ }
+
+ ASSERT(hdr.object_id == 'DATA'
+ || GetPos() == pos + hdr.size
+ || GetPos() == pos + sizeof(hdr));
+
+ pos += hdr.size;
+ if(pos > GetPos())
+ Seek(pos);
+ }
+
+ return S_OK;
}
#define GetBits(n) GetBits2(n, p, bit_offset, bit_buffer)
unsigned int GetBits2(int n, unsigned char*& p, unsigned int& bit_offset, unsigned int& bit_buffer)
{
- unsigned int ret = ((unsigned int)bit_buffer >> (32-(n)));
-
- bit_offset += n;
- bit_buffer <<= n;
- if(bit_offset > (32-16))
- {
- p += bit_offset >> 3;
- bit_offset &= 7;
- bit_buffer = (unsigned int)p[0] << 24;
- bit_buffer |= (unsigned int)p[1] << 16;
- bit_buffer |= (unsigned int)p[2] << 8;
- bit_buffer |= (unsigned int)p[3];
- bit_buffer <<= bit_offset;
- }
-
- return ret;
+ unsigned int ret = ((unsigned int)bit_buffer >> (32 - (n)));
+
+ bit_offset += n;
+ bit_buffer <<= n;
+ if(bit_offset > (32 - 16))
+ {
+ p += bit_offset >> 3;
+ bit_offset &= 7;
+ bit_buffer = (unsigned int)p[0] << 24;
+ bit_buffer |= (unsigned int)p[1] << 16;
+ bit_buffer |= (unsigned int)p[2] << 8;
+ bit_buffer |= (unsigned int)p[3];
+ bit_buffer <<= bit_offset;
+ }
+
+ return ret;
}
void GetDimensions(unsigned char* p, unsigned int* wi, unsigned int* hi)
{
- unsigned int w, h, c;
-
- const unsigned int cw[8] = {160, 176, 240, 320, 352, 640, 704, 0};
- const unsigned int ch1[8] = {120, 132, 144, 240, 288, 480, 0, 0};
- const unsigned int ch2[4] = {180, 360, 576, 0};
-
- unsigned int bit_offset = 0;
- unsigned int bit_buffer = *(unsigned int*)p;
- bswap(bit_buffer);
-
- GetBits(13);
-
- GetBits(13);
-
- w = cw[GetBits(3)];
- if(w == 0)
- {
- do
- {
- c = GetBits(8);
- w += (c << 2);
- }
- while(c == 255);
- }
-
- c = GetBits(3);
-
- h = ch1[c];
- if(h == 0)
- {
- c = ((c << 1) | GetBits(1)) & 3;
-
- h = ch2[c];
- if(h == 0)
- {
- do
- {
- c = GetBits(8);
- h += (c << 2);
- }
- while(c == 255);
- }
- }
-
- *wi = w;
- *hi = h;
+ unsigned int w, h, c;
+
+ const unsigned int cw[8] = {160, 176, 240, 320, 352, 640, 704, 0};
+ const unsigned int ch1[8] = {120, 132, 144, 240, 288, 480, 0, 0};
+ const unsigned int ch2[4] = {180, 360, 576, 0};
+
+ unsigned int bit_offset = 0;
+ unsigned int bit_buffer = *(unsigned int*)p;
+ bswap(bit_buffer);
+
+ GetBits(13);
+
+ GetBits(13);
+
+ w = cw[GetBits(3)];
+ if(w == 0)
+ {
+ do
+ {
+ c = GetBits(8);
+ w += (c << 2);
+ }
+ while(c == 255);
+ }
+
+ c = GetBits(3);
+
+ h = ch1[c];
+ if(h == 0)
+ {
+ c = ((c << 1) | GetBits(1)) & 3;
+
+ h = ch2[c];
+ if(h == 0)
+ {
+ do
+ {
+ c = GetBits(8);
+ h += (c << 2);
+ }
+ while(c == 255);
+ }
+ }
+
+ *wi = w;
+ *hi = h;
}
-void GetDimensions_X10(unsigned char* p, unsigned int* wi, unsigned int* hi,
- bool *interlaced, bool *top_field_first, bool *repeat_field)
-{
- unsigned int w, h, c;
-
- const unsigned int cw[8] = {160, 176, 240, 320, 352, 640, 704, 0};
- const unsigned int ch1[8] = {120, 132, 144, 240, 288, 480, 0, 0};
- const unsigned int ch2[4] = {180, 360, 576, 0};
-
- unsigned int bit_offset = 0;
- unsigned int bit_buffer = *(unsigned int*)p;
- bswap(bit_buffer);
-
- GetBits(9);
-
- *interlaced = false;
- *top_field_first = false;
- *repeat_field = false;
- c = GetBits(1);
- if (c)
- {
- c = GetBits(1);
- if (c)
- *interlaced = true;
- c = GetBits(1);
- if (c)
- *top_field_first = true;
- c = GetBits(1);
- if (c)
- *repeat_field = true;
-
- c = GetBits(1);
- c = GetBits(1);
- if (c)
- GetBits(2);
- }
-
- GetBits(16);
-
- w = cw[GetBits(3)];
- if(w == 0)
- {
- do
- {
- c = GetBits(8);
- w += (c << 2);
- }
- while(c == 255);
- }
-
- c = GetBits(3);
-
- h = ch1[c];
- if(h == 0)
- {
- c = ((c << 1) | GetBits(1)) & 3;
-
- h = ch2[c];
- if(h == 0)
- {
- do
- {
- c = GetBits(8);
- h += (c << 2);
- }
- while(c == 255);
- }
- }
-
- *wi = w;
- *hi = h;
+void GetDimensions_X10(unsigned char* p, unsigned int* wi, unsigned int* hi,
+ bool *interlaced, bool *top_field_first, bool *repeat_field)
+{
+ unsigned int w, h, c;
+
+ const unsigned int cw[8] = {160, 176, 240, 320, 352, 640, 704, 0};
+ const unsigned int ch1[8] = {120, 132, 144, 240, 288, 480, 0, 0};
+ const unsigned int ch2[4] = {180, 360, 576, 0};
+
+ unsigned int bit_offset = 0;
+ unsigned int bit_buffer = *(unsigned int*)p;
+ bswap(bit_buffer);
+
+ GetBits(9);
+
+ *interlaced = false;
+ *top_field_first = false;
+ *repeat_field = false;
+ c = GetBits(1);
+ if(c)
+ {
+ c = GetBits(1);
+ if(c)
+ *interlaced = true;
+ c = GetBits(1);
+ if(c)
+ *top_field_first = true;
+ c = GetBits(1);
+ if(c)
+ *repeat_field = true;
+
+ c = GetBits(1);
+ c = GetBits(1);
+ if(c)
+ GetBits(2);
+ }
+
+ GetBits(16);
+
+ w = cw[GetBits(3)];
+ if(w == 0)
+ {
+ do
+ {
+ c = GetBits(8);
+ w += (c << 2);
+ }
+ while(c == 255);
+ }
+
+ c = GetBits(3);
+
+ h = ch1[c];
+ if(h == 0)
+ {
+ c = ((c << 1) | GetBits(1)) & 3;
+
+ h = ch2[c];
+ if(h == 0)
+ {
+ do
+ {
+ c = GetBits(8);
+ h += (c << 2);
+ }
+ while(c == 255);
+ }
+ }
+
+ *wi = w;
+ *hi = h;
}
void CRMFile::GetDimensions()
{
- POSITION pos = m_mps.GetHeadPosition();
- while(pos)
- {
- UINT64 filepos = GetPos();
-
- MediaProperies* pmp = m_mps.GetNext(pos);
- if(pmp->mime == "video/x-pn-realvideo")
- {
- pmp->width = pmp->height = 0;
-
- rvinfo rvi = *(rvinfo*)pmp->typeSpecData.GetData();
- rvi.bswap();
-
- if(rvi.fcc2 != '04VR' && rvi.fcc2 != '14VR')
- continue;
-
- MediaPacketHeader mph;
- while(S_OK == Read(mph))
- {
- if(mph.stream != pmp->stream || mph.len == 0
- || !(mph.flags&MediaPacketHeader::PN_KEYFRAME_FLAG))
- continue;
-
- BYTE* p = mph.pData.GetData();
- BYTE* p0 = p;
- int len = mph.pData.GetCount();
-
- BYTE hdr = *p++;
- DWORD packetlen = 0, packetoffset = 0;
-
- if((hdr&0xc0) == 0x40)
- {
- packetlen = len - (++p - p0);
- }
- else
- {
- if((hdr&0x40) == 0) p++;
-
- #define GetWORD(var) \
+ POSITION pos = m_mps.GetHeadPosition();
+ while(pos)
+ {
+ UINT64 filepos = GetPos();
+
+ MediaProperies* pmp = m_mps.GetNext(pos);
+ if(pmp->mime == "video/x-pn-realvideo")
+ {
+ pmp->width = pmp->height = 0;
+
+ rvinfo rvi = *(rvinfo*)pmp->typeSpecData.GetData();
+ rvi.bswap();
+
+ if(rvi.fcc2 != '04VR' && rvi.fcc2 != '14VR')
+ continue;
+
+ MediaPacketHeader mph;
+ while(S_OK == Read(mph))
+ {
+ if(mph.stream != pmp->stream || mph.len == 0
+ || !(mph.flags & MediaPacketHeader::PN_KEYFRAME_FLAG))
+ continue;
+
+ BYTE* p = mph.pData.GetData();
+ BYTE* p0 = p;
+ int len = mph.pData.GetCount();
+
+ BYTE hdr = *p++;
+ DWORD packetlen = 0, packetoffset = 0;
+
+ if((hdr & 0xc0) == 0x40)
+ {
+ packetlen = len - (++p - p0);
+ }
+ else
+ {
+ if((hdr & 0x40) == 0) p++;
+
+#define GetWORD(var) \
var = (var<<8)|(*p++); \
var = (var<<8)|(*p++); \
+
+ GetWORD(packetlen);
+ if((packetlen & 0x4000) == 0)
+ {
+ GetWORD(packetlen);
+ packetlen &= 0x3fffffff;
+ }
+ else packetlen &= 0x3fff;
+
+ GetWORD(packetoffset);
+ if((packetoffset & 0x4000) == 0)
+ {
+ GetWORD(packetoffset);
+ packetoffset &= 0x3fffffff;
+ }
+ else packetoffset &= 0x3fff;
+
+#undef GetWORD
+
+ if((hdr & 0xc0) == 0xc0) packetoffset = 0;
+ else if((hdr & 0xc0) == 0x80) packetoffset = packetlen - packetoffset;
+
+ p++;
+ }
+
+ len = min(len - (p - p0), packetlen - packetoffset);
+
+ if(len > 0)
+ {
+ bool repeat_field;
+ if(rvi.fcc2 == '14VR') ::GetDimensions_X10(p, &pmp->width, &pmp->height, &pmp->interlaced, &pmp->top_field_first, &repeat_field);
+ else ::GetDimensions(p, &pmp->width, &pmp->height);
+
+ if(rvi.w == pmp->width && rvi.h == pmp->height)
+ pmp->width = pmp->height = 0;
+
+ break;
+ }
+ }
+ }
- GetWORD(packetlen);
- if((packetlen&0x4000) == 0) {GetWORD(packetlen); packetlen &= 0x3fffffff;}
- else packetlen &= 0x3fff;
-
- GetWORD(packetoffset);
- if((packetoffset&0x4000) == 0) {GetWORD(packetoffset); packetoffset &= 0x3fffffff;}
- else packetoffset &= 0x3fff;
-
- #undef GetWORD
-
- if((hdr&0xc0) == 0xc0) packetoffset = 0;
- else if((hdr&0xc0) == 0x80) packetoffset = packetlen - packetoffset;
-
- p++;
- }
-
- len = min(len - (p - p0), packetlen - packetoffset);
-
- if(len > 0)
- {
- bool repeat_field;
- if(rvi.fcc2 == '14VR') ::GetDimensions_X10(p, &pmp->width, &pmp->height, &pmp->interlaced, &pmp->top_field_first, &repeat_field);
- else ::GetDimensions(p, &pmp->width, &pmp->height);
-
- if(rvi.w == pmp->width && rvi.h == pmp->height)
- pmp->width = pmp->height = 0;
-
- break;
- }
- }
- }
-
- Seek(filepos);
- }
+ Seek(filepos);
+ }
}
int CRMFile::GetMasterStream()
{
- int s1 = -1, s2 = -1;
+ int s1 = -1, s2 = -1;
- POSITION pos = m_mps.GetHeadPosition();
- while(pos)
- {
- MediaProperies* pmp = m_mps.GetNext(pos);
- if(pmp->mime == "video/x-pn-realvideo") {s1 = pmp->stream; break;}
- else if(pmp->mime == "audio/x-pn-realaudio" && s2 == -1) s2 = pmp->stream;
- }
+ POSITION pos = m_mps.GetHeadPosition();
+ while(pos)
+ {
+ MediaProperies* pmp = m_mps.GetNext(pos);
+ if(pmp->mime == "video/x-pn-realvideo")
+ {
+ s1 = pmp->stream;
+ break;
+ }
+ else if(pmp->mime == "audio/x-pn-realaudio" && s2 == -1) s2 = pmp->stream;
+ }
- if(s1 == -1)
- s1 = s2;
+ if(s1 == -1)
+ s1 = s2;
- return s1;
+ return s1;
}
@@ -1452,421 +1531,443 @@ int CRMFile::GetMasterStream()
//
CRealVideoDecoder::CRealVideoDecoder(LPUNKNOWN lpunk, HRESULT* phr)
- : CBaseVideoFilter(NAME("CRealVideoDecoder"), lpunk, phr, __uuidof(this))
- , m_hDrvDll(NULL)
- , m_dwCookie(0)
- , m_lastBuffSizeDim(0)
+ : CBaseVideoFilter(NAME("CRealVideoDecoder"), lpunk, phr, __uuidof(this))
+ , m_hDrvDll(NULL)
+ , m_dwCookie(0)
+ , m_lastBuffSizeDim(0)
{
}
CRealVideoDecoder::~CRealVideoDecoder()
{
- if(m_hDrvDll) FreeLibrary(m_hDrvDll);
+ if(m_hDrvDll) FreeLibrary(m_hDrvDll);
}
HRESULT CRealVideoDecoder::InitRV(const CMediaType* pmt)
{
- FreeRV();
-
- HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
-
- rvinfo rvi = *(rvinfo*)(pmt->Format() + (pmt->formattype == FORMAT_VideoInfo ? sizeof(VIDEOINFOHEADER) : sizeof(VIDEOINFOHEADER2)));
- rvi.bswap();
-
- #pragma pack(push, 1)
- struct {WORD unk1, w, h, unk3; DWORD unk2, subformat, unk5, format;} i =
- {11, rvi.w, rvi.h, 0, 0, rvi.type1, 1, rvi.type2};
- #pragma pack(pop)
-
- if(FAILED(hr = RVInit(&i, &m_dwCookie)))
- return hr;
-
- if(rvi.fcc2 <= '03VR' && rvi.type2 >= 0x20200002)
- {
- int nWidthHeight = (1+((rvi.type1>>16)&7));
- UINT32* pWH = DNew UINT32[nWidthHeight*2];
- pWH[0] = rvi.w; pWH[1] = rvi.h;
- for(int i = 2; i < nWidthHeight*2; i++)
- pWH[i] = rvi.morewh[i-2]*4;
- #pragma pack(push, 1)
- struct {UINT32 data1; UINT32 data2; UINT32* dimensions;} cmsg_data =
- {0x24, nWidthHeight, pWH};
- #pragma pack(pop)
- hr = RVCustomMessage(&cmsg_data, m_dwCookie);
- delete [] pWH;
- }
-
- return hr;
+ FreeRV();
+
+ HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
+
+ rvinfo rvi = *(rvinfo*)(pmt->Format() + (pmt->formattype == FORMAT_VideoInfo ? sizeof(VIDEOINFOHEADER) : sizeof(VIDEOINFOHEADER2)));
+ rvi.bswap();
+
+#pragma pack(push, 1)
+ struct
+ {
+ WORD unk1, w, h, unk3;
+ DWORD unk2, subformat, unk5, format;
+ } i =
+ {11, rvi.w, rvi.h, 0, 0, rvi.type1, 1, rvi.type2};
+#pragma pack(pop)
+
+ if(FAILED(hr = RVInit(&i, &m_dwCookie)))
+ return hr;
+
+ if(rvi.fcc2 <= '03VR' && rvi.type2 >= 0x20200002)
+ {
+ int nWidthHeight = (1 + ((rvi.type1 >> 16) & 7));
+ UINT32* pWH = DNew UINT32[nWidthHeight*2];
+ pWH[0] = rvi.w;
+ pWH[1] = rvi.h;
+ for(int i = 2; i < nWidthHeight * 2; i++)
+ pWH[i] = rvi.morewh[i-2] * 4;
+#pragma pack(push, 1)
+ struct
+ {
+ UINT32 data1;
+ UINT32 data2;
+ UINT32* dimensions;
+ } cmsg_data =
+ {0x24, nWidthHeight, pWH};
+#pragma pack(pop)
+ hr = RVCustomMessage(&cmsg_data, m_dwCookie);
+ delete [] pWH;
+ }
+
+ return hr;
}
void CRealVideoDecoder::FreeRV()
{
- if(m_dwCookie)
- {
- RVFree(m_dwCookie);
- m_dwCookie = 0;
- }
+ if(m_dwCookie)
+ {
+ RVFree(m_dwCookie);
+ m_dwCookie = 0;
+ }
}
HRESULT CRealVideoDecoder::Transform(IMediaSample* pIn)
{
- CAutoLock cAutoLock(&m_csReceive);
-
- HRESULT hr;
-
- BYTE* pDataIn = NULL;
- if(FAILED(hr = pIn->GetPointer(&pDataIn)))
- return hr;
-
- long len = pIn->GetActualDataLength();
- if(len <= 0) return S_OK; // nothing to do
-
- REFERENCE_TIME rtStart, rtStop;
- pIn->GetTime(&rtStart, &rtStop);
-
- rtStart += m_tStart;
-
- int offset = 1+((*pDataIn)+1)*8;
-
- #pragma pack(push, 1)
- struct {DWORD len, unk1, chunks; DWORD* extra; DWORD unk2, timestamp;} transform_in =
- {len - offset, 0, *pDataIn, (DWORD*)(pDataIn+1), 0, (DWORD)(rtStart/10000)};
- struct {DWORD unk1, unk2, timestamp, w, h;} transform_out =
- {0,0,0,0,0};
- #pragma pack(pop)
-
- pDataIn += offset;
-
- if(m_fDropFrames && m_timestamp+1 == transform_in.timestamp)
- {
- m_timestamp = transform_in.timestamp;
- return S_OK;
- }
-
-
- unsigned int tmp1, tmp2;
- bool interlaced = false, tmp3, tmp4;
- ::GetDimensions_X10(pDataIn, &tmp1, &tmp2, &interlaced, &tmp3, &tmp4);
-
- int size = tmp1*tmp2;
- if( m_lastBuffSizeDim < size )
- {
- m_pI420.Free();
- m_pI420Tmp.Free();
-
- m_lastBuffSizeDim = size;
- ATLTRACE("resize out put buff %d" ,size);
- if ( m_pI420.Allocate(size*3/2) )
- {
- ATLTRACE(" m_pI420.Allocated 1" );
- memset(m_pI420, 0, size);
- ATLTRACE(" m_pI420.Allocated 2" );
- memset(m_pI420 + size, 0x80, size/2);
- ATLTRACE(" m_pI420.Allocated 3" );
- }
- else
- {
- ATLTRACE(" m_pI420.Allocate fail %d" ,size*3/2);
- return S_OK;
- }
- if( m_pI420Tmp.Allocate(size*3/2) )
- {
- ATLTRACE(" m_pI420Tmp.Allocated 1" );
- memset(m_pI420Tmp, 0, size);
- ATLTRACE(" m_pI420Tmp.Allocated 2" );
- memset(m_pI420Tmp + size, 0x80, size/2);
- ATLTRACE(" m_pI420Tmp.Allocated 3" );
- }
- else
- {
- ATLTRACE(" m_pI420Tmp.Allocate fail %d" ,size*3/2);
- return S_OK;
- }
- }
-
- hr = RVTransform(pDataIn, (BYTE*)m_pI420, &transform_in, &transform_out, m_dwCookie);
-
- m_timestamp = transform_in.timestamp;
-
- if(FAILED(hr))
- {
- TRACE(_T("RV returned an error code!!!\n"));
- ASSERT(!(transform_out.unk1&1)); // error allowed when the "render" flag is not set
+ CAutoLock cAutoLock(&m_csReceive);
+
+ HRESULT hr;
+
+ BYTE* pDataIn = NULL;
+ if(FAILED(hr = pIn->GetPointer(&pDataIn)))
+ return hr;
+
+ long len = pIn->GetActualDataLength();
+ if(len <= 0) return S_OK; // nothing to do
+
+ REFERENCE_TIME rtStart, rtStop;
+ pIn->GetTime(&rtStart, &rtStop);
+
+ rtStart += m_tStart;
+
+ int offset = 1 + ((*pDataIn) + 1) * 8;
+
+#pragma pack(push, 1)
+ struct
+ {
+ DWORD len, unk1, chunks;
+ DWORD* extra;
+ DWORD unk2, timestamp;
+ } transform_in =
+ {len - offset, 0, *pDataIn, (DWORD*)(pDataIn + 1), 0, (DWORD)(rtStart / 10000)};
+ struct
+ {
+ DWORD unk1, unk2, timestamp, w, h;
+ } transform_out =
+ {0, 0, 0, 0, 0};
+#pragma pack(pop)
+
+ pDataIn += offset;
+
+ if(m_fDropFrames && m_timestamp + 1 == transform_in.timestamp)
+ {
+ m_timestamp = transform_in.timestamp;
+ return S_OK;
+ }
+
+
+ unsigned int tmp1, tmp2;
+ bool interlaced = false, tmp3, tmp4;
+ ::GetDimensions_X10(pDataIn, &tmp1, &tmp2, &interlaced, &tmp3, &tmp4);
+
+ int size = tmp1 * tmp2;
+ if(m_lastBuffSizeDim < size)
+ {
+ m_pI420.Free();
+ m_pI420Tmp.Free();
+
+ m_lastBuffSizeDim = size;
+ ATLTRACE("resize out put buff %d" , size);
+ if(m_pI420.Allocate(size * 3 / 2))
+ {
+ ATLTRACE(" m_pI420.Allocated 1");
+ memset(m_pI420, 0, size);
+ ATLTRACE(" m_pI420.Allocated 2");
+ memset(m_pI420 + size, 0x80, size / 2);
+ ATLTRACE(" m_pI420.Allocated 3");
+ }
+ else
+ {
+ ATLTRACE(" m_pI420.Allocate fail %d" , size * 3 / 2);
+ return S_OK;
+ }
+ if(m_pI420Tmp.Allocate(size * 3 / 2))
+ {
+ ATLTRACE(" m_pI420Tmp.Allocated 1");
+ memset(m_pI420Tmp, 0, size);
+ ATLTRACE(" m_pI420Tmp.Allocated 2");
+ memset(m_pI420Tmp + size, 0x80, size / 2);
+ ATLTRACE(" m_pI420Tmp.Allocated 3");
+ }
+ else
+ {
+ ATLTRACE(" m_pI420Tmp.Allocate fail %d" , size * 3 / 2);
+ return S_OK;
+ }
+ }
+
+ hr = RVTransform(pDataIn, (BYTE*)m_pI420, &transform_in, &transform_out, m_dwCookie);
+
+ m_timestamp = transform_in.timestamp;
+
+ if(FAILED(hr))
+ {
+ TRACE(_T("RV returned an error code!!!\n"));
+ ASSERT(!(transform_out.unk1 & 1)); // error allowed when the "render" flag is not set
// return hr;
- }
+ }
- if(pIn->IsPreroll() == S_OK || rtStart < 0 || !(transform_out.unk1&1))
- return S_OK;
+ if(pIn->IsPreroll() == S_OK || rtStart < 0 || !(transform_out.unk1 & 1))
+ return S_OK;
- CComPtr<IMediaSample> pOut;
- BYTE* pDataOut = NULL;
- if(/*FAILED(hr = GetDeliveryBuffer(transform_out.w, transform_out.h, &pOut)) // TODO
+ CComPtr<IMediaSample> pOut;
+ BYTE* pDataOut = NULL;
+ if(/*FAILED(hr = GetDeliveryBuffer(transform_out.w, transform_out.h, &pOut)) // TODO
&& */ FAILED(hr = GetDeliveryBuffer(m_w, m_h, &pOut))
- || FAILED(hr = pOut->GetPointer(&pDataOut)))
- return hr;
+ || FAILED(hr = pOut->GetPointer(&pDataOut)))
+ return hr;
- BYTE* pI420[3] = {m_pI420, m_pI420Tmp, NULL};
+ BYTE* pI420[3] = {m_pI420, m_pI420Tmp, NULL};
- if(interlaced)
- {
- int size = m_w*m_h;
- DeinterlaceBlend(pI420[1], pI420[0], m_w, m_h, m_w, m_w);
- DeinterlaceBlend(pI420[1]+size, pI420[0]+size, m_w/2, m_h/2, m_w/2, m_w/2);
- DeinterlaceBlend(pI420[1]+size*5/4, pI420[0]+size*5/4, m_w/2, m_h/2, m_w/2, m_w/2);
- pI420[2] = pI420[1], pI420[1] = pI420[0], pI420[0] = pI420[2];
- }
+ if(interlaced)
+ {
+ int size = m_w * m_h;
+ DeinterlaceBlend(pI420[1], pI420[0], m_w, m_h, m_w, m_w);
+ DeinterlaceBlend(pI420[1] + size, pI420[0] + size, m_w / 2, m_h / 2, m_w / 2, m_w / 2);
+ DeinterlaceBlend(pI420[1] + size * 5 / 4, pI420[0] + size * 5 / 4, m_w / 2, m_h / 2, m_w / 2, m_w / 2);
+ pI420[2] = pI420[1], pI420[1] = pI420[0], pI420[0] = pI420[2];
+ }
- if(transform_out.w != m_w || transform_out.h != m_h)
- {
- Resize(pI420[0], transform_out.w, transform_out.h, pI420[1], m_w, m_h);
- // only one of these can be true, and when it happens the result image must be in the tmp buffer
- if(transform_out.w == m_w || transform_out.h == m_h)
- pI420[2] = pI420[1], pI420[1] = pI420[0], pI420[0] = pI420[2];
- }
+ if(transform_out.w != m_w || transform_out.h != m_h)
+ {
+ Resize(pI420[0], transform_out.w, transform_out.h, pI420[1], m_w, m_h);
+ // only one of these can be true, and when it happens the result image must be in the tmp buffer
+ if(transform_out.w == m_w || transform_out.h == m_h)
+ pI420[2] = pI420[1], pI420[1] = pI420[0], pI420[0] = pI420[2];
+ }
- rtStart = 10000i64*transform_out.timestamp - m_tStart;
- rtStop = rtStart + 1;
- pOut->SetTime(&rtStart, /*NULL*/&rtStop);
+ rtStart = 10000i64 * transform_out.timestamp - m_tStart;
+ rtStop = rtStart + 1;
+ pOut->SetTime(&rtStart, /*NULL*/&rtStop);
- pOut->SetDiscontinuity(pIn->IsDiscontinuity() == S_OK);
+ pOut->SetDiscontinuity(pIn->IsDiscontinuity() == S_OK);
- CopyBuffer(pDataOut, pI420[0], m_w, m_h, m_w, MEDIASUBTYPE_I420);
+ CopyBuffer(pDataOut, pI420[0], m_w, m_h, m_w, MEDIASUBTYPE_I420);
-DbgLog((LOG_TRACE, 0, _T("V: rtStart=%I64d, rtStop=%I64d, disc=%d, sync=%d"),
- rtStart, rtStop, pOut->IsDiscontinuity() == S_OK, pOut->IsSyncPoint() == S_OK));
+ DbgLog((LOG_TRACE, 0, _T("V: rtStart=%I64d, rtStop=%I64d, disc=%d, sync=%d"),
+ rtStart, rtStop, pOut->IsDiscontinuity() == S_OK, pOut->IsSyncPoint() == S_OK));
- return m_pOutput->Deliver(pOut);
+ return m_pOutput->Deliver(pOut);
}
void CRealVideoDecoder::Resize(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho)
{
- int si = wi*hi, so = wo*ho;
- ASSERT(((si*so)&3) == 0);
-
- if(wi < wo)
- {
- ResizeWidth(pIn, wi, hi, pOut, wo, ho);
- ResizeWidth(pIn + si, wi/2, hi/2, pOut + so, wo/2, ho/2);
- ResizeWidth(pIn + si + si/4, wi/2, hi/2, pOut + so + so/4, wo/2, ho/2);
- if(hi == ho) return;
- ResizeHeight(pOut, wo, hi, pIn, wo, ho);
- ResizeHeight(pOut + so, wo/2, hi/2, pIn + so, wo/2, ho/2);
- ResizeHeight(pOut + so + so/4, wo/2, hi/2, pIn + so + so/4, wo/2, ho/2);
- }
- else if(hi < ho)
- {
- ResizeHeight(pIn, wi, hi, pOut, wo, ho);
- ResizeHeight(pIn + si, wi/2, hi/2, pOut + so, wo/2, ho/2);
- ResizeHeight(pIn + si + si/4, wi/2, hi/2, pOut + so + so/4, wo/2, ho/2);
- if(wi == wo) return;
- ASSERT(0); // this is uncreachable code, but anyway... looks nice being so symmetric
- ResizeWidth(pOut, wi, ho, pIn, wo, ho);
- ResizeWidth(pOut + so, wi/2, ho/2, pIn + so, wo/2, ho/2);
- ResizeWidth(pOut + so + so/4, wi/2, ho/2, pIn + so + so/4, wo/2, ho/2);
- }
+ int si = wi * hi, so = wo * ho;
+ ASSERT(((si * so) & 3) == 0);
+
+ if(wi < wo)
+ {
+ ResizeWidth(pIn, wi, hi, pOut, wo, ho);
+ ResizeWidth(pIn + si, wi / 2, hi / 2, pOut + so, wo / 2, ho / 2);
+ ResizeWidth(pIn + si + si / 4, wi / 2, hi / 2, pOut + so + so / 4, wo / 2, ho / 2);
+ if(hi == ho) return;
+ ResizeHeight(pOut, wo, hi, pIn, wo, ho);
+ ResizeHeight(pOut + so, wo / 2, hi / 2, pIn + so, wo / 2, ho / 2);
+ ResizeHeight(pOut + so + so / 4, wo / 2, hi / 2, pIn + so + so / 4, wo / 2, ho / 2);
+ }
+ else if(hi < ho)
+ {
+ ResizeHeight(pIn, wi, hi, pOut, wo, ho);
+ ResizeHeight(pIn + si, wi / 2, hi / 2, pOut + so, wo / 2, ho / 2);
+ ResizeHeight(pIn + si + si / 4, wi / 2, hi / 2, pOut + so + so / 4, wo / 2, ho / 2);
+ if(wi == wo) return;
+ ASSERT(0); // this is uncreachable code, but anyway... looks nice being so symmetric
+ ResizeWidth(pOut, wi, ho, pIn, wo, ho);
+ ResizeWidth(pOut + so, wi / 2, ho / 2, pIn + so, wo / 2, ho / 2);
+ ResizeWidth(pOut + so + so / 4, wi / 2, ho / 2, pIn + so + so / 4, wo / 2, ho / 2);
+ }
}
void CRealVideoDecoder::ResizeWidth(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho)
{
- for(DWORD y = 0; y < hi; y++, pIn += wi, pOut += wo)
- {
- if(wi == wo) memcpy(pOut, pIn, wo);
- else ResizeRow(pIn, wi, 1, pOut, wo, 1);
- }
+ for(DWORD y = 0; y < hi; y++, pIn += wi, pOut += wo)
+ {
+ if(wi == wo) memcpy(pOut, pIn, wo);
+ else ResizeRow(pIn, wi, 1, pOut, wo, 1);
+ }
}
void CRealVideoDecoder::ResizeHeight(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho)
{
- if(hi == ho)
- {
- memcpy(pOut, pIn, wo*ho);
- }
- else
- {
- for(DWORD x = 0; x < wo; x++, pIn++, pOut++)
- ResizeRow(pIn, hi, wo, pOut, ho, wo);
- }
+ if(hi == ho)
+ {
+ memcpy(pOut, pIn, wo * ho);
+ }
+ else
+ {
+ for(DWORD x = 0; x < wo; x++, pIn++, pOut++)
+ ResizeRow(pIn, hi, wo, pOut, ho, wo);
+ }
}
void CRealVideoDecoder::ResizeRow(BYTE* pIn, DWORD wi, DWORD dpi, BYTE* pOut, DWORD wo, DWORD dpo)
{
- ASSERT(wi < wo);
+ ASSERT(wi < wo);
if(dpo == 1)
- {
- for(DWORD i = 0, j = 0, dj = (wi<<16)/wo; i < wo-1; i++, pOut++, j += dj)
+ {
+ for(DWORD i = 0, j = 0, dj = (wi << 16) / wo; i < wo - 1; i++, pOut++, j += dj)
// pOut[i] = pIn[j>>16];
- {
- BYTE* p = &pIn[j>>16];
- DWORD jf = j&0xffff;
- *pOut = ((p[0]*(0xffff-jf) + p[1]*jf) + 0x7fff) >> 16;
- }
-
- *pOut = pIn[wi-1];
- }
- else
- {
- for(DWORD i = 0, j = 0, dj = (wi<<16)/wo; i < wo-1; i++, pOut += dpo, j += dj)
+ {
+ BYTE* p = &pIn[j>>16];
+ DWORD jf = j & 0xffff;
+ *pOut = ((p[0] * (0xffff - jf) + p[1] * jf) + 0x7fff) >> 16;
+ }
+
+ *pOut = pIn[wi-1];
+ }
+ else
+ {
+ for(DWORD i = 0, j = 0, dj = (wi << 16) / wo; i < wo - 1; i++, pOut += dpo, j += dj)
// *pOut = pIn[dpi*(j>>16)];
- {
- BYTE* p = &pIn[dpi*(j>>16)];
- DWORD jf = j&0xffff;
- *pOut = ((p[0]*(0xffff-jf) + p[dpi]*jf) + 0x7fff) >> 16;
- }
-
- *pOut = pIn[dpi*(wi-1)];
- }
+ {
+ BYTE* p = &pIn[dpi*(j>>16)];
+ DWORD jf = j & 0xffff;
+ *pOut = ((p[0] * (0xffff - jf) + p[dpi] * jf) + 0x7fff) >> 16;
+ }
+
+ *pOut = pIn[dpi*(wi-1)];
+ }
}
HRESULT CRealVideoDecoder::CheckInputType(const CMediaType* mtIn)
{
- if(mtIn->majortype != MEDIATYPE_Video
- || mtIn->subtype != MEDIASUBTYPE_RV20
- && mtIn->subtype != MEDIASUBTYPE_RV30
- && mtIn->subtype != MEDIASUBTYPE_RV40
- && mtIn->subtype != MEDIASUBTYPE_RV41)
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- if(mtIn->formattype == FORMAT_VideoInfo2)
- {
- VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mtIn->Format();
- if(vih2->dwPictAspectRatioX < vih2->bmiHeader.biWidth
- || vih2->dwPictAspectRatioY < vih2->bmiHeader.biHeight)
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
-
- if(!m_pInput->IsConnected())
- {
- if(m_hDrvDll) {FreeLibrary(m_hDrvDll); m_hDrvDll = NULL;}
-
- CAtlList<CString> paths;
- CString olddll, newdll, oldpath, newpath;
-
- olddll.Format(_T("drv%c3260.dll"), (TCHAR)((mtIn->subtype.Data1>>16)&0xff));
- newdll =
- mtIn->subtype == FOURCCMap('14VR') ? _T("drvi.dll") :
- mtIn->subtype == FOURCCMap('02VR') ? _T("drv2.dll") :
- _T("drvc.dll");
-
- CRegKey key;
- TCHAR buff[_MAX_PATH];
- ULONG len = sizeof(buff);
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Software\\RealNetworks\\Preferences\\DT_Codecs"), KEY_READ)
- && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
- {
- oldpath = buff;
- TCHAR c = oldpath[oldpath.GetLength()-1];
- if(c != '\\' && c != '/') oldpath += '\\';
- key.Close();
- }
- len = sizeof(buff);
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Helix\\HelixSDK\\10.0\\Preferences\\DT_Codecs"), KEY_READ)
- && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
- {
- newpath = buff;
- TCHAR c = newpath[newpath.GetLength()-1];
- if(c != '\\' && c != '/') newpath += '\\';
- key.Close();
- }
-
- if(!newpath.IsEmpty()) paths.AddTail(newpath + newdll);
- if(!oldpath.IsEmpty()) paths.AddTail(oldpath + newdll);
- paths.AddTail(newdll); // default dll paths
- if(!newpath.IsEmpty()) paths.AddTail(newpath + olddll);
- if(!oldpath.IsEmpty()) paths.AddTail(oldpath + olddll);
- paths.AddTail(olddll); // default dll paths
-
- POSITION pos = paths.GetHeadPosition();
- while(pos && !(m_hDrvDll = LoadLibrary(paths.GetNext(pos))));
-
- if(m_hDrvDll)
- {
- RVCustomMessage = (PRVCustomMessage)GetProcAddress(m_hDrvDll, "RV20toYUV420CustomMessage");
- RVFree = (PRVFree)GetProcAddress(m_hDrvDll, "RV20toYUV420Free");
- RVHiveMessage = (PRVHiveMessage)GetProcAddress(m_hDrvDll, "RV20toYUV420HiveMessage");
- RVInit = (PRVInit)GetProcAddress(m_hDrvDll, "RV20toYUV420Init");
- RVTransform = (PRVTransform)GetProcAddress(m_hDrvDll, "RV20toYUV420Transform");
-
- if(!RVCustomMessage) RVCustomMessage = (PRVCustomMessage)GetProcAddress(m_hDrvDll, "RV40toYUV420CustomMessage");
- if(!RVFree) RVFree = (PRVFree)GetProcAddress(m_hDrvDll, "RV40toYUV420Free");
- if(!RVHiveMessage) RVHiveMessage = (PRVHiveMessage)GetProcAddress(m_hDrvDll, "RV40toYUV420HiveMessage");
- if(!RVInit) RVInit = (PRVInit)GetProcAddress(m_hDrvDll, "RV40toYUV420Init");
- if(!RVTransform) RVTransform = (PRVTransform)GetProcAddress(m_hDrvDll, "RV40toYUV420Transform");
- }
-
- if(!m_hDrvDll || !RVCustomMessage
- || !RVFree || !RVHiveMessage
- || !RVInit || !RVTransform)
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- if(FAILED(InitRV(mtIn)))
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
-
- return S_OK;
+ if(mtIn->majortype != MEDIATYPE_Video
+ || mtIn->subtype != MEDIASUBTYPE_RV20
+ && mtIn->subtype != MEDIASUBTYPE_RV30
+ && mtIn->subtype != MEDIASUBTYPE_RV40
+ && mtIn->subtype != MEDIASUBTYPE_RV41)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ if(mtIn->formattype == FORMAT_VideoInfo2)
+ {
+ VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mtIn->Format();
+ if(vih2->dwPictAspectRatioX < vih2->bmiHeader.biWidth
+ || vih2->dwPictAspectRatioY < vih2->bmiHeader.biHeight)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ if(!m_pInput->IsConnected())
+ {
+ if(m_hDrvDll)
+ {
+ FreeLibrary(m_hDrvDll);
+ m_hDrvDll = NULL;
+ }
+
+ CAtlList<CString> paths;
+ CString olddll, newdll, oldpath, newpath;
+
+ olddll.Format(_T("drv%c3260.dll"), (TCHAR)((mtIn->subtype.Data1 >> 16) & 0xff));
+ newdll =
+ mtIn->subtype == FOURCCMap('14VR') ? _T("drvi.dll") :
+ mtIn->subtype == FOURCCMap('02VR') ? _T("drv2.dll") :
+ _T("drvc.dll");
+
+ CRegKey key;
+ TCHAR buff[_MAX_PATH];
+ ULONG len = sizeof(buff);
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Software\\RealNetworks\\Preferences\\DT_Codecs"), KEY_READ)
+ && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
+ {
+ oldpath = buff;
+ TCHAR c = oldpath[oldpath.GetLength()-1];
+ if(c != '\\' && c != '/') oldpath += '\\';
+ key.Close();
+ }
+ len = sizeof(buff);
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Helix\\HelixSDK\\10.0\\Preferences\\DT_Codecs"), KEY_READ)
+ && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
+ {
+ newpath = buff;
+ TCHAR c = newpath[newpath.GetLength()-1];
+ if(c != '\\' && c != '/') newpath += '\\';
+ key.Close();
+ }
+
+ if(!newpath.IsEmpty()) paths.AddTail(newpath + newdll);
+ if(!oldpath.IsEmpty()) paths.AddTail(oldpath + newdll);
+ paths.AddTail(newdll); // default dll paths
+ if(!newpath.IsEmpty()) paths.AddTail(newpath + olddll);
+ if(!oldpath.IsEmpty()) paths.AddTail(oldpath + olddll);
+ paths.AddTail(olddll); // default dll paths
+
+ POSITION pos = paths.GetHeadPosition();
+ while(pos && !(m_hDrvDll = LoadLibrary(paths.GetNext(pos))));
+
+ if(m_hDrvDll)
+ {
+ RVCustomMessage = (PRVCustomMessage)GetProcAddress(m_hDrvDll, "RV20toYUV420CustomMessage");
+ RVFree = (PRVFree)GetProcAddress(m_hDrvDll, "RV20toYUV420Free");
+ RVHiveMessage = (PRVHiveMessage)GetProcAddress(m_hDrvDll, "RV20toYUV420HiveMessage");
+ RVInit = (PRVInit)GetProcAddress(m_hDrvDll, "RV20toYUV420Init");
+ RVTransform = (PRVTransform)GetProcAddress(m_hDrvDll, "RV20toYUV420Transform");
+
+ if(!RVCustomMessage) RVCustomMessage = (PRVCustomMessage)GetProcAddress(m_hDrvDll, "RV40toYUV420CustomMessage");
+ if(!RVFree) RVFree = (PRVFree)GetProcAddress(m_hDrvDll, "RV40toYUV420Free");
+ if(!RVHiveMessage) RVHiveMessage = (PRVHiveMessage)GetProcAddress(m_hDrvDll, "RV40toYUV420HiveMessage");
+ if(!RVInit) RVInit = (PRVInit)GetProcAddress(m_hDrvDll, "RV40toYUV420Init");
+ if(!RVTransform) RVTransform = (PRVTransform)GetProcAddress(m_hDrvDll, "RV40toYUV420Transform");
+ }
+
+ if(!m_hDrvDll || !RVCustomMessage
+ || !RVFree || !RVHiveMessage
+ || !RVInit || !RVTransform)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ if(FAILED(InitRV(mtIn)))
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ return S_OK;
}
HRESULT CRealVideoDecoder::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
{
- if(m_pOutput && m_pOutput->IsConnected())
- {
- BITMAPINFOHEADER bih1, bih2;
- if(ExtractBIH(mtOut, &bih1) && ExtractBIH(&m_pOutput->CurrentMediaType(), &bih2)
- && abs(bih1.biHeight) != abs(bih2.biHeight))
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
+ if(m_pOutput && m_pOutput->IsConnected())
+ {
+ BITMAPINFOHEADER bih1, bih2;
+ if(ExtractBIH(mtOut, &bih1) && ExtractBIH(&m_pOutput->CurrentMediaType(), &bih2)
+ && abs(bih1.biHeight) != abs(bih2.biHeight))
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
- return __super::CheckTransform(mtIn, mtOut);
+ return __super::CheckTransform(mtIn, mtOut);
}
HRESULT CRealVideoDecoder::StartStreaming()
{
- const CMediaType& mt = m_pInput->CurrentMediaType();
- if(FAILED(InitRV(&mt)))
- return E_FAIL;
+ const CMediaType& mt = m_pInput->CurrentMediaType();
+ if(FAILED(InitRV(&mt)))
+ return E_FAIL;
- int size = m_w*m_h;
- m_lastBuffSizeDim = size;
- m_pI420.Allocate(size*3/2);
- memset(m_pI420, 0, size);
- memset(m_pI420 + size, 0x80, size/2);
- m_pI420Tmp.Allocate(size*3/2);
- memset(m_pI420Tmp, 0, size);
- memset(m_pI420Tmp + size, 0x80, size/2);
+ int size = m_w * m_h;
+ m_lastBuffSizeDim = size;
+ m_pI420.Allocate(size * 3 / 2);
+ memset(m_pI420, 0, size);
+ memset(m_pI420 + size, 0x80, size / 2);
+ m_pI420Tmp.Allocate(size * 3 / 2);
+ memset(m_pI420Tmp, 0, size);
+ memset(m_pI420Tmp + size, 0x80, size / 2);
- return __super::StartStreaming();
+ return __super::StartStreaming();
}
HRESULT CRealVideoDecoder::StopStreaming()
{
- m_pI420.Free();
- m_pI420Tmp.Free();
+ m_pI420.Free();
+ m_pI420Tmp.Free();
- FreeRV();
+ FreeRV();
- return __super::StopStreaming();
+ return __super::StopStreaming();
}
HRESULT CRealVideoDecoder::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- CAutoLock cAutoLock(&m_csReceive);
+ CAutoLock cAutoLock(&m_csReceive);
- m_timestamp = ~0;
- m_fDropFrames = false;
+ m_timestamp = ~0;
+ m_fDropFrames = false;
- DWORD tmp[2] = {20, 0};
- RVHiveMessage(tmp, m_dwCookie);
+ DWORD tmp[2] = {20, 0};
+ RVHiveMessage(tmp, m_dwCookie);
- m_tStart = tStart;
- return __super::NewSegment(tStart, tStop, dRate);
+ m_tStart = tStart;
+ return __super::NewSegment(tStart, tStop, dRate);
}
HRESULT CRealVideoDecoder::AlterQuality(Quality q)
{
- if(q.Late > 500*10000i64) m_fDropFrames = true;
- if(q.Late <= 0) m_fDropFrames = false;
+ if(q.Late > 500 * 10000i64) m_fDropFrames = true;
+ if(q.Late <= 0) m_fDropFrames = false;
// TRACE(_T("CRealVideoDecoder::AlterQuality: Type=%d, Proportion=%d, Late=%I64d, TimeStamp=%I64d\n"), q.Type, q.Proportion, q.Late, q.TimeStamp);
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
/////////////////////////
@@ -1876,518 +1977,543 @@ HRESULT CRealVideoDecoder::AlterQuality(Quality q)
//
CRealAudioDecoder::CRealAudioDecoder(LPUNKNOWN lpunk, HRESULT* phr)
- : CTransformFilter(NAME("CRealAudioDecoder"), lpunk, __uuidof(this))
- , m_hDrvDll(NULL)
- , m_dwCookie(0)
+ : CTransformFilter(NAME("CRealAudioDecoder"), lpunk, __uuidof(this))
+ , m_hDrvDll(NULL)
+ , m_dwCookie(0)
{
- if(phr) *phr = S_OK;
+ if(phr) *phr = S_OK;
}
CRealAudioDecoder::~CRealAudioDecoder()
{
// FreeRA();
- if(m_hDrvDll) FreeLibrary(m_hDrvDll);
+ if(m_hDrvDll) FreeLibrary(m_hDrvDll);
}
HRESULT CRealAudioDecoder::InitRA(const CMediaType* pmt)
{
- FreeRA();
-
- HRESULT hr;
-
- if(RAOpenCodec2 && FAILED(hr = RAOpenCodec2(&m_dwCookie, m_dllpath))
- || RAOpenCodec && FAILED(hr = RAOpenCodec(&m_dwCookie)))
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)pmt->Format();
-
- // someone might be doing cbSize = sizeof(WAVEFORMATEX), chances of
- // cbSize being really sizeof(WAVEFORMATEX) is less than this,
- // especially with our rm splitter ;)
- DWORD cbSize = pwfe->cbSize;
- if(cbSize == sizeof(WAVEFORMATEX)) {ASSERT(0); cbSize = 0;}
-
- WORD wBitsPerSample = pwfe->wBitsPerSample;
- if(!wBitsPerSample) wBitsPerSample = 16;
-
- #pragma pack(push, 1)
- struct {DWORD freq; WORD bpsample, channels, quality; DWORD bpframe, packetsize, extralen; void* extra;} initdata =
- {pwfe->nSamplesPerSec, wBitsPerSample, pwfe->nChannels, 100,
- 0, 0, 0, NULL};
- #pragma pack(pop)
-
- CAutoVectorPtr<BYTE> pBuff;
-
- if(pmt->subtype == MEDIASUBTYPE_AAC)
- {
- pBuff.Allocate(cbSize+1);
- pBuff[0] = 0x02;
- memcpy(pBuff+1, pwfe+1, cbSize);
- initdata.extralen = cbSize+1;
- initdata.extra = pBuff;
- }
- else
- {
- if(pmt->FormatLength() <= sizeof(WAVEFORMATEX) + cbSize) // must have type_specific_data appended
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- BYTE* fmt = pmt->Format() + sizeof(WAVEFORMATEX) + cbSize;
-
- for(int i = 0, len = pmt->FormatLength() - (sizeof(WAVEFORMATEX) + cbSize); i < len-4; i++, fmt++)
- {
- if(fmt[0] == '.' || fmt[1] == 'r' || fmt[2] == 'a')
- break;
- }
-
- m_rai = *(rainfo*)fmt;
- m_rai.bswap();
-
- BYTE* p;
-
- if(m_rai.version2 == 4)
- {
- p = (BYTE*)((rainfo4*)fmt+1);
- int len = *p++; p += len; len = *p++; p += len;
- ASSERT(len == 4);
- }
- else if(m_rai.version2 == 5)
- {
- p = (BYTE*)((rainfo5*)fmt+1);
- }
- else
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
-
- p += 3;
- if(m_rai.version2 == 5) p++;
-
- initdata.bpframe = m_rai.sub_packet_size;
- initdata.packetsize = m_rai.coded_frame_size;
- initdata.extralen = min((pmt->Format() + pmt->FormatLength()) - (p + 4), *(DWORD*)p);
- initdata.extra = p + 4;
- }
-
- if(FAILED(hr = RAInitDecoder(m_dwCookie, &initdata)))
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- if(RASetPwd)
- RASetPwd(m_dwCookie, "Ardubancel Quazanga");
-
- if(RASetFlavor && FAILED(hr = RASetFlavor(m_dwCookie, m_rai.flavor)))
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- return S_OK;
+ FreeRA();
+
+ HRESULT hr;
+
+ if(RAOpenCodec2 && FAILED(hr = RAOpenCodec2(&m_dwCookie, m_dllpath))
+ || RAOpenCodec && FAILED(hr = RAOpenCodec(&m_dwCookie)))
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)pmt->Format();
+
+ // someone might be doing cbSize = sizeof(WAVEFORMATEX), chances of
+ // cbSize being really sizeof(WAVEFORMATEX) is less than this,
+ // especially with our rm splitter ;)
+ DWORD cbSize = pwfe->cbSize;
+ if(cbSize == sizeof(WAVEFORMATEX))
+ {
+ ASSERT(0);
+ cbSize = 0;
+ }
+
+ WORD wBitsPerSample = pwfe->wBitsPerSample;
+ if(!wBitsPerSample) wBitsPerSample = 16;
+
+#pragma pack(push, 1)
+ struct
+ {
+ DWORD freq;
+ WORD bpsample, channels, quality;
+ DWORD bpframe, packetsize, extralen;
+ void* extra;
+ } initdata =
+ {
+ pwfe->nSamplesPerSec, wBitsPerSample, pwfe->nChannels, 100,
+ 0, 0, 0, NULL
+ };
+#pragma pack(pop)
+
+ CAutoVectorPtr<BYTE> pBuff;
+
+ if(pmt->subtype == MEDIASUBTYPE_AAC)
+ {
+ pBuff.Allocate(cbSize + 1);
+ pBuff[0] = 0x02;
+ memcpy(pBuff + 1, pwfe + 1, cbSize);
+ initdata.extralen = cbSize + 1;
+ initdata.extra = pBuff;
+ }
+ else
+ {
+ if(pmt->FormatLength() <= sizeof(WAVEFORMATEX) + cbSize) // must have type_specific_data appended
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ BYTE* fmt = pmt->Format() + sizeof(WAVEFORMATEX) + cbSize;
+
+ for(int i = 0, len = pmt->FormatLength() - (sizeof(WAVEFORMATEX) + cbSize); i < len - 4; i++, fmt++)
+ {
+ if(fmt[0] == '.' || fmt[1] == 'r' || fmt[2] == 'a')
+ break;
+ }
+
+ m_rai = *(rainfo*)fmt;
+ m_rai.bswap();
+
+ BYTE* p;
+
+ if(m_rai.version2 == 4)
+ {
+ p = (BYTE*)((rainfo4*)fmt + 1);
+ int len = *p++;
+ p += len;
+ len = *p++;
+ p += len;
+ ASSERT(len == 4);
+ }
+ else if(m_rai.version2 == 5)
+ {
+ p = (BYTE*)((rainfo5*)fmt + 1);
+ }
+ else
+ {
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ p += 3;
+ if(m_rai.version2 == 5) p++;
+
+ initdata.bpframe = m_rai.sub_packet_size;
+ initdata.packetsize = m_rai.coded_frame_size;
+ initdata.extralen = min((pmt->Format() + pmt->FormatLength()) - (p + 4), *(DWORD*)p);
+ initdata.extra = p + 4;
+ }
+
+ if(FAILED(hr = RAInitDecoder(m_dwCookie, &initdata)))
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ if(RASetPwd)
+ RASetPwd(m_dwCookie, "Ardubancel Quazanga");
+
+ if(RASetFlavor && FAILED(hr = RASetFlavor(m_dwCookie, m_rai.flavor)))
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ return S_OK;
}
void CRealAudioDecoder::FreeRA()
{
- if(m_dwCookie)
- {
- RAFreeDecoder(m_dwCookie);
- RACloseCodec(m_dwCookie);
- m_dwCookie = 0;
- }
+ if(m_dwCookie)
+ {
+ RAFreeDecoder(m_dwCookie);
+ RACloseCodec(m_dwCookie);
+ m_dwCookie = 0;
+ }
}
HRESULT CRealAudioDecoder::Receive(IMediaSample* pIn)
{
- CAutoLock cAutoLock(&m_csReceive);
+ CAutoLock cAutoLock(&m_csReceive);
- HRESULT hr;
+ HRESULT hr;
AM_SAMPLE2_PROPERTIES* const pProps = m_pInput->SampleProps();
if(pProps->dwStreamId != AM_STREAM_MEDIA)
- return m_pOutput->Deliver(pIn);
-
- BYTE* pDataIn = NULL;
- if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
- BYTE* pDataInOrg = pDataIn;
-
- long len = pIn->GetActualDataLength();
- if(len <= 0) return S_OK;
+ return m_pOutput->Deliver(pIn);
+
+ BYTE* pDataIn = NULL;
+ if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
+ BYTE* pDataInOrg = pDataIn;
+
+ long len = pIn->GetActualDataLength();
+ if(len <= 0) return S_OK;
+
+ REFERENCE_TIME rtStart, rtStop;
+ pIn->GetTime(&rtStart, &rtStop);
+ /*
+ if(pIn->IsPreroll() == S_OK || rtStart < 0)
+ return S_OK;
+ */
+ //
+
+ if(S_OK == pIn->IsSyncPoint())
+ {
+ m_bufflen = 0;
+ m_rtBuffStart = rtStart;
+ m_fBuffDiscontinuity = pIn->IsDiscontinuity() == S_OK;
+ }
+
+ BYTE* src = NULL;
+ BYTE* dst = NULL;
+
+ int w = m_rai.coded_frame_size;
+ int h = m_rai.sub_packet_h;
+ int sps = m_rai.sub_packet_size;
+
+ if(m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_RAAC
+ || m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_RACP
+ || m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_AAC)
+ {
+ src = pDataIn;
+ dst = pDataIn + len;
+ w = len;
+ }
+ else
+ {
+ memcpy(&m_buff[m_bufflen], pDataIn, len);
+ m_bufflen += len;
+
+ len = w * h;
+
+ if(m_bufflen >= len)
+ {
+ ASSERT(m_bufflen == len);
+
+ src = m_buff;
+ dst = m_buff + len;
+
+ if(sps > 0
+ && (m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_COOK
+ || m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_ATRC))
+ {
+ for(int y = 0; y < h; y++)
+ {
+ for(int x = 0, w2 = w / sps; x < w2; x++)
+ {
+ // TRACE(_T("--- %d, %d\n"), (h*x+((h+1)/2)*(y&1)+(y>>1)), sps*(h*x+((h+1)/2)*(y&1)+(y>>1)));
+ memcpy(dst + sps*(h * x + ((h + 1) / 2)*(y & 1) + (y >> 1)), src, sps);
+ src += sps;
+ }
+ }
+
+ src = m_buff + len;
+ dst = m_buff + len * 2;
+ }
+ else if(m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_SIPR)
+ {
+ // http://mplayerhq.hu/pipermail/mplayer-dev-eng/2002-August/010569.html
+
+ static BYTE sipr_swaps[38][2] =
+ {
+ {0, 63}, {1, 22}, {2, 44}, {3, 90}, {5, 81}, {7, 31}, {8, 86}, {9, 58}, {10, 36}, {12, 68},
+ {13, 39}, {14, 73}, {15, 53}, {16, 69}, {17, 57}, {19, 88}, {20, 34}, {21, 71}, {24, 46},
+ {25, 94}, {26, 54}, {28, 75}, {29, 50}, {32, 70}, {33, 92}, {35, 74}, {38, 85}, {40, 56},
+ {42, 87}, {43, 65}, {45, 59}, {48, 79}, {49, 93}, {51, 89}, {55, 95}, {61, 76}, {67, 83},
+ {77, 80}
+ };
+
+ int bs = h * w * 2 / 96; // nibbles per subpacket
+ for(int n = 0; n < 38; n++)
+ {
+ int i = bs * sipr_swaps[n][0];
+ int o = bs * sipr_swaps[n][1];
+ // swap nibbles of block 'i' with 'o' TODO: optimize
+ for(int j = 0; j < bs; j++)
+ {
+ int x = (i & 1) ? (src[(i>>1)] >> 4) : (src[(i>>1)] & 15);
+ int y = (o & 1) ? (src[(o>>1)] >> 4) : (src[(o>>1)] & 15);
+ if(o & 1) src[(o>>1)] = (src[(o>>1)] & 0x0F) | (x << 4);
+ else src[(o>>1)] = (src[(o>>1)] & 0xF0) | x;
+ if(i & 1) src[(i>>1)] = (src[(i>>1)] & 0x0F) | (y << 4);
+ else src[(i>>1)] = (src[(i>>1)] & 0xF0) | y;
+ ++i;
+ ++o;
+ }
+ }
+ }
- REFERENCE_TIME rtStart, rtStop;
- pIn->GetTime(&rtStart, &rtStop);
-/*
- if(pIn->IsPreroll() == S_OK || rtStart < 0)
- return S_OK;
-*/
- //
-
- if(S_OK == pIn->IsSyncPoint())
- {
- m_bufflen = 0;
- m_rtBuffStart = rtStart;
- m_fBuffDiscontinuity = pIn->IsDiscontinuity() == S_OK;
- }
-
- BYTE* src = NULL;
- BYTE* dst = NULL;
-
- int w = m_rai.coded_frame_size;
- int h = m_rai.sub_packet_h;
- int sps = m_rai.sub_packet_size;
-
- if(m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_RAAC
- || m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_RACP
- || m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_AAC)
- {
- src = pDataIn;
- dst = pDataIn + len;
- w = len;
- }
- else
- {
- memcpy(&m_buff[m_bufflen], pDataIn, len);
- m_bufflen += len;
-
- len = w*h;
-
- if(m_bufflen >= len)
- {
- ASSERT(m_bufflen == len);
-
- src = m_buff;
- dst = m_buff + len;
-
- if(sps > 0
- && (m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_COOK
- || m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_ATRC))
- {
- for(int y = 0; y < h; y++)
- {
- for(int x = 0, w2 = w / sps; x < w2; x++)
- {
- // TRACE(_T("--- %d, %d\n"), (h*x+((h+1)/2)*(y&1)+(y>>1)), sps*(h*x+((h+1)/2)*(y&1)+(y>>1)));
- memcpy(dst + sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), src, sps);
- src += sps;
- }
- }
-
- src = m_buff + len;
- dst = m_buff + len*2;
- }
- else if(m_pInput->CurrentMediaType().subtype == MEDIASUBTYPE_SIPR)
- {
- // http://mplayerhq.hu/pipermail/mplayer-dev-eng/2002-August/010569.html
-
- static BYTE sipr_swaps[38][2]={
- {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68},
- {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46},
- {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56},
- {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83},
- {77,80} };
-
- int bs=h*w*2/96; // nibbles per subpacket
- for(int n=0;n<38;n++){
- int i=bs*sipr_swaps[n][0];
- int o=bs*sipr_swaps[n][1];
- // swap nibbles of block 'i' with 'o' TODO: optimize
- for(int j=0;j<bs;j++){
- int x=(i&1) ? (src[(i>>1)]>>4) : (src[(i>>1)]&15);
- int y=(o&1) ? (src[(o>>1)]>>4) : (src[(o>>1)]&15);
- if(o&1) src[(o>>1)]=(src[(o>>1)]&0x0F)|(x<<4);
- else src[(o>>1)]=(src[(o>>1)]&0xF0)|x;
- if(i&1) src[(i>>1)]=(src[(i>>1)]&0x0F)|(y<<4);
- else src[(i>>1)]=(src[(i>>1)]&0xF0)|y;
- ++i;++o;
- }
- }
- }
-
- m_bufflen = 0;
- }
- }
-
- rtStart = m_rtBuffStart;
-
- for(; src < dst; src += w)
- {
- CComPtr<IMediaSample> pOut;
- BYTE* pDataOut = NULL;
- if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pOut, NULL, NULL, 0))
- || FAILED(hr = pOut->GetPointer(&pDataOut)))
- return hr;
-
- AM_MEDIA_TYPE* pmt;
- if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
- {
- CMediaType mt(*pmt);
- m_pOutput->SetMediaType(&mt);
- DeleteMediaType(pmt);
- }
-
- hr = RADecode(m_dwCookie, src, w, pDataOut, &len, -1);
-
- if(FAILED(hr))
- {
- TRACE(_T("RA returned an error code!!!\n"));
- continue;
+ m_bufflen = 0;
+ }
+ }
+
+ rtStart = m_rtBuffStart;
+
+ for(; src < dst; src += w)
+ {
+ CComPtr<IMediaSample> pOut;
+ BYTE* pDataOut = NULL;
+ if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pOut, NULL, NULL, 0))
+ || FAILED(hr = pOut->GetPointer(&pDataOut)))
+ return hr;
+
+ AM_MEDIA_TYPE* pmt;
+ if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
+ {
+ CMediaType mt(*pmt);
+ m_pOutput->SetMediaType(&mt);
+ DeleteMediaType(pmt);
+ }
+
+ hr = RADecode(m_dwCookie, src, w, pDataOut, &len, -1);
+
+ if(FAILED(hr))
+ {
+ TRACE(_T("RA returned an error code!!!\n"));
+ continue;
// return hr;
- }
+ }
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)m_pOutput->CurrentMediaType().Format();
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)m_pOutput->CurrentMediaType().Format();
- rtStop = rtStart + 1000i64*len/pwfe->nAvgBytesPerSec*10000;
- pOut->SetTime(&rtStart, &rtStop);
- pOut->SetMediaTime(NULL, NULL);
+ rtStop = rtStart + 1000i64 * len / pwfe->nAvgBytesPerSec * 10000;
+ pOut->SetTime(&rtStart, &rtStop);
+ pOut->SetMediaTime(NULL, NULL);
- pOut->SetDiscontinuity(m_fBuffDiscontinuity); m_fBuffDiscontinuity = false;
- pOut->SetSyncPoint(TRUE);
+ pOut->SetDiscontinuity(m_fBuffDiscontinuity);
+ m_fBuffDiscontinuity = false;
+ pOut->SetSyncPoint(TRUE);
- pOut->SetActualDataLength(len);
+ pOut->SetActualDataLength(len);
-DbgLog((LOG_TRACE, 0, _T("A: rtStart=%I64d, rtStop=%I64d, disc=%d, sync=%d"),
-rtStart, rtStop, pOut->IsDiscontinuity() == S_OK, pOut->IsSyncPoint() == S_OK));
+ DbgLog((LOG_TRACE, 0, _T("A: rtStart=%I64d, rtStop=%I64d, disc=%d, sync=%d"),
+ rtStart, rtStop, pOut->IsDiscontinuity() == S_OK, pOut->IsSyncPoint() == S_OK));
- if(rtStart >= 0 && S_OK != (hr = m_pOutput->Deliver(pOut)))
- return hr;
+ if(rtStart >= 0 && S_OK != (hr = m_pOutput->Deliver(pOut)))
+ return hr;
- rtStart = rtStop;
- }
+ rtStart = rtStop;
+ }
- m_rtBuffStart = rtStart;
+ m_rtBuffStart = rtStart;
- return S_OK;
+ return S_OK;
}
HRESULT CRealAudioDecoder::CheckInputType(const CMediaType* mtIn)
{
- if(mtIn->majortype != MEDIATYPE_Audio
- || mtIn->subtype != MEDIASUBTYPE_14_4
- && mtIn->subtype != MEDIASUBTYPE_28_8
- && mtIn->subtype != MEDIASUBTYPE_ATRC
- && mtIn->subtype != MEDIASUBTYPE_COOK
- && mtIn->subtype != MEDIASUBTYPE_DNET
- && mtIn->subtype != MEDIASUBTYPE_SIPR
- && mtIn->subtype != MEDIASUBTYPE_RAAC
- && mtIn->subtype != MEDIASUBTYPE_RACP
- && mtIn->subtype != MEDIASUBTYPE_AAC)
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- if(!m_pInput->IsConnected())
- {
- if(m_hDrvDll) {FreeLibrary(m_hDrvDll); m_hDrvDll = NULL;}
-
- CAtlList<CString> paths;
- CString olddll, newdll, oldpath, newpath;
-
- TCHAR fourcc[5] =
- {
- (TCHAR)((mtIn->subtype.Data1>>0)&0xff),
- (TCHAR)((mtIn->subtype.Data1>>8)&0xff),
- (TCHAR)((mtIn->subtype.Data1>>16)&0xff),
- (TCHAR)((mtIn->subtype.Data1>>24)&0xff),
- 0
- };
-
- if(!_tcscmp(_T("RACP"), fourcc) || !_tcscmp(_T("\xff"), fourcc))
- _tcscpy(fourcc, _T("RAAC"));
-
- olddll.Format(_T("%s3260.dll"), fourcc);
- newdll.Format(_T("%s.dll"), fourcc);
-
- CRegKey key;
- TCHAR buff[_MAX_PATH];
- ULONG len = sizeof(buff);
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Software\\RealNetworks\\Preferences\\DT_Codecs"), KEY_READ)
- && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
- {
- oldpath = buff;
- TCHAR c = oldpath[oldpath.GetLength()-1];
- if(c != '\\' && c != '/') oldpath += '\\';
- key.Close();
- }
- len = sizeof(buff);
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Helix\\HelixSDK\\10.0\\Preferences\\DT_Codecs"), KEY_READ)
- && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
- {
- newpath = buff;
- TCHAR c = newpath[newpath.GetLength()-1];
- if(c != '\\' && c != '/') newpath += '\\';
- key.Close();
- }
-
- if(!newpath.IsEmpty()) paths.AddTail(newpath + newdll);
- if(!oldpath.IsEmpty()) paths.AddTail(oldpath + newdll);
- paths.AddTail(newdll); // default dll paths
- if(!newpath.IsEmpty()) paths.AddTail(newpath + olddll);
- if(!oldpath.IsEmpty()) paths.AddTail(oldpath + olddll);
- paths.AddTail(olddll); // default dll paths
-
- POSITION pos = paths.GetHeadPosition();
- while(pos && !(m_hDrvDll = LoadLibrary(paths.GetNext(pos))));
-
- if(m_hDrvDll)
- {
- RACloseCodec = (PCloseCodec)GetProcAddress(m_hDrvDll, "RACloseCodec");
- RADecode = (PDecode)GetProcAddress(m_hDrvDll, "RADecode");
- RAFlush = (PFlush)GetProcAddress(m_hDrvDll, "RAFlush");
- RAFreeDecoder = (PFreeDecoder)GetProcAddress(m_hDrvDll, "RAFreeDecoder");
- RAGetFlavorProperty = (PGetFlavorProperty)GetProcAddress(m_hDrvDll, "RAGetFlavorProperty");
- RAInitDecoder = (PInitDecoder)GetProcAddress(m_hDrvDll, "RAInitDecoder");
- RAOpenCodec = (POpenCodec)GetProcAddress(m_hDrvDll, "RAOpenCodec");
- RAOpenCodec2 = (POpenCodec2)GetProcAddress(m_hDrvDll, "RAOpenCodec2");
- RASetFlavor = (PSetFlavor)GetProcAddress(m_hDrvDll, "RASetFlavor");
- RASetDLLAccessPath = (PSetDLLAccessPath)GetProcAddress(m_hDrvDll, "RASetDLLAccessPath");
- RASetPwd = (PSetPwd)GetProcAddress(m_hDrvDll, "RASetPwd");
- }
-
- if(!m_hDrvDll || !RACloseCodec || !RADecode /*|| !RAFlush*/
- || !RAFreeDecoder || !RAGetFlavorProperty || !RAInitDecoder
- || !(RAOpenCodec || RAOpenCodec2) /*|| !RASetFlavor*/)
- return VFW_E_TYPE_NOT_ACCEPTED;
-
- if(m_hDrvDll)
- {
- char buff[_MAX_PATH];
- GetModuleFileNameA(m_hDrvDll, buff, MAX_PATH);
- CPathA p(buff);
- p.RemoveFileSpec();
- p.AddBackslash();
- m_dllpath = p.m_strPath;
- if(RASetDLLAccessPath)
- RASetDLLAccessPath("DT_Codecs=" + m_dllpath);
- }
-
- if(FAILED(InitRA(mtIn)))
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
-
- return S_OK;
+ if(mtIn->majortype != MEDIATYPE_Audio
+ || mtIn->subtype != MEDIASUBTYPE_14_4
+ && mtIn->subtype != MEDIASUBTYPE_28_8
+ && mtIn->subtype != MEDIASUBTYPE_ATRC
+ && mtIn->subtype != MEDIASUBTYPE_COOK
+ && mtIn->subtype != MEDIASUBTYPE_DNET
+ && mtIn->subtype != MEDIASUBTYPE_SIPR
+ && mtIn->subtype != MEDIASUBTYPE_RAAC
+ && mtIn->subtype != MEDIASUBTYPE_RACP
+ && mtIn->subtype != MEDIASUBTYPE_AAC)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ if(!m_pInput->IsConnected())
+ {
+ if(m_hDrvDll)
+ {
+ FreeLibrary(m_hDrvDll);
+ m_hDrvDll = NULL;
+ }
+
+ CAtlList<CString> paths;
+ CString olddll, newdll, oldpath, newpath;
+
+ TCHAR fourcc[5] =
+ {
+ (TCHAR)((mtIn->subtype.Data1 >> 0) & 0xff),
+ (TCHAR)((mtIn->subtype.Data1 >> 8) & 0xff),
+ (TCHAR)((mtIn->subtype.Data1 >> 16) & 0xff),
+ (TCHAR)((mtIn->subtype.Data1 >> 24) & 0xff),
+ 0
+ };
+
+ if(!_tcscmp(_T("RACP"), fourcc) || !_tcscmp(_T("\xff"), fourcc))
+ _tcscpy(fourcc, _T("RAAC"));
+
+ olddll.Format(_T("%s3260.dll"), fourcc);
+ newdll.Format(_T("%s.dll"), fourcc);
+
+ CRegKey key;
+ TCHAR buff[_MAX_PATH];
+ ULONG len = sizeof(buff);
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Software\\RealNetworks\\Preferences\\DT_Codecs"), KEY_READ)
+ && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
+ {
+ oldpath = buff;
+ TCHAR c = oldpath[oldpath.GetLength()-1];
+ if(c != '\\' && c != '/') oldpath += '\\';
+ key.Close();
+ }
+ len = sizeof(buff);
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Helix\\HelixSDK\\10.0\\Preferences\\DT_Codecs"), KEY_READ)
+ && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && _tcslen(buff) > 0)
+ {
+ newpath = buff;
+ TCHAR c = newpath[newpath.GetLength()-1];
+ if(c != '\\' && c != '/') newpath += '\\';
+ key.Close();
+ }
+
+ if(!newpath.IsEmpty()) paths.AddTail(newpath + newdll);
+ if(!oldpath.IsEmpty()) paths.AddTail(oldpath + newdll);
+ paths.AddTail(newdll); // default dll paths
+ if(!newpath.IsEmpty()) paths.AddTail(newpath + olddll);
+ if(!oldpath.IsEmpty()) paths.AddTail(oldpath + olddll);
+ paths.AddTail(olddll); // default dll paths
+
+ POSITION pos = paths.GetHeadPosition();
+ while(pos && !(m_hDrvDll = LoadLibrary(paths.GetNext(pos))));
+
+ if(m_hDrvDll)
+ {
+ RACloseCodec = (PCloseCodec)GetProcAddress(m_hDrvDll, "RACloseCodec");
+ RADecode = (PDecode)GetProcAddress(m_hDrvDll, "RADecode");
+ RAFlush = (PFlush)GetProcAddress(m_hDrvDll, "RAFlush");
+ RAFreeDecoder = (PFreeDecoder)GetProcAddress(m_hDrvDll, "RAFreeDecoder");
+ RAGetFlavorProperty = (PGetFlavorProperty)GetProcAddress(m_hDrvDll, "RAGetFlavorProperty");
+ RAInitDecoder = (PInitDecoder)GetProcAddress(m_hDrvDll, "RAInitDecoder");
+ RAOpenCodec = (POpenCodec)GetProcAddress(m_hDrvDll, "RAOpenCodec");
+ RAOpenCodec2 = (POpenCodec2)GetProcAddress(m_hDrvDll, "RAOpenCodec2");
+ RASetFlavor = (PSetFlavor)GetProcAddress(m_hDrvDll, "RASetFlavor");
+ RASetDLLAccessPath = (PSetDLLAccessPath)GetProcAddress(m_hDrvDll, "RASetDLLAccessPath");
+ RASetPwd = (PSetPwd)GetProcAddress(m_hDrvDll, "RASetPwd");
+ }
+
+ if(!m_hDrvDll || !RACloseCodec || !RADecode /*|| !RAFlush*/
+ || !RAFreeDecoder || !RAGetFlavorProperty || !RAInitDecoder
+ || !(RAOpenCodec || RAOpenCodec2) /*|| !RASetFlavor*/)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ if(m_hDrvDll)
+ {
+ char buff[_MAX_PATH];
+ GetModuleFileNameA(m_hDrvDll, buff, MAX_PATH);
+ CPathA p(buff);
+ p.RemoveFileSpec();
+ p.AddBackslash();
+ m_dllpath = p.m_strPath;
+ if(RASetDLLAccessPath)
+ RASetDLLAccessPath("DT_Codecs=" + m_dllpath);
+ }
+
+ if(FAILED(InitRA(mtIn)))
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
+ return S_OK;
}
HRESULT CRealAudioDecoder::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
{
- return mtIn->majortype == MEDIATYPE_Audio && (mtIn->subtype == MEDIASUBTYPE_14_4
- || mtIn->subtype == MEDIASUBTYPE_28_8
- || mtIn->subtype == MEDIASUBTYPE_ATRC
- || mtIn->subtype == MEDIASUBTYPE_COOK
- || mtIn->subtype == MEDIASUBTYPE_DNET
- || mtIn->subtype == MEDIASUBTYPE_SIPR
- || mtIn->subtype == MEDIASUBTYPE_RAAC
- || mtIn->subtype == MEDIASUBTYPE_RACP
- || mtIn->subtype == MEDIASUBTYPE_AAC)
- && mtOut->majortype == MEDIATYPE_Audio && mtOut->subtype == MEDIASUBTYPE_PCM
- ? S_OK
- : VFW_E_TYPE_NOT_ACCEPTED;
+ return mtIn->majortype == MEDIATYPE_Audio && (mtIn->subtype == MEDIASUBTYPE_14_4
+ || mtIn->subtype == MEDIASUBTYPE_28_8
+ || mtIn->subtype == MEDIASUBTYPE_ATRC
+ || mtIn->subtype == MEDIASUBTYPE_COOK
+ || mtIn->subtype == MEDIASUBTYPE_DNET
+ || mtIn->subtype == MEDIASUBTYPE_SIPR
+ || mtIn->subtype == MEDIASUBTYPE_RAAC
+ || mtIn->subtype == MEDIASUBTYPE_RACP
+ || mtIn->subtype == MEDIASUBTYPE_AAC)
+ && mtOut->majortype == MEDIATYPE_Audio && mtOut->subtype == MEDIASUBTYPE_PCM
+ ? S_OK
+ : VFW_E_TYPE_NOT_ACCEPTED;
}
HRESULT CRealAudioDecoder::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
{
- if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
+ if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
- CComPtr<IMemAllocator> pAllocatorIn;
- m_pInput->GetAllocator(&pAllocatorIn);
- if(!pAllocatorIn) return E_UNEXPECTED;
+ CComPtr<IMemAllocator> pAllocatorIn;
+ m_pInput->GetAllocator(&pAllocatorIn);
+ if(!pAllocatorIn) return E_UNEXPECTED;
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)m_pOutput->CurrentMediaType().Format();
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)m_pOutput->CurrentMediaType().Format();
- WORD wBitsPerSample = pwfe->wBitsPerSample;
- if(!wBitsPerSample) wBitsPerSample = 16;
+ WORD wBitsPerSample = pwfe->wBitsPerSample;
+ if(!wBitsPerSample) wBitsPerSample = 16;
- // ok, maybe this is too much...
- pProperties->cBuffers = 8;
- pProperties->cbBuffer = pwfe->nChannels*pwfe->nSamplesPerSec*wBitsPerSample>>3; // nAvgBytesPerSec;
- pProperties->cbAlign = 1;
- pProperties->cbPrefix = 0;
+ // ok, maybe this is too much...
+ pProperties->cBuffers = 8;
+ pProperties->cbBuffer = pwfe->nChannels * pwfe->nSamplesPerSec * wBitsPerSample >> 3; // nAvgBytesPerSec;
+ pProperties->cbAlign = 1;
+ pProperties->cbPrefix = 0;
- HRESULT hr;
- ALLOCATOR_PROPERTIES Actual;
- if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
- return hr;
+ HRESULT hr;
+ ALLOCATOR_PROPERTIES Actual;
+ if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
+ return hr;
return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
- ? E_FAIL
- : NOERROR);
+ ? E_FAIL
+ : NOERROR);
}
HRESULT CRealAudioDecoder::GetMediaType(int iPosition, CMediaType* pmt)
{
if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
- *pmt = m_pInput->CurrentMediaType();
- pmt->subtype = MEDIASUBTYPE_PCM;
- WAVEFORMATEX* pwfe = (WAVEFORMATEX*)pmt->ReallocFormatBuffer(sizeof(WAVEFORMATEX));
-
- if(iPosition < 0) return E_INVALIDARG;
- if(iPosition > (pwfe->nChannels > 2 && pwfe->nChannels <= 6 ? 1 : 0)) return VFW_S_NO_MORE_ITEMS;
-
- if(!pwfe->wBitsPerSample) pwfe->wBitsPerSample = 16;
-
- pwfe->cbSize = 0;
- pwfe->wFormatTag = WAVE_FORMAT_PCM;
- pwfe->nBlockAlign = pwfe->nChannels*pwfe->wBitsPerSample>>3;
- pwfe->nAvgBytesPerSec = pwfe->nSamplesPerSec*pwfe->nBlockAlign;
-
- if(iPosition == 0 && pwfe->nChannels > 2 && pwfe->nChannels <= 6)
- {
- static DWORD chmask[] =
- {
- KSAUDIO_SPEAKER_DIRECTOUT,
- KSAUDIO_SPEAKER_MONO,
- KSAUDIO_SPEAKER_STEREO,
- KSAUDIO_SPEAKER_STEREO|SPEAKER_FRONT_CENTER,
- KSAUDIO_SPEAKER_QUAD,
- KSAUDIO_SPEAKER_QUAD|SPEAKER_FRONT_CENTER,
- KSAUDIO_SPEAKER_5POINT1
- };
-
- WAVEFORMATEXTENSIBLE* pwfex = (WAVEFORMATEXTENSIBLE*)pmt->ReallocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
- pwfex->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
- pwfex->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
- pwfex->dwChannelMask = chmask[pwfex->Format.nChannels];
- pwfex->Samples.wValidBitsPerSample = pwfex->Format.wBitsPerSample;
- pwfex->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- }
-
- return S_OK;
+ *pmt = m_pInput->CurrentMediaType();
+ pmt->subtype = MEDIASUBTYPE_PCM;
+ WAVEFORMATEX* pwfe = (WAVEFORMATEX*)pmt->ReallocFormatBuffer(sizeof(WAVEFORMATEX));
+
+ if(iPosition < 0) return E_INVALIDARG;
+ if(iPosition > (pwfe->nChannels > 2 && pwfe->nChannels <= 6 ? 1 : 0)) return VFW_S_NO_MORE_ITEMS;
+
+ if(!pwfe->wBitsPerSample) pwfe->wBitsPerSample = 16;
+
+ pwfe->cbSize = 0;
+ pwfe->wFormatTag = WAVE_FORMAT_PCM;
+ pwfe->nBlockAlign = pwfe->nChannels * pwfe->wBitsPerSample >> 3;
+ pwfe->nAvgBytesPerSec = pwfe->nSamplesPerSec * pwfe->nBlockAlign;
+
+ if(iPosition == 0 && pwfe->nChannels > 2 && pwfe->nChannels <= 6)
+ {
+ static DWORD chmask[] =
+ {
+ KSAUDIO_SPEAKER_DIRECTOUT,
+ KSAUDIO_SPEAKER_MONO,
+ KSAUDIO_SPEAKER_STEREO,
+ KSAUDIO_SPEAKER_STEREO | SPEAKER_FRONT_CENTER,
+ KSAUDIO_SPEAKER_QUAD,
+ KSAUDIO_SPEAKER_QUAD | SPEAKER_FRONT_CENTER,
+ KSAUDIO_SPEAKER_5POINT1
+ };
+
+ WAVEFORMATEXTENSIBLE* pwfex = (WAVEFORMATEXTENSIBLE*)pmt->ReallocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
+ pwfex->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+ pwfex->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ pwfex->dwChannelMask = chmask[pwfex->Format.nChannels];
+ pwfex->Samples.wValidBitsPerSample = pwfex->Format.wBitsPerSample;
+ pwfex->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ }
+
+ return S_OK;
}
HRESULT CRealAudioDecoder::StartStreaming()
{
- int w = m_rai.coded_frame_size;
- int h = m_rai.sub_packet_h;
- int sps = m_rai.sub_packet_size;
+ int w = m_rai.coded_frame_size;
+ int h = m_rai.sub_packet_h;
+ int sps = m_rai.sub_packet_size;
- int len = w*h;
+ int len = w * h;
- m_buff.Allocate(len*2);
- m_bufflen = 0;
- m_rtBuffStart = 0;
+ m_buff.Allocate(len * 2);
+ m_bufflen = 0;
+ m_rtBuffStart = 0;
- return __super::StartStreaming();
+ return __super::StartStreaming();
}
HRESULT CRealAudioDecoder::StopStreaming()
{
- m_buff.Free();
- m_bufflen = 0;
+ m_buff.Free();
+ m_bufflen = 0;
- return __super::StopStreaming();
+ return __super::StopStreaming();
}
HRESULT CRealAudioDecoder::EndOfStream()
{
- return __super::EndOfStream();
+ return __super::EndOfStream();
}
HRESULT CRealAudioDecoder::BeginFlush()
{
- return __super::BeginFlush();
+ return __super::BeginFlush();
}
HRESULT CRealAudioDecoder::EndFlush()
{
- return __super::EndFlush();
+ return __super::EndFlush();
}
HRESULT CRealAudioDecoder::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- CAutoLock cAutoLock(&m_csReceive);
- m_tStart = tStart;
- m_bufflen = 0;
- m_rtBuffStart = 0;
- return __super::NewSegment(tStart, tStop, dRate);
+ CAutoLock cAutoLock(&m_csReceive);
+ m_tStart = tStart;
+ m_bufflen = 0;
+ m_rtBuffStart = 0;
+ return __super::NewSegment(tStart, tStop, dRate);
}
diff --git a/src/filters/parser/RealMediaSplitter/RealMediaSplitter.h b/src/filters/parser/RealMediaSplitter/RealMediaSplitter.h
index 42b28e5da..200c3b5fc 100644
--- a/src/filters/parser/RealMediaSplitter/RealMediaSplitter.h
+++ b/src/filters/parser/RealMediaSplitter/RealMediaSplitter.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
@@ -30,185 +30,219 @@
namespace RMFF
{
- typedef struct {union {char id[4]; UINT32 object_id;}; UINT32 size; UINT16 object_version;} ChunkHdr;
- typedef struct {UINT32 version, nHeaders;} FileHdr;
- typedef struct
- {
- UINT32 maxBitRate, avgBitRate;
- UINT32 maxPacketSize, avgPacketSize, nPackets;
- UINT32 tDuration, tPreroll;
- UINT32 ptrIndex, ptrData;
- UINT16 nStreams;
- enum flags_t {PN_SAVE_ENABLED=1, PN_PERFECT_PLAY_ENABLED=2, PN_LIVE_BROADCAST=4} flags;
- } Properies;
- typedef struct
- {
- UINT16 stream;
- UINT32 maxBitRate, avgBitRate;
- UINT32 maxPacketSize, avgPacketSize;
- UINT32 tStart, tPreroll, tDuration;
- CStringA name, mime;
- CAtlArray<BYTE> typeSpecData;
- UINT32 width, height;
- bool interlaced, top_field_first;
- } MediaProperies;
- typedef struct {CStringA title, author, copyright, comment;} ContentDesc;
- typedef struct {UINT64 pos; UINT32 nPackets, ptrNext;} DataChunk;
- typedef struct
- {
- UINT16 len, stream;
- UINT32 tStart;
- UINT8 reserved;
- enum flag_t {PN_RELIABLE_FLAG=1, PN_KEYFRAME_FLAG=2} flags; // UINT8
- CAtlArray<BYTE> pData;
- } MediaPacketHeader;
- typedef struct {UINT32 nIndices; UINT16 stream; UINT32 ptrNext;} IndexChunkHeader;
- typedef struct {UINT32 tStart, ptrFilePos, packet;} IndexRecord;
+typedef struct
+{
+ union
+ {
+ char id[4];
+ UINT32 object_id;
+ };
+ UINT32 size;
+ UINT16 object_version;
+} ChunkHdr;
+typedef struct
+{
+ UINT32 version, nHeaders;
+} FileHdr;
+typedef struct
+{
+ UINT32 maxBitRate, avgBitRate;
+ UINT32 maxPacketSize, avgPacketSize, nPackets;
+ UINT32 tDuration, tPreroll;
+ UINT32 ptrIndex, ptrData;
+ UINT16 nStreams;
+ enum flags_t {PN_SAVE_ENABLED = 1, PN_PERFECT_PLAY_ENABLED = 2, PN_LIVE_BROADCAST = 4} flags;
+} Properies;
+typedef struct
+{
+ UINT16 stream;
+ UINT32 maxBitRate, avgBitRate;
+ UINT32 maxPacketSize, avgPacketSize;
+ UINT32 tStart, tPreroll, tDuration;
+ CStringA name, mime;
+ CAtlArray<BYTE> typeSpecData;
+ UINT32 width, height;
+ bool interlaced, top_field_first;
+} MediaProperies;
+typedef struct
+{
+ CStringA title, author, copyright, comment;
+} ContentDesc;
+typedef struct
+{
+ UINT64 pos;
+ UINT32 nPackets, ptrNext;
+} DataChunk;
+typedef struct
+{
+ UINT16 len, stream;
+ UINT32 tStart;
+ UINT8 reserved;
+ enum flag_t {PN_RELIABLE_FLAG = 1, PN_KEYFRAME_FLAG = 2} flags; // UINT8
+ CAtlArray<BYTE> pData;
+} MediaPacketHeader;
+typedef struct
+{
+ UINT32 nIndices;
+ UINT16 stream;
+ UINT32 ptrNext;
+} IndexChunkHeader;
+typedef struct
+{
+ UINT32 tStart, ptrFilePos, packet;
+} IndexRecord;
}
struct rvinfo
{
- DWORD dwSize, fcc1, fcc2;
- WORD w, h, bpp;
- DWORD unk1, fps, type1, type2;
- BYTE morewh[14];
- void bswap();
+ DWORD dwSize, fcc1, fcc2;
+ WORD w, h, bpp;
+ DWORD unk1, fps, type1, type2;
+ BYTE morewh[14];
+ void bswap();
};
struct rainfo
{
- DWORD fourcc1; // '.', 'r', 'a', 0xfd
- WORD version1; // 4 or 5
- WORD unknown1; // 00 000
- DWORD fourcc2; // .ra4 or .ra5
- DWORD unknown2; // ???
- WORD version2; // 4 or 5
- DWORD header_size; // == 0x4e
- WORD flavor; // codec flavor id
- DWORD coded_frame_size; // coded frame size
- DWORD unknown3; // big number
- DWORD unknown4; // bigger number
- DWORD unknown5; // yet another number
- WORD sub_packet_h;
- WORD frame_size;
- WORD sub_packet_size;
- WORD unknown6; // 00 00
- void bswap();
+ DWORD fourcc1; // '.', 'r', 'a', 0xfd
+ WORD version1; // 4 or 5
+ WORD unknown1; // 00 000
+ DWORD fourcc2; // .ra4 or .ra5
+ DWORD unknown2; // ???
+ WORD version2; // 4 or 5
+ DWORD header_size; // == 0x4e
+ WORD flavor; // codec flavor id
+ DWORD coded_frame_size; // coded frame size
+ DWORD unknown3; // big number
+ DWORD unknown4; // bigger number
+ DWORD unknown5; // yet another number
+ WORD sub_packet_h;
+ WORD frame_size;
+ WORD sub_packet_size;
+ WORD unknown6; // 00 00
+ void bswap();
};
struct rainfo4 : rainfo
{
- WORD sample_rate;
- WORD unknown8; // 0
- WORD sample_size;
- WORD channels;
- void bswap();
+ WORD sample_rate;
+ WORD unknown8; // 0
+ WORD sample_size;
+ WORD channels;
+ void bswap();
};
struct rainfo5 : rainfo
{
- BYTE unknown7[6]; // 0, srate, 0
- WORD sample_rate;
- WORD unknown8; // 0
- WORD sample_size;
- WORD channels;
- DWORD genr; // "genr"
- DWORD fourcc3; // fourcc
- void bswap();
+ BYTE unknown7[6]; // 0, srate, 0
+ WORD sample_rate;
+ WORD unknown8; // 0
+ WORD sample_size;
+ WORD channels;
+ DWORD genr; // "genr"
+ DWORD fourcc3; // fourcc
+ void bswap();
};
#pragma pack(pop)
class CRMFile : public CBaseSplitterFile
{
- // using CBaseSplitterFile::Read;
+ // using CBaseSplitterFile::Read;
- HRESULT Init();
- void GetDimensions();
+ HRESULT Init();
+ void GetDimensions();
public:
- CRMFile(IAsyncReader* pAsyncReader, HRESULT& hr);
-
- template<typename T> HRESULT Read(T& var);
- HRESULT Read(RMFF::ChunkHdr& hdr);
- HRESULT Read(RMFF::MediaPacketHeader& mph, bool fFull = true);
-
- RMFF::FileHdr m_fh;
- RMFF::ContentDesc m_cd;
- RMFF::Properies m_p;
- CAutoPtrList<RMFF::MediaProperies> m_mps;
- CAutoPtrList<RMFF::DataChunk> m_dcs;
- CAutoPtrList<RMFF::IndexRecord> m_irs;
-
- typedef struct {CStringA name, data;} subtitle;
- CAtlList<subtitle> m_subs;
-
- int GetMasterStream();
+ CRMFile(IAsyncReader* pAsyncReader, HRESULT& hr);
+
+ template<typename T> HRESULT Read(T& var);
+ HRESULT Read(RMFF::ChunkHdr& hdr);
+ HRESULT Read(RMFF::MediaPacketHeader& mph, bool fFull = true);
+
+ RMFF::FileHdr m_fh;
+ RMFF::ContentDesc m_cd;
+ RMFF::Properies m_p;
+ CAutoPtrList<RMFF::MediaProperies> m_mps;
+ CAutoPtrList<RMFF::DataChunk> m_dcs;
+ CAutoPtrList<RMFF::IndexRecord> m_irs;
+
+ typedef struct
+ {
+ CStringA name, data;
+ } subtitle;
+ CAtlList<subtitle> m_subs;
+
+ int GetMasterStream();
};
class CRealMediaSplitterOutputPin : public CBaseSplitterOutputPin
{
private:
- typedef struct {CAtlArray<BYTE> data; DWORD offset;} segment;
-
- class CSegments : public CAutoPtrList<segment>, public CCritSec
- {
- public:
- REFERENCE_TIME rtStart;
- bool fDiscontinuity, fSyncPoint, fMerged;
- void Clear()
- {
- CAutoLock cAutoLock(this);
- rtStart = 0;
- fDiscontinuity = fSyncPoint = fMerged = false;
- RemoveAll();
- }
- } m_segments;
-
- CCritSec m_csQueue;
-
- HRESULT DeliverSegments();
+ typedef struct
+ {
+ CAtlArray<BYTE> data;
+ DWORD offset;
+ } segment;
+
+ class CSegments : public CAutoPtrList<segment>, public CCritSec
+ {
+ public:
+ REFERENCE_TIME rtStart;
+ bool fDiscontinuity, fSyncPoint, fMerged;
+ void Clear()
+ {
+ CAutoLock cAutoLock(this);
+ rtStart = 0;
+ fDiscontinuity = fSyncPoint = fMerged = false;
+ RemoveAll();
+ }
+ } m_segments;
+
+ CCritSec m_csQueue;
+
+ HRESULT DeliverSegments();
protected:
- HRESULT DeliverPacket(CAutoPtr<Packet> p);
+ HRESULT DeliverPacket(CAutoPtr<Packet> p);
public:
- CRealMediaSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
- virtual ~CRealMediaSplitterOutputPin();
+ CRealMediaSplitterOutputPin(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr);
+ virtual ~CRealMediaSplitterOutputPin();
- HRESULT DeliverEndFlush();
+ HRESULT DeliverEndFlush();
};
[uuid("E21BE468-5C18-43EB-B0CC-DB93A847D769")]
class CRealMediaSplitterFilter : public CBaseSplitterFilter
{
protected:
- CAutoPtr<CRMFile> m_pFile;
- HRESULT CreateOutputs(IAsyncReader* pAsyncReader);
+ CAutoPtr<CRMFile> m_pFile;
+ HRESULT CreateOutputs(IAsyncReader* pAsyncReader);
- bool DemuxInit();
- void DemuxSeek(REFERENCE_TIME rt);
- bool DemuxLoop();
+ bool DemuxInit();
+ void DemuxSeek(REFERENCE_TIME rt);
+ bool DemuxLoop();
- POSITION m_seekpos;
- UINT32 m_seekpacket;
- UINT64 m_seekfilepos;
+ POSITION m_seekpos;
+ UINT32 m_seekpacket;
+ UINT64 m_seekfilepos;
public:
- CRealMediaSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr);
- virtual ~CRealMediaSplitterFilter();
+ CRealMediaSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr);
+ virtual ~CRealMediaSplitterFilter();
- // IKeyFrameInfo
+ // IKeyFrameInfo
- STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
- STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
+ STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
+ STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
};
[uuid("765035B3-5944-4A94-806B-20EE3415F26F")]
class CRealMediaSourceFilter : public CRealMediaSplitterFilter
{
public:
- CRealMediaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr);
+ CRealMediaSourceFilter(LPUNKNOWN pUnk, HRESULT* phr);
};
////////////
@@ -216,106 +250,106 @@ public:
[uuid("238D0F23-5DC9-45A6-9BE2-666160C324DD")]
class CRealVideoDecoder : public CBaseVideoFilter
{
- typedef HRESULT (WINAPI *PRVCustomMessage)(void*, DWORD);
- typedef HRESULT (WINAPI *PRVFree)(DWORD);
- typedef HRESULT (WINAPI *PRVHiveMessage)(void*, DWORD);
- typedef HRESULT (WINAPI *PRVInit)(void*, DWORD* dwCookie);
- typedef HRESULT (WINAPI *PRVTransform)(BYTE*, BYTE*, void*, void*, DWORD);
+ typedef HRESULT(WINAPI *PRVCustomMessage)(void*, DWORD);
+ typedef HRESULT(WINAPI *PRVFree)(DWORD);
+ typedef HRESULT(WINAPI *PRVHiveMessage)(void*, DWORD);
+ typedef HRESULT(WINAPI *PRVInit)(void*, DWORD* dwCookie);
+ typedef HRESULT(WINAPI *PRVTransform)(BYTE*, BYTE*, void*, void*, DWORD);
- PRVCustomMessage RVCustomMessage;
- PRVFree RVFree;
- PRVHiveMessage RVHiveMessage;
- PRVInit RVInit;
- PRVTransform RVTransform;
+ PRVCustomMessage RVCustomMessage;
+ PRVFree RVFree;
+ PRVHiveMessage RVHiveMessage;
+ PRVInit RVInit;
+ PRVTransform RVTransform;
- HMODULE m_hDrvDll;
- DWORD m_dwCookie;
- int m_lastBuffSizeDim;
+ HMODULE m_hDrvDll;
+ DWORD m_dwCookie;
+ int m_lastBuffSizeDim;
- HRESULT InitRV(const CMediaType* pmt);
- void FreeRV();
+ HRESULT InitRV(const CMediaType* pmt);
+ void FreeRV();
- REFERENCE_TIME m_tStart;
+ REFERENCE_TIME m_tStart;
- void Resize(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho);
- void ResizeWidth(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho);
- void ResizeHeight(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho);
- void ResizeRow(BYTE* pIn, DWORD wi, DWORD dpi, BYTE* pOut, DWORD wo, DWORD dpo);
+ void Resize(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho);
+ void ResizeWidth(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho);
+ void ResizeHeight(BYTE* pIn, DWORD wi, DWORD hi, BYTE* pOut, DWORD wo, DWORD ho);
+ void ResizeRow(BYTE* pIn, DWORD wi, DWORD dpi, BYTE* pOut, DWORD wo, DWORD dpo);
- CAutoVectorPtr<BYTE> m_pI420, m_pI420Tmp;
+ CAutoVectorPtr<BYTE> m_pI420, m_pI420Tmp;
public:
- CRealVideoDecoder(LPUNKNOWN lpunk, HRESULT* phr);
- virtual ~CRealVideoDecoder();
+ CRealVideoDecoder(LPUNKNOWN lpunk, HRESULT* phr);
+ virtual ~CRealVideoDecoder();
- HRESULT Transform(IMediaSample* pIn);
- HRESULT CheckInputType(const CMediaType* mtIn);
- HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
+ HRESULT Transform(IMediaSample* pIn);
+ HRESULT CheckInputType(const CMediaType* mtIn);
+ HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
- HRESULT StartStreaming();
- HRESULT StopStreaming();
+ HRESULT StartStreaming();
+ HRESULT StopStreaming();
- HRESULT NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+ HRESULT NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
- DWORD m_timestamp;
- bool m_fDropFrames;
- HRESULT AlterQuality(Quality q);
+ DWORD m_timestamp;
+ bool m_fDropFrames;
+ HRESULT AlterQuality(Quality q);
};
[uuid("941A4793-A705-4312-8DFC-C11CA05F397E")]
class CRealAudioDecoder : public CTransformFilter
{
- typedef HRESULT (WINAPI *PCloseCodec)(DWORD);
- typedef HRESULT (WINAPI *PDecode)(DWORD,BYTE*,long,BYTE*,long*,long);
- typedef HRESULT (WINAPI *PFlush)(DWORD,DWORD,DWORD);
- typedef HRESULT (WINAPI *PFreeDecoder)(DWORD);
- typedef void* (WINAPI *PGetFlavorProperty)(void*,DWORD,DWORD,int*);
- typedef HRESULT (WINAPI *PInitDecoder)(DWORD, void*);
- typedef HRESULT (WINAPI *POpenCodec)(void*);
- typedef HRESULT (WINAPI *POpenCodec2)(void*, const char*);
- typedef HRESULT (WINAPI *PSetFlavor)(DWORD, WORD);
- typedef void (WINAPI *PSetDLLAccessPath)(const char*);
- typedef void (WINAPI *PSetPwd)(DWORD, const char*);
-
- PCloseCodec RACloseCodec;
- PDecode RADecode;
- PFlush RAFlush;
- PFreeDecoder RAFreeDecoder;
- PGetFlavorProperty RAGetFlavorProperty;
- PInitDecoder RAInitDecoder;
- POpenCodec RAOpenCodec;
- POpenCodec2 RAOpenCodec2;
- PSetFlavor RASetFlavor;
- PSetDLLAccessPath RASetDLLAccessPath;
- PSetPwd RASetPwd;
-
- CStringA m_dllpath;
- HMODULE m_hDrvDll;
- DWORD m_dwCookie;
-
- HRESULT InitRA(const CMediaType* pmt);
- void FreeRA();
-
- REFERENCE_TIME m_tStart;
-
- rainfo m_rai;
- CAutoVectorPtr<BYTE> m_buff;
- int m_bufflen;
- REFERENCE_TIME m_rtBuffStart;
- bool m_fBuffDiscontinuity;
+ typedef HRESULT(WINAPI *PCloseCodec)(DWORD);
+ typedef HRESULT(WINAPI *PDecode)(DWORD, BYTE*, long, BYTE*, long*, long);
+ typedef HRESULT(WINAPI *PFlush)(DWORD, DWORD, DWORD);
+ typedef HRESULT(WINAPI *PFreeDecoder)(DWORD);
+ typedef void*(WINAPI *PGetFlavorProperty)(void*, DWORD, DWORD, int*);
+ typedef HRESULT(WINAPI *PInitDecoder)(DWORD, void*);
+ typedef HRESULT(WINAPI *POpenCodec)(void*);
+ typedef HRESULT(WINAPI *POpenCodec2)(void*, const char*);
+ typedef HRESULT(WINAPI *PSetFlavor)(DWORD, WORD);
+ typedef void (WINAPI *PSetDLLAccessPath)(const char*);
+ typedef void (WINAPI *PSetPwd)(DWORD, const char*);
+
+ PCloseCodec RACloseCodec;
+ PDecode RADecode;
+ PFlush RAFlush;
+ PFreeDecoder RAFreeDecoder;
+ PGetFlavorProperty RAGetFlavorProperty;
+ PInitDecoder RAInitDecoder;
+ POpenCodec RAOpenCodec;
+ POpenCodec2 RAOpenCodec2;
+ PSetFlavor RASetFlavor;
+ PSetDLLAccessPath RASetDLLAccessPath;
+ PSetPwd RASetPwd;
+
+ CStringA m_dllpath;
+ HMODULE m_hDrvDll;
+ DWORD m_dwCookie;
+
+ HRESULT InitRA(const CMediaType* pmt);
+ void FreeRA();
+
+ REFERENCE_TIME m_tStart;
+
+ rainfo m_rai;
+ CAutoVectorPtr<BYTE> m_buff;
+ int m_bufflen;
+ REFERENCE_TIME m_rtBuffStart;
+ bool m_fBuffDiscontinuity;
public:
- CRealAudioDecoder(LPUNKNOWN lpunk, HRESULT* phr);
- virtual ~CRealAudioDecoder();
+ CRealAudioDecoder(LPUNKNOWN lpunk, HRESULT* phr);
+ virtual ~CRealAudioDecoder();
- HRESULT Receive(IMediaSample* pIn);
- HRESULT CheckInputType(const CMediaType* mtIn);
- HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
- HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties);
- HRESULT GetMediaType(int iPosition, CMediaType* pMediaType);
+ HRESULT Receive(IMediaSample* pIn);
+ HRESULT CheckInputType(const CMediaType* mtIn);
+ HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
+ HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties);
+ HRESULT GetMediaType(int iPosition, CMediaType* pMediaType);
- HRESULT StartStreaming();
- HRESULT StopStreaming();
+ HRESULT StartStreaming();
+ HRESULT StopStreaming();
HRESULT EndOfStream();
HRESULT BeginFlush();
diff --git a/src/filters/parser/RealMediaSplitter/resource.h b/src/filters/parser/RealMediaSplitter/resource.h
index 68f7b566d..713badf0e 100644
--- a/src/filters/parser/RealMediaSplitter/resource.h
+++ b/src/filters/parser/RealMediaSplitter/resource.h
@@ -3,7 +3,7 @@
// Used by RealMediaSplitter.rc
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
diff --git a/src/filters/parser/RealMediaSplitter/stdafx.cpp b/src/filters/parser/RealMediaSplitter/stdafx.cpp
index 8a7154bc7..54ea1d445 100644
--- a/src/filters/parser/RealMediaSplitter/stdafx.cpp
+++ b/src/filters/parser/RealMediaSplitter/stdafx.cpp
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
diff --git a/src/filters/parser/RealMediaSplitter/stdafx.h b/src/filters/parser/RealMediaSplitter/stdafx.h
index f7ba733d1..6fe7f24f9 100644
--- a/src/filters/parser/RealMediaSplitter/stdafx.h
+++ b/src/filters/parser/RealMediaSplitter/stdafx.h
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003-2006 Gabest
* http://www.gabest.org
*
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/