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 }

Generated on Tue Dec 13 14:47:49 2005 for guliverkli by  doxygen 1.4.5