00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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, 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);
00119 }
00120
00121 #endif
00122
00123
00124
00125
00126
00127
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},
00138 {1, {0,-1,-1,-1,-1,-1}, 0},
00139 {2, {0, 1,-1,-1,-1,-1}, 0},
00140 {3, {0, 2, 1,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER},
00141 {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_CENTER},
00142 {4, {0, 2, 1, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_CENTER},
00143 {4, {0, 1, 2, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},
00144 {5, {0, 2, 1, 3, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},
00145 {1, {0,-1,-1,-1,-1,-1}, 0},
00146 {1, {0,-1,-1,-1,-1,-1}, 0},
00147 {2, {0, 1,-1,-1,-1,-1}, 0},
00148
00149 {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00150 {2, {1, 0,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},
00151 {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00152 {4, {1, 3, 2, 0,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},
00153 {4, {1, 2, 0, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER},
00154 {5, {1, 3, 2, 0, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER},
00155 {5, {1, 2, 0, 3, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},
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},
00157 {2, {1, 0,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},
00158 {2, {1, 0,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},
00159 {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00160 },
00161 s_scmap_dts[2*10] =
00162 {
00163 {1, {0,-1,-1,-1,-1,-1}, 0},
00164 {2, {0, 1,-1,-1,-1,-1}, 0},
00165 {2, {0, 1,-1,-1,-1,-1}, 0},
00166 {2, {0, 1,-1,-1,-1,-1}, 0},
00167 {2, {0, 1,-1,-1,-1,-1}, 0},
00168 {3, {1, 2, 0,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER},
00169 {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_CENTER},
00170 {4, {1, 2, 0, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_CENTER},
00171 {4, {0, 1, 2, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},
00172 {5, {1, 2, 0, 3, 4,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},
00173
00174 {2, {0, 1,-1,-1,-1,-1}, SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},
00175 {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00176 {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00177 {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00178 {3, {0, 1, 2,-1,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY},
00179 {4, {1, 2, 0, 3,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},
00180 {4, {0, 1, 3, 2,-1,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER},
00181 {5, {1, 2, 0, 4, 3,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER},
00182 {5, {0, 1, 4, 2, 3,-1}, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},
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},
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
00284 if(FAILED(hr)) {TRACE(_T("mpa: disc. w/o timestamp\n")); return S_OK;}
00285 m_rtStart = rtStart;
00286 }
00287
00288 if(SUCCEEDED(hr) && abs((int)(m_rtStart - rtStart)) > 1000000)
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
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;
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
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
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
00540 if(info.error) m_aac_state.init(m_pInput->CurrentMediaType());
00541 if(!src || info.samples == 0) return S_OK;
00542
00543
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
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
00791
00792
00793 continue;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
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
00877 if(rtStart < 0 )
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
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
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
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)
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)
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
01151 pProperties->cbBuffer = 48000*6*(32/8)/10;
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);
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
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
01300
01301
01302 CMpaDecInputPin::CMpaDecInputPin(CTransformFilter* pFilter, HRESULT* phr, LPWSTR pName)
01303 : CDeCSSInputPin(NAME("CMpaDecInputPin"), pFilter, phr, pName)
01304 {
01305 }
01306
01307
01308
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);
01333 open();
01334 WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.Format();
01335 return !NeAACDecInit2(h, (BYTE*)(wfe+1), wfe->cbSize, &freq, &channels);
01336 }