- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# MpaDecFilter.cpp

    00001 /*
    00002  *      Copyright (C) 2003-2005 Gabest
    00003  *      http://www.gabest.org
    00004  *
    00005  *  This Program is free software; you can redistribute it and/or modify
    00006  *  it under the terms of the GNU General Public License as published by
    00007  *  the Free Software Foundation; either version 2, or (at your option)
    00008  *  any later version.
    00009  *
    00010  *  This Program is distributed in the hope that it will be useful,
    00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    00013  *  GNU General Public License for more details.
    00014  *
    00015  *  You should have received a copy of the GNU General Public License
    00016  *  along with GNU Make; see the file COPYING.  If not, write to
    00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    00018  *  http://www.gnu.org/copyleft/gpl.html
    00019  *
    00020  */
    00021
    00022 #include "stdafx.h"
    00023 #include <math.h>
    00024 #include <atlbase.h>
    00025 #include <mmreg.h>
    00026 #include "MpaDecFilter.h"
    00027
    00028 #include "..\..\..\DSUtil\DSUtil.h"
    00029
    00030 #include <initguid.h>
    00031 #include "..\..\..\..\include\moreuuids.h"
    00032
    00033 #include "faad2\include\neaacdec.h"
    00034
    00035 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
    00036 {
    00037         {&MEDIATYPE_Audio, &MEDIASUBTYPE_MP3},
    00038         {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
    00039         {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Payload},
    00040         {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
    00041         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_MPEG2_AUDIO},
    00042         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_MPEG2_AUDIO},
    00043         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_MPEG2_AUDIO},
    00044         {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG2_AUDIO},
    00045         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_DOLBY_AC3},
    00046         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_DOLBY_AC3},
    00047         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_DOLBY_AC3},
    00048         {&MEDIATYPE_Audio, &MEDIASUBTYPE_DOLBY_AC3},
    00049         {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE_DOLBY_AC3},
    00050         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_DTS},
    00051         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_DTS},
    00052         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_DTS},
    00053         {&MEDIATYPE_Audio, &MEDIASUBTYPE_DTS},
    00054         {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE_DTS},
    00055         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_DVD_LPCM_AUDIO},
    00056         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_DVD_LPCM_AUDIO},
    00057         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_DVD_LPCM_AUDIO},
    00058         {&MEDIATYPE_Audio, &MEDIASUBTYPE_DVD_LPCM_AUDIO},
    00059         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_AAC},
    00060         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_AAC},
    00061         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_AAC},
    00062         {&MEDIATYPE_Audio, &MEDIASUBTYPE_AAC},
    00063         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_MP4A},
    00064         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_MP4A},
    00065         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_MP4A},
    00066         {&MEDIATYPE_Audio, &MEDIASUBTYPE_MP4A},
    00067         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_PS2_PCM},
    00068         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_PS2_PCM},
    00069         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_PS2_PCM},
    00070         {&MEDIATYPE_Audio, &MEDIASUBTYPE_PS2_PCM},
    00071         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_PS2_ADPCM},
    00072         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_PS2_ADPCM},
    00073         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_PS2_ADPCM},
    00074         {&MEDIATYPE_Audio, &MEDIASUBTYPE_PS2_ADPCM},
    00075 };
    00076
    00077 #ifdef REGISTER_FILTER
    00078
    00079 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
    00080 {
    00081         {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM},
    00082 };
    00083
    00084 const AMOVIESETUP_PIN sudpPins[] =
    00085 {
    00086     {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
    00087     {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
    00088 };
    00089
    00090 const AMOVIESETUP_FILTER sudFilter[] =
    00091 {
    00092         {&__uuidof(CMpaDecFilter), L"MPEG/AC3/DTS/LPCM Audio Decoder", MERIT_DO_NOT_USE/*0x40000001*/, countof(sudpPins), sudpPins},
    00093 };
    00094
    00095 CFactoryTemplate g_Templates[] =
    00096 {
    00097     {L"MPEG/AC3/DTS/LPCM Audio Decoder", &__uuidof(CMpaDecFilter), CreateInstance<CMpaDecFilter>, NULL, &sudFilter[0]},
    00098 };
    00099
    00100 int g_cTemplates = countof(g_Templates);
    00101
    00102 STDAPI DllRegisterServer()
    00103 {
    00104         return AMovieDllRegisterServer2(TRUE);
    00105 }
    00106
    00107 STDAPI DllUnregisterServer()
    00108 {
    00109         return AMovieDllRegisterServer2(FALSE);
    00110 }
    00111
    00112 //
    00113
    00114 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
    00115
    00116 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
    00117 {
    00118         return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
    00119 }
    00120
    00121 #endif
    00122
    00123 // dshow: left, right, center, LFE, left surround, right surround
    00124 // ac3: LFE, left, center, right, left surround, right surround
    00125 // dts: center, left, right, left surround, right surround, LFE
    00126
    00127 // lets see how we can map these things to dshow (oh the joy!)
    00128
    00129 static struct scmap_t
    00130 {
    00131         WORD nChannels;
    00132         BYTE ch[6];
    00133         DWORD dwChannelMask;
    00134 }
    00135 s_scmap_ac3[2*11] =
    00136 {
    00137         {2, {0, 1,-1,-1,-1,-1}, 0},     // A52_CHANNEL
    00138         {1, {0,-1,-1,-1,-1,-1}, 0}, // A52_MONO
    00139         {2, {0, 1,-1,-1,-1,-1}, 0}, // A52_STEREO
    00140         {3, {0, 2, 1,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER}, // A52_3F
    00141         {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_CENTER}, // A52_2F1R
    00142         {4, {0, 2, 1, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_CENTER}, // A52_3F1R
    00143         {4, {0, 1, 2, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // A52_2F2R
    00144         {5, {0, 2, 1, 3, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // A52_3F2R
    00145         {1, {0,-1,-1,-1,-1,-1}, 0}, // A52_CHANNEL1
    00146         {1, {0,-1,-1,-1,-1,-1}, 0}, // A52_CHANNEL2
    00147         {2, {0, 1,-1,-1,-1,-1}, 0}, // A52_DOLBY
    00148
    00149         {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},  // A52_CHANNEL|A52_LFE
    00150         {2, {1, 0,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY}, // A52_MONO|A52_LFE
    00151         {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY}, // A52_STEREO|A52_LFE
    00152         {4, {1, 3, 2, 0,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY}, // A52_3F|A52_LFE
    00153         {4, {1, 2, 0, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER}, // A52_2F1R|A52_LFE
    00154         {5, {1, 3, 2, 0, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER}, // A52_3F1R|A52_LFE
    00155         {5, {1, 2, 0, 3, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // A52_2F2R|A52_LFE
    00156         {6, {1, 3, 2, 0, 4, 5}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // A52_3F2R|A52_LFE
    00157         {2, {1, 0,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY}, // A52_CHANNEL1|A52_LFE
    00158         {2, {1, 0,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY}, // A52_CHANNEL2|A52_LFE
    00159         {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY}, // A52_DOLBY|A52_LFE
    00160 },
    00161 s_scmap_dts[2*10] =
    00162 {
    00163         {1, {0,-1,-1,-1,-1,-1}, 0}, // DTS_MONO
    00164         {2, {0, 1,-1,-1,-1,-1}, 0},     // DTS_CHANNEL
    00165         {2, {0, 1,-1,-1,-1,-1}, 0}, // DTS_STEREO
    00166         {2, {0, 1,-1,-1,-1,-1}, 0}, // DTS_STEREO_SUMDIFF
    00167         {2, {0, 1,-1,-1,-1,-1}, 0}, // DTS_STEREO_TOTAL
    00168         {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER}, // DTS_3F
    00169         {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_CENTER}, // DTS_2F1R
    00170         {4, {1, 2, 0, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_CENTER}, // DTS_3F1R
    00171         {4, {0, 1, 2, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // DTS_2F2R
    00172         {5, {1, 2, 0, 3, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // DTS_3F2R
    00173
    00174         {2, {0, 1,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY}, // DTS_MONO|DTS_LFE
    00175         {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},  // DTS_CHANNEL|DTS_LFE
    00176         {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY}, // DTS_STEREO|DTS_LFE
    00177         {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY}, // DTS_STEREO_SUMDIFF|DTS_LFE
    00178         {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY}, // DTS_STEREO_TOTAL|DTS_LFE
    00179         {4, {1, 2, 0, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY}, // DTS_3F|DTS_LFE
    00180         {4, {0, 1, 3, 2,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER}, // DTS_2F1R|DTS_LFE
    00181         {5, {1, 2, 0, 4, 3,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER}, // DTS_3F1R|DTS_LFE
    00182         {5, {0, 1, 4, 2, 3,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // DTS_2F2R|DTS_LFE
    00183         {6, {1, 2, 0, 5, 3, 4}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT}, // DTS_3F2R|DTS_LFE
    00184 };
    00185
    00186 CMpaDecFilter::CMpaDecFilter(LPUNKNOWN lpunk, HRESULT* phr)
    00187         : CTransformFilter(NAME("CMpaDecFilter"), lpunk, __uuidof(this))
    00188         , m_iSampleFormat(SF_PCM16)
    00189         , m_fNormalize(false)
    00190         , m_boost(1)
    00191 {
    00192         if(phr) *phr = S_OK;
    00193
    00194         if(!(m_pInput = new CMpaDecInputPin(this, phr, L"In"))) *phr = E_OUTOFMEMORY;
    00195         if(FAILED(*phr)) return;
    00196
    00197         if(!(m_pOutput = new CTransformOutputPin(NAME("CTransformOutputPin"), this, phr, L"Out"))) *phr = E_OUTOFMEMORY;
    00198         if(FAILED(*phr))  {delete m_pInput, m_pInput = NULL; return;}
    00199
    00200         m_iSpeakerConfig[ac3] = A52_STEREO;
    00201         m_iSpeakerConfig[dts] = DTS_STEREO;
    00202         m_iSpeakerConfig[aac] = AAC_STEREO;
    00203         m_fDynamicRangeControl[ac3] = false;
    00204         m_fDynamicRangeControl[dts] = false;
    00205         m_fDynamicRangeControl[aac] = false;
    00206 }
    00207
    00208 CMpaDecFilter::~CMpaDecFilter()
    00209 {
    00210 }
    00211
    00212 STDMETHODIMP CMpaDecFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
    00213 {
    00214         return
    00215                 QI(IMpaDecFilter)
    00216                  __super::NonDelegatingQueryInterface(riid, ppv);
    00217 }
    00218
    00219 HRESULT CMpaDecFilter::EndOfStream()
    00220 {
    00221         CAutoLock cAutoLock(&m_csReceive);
    00222         return __super::EndOfStream();
    00223 }
    00224
    00225 HRESULT CMpaDecFilter::BeginFlush()
    00226 {
    00227         return __super::BeginFlush();
    00228 }
    00229
    00230 HRESULT CMpaDecFilter::EndFlush()
    00231 {
    00232         CAutoLock cAutoLock(&m_csReceive);
    00233         m_buff.RemoveAll();
    00234         m_sample_max = 0.1f;
    00235         return __super::EndFlush();
    00236 }
    00237
    00238 HRESULT CMpaDecFilter::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
    00239 {
    00240         CAutoLock cAutoLock(&m_csReceive);
    00241         m_buff.RemoveAll();
    00242         m_sample_max = 0.1f;
    00243         m_ps2_state.sync = false;
    00244         return __super::NewSegment(tStart, tStop, dRate);
    00245 }
    00246
    00247 HRESULT CMpaDecFilter::Receive(IMediaSample* pIn)
    00248 {
    00249         CAutoLock cAutoLock(&m_csReceive);
    00250
    00251         HRESULT hr;
    00252
    00253     AM_SAMPLE2_PROPERTIES* const pProps = m_pInput->SampleProps();
    00254     if(pProps->dwStreamId != AM_STREAM_MEDIA)
    00255                 return m_pOutput->Deliver(pIn);
    00256
    00257         AM_MEDIA_TYPE* pmt;
    00258         if(SUCCEEDED(pIn->GetMediaType(&pmt)) && pmt)
    00259         {
    00260                 CMediaType mt(*pmt);
    00261                 m_pInput->SetMediaType(&mt);
    00262                 DeleteMediaType(pmt);
    00263                 pmt = NULL;
    00264                 m_sample_max = 0.1f;
    00265                 m_aac_state.init(mt);
    00266         }
    00267
    00268         BYTE* pDataIn = NULL;
    00269         if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
    00270
    00271         long len = pIn->GetActualDataLength();
    00272
    00273         ((CDeCSSInputPin*)m_pInput)->StripPacket(pDataIn, len);
    00274
    00275         REFERENCE_TIME rtStart = _I64_MIN, rtStop = _I64_MIN;
    00276         hr = pIn->GetTime(&rtStart, &rtStop);
    00277
    00278         if(pIn->IsDiscontinuity() == S_OK)
    00279         {
    00280                 m_fDiscontinuity = true;
    00281                 m_buff.RemoveAll();
    00282                 m_sample_max = 0.1f;
    00283                 // ASSERT(SUCCEEDED(hr)); // what to do if not?
    00284                 if(FAILED(hr)) {TRACE(_T("mpa: disc. w/o timestamp\n")); return S_OK;} // lets wait then...
    00285                 m_rtStart = rtStart;
    00286         }
    00287
    00288         if(SUCCEEDED(hr) && abs((int)(m_rtStart - rtStart)) > 1000000) // +-100ms jitter is allowed for now
    00289         {
    00290                 m_buff.RemoveAll();
    00291                 m_rtStart = rtStart;
    00292         }
    00293
    00294         int tmp = m_buff.GetSize();
    00295         m_buff.SetSize(m_buff.GetSize() + len);
    00296         memcpy(m_buff.GetData() + tmp, pDataIn, len);
    00297         len += tmp;
    00298
    00299         const GUID& subtype = m_pInput->CurrentMediaType().subtype;
    00300
    00301         if(subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
    00302                 hr = ProcessLPCM();
    00303         else if(subtype == MEDIASUBTYPE_DOLBY_AC3 || subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3)
    00304                 hr = ProcessAC3();
    00305         else if(subtype == MEDIASUBTYPE_DTS || subtype == MEDIASUBTYPE_WAVE_DTS)
    00306                 hr = ProcessDTS();
    00307         else if(subtype == MEDIASUBTYPE_AAC || subtype == MEDIASUBTYPE_MP4A)
    00308                 hr = ProcessAAC();
    00309         else if(subtype == MEDIASUBTYPE_PS2_PCM)
    00310                 hr = ProcessPS2PCM();
    00311         else if(subtype == MEDIASUBTYPE_PS2_ADPCM)
    00312                 hr = ProcessPS2ADPCM();
    00313         else // if(.. the rest ..)
    00314                 hr = ProcessMPA();
    00315
    00316         return hr;
    00317 }
    00318
    00319 HRESULT CMpaDecFilter::ProcessLPCM()
    00320 {
    00321         WAVEFORMATEX* wfein = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
    00322
    00323         ASSERT(wfein->nChannels == 2);
    00324         ASSERT(wfein->wBitsPerSample == 16);
    00325
    00326         BYTE* pDataIn = m_buff.GetData();
    00327         int len = m_buff.GetSize() & ~(wfein->nChannels*wfein->wBitsPerSample/8-1);
    00328
    00329         CArray<float> pBuff;
    00330         pBuff.SetSize(len*8/wfein->wBitsPerSample);
    00331
    00332         float* pDataOut = pBuff.GetData();
    00333         for(int i = 0; i < len; i += 2, pDataIn += 2, pDataOut++)
    00334                 *pDataOut = (float)(short)((pDataIn[0]<<8)|pDataIn[1]) / 0x8000; // FIXME: care about 20/24 bps too
    00335
    00336         memmove(m_buff.GetData(), pDataIn, m_buff.GetSize() - len);
    00337         m_buff.SetSize(m_buff.GetSize() - len);
    00338
    00339         return Deliver(pBuff, wfein->nSamplesPerSec, wfein->nChannels);
    00340 }
    00341
    00342 HRESULT CMpaDecFilter::ProcessAC3()
    00343 {
    00344         BYTE* p = m_buff.GetData();
    00345         BYTE* base = p;
    00346         BYTE* end = p + m_buff.GetSize();
    00347
    00348         while(end - p >= 7)
    00349         {
    00350                 int size = 0, flags, sample_rate, bit_rate;
    00351
    00352                 if((size = a52_syncinfo(p, &flags, &sample_rate, &bit_rate)) > 0)
    00353                 {
    00354 //                      TRACE(_T("ac3: size=%d, flags=%08x, sample_rate=%d, bit_rate=%d\n"), size, flags, sample_rate, bit_rate);
    00355
    00356                         bool fEnoughData = p + size <= end;
    00357
    00358                         if(fEnoughData)
    00359                         {
    00360                                 int iSpeakerConfig = GetSpeakerConfig(ac3);
    00361
    00362                                 if(iSpeakerConfig < 0)
    00363                                 {
    00364                                         HRESULT hr;
    00365                                         if(S_OK != (hr = Deliver(p, size, bit_rate, 0x0001)))
    00366                                                 return hr;
    00367                                 }
    00368                                 else
    00369                                 {
    00370                                         flags = iSpeakerConfig&(A52_CHANNEL_MASK|A52_LFE);
    00371                                         flags |= A52_ADJUST_LEVEL;
    00372
    00373                                         sample_t level = 1, gain = 1, bias = 0;
    00374                                         level *= gain;
    00375
    00376                                         if(a52_frame(m_a52_state, p, &flags, &level, bias) == 0)
    00377                                         {
    00378                                                 if(GetDynamicRangeControl(ac3))
    00379                                                         a52_dynrng(m_a52_state, NULL, NULL);
    00380
    00381                                                 int scmapidx = min(flags&A52_CHANNEL_MASK, countof(s_scmap_ac3)/2);
    00382                         scmap_t& scmap = s_scmap_ac3[scmapidx + ((flags&A52_LFE)?(countof(s_scmap_ac3)/2):0)];
    00383
    00384                                                 CArray<float> pBuff;
    00385                                                 pBuff.SetSize(6*256*scmap.nChannels);
    00386                                                 float* p = pBuff.GetData();
    00387
    00388                                                 int i = 0;
    00389
    00390                                                 for(; i < 6 && a52_block(m_a52_state) == 0; i++)
    00391                                                 {
    00392                                                         sample_t* samples = a52_samples(m_a52_state);
    00393
    00394                                                         for(int j = 0; j < 256; j++, samples++)
    00395                                                         {
    00396                                                                 for(int ch = 0; ch < scmap.nChannels; ch++)
    00397                                                                 {
    00398                                                                         ASSERT(scmap.ch[ch] != -1);
    00399                                                                         *p++ = (float)(*(samples + 256*scmap.ch[ch]) / level);
    00400                                                                 }
    00401                                                         }
    00402                                                 }
    00403
    00404                                                 if(i == 6)
    00405                                                 {
    00406                                                         HRESULT hr;
    00407                                                         if(S_OK != (hr = Deliver(pBuff, sample_rate, scmap.nChannels, scmap.dwChannelMask)))
    00408                                                                 return hr;
    00409                                                 }
    00410                                         }
    00411                                 }
    00412
    00413                                 p += size;
    00414                         }
    00415
    00416                         memmove(base, p, end - p);
    00417                         end = base + (end - p);
    00418                         p = base;
    00419
    00420                         if(!fEnoughData)
    00421                                 break;
    00422                 }
    00423                 else
    00424                 {
    00425                         p++;
    00426                 }
    00427         }
    00428
    00429         m_buff.SetSize(end - p);
    00430
    00431         return S_OK;
    00432 }
    00433
    00434 HRESULT CMpaDecFilter::ProcessDTS()
    00435 {
    00436         BYTE* p = m_buff.GetData();
    00437         BYTE* base = p;
    00438         BYTE* end = p + m_buff.GetSize();
    00439
    00440         while(end - p >= 14)
    00441         {
    00442                 int size = 0, flags, sample_rate, bit_rate, frame_length;
    00443
    00444                 if((size = dts_syncinfo(m_dts_state, p, &flags, &sample_rate, &bit_rate, &frame_length)) > 0)
    00445                 {
    00446 //                      TRACE(_T("dts: size=%d, flags=%08x, sample_rate=%d, bit_rate=%d, frame_length=%d\n"), size, flags, sample_rate, bit_rate, frame_length);
    00447
    00448                         bool fEnoughData = p + size <= end;
    00449
    00450                         if(fEnoughData)
    00451                         {
    00452                                 int iSpeakerConfig = GetSpeakerConfig(dts);
    00453
    00454                                 if(iSpeakerConfig < 0)
    00455                                 {
    00456                                         HRESULT hr;
    00457                                         if(S_OK != (hr = Deliver(p, size, bit_rate, 0x000b)))
    00458                                                 return hr;
    00459                                 }
    00460                                 else
    00461                                 {
    00462                                         flags = iSpeakerConfig&(DTS_CHANNEL_MASK|DTS_LFE);
    00463                                         flags |= DTS_ADJUST_LEVEL;
    00464
    00465                                         sample_t level = 1, gain = 1, bias = 0;
    00466                                         level *= gain;
    00467
    00468                                         if(dts_frame(m_dts_state, p, &flags, &level, bias) == 0)
    00469                                         {
    00470                                                 if(GetDynamicRangeControl(dts))
    00471                                                         dts_dynrng(m_dts_state, NULL, NULL);
    00472
    00473                                                 int scmapidx = min(flags&DTS_CHANNEL_MASK, countof(s_scmap_dts)/2);
    00474                         scmap_t& scmap = s_scmap_dts[scmapidx + ((flags&DTS_LFE)?(countof(s_scmap_dts)/2):0)];
    00475
    00476                                                 int blocks = dts_blocks_num(m_dts_state);
    00477
    00478                                                 CArray<float> pBuff;
    00479                                                 pBuff.SetSize(blocks*256*scmap.nChannels);
    00480                                                 float* p = pBuff.GetData();
    00481
    00482                                                 int i = 0;
    00483
    00484                                                 for(; i < blocks && dts_block(m_dts_state) == 0; i++)
    00485                                                 {
    00486                                                         sample_t* samples = dts_samples(m_dts_state);
    00487
    00488                                                         for(int j = 0; j < 256; j++, samples++)
    00489                                                         {
    00490                                                                 for(int ch = 0; ch < scmap.nChannels; ch++)
    00491                                                                 {
    00492                                                                         ASSERT(scmap.ch[ch] != -1);
    00493                                                                         *p++ = (float)(*(samples + 256*scmap.ch[ch]) / level);
    00494                                                                 }
    00495                                                         }
    00496                                                 }
    00497
    00498                                                 if(i == blocks)
    00499                                                 {
    00500                                                         HRESULT hr;
    00501                                                         if(S_OK != (hr = Deliver(pBuff, sample_rate, scmap.nChannels, scmap.dwChannelMask)))
    00502                                                                 return hr;
    00503                                                 }
    00504                                         }
    00505                                 }
    00506
    00507                                 p += size;
    00508                         }
    00509
    00510                         memmove(base, p, end - p);
    00511                         end = base + (end - p);
    00512                         p = base;
    00513
    00514                         if(!fEnoughData)
    00515                                 break;
    00516                 }
    00517                 else
    00518                 {
    00519                         p++;
    00520                 }
    00521         }
    00522
    00523         m_buff.SetSize(end - p);
    00524
    00525         return S_OK;
    00526 }
    00527
    00528 HRESULT CMpaDecFilter::ProcessAAC()
    00529 {
    00530         int iSpeakerConfig = GetSpeakerConfig(aac);
    00531
    00532         NeAACDecConfigurationPtr c = NeAACDecGetCurrentConfiguration(m_aac_state.h);
    00533         c->downMatrix = iSpeakerConfig;
    00534         NeAACDecSetConfiguration(m_aac_state.h, c);
    00535
    00536         NeAACDecFrameInfo info;
    00537         float* src = (float*)NeAACDecDecode(m_aac_state.h, &info, m_buff.GetData(), m_buff.GetSize());
    00538         m_buff.SetSize(0);
    00539         //if(!src) return E_FAIL;
    00540         if(info.error)  m_aac_state.init(m_pInput->CurrentMediaType());
    00541         if(!src || info.samples == 0) return S_OK;
    00542
    00543         // HACK: bug in faad2 with mono sources?
    00544         if(info.channels == 2 && info.channel_position[1] == UNKNOWN_CHANNEL)
    00545         {
    00546                 info.channel_position[0] = FRONT_CHANNEL_LEFT;
    00547                 info.channel_position[1] = FRONT_CHANNEL_RIGHT;
    00548         }
    00549
    00550         CArray<float> pBuff;
    00551         pBuff.SetSize(info.samples);
    00552         float* dst = pBuff.GetData();
    00553
    00554         CMap<int,int,int,int> chmask;
    00555         chmask[FRONT_CHANNEL_CENTER] = SPEAKER_FRONT_CENTER;
    00556         chmask[FRONT_CHANNEL_LEFT] = SPEAKER_FRONT_LEFT;
    00557         chmask[FRONT_CHANNEL_RIGHT] = SPEAKER_FRONT_RIGHT;
    00558         chmask[SIDE_CHANNEL_LEFT] = SPEAKER_SIDE_LEFT;
    00559         chmask[SIDE_CHANNEL_RIGHT] = SPEAKER_SIDE_RIGHT;
    00560         chmask[BACK_CHANNEL_LEFT] = SPEAKER_BACK_LEFT;
    00561         chmask[BACK_CHANNEL_RIGHT] = SPEAKER_BACK_RIGHT;
    00562         chmask[BACK_CHANNEL_CENTER] = SPEAKER_BACK_CENTER;
    00563         chmask[LFE_CHANNEL] = SPEAKER_LOW_FREQUENCY;
    00564
    00565         DWORD dwChannelMask = 0;
    00566         for(int i = 0; i < info.channels; i++)
    00567         {
    00568                 if(info.channel_position[i] == UNKNOWN_CHANNEL) {ASSERT(0); return E_FAIL;}
    00569                 dwChannelMask |= chmask[info.channel_position[i]];
    00570         }
    00571
    00572         int chmap[countof(info.channel_position)];
    00573         memset(chmap, 0, sizeof(chmap));
    00574
    00575         for(int i = 0; i < info.channels; i++)
    00576         {
    00577                 unsigned int ch = 0, mask = chmask[info.channel_position[i]];
    00578
    00579                 for(int j = 0; j < 32; j++)
    00580                 {
    00581                         if(dwChannelMask & (1 << j))
    00582                         {
    00583                                 if((1 << j) == mask) {chmap[i] = ch; break;}
    00584                                 ch++;
    00585                         }
    00586                 }
    00587         }
    00588
    00589         if(info.channels <= 2) dwChannelMask = 0;
    00590
    00591         for(int j = 0; j < info.samples; j += info.channels, dst += info.channels)
    00592                 for(int i = 0; i < info.channels; i++)
    00593                         dst[chmap[i]] = *src++;
    00594
    00595         HRESULT hr;
    00596         if(S_OK != (hr = Deliver(pBuff, info.samplerate, info.channels, dwChannelMask)))
    00597                 return hr;
    00598
    00599         return S_OK;
    00600 }
    00601
    00602 HRESULT CMpaDecFilter::ProcessPS2PCM()
    00603 {
    00604         BYTE* p = m_buff.GetData();
    00605         BYTE* base = p;
    00606         BYTE* end = p + m_buff.GetSize();
    00607
    00608         WAVEFORMATEXPS2* wfe = (WAVEFORMATEXPS2*)m_pInput->CurrentMediaType().Format();
    00609         int size = wfe->dwInterleave*wfe->nChannels;
    00610         int samples = wfe->dwInterleave/(wfe->wBitsPerSample>>3);
    00611         int channels = wfe->nChannels;
    00612
    00613         CArray<float> pBuff;
    00614         pBuff.SetSize(samples*channels);
    00615         float* f = pBuff.GetData();
    00616
    00617         while(end - p >= size)
    00618         {
    00619                 DWORD* dw = (DWORD*)p;
    00620
    00621                 if(dw[0] == 'dhSS')
    00622                 {
    00623                         p += dw[1] + 8;
    00624                 }
    00625                 else if(dw[0] == 'dbSS')
    00626                 {
    00627                         p += 8;
    00628                         m_ps2_state.sync = true;
    00629                 }
    00630                 else
    00631                 {
    00632                         if(m_ps2_state.sync)
    00633                         {
    00634                                 short* s = (short*)p;
    00635
    00636                                 for(int i = 0; i < samples; i++)
    00637                                         for(int j = 0; j < channels; j++)
    00638                                                 f[i*channels+j] = (float)s[j*samples+i] / 32768;
    00639                         }
    00640                         else
    00641                         {
    00642                                 for(int i = 0, j = samples*channels; i < j; i++)
    00643                                         f[i] = 0;
    00644                         }
    00645
    00646                         HRESULT hr;
    00647                         if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels)))
    00648                                 return hr;
    00649
    00650                         p += size;
    00651
    00652                         memmove(base, p, end - p);
    00653                         end = base + (end - p);
    00654                         p = base;
    00655                 }
    00656         }
    00657
    00658         m_buff.SetSize(end - p);
    00659
    00660         return S_OK;
    00661 }
    00662
    00663 static void decodeps2adpcm(ps2_state_t& s, int channel, BYTE* pin, double* pout)
    00664 {
    00665         int tbl_index = pin[0]>>4;
    00666         int shift = pin[0]&0xf;
    00667     int unk = pin[1]; // ?
    00668
    00669         if(tbl_index >= 10) {ASSERT(0); return;}
    00670         // if(unk == 7) {ASSERT(0); return;} // ???
    00671
    00672         static double s_tbl[] =
    00673         {
    00674                 0.0, 0.0, 0.9375, 0.0, 1.796875, -0.8125, 1.53125, -0.859375, 1.90625, -0.9375,
    00675                 0.0, 0.0, -0.9375, 0.0, -1.796875, 0.8125, -1.53125, 0.859375 -1.90625, 0.9375
    00676         };
    00677
    00678         double* tbl = &s_tbl[tbl_index*2];
    00679         double& a = s.a[channel];
    00680         double& b = s.b[channel];
    00681
    00682         for(int i = 0; i < 28; i++)
    00683         {
    00684                 short input = (short)(((pin[2+i/2] >> ((i&1) << 2)) & 0xf) << 12) >> shift;
    00685                 double output = a * tbl[1] + b * tbl[0] + input;
    00686
    00687                 a = b;
    00688                 b = output;
    00689
    00690                 *pout++ = output / SHRT_MAX;
    00691         }
    00692 }
    00693
    00694 HRESULT CMpaDecFilter::ProcessPS2ADPCM()
    00695 {
    00696         BYTE* p = m_buff.GetData();
    00697         BYTE* base = p;
    00698         BYTE* end = p + m_buff.GetSize();
    00699
    00700         WAVEFORMATEXPS2* wfe = (WAVEFORMATEXPS2*)m_pInput->CurrentMediaType().Format();
    00701         int size = wfe->dwInterleave*wfe->nChannels;
    00702         int samples = wfe->dwInterleave * 14 / 16 * 2;
    00703         int channels = wfe->nChannels;
    00704
    00705         CArray<float> pBuff;
    00706         pBuff.SetSize(samples*channels);
    00707         float* f = pBuff.GetData();
    00708
    00709         while(end - p >= size)
    00710         {
    00711                 DWORD* dw = (DWORD*)p;
    00712
    00713                 if(dw[0] == 'dhSS')
    00714                 {
    00715                         p += dw[1] + 8;
    00716                 }
    00717                 else if(dw[0] == 'dbSS')
    00718                 {
    00719                         p += 8;
    00720                         m_ps2_state.sync = true;
    00721                 }
    00722                 else
    00723                 {
    00724                         if(m_ps2_state.sync)
    00725                         {
    00726                                 double* tmp = new double[samples*channels];
    00727
    00728                                 for(int channel = 0, j = 0, k = 0; channel < channels; channel++, j += wfe->dwInterleave)
    00729                                         for(int i = 0; i < wfe->dwInterleave; i += 16, k += 28)
    00730                                                 decodeps2adpcm(m_ps2_state, channel, p + i + j, tmp + k);
    00731
    00732                                 for(int i = 0, k = 0; i < samples; i++)
    00733                                         for(int j = 0; j < channels; j++, k++)
    00734                                                 f[k] = (float)tmp[j*samples+i];
    00735
    00736                                 delete [] tmp;
    00737                         }
    00738                         else
    00739                         {
    00740                                 for(int i = 0, j = samples*channels; i < j; i++)
    00741                                         f[i] = 0;
    00742                         }
    00743
    00744                         HRESULT hr;
    00745                         if(S_OK != (hr = Deliver(pBuff, wfe->nSamplesPerSec, wfe->nChannels)))
    00746                                 return hr;
    00747
    00748                         p += size;
    00749                 }
    00750         }
    00751
    00752         memmove(base, p, end - p);
    00753         end = base + (end - p);
    00754         p = base;
    00755
    00756         m_buff.SetSize(end - p);
    00757
    00758         return S_OK;
    00759 }
    00760
    00761 static inline float fscale(mad_fixed_t sample)
    00762 {
    00763         if(sample >= MAD_F_ONE) sample = MAD_F_ONE - 1;
    00764         else if(sample < -MAD_F_ONE) sample = -MAD_F_ONE;
    00765
    00766         return (float)sample / (1 << MAD_F_FRACBITS);
    00767 }
    00768
    00769 HRESULT CMpaDecFilter::ProcessMPA()
    00770 {
    00771         mad_stream_buffer(&m_stream, m_buff.GetData(), m_buff.GetSize());
    00772
    00773         while(1)
    00774         {
    00775                 if(mad_frame_decode(&m_frame, &m_stream) == -1)
    00776                 {
    00777                         if(m_stream.error == MAD_ERROR_BUFLEN)
    00778                         {
    00779                                 memmove(m_buff.GetData(), m_stream.this_frame, m_stream.bufend - m_stream.this_frame);
    00780                                 m_buff.SetSize(m_stream.bufend - m_stream.this_frame);
    00781                                 break;
    00782                         }
    00783
    00784                         if(!MAD_RECOVERABLE(m_stream.error))
    00785                         {
    00786                                 TRACE(_T("*m_stream.error == %d\n"), m_stream.error);
    00787                                 return E_FAIL;
    00788                         }
    00789
    00790                         // FIXME: the renderer doesn't like this
    00791                         // m_fDiscontinuity = true;
    00792
    00793                         continue;
    00794                 }
    00795 /*
    00796 // TODO: needs to be tested... (has anybody got an external mpeg audio decoder?)
    00797 HRESULT hr;
    00798 if(S_OK != (hr = Deliver(
    00799    (BYTE*)m_stream.this_frame,
    00800    m_stream.next_frame - m_stream.this_frame,
    00801    m_frame.header.bitrate,
    00802    m_frame.header.layer == 1 ? 0x0004 : 0x0005)))
    00803         return hr;
    00804 continue;
    00805 */
    00806                 mad_synth_frame(&m_synth, &m_frame);
    00807
    00808                 WAVEFORMATEX* wfein = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
    00809                 if(wfein->nChannels != m_synth.pcm.channels || wfein->nSamplesPerSec != m_synth.pcm.samplerate)
    00810                         continue;
    00811
    00812                 const mad_fixed_t* left_ch   = m_synth.pcm.samples[0];
    00813                 const mad_fixed_t* right_ch  = m_synth.pcm.samples[1];
    00814
    00815                 CArray<float> pBuff;
    00816                 pBuff.SetSize(m_synth.pcm.length*m_synth.pcm.channels);
    00817
    00818                 float* pDataOut = pBuff.GetData();
    00819                 for(unsigned short i = 0; i < m_synth.pcm.length; i++)
    00820                 {
    00821                         *pDataOut++ = fscale(*left_ch++);
    00822                         if(m_synth.pcm.channels == 2) *pDataOut++ = fscale(*right_ch++);
    00823                 }
    00824
    00825                 HRESULT hr;
    00826                 if(S_OK != (hr = Deliver(pBuff, m_synth.pcm.samplerate, m_synth.pcm.channels)))
    00827                         return hr;
    00828         }
    00829
    00830         return S_OK;
    00831 }
    00832
    00833 HRESULT CMpaDecFilter::GetDeliveryBuffer(IMediaSample** pSample, BYTE** pData)
    00834 {
    00835         HRESULT hr;
    00836
    00837         *pData = NULL;
    00838         if(FAILED(hr = m_pOutput->GetDeliveryBuffer(pSample, NULL, NULL, 0))
    00839         || FAILED(hr = (*pSample)->GetPointer(pData)))
    00840                 return hr;
    00841
    00842         AM_MEDIA_TYPE* pmt = NULL;
    00843         if(SUCCEEDED((*pSample)->GetMediaType(&pmt)) && pmt)
    00844         {
    00845                 CMediaType mt = *pmt;
    00846                 m_pOutput->SetMediaType(&mt);
    00847                 DeleteMediaType(pmt);
    00848                 pmt = NULL;
    00849         }
    00850
    00851         return S_OK;
    00852 }
    00853
    00854 HRESULT CMpaDecFilter::Deliver(CArray<float>& pBuff, DWORD nSamplesPerSec, WORD nChannels, DWORD dwChannelMask)
    00855 {
    00856         HRESULT hr;
    00857
    00858         SampleFormat sf = GetSampleFormat();
    00859
    00860         CMediaType mt = CreateMediaType(sf, nSamplesPerSec, nChannels, dwChannelMask);
    00861         WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
    00862
    00863         int nSamples = pBuff.GetSize()/wfe->nChannels;
    00864
    00865         if(FAILED(hr = ReconnectOutput(nSamples, mt)))
    00866                 return hr;
    00867
    00868         CComPtr<IMediaSample> pOut;
    00869         BYTE* pDataOut = NULL;
    00870         if(FAILED(GetDeliveryBuffer(&pOut, &pDataOut)))
    00871                 return E_FAIL;
    00872
    00873         REFERENCE_TIME rtDur = 10000000i64*nSamples/wfe->nSamplesPerSec;
    00874         REFERENCE_TIME rtStart = m_rtStart, rtStop = m_rtStart + rtDur;
    00875         m_rtStart += rtDur;
    00876 //TRACE(_T("CMpaDecFilter: %I64d - %I64d\n"), rtStart/10000, rtStop/10000);
    00877         if(rtStart < 0 /*200000*/ /* < 0, FIXME: 0 makes strange noises */)
    00878                 return S_OK;
    00879
    00880         if(hr == S_OK)
    00881         {
    00882                 m_pOutput->SetMediaType(&mt);
    00883                 pOut->SetMediaType(&mt);
    00884         }
    00885
    00886         pOut->SetTime(&rtStart, &rtStop);
    00887         pOut->SetMediaTime(NULL, NULL);
    00888
    00889         pOut->SetPreroll(FALSE);
    00890         pOut->SetDiscontinuity(m_fDiscontinuity); m_fDiscontinuity = false;
    00891         pOut->SetSyncPoint(TRUE);
    00892
    00893         pOut->SetActualDataLength(pBuff.GetSize()*wfe->wBitsPerSample/8);
    00894
    00895 WAVEFORMATEX* wfeout = (WAVEFORMATEX*)m_pOutput->CurrentMediaType().Format();
    00896 ASSERT(wfeout->nChannels == wfe->nChannels);
    00897 ASSERT(wfeout->nSamplesPerSec == wfe->nSamplesPerSec);
    00898
    00899         float* pDataIn = pBuff.GetData();
    00900
    00901         // TODO: move this into the audio switcher
    00902         float sample_mul = 1;
    00903         if(m_fNormalize)
    00904         {
    00905                 for(int i = 0, len = pBuff.GetSize(); i < len; i++)
    00906                 {
    00907                         float f = *pDataIn++;
    00908                         if(f < 0) f = -f;
    00909                         if(m_sample_max < f) m_sample_max = f;
    00910                 }
    00911                 sample_mul = 1.0f / m_sample_max;
    00912                 pDataIn = pBuff.GetData();
    00913         }
    00914
    00915         bool fBoost = m_boost > 1;
    00916         double boost = 1+log10(m_boost);
    00917
    00918         for(int i = 0, len = pBuff.GetSize(); i < len; i++)
    00919         {
    00920                 float f = *pDataIn++;
    00921
    00922                 // TODO: move this into the audio switcher
    00923
    00924                 if(m_fNormalize)
    00925                         f *= sample_mul;
    00926
    00927                 if(fBoost)
    00928                         f *= boost;
    00929
    00930                 if(f < -1) f = -1;
    00931                 else if(f > 1) f = 1;
    00932
    00933                 #define round(x) ((x) > 0 ? (x) + 0.5 : (x) - 0.5)
    00934
    00935                 switch(sf)
    00936                 {
    00937                 default:
    00938                 case SF_PCM16:
    00939                         *(short*)pDataOut = (short)round(f * SHRT_MAX);
    00940                         pDataOut += sizeof(short);
    00941                         break;
    00942                 case SF_PCM24:
    00943                         {DWORD i24 = (DWORD)(int)round(f * ((1<<23)-1));
    00944                         *pDataOut++ = (BYTE)(i24);
    00945                         *pDataOut++ = (BYTE)(i24>>8);
    00946                         *pDataOut++ = (BYTE)(i24>>16);}
    00947                         break;
    00948                 case SF_PCM32:
    00949                         *(int*)pDataOut = (int)round(f * INT_MAX);
    00950                         pDataOut += sizeof(int);
    00951                         break;
    00952                 case SF_FLOAT32:
    00953                         *(float*)pDataOut = f;
    00954                         pDataOut += sizeof(float);
    00955                         break;
    00956                 }
    00957         }
    00958
    00959         return m_pOutput->Deliver(pOut);
    00960 }
    00961
    00962 HRESULT CMpaDecFilter::Deliver(BYTE* pBuff, int size, int bit_rate, BYTE type)
    00963 {
    00964         HRESULT hr;
    00965
    00966         CMediaType mt = CreateMediaTypeSPDIF();
    00967         WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
    00968
    00969         int length = 0;
    00970         while(length < size+sizeof(WORD)*4) length += 0x800;
    00971         int size2 = 1i64 * wfe->nBlockAlign * wfe->nSamplesPerSec * size*8 / bit_rate;
    00972         while(length < size2) length += 0x800;
    00973
    00974         if(FAILED(hr = ReconnectOutput(length / wfe->nBlockAlign, mt)))
    00975                 return hr;
    00976
    00977         CComPtr<IMediaSample> pOut;
    00978         BYTE* pDataOut = NULL;
    00979         if(FAILED(GetDeliveryBuffer(&pOut, &pDataOut)))
    00980                 return E_FAIL;
    00981
    00982         REFERENCE_TIME rtDur = 10000000i64 * size*8 / bit_rate;
    00983         REFERENCE_TIME rtStart = m_rtStart, rtStop = m_rtStart + rtDur;
    00984         m_rtStart += rtDur;
    00985
    00986         if(rtStart < 0)
    00987                 return S_OK;
    00988
    00989         if(hr == S_OK)
    00990         {
    00991                 m_pOutput->SetMediaType(&mt);
    00992                 pOut->SetMediaType(&mt);
    00993         }
    00994
    00995         pOut->SetTime(&rtStart, &rtStop);
    00996         pOut->SetMediaTime(NULL, NULL);
    00997
    00998         pOut->SetPreroll(FALSE);
    00999         pOut->SetDiscontinuity(m_fDiscontinuity); m_fDiscontinuity = false;
    01000         pOut->SetSyncPoint(TRUE);
    01001
    01002         pOut->SetActualDataLength(length);
    01003
    01004         WORD* pDataOutW = (WORD*)pDataOut;
    01005         pDataOutW[0] = 0xf872;
    01006         pDataOutW[1] = 0x4e1f;
    01007         pDataOutW[2] = type;
    01008         pDataOutW[3] = size*8;
    01009         _swab((char*)pBuff, (char*)&pDataOutW[4], size);
    01010
    01011         return m_pOutput->Deliver(pOut);
    01012 }
    01013
    01014 HRESULT CMpaDecFilter::ReconnectOutput(int nSamples, CMediaType& mt)
    01015 {
    01016         HRESULT hr;
    01017
    01018         CComQIPtr<IMemInputPin> pPin = m_pOutput->GetConnected();
    01019         if(!pPin) return E_NOINTERFACE;
    01020
    01021         CComPtr<IMemAllocator> pAllocator;
    01022         if(FAILED(hr = pPin->GetAllocator(&pAllocator)) || !pAllocator)
    01023                 return hr;
    01024
    01025         ALLOCATOR_PROPERTIES props, actual;
    01026         if(FAILED(hr = pAllocator->GetProperties(&props)))
    01027                 return hr;
    01028
    01029         WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
    01030         long cbBuffer = nSamples * wfe->nBlockAlign;
    01031
    01032         if(mt != m_pOutput->CurrentMediaType() || cbBuffer > props.cbBuffer)
    01033         {
    01034                 if(cbBuffer > props.cbBuffer)
    01035                 {
    01036                         props.cBuffers = 4;
    01037                         props.cbBuffer = cbBuffer*3/2;
    01038
    01039                         if(FAILED(hr = m_pOutput->DeliverBeginFlush())
    01040                         || FAILED(hr = m_pOutput->DeliverEndFlush())
    01041                         || FAILED(hr = pAllocator->Decommit())
    01042                         || FAILED(hr = pAllocator->SetProperties(&props, &actual))
    01043                         || FAILED(hr = pAllocator->Commit()))
    01044                                 return hr;
    01045
    01046                         if(props.cBuffers > actual.cBuffers || props.cbBuffer > actual.cbBuffer)
    01047                         {
    01048                                 NotifyEvent(EC_ERRORABORT, hr, 0);
    01049                                 return E_FAIL;
    01050                         }
    01051                 }
    01052
    01053                 return S_OK;
    01054         }
    01055
    01056         return S_FALSE;
    01057 }
    01058
    01059 CMediaType CMpaDecFilter::CreateMediaType(SampleFormat sf, DWORD nSamplesPerSec, WORD nChannels, DWORD dwChannelMask)
    01060 {
    01061         CMediaType mt;
    01062
    01063         mt.majortype = MEDIATYPE_Audio;
    01064         mt.subtype = sf == SF_FLOAT32 ? MEDIASUBTYPE_IEEE_FLOAT : MEDIASUBTYPE_PCM;
    01065         mt.formattype = FORMAT_WaveFormatEx;
    01066
    01067         WAVEFORMATEXTENSIBLE wfex;
    01068         memset(&wfex, 0, sizeof(wfex));
    01069         WAVEFORMATEX* wfe = &wfex.Format;
    01070         wfe->wFormatTag = (WORD)mt.subtype.Data1;
    01071         wfe->nChannels = nChannels;
    01072         wfe->nSamplesPerSec = nSamplesPerSec;
    01073         switch(sf)
    01074         {
    01075         default:
    01076         case SF_PCM16: wfe->wBitsPerSample = 16; break;
    01077         case SF_PCM24: wfe->wBitsPerSample = 24; break;
    01078         case SF_PCM32: case SF_FLOAT32: wfe->wBitsPerSample = 32; break;
    01079         }
    01080         wfe->nBlockAlign = wfe->nChannels*wfe->wBitsPerSample/8;
    01081         wfe->nAvgBytesPerSec = wfe->nSamplesPerSec*wfe->nBlockAlign;
    01082
    01083         // FIXME: 24/32 bit only seems to work with WAVE_FORMAT_EXTENSIBLE
    01084         if(dwChannelMask == 0 && (sf == SF_PCM24 || sf == SF_PCM32))
    01085                 dwChannelMask = nChannels == 2 ? (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT) : SPEAKER_FRONT_CENTER;
    01086
    01087         if(dwChannelMask)
    01088         {
    01089                 wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
    01090                 wfex.Format.cbSize = sizeof(wfex) - sizeof(wfex.Format);
    01091                 wfex.dwChannelMask = dwChannelMask;
    01092                 wfex.Samples.wValidBitsPerSample = wfex.Format.wBitsPerSample;
    01093                 wfex.SubFormat = mt.subtype;
    01094         }
    01095
    01096         mt.SetFormat((BYTE*)&wfex, sizeof(wfex.Format) + wfex.Format.cbSize);
    01097
    01098         return mt;
    01099 }
    01100
    01101 CMediaType CMpaDecFilter::CreateMediaTypeSPDIF()
    01102 {
    01103         CMediaType mt = CreateMediaType(SF_PCM16, 48000, 2);
    01104         ((WAVEFORMATEX*)mt.pbFormat)->wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
    01105         return mt;
    01106 }
    01107
    01108 HRESULT CMpaDecFilter::CheckInputType(const CMediaType* mtIn)
    01109 {
    01110         if(mtIn->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
    01111         {
    01112                 WAVEFORMATEX* wfe = (WAVEFORMATEX*)mtIn->Format();
    01113                 if(wfe->nChannels != 2 || wfe->wBitsPerSample != 16) // TODO: remove this limitation
    01114                         return VFW_E_TYPE_NOT_ACCEPTED;
    01115         }
    01116         else if(mtIn->subtype == MEDIASUBTYPE_PS2_ADPCM)
    01117         {
    01118                 WAVEFORMATEXPS2* wfe = (WAVEFORMATEXPS2*)mtIn->Format();
    01119                 if(wfe->dwInterleave & 0xf) // has to be a multiple of the block size (16 bytes)
    01120                         return VFW_E_TYPE_NOT_ACCEPTED;
    01121         }
    01122
    01123         for(int i = 0; i < countof(sudPinTypesIn); i++)
    01124         {
    01125                 if(*sudPinTypesIn[i].clsMajorType == mtIn->majortype
    01126                 && *sudPinTypesIn[i].clsMinorType == mtIn->subtype)
    01127                         return S_OK;
    01128         }
    01129
    01130         return VFW_E_TYPE_NOT_ACCEPTED;
    01131 }
    01132
    01133 HRESULT CMpaDecFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
    01134 {
    01135         return SUCCEEDED(CheckInputType(mtIn))
    01136                 && mtOut->majortype == MEDIATYPE_Audio && mtOut->subtype == MEDIASUBTYPE_PCM
    01137                 || mtOut->majortype == MEDIATYPE_Audio && mtOut->subtype == MEDIASUBTYPE_IEEE_FLOAT
    01138                 ? S_OK
    01139                 : VFW_E_TYPE_NOT_ACCEPTED;
    01140 }
    01141
    01142 HRESULT CMpaDecFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
    01143 {
    01144         if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    01145
    01146         CMediaType& mt = m_pInput->CurrentMediaType();
    01147         WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
    01148
    01149         pProperties->cBuffers = 4;
    01150         // pProperties->cbBuffer = 1;
    01151         pProperties->cbBuffer = 48000*6*(32/8)/10; // 48KHz 6ch 32bps 100ms
    01152         pProperties->cbAlign = 1;
    01153         pProperties->cbPrefix = 0;
    01154
    01155         HRESULT hr;
    01156         ALLOCATOR_PROPERTIES Actual;
    01157     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
    01158                 return hr;
    01159
    01160     return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
    01161                 ? E_FAIL
    01162                 : NOERROR;
    01163 }
    01164
    01165 HRESULT CMpaDecFilter::GetMediaType(int iPosition, CMediaType* pmt)
    01166 {
    01167     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    01168
    01169         if(iPosition < 0) return E_INVALIDARG;
    01170         if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
    01171
    01172         CMediaType mt = m_pInput->CurrentMediaType();
    01173         const GUID& subtype = mt.subtype;
    01174         WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
    01175
    01176         if(GetSpeakerConfig(ac3) < 0 && (subtype == MEDIASUBTYPE_DOLBY_AC3 || subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3)
    01177         || GetSpeakerConfig(dts) < 0 && (subtype == MEDIASUBTYPE_DTS || subtype == MEDIASUBTYPE_WAVE_DTS))
    01178         {
    01179                 *pmt = CreateMediaTypeSPDIF();
    01180         }
    01181         else
    01182         {
    01183                 *pmt = CreateMediaType(GetSampleFormat(), wfe->nSamplesPerSec, min(2, wfe->nChannels));
    01184         }
    01185
    01186         return S_OK;
    01187 }
    01188
    01189 HRESULT CMpaDecFilter::StartStreaming()
    01190 {
    01191         HRESULT hr = __super::StartStreaming();
    01192         if(FAILED(hr)) return hr;
    01193
    01194         m_a52_state = a52_init(0);
    01195
    01196         m_dts_state = dts_init(0);
    01197
    01198         m_aac_state.init(m_pInput->CurrentMediaType());
    01199
    01200         mad_stream_init(&m_stream);
    01201         mad_frame_init(&m_frame);
    01202         mad_synth_init(&m_synth);
    01203         mad_stream_options(&m_stream, 0/*options*/);
    01204
    01205         m_ps2_state.reset();
    01206
    01207         m_fDiscontinuity = false;
    01208
    01209         m_sample_max = 0.1f;
    01210
    01211         return S_OK;
    01212 }
    01213
    01214 HRESULT CMpaDecFilter::StopStreaming()
    01215 {
    01216         a52_free(m_a52_state);
    01217
    01218         dts_free(m_dts_state);
    01219
    01220         mad_synth_finish(&m_synth);
    01221         mad_frame_finish(&m_frame);
    01222         mad_stream_finish(&m_stream);
    01223
    01224         return __super::StopStreaming();
    01225 }
    01226
    01227 // IMpaDecFilter
    01228
    01229 STDMETHODIMP CMpaDecFilter::SetSampleFormat(SampleFormat sf)
    01230 {
    01231         CAutoLock cAutoLock(&m_csProps);
    01232         m_iSampleFormat = sf;
    01233         return S_OK;
    01234 }
    01235
    01236 STDMETHODIMP_(SampleFormat) CMpaDecFilter::GetSampleFormat()
    01237 {
    01238         CAutoLock cAutoLock(&m_csProps);
    01239         return m_iSampleFormat;
    01240 }
    01241
    01242 STDMETHODIMP CMpaDecFilter::SetNormalize(bool fNormalize)
    01243 {
    01244         CAutoLock cAutoLock(&m_csProps);
    01245         if(m_fNormalize != fNormalize) m_sample_max = 0.1f;
    01246         m_fNormalize = fNormalize;
    01247         return S_OK;
    01248 }
    01249
    01250 STDMETHODIMP_(bool) CMpaDecFilter::GetNormalize()
    01251 {
    01252         CAutoLock cAutoLock(&m_csProps);
    01253         return m_fNormalize;
    01254 }
    01255
    01256 STDMETHODIMP CMpaDecFilter::SetSpeakerConfig(enctype et, int sc)
    01257 {
    01258         CAutoLock cAutoLock(&m_csProps);
    01259         if(et >= 0 && et < etlast) m_iSpeakerConfig[et] = sc;
    01260         return S_OK;
    01261 }
    01262
    01263 STDMETHODIMP_(int) CMpaDecFilter::GetSpeakerConfig(enctype et)
    01264 {
    01265         CAutoLock cAutoLock(&m_csProps);
    01266         if(et >= 0 && et < etlast) return m_iSpeakerConfig[et];
    01267         return -1;
    01268 }
    01269
    01270 STDMETHODIMP CMpaDecFilter::SetDynamicRangeControl(enctype et, bool fDRC)
    01271 {
    01272         CAutoLock cAutoLock(&m_csProps);
    01273         if(et >= 0 && et < etlast) m_fDynamicRangeControl[et] = fDRC;
    01274         else return E_INVALIDARG;
    01275         return S_OK;
    01276 }
    01277
    01278 STDMETHODIMP_(bool) CMpaDecFilter::GetDynamicRangeControl(enctype et)
    01279 {
    01280         CAutoLock cAutoLock(&m_csProps);
    01281         if(et >= 0 && et < etlast) return m_fDynamicRangeControl[et];
    01282         return false;
    01283 }
    01284
    01285 STDMETHODIMP CMpaDecFilter::SetBoost(float boost)
    01286 {
    01287         CAutoLock cAutoLock(&m_csProps);
    01288         m_boost = max(boost, 1);
    01289         return S_OK;
    01290 }
    01291
    01292 STDMETHODIMP_(float) CMpaDecFilter::GetBoost()
    01293 {
    01294         CAutoLock cAutoLock(&m_csProps);
    01295         return m_boost;
    01296 }
    01297
    01298 //
    01299 // CMpaDecInputPin
    01300 //
    01301
    01302 CMpaDecInputPin::CMpaDecInputPin(CTransformFilter* pFilter, HRESULT* phr, LPWSTR pName)
    01303         : CDeCSSInputPin(NAME("CMpaDecInputPin"), pFilter, phr, pName)
    01304 {
    01305 }
    01306
    01307 //
    01308 // aac_state_t
    01309 //
    01310
    01311 aac_state_t::aac_state_t() : h(NULL), freq(0), channels(0) {open();}
    01312 aac_state_t::~aac_state_t() {close();}
    01313
    01314 bool aac_state_t::open()
    01315 {
    01316         close();
    01317         if(!(h = NeAACDecOpen())) return false;
    01318         NeAACDecConfigurationPtr c = NeAACDecGetCurrentConfiguration(h);
    01319         c->outputFormat = FAAD_FMT_FLOAT;
    01320         NeAACDecSetConfiguration(h, c);
    01321         return true;
    01322 }
    01323
    01324 void aac_state_t::close()
    01325 {
    01326         if(h) NeAACDecClose(h);
    01327         h = NULL;
    01328 }
    01329
    01330 bool aac_state_t::init(CMediaType& mt)
    01331 {
    01332         if(mt.subtype != MEDIASUBTYPE_AAC && mt.subtype != MEDIASUBTYPE_MP4A) return(true); // nothing to do
    01333         open();
    01334         WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
    01335         return !NeAACDecInit2(h, (BYTE*)(wfe+1), wfe->cbSize, &freq, &channels);
    01336 }