diff options
author | XhmikosR <xhmikosr@users.sourceforge.net> | 2010-09-15 19:46:24 +0400 |
---|---|---|
committer | XhmikosR <xhmikosr@users.sourceforge.net> | 2010-09-15 19:46:24 +0400 |
commit | 88174d2d1720fc8341ee21f0967e7aa726a2c3e8 (patch) | |
tree | 970b020eac57e2f6b7ec9c1bba66bbedc74b5d4c /src/filters/transform/MpaDecFilter/MpaDecFilter.cpp | |
parent | 08fabf0cb807f2cb1d5b2fc9dca3c180827e07c3 (diff) |
merge changes from trunk r2365-r2561
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/branches/legacy@2562 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/transform/MpaDecFilter/MpaDecFilter.cpp')
-rw-r--r-- | src/filters/transform/MpaDecFilter/MpaDecFilter.cpp | 219 |
1 files changed, 160 insertions, 59 deletions
diff --git a/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp b/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp index 9cac6e794..84873a2d6 100644 --- a/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp +++ b/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp @@ -1,6 +1,6 @@ /*
- * Copyright (C) 2003-2006 Gabest
- * http://www.gabest.org
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@ *
* 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
*
*/
@@ -111,11 +111,15 @@ const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] = {&MEDIATYPE_Audio, &MEDIASUBTYPE_Vorbis2},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_FLAC_FRAMED},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_NELLYMOSER},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_NONE},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_RAW},
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_SOWT},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_TWOS},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_SOWT},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_IN24},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_IN32},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_FL32},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_FL64},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_IMA4},
};
#ifdef REGISTER_FILTER
@@ -463,7 +467,7 @@ HRESULT CMpaDecFilter::Receive(IMediaSample* pIn) else if(subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO)
hr = ProcessHdmvLPCM(pIn->IsSyncPoint());
else if(subtype == MEDIASUBTYPE_DOLBY_AC3 ||
- subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3 ||
+ subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3 ||
subtype == MEDIASUBTYPE_DOLBY_DDPLUS ||
subtype == MEDIASUBTYPE_DOLBY_TRUEHD)
hr = ProcessAC3();
@@ -481,15 +485,35 @@ HRESULT CMpaDecFilter::Receive(IMediaSample* pIn) hr = ProcessFlac();
else if(subtype == MEDIASUBTYPE_NELLYMOSER)
hr = ProcessFfmpeg(CODEC_ID_NELLYMOSER);
- else if(subtype == MEDIASUBTYPE_PCM_RAW)
+ else if(subtype == MEDIASUBTYPE_PCM_NONE ||
+ subtype == MEDIASUBTYPE_PCM_RAW){
+ if(m_buff.GetCount() < 480){return S_OK;}
hr = ProcessPCMraw();
- else if(subtype == MEDIASUBTYPE_PCM_TWOS)
- hr = ProcessPCMtwos();
- else if(subtype == MEDIASUBTYPE_PCM_SOWT ||
- subtype == MEDIASUBTYPE_PCM_IN32)
- hr = ProcessPCMintSE();
- else if(subtype == MEDIASUBTYPE_PCM_FL32)
+ }
+ else if(subtype == MEDIASUBTYPE_PCM_TWOS){
+ if(m_buff.GetCount() < 960){return S_OK;}
+ hr = ProcessPCMintBE();
+ }
+ else if(subtype == MEDIASUBTYPE_PCM_SOWT){
+ if(m_buff.GetCount() < 960){return S_OK;}
+ hr = ProcessPCMintLE();
+ }
+ else if(subtype == MEDIASUBTYPE_PCM_IN24 ||
+ subtype == MEDIASUBTYPE_PCM_IN32){
+ if(m_buff.GetCount() < 1920){return S_OK;}
+ //The order of bytes can be big-endian and little-endian.
+ //hr = ProcessPCMintBE();
+ hr = ProcessPCMintLE();
+ }
+ else if(subtype == MEDIASUBTYPE_PCM_FL32 ||
+ subtype == MEDIASUBTYPE_PCM_FL64){
+ if(m_buff.GetCount() < 3840){return S_OK;}
+ //The order of bytes can be big-endian and little-endian.
hr = ProcessPCMfloatBE();
+ //hr = ProcessPCMfloatLE();
+ }
+ else if(subtype == MEDIASUBTYPE_IMA4)
+ hr = ProcessFfmpeg(CODEC_ID_ADPCM_IMA_QT);
else // if(.. the rest ..)
hr = ProcessMPA();
@@ -503,14 +527,14 @@ HRESULT CMpaDecFilter::ProcessLPCM() if (wfein->nChannels < 1 || wfein->nChannels > 8)
return ERROR_NOT_SUPPORTED;
- scmap_t* remap = &m_scmap_default [wfein->nChannels-1];
- int nChannels = wfein->nChannels;
+ scmap_t* remap = &m_scmap_default [wfein->nChannels-1];
+ int nChannels = wfein->nChannels;
- BYTE* pDataIn = m_buff.GetData();
- int BytesPerDoubleSample = (wfein->wBitsPerSample * 2)/8;
+ BYTE* pDataIn = m_buff.GetData();
+ int BytesPerDoubleSample = (wfein->wBitsPerSample * 2)/8;
int BytesPerDoubleChannelSample = BytesPerDoubleSample * nChannels;
- int nInBytes = m_buff.GetCount();
- int len = (nInBytes / BytesPerDoubleChannelSample) * (BytesPerDoubleChannelSample); // We always code 2 samples at a time
+ int nInBytes = m_buff.GetCount();
+ int len = (nInBytes / BytesPerDoubleChannelSample) * (BytesPerDoubleChannelSample); // We always code 2 samples at a time
CAtlArray<float> pBuff;
pBuff.SetCount((len/BytesPerDoubleSample) * 2);
@@ -1166,62 +1190,77 @@ HRESULT CMpaDecFilter::ProcessAAC() return S_OK;
}
-HRESULT CMpaDecFilter::ProcessPCMraw() //'raw ': unsigned 8-bit, signed big-endian 16 bit (?)
+HRESULT CMpaDecFilter::ProcessPCMraw() //'raw '
{
- if (m_buff.GetCount() < 480 ){return S_OK;}
WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
- int nSamples = (m_buff.GetCount() * 8)/(wfe->wBitsPerSample);
+ int nSamples = m_buff.GetCount() * 8 / wfe->wBitsPerSample;
CAtlArray<float> pBuff;
pBuff.SetCount(nSamples);
float* f = pBuff.GetData();
switch(wfe->wBitsPerSample){
- case 8:
+ case 8: //unsigned 8-bit
{BYTE* b = m_buff.GetData();
for(int i = 0; i < nSamples; i++){
- f[i] = ((float)(b[i])-128) / 128;
+ f[i] = (float)(CHAR)(b[i] - 128) / 128;
}}
break;
- case 16:
- SHORT* d = (SHORT*)m_buff.GetData();
+ case 16: //signed big-endian 16 bit
+ {USHORT* d = (USHORT*)m_buff.GetData();//signed take as an unsigned to shift operations.
for(int i = 0; i < nSamples; i++){
- f[i] = ((float)((SHORT) (((d[i] & 0x00ff) << 8) | ((d[i] & 0xff00) >> 8)) )) / 32768;
- }
+ f[i] = (float)(SHORT)(d[i] << 8 | d[i] >> 8) / 32768;
+ }}
break;
}
+
HRESULT hr;
if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels))){
return hr;
}
m_buff.RemoveAll();
-
return S_OK;
}
-HRESULT CMpaDecFilter::ProcessPCMtwos() //"twos": signed 8-bit, signed big-endian 16-bit
+HRESULT CMpaDecFilter::ProcessPCMintBE() //'twos', big-endian 'in24' and 'in32'
{
- if(m_buff.GetCount() < 960){return S_OK;}
WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
- int nSamples = (m_buff.GetCount() * 8)/(wfe->wBitsPerSample);
+ int nSamples = m_buff.GetCount() * 8 / wfe->wBitsPerSample;
CAtlArray<float> pBuff;
pBuff.SetCount(nSamples);
float* f = pBuff.GetData();
switch(wfe->wBitsPerSample){
- case 8:
+ case 8: //signed 8-bit
{CHAR* b = (CHAR*)m_buff.GetData();
for(int i = 0; i < nSamples; i++){
- f[i] = ((float)(b[i])) / 128;
+ f[i] = (float)b[i] / 128;
}}
break;
- case 16:
- SHORT* d = (SHORT*)m_buff.GetData();
+ case 16: //signed big-endian 16-bit
+ {USHORT* d = (USHORT*)m_buff.GetData();//signed take as an unsigned to shift operations.
for(int i = 0; i < nSamples; i++){
- f[i] = ((float)((SHORT) (((d[i] & 0x00ff) << 8) | ((d[i] & 0xff00) >> 8)) )) / 32768;
- }
+ f[i] = (float)(SHORT)(d[i] << 8 | d[i] >> 8) / 32768;
+ }}
+ break;
+ case 24: //signed big-endian 24-bit
+ {BYTE* b = (BYTE*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = (float)(signed int)((unsigned int)b[3*i] << 24 |
+ (unsigned int)b[3*i+1] << 16 |
+ (unsigned int)b[3*i+2] << 8) / 2147483648;
+ }}
+ break;
+ case 32: //signed big-endian 32-bit
+ {UINT* q = (UINT*)m_buff.GetData();//signed take as an unsigned to shift operations.
+ for(int i = 0; i < nSamples; i++){
+ f[i] = (float)(INT)(q[i] >> 24 |
+ (q[i] & 0x00ff0000) >> 8 |
+ (q[i] & 0x0000ff00) << 8 |
+ q[i] << 24) / 2147483648;
+ }}
break;
}
@@ -1231,70 +1270,132 @@ HRESULT CMpaDecFilter::ProcessPCMtwos() //"twos": signed 8-bit, signed big-endia }
m_buff.RemoveAll();
-
return S_OK;
}
-HRESULT CMpaDecFilter::ProcessPCMintSE() //signed little-endian: 'sowt', 'in32'
+HRESULT CMpaDecFilter::ProcessPCMintLE() //'sowt', little-endian 'in24' and 'in32'
{
- if(m_buff.GetCount() < 1920){return S_OK;}
WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
- int nSamples = (m_buff.GetCount() * 8)/(wfe->wBitsPerSample);
+ int nSamples = m_buff.GetCount() * 8 / wfe->wBitsPerSample;
CAtlArray<float> pBuff;
pBuff.SetCount(nSamples);
float* f = pBuff.GetData();
switch(wfe->wBitsPerSample){
- case 16:
+ case 8: //signed 8-bit
+ {CHAR* b = (CHAR*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = (float)b[i] / 128;
+ }}
+ break;
+ case 16: //signed little-endian 16-bit
{SHORT* d = (SHORT*)m_buff.GetData();
for(int i = 0; i < nSamples; i++){
- f[i] = ((float)(d[i])) / 32768;
+ f[i] = (float)d[i] / 32768;
}}
break;
- case 32:
- INT* q = (INT*)m_buff.GetData();
+ case 24: //signed little-endian 32-bit
+ {BYTE* b = (BYTE*)m_buff.GetData();
for(int i = 0; i < nSamples; i++){
- f[i] = ((float)(q[i])) / 2147483648;
- }
+ f[i] = (float)(signed int)((unsigned int)b[3*i] << 8 |
+ (unsigned int)b[3*i+1] << 16 |
+ (unsigned int)b[3*i+2] << 24) / 2147483648;
+ }}
+ break;
+ case 32: //signed little-endian 32-bit
+ {INT* q = (INT*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = (float)q[i] / 2147483648;
+ }}
break;
}
+
HRESULT hr;
if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels))){
return hr;
}
m_buff.RemoveAll();
-
return S_OK;
}
-HRESULT CMpaDecFilter::ProcessPCMfloatBE() //'fl32'
+HRESULT CMpaDecFilter::ProcessPCMfloatBE() //big-endian 'fl32' and 'fl64'
{
- if(m_buff.GetCount() < 1920){return S_OK;}
WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
- int nSamples = (m_buff.GetCount() * 8)/(wfe->wBitsPerSample);
+ int nSamples = m_buff.GetCount() * 8 / wfe->wBitsPerSample;
CAtlArray<float> pBuff;
pBuff.SetCount(nSamples);
float* f = pBuff.GetData();
- if (wfe->wBitsPerSample == 32)
- {
- unsigned int* q = (unsigned int*)m_buff.GetData();
- unsigned int* v = (unsigned int*)f;
- for(int i = 0; i < nSamples; i++){
- v[i] = (q[i] << 24) | ((q[i] & 0x0000ff00) << 8) | ((q[i] & 0x00ff0000) >> 8) | (q[i] >> 24);
- }
+ switch(wfe->wBitsPerSample){
+ case 32:
+ {unsigned int* q = (unsigned int*)m_buff.GetData();
+ unsigned int* vf = (unsigned int*)f;
+ for(int i = 0; i < nSamples; i++){
+ vf[i] = q[i] >> 24 |
+ (q[i] & 0x00ff0000) >> 8 |
+ (q[i] & 0x0000ff00) << 8 |
+ q[i] << 24;
+ }}
+ break;
+ case 64:
+ {unsigned __int64* q = (unsigned __int64*)m_buff.GetData();
+ unsigned __int64 x;
+ for(int i = 0; i < nSamples; i++){
+ x = q[i] >>56 |
+ (q[i] & 0x00FF000000000000) >> 40 |
+ (q[i] & 0x0000FF0000000000) >> 24 |
+ (q[i] & 0x000000FF00000000) >> 8 |
+ (q[i] & 0x00000000FF000000) << 8 |
+ (q[i] & 0x0000000000FF0000) << 24 |
+ (q[i] & 0x000000000000FF00) << 40 |
+ q[i] << 56;
+ f[i] = (float)*(double*)&x;
+ }}
+ break;
+ }
+
+ HRESULT hr;
+ if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels))){
+ return hr;
}
+ m_buff.RemoveAll();
+ return S_OK;
+}
+
+HRESULT CMpaDecFilter::ProcessPCMfloatLE() //little-endian 'fl32' and 'fl64'
+ {
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
+ int nSamples = m_buff.GetCount() * 8 / wfe->wBitsPerSample;
+
+ CAtlArray<float> pBuff;
+ pBuff.SetCount(nSamples);
+ float* f = pBuff.GetData();
+
+ switch(wfe->wBitsPerSample){
+ case 32:
+ {float* q = (float*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = q[i];
+ }}
+ break;
+ case 64:
+ {double* q = (double*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = (float)q[i];
+ }}
+ break;
+ }
+
HRESULT hr;
if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels))){
return hr;
}
m_buff.RemoveAll();
-
return S_OK;
}
|