gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp
changeset 0 0e761a78d257
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp	Thu Dec 17 08:53:32 2009 +0200
@@ -0,0 +1,729 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include "devsoundsinkwrapper.h"
+#include <mmcccodecinformation.h>
+#include "debugtracemacros.h"
+
+DevSoundWrapper::DevSoundWrapper()
+    {
+    init_complete = 0;
+    dev_sound = NULL;
+
+    buffersize = 0;
+    dev_count = 0;
+    caps.iRate = EMMFSampleRate8000Hz;
+    caps.iEncoding = EMMFSoundEncoding16BitPCM;
+    caps.iChannels = EMMFMono;
+    fourcc = KMMFFourCCCodePCM16;
+    eosReceived = false;
+    iErrConcealmentIntfc = NULL;
+    iG711DecoderIntfc = NULL;
+    iG729DecoderIntfc = NULL;
+    iIlbcDecoderIntfc = NULL;
+    iCallbackError = KErrNone;
+    iAudioOutput = NULL;
+    }
+
+/*********************************************************/
+void DevSoundWrapper::InitializeComplete(TInt aError)
+    {
+    TRACE_PRN_FN_ENT;
+    TRequestStatus* stat = &(AL->iStatus);
+
+    if (aError == KErrNone)
+        {
+        init_complete = 1;
+        }
+    else
+        {
+        init_complete = 0;
+        }
+
+    User::RequestComplete(stat, aError);
+    TRACE_PRN_IF_ERR(aError);
+    TRACE_PRN_FN_EXT;
+    }
+/************************************************************/
+
+void DevSoundWrapper::BufferToBeFilled(CMMFBuffer* aBuffer)
+    {
+//    TRACE_PRN_FN_ENT;
+    buffer = aBuffer;
+    buffersize = aBuffer->RequestSize();
+    TRACE_PRN_N1(_L("DevSoundWrapper::BufferToBeFilled->buffersize [%d]"), buffersize);
+
+    TRequestStatus* stat = &(AL->iStatus);
+
+    if (aBuffer)
+        {
+        User::RequestComplete(stat, KErrNone);
+        iCallbackError = KErrNone;
+        }
+    else
+        {
+        User::RequestComplete(stat, KErrNotFound);
+        iCallbackError = KErrNotFound;
+        }
+
+//    TRACE_PRN_FN_EXT;
+    }
+
+/***********************************************************/
+void DevSoundWrapper::PlayError(TInt aError)
+    {
+    TRequestStatus* stat = &(AL->iStatus);
+    User::RequestComplete(stat, aError);
+    iCallbackError = aError;
+    }
+/*******************************************************/
+void DevSoundWrapper::BufferToBeEmptied(CMMFBuffer* /*aBuffer*/)
+    {
+
+    }
+/********************************************************/
+void DevSoundWrapper::RecordError(TInt /*aError*/)
+    {
+
+    }
+/**********************************************************/
+void DevSoundWrapper::ConvertError(TInt /*aError*/)
+    {
+
+    }
+/***********************************************************/
+void DevSoundWrapper::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /*aMsg*/)
+    {
+
+    }
+/***********************************************************/
+void DevSoundWrapper::SendEventToClient(const TMMFEvent& /*aEvent*/)
+    {
+
+    }
+/************************************************************/
+void DevSoundWrapper::ToneFinished(TInt /*aError*/)
+    {
+
+    }
+
+/***********************************************************
+ *********C interface functions******************************
+ ************************************************************/
+
+/******************************************************/
+int open_devsound(DevSoundWrapper **handle)
+    {
+    TRACE_PRN_FN_ENT;
+    int ret = 0;
+    *handle = new DevSoundWrapper();
+    if (handle)
+        {
+        ret = open_device(handle);
+        }
+    else
+        {
+        ret = KErrNoMemory;
+        }
+    TRACE_PRN_FN_EXT;
+    return ret;
+    }
+
+/*********************************************************/
+
+int check_if_device_open(DevSoundWrapper *handle)
+    {
+    TRACE_PRN_FN_ENT;
+
+    int ret;
+    if ((handle->dev_count) == 1)
+        {
+        ret = 1;
+        }
+    else
+        {
+        ret = 0;
+        }
+
+    TRACE_PRN_FN_EXT;
+    return ret;
+    }
+
+/*********************************************************/
+int open_device(DevSoundWrapper **handle)
+    {
+    int retcode = KErrNone;
+    TRACE_PRN_FN_ENT;
+
+    (*handle)->dev_count++;
+
+    (*handle)->as = CActiveScheduler::Current();
+
+    if (!((*handle)->as))
+        {
+        (*handle)->as = new CActiveScheduler();
+        if ((*handle)->as)
+            {
+            CActiveScheduler::Install((*handle)->as);
+            }
+
+        }
+    (*handle)->AL = new CActiveListener;
+    ((*handle)->AL)->asw = new CActiveSchedulerWait();
+
+        TRAP( retcode,(*handle)->dev_sound = CMMFDevSound::NewL() );
+
+    if (!(*handle)->AL || !((*handle)->AL)->asw || !(*handle)->dev_sound
+            || !(*handle)->as)
+        {
+        retcode = KErrNoMemory;
+        }
+
+    TRACE_PRN_FN_EXT;
+    return retcode;
+    }
+
+/*******************************************************/
+int initialize_devsound(GstDevsoundSink* ds)
+    {
+    TRACE_PRN_FN_ENT;
+    int ret = 0;
+    DevSoundWrapper* handle = (DevSoundWrapper*) ds->handle;
+
+    handle->AL->InitialiseActiveListener();
+
+        TRAP (ret, handle->dev_sound->InitializeL(*handle, handle->fourcc, EMMFStatePlaying));
+
+    if (ret)
+        {
+        TRACE_PRN_IF_ERR(ret);
+        return ret;
+        }
+
+    handle->AL->StartActiveScheduler();
+
+    if (handle->init_complete==1)
+        {
+        TMMFPrioritySettings temp;
+        temp.iPref = (TMdaPriorityPreference)ds->preference;
+        temp.iPriority = ds->priority;
+        handle->dev_sound->SetPrioritySettings(temp);
+
+        //set post initialize properties
+        post_init_setconfig(handle);
+        ret = KErrNone;
+        }
+    else
+        {
+        ret = KErrNotFound;
+        }
+
+    TRACE_PRN_IF_ERR(ret);
+    TRACE_PRN_FN_EXT;
+    return ret;
+    }
+
+/************************************************************/
+
+int close_devsound(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+
+    g_list_foreach(ds->fmt, (GFunc) g_free, NULL);
+    g_list_free(ds->fmt);
+    ds->fmt = NULL;
+    delete ds->handle;
+    TRACE_PRN_FN_EXT;
+    return 0;
+    }
+
+/************************************************************/
+
+int post_init_setconfig(DevSoundWrapper *handle)
+    {
+    TRACE_PRN_FN_ENT;
+    int ret = 0;
+
+        TRAP(ret, (handle->dev_sound)->SetConfigL(handle->caps) );
+
+    if (ret)
+        {
+        TRACE_PRN_IF_ERR(ret);
+        return ret;
+        }
+
+    (handle->caps)= (handle->dev_sound)->Config();
+
+    if (handle->fourcc == KMccFourCCIdG711 ||
+            handle->fourcc == KMccFourCCIdG729 ||
+            handle->fourcc == KMccFourCCIdILBC ||
+            handle->fourcc == KMccFourCCIdAMRNB)
+        {
+        if (!handle->iErrConcealmentIntfc)
+            {
+
+            TRAP(ret, handle->iErrConcealmentIntfc = CErrorConcealmentIntfc::NewL(*handle->dev_sound) );
+            }
+        }
+    switch (handle->fourcc)
+        {
+        case KMccFourCCIdG711:
+            {
+            if (!handle->iG711DecoderIntfc)
+                {
+
+                TRAP(ret, handle->iG711DecoderIntfc = CG711DecoderIntfc::NewL(*handle->dev_sound) );
+                }
+            break;
+            }
+        case KMccFourCCIdG729:
+            {
+            if (!handle->iG729DecoderIntfc)
+                {
+
+                TRAP(ret, handle->iG729DecoderIntfc = CG729DecoderIntfc::NewL(*handle->dev_sound) );
+                }
+            break;
+            }
+        case KMccFourCCIdILBC:
+            {
+            if (!handle->iIlbcDecoderIntfc)
+                {
+
+                TRAP(ret, handle->iIlbcDecoderIntfc = CIlbcDecoderIntfc::NewL(*handle->dev_sound) );
+                }
+            break;
+            }
+        case KMccFourCCIdAMRNB:
+        case KMMFFourCCCodePCM16:
+        default:
+            {
+            break;
+            }
+        }
+   
+    if (!handle->iAudioOutput)
+        {
+        TRAP(ret, handle->iAudioOutput = CAudioOutput::NewL(*handle->dev_sound) );
+        }
+    
+    TRACE_PRN_IF_ERR(ret);
+    TRACE_PRN_FN_EXT;
+    return ret;
+
+    }
+
+/*********************************************************/
+
+void conceal_error_for_next_buffer(DevSoundWrapper *handle)
+    {
+    TRACE_PRN_FN_ENT;
+    if (handle->iErrConcealmentIntfc)
+        {
+        (handle->iErrConcealmentIntfc)->ConcealErrorForNextBuffer();
+        }
+    TRACE_PRN_FN_EXT;
+    }
+
+/*********************************************************/
+void set_framemode(DevSoundWrapper *handle, gboolean mode)
+    {
+    TRACE_PRN_FN_ENT;
+    if (handle->iErrConcealmentIntfc)
+        {
+        (handle->iErrConcealmentIntfc)->SetFrameMode(mode);
+        }
+    TRACE_PRN_FN_EXT;
+    }
+
+/*********************************************************/
+int framemode_rqrd_for_ec(DevSoundWrapper *handle, gboolean* modereq)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iErrConcealmentIntfc)
+        {
+        err = (handle->iErrConcealmentIntfc)->FrameModeRqrdForEC(*modereq);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/*********************************************************/
+int set_decodermode(DevSoundWrapper *handle, int aDecodeMode)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iG711DecoderIntfc)
+        {
+        err = (handle->iG711DecoderIntfc)->SetDecoderMode(
+                (CG711DecoderIntfc::TDecodeMode) aDecodeMode);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/*********************************************************/
+
+int set_cng(DevSoundWrapper *handle, gboolean aCng)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iG711DecoderIntfc)
+        {
+        err = (handle->iG711DecoderIntfc)->SetCng(aCng);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/*********************************************************/
+int get_cng(DevSoundWrapper *handle, gboolean* aCng)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iG711DecoderIntfc)
+        {
+        err = (handle->iG711DecoderIntfc)->GetCng(*aCng);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/*********************************************************/
+int set_plc(DevSoundWrapper *handle, gboolean aPlc)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iG711DecoderIntfc)
+        {
+        err = (handle->iG711DecoderIntfc)->SetPlc(aPlc);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+/*********************************************************/
+//G729 custom interface
+gint badlsfnextbuffer(DevSoundWrapper *handle)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iG729DecoderIntfc)
+        {
+        err = (handle->iG729DecoderIntfc)->BadLsfNextBuffer();
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+/*********************************************************/
+//Ilbc custom interace
+gint get_ilbccng(DevSoundWrapper *handle, gboolean* aCng)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iIlbcDecoderIntfc)
+        {
+        err = (handle->iIlbcDecoderIntfc)->GetCng(*aCng);
+        }
+
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+/*********************************************************/
+gint set_ilbccng(DevSoundWrapper *handle, gboolean aCng)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iIlbcDecoderIntfc)
+        {
+        err = (handle->iIlbcDecoderIntfc)->SetCng(aCng);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+/*********************************************************/
+gint set_ilbcdecodermode(DevSoundWrapper *handle,
+        enum TIlbcDecodeMode aDecodeMode)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iIlbcDecoderIntfc)
+        {
+        err = (handle->iIlbcDecoderIntfc)->SetDecoderMode(
+                (CIlbcDecoderIntfc::TDecodeMode) aDecodeMode);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/*********************************************************/
+gint set_outputdevice(DevSoundWrapper *handle, gint outputDev)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iAudioOutput)
+        {
+        (handle->iAudioOutput)->SetAudioOutputL(
+                (CAudioOutput::TAudioOutputPreference) outputDev);
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/*********************************************************/
+gint get_outputdevice(DevSoundWrapper *handle, gint* outputDev)
+    {
+    TRACE_PRN_FN_ENT;
+    int err = 0;
+    if (handle->iAudioOutput)
+        {
+        *outputDev = (handle->iAudioOutput)->AudioOutput();
+        }
+    TRACE_PRN_FN_EXT;
+    return err;
+    }
+
+/**************************************************************/
+int reset_devsound(DevSoundWrapper* /*handle*/)
+    {
+    return 0;
+    }
+/*****************************************************************/
+int get_rate(DevSoundWrapper *handle)
+    {
+    return handle->caps.iRate;
+
+    }
+/*****************************************************************/
+int get_channels(DevSoundWrapper *handle)
+    {
+    return handle->caps.iChannels;
+    }
+/********************************************************************/
+int get_encoding(DevSoundWrapper *handle)
+    {
+    return handle->caps.iEncoding;
+
+    }
+/*******************************************************************/
+int get_size(DevSoundWrapper *handle)
+    {
+    return handle->caps.iBufferSize;
+    }
+/******************************************************************/
+
+void set_rate(DevSoundWrapper *handle, int rate)
+    {
+    handle->caps.iRate = rate;
+    }
+/******************************************************************/
+void set_channels(DevSoundWrapper *handle, int channels)
+    {
+    handle->caps.iChannels = channels;
+    }
+/****************************************************************/
+void set_encoding(DevSoundWrapper *handle, int encoding)
+    {
+    handle->caps.iEncoding = encoding;
+    }
+/*****************************************************************/
+void set_size(DevSoundWrapper *handle, int size)
+    {
+    handle->caps.iBufferSize = size;
+    }
+/*****************************************************************/
+void set_fourcc(DevSoundWrapper *handle, int fourcc)
+    {
+    handle->fourcc = fourcc;
+    }
+
+int get_ds_cb_error(DevSoundWrapper *handle)
+    {
+    return handle->iCallbackError;
+    }
+/*******************************************************************/
+
+int playinit(DevSoundWrapper *handle)
+    {
+    TRACE_PRN_FN_ENT;
+
+    ((handle)->AL)->InitialiseActiveListener();
+    handle->eosReceived = false;
+
+        TRAP(handle->iCallbackError,(handle->dev_sound)->PlayInitL());
+    if (handle->iCallbackError == KErrNone)
+        {
+        ((handle)->AL)->StartActiveScheduler();
+        }
+
+    TRACE_PRN_IF_ERR(handle->iCallbackError);
+    TRACE_PRN_FN_EXT;
+    return handle->iCallbackError;
+    }
+/******************************************************************/
+int write_data(DevSoundWrapper *handle, TUint8* gstPtr, int gstBufferSize,
+        gboolean lastBuffer)
+    {
+    TRACE_PRN_FN_ENT;
+
+    CMMFDataBuffer* buf = STATIC_CAST (CMMFDataBuffer*, handle->buffer);
+
+    TRACE_PRN_N2(_L("***gstBufferSize:[%d], handle->buffersize:[%d]"), gstBufferSize, handle->buffersize);
+
+    if ((lastBuffer == TRUE) && (gstBufferSize <= handle->buffersize))
+        {
+        buf->SetLastBuffer(ETrue);
+        }
+    
+    TInt copySize = Min(gstBufferSize, handle->buffersize);
+
+    if (copySize <= 0)
+        {
+        //will crash thread if not handled here
+        return gstBufferSize;
+        }
+
+    TPtr8 srcPtr(gstPtr, copySize, copySize);
+    TUint8* p = (TUint8*) (buf->Data().Ptr());
+    TPtr8 destPtr(p, buf->Data().Length(), buf->Data().MaxLength());
+
+    destPtr.Append(srcPtr);
+    TRACE_PRN_N(_L("write_data->Append"));
+    buf->Data().SetLength(buf->Data().Length() + copySize);
+
+    gstBufferSize -= copySize;
+    handle->buffersize -= copySize;
+
+    if ((handle->buffersize == 0) || (buf->LastBuffer()))
+        {
+        play_data(handle);
+        }
+
+    TRACE_PRN_FN_EXT;
+    return gstBufferSize;
+    }
+
+/*******************************************************************/
+int play_data(DevSoundWrapper *handle)
+    {
+    TRACE_PRN_FN_ENT;
+    (handle->AL)->InitialiseActiveListener();
+
+    (handle->dev_sound)->PlayData();
+
+    ((handle)->AL)->StartActiveScheduler();
+
+    TRACE_PRN_FN_EXT;
+    return KErrNone;
+    }
+
+/*********************************************************************/
+
+int pre_init_setconf(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    int ret = 0;
+
+    DevSoundWrapper* dsPtr = STATIC_CAST(DevSoundWrapper*, ds->handle);
+
+    // NOTE: it is too late for setting prio/pref here
+    if (ds->pending.preferenceupdate == 1 || ds->pending.priorityupdate == 1)
+        {
+        ds->pending.preferenceupdate = FALSE;
+        ds->pending.priorityupdate = FALSE;
+        }
+    if (ds->pending.volumeupdate == 1)
+        {
+        (dsPtr->dev_sound)->SetVolume(ds->volume);
+        ds->pending.volumeupdate = FALSE;
+        }
+    if (ds->pending.volumerampupdate == 1)
+        {
+        (dsPtr->dev_sound)->SetVolumeRamp(ds->volumeramp);
+        ds->pending.volumerampupdate = FALSE;
+        }
+    if (ds->pending.leftbalanceupdate == 1 || ds->pending.rightbalanceupdate
+            == 1)
+        {
+            TRAP( ret, (dsPtr->dev_sound)->SetPlayBalanceL(ds->leftbalance,ds->rightbalance) );
+        ds->pending.leftbalanceupdate = FALSE;
+        ds->pending.rightbalanceupdate = FALSE;
+        }
+    if(ds->pending.outputupdate == 1)
+        {
+        set_outputdevice(dsPtr,ds->output);
+        ds->pending.outputupdate = FALSE;
+        }
+    TRACE_PRN_FN_EXT;
+    return ret;
+    }
+/*********************************************************/
+void getsupporteddatatypes(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapper* dsPtr = STATIC_CAST(DevSoundWrapper*, ds->handle);
+        TRAP_IGNORE(dsPtr->GetDataTypesL(ds));
+
+    TRACE_PRN_FN_EXT;
+    }
+
+/*********************************************************/
+void DevSoundWrapper::GetDataTypesL(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+
+    RArray<TFourCC> outputdatatypes;
+    TMMFPrioritySettings prioritysettings;
+    DevSoundWrapper* dsPtr = STATIC_CAST(DevSoundWrapper*, ds->handle);
+
+    CleanupClosePushL(outputdatatypes);
+
+    TRAP_IGNORE( (dsPtr->dev_sound)->GetSupportedOutputDataTypesL(outputdatatypes,prioritysettings) );
+
+    for (TInt i = 0; i < outputdatatypes.Count(); i++)
+        {
+        TRACE_PRN_N2(_L("GstDevsoundSink supported Codec[%d]==[0x%x]"), i+1, outputdatatypes[i].FourCC());
+        guint *ip = g_new (guint, 1);
+        *ip = outputdatatypes[i].FourCC();
+        ds->fmt = g_list_append(ds->fmt, ip);
+        }
+    CleanupStack::PopAndDestroy(&outputdatatypes);
+    TRACE_PRN_FN_EXT;
+    }
+
+/*********************************************************/
+void populateproperties(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapper* dsPtr = STATIC_CAST(DevSoundWrapper*, ds->handle);
+    ds->samplesplayed = (dsPtr->dev_sound)->SamplesPlayed();
+    get_outputdevice(dsPtr,&ds->output);
+    TRACE_PRN_FN_EXT;
+    }
+
+void initproperties(GstDevsoundSink* ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapper* dsPtr=  STATIC_CAST(DevSoundWrapper*, ds->handle);
+    ds->maxvolume     = (dsPtr->dev_sound)->MaxVolume();
+    ds->volume        = (dsPtr->dev_sound)->Volume();
+    framemode_rqrd_for_ec(dsPtr,&ds->framemodereq);   
+    get_cng(dsPtr,&ds->g711cng);
+    get_ilbccng(dsPtr,&ds->ilbccng);
+    TRACE_PRN_FN_EXT;    
+    }