Media (Intel® oneAPI Video Processing Library, Intel Media SDK)
Access community support with transcoding, decoding, and encoding in applications using media tools from Intel. This includes Intel® oneAPI Video Processing Library and Intel® Media SDK.
2965 Discussions

Need some help on developing AAC Encoder Filter using Audio Processing API

Zheng_L_
Beginner
137 Views

I write an AAC Audio Encoder DirectShow Filter using the audio processing api implemented in Intel Media SDK 2016 R2,but the performance of my filter is very bad compare to the "imc_aac_enc_ds.dll" encoder filter shipped with Media SDK Samples,my encoder filter only reach 1/3 speed of "imc_aac_enc_ds.dll" encoder filter;I don't know why my filter's performance was so bad,so I post some source code of my filter below,and please tell me where is the problem of my code,thanks!

// the function to create Audio Encoder
BOOL CMfxAudioEncFilter::CreateAudioEncoder()
{
    assert(m_pInput->IsConnected());
    if(!m_pInput->IsConnected())
        return FALSE;

    DestroyAudioEncoder();

    mfxStatus sts;

    m_audioSession = new MFXAudioSession();

    mfxVersion ver = { {1,1} };
    sts = m_audioSession->Init(MFX_IMPL_AUDIO|MFX_IMPL_SOFTWARE,&ver);
    assert(sts == MFX_ERR_NONE);
    if(sts != MFX_ERR_NONE)
        return FALSE;
    mfxVersion qVer;
    sts = m_audioSession->QueryVersion(&qVer);
    assert(sts == MFX_ERR_NONE);
    TRACE(_T("CMfxAudioEncFilter::CreateAudioEncoder() -> MSDK Version is V%d.%d"),qVer.Major,qVer.Minor);

    m_audioEncoder = new MFXAudioENCODE(*m_audioSession);

    mfxAudioParam initPar;
    memset(&initPar,0,sizeof(mfxAudioParam));
    initPar.AsyncDepth = 1;
    initPar.mfx.CodecId = MFX_CODEC_AAC;
    initPar.mfx.CodecProfile = MFX_PROFILE_AAC_LC;
    initPar.mfx.CodecLevel = 0;
    initPar.mfx.BitPerSample = 16;    // input audio is 16bit;
    initPar.mfx.SampleFrequency = 44100;    // input audio is 44.1khz
    initPar.mfx.NumChannel = 2;    // input audio is 2 channels;
    initPar.mfx.Bitrate = 128000;    // 128kbps
    initPar.mfx.OutputFormat = MFX_AUDIO_AAC_ADTS;
    initPar.mfx.StereoMode = MFX_AUDIO_AAC_LR_STEREO;
    sts = m_audioEncoder->Query(&initPar,&initPar);
    assert(sts == MFX_ERR_NONE);
    if(sts != MFX_ERR_NONE)
        return FALSE;
    sts = m_audioEncoder->Init(&initPar);
    assert(sts == MFX_ERR_NONE);
    if(sts != MFX_ERR_NONE)
        return FALSE;
    memcpy(&m_EncInitPar,&initPar,sizeof(mfxAudioParam));    

    return TRUE;
}

// the function to do aac encoding, it is called from CTransformFilter::Transform();
BOOL CMfxAudioEncFilter::DoEncode(IMediaSample * pInSample,IMediaSample * pOutSample)
{
    mfxAudioFrame audioFrame;
    memset(&audioFrame,0,sizeof(mfxAudioFrame));
    audioFrame.BitPerSample = 16;
    audioFrame.NumChannels = 2;
    audioFrame.SampleFrequency = 44100;
    audioFrame.Locked = 0;
    REFERENCE_TIME tBeg,tEnd;
    HRESULT hr = pInSample->GetTime(&tBeg,&tEnd);
    assert(hr == S_OK);
    audioFrame.TimeStamp = ConvertDShowTimeToMfxTime(tBeg);
    pInSample->GetPointer(&audioFrame.Data);    
    audioFrame.DataLength = pInSample->GetActualDataLength();
    audioFrame.MaxLength = audioFrame.DataLength;
    
    mfxBitstream bs;
    memset(&bs,0,sizeof(mfxBitstream));
    pOutSample->GetPointer(&bs.Data);
    bs.MaxLength = pOutSample->GetSize();

    mfxSyncPoint syncp = NULL;
    mfxStatus sts = m_audioEncoder->EncodeFrameAsync(&audioFrame,&bs,&syncp);
    switch(sts)
    {
    case MFX_ERR_NONE:
        {
            sts = m_audioSession->SyncOperation(syncp,5000);    // wait encode done;
            if(sts == MFX_ERR_NONE)
            {
                // copy mfxBitstream to IMediaSample
                BYTE * pTargetBuff;
                pOutSample->GetPointer(&pTargetBuff);
                CopyMemory(pTargetBuff,bs.Data+bs.DataOffset,bs.DataLength);
                pOutSample->SetActualDataLength(bs.DataLength);
                REFERENCE_TIME tBeg=ConvertMfxTimeToDShowTime(bs.TimeStamp),tEnd=tBeg + (REFERENCE_TIME)((double)bs.DataLength/(double)m_aiInput.nAvgBytesPerSec*UNITS);
                pOutSample->SetTime(&tBeg,&tEnd);
            }
            else
            {
                assert(FALSE);
            }
        }
        break;
    case MFX_ERR_MORE_BITSTREAM:
        assert(FALSE);
        break;
    case MFX_ERR_MORE_DATA:
        assert(FALSE);
        break;
    default:
        assert(FALSE);
        return FALSE;
    }

    return TRUE;
}

 

0 Kudos
0 Replies
Reply