diff -r 4c282e7dd6d3 -r 5505e8908944 gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp Fri Jan 22 09:59:59 2010 +0200 @@ -0,0 +1,733 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Description: +* +*/ + +#include "devsoundsinkwrapper.h" +#include +#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 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; + }