~ubuntu-branches/debian/wheezy/vlc/wheezy

« back to all changes in this revision

Viewing changes to extras/faad2/CoreAAC/CoreAAC.cpp

Tags: upstream-0.7.2.final
ImportĀ upstreamĀ versionĀ 0.7.2.final

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * CoreAAC - AAC DirectShow Decoder Filter
 
3
 *
 
4
 * Modification to decode AAC without ADTS and multichannel support
 
5
 * (c) 2003 christophe.paris@free.fr
 
6
 *
 
7
 * Under section 8 of the GNU General Public License, the copyright
 
8
 * holders of CoreAAC explicitly forbid distribution in the following
 
9
 * countries:
 
10
 * - Japan
 
11
 * - United States of America 
 
12
 *
 
13
 *
 
14
 * AAC DirectShow Decoder Filter
 
15
 * Copyright (C) 2003 Robert Cioch
 
16
 *
 
17
 * This program is free software; you can redistribute it and/or modify
 
18
 * it under the terms of the GNU General Public License as published by
 
19
 * the Free Software Foundation; either version 2 of the License, or
 
20
 * (at your option) any later version.
 
21
 *
 
22
 * This program is distributed in the hope that it will be useful,
 
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
25
 * GNU General Public License for more details.
 
26
 *
 
27
 * You should have received a copy of the GNU General Public License
 
28
 * along with this program; if not, write to the Free Software 
 
29
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
30
 *
 
31
 */
 
32
 
 
33
 
 
34
#include <windows.h>
 
35
#include <streams.h>
 
36
#include <initguid.h>
 
37
#include <olectl.h>
 
38
#include <transfrm.h>
 
39
 
 
40
#include <mmreg.h>
 
41
#include <ks.h>
 
42
#include <ksmedia.h>
 
43
 
 
44
#include <stdio.h>
 
45
 
 
46
#include "AACProfilesName.h"
 
47
#include "ICoreAAC.h"
 
48
#include "CoreAACGUID.h"
 
49
#include "CoreAACInfoProp.h"
 
50
#include "CoreAACAboutProp.h"
 
51
#include "CoreAAC.h"
 
52
 
 
53
// ============================================================================
 
54
//  Registration setup stuff
 
55
 
 
56
AMOVIESETUP_MEDIATYPE sudInputType[] =
 
57
{
 
58
        { &MEDIATYPE_Audio, &MEDIASUBTYPE_AAC }
 
59
};
 
60
 
 
61
AMOVIESETUP_MEDIATYPE sudOutputType[] =
 
62
{
 
63
        { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }
 
64
};
 
65
 
 
66
AMOVIESETUP_PIN sudPins[] =
 
67
{
 
68
        { L"Input",
 
69
                FALSE,                                                  // bRendered
 
70
                FALSE,                                                  // bOutput
 
71
                FALSE,                                                  // bZero
 
72
                FALSE,                                                  // bMany
 
73
                &CLSID_NULL,                                    // clsConnectsToFilter
 
74
                NULL,                                                   // ConnectsToPin
 
75
                NUMELMS(sudInputType),                  // Number of media types
 
76
                sudInputType
 
77
        },
 
78
        { L"Output",
 
79
                FALSE,                                                  // bRendered
 
80
                TRUE,                                                   // bOutput
 
81
                FALSE,                                                  // bZero
 
82
                FALSE,                                                  // bMany
 
83
                &CLSID_NULL,                                    // clsConnectsToFilter
 
84
                NULL,                                                   // ConnectsToPin
 
85
                NUMELMS(sudOutputType),                 // Number of media types
 
86
                sudOutputType
 
87
        }
 
88
};
 
89
 
 
90
AMOVIESETUP_FILTER sudDecoder =
 
91
{
 
92
        &CLSID_DECODER,
 
93
        L"CoreAAC Audio Decoder",
 
94
        MERIT_PREFERRED,
 
95
        NUMELMS(sudPins),
 
96
        sudPins
 
97
};
 
98
 
 
99
// ============================================================================
 
100
// COM Global table of objects in this dll
 
101
 
 
102
CFactoryTemplate g_Templates[] = 
 
103
{
 
104
  { L"CoreAAC Audio Decoder", &CLSID_DECODER, CCoreAACDecoder::CreateInstance, NULL, &sudDecoder },
 
105
  { L"CoreAAC Audio Decoder Info", &CLSID_CoreAACInfoProp, CCoreAACInfoProp::CreateInstance, NULL, NULL},
 
106
  { L"CoreAAC Audio Decoder About", &CLSID_CoreAACAboutProp, CCoreAACAboutProp::CreateInstance, NULL, NULL},
 
107
};
 
108
 
 
109
// Count of objects listed in g_cTemplates
 
110
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
 
111
 
 
112
// ============================================================================
 
113
 
 
114
STDAPI DllRegisterServer()
 
115
{
 
116
        return AMovieDllRegisterServer2(TRUE);
 
117
}
 
118
 
 
119
// ----------------------------------------------------------------------------
 
120
 
 
121
STDAPI DllUnregisterServer()
 
122
{
 
123
        return AMovieDllRegisterServer2(FALSE);
 
124
}
 
125
 
 
126
// ----------------------------------------------------------------------------
 
127
 
 
128
// The streams.h DLL entrypoint.
 
129
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
 
130
 
 
131
// The entrypoint required by the MSVC runtimes. This is used instead
 
132
// of DllEntryPoint directly to ensure global C++ classes get initialised.
 
133
BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) {
 
134
        
 
135
    return DllEntryPoint(reinterpret_cast<HINSTANCE>(hDllHandle), dwReason, lpreserved);
 
136
}
 
137
 
 
138
// ----------------------------------------------------------------------------
 
139
 
 
140
CUnknown *WINAPI CCoreAACDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
 
141
{
 
142
        CCoreAACDecoder *pNewObject = new CCoreAACDecoder(punk, phr);
 
143
        if (!pNewObject)
 
144
                *phr = E_OUTOFMEMORY;
 
145
        return pNewObject;
 
146
}
 
147
 
 
148
// ----------------------------------------------------------------------------
 
149
 
 
150
void SaveInt(char* keyname, int value)
 
151
{
 
152
        HKEY hKey;
 
153
        DWORD dwDisp;
 
154
        if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,
 
155
                "Software\\CoreAAC", 0, "REG_SZ",
 
156
                REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp))
 
157
        {
 
158
                DWORD dwSize = sizeof(DWORD);
 
159
                RegSetValueEx(hKey, keyname, 0, REG_DWORD, (CONST BYTE*)&value, dwSize);
 
160
                RegCloseKey(hKey);
 
161
        }
 
162
}
 
163
 
 
164
int LoadInt(char* keyname, int default_value)
 
165
{
 
166
        HKEY hKey;
 
167
        int result = default_value;
 
168
        
 
169
        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
 
170
                "Software\\CoreAAC", 0, KEY_READ, &hKey))
 
171
        {
 
172
                DWORD dwTmp = 0;
 
173
                DWORD dwcbData = sizeof(DWORD);
 
174
                if(RegQueryValueEx(hKey, keyname, NULL, NULL, (LPBYTE) &dwTmp, &dwcbData) == ERROR_SUCCESS)
 
175
                {
 
176
                        result = dwTmp;
 
177
                }
 
178
                RegCloseKey(hKey);
 
179
        }
 
180
        return result;
 
181
}
 
182
 
 
183
// ----------------------------------------------------------------------------
 
184
 
 
185
CCoreAACDecoder::CCoreAACDecoder(LPUNKNOWN lpunk, HRESULT *phr) :
 
186
        CTransformFilter(NAME("CoreAAC Audio Decoder"), lpunk, CLSID_DECODER),
 
187
        m_decHandle(NULL),
 
188
        m_decoderSpecificLen(0),
 
189
        m_decoderSpecific(NULL),
 
190
        m_Channels(0),
 
191
        m_SamplesPerSec(0),
 
192
        m_BitsPerSample(0),
 
193
        m_Bitrate(0),
 
194
        m_brCalcFrames(0),
 
195
        m_brBytesConsumed(0),
 
196
        m_DecodedFrames(0),
 
197
        m_OutputBuffLen(0),
 
198
        m_DownMatrix(false)
 
199
{
 
200
        NOTE("CCoreAACDecoder::CCoreAACDecoder");
 
201
 
 
202
        m_ProfileName[0] = '\0';
 
203
        m_DownMatrix = LoadInt("DownMatrix", TRUE) ? true : false;      
 
204
}
 
205
 
 
206
// ----------------------------------------------------------------------------
 
207
 
 
208
CCoreAACDecoder::~CCoreAACDecoder()
 
209
{
 
210
        NOTE("CCoreAACDecoder::~CCoreAACDecoder");
 
211
 
 
212
        SaveInt("DownMatrix",m_DownMatrix);
 
213
 
 
214
        if(m_decHandle)
 
215
        {
 
216
                faacDecClose(m_decHandle);
 
217
                m_decHandle = NULL;
 
218
        }
 
219
        if(m_decoderSpecific)
 
220
        {
 
221
                delete m_decoderSpecific;
 
222
                m_decoderSpecific = NULL;
 
223
        }
 
224
}
 
225
 
 
226
// ----------------------------------------------------------------------------
 
227
 
 
228
STDMETHODIMP CCoreAACDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv)
 
229
{
 
230
        if(riid == IID_ICoreAACDec)
 
231
                return GetInterface((ICoreAACDec *)this, ppv);  
 
232
        else if (riid == IID_ISpecifyPropertyPages)
 
233
                return GetInterface((ISpecifyPropertyPages *)this, ppv);
 
234
        else
 
235
                return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
 
236
}
 
237
 
 
238
// ----------------------------------------------------------------------------
 
239
// property pages
 
240
 
 
241
STDMETHODIMP CCoreAACDecoder::GetPages(CAUUID *pPages)
 
242
{
 
243
        pPages->cElems = 2;
 
244
        pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
 
245
        if (!pPages->pElems)
 
246
                return E_OUTOFMEMORY;
 
247
 
 
248
        pPages->pElems[0] = CLSID_CoreAACInfoProp;
 
249
        pPages->pElems[1] = CLSID_CoreAACAboutProp;
 
250
 
 
251
        return S_OK;
 
252
}
 
253
 
 
254
// ============================================================================
 
255
// accept only aac audio wrapped in waveformat
 
256
 
 
257
HRESULT CCoreAACDecoder::CheckInputType(const CMediaType *mtIn)
 
258
{
 
259
        if (*mtIn->Type() != MEDIATYPE_Audio || *mtIn->Subtype() != MEDIASUBTYPE_AAC)
 
260
                return VFW_E_TYPE_NOT_ACCEPTED;
 
261
 
 
262
        if (*mtIn->FormatType() != FORMAT_WaveFormatEx)
 
263
                return VFW_E_TYPE_NOT_ACCEPTED;
 
264
 
 
265
        WAVEFORMATEX *wfex = (WAVEFORMATEX *)mtIn->Format();
 
266
        if (wfex->wFormatTag != WAVE_FORMAT_AAC)
 
267
                return VFW_E_TYPE_NOT_ACCEPTED;
 
268
 
 
269
        if(wfex->cbSize < 2)
 
270
                return VFW_E_TYPE_NOT_ACCEPTED;
 
271
 
 
272
        m_decoderSpecificLen = wfex->cbSize;
 
273
        if(m_decoderSpecific)
 
274
        {
 
275
                delete m_decoderSpecific;
 
276
                m_decoderSpecific = NULL;
 
277
        }
 
278
        m_decoderSpecific = new unsigned char[m_decoderSpecificLen];
 
279
        
 
280
        // Keep decoderSpecific initialization data (appended to the WAVEFORMATEX struct)
 
281
        memcpy(m_decoderSpecific,(char*)wfex+sizeof(WAVEFORMATEX), m_decoderSpecificLen);
 
282
        
 
283
        return S_OK;
 
284
}
 
285
 
 
286
// ============================================================================
 
287
// propose proper waveformat
 
288
 
 
289
HRESULT CCoreAACDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
 
290
{
 
291
        if (!m_pInput->IsConnected())
 
292
        {
 
293
                return E_UNEXPECTED;
 
294
        }
 
295
        
 
296
        if (iPosition < 0)
 
297
        {
 
298
                return E_INVALIDARG;
 
299
        }
 
300
        
 
301
        if (iPosition > 0)
 
302
        {
 
303
                return VFW_S_NO_MORE_ITEMS;
 
304
        }
 
305
        
 
306
        // Some drivers don't like WAVEFORMATEXTENSIBLE when channels are <= 2 so
 
307
        // we fall back to a classic WAVEFORMATEX struct in this case 
 
308
        
 
309
        WAVEFORMATEXTENSIBLE wfex;
 
310
        ZeroMemory(&wfex, sizeof(WAVEFORMATEXTENSIBLE));
 
311
        
 
312
        wfex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
 
313
        wfex.Format.wFormatTag = (m_Channels <= 2) ? WAVE_FORMAT_PCM : WAVE_FORMAT_EXTENSIBLE;
 
314
        wfex.Format.cbSize = (m_Channels <= 2) ? 0 : sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
 
315
        wfex.Format.nChannels = (unsigned short)m_Channels;
 
316
        wfex.Format.nSamplesPerSec = (unsigned short)m_SamplesPerSec;
 
317
        wfex.Format.wBitsPerSample = m_BitsPerSample;
 
318
        wfex.Format.nBlockAlign = (unsigned short)((wfex.Format.nChannels * wfex.Format.wBitsPerSample) / 8);
 
319
        wfex.Format.nAvgBytesPerSec = wfex.Format.nSamplesPerSec * wfex.Format.nBlockAlign;
 
320
        switch(m_Channels)
 
321
        {
 
322
        case 1:
 
323
                wfex.dwChannelMask = KSAUDIO_SPEAKER_MONO;              
 
324
                break;
 
325
        case 2:
 
326
                wfex.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
 
327
                break;
 
328
        case 3:
 
329
                wfex.dwChannelMask = KSAUDIO_SPEAKER_STEREO | SPEAKER_FRONT_CENTER;
 
330
                break;
 
331
        case 4:
 
332
                //wfex.dwChannelMask = KSAUDIO_SPEAKER_QUAD;
 
333
                wfex.dwChannelMask = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER);
 
334
                break;
 
335
        case 5:
 
336
                wfex.dwChannelMask = KSAUDIO_SPEAKER_QUAD | SPEAKER_FRONT_CENTER;
 
337
                break;
 
338
        case 6:
 
339
                wfex.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
 
340
                break;
 
341
        default:
 
342
                wfex.dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT; // XXX : or SPEAKER_ALL ??
 
343
                break;
 
344
        }
 
345
        wfex.Samples.wValidBitsPerSample = wfex.Format.wBitsPerSample;  
 
346
        
 
347
        mtOut->SetType(&MEDIATYPE_Audio);
 
348
        mtOut->SetSubtype(&MEDIASUBTYPE_PCM);
 
349
        mtOut->SetFormatType(&FORMAT_WaveFormatEx);
 
350
        mtOut->SetFormat( (BYTE*) &wfex, sizeof(WAVEFORMATEX)+wfex.Format.cbSize);
 
351
        mtOut->SetTemporalCompression(FALSE);
 
352
        
 
353
        return S_OK;
 
354
}
 
355
 
 
356
// ----------------------------------------------------------------------------
 
357
 
 
358
HRESULT CCoreAACDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
 
359
{
 
360
        if (*mtOut->Type() != MEDIATYPE_Audio   ||
 
361
                *mtOut->Subtype() != MEDIASUBTYPE_PCM ||
 
362
                *mtOut->FormatType() != FORMAT_WaveFormatEx)
 
363
        {
 
364
                return VFW_E_TYPE_NOT_ACCEPTED;
 
365
        }
 
366
        
 
367
        return S_OK; 
 
368
}
 
369
 
 
370
// ----------------------------------------------------------------------------
 
371
 
 
372
// 960 for LD or else 1024 (expanded to 2048 for HE-AAC)
 
373
#define MAXFRAMELEN 2048
 
374
 
 
375
HRESULT CCoreAACDecoder::DecideBufferSize(IMemAllocator *pAllocator, ALLOCATOR_PROPERTIES *pProperties)
 
376
{
 
377
        pProperties->cBuffers = 8;
 
378
        m_OutputBuffLen = m_Channels * MAXFRAMELEN * sizeof(short);
 
379
        pProperties->cbBuffer = m_OutputBuffLen;
 
380
        
 
381
        NOTE1("CCoreAACDecoder::DecideBufferSize %d", pProperties->cbBuffer);
 
382
 
 
383
        ALLOCATOR_PROPERTIES Actual;
 
384
        HRESULT hr = pAllocator->SetProperties(pProperties, &Actual);
 
385
        if(FAILED(hr))
 
386
                return hr;
 
387
 
 
388
        if (Actual.cbBuffer < pProperties->cbBuffer || Actual.cBuffers < pProperties->cBuffers)
 
389
                return E_INVALIDARG;
 
390
 
 
391
        return S_OK;
 
392
}
 
393
 
 
394
// ----------------------------------------------------------------------------
 
395
 
 
396
HRESULT CCoreAACDecoder::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
 
397
{
 
398
        HRESULT hr = CTransformFilter::CompleteConnect(direction, pReceivePin);
 
399
        
 
400
        if(direction == PINDIR_INPUT)
 
401
        {
 
402
                if(m_decHandle)
 
403
                {
 
404
                        faacDecClose(m_decHandle);
 
405
                        m_decHandle = NULL;
 
406
                }
 
407
                m_decHandle = faacDecOpen();
 
408
 
 
409
        faacDecConfigurationPtr config;         
 
410
        config = faacDecGetCurrentConfiguration(m_decHandle);
 
411
                config->downMatrix = m_DownMatrix;
 
412
        faacDecSetConfiguration(m_decHandle, config);
 
413
 
 
414
                // Initialize the decoder
 
415
                unsigned long SamplesPerSec = 0;
 
416
                unsigned char Channels = 0;
 
417
                if(faacDecInit2(m_decHandle, m_decoderSpecific, m_decoderSpecificLen,
 
418
                        &SamplesPerSec, &Channels) < 0)
 
419
                {
 
420
                        return E_FAIL;
 
421
                }
 
422
                
 
423
                if(m_DownMatrix)
 
424
                {
 
425
                        Channels = 2; // TODO : check with mono
 
426
                }
 
427
 
 
428
                mp4AudioSpecificConfig info;
 
429
                AudioSpecificConfig(m_decoderSpecific,m_decoderSpecificLen,&info);
 
430
                
 
431
                wsprintf(m_ProfileName,"%s%s",
 
432
                        ObjectTypesNameTable[info.objectTypeIndex],
 
433
#if 0
 
434
                        info.sbr_present_flag ?
 
435
#else
 
436
                        false ?
 
437
#endif
 
438
                        "+SBR" :
 
439
                        ""
 
440
                        );
 
441
 
 
442
                m_Channels = Channels;
 
443
                m_SamplesPerSec = SamplesPerSec;
 
444
                m_BitsPerSample = 16; // we always decode to the default 16 bits (we could add 24,32,float)
 
445
                
 
446
                m_brCalcFrames = 0;
 
447
                m_brBytesConsumed = 0;
 
448
                m_DecodedFrames = 0;
 
449
        }
 
450
 
 
451
        return hr;
 
452
}
 
453
 
 
454
// ----------------------------------------------------------------------------
 
455
 
 
456
HRESULT CCoreAACDecoder::StartStreaming(void)
 
457
{
 
458
        m_brCalcFrames = 0;
 
459
        m_brBytesConsumed = 0;
 
460
        m_DecodedFrames = 0;
 
461
        return CTransformFilter::StartStreaming();
 
462
}
 
463
 
 
464
// ----------------------------------------------------------------------------
 
465
 
 
466
HRESULT CCoreAACDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
 
467
{
 
468
        if (m_State == State_Stopped)
 
469
        {       
 
470
                pOut->SetActualDataLength(0);
 
471
                return S_OK;
 
472
        }
 
473
 
 
474
        if(pIn->IsPreroll() == S_OK)
 
475
        {
 
476
                return S_FALSE;
 
477
        }
 
478
 
 
479
        // Decode the sample data
 
480
        DWORD ActualDstLength;
 
481
        BYTE *pSrc, *pDst;
 
482
        DWORD SrcLength = pIn->GetActualDataLength();
 
483
        DWORD DstLength = pOut->GetSize();
 
484
        HRESULT hr;
 
485
        hr = pIn->GetPointer(&pSrc);
 
486
        if(hr != S_OK)
 
487
                return hr;
 
488
        hr = pOut->GetPointer(&pDst);
 
489
        if(hr != S_OK)
 
490
                return hr;
 
491
        
 
492
        if(!pSrc || !pDst || (DstLength < m_OutputBuffLen))
 
493
                return S_FALSE;  
 
494
 
 
495
        // Decode data
 
496
        // (use our buffer calculated len, as the Waveout renderer seems to report wrongly a bigger size)       
 
497
        if(!Decode(pSrc, SrcLength, pDst, m_OutputBuffLen, &ActualDstLength))
 
498
                return S_FALSE;
 
499
 
 
500
        NOTE3("Transform: %u->%u (%u)\n", SrcLength, ActualDstLength, m_OutputBuffLen);
 
501
 
 
502
        // Copy the actual data length
 
503
        pOut->SetActualDataLength(ActualDstLength);
 
504
        return S_OK;
 
505
}
 
506
 
 
507
// ----------------------------------------------------------------------------
 
508
 
 
509
// AAC order : C, L, R, L", R", LFE
 
510
// DShow order : L, R, C, LFE, L", R"
 
511
 
 
512
const int MAXCHANNELS = 6;
 
513
const int chmap[MAXCHANNELS][MAXCHANNELS+1] = {
 
514
        // first column tell us if we need to remap
 
515
        {  0, },                                        // mono
 
516
        {  0, },                                        // l, r
 
517
        {  1, 1, 2, 0, },                       // c ,l, r -> l, r, c
 
518
        {  1, 1, 2, 0, 3, },            // c, l, r, bc -> l, r, c, bc
 
519
        {  1, 1, 2, 0, 3, 4, },         // c, l, r, bl, br -> l, r, c, bl, br
 
520
        {  1, 1, 2, 0, 5, 3, 4 }        // c, l, r, bl, br, lfe -> l, r, c, lfe, bl, br
 
521
};
 
522
 
 
523
// ----------------------------------------------------------------------------
 
524
 
 
525
bool CCoreAACDecoder::Decode(BYTE *pSrc, DWORD SrcLength, BYTE *pDst, DWORD DstLength, DWORD *ActualDstLength)
 
526
{
 
527
        faacDecFrameInfo frameInfo;
 
528
        short *outsamples = (short *)faacDecDecode(m_decHandle, &frameInfo, pSrc, DstLength);
 
529
 
 
530
        if (frameInfo.error)
 
531
        {
 
532
                NOTE2("CCoreAACDecoder::Decode Error %d [%s]\n", 
 
533
                        frameInfo.error, faacDecGetErrorMessage(frameInfo.error));
 
534
                return false;
 
535
        }
 
536
 
 
537
        m_brCalcFrames++;
 
538
        m_DecodedFrames++;
 
539
        m_brBytesConsumed += SrcLength;
 
540
 
 
541
        if(m_brCalcFrames == 43)
 
542
        {
 
543
                m_Bitrate = (int)((m_brBytesConsumed * 8) / (m_DecodedFrames / 43.07));
 
544
                m_brCalcFrames = 0;
 
545
        }
 
546
 
 
547
        if (!frameInfo.error && outsamples)
 
548
        {
 
549
                int channelidx = frameInfo.channels-1;
 
550
                if(chmap[channelidx][0])
 
551
                {
 
552
                        // dshow remapping
 
553
                        short *dstBuffer = (short*)pDst;
 
554
                        for(unsigned int i = 0;
 
555
                            i < frameInfo.samples;
 
556
                                i += frameInfo.channels, outsamples += frameInfo.channels)
 
557
                        {
 
558
                                for(unsigned int j=1; j <= frameInfo.channels; j++)
 
559
                                {
 
560
                                        *dstBuffer++ = outsamples[chmap[channelidx][j]];
 
561
                                }                               
 
562
                        }
 
563
                }
 
564
                else
 
565
                {
 
566
                        memcpy(pDst, outsamples, frameInfo.samples * sizeof(short));
 
567
                }
 
568
        }
 
569
        else
 
570
                return false;
 
571
 
 
572
        *ActualDstLength = frameInfo.samples * sizeof(short);
 
573
        return true;
 
574
}
 
575
 
 
576
// ============================================================================
 
577
// ICoreAAC
 
578
// ============================================================================
 
579
 
 
580
STDMETHODIMP CCoreAACDecoder::get_ProfileName(char** name)
 
581
{
 
582
        CheckPointer(name,E_POINTER);
 
583
        *name = m_ProfileName;
 
584
        return S_OK;
 
585
}
 
586
 
 
587
STDMETHODIMP CCoreAACDecoder::get_SampleRate(int* sample_rate)
 
588
{
 
589
        CheckPointer(sample_rate,E_POINTER);
 
590
        *sample_rate = m_SamplesPerSec;
 
591
        return S_OK;
 
592
}
 
593
 
 
594
STDMETHODIMP CCoreAACDecoder::get_Channels(int *channels)
 
595
{
 
596
        CheckPointer(channels,E_POINTER);
 
597
        *channels = m_Channels;
 
598
        return S_OK;
 
599
}
 
600
 
 
601
STDMETHODIMP CCoreAACDecoder::get_BitsPerSample(int *bits_per_sample)
 
602
{
 
603
        CheckPointer(bits_per_sample,E_POINTER);
 
604
        *bits_per_sample = m_BitsPerSample;
 
605
        return S_OK;
 
606
}
 
607
 
 
608
STDMETHODIMP CCoreAACDecoder::get_Bitrate(int *bitrate)
 
609
{
 
610
        CheckPointer(bitrate,E_POINTER);
 
611
        *bitrate = m_Bitrate;
 
612
        return S_OK;
 
613
}
 
614
 
 
615
STDMETHODIMP CCoreAACDecoder::get_FramesDecoded(unsigned int *frames_decoded)
 
616
{
 
617
        CheckPointer(frames_decoded,E_POINTER);
 
618
        *frames_decoded = m_DecodedFrames;
 
619
        return S_OK;
 
620
}
 
621
 
 
622
STDMETHODIMP CCoreAACDecoder::get_DownMatrix(bool *down_matrix)
 
623
{
 
624
        CheckPointer(down_matrix,E_POINTER);
 
625
        *down_matrix = m_DownMatrix;
 
626
        return S_OK;
 
627
}
 
628
 
 
629
STDMETHODIMP CCoreAACDecoder::set_DownMatrix(bool down_matrix)
 
630
{
 
631
        m_DownMatrix = down_matrix;
 
632
        return S_OK;
 
633
}
 
634
 
 
635
// ============================================================================
 
636
 
 
637
 
 
638