void UT_CMccRtpDataSource::UT_CMccRtpDataSource_FillBufferLL()
    {
    EUNIT_ASSERT_NO_LEAVE( iSource->FillBufferL( NULL, NULL, TMediaId() ) );
    CMMFDataBuffer* buffer = CMMFDataBuffer::NewL( 100 );
    CleanupStack::PushL( buffer );
    EUNIT_ASSERT_SPECIFIC_LEAVE( iSource->FillBufferL( buffer, NULL, TMediaId() ), KErrArgument );
    CleanupStack::PopAndDestroy( buffer );
    }
EXPORT_C CMMFDataPath2* CMMFDataPath2::NewL(TUid aCodecUid, MAsyncEventHandler& aEventHandler)
	{
	CMMFDataPath2* self = new(ELeave) CMMFDataPath2(TMediaId(), aEventHandler);
	CleanupStack::PushL(self);
	self->ConstructL(aCodecUid);
	CleanupStack::Pop();
	return self;
	}
 void COggVorbisFile::BufferEmptiedL(CMMFBuffer* aBuffer)
    {
    if (aBuffer->Type()==KUidMmfDescriptorBuffer)
        {
        CMMFDataBuffer* db = static_cast<CMMFDataBuffer*>(aBuffer);
        iBody->PCMOutL(*db);
        iBody->iSink->EmptyBufferL(db, this, TMediaId(KUidMediaTypeAudio));
        }
    else User::Leave(KErrNotSupported);
    }
// ---------------------------------------------------------------------------
// CDTMFPayloadFormatWrite::DeliverPacketL
// Prepare the RTP packet header and deliver the packet to the datasink.
// ---------------------------------------------------------------------------
//
void CDTMFPayloadFormatWrite::DeliverPacketL( CMMFDataBuffer& aPayload, 
                                              TBool aMarkerBit )
    {
    DP_DTMF_WRITE4( 
        _L("CDTMFPayloadFormatWrite::DeliverPacketL - TSTAMP: %u, TDUR: %d, tick = %u"),
        TUint32( aPayload.TimeToPlay().Int64() ), iToneDuration, 
        User::NTickCount() );
    
    if ( KSignalOutbandDtmf == iGenerationMode )
        {
        // Set the marker bit if it is very first packet.
        if ( aMarkerBit )
            {
            iRtpSendHeader.iMarker = 1;
            }
        else
            {
            iRtpSendHeader.iMarker = 0;
            }
            
        // Construct RTP header.
        if ( EGenRedUsed == iCInfo.iAlgoUsed )
            {
            iRtpSendHeader.iPayloadType = iCInfo.iRedundantPayload;
            }
        else
            {
            iRtpSendHeader.iPayloadType = iCInfo.iPayloadType;
            }

        // Timestamp must be updated before coming here
        iRtpSendHeader.iTimestamp = TUint32( aPayload.TimeToPlay().Int64() );

        // Deliver the packet
        iRtpDataSink->EmptyBufferL( &aPayload, this,
            TMediaId( KUidMediaTypeAudio ), iRtpSendHeader );

        // Do not reset payload buffer because update packets
        // are send based on same buffer.
        }
    else
        {
        DP_DTMF_WRITE( _L("CDTMFPayloadFormatWrite::DeliverPacketL - INBAND TONE") );
        }
    }
void CMMFVideoInput::NegotiateL(MDataSink& aSink)
	{
	aSink = aSink; //to keep compiler happy
#ifdef KVideoInputCanResample
	if (aSink.DataSinkType() == KUidMmfFormatDecode) 
		{//source is a clip so for now set sink settings to match source
		iSinkSampleRate = ((CMMFFormatDecode&)aSink).SampleRate(); 
		iSinkChannels = ((CMMFFormatDecode&)aSink).NumChannels();
		iSinkFourCC.Set(aSink.SinkDataTypeCode(TMediaId(KUidMediaTypeVideo)));
		((CMMFFormatDecode&)aSink).SuggestSourceBufferSize(KVideoInputDefaultFrameSize); 
		}

	//Use SW conversion but  should configure Dev sound where possible
	//WINS DevSound is always 8000 sample rate, mono & pcm16
	if ((iSinkChannels != 1)||(iSinkSampleRate != 8000)) iNeedsSWConversion = ETrue;
	else iNeedsSWConversion = EFalse; //incase it was set to true
#endif
	}
/**
Negotiates with the sink.

Called if the source's setup depends on sink.

@param  aSink
        The Data sink. Takes an MDataSink reference so a DataSource can negotiate with this
        MDataSource.
*/
void CMMFAudioInput::NegotiateSourceL(MDataSink& aSink)
	{
	if (aSink.DataSinkType() == KUidMmfFormatEncode) 
		{//sink is a clip so for now set sink settings to match sink
		iSinkSampleRate = ((CMMFFormatEncode&)aSink).SampleRate(); 
		iSinkChannels = ((CMMFFormatEncode&)aSink).NumChannels();
		iSinkFourCC.Set(aSink.SinkDataTypeCode(TMediaId(KUidMediaTypeAudio)));

		// if the sink's sample rate is undefined, try to obtain and use a
		// default sample rate from the sink. If this is zero, use 8K
		if (iSinkSampleRate == 0)
			{
			iSinkSampleRate = ((CMMFFormatEncode&)aSink).GetDefaultSampleRate(); 
			if (iSinkSampleRate == 0)
				iSinkSampleRate = 8000;
			}
		
		}

	if (iMMFDevSound == NULL)
  		User::Leave(KErrNotReady);

	TMMFState prioritySettingsState = iPrioritySettings.iState; //should be EMMFStateRecording
	//to use the GetSupportedOutputDatatypes but we'll save it just in case it's not
	iPrioritySettings.iState = EMMFStateRecording; //if playing does not support any output data types
	RArray<TFourCC> supportedDataTypes;
	//note Output data types becuase if we are recording audio ie audio input
	//the data is sent as an output from DevSound
	TRAPD(err, iMMFDevSound->GetSupportedOutputDataTypesL(supportedDataTypes, iPrioritySettings));
	iPrioritySettings.iState = prioritySettingsState;
	if (err == KErrNone)
		{
		if (supportedDataTypes.Find(iSinkFourCC) == KErrNotFound)
			{//the source fourCC code could not be found in the list of 
			//data types supported by the Devsound therefor default to pcm16
			iDataTypeCode = KMMFFourCCCodePCM16;	
			}
		else
			{
			//the DevSound does support the same datatype as the source 
			//so set the fourcc to that of the source
			iDataTypeCode = iSinkFourCC;
			}
		}
	supportedDataTypes.Close();
	if (err == KErrNotSupported)
		{//if the Devsound does not support the GetSupportedOutputDataTypesL method
		//then assume that the DevSound is pcm16 only
		iDataTypeCode = KMMFFourCCCodePCM16;	
		}
	else if (err != KErrNone) //we had a real leave error from GetSupportedOuputDataTypesL
		{
		User::Leave(err);
		}

    // Prevent defect when SourcePrimeL is called before NegotiateSourceL()
	// since characterization is ambiguous
    if(iState == EDevSoundReady)
      {
      iState = EIdle;
      }

  	// moved from LoadL - fix for DEF037168 - AD
	iMMFDevSound->InitializeL(*this, iDataTypeCode, EMMFStateRecording);

	// In some implementations InitializeComplete is sent
	// in context, so check before starting activeSchedulerWait.
	if (iState != EDevSoundReady)
		{
		iInitializeState = KRequestPending;
		iActiveSchedulerWait->Start();
		}		
	User::LeaveIfError(iInitializeState);

	iMMFDevSound->SetPrioritySettings(iPrioritySettings);

	// Attempt to configure DevSound to the same settings as the sink.
	// Need to do this after calling CMMFDevSound::InitializeL() as
	// this sets up the device capabilities 
	// (returned by iMMFDevSound->Capabilities()).
	ConfigDevSoundL();
	}
void UT_CMccRtpDataSource::UT_CMccRtpDataSource_ValidatePacketL()
    {
    TRtpId streamId( KNullId );
    TRtpRecvHeader header;

    TBuf8<5> data5;
    TBuf8<15> data15;
    data5.Format( _L8( "foo42" ) );
    data15.Format( _L8( "foo42foo42foo42" ) );

    // Data too big, stream ok, wrong payload type
    EUNIT_ASSERT_LEAVE( iSource->ValidatePacketL( streamId, header, data15 ) );

    // Data ok, stream ok, wrong payload type
    EUNIT_ASSERT_LEAVE( iSource->ValidatePacketL( streamId, header, data5 ) );

    header.iPayloadType = KMccPayloadTypeMax;

    // header not OK
    CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(10);
    CleanupStack::PushL( buffer );
    iSource->iBufferToFill = buffer;
    EUNIT_ASSERT_LEAVE( iSource->ValidatePacketL( streamId, header, data5 ) );
    
    // Get a new source
    //Teardown();
    if( iRtpKeepaliveMechanism )
    	{
    	delete iRtpKeepaliveMechanism;
    	iRtpKeepaliveMechanism = NULL;
    	}
    
    if ( iSource )
        {
        delete iSource;
        iSource = NULL;
        }
    //SetupL();
    TUid dummyUid( TUid::Uid( 42 ) ); 
    TBuf8<5> dummyBuf( _L8( "foo" ) );
    iSource = static_cast<CMccRtpDataSource*>(
        CMccRtpDataSource::NewSourceL( dummyUid, dummyBuf ) );
    
    TMccRtpSourceSetting setting;
    setting.iStandByTimerValue = 3000;   
    TMccRtpSourceSettingBuf settingBuf( setting );
    iSource->ConstructSourceL( settingBuf );
    
    MAsyncEventHandler* eventHandler = NULL;
    TRtpId rtpSessionId(0);
    iRtpKeepaliveMechanism = 
        CMccRtpKeepaliveContainer::NewL( *eventHandler, 
                                         *iRtpApi, 
                                         rtpSessionId ); 

    TMccRtpSessionParams params;
    params.iRtpAPI = iRtpApi;
    params.iSessionId = iSession;
    params.iEnableRTCP = EFalse;
    params.iRtpKeepalive = iRtpKeepaliveMechanism;
    EUNIT_ASSERT_NO_LEAVE( iSource->SetSessionParamsL( params ) );

    TMccCodecInfo cInfo;
    cInfo.iFourCC = TFourCC( KMccFourCCIdG711 );
    cInfo.iEnableDTX = ETrue;
    TMccCodecInfoBuffer cInfoBuf( cInfo );
    EUNIT_ASSERT_NO_LEAVE( iSource->ConfigureL( cInfoBuf, iRtpMediaClock ) );

    header.iPayloadType = KPcmuPayloadType;

    // Data ok, stream ok, payload type ok    
    CAmrPayloadFormatRead* amrPfRead = CAmrPayloadFormatRead::NewL( NULL );
    CleanupStack::PushL( amrPfRead );
    
    RArray<TUint> payloads;
    CleanupClosePushL( payloads );
    payloads.AppendL( KPcmuPayloadType );
    iSource->RegisterPayloadTypesL( payloads );
    iSource->FillBufferL( buffer, amrPfRead, TMediaId() );
    EUNIT_ASSERT_NO_LEAVE( iSource->ValidatePacketL( streamId, header, data5 ) );
    CleanupStack::PopAndDestroy( &payloads );
    CleanupStack::PopAndDestroy( amrPfRead );
    CleanupStack::PopAndDestroy( buffer );
    
    }
void UT_CMccRtpDataSource::UT_CMccRtpDataSource_RtpPacketReceivedL()
    {
    TRtpId stream( 0 );
    TRtpId wrongStream( 99 );
    TRtpRecvHeader header;
    TBuf8<5> data;
    data.Format( _L8( "foo42" ) );
    iSource->SourceThreadLogon( *iEventHandler );

    CMMFBuffer* buffer = CMMFDescriptorBuffer::NewL(10);
    CleanupStack::PushL( buffer );    
    CAmrPayloadFormatRead* amrPfRead = CAmrPayloadFormatRead::NewL( NULL );
    CleanupStack::PushL( amrPfRead );
    
    header.iPayloadType = KPcmuPayloadType;    
    RArray<TUint> payloads;
    CleanupClosePushL( payloads );
    payloads.AppendL( KDefaultAmrNbPT );
    payloads.AppendL( KPcmuPayloadType );
    iSource->RegisterPayloadTypesL( payloads );
    CleanupStack::PopAndDestroy( &payloads );
    
    // Wrong stream
    iSource->FillBufferL( buffer, amrPfRead, TMediaId() );
    iSource->RtpPacketReceived( wrongStream, header, data );

    TMccRtpSessionParams params;
    params.iRtpAPI = iRtpApi;
    params.iSessionId = iSession;
    params.iEnableRTCP = EFalse;
    params.iRtpKeepalive = iRtpKeepaliveMechanism;
    EUNIT_ASSERT_NO_LEAVE( iSource->SetSessionParamsL( params ) );

    TMccCodecInfo cInfo;
    cInfo.iFourCC = TFourCC( ' ','A','M','R' );
    cInfo.iBitrate = 8000;
    cInfo.iPayloadType = KDefaultAmrNbPT;
    TMccCodecInfoBuffer cInfoBuf( cInfo );
    
    EUNIT_ASSERT_NO_LEAVE( iSource->ConfigureL( cInfoBuf, iRtpMediaClock ) );
    //iSource->NegotiateSourceL( *iEventHandler );
    EUNIT_ASSERT_NO_LEAVE( iSource->NegotiateSourceL( *amrPfRead ) );
    EUNIT_ASSERT_NO_LEAVE( iSource->SourcePrimeL() );
    EUNIT_ASSERT_NO_LEAVE( iSource->SourcePlayL() );

    stream = 2; // This is what the RtpAPI stub gives
    header.iPayloadType = KDefaultAmrNbPT;
    
    EUNIT_ASSERT_EQUALS( iSource->iTimeoutTime, 0 );
    iSource->FillBufferL( buffer, amrPfRead, TMediaId() );
    iSource->RtpPacketReceived( stream, header, data );
    EUNIT_ASSERT_EQUALS( iSource->iTimeoutTime, 0 );
    EUNIT_ASSERT_EQUALS( iSource->iInactivityTimerId, KMaxTUint32 );
    
    // Inactivity timer is activated when receiving packet
    MCC_EUNIT_ASSERT_NO_LEAVE( iSource->StartInactivityTimerL( 500000 ) );
    iSource->RtpPacketReceived( stream, header, data );
    EUNIT_ASSERT_EQUALS( iSource->iTimeoutTime, 500000 );
    EUNIT_ASSERT( iSource->iInactivityTimerId != KMaxTUint32 );

    // Jitter observing is active
    iSource->iJitCalc->iMediaQualityObservingStarted = ETrue;
    iSource->RtpPacketReceived( stream, header, data );
    
    // Sink not ready, error ignored silently
    iEventHandler->iLastEvent.iEventType = KMccEventNone;
    iSource->iFillBufferRequester = NULL;
    iSource->RtpPacketReceived( stream, header, data );
    EUNIT_ASSERT_EQUALS( iEventHandler->iLastEvent.iEventType, KMccEventNone );
    
    // secure key expired, error ignored silently
    iSource->iSecureKeyExpired = ETrue;
    iSource->RtpPacketReceived( stream, header, data );
    EUNIT_ASSERT_EQUALS( iEventHandler->iLastEvent.iEventType, KMccEventNone );
    
    CleanupStack::PopAndDestroy( amrPfRead );
    CleanupStack::PopAndDestroy( buffer );
    iSource->SourceThreadLogoff();
    }