qtmobility/plugins/multimedia/symbian/openmaxal/mediarecorder/xarecordsessionimpl.cpp
changeset 4 90517678cc4f
child 11 06b8e2af4411
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/plugins/multimedia/symbian/openmaxal/mediarecorder/xarecordsessionimpl.cpp	Mon May 03 13:18:40 2010 +0300
@@ -0,0 +1,1260 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xarecordsessionimpl.h"
+#include "xarecordsessioncommon.h"
+
+_LIT8(K8WAVMIMETYPE, "audio/x-wav");
+
+/*
+ * These codec names are not part of AL. Hence we need to define names here.
+ * */
+_LIT(KAUDIOCODECPCM, "pcm");
+_LIT(KAUDIOCODECAMR, "amr");
+_LIT(KAUDIOCODECAAC, "aac");
+
+_LIT(KCONTAINERWAV, "wav");
+_LIT(KCONTAINERWAVDESC, "wav container");
+_LIT(KCONTAINERAMR, "amr-nb");
+_LIT(KCONTAINERAMRDESC, "amr-nb File format");
+_LIT(KCONTAINERMP4, "mp4");
+_LIT(KCONTAINERMP4DESC, "mp4 container");
+
+const TUint KRecordPosUpdatePeriod = 1000;
+const TUint KMilliToHz = 1000;
+const TUint KMaxNameLength = 256;
+
+
+/* Local functions for callback registation */
+void cbXAObjectItf(
+            XAObjectItf caller,
+            const void *pContext,
+            XAuint32 event,
+            XAresult result,
+            XAuint32 param,
+            void *pInterface);
+
+void cbXARecordItf(
+            XARecordItf caller,
+            void *pContext,
+            XAuint32 event);
+
+void cbXAAvailableAudioInputsChanged(
+            XAAudioIODeviceCapabilitiesItf caller,
+            void *pContext,
+            XAuint32 deviceID,
+            XAint32 numInputs,
+            XAboolean isNew);
+
+XARecordSessionImpl::XARecordSessionImpl(XARecordObserver &parent)
+:m_Parent(parent),
+m_EOEngine(NULL),
+m_MORecorder(NULL),
+m_RecordItf(NULL),
+m_AudioEncItf(NULL),
+m_WAVMime(NULL),
+m_URIName(NULL),
+m_InputDeviceId(0),
+m_ContainerType(0),
+m_BitRate(0),
+m_RateControl(0),
+m_ChannelsOut(0),
+m_SampleRate(0),
+m_AudioIODevCapsItf(NULL),
+m_AudioInputDeviceNames(NULL),
+m_DefaultAudioInputDeviceNames(NULL),
+m_AudioEncCapsItf(NULL)
+{
+    TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+XARecordSessionImpl::~XARecordSessionImpl()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    if (m_MORecorder)
+        (*m_MORecorder)->Destroy(m_MORecorder);
+
+    if (m_EOEngine)
+        (*m_EOEngine)->Destroy(m_EOEngine);
+
+    delete m_WAVMime;
+    delete m_URIName;
+
+    m_InputDeviceIDs.Close();
+    if (m_AudioInputDeviceNames)
+        m_AudioInputDeviceNames->Reset();
+    delete m_AudioInputDeviceNames;
+    m_DefaultInputDeviceIDs.Close();
+    if (m_DefaultAudioInputDeviceNames)
+        m_DefaultAudioInputDeviceNames->Reset();
+    delete m_DefaultAudioInputDeviceNames;
+    m_EncoderIds.Close();
+    m_EncoderNames.Close();
+    m_ContainerNames.Close();
+    m_ContainerDescs.Close();
+
+    TRACE_FUNCTION_EXIT;
+}
+
+TInt32 XARecordSessionImpl::postConstruct()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    XAEngineOption engineOption[] = { (XAuint32) XA_ENGINEOPTION_THREADSAFE, (XAuint32) XA_BOOLEAN_TRUE};
+
+    /* Create and realize Engine object */
+    TRACE_LOG(_L("XARecordSessionImpl: Creating Engine..."));
+    XAresult xa_result = xaCreateEngine (&m_EOEngine, 1, engineOption, 0, NULL, NULL);
+    TInt returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+    TRACE_LOG(_L("XARecordSessionImpl: Realizing engine..."));
+    xa_result = (*m_EOEngine)->Realize(m_EOEngine, XA_BOOLEAN_FALSE);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+    TRACE_LOG(_L("XARecordSessionImpl: OMX AL Engine realized successfully"));
+
+    XAEngineItf engineItf;
+    xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, XA_IID_ENGINE, (void**) &engineItf);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    xa_result = (*m_EOEngine)->GetInterface(m_EOEngine,
+                                         XA_IID_AUDIOIODEVICECAPABILITIES,
+                                         (void**) &m_AudioIODevCapsItf);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+    xa_result = (*m_AudioIODevCapsItf)->RegisterAvailableAudioInputsChangedCallback(
+                                        m_AudioIODevCapsItf,
+                                        cbXAAvailableAudioInputsChanged,
+                                        (void*)this);
+
+    xa_result = (*m_EOEngine)->GetInterface(
+                                 m_EOEngine,
+                                 XA_IID_AUDIOENCODERCAPABILITIES,
+                                 (void**) &m_AudioEncCapsItf);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    TRAP(returnValue, m_WAVMime = HBufC8::NewL(K8WAVMIMETYPE().Length() + 1));
+    RET_ERR_IF_ERR(returnValue);
+    TPtr8 ptr = m_WAVMime->Des();
+    ptr = K8WAVMIMETYPE(); // copy uri name into local variable
+    ptr.PtrZ(); // append zero terminator to end of URI
+
+    m_AudioInputDeviceNames = new CDesC16ArrayFlat(2);
+    if (m_AudioInputDeviceNames == NULL)
+        returnValue = KErrNoMemory;
+    RET_ERR_IF_ERR(returnValue);
+
+    m_DefaultAudioInputDeviceNames = new CDesC16ArrayFlat(2);
+    if (m_DefaultAudioInputDeviceNames == NULL)
+        returnValue = KErrNoMemory;
+    RET_ERR_IF_ERR(returnValue);
+
+    returnValue = initContainersList();
+    RET_ERR_IF_ERR(returnValue);
+    returnValue = initAudioEncodersList();
+    RET_ERR_IF_ERR(returnValue);
+    returnValue = initAudioInputDevicesList();
+    RET_ERR_IF_ERR(returnValue);
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::setURI(const TDesC &aURI)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    /* This function will only get called when aURI is different than m_URIName
+     * and only when recorder is in stopped state.
+     * If the recorder object was created for a different URI (than aURI), we
+     * need to tear it down here.
+     */
+    if (!m_URIName && m_MORecorder) {
+        (*m_MORecorder)->Destroy(m_MORecorder);
+        m_MORecorder = NULL;
+        m_RecordItf = NULL;
+    }
+
+    delete m_URIName;
+    m_URIName = NULL;
+    TRAPD(returnValue, m_URIName = HBufC8::NewL(aURI.Length()+1));
+    RET_ERR_IF_ERR(returnValue);
+
+    TPtr8 uriPtr = m_URIName->Des();
+     /* copy uri name into local variable */
+    uriPtr.Copy(aURI);
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::record()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TInt32 returnValue(KErrGeneral);
+    if (!m_MORecorder || !m_RecordItf) {
+        TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created"));
+        returnValue = createMediaRecorderObject();
+        RET_ERR_IF_ERR(returnValue);
+    }
+
+    returnValue = setEncoderSettingsToMediaRecorder();
+    RET_ERR_IF_ERR(returnValue);
+
+    XAuint32 state;
+    XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    if ((state == XA_RECORDSTATE_STOPPED)
+        || (state == XA_RECORDSTATE_PAUSED)) {
+        TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Recording..."));
+        xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_RECORDING);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+        TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Recording"));
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::pause()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TInt32 returnValue(KErrGeneral);
+    if (!m_MORecorder || !m_RecordItf) {
+        TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created"));
+        return returnValue;
+    }
+
+    XAuint32 state;
+    XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    if ((state == XA_RECORDSTATE_STOPPED)
+        || (state == XA_RECORDSTATE_RECORDING)) {
+        TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Paused..."));
+        xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_PAUSED);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+        TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Paused"));
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::stop()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TInt32 returnValue(KErrGeneral);
+    if (!m_MORecorder || !m_RecordItf) {
+        TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created"));
+        return returnValue;
+    }
+
+    XAuint32 state;
+    XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    if ((state == XA_RECORDSTATE_PAUSED)
+        || (state == XA_RECORDSTATE_RECORDING)) {
+        TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Stopped..."));
+        xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_STOPPED);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+        TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Stopped"));
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::duration(TInt64 &aDur)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TInt32 returnValue(KErrGeneral);
+
+    if (!m_MORecorder || !m_RecordItf) {
+        TRACE_LOG(_L("XARecordSessionImpl::Duration: MORecoder/RecordItf is not created"));
+        return returnValue;
+    }
+
+    XAmillisecond milliSec;
+    XAresult xa_result = (*m_RecordItf)->GetPosition(m_RecordItf, &milliSec);
+    returnValue = mapError(xa_result, ETrue);
+    if (returnValue == KErrNone)
+        aDur = (TInt64)milliSec;
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+void XARecordSessionImpl::cbMediaRecorder(
+                            XAObjectItf /*caller*/,
+                            const void */*pContext*/,
+                            XAuint32 event,
+                            XAresult result,
+                            XAuint32 /*param*/,
+                            void */*pInterface*/)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    switch (event) {
+    case XA_OBJECT_EVENT_RESOURCES_LOST:
+        m_Parent.cbRecordingStopped();
+        break;
+        case XA_OBJECT_EVENT_RUNTIME_ERROR: {
+            switch (result) {
+            case XA_RESULT_RESOURCE_LOST:
+                m_Parent.cbRecordingStopped();
+                break;
+            default:
+                break;
+            }; /* of switch (result) */
+        }
+    default:
+        break;
+    } /* of switch (event) */
+
+    TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::cbRecordItf(
+                        XARecordItf /*caller*/,
+                        void */*pContext*/,
+                        XAuint32 event)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    switch(event) {
+    case XA_RECORDEVENT_HEADATLIMIT:
+        TRACE_LOG(_L("XA_RECORDEVENT_HEADATLIMIT"));
+        break;
+    case XA_RECORDEVENT_HEADATMARKER:
+        TRACE_LOG(_L("XA_RECORDEVENT_HEADATMARKER"));
+        break;
+    case XA_RECORDEVENT_HEADATNEWPOS: {
+        TInt32 returnValue;
+        XAresult xa_result;
+        XAmillisecond milliSec;
+        xa_result = (*m_RecordItf)->GetPosition(m_RecordItf, &milliSec);
+        returnValue = mapError(xa_result, ETrue);
+        if (returnValue == KErrNone)
+            m_Parent.cbDurationChanged((TInt64)milliSec);
+        }
+        break;
+    case XA_RECORDEVENT_HEADMOVING:
+        TRACE_LOG(_L("XA_RECORDEVENT_HEADMOVING"));
+        m_Parent.cbRecordingStarted();
+        break;
+    case XA_RECORDEVENT_HEADSTALLED:
+        TRACE_LOG(_L("XA_RECORDEVENT_HEADSTALLED"));
+        break;
+    case XA_RECORDEVENT_BUFFER_FULL:
+        TRACE_LOG(_L("XA_RECORDEVENT_BUFFER_FULL"));
+        break;
+    default:
+        TRACE_LOG(_L("UNKNOWN RECORDEVENT EVENT"));
+        break;
+    } /* of switch(event) */
+
+    TRACE_FUNCTION_EXIT;
+}
+
+/* For QAudioEndpointSelector begin */
+void XARecordSessionImpl::getAudioInputDeviceNames(RArray<TPtrC> &aArray)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    for(TInt index = 0; index < m_AudioInputDeviceNames->MdcaCount(); index++)
+        aArray.Append(m_AudioInputDeviceNames->MdcaPoint(index));
+    TRACE_FUNCTION_EXIT;
+}
+
+TInt32 XARecordSessionImpl::defaultAudioInputDevice(TPtrC &endPoint)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TInt32 err(KErrGeneral);
+    if (m_DefaultAudioInputDeviceNames->MdcaCount() >= 0)
+        endPoint.Set(m_DefaultAudioInputDeviceNames->MdcaPoint(0));
+
+    TRACE_FUNCTION_EXIT;
+    return err;
+}
+
+TInt32 XARecordSessionImpl::activeAudioInputDevice(TPtrC &endPoint)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TInt32 returnValue(KErrGeneral);
+    TBool found(EFalse);
+    TInt index = 0;
+    for(; index < m_InputDeviceIDs.Count(); index++) {
+        if (m_InputDeviceIDs[index] == m_InputDeviceId) {
+            found = ETrue;
+            break;
+        }
+    }
+
+    /* Comparing found with ETrue produces linker error */
+    if (found == true) {
+        endPoint.Set(m_AudioInputDeviceNames->MdcaPoint(index));
+        returnValue = KErrNone;
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TBool XARecordSessionImpl::setAudioInputDevice(const TDesC &aDevice)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    /* validate if we can set input device id */
+    TBool found(EFalse);
+    m_InputDeviceId = 0;
+    TInt index = 0;
+    for(; index < m_AudioInputDeviceNames->MdcaCount(); index++) {
+        if (m_AudioInputDeviceNames->MdcaPoint(index).Compare(aDevice) == 0) {
+            found = ETrue;
+            break;
+        }
+    }
+    if (found == true) {
+        m_InputDeviceId = m_InputDeviceIDs[index];
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return found;
+}
+
+void XARecordSessionImpl::cbAvailableAudioInputsChanged(
+                                    XAAudioIODeviceCapabilitiesItf /*caller*/,
+                                    void */*pContext*/,
+                                    XAuint32 deviceID,
+                                    XAint32 /*numInputs*/,
+                                    XAboolean isNew)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    /* If a new device is added into the system, append it to available input list */
+    if (isNew == XA_BOOLEAN_TRUE) {
+        XAAudioInputDescriptor audioInputDescriptor;
+        m_InputDeviceIDs.Append(deviceID);
+
+        XAresult xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities(
+                m_AudioIODevCapsItf,
+                deviceID,
+                &audioInputDescriptor);
+
+        if ((mapError(xa_result, ETrue)) == KErrNone) {
+            TUint8* inDevNamePtr = audioInputDescriptor.deviceName;
+            TUint8* tempPtr = audioInputDescriptor.deviceName;
+            TInt32 inDevNameLength = 0;
+            while (*tempPtr++) inDevNameLength++;
+            TPtrC8 ptr(inDevNamePtr, inDevNameLength);
+            /* Convert 8 bit to 16 bit */
+            TBuf16<KMaxNameLength> name;
+            name.Copy(ptr);
+            /* Using TRAP with returnValue results in compiler error */
+            TRAP_IGNORE(m_AudioInputDeviceNames->AppendL(name));
+        }
+    }
+    else {
+        /* an available device has been removed from the the system, remove it from
+         * available input list and also default list */
+        TBool found(EFalse);
+        TInt index = 0;
+        for (; index < m_InputDeviceIDs.Count(); index++) {
+            if (deviceID == m_InputDeviceIDs[index]) {
+                found = ETrue;
+                break;
+            }
+        }
+        if (found == true) {
+            m_InputDeviceIDs.Remove(index);
+            m_AudioInputDeviceNames->Delete(index);
+        }
+        if (deviceID == m_InputDeviceId)
+            m_InputDeviceId = 0;
+
+        found = EFalse;
+        for (index = 0; index < m_DefaultInputDeviceIDs.Count(); index++) {
+            if (deviceID == m_DefaultInputDeviceIDs[index]) {
+                found = ETrue;
+                break;
+            }
+        }
+        if (found == true) {
+            m_DefaultInputDeviceIDs.Remove(index);
+            m_DefaultAudioInputDeviceNames->Delete(index);
+        }
+    }
+    m_Parent.cbAvailableAudioInputsChanged();
+
+    TRACE_FUNCTION_EXIT;
+}
+/* For QAudioEndpointSelector end */
+
+/* For QAudioEncoderControl begin */
+const RArray<TPtrC>& XARecordSessionImpl::getAudioEncoderNames()
+{
+    TRACE_FUNCTION_ENTRY_EXIT;
+    return m_EncoderNames;
+}
+
+TInt32 XARecordSessionImpl::getSampleRates(
+        const TDesC& aEncoder,
+        RArray<TInt32> &aSampleRates,
+        TBool &aIsContinuous)
+{
+    TRACE_FUNCTION_ENTRY;
+
+
+    aSampleRates.Reset();
+    aIsContinuous = EFalse;
+
+    XAuint32 encoderId = 0;
+    TBool found(EFalse);
+    for (TInt index = 0; index < m_EncoderIds.Count(); index++) {
+        if (m_EncoderNames[index].Compare(aEncoder) == 0) {
+            found = ETrue;
+            encoderId = m_EncoderIds[index];
+            break;
+        }
+    }
+
+    TInt32 returnValue(KErrGeneral);
+    if (found == false)
+        return returnValue;
+
+    XAuint32 numCaps = 0;
+    XAAudioCodecDescriptor codecDesc;
+    XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoderCapabilities(
+                                        m_AudioEncCapsItf,
+                                        encoderId,
+                                        &numCaps,
+                                        &codecDesc);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    /* TODO What do we do if we have more than one caps?? */
+    aIsContinuous = codecDesc.isFreqRangeContinuous;
+    if (aIsContinuous) {
+        aSampleRates.Append(codecDesc.minSampleRate / KMilliToHz);
+        aSampleRates.Append(codecDesc.maxSampleRate / KMilliToHz);
+    }
+    else {
+        XAuint32 numSRSupported = codecDesc.numSampleRatesSupported;
+        XAmilliHertz *pSampleRatesSupported(NULL);
+        pSampleRatesSupported = codecDesc.pSampleRatesSupported;
+        for (TInt index = 0; index < numSRSupported; index++)
+            aSampleRates.Append((*(pSampleRatesSupported + index)) / KMilliToHz);
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::getBitrates(
+                        const TDesC& aEncoder,
+                        RArray<TUint32> &aBitrates)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    aBitrates.Reset();
+
+    XAuint32 encoderId = 0;
+    TBool found(EFalse);
+    for (TInt index = 0; index < m_EncoderIds.Count(); index++) {
+        if (m_EncoderNames[index].Compare(aEncoder) == 0) {
+            found = ETrue;
+            encoderId = m_EncoderIds[index];
+            break;
+        }
+    }
+
+    TInt32 returnValue(KErrNotSupported);
+    if (found == false)
+        return returnValue;
+
+    returnValue = getBitratesByAudioCodecID(encoderId, aBitrates);
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+/* For QAudioEncoderControl end */
+
+/* For QMediaContainerControl begin */
+const RArray<TPtrC>& XARecordSessionImpl::getContainerNames()
+{
+    TRACE_FUNCTION_ENTRY_EXIT;
+    return m_ContainerNames;
+}
+
+const RArray<TPtrC>& XARecordSessionImpl::getContainerDescs()
+{
+    TRACE_FUNCTION_ENTRY_EXIT;
+    return m_ContainerDescs;
+}
+
+/* For QMediaContainerControl end */
+
+void XARecordSessionImpl::resetEncoderAttributes()
+{
+    m_ContainerType = 0;
+    m_AudioEncoderId = 0;
+    m_ProfileSetting = 0;
+    m_BitRate = 0;
+    m_ChannelsOut = 0;
+    m_SampleRate = 0;
+    m_RateControl = 0;
+}
+
+void XARecordSessionImpl::setContainerType(const TDesC &aURI)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    if (aURI.Compare(KCONTAINERWAV()) == 0)
+        m_ContainerType = XA_CONTAINERTYPE_WAV;
+    else if (aURI.Compare(KCONTAINERAMR()) == 0)
+        m_ContainerType = XA_CONTAINERTYPE_AMR;
+    else if (aURI.Compare(KCONTAINERMP4()) == 0)
+        m_ContainerType = XA_CONTAINERTYPE_MP4;
+
+    TRACE_FUNCTION_EXIT;
+}
+
+TBool XARecordSessionImpl::setCodec(const TDesC &aCodec)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    TBool returnValue(EFalse);
+    if (aCodec.Compare(KAUDIOCODECPCM()) == 0) {
+        m_AudioEncoderId = XA_AUDIOCODEC_PCM;
+        m_ProfileSetting = XA_AUDIOPROFILE_PCM;
+        returnValue = ETrue;
+    }
+    else if (aCodec.Compare(KAUDIOCODECAAC()) == 0) {
+        m_AudioEncoderId = XA_AUDIOCODEC_AAC;
+        m_ProfileSetting = XA_AUDIOPROFILE_AAC_AAC;
+        returnValue = ETrue;
+    }
+    else if (aCodec.Compare(KAUDIOCODECAMR()) == 0) {
+        m_AudioEncoderId = XA_AUDIOCODEC_AMR;
+        m_ProfileSetting = XA_AUDIOPROFILE_AMR;
+        returnValue = ETrue;
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+void XARecordSessionImpl::setBitRate(TUint32 aBitRate) {
+    TRACE_FUNCTION_ENTRY;
+    m_BitRate = aBitRate;
+    TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::setChannels(TUint32 aChannels) {
+    TRACE_FUNCTION_ENTRY;
+    m_ChannelsOut = aChannels;
+    TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::setOptimalChannelCount() {
+    TRACE_FUNCTION_ENTRY;
+    m_ChannelsOut = 0xffffffff;
+    TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::setSampleRate(TUint32 aSampleRate) {
+    TRACE_FUNCTION_ENTRY;
+    /* convert Hz to MilliHz */
+    m_SampleRate = aSampleRate * KMilliToHz;
+    TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::setOptimalSampleRate() {
+    TRACE_FUNCTION_ENTRY;
+    m_SampleRate = 0xffffffff;
+    TRACE_FUNCTION_EXIT;
+}
+
+TInt32 XARecordSessionImpl::setCBRMode()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    m_RateControl = XA_RATECONTROLMODE_CONSTANTBITRATE;
+
+    TRACE_FUNCTION_EXIT;
+    return KErrNone;
+}
+
+TInt32 XARecordSessionImpl::setVBRMode()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    m_RateControl = XA_RATECONTROLMODE_VARIABLEBITRATE;
+
+    TRACE_FUNCTION_EXIT;
+    return KErrNone;
+}
+
+void XARecordSessionImpl::setVeryLowQuality()
+{
+    /* Set to very low quality encoder preset */
+    RArray<TUint32> bitrates;
+    TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates);
+    if ((res == KErrNone) && (bitrates.Count() > 0) ) {
+        /* Sort the array and pick the lowest bit rate */
+        bitrates.SortUnsigned();
+        m_BitRate = bitrates[0];
+    }
+}
+
+void XARecordSessionImpl::setLowQuality()
+{
+    /* Set to low quality encoder preset */
+    RArray<TUint32> bitrates;
+    TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates);
+    if ((res == KErrNone) && (bitrates.Count() > 0)) {
+        /* Sort the array and pick the low quality bit rate */
+        bitrates.SortUnsigned();
+        m_BitRate = bitrates[bitrates.Count()*1/4];
+    }
+}
+
+void XARecordSessionImpl::setNormalQuality()
+{
+    /* Set to normal quality encoder preset */
+    RArray<TUint32> bitrates;
+    TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates);
+    if ((res == KErrNone) && (bitrates.Count() > 0)) {
+        /* Sort the array and pick the middle range bit rate */
+        bitrates.SortUnsigned();
+        m_BitRate = bitrates[bitrates.Count()/2];
+    }
+}
+
+void XARecordSessionImpl::setHighQuality()
+{
+    /* Set to high quality encoder preset */
+    RArray<TUint32> bitrates;
+    TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates);
+    if ((res == KErrNone) && (bitrates.Count() > 0)) {
+        /* Sort the array and pick the high quality bit rate */
+        bitrates.SortUnsigned();
+        m_BitRate = bitrates[bitrates.Count()*3/4];
+    }
+}
+
+void XARecordSessionImpl::setVeryHighQuality()
+{
+    /* Set to very high quality encoder preset */
+    RArray<TUint32> bitrates;
+    TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates);
+    if ((res == KErrNone) && (bitrates.Count() > 0)) {
+        /* Sort the array and pick the highest bit rate */
+        bitrates.SortUnsigned();
+        m_BitRate = bitrates[bitrates.Count()-1];
+    }
+}
+
+/* Internal function */
+TInt32 XARecordSessionImpl::createMediaRecorderObject()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    if (!m_EOEngine)
+        return KErrGeneral;
+
+    TInt32 returnValue(KErrNone);
+
+    TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject"));
+    if (!m_MORecorder && !m_RecordItf) {
+
+        /* Setup the data source */
+        m_LocatorMic.locatorType = XA_DATALOCATOR_IODEVICE;
+        m_LocatorMic.deviceType  = XA_IODEVICE_AUDIOINPUT;
+        m_LocatorMic.deviceID    = m_InputDeviceId;
+        m_LocatorMic.device      = NULL;
+        m_DataSource.pLocator    = (void*) &m_LocatorMic;
+        m_DataSource.pFormat     = NULL;
+
+        /* Setup the data sink structure */
+        m_Uri.locatorType    = XA_DATALOCATOR_URI;
+        /* append zero terminator to end of URI */
+        TPtr8 uriPtr = m_URIName->Des();
+        m_Uri.URI = (XAchar*) uriPtr.PtrZ();
+        m_Mime.formatType    = XA_DATAFORMAT_MIME;
+        m_Mime.containerType = XA_CONTAINERTYPE_WAV;
+        TPtr8 mimeTypePtr(m_WAVMime->Des());
+        m_Mime.mimeType = (XAchar*)mimeTypePtr.Ptr();
+        m_DataSink.pLocator = (void*) &m_Uri;
+        m_DataSink.pFormat  = (void*) &m_Mime;
+
+        /* Init arrays required[] and iidArray[] */
+        XAboolean required[MAX_NUMBER_INTERFACES];
+        XAInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+        for (TInt32 i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+            required[i] = XA_BOOLEAN_FALSE;
+            iidArray[i] = XA_IID_NULL;
+        }
+        XAuint32 noOfInterfaces = 0;
+        required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+        iidArray[noOfInterfaces] = XA_IID_RECORD;
+        noOfInterfaces++;
+        required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+        iidArray[noOfInterfaces] = XA_IID_AUDIOENCODER;
+        noOfInterfaces++;
+
+        XAEngineItf engineItf;
+        XAresult xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, XA_IID_ENGINE, (void**) &engineItf);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Create Media Recorder..."));
+
+        /* Create recorder with NULL for a the image/video source, since this is for audio-only recording */
+        xa_result = (*engineItf)->CreateMediaRecorder(
+                                    engineItf,
+                                    &m_MORecorder,
+                                    &m_DataSource,
+                                    NULL,
+                                    &m_DataSink,
+                                    noOfInterfaces,
+                                    iidArray,
+                                    required);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Realize Media Recorder..."));
+        xa_result = (*m_MORecorder)->Realize(m_MORecorder, XA_BOOLEAN_FALSE);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Register Callback on recorder..."));
+        xa_result = (*m_MORecorder)->RegisterCallback(m_MORecorder, cbXAObjectItf, (void*)this);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Getting Record Interface..."));
+        xa_result = (*m_MORecorder)->GetInterface(m_MORecorder, XA_IID_RECORD, &m_RecordItf);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Registering Callback on record Interface..."));
+        xa_result = (*m_RecordItf)->RegisterCallback(m_RecordItf, cbXARecordItf, (void*)this);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: SetPositionUpdatePeriod on record Interface..."));
+        xa_result = (*m_RecordItf)->SetPositionUpdatePeriod(m_RecordItf, (XAmillisecond)KRecordPosUpdatePeriod);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: SetCallbackEventsMask on record Interface..."));
+        xa_result = (*m_RecordItf)->SetCallbackEventsMask(m_RecordItf, XA_RECORDEVENT_HEADATNEWPOS |
+                                                                    XA_RECORDEVENT_HEADMOVING |
+                                                                    XA_RECORDEVENT_HEADSTALLED);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+
+        TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Getting Audio Encoder Interface..."));
+        xa_result = (*m_MORecorder)->GetInterface(m_MORecorder, XA_IID_AUDIOENCODER, &m_AudioEncItf);
+        returnValue = mapError(xa_result, ETrue);
+        RET_ERR_IF_ERR(returnValue);
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::mapError(XAresult xa_err, TBool debPrn)
+{
+    TInt32 returnValue(KErrGeneral);
+    switch(xa_err) {
+    case XA_RESULT_SUCCESS:
+        returnValue = KErrNone;
+        break;
+    case XA_RESULT_PRECONDITIONS_VIOLATED:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_PRECONDITIONS_VIOLATED"));
+        break;
+    case XA_RESULT_PARAMETER_INVALID:
+        if (debPrn)
+             TRACE_LOG(_L("XA_RESULT_PARAMETER_INVALID"));
+        break;
+    case XA_RESULT_MEMORY_FAILURE:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_MEMORY_FAILURE"));
+        break;
+    case XA_RESULT_RESOURCE_ERROR:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_RESOURCE_ERROR"));
+        break;
+    case XA_RESULT_RESOURCE_LOST:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_RESOURCE_LOST"));
+        break;
+    case XA_RESULT_IO_ERROR:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_IO_ERROR"));
+        break;
+    case XA_RESULT_BUFFER_INSUFFICIENT:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_BUFFER_INSUFFICIENT"));
+        break;
+    case XA_RESULT_CONTENT_CORRUPTED:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_CONTENT_CORRUPTED"));
+        break;
+    case XA_RESULT_CONTENT_UNSUPPORTED:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_CONTENT_UNSUPPORTED"));
+        break;
+    case XA_RESULT_CONTENT_NOT_FOUND:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_CONTENT_NOT_FOUND"));
+        break;
+    case XA_RESULT_PERMISSION_DENIED:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_PERMISSION_DENIED"));
+        break;
+    case XA_RESULT_FEATURE_UNSUPPORTED:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_FEATURE_UNSUPPORTED"));
+        break;
+    case XA_RESULT_INTERNAL_ERROR:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_INTERNAL_ERROR"));
+        break;
+    case XA_RESULT_UNKNOWN_ERROR:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_UNKNOWN_ERROR"));
+        break;
+    case XA_RESULT_OPERATION_ABORTED:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_OPERATION_ABORTED"));
+        break;
+    case XA_RESULT_CONTROL_LOST:
+        if (debPrn)
+            TRACE_LOG(_L("XA_RESULT_CONTROL_LOST"));
+        break;
+    default:
+        if (debPrn)
+            TRACE_LOG(_L("Unknown Error!!!"));
+        break;
+    }
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::initContainersList()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    m_ContainerNames.Reset();
+    m_ContainerDescs.Reset();
+
+    m_ContainerNames.Append(KCONTAINERWAV());
+    m_ContainerNames.Append(KCONTAINERAMR());
+    m_ContainerNames.Append(KCONTAINERMP4());
+
+    m_ContainerDescs.Append(KCONTAINERWAVDESC());
+    m_ContainerDescs.Append(KCONTAINERAMRDESC());
+    m_ContainerDescs.Append(KCONTAINERMP4DESC());
+
+    TRACE_FUNCTION_EXIT;
+    return KErrNone;
+}
+
+TInt32 XARecordSessionImpl::initAudioEncodersList()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    m_EncoderIds.Reset();
+    m_EncoderNames.Reset();
+
+    XAuint32 encoderIds[MAX_NUMBER_ENCODERS];
+
+    for(TInt index = 0; index < MAX_NUMBER_ENCODERS; index++)
+        encoderIds[index] = 0;
+
+    XAuint32 numEncoders = MAX_NUMBER_ENCODERS;
+    XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoders(
+                                        m_AudioEncCapsItf,
+                                        &numEncoders,
+                                        encoderIds);
+    TInt32 returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    for (TInt index = 0; index < numEncoders; index++) {
+        m_EncoderIds.Append(encoderIds[index]);
+        switch (encoderIds[index]) {
+        case XA_AUDIOCODEC_PCM:
+            m_EncoderNames.Append(KAUDIOCODECPCM());
+            break;
+        case XA_AUDIOCODEC_AMR:
+            m_EncoderNames.Append(KAUDIOCODECAMR());
+            break;
+        case XA_AUDIOCODEC_AAC:
+            m_EncoderNames.Append(KAUDIOCODECAAC());
+            break;
+        default:
+            break;
+        };
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::initAudioInputDevicesList()
+{
+    TRACE_FUNCTION_ENTRY;
+
+    m_InputDeviceIDs.Reset();
+
+    XAuint32 deviceIds[MAX_NUMBER_INPUT_DEVICES];
+    for(TInt index = 0; index < MAX_NUMBER_INPUT_DEVICES; index++)
+        deviceIds[index] = 0;
+
+    XAint32 numInputs = MAX_NUMBER_INPUT_DEVICES;
+    XAresult xa_result = (*m_AudioIODevCapsItf)->GetAvailableAudioInputs(
+                                        m_AudioIODevCapsItf,
+                                        &numInputs,
+                                        deviceIds);
+    TInt32 returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    XAAudioInputDescriptor audioInputDescriptor;
+    for (TInt index = 0; index < numInputs; index++) {
+        m_InputDeviceIDs.Append(deviceIds[index]);
+        xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities(
+                m_AudioIODevCapsItf,
+                deviceIds[index],
+                &audioInputDescriptor);
+        returnValue = mapError(xa_result, ETrue);
+        if (returnValue != KErrNone)
+            continue;
+
+        TUint8 * inDevNamePtr = audioInputDescriptor.deviceName;
+        TUint8 * tempPtr = audioInputDescriptor.deviceName;
+        TInt32 inDevNameLength = 0;
+        while (*tempPtr++) inDevNameLength++;
+        TPtrC8 ptr(inDevNamePtr, inDevNameLength);
+        /* Convert 8 bit to 16 bit */
+        TBuf16<KMaxNameLength> name;
+        name.Copy(ptr);
+        /* Using TRAP with returnValue results in compiler error */
+        TRAPD(err2, m_AudioInputDeviceNames->AppendL(name));
+        returnValue = err2;
+        RET_ERR_IF_ERR(returnValue);
+    }
+
+    numInputs = MAX_NUMBER_INPUT_DEVICES;
+    for(TInt index = 0; index < MAX_NUMBER_INPUT_DEVICES; index++)
+        deviceIds[index] = 0;
+    xa_result = (*m_AudioIODevCapsItf)->GetDefaultAudioDevices(
+                                        m_AudioIODevCapsItf,
+                                        XA_DEFAULTDEVICEID_AUDIOINPUT,
+                                        &numInputs,
+                                        deviceIds);
+    returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    for (TInt index = 0; index < numInputs; index++) {
+        m_DefaultInputDeviceIDs.Append(deviceIds[index]);
+        xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities(
+                m_AudioIODevCapsItf,
+                deviceIds[index],
+                &audioInputDescriptor);
+        returnValue = mapError(xa_result, ETrue);
+        if (returnValue != KErrNone)
+            continue;
+        TUint8* inDevNamePtr = audioInputDescriptor.deviceName;
+        TUint8* tempPtr = audioInputDescriptor.deviceName;
+        TInt32 inDevNameLength = 0;
+        while (*tempPtr++) inDevNameLength++;
+        TPtrC8 ptr(inDevNamePtr, inDevNameLength);
+        /* Convert 8 bit to 16 bit */
+        TBuf16<KMaxNameLength> name;
+        name.Copy(ptr);
+        /* Using TRAP with returnValue results in compiler error */
+        TRAPD(err2, m_DefaultAudioInputDeviceNames->AppendL(name));
+        returnValue = err2;
+        RET_ERR_IF_ERR(returnValue);
+    }
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::setEncoderSettingsToMediaRecorder()
+{
+    TRACE_FUNCTION_EXIT;
+
+    /* Get current settings */
+    XAAudioEncoderSettings settings;
+    XAresult xa_result = (*m_AudioEncItf)->GetEncoderSettings(
+            m_AudioEncItf,
+            &settings);
+    TInt32 returnValue = mapError(xa_result, ETrue);
+
+    settings.encoderId = m_AudioEncoderId;
+    if (m_ChannelsOut != 0xffffffff)
+        settings.channelsOut = m_ChannelsOut;
+    if (m_SampleRate != 0xffffffff)
+        settings.sampleRate = m_SampleRate;
+    if (m_BitRate != 0)
+        settings.bitRate = m_BitRate;
+    if (m_RateControl != 0)
+        settings.rateControl = m_RateControl;
+    settings.profileSetting = m_ProfileSetting;
+    xa_result = (*m_AudioEncItf)->SetEncoderSettings(
+            m_AudioEncItf,
+            &settings);
+    returnValue = mapError(xa_result, ETrue);
+
+    TRACE_FUNCTION_EXIT;
+    return returnValue;
+}
+
+TInt32 XARecordSessionImpl::getBitratesByAudioCodecID(
+        XAuint32 encoderId,
+        RArray<TUint32> &aBitrates)
+{
+    TRACE_FUNCTION_ENTRY;
+
+    if (!m_AudioEncCapsItf)
+        return KErrGeneral;
+
+    XAuint32 numCaps = 0;
+    XAAudioCodecDescriptor codecDesc;
+    XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoderCapabilities(
+                                        m_AudioEncCapsItf,
+                                        encoderId,
+                                        &numCaps,
+                                        &codecDesc);
+    TInt32 returnValue = mapError(xa_result, ETrue);
+    RET_ERR_IF_ERR(returnValue);
+
+    /* TODO What do we do if we have more than one caps?? */
+    if (codecDesc.isBitrateRangeContinuous == XA_BOOLEAN_TRUE) {
+        aBitrates.Append(codecDesc.minBitRate);
+        aBitrates.Append(codecDesc.maxBitRate);
+    }
+    else {
+        XAuint32 numBrSupported = codecDesc.numBitratesSupported;
+        XAuint32 * pBitratesSupported(NULL);
+        pBitratesSupported = codecDesc.pBitratesSupported;
+        TInt32 index = 0;
+        for (index = 0; index < numBrSupported; index++)
+            aBitrates.Append(*(pBitratesSupported + index));
+    }
+
+    TRACE_FUNCTION_ENTRY;
+    return returnValue;
+}
+
+/* Local function implementation */
+void cbXAObjectItf(
+            XAObjectItf caller,
+            const void *pContext,
+            XAuint32 event,
+            XAresult result,
+            XAuint32 param,
+            void *pInterface)
+{
+    if (pContext) {
+        ((XARecordSessionImpl*)pContext)->cbMediaRecorder(
+                                                        caller,
+                                                        pContext,
+                                                        event,
+                                                        result,
+                                                        param,
+                                                        pInterface);
+    }
+}
+
+void cbXARecordItf(
+            XARecordItf caller,
+            void *pContext,
+            XAuint32 event)
+{
+    if (pContext) {
+        ((XARecordSessionImpl*)pContext)->cbRecordItf(
+                                                    caller,
+                                                    pContext,
+                                                    event);
+    }
+}
+
+void cbXAAvailableAudioInputsChanged(
+            XAAudioIODeviceCapabilitiesItf caller,
+            void * pContext,
+            XAuint32 deviceID,
+            XAint32 numInputs,
+            XAboolean isNew)
+{
+    if (pContext) {
+        ((XARecordSessionImpl*)pContext)->cbAvailableAudioInputsChanged(
+                                                    caller,
+                                                    pContext,
+                                                    deviceID,
+                                                    numInputs,
+                                                    isNew);
+    }
+}