diff options
author | Aleksoid <aleksoid@users.sourceforge.net> | 2010-08-20 02:29:43 +0400 |
---|---|---|
committer | Aleksoid <aleksoid@users.sourceforge.net> | 2010-08-20 02:29:43 +0400 |
commit | d7b8dffbcc20a1901d9ee36d35fde681e6d84db2 (patch) | |
tree | ee712f1dc71fd8140d131798d93f8846ee2ce085 /src | |
parent | fe385e117952ba595e0a761b5921beb5f65de741 (diff) |
Change : rewrite code for 'raw ','twos','sowt';
Add : support for 8-bit 'twos';
Add : support for 'in32', 'fl32';
Fix : bug bit depth of sound in Bento4;
Thanks to V0lt for patch.
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@2278 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src')
6 files changed, 121 insertions, 62 deletions
diff --git a/src/apps/mplayerc/FGManager.cpp b/src/apps/mplayerc/FGManager.cpp index 2635cd3dd..401b0c804 100644 --- a/src/apps/mplayerc/FGManager.cpp +++ b/src/apps/mplayerc/FGManager.cpp @@ -1816,6 +1816,8 @@ CFGManagerCustom::CFGManagerCustom(LPCTSTR pName, LPUNKNOWN pUnk) pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_RAW);
pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_SOWT);
pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_TWOS);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_IN32);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_FL32);
m_transform.AddTail(pFGF);
#endif
diff --git a/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4Atom.h b/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4Atom.h index fba2fa91b..b661f2a43 100644 --- a/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4Atom.h +++ b/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4Atom.h @@ -253,6 +253,8 @@ const AP4_Atom::Type AP4_ATOM_TYPE_QDMC = AP4_ATOM_TYPE('Q','D','M','C'); const AP4_Atom::Type AP4_ATOM_TYPE_QDM2 = AP4_ATOM_TYPE('Q','D','M','2');
const AP4_Atom::Type AP4_ATOM_TYPE_TWOS = AP4_ATOM_TYPE('t','w','o','s');
const AP4_Atom::Type AP4_ATOM_TYPE_SOWT = AP4_ATOM_TYPE('s','o','w','t');
+const AP4_Atom::Type AP4_ATOM_TYPE_IN32 = AP4_ATOM_TYPE('i','n','3','2');
+const AP4_Atom::Type AP4_ATOM_TYPE_FL32 = AP4_ATOM_TYPE('f','l','3','2');
const AP4_Atom::Type AP4_ATOM_TYPE_CHPL = AP4_ATOM_TYPE('c','h','p','l');
const AP4_Atom::Type AP4_ATOM_TYPE_NAM = AP4_ATOM_TYPE(169,'n','a','m');
const AP4_Atom::Type AP4_ATOM_TYPE_ART = AP4_ATOM_TYPE(169,'A','R','T');
diff --git a/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4AtomFactory.cpp b/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4AtomFactory.cpp index 6b2927879..99d74643d 100644 --- a/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4AtomFactory.cpp +++ b/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4AtomFactory.cpp @@ -405,6 +405,8 @@ AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream, case AP4_ATOM_TYPE_QDM2:
case AP4_ATOM_TYPE_TWOS:
case AP4_ATOM_TYPE_SOWT:
+ case AP4_ATOM_TYPE_IN32:
+ case AP4_ATOM_TYPE_FL32:
case AP4_ATOM_TYPE_RAW:
case AP4_ATOM_TYPE_ULAW:
atom = DNew AP4_AudioSampleEntry(type, size, stream, *this);
diff --git a/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4SampleEntry.cpp b/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4SampleEntry.cpp index 48bb52879..85d4a88dd 100644 --- a/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4SampleEntry.cpp +++ b/src/filters/parser/MP4Splitter/AP4/Source/Core/Ap4SampleEntry.cpp @@ -384,7 +384,9 @@ AP4_AudioSampleEntry::ReadFields(AP4_ByteStream& stream) if(m_DescriptionVersion == 1)
{
stream.ReadUI32(m_SamplesPerPacket);
- stream.ReadUI32(m_BytesPerPacket);
+ stream.ReadUI32(m_BytesPerPacket);
+ //QuickTime File Format Specification->Sound Sample Description (Version 1)->Bytes per packet
+ if (m_SampleSize == 16) {m_SampleSize = m_BytesPerPacket * 8;}
stream.ReadUI32(m_BytesPerFrame);
stream.ReadUI32(m_BytesPerSample);
}
diff --git a/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp b/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp index 3d7a54a3a..ed4773a58 100644 --- a/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp +++ b/src/filters/transform/MpaDecFilter/MpaDecFilter.cpp @@ -114,6 +114,8 @@ const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] = {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_RAW},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_SOWT},
{&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_TWOS},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_IN32},
+ {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM_FL32},
};
#ifdef REGISTER_FILTER
@@ -480,11 +482,14 @@ HRESULT CMpaDecFilter::Receive(IMediaSample* pIn) else if(subtype == MEDIASUBTYPE_NELLYMOSER)
hr = ProcessFfmpeg(CODEC_ID_NELLYMOSER);
else if(subtype == MEDIASUBTYPE_PCM_RAW)
- hr = ProcessPCMU8();
- else if(subtype == MEDIASUBTYPE_PCM_SOWT)
- hr = ProcessPCM16(false);
+ hr = ProcessPCMraw();
else if(subtype == MEDIASUBTYPE_PCM_TWOS)
- hr = ProcessPCM16(true);
+ hr = ProcessPCMtwos();
+ else if(subtype == MEDIASUBTYPE_PCM_SOWT ||
+ subtype == MEDIASUBTYPE_PCM_IN32)
+ hr = ProcessPCMintSE();
+ else if(subtype == MEDIASUBTYPE_PCM_FL32)
+ hr = ProcessPCMfloatBE();
else // if(.. the rest ..)
hr = ProcessMPA();
@@ -1161,93 +1166,137 @@ HRESULT CMpaDecFilter::ProcessAAC() return S_OK;
}
-HRESULT CMpaDecFilter::ProcessPCM16(bool bigendian)
+HRESULT CMpaDecFilter::ProcessPCMraw() //'raw ': unsigned 8-bit, signed big-endian 16 bit (?)
{
- size_t inSamples = m_buff.GetCount()/2;
- if(inSamples < 480){return S_OK;}
- SHORT* p = (SHORT*)m_buff.GetData();
+ if (m_buff.GetCount() < 480 ){return S_OK;}
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
+ int nSamples = (m_buff.GetCount() * 8)/(wfe->wBitsPerSample);
- WAVEFORMATEXPS2* wfe = (WAVEFORMATEXPS2*)m_pInput->CurrentMediaType().Format();
- int doubleit = 1;
- if(wfe->wBitsPerSample == 8)
- doubleit = 2;
-
CAtlArray<float> pBuff;
- pBuff.SetCount(inSamples*doubleit);
-
+ pBuff.SetCount(nSamples);
float* f = pBuff.GetData();
-
- if(bigendian){
-
- for(int i = 0; i < inSamples; i++){
-
- float t = ((float)((SHORT) (((p[i] & 0xff) << 8 )| ( (p[i] & 0xff00) >> 8)))) / SHORT_MAX;
- if(doubleit == 1){
- f[i] = t;
- }else{
- f[((int)(i/2)) * 4 +(i%2)] = t;
- f[((int)(i/2)) * 4 + 2 +(i%2)] = t;
- }
- TRACE(_T("ProcessPCM16 bigendian - %f %d"), f[i] , p[i]);
- }
- }else{
- for(int i = 0; i < inSamples; i++){
- float t = ((float)(p[i])) / SHORT_MAX;
- if(doubleit == 1){
- f[i] = t;
- }else{
- f[((int)(i/2)) * 4 +(i%2)] = t;
- f[((int)(i/2)) * 4 + 2 +(i%2)] = t;
- }
- TRACE(_T("ProcessPCM16 littleendian %f %d"), f[i] , p[i]);
- }
+ switch(wfe->wBitsPerSample){
+ case 8:
+ {BYTE* b = m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = ((float)(b[i])-128) / 128;
+ }}
+ break;
+ case 16:
+ SHORT* d = (SHORT*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = ((float)((SHORT) (((d[i] & 0x00ff) << 8) | ((d[i] & 0xff00) >> 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
+{
+ if(m_buff.GetCount() < 960){return S_OK;}
+ 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 8:
+ {CHAR* b = (CHAR*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = ((float)(b[i])) / 128;
+ }}
+ break;
+ case 16:
+ SHORT* d = (SHORT*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = ((float)((SHORT) (((d[i] & 0x00ff) << 8) | ((d[i] & 0xff00) >> 8)) )) / 32768;
+ }
+ break;
+ }
HRESULT hr;
if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels))){
- TRACE(_T("ProcessPCM16 - PCM Error %d"), wfe->nSamplesPerSec);
return hr;
}
- TRACE(_T("ProcessPCM16 - PCM Done %d"), inSamples);
m_buff.RemoveAll();
return S_OK;
}
-HRESULT CMpaDecFilter::ProcessPCMU8(){
- size_t inSamples = m_buff.GetCount();
- if(inSamples < 480){return S_OK;}
- BYTE* p = m_buff.GetData();
- WAVEFORMATEXPS2* wfe = (WAVEFORMATEXPS2*)m_pInput->CurrentMediaType().Format();
+
+HRESULT CMpaDecFilter::ProcessPCMintSE() //signed little-endian: 'sowt', 'in32'
+{
+ if(m_buff.GetCount() < 1920){return S_OK;}
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
+ int nSamples = (m_buff.GetCount() * 8)/(wfe->wBitsPerSample);
+
CAtlArray<float> pBuff;
- pBuff.SetCount(inSamples);
-
+ pBuff.SetCount(nSamples);
float* f = pBuff.GetData();
+
switch(wfe->wBitsPerSample){
case 16:
- for(int i = 0; i < inSamples; i++)
- f[i] = ((float)(p[i])-SHORT_MAX) / SHORT_MAX;
-
- default:
- for(int i = 0; i < inSamples; i++)
- f[i] = ((float)(p[i])-128) / 128;
-
- break;
+ {SHORT* d = (SHORT*)m_buff.GetData();
+ for(int i = 0; i < nSamples; i++){
+ f[i] = ((float)(d[i])) / 32768;
+ }}
+ break;
+ case 32:
+ 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))){
- TRACE(_T("ProcessPCMU8 - PCM Error %d"), wfe->nSamplesPerSec);
return hr;
}
- TRACE(_T("ProcessPCMU8 - PCM Done %d"), inSamples);
m_buff.RemoveAll();
return S_OK;
}
+HRESULT CMpaDecFilter::ProcessPCMfloatBE() //'fl32'
+{
+ if(m_buff.GetCount() < 1920){return S_OK;}
+ 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();
+
+ 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);
+ }
+ }
+
+ HRESULT hr;
+ if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels))){
+ return hr;
+ }
+
+ m_buff.RemoveAll();
+
+ return S_OK;
+}
HRESULT CMpaDecFilter::ProcessPS2PCM()
{
diff --git a/src/filters/transform/MpaDecFilter/MpaDecFilter.h b/src/filters/transform/MpaDecFilter/MpaDecFilter.h index 8ba355a79..332e8dbca 100644 --- a/src/filters/transform/MpaDecFilter/MpaDecFilter.h +++ b/src/filters/transform/MpaDecFilter/MpaDecFilter.h @@ -127,8 +127,10 @@ protected: HRESULT ProcessFlac();
HRESULT ProcessMPA();
HRESULT ProcessFfmpeg(int nCodecId);
- HRESULT ProcessPCMU8();
- HRESULT ProcessPCM16(bool bigendian);
+ HRESULT ProcessPCMraw();
+ HRESULT ProcessPCMtwos();
+ HRESULT ProcessPCMintSE();
+ HRESULT ProcessPCMfloatBE();
HRESULT GetDeliveryBuffer(IMediaSample** pSample, BYTE** pData);
HRESULT Deliver(CAtlArray<float>& pBuff, DWORD nSamplesPerSec, WORD nChannels, DWORD dwChannelMask = 0);
|