diff -r 798ee5f1972c -r 826cea16efd9 dvrengine/CommonRecordingEngine/src/CCRRTSPPacketSource.cpp --- a/dvrengine/CommonRecordingEngine/src/CCRRTSPPacketSource.cpp Thu Aug 19 10:54:18 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2854 +0,0 @@ -/* -* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: RTSP Client impl.* -*/ - - - - -// INCLUDE FILES -#include "CCRRtspPacketSource.h" -#include "CCRPunchPacketSender.h" -#include "CCRRtpTcpStreamer.h" -#include "CCRRtspCommand.h" -#include "CCRPacketBuffer.h" -#include -#include "CCRTimer.h" -#include -#include -#include -#include -#include // ROP error codes - -// DATA TYPES -// ###################################################### -// WARNING: JUMBOJET-SIZED KLUDGE AHEAD: -// ###################################################### -#define private public -// Explanation: timestamp getter in rtcp sender report -// class is broken beyond repair. It may be fixed but the -// broken version is already shipped to millions of phones -// around the world. The broken getter method can't -// be overridden as it requires access to private part -// of sender reports instance variables. The item we -// need (ntp timestamp) is there intact in private instance -// variables but there is useless getter for that. -#include - -/* sender report (SR) */ -class TRtcpSRPart - { -public: - TUint32 ssrc; /**< sender generating this report */ - TUint32 ntp_sec; /**< NTP timestamp */ - TUint32 ntp_frac; /**< Fractal seconds */ - TUint32 rtp_ts; /**< RTP timestamp */ - TUint32 psent; /**< packets sent */ - TUint32 osent; /**< octets sent */ - }; -#undef private -// ###################################################### -// Major kludge ends here. -// ###################################################### - -// CONSTANTS -const TInt KCRPortNumberBase( 16670 ); -const TInt KCSeqForRtspNegoation( 42 ); -const TInt KRtspPortNumber( 554 ); -const TInt KRtpPacketVersion( 2 ); -const TUint KSenderReportPacketType( 0xC8 ); // 200 decimal -const TInt KDVR10Seconds( 10000000 ); - -// The number of sequential packets that must be received -// before a stream is considered good. 1 means no delay, start -// from very first packet -const TInt KDVRMinSequential( 1 ); -// The maximum number of dropped packets to be considered a -// dropout, as opposed to an ended and restarted stream. -const TInt KDVRMaxMisorder( 50 ); -// The maximum number of packets by which a packet can be delayed -// before it is considered dropped. -const TInt KDVRMaxDropOut( 3000 ); -_LIT( KRtspPortString, "554" ); -_LIT8( KCRCName, "N++ " ); -// Timeout for RTP/UDP reception before switching to TCP mode -const TTimeIntervalMicroSeconds32 KCRRtspRtpUdpTimeout( 10 * 1e6 ); -// Timeout for waiting for server response to any RTSP command -const TTimeIntervalMicroSeconds32 KCRRtspResponseTimeout( 15 * 1e6 ); -// Timeout for waiting for server response to TIERDOWN command -const TTimeIntervalMicroSeconds32 KCRRtspTierdownTimeout( 3 * 1e6 ); - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::NewL -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -CCRRtspPacketSource* CCRRtspPacketSource::NewL( - const SCRRtspParams& aParams, - CCRConnection& aConnection, - RSocketServ& aSockServer, - MCRStreamObserver& aSessionObs, - CCRStreamingSession& aOwningSession ) - { - CCRRtspPacketSource* self = new( ELeave ) - CCRRtspPacketSource( aConnection, aSockServer, aSessionObs, aOwningSession ); - CleanupStack::PushL( self ); - self->ConstructL( aParams ); - CleanupStack::Pop( self ); - return self; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::CCRRtspPacketSource -// C++ default constructor can NOT contain any code, that might leave. -// ----------------------------------------------------------------------------- -// -CCRRtspPacketSource::CCRRtspPacketSource( - CCRConnection& aConnection, - RSocketServ& aSockServer, - MCRStreamObserver& aSessionObs, - CCRStreamingSession& aOwningSession ) - : CCRPacketSourceBase( aOwningSession, CCRStreamingSession::ECRRtspSourceId ), - iSockServer( aSockServer ), - iConnection( aConnection ), - iStage( ERTSPInit ), - iCSeq( KCSeqForRtspNegoation ), - iClientPort( KCRPortNumberBase ), - iSessionId(NULL, 0 ), - iReadyToPlay(EFalse), - iSessionObs( aSessionObs ), - iStartPos( KRealZero ), - iEndPos( KRealMinusOne ), - iUdpFound( EFalse ), - iTrafficFound( EFalse ) - { - // None - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ConstructL -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ConstructL( const SCRRtspParams& aParams ) - { - LOG( "CCRRtspPacketSource::ConstructL() in" ); - if ( aParams.iUrl.Length() == 0 ) - { - User::Leave ( KErrArgument ); - } - - iSentData = HBufC8::NewL ( KCROptionsReply().Length() + KMaxInfoName ); - iRtpTcpStreamer = CCRRtpTcpStreamer::NewL( *this ); - iRtspUri = aParams.iUrl.AllocL(); - iRtspUri8 = HBufC8::NewL( aParams.iUrl.Length()); - iRtspUri8->Des().Copy( aParams.iUrl ); - iUserName = aParams.iUserName.AllocL(); - iPassword = aParams.iPassword.AllocL(); - User::LeaveIfError( iConnection.RegisterObserver( this ) ); - iUdpReceptionTimer = CCRTimer::NewL( EPriorityLow, *this ); - iProxyServerAddr = aParams.iProxyServerAddr; - iProxyServerPort = aParams.iProxyServerPort; - DoConnectL(); // Makes no sense to construct without immediately connecting - - LOG( "CCRRtspPacketSource::ConstructL() out" ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::~CCRRtspPacketSource -// Destructor. -// ----------------------------------------------------------------------------- -// -CCRRtspPacketSource::~CCRRtspPacketSource() - { - LOG( "CCRRtspPacketSource::~CCRRtspPacketSource() in" ); - // Deletes everything related to session - CleanUp(); - delete iRtspTimeout; - delete iSentData; - delete iAuthType; - delete iRtspUri8; - delete iUserName; - delete iPassword; - delete iNonce; - delete iOpaque; - delete iRealm; - delete iRtpTcpStreamer; - delete iUdpReceptionTimer; - iReceiveStreams.Reset(); - iObserver = NULL; - iConnection.UnregisterObserver( this ); - LOG( "CCRRtspPacketSource::~CCRRtspPacketSource() out" ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::CleanUp -// Callback method called from cleanup-cidle that just calls the actual -// cleanup method. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::CleanUp() - { - LOG( "CCRRtspPacketSource::CleanUp() in" ); - if ( iUdpReceptionTimer ) - { - iUdpReceptionTimer->Cancel(); - } - delete iRtspPingTimer; - iRtspPingTimer = NULL; - - iRtpRecvSrcAudio.Close(); - iRtpRecvSrcVideo.Close(); - iAudioSession.Close(); - iVideoSession.Close(); - iReadyToPlay = EFalse; - delete iSdpParser; iSdpParser = NULL; - delete iRtspUri; iRtspUri = NULL; - delete iRtspSock; iRtspSock = NULL; - - for ( TInt i( 0 ); i < ERTPMaxSockets; i++ ) - { - delete iRTPSockArr[i]; - iRTPSockArr[i] = NULL; - } - for ( TInt i( 0 ); i < ERTSPLastStage; i++ ) - { - delete iPrevCommands[i]; - iPrevCommands[i] = NULL; - delete iResponses[i]; - iResponses[i] = NULL; - } - - iSessionId.Set( NULL, 0 ); - delete iPunchPacketSenderAudio; iPunchPacketSenderAudio = NULL; - delete iPunchPacketSenderVideo; iPunchPacketSenderVideo = NULL; - delete iUserAgent; iUserAgent = NULL; - delete iWapProfile; iWapProfile = NULL; - iStartPos = KRealZero; - iEndPos = KRealMinusOne; - - LOG( "CCRRtspPacketSource::CleanUp() out" ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::DoConnectL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::DoConnectL( void ) - { - if ( !iRtspUri ) - { - User::Leave( KErrNotReady ); - } - if ( iRtspSock ) - { - delete iRtspSock; iRtspSock = NULL; - } - - iRtspSock = CCRSock::NewL( *this, ERTPControl, iConnection.Connection(), - iSockServer, ETrue, ETrue ); - TUriParser uriParser; - User::LeaveIfError( uriParser.Parse( iRtspUri->Des() ) ); - iRtspUriHost.Set( uriParser.Extract( EUriHost ) ); - TPtrC portString( KRtspPortString ); - if ( uriParser.IsPresent( EUriPort ) ) - { - portString.Set( uriParser.Extract( EUriPort ) ); - } - - TLex portLex( portString ); - TInt port( KRtspPortNumber ); - if ( portLex.Val( port ) != KErrNone ) - { - User::Leave( KErrMMInvalidURL ); - } - if ( iProxyServerAddr.Length() && iProxyServerPort ) - { - LOG2( "CCRRtspPacketSource::DoConnectL(), Proxy: %S port: %d", - &iProxyServerAddr, iProxyServerPort ); - User::LeaveIfError( iRtspSock->ConnectSock( iProxyServerAddr, iProxyServerPort ) ); - } - else - { - User::LeaveIfError(iRtspSock->ConnectSock( iRtspUriHost, port ) ); - } - iCSeq = KCSeqForRtspNegoation; - - TTime now; - now.UniversalTime(); - iClientPort = - KCRPortNumberBase + ( ( now.DateTime().MicroSecond() / 1000 ) * 2 ); - - // Get transport method from connection heuristics - iTransport = ( iConnection.GetHeuristic( - CCRConnection::EUdpStreamingBlocked ) )? ERTPOverTCP: ERTPOverUDP; - LOG1( "CCRRtspPacketSource::DoConnectL(), RTP transport: %d (0=UDP, 1=TCP)", iTransport ); - - // Get user agent, bandwidth and wap profile based on connection bearer (3G or not) - TConnMonBearerType bearer = iConnection.BearerType(); - TBool is3g( iConnection.IsBearerWLANor3G( bearer ) ); - - // Fetch wap profile from WebUtils repository - if ( !iWapProfile ) - { - CRepository* repository = CRepository::NewLC( KCRUidWebUtils ); - TUint32 profilekey = ( is3g )? KWebUtilsUaProf3G: KWebUtilsUaProf; - TFileName profilebuf( KNullDesC ); - if ( !repository->Get( profilekey, profilebuf ) ) - { - iWapProfile = HBufC8::NewL( profilebuf.Length() ); - iWapProfile->Des().Copy( profilebuf ); - } - - CleanupStack::PopAndDestroy( repository ); - LOG1( "CCRRtspPacketSource::DoConnectL(), iWapProfile: %S", &profilebuf ); - } - - // Fetch user agent - // Should we add version information to user agent string? - delete iUserAgent; iUserAgent = NULL; - iUserAgent = KCRRTSPDefaultUserAgent().AllocL(); - - // Get bandwidth from connection - iBandwidth = iConnection.MaximumBandwidth(); - - LOG( "CCRRtspPacketSource::DoConnectL out" ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::URI -// ----------------------------------------------------------------------------- -// -TPtr CCRRtspPacketSource::URI(void) - { - __ASSERT_DEBUG( iRtspUri != NULL , User::Panic( _L( "RTSP source" ), KErrBadHandle ) ); - TPtr retval ( NULL , 0 ); - if ( iRtspUri ) - { - retval.Set( iRtspUri->Des() ); - } - else - { - LOG( "CCRRtspPacketSource::URI iRtspUri was NULL !!!!!!!!!! " ); - } - return retval; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::GetSdp -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::GetSdp( TPtrC8& aSdp ) - { - TInt retval( KErrNotReady ); - if ( iSdpParser ) - { - return iSdpParser->GetSdp( aSdp ); - } - - return retval; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SeqAndTS -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::SeqAndTS( - TUint& aAudioSeq, - TUint& aAudioTS, - TUint& aVideoSeq, - TUint& aVideoTS ) - { - TInt retval( KErrNotReady ); - if ( iSeqFromRtpInfoForVideo != 0 || iSeqFromRtpInfoForAudio != 0 ) - { - aAudioSeq = iSeqFromRtpInfoForAudio; - aAudioTS = iRTPTimeStampAudio; - aVideoSeq = iSeqFromRtpInfoForVideo; - aVideoTS = iRTPTimeStampVideo; - retval = KErrNone; - } - - return retval; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::PostActionL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::PostActionL() - { - LOG1( "CCRRtspPacketSource::PostActionL(), SDP will be handled, iSdpParser: %d", - iSdpParser ); - User::LeaveIfNull( iSdpParser ); - iSessionObs.StatusChanged( MCRPacketSource::ERtpStateSdpAvailable ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::Play -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::Play( const TReal& aStartPos, const TReal& aEndPos ) - { - LOG2( "CCRRtspPacketSource::Play(), aStartPos: %f, aEndPos: %f", - aStartPos, aEndPos ); - LOG2( "CCRRtspPacketSource::Play(), sent seq: %d, rec: %d", - iCSeq, iLastReceivedSeq ); - iReadyToPlay = ETrue; - iStartPos = aStartPos; - iEndPos = aEndPos; - ResetStreamFlags(); - - // In xps case we never get startpos with this method. - // instead setposition will be called - if ( iBuffer ) - { - iBuffer->ResetBuffer(); - } - - // If both audio and video sessions are closed, we - // need to open at least one of them: - TInt err( KErrNone ); - if ( iStage == ERTSPReadyToPlay || iStage == ERTSPPauseSent ) - { - if ( iStage == ERTSPReadyToPlay || iCSeq == ( iLastReceivedSeq + 1 ) ) - { - TRAP( err, SendPlayCommandL() ); - } - else - { - // We have a fast-fingered user in charge; play has been issued - // but the previous pause has not been completed yet: postpone this - // operation - iPostPonedPlay = ETrue; - } - } - - return err; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::Pause -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::Pause() - { - LOG1( "CCRRTSPPacketSource::Pause() stage %d", iStage ); - TInt err( KErrNotReady ); - if ( iStage == ERTSPPlaying ) - { - if ( iResponses[ERTSPPlaySent]->IsLiveStream() || iSdpParser->IsLiveStream() ) - { - err = KErrNotSupported; - } - else - { - TRAP( err, SendPauseCommandL() ); - } - } - if ( iStage == ERTSPPauseSent ) - { - err = KErrNone; - } - return err; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::Stop -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::Stop() - { - LOG( "CCRRtspPacketSource::Stop()" ); - - iReadyToPlay = EFalse; - iPostPonedPlay = EFalse; - iStartPos = KRealZero; - TInt err( KErrDisconnected ); - - if ( iStage == ERTSPPlaySent || iStage == ERTSPPlaying || - iStage == ERTSPPauseSent || iStage == ERTSPSetupAudioSent || - iStage == ERTSPSetupVideoSent ) - { - err = KErrNone; - if ( iRtspSock ) - { - iRtspSock->Cancel(); - } - - TRAP_IGNORE( SendTearDownCommandL() ); // if this fails, we don't care - iStage = ERTSPTearDownSent; - StartRtspTimeout( KCRRtspTierdownTimeout ); - } - - return err; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SetPosition -// ----------------------------------------------------------------------------- - -TInt CCRRtspPacketSource::SetPosition( const TInt64 aPosition ) - { - LOG1( "CCRRtspPacketSource::SetPosition(), iStartPos: %f", iStartPos ); - - if ( aPosition == -2 ) - { - if ( iStage != ERTSPPlaySent && iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRReadyToSeek, KErrNone ); - } - } - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::GetRange -// ----------------------------------------------------------------------------- -void CCRRtspPacketSource::GetRange( TReal& aLower, TReal& aUpper ) - { - aLower = KRealZero; - aUpper = KRealMinusOne; - - if ( ( iStage == ERTSPPlaySent || iStage == ERTSPPlaying ) && - iResponses[ERTSPPlaySent] ) - { - iResponses[ERTSPPlaySent]->GetRange(aLower,aUpper); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::DataReceived -// This is called when data is received from socket. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::DataReceived( TInt /*aSockId*/, const TDesC8& aData ) - { - // Find out RTCP message or RTP packet from IP packet - iRtpTcpStreamer->DataAvailable( aData, ( iTransport == ERTPOverTCP ) ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::RtspMsgAvailable -// This is called when data is received from socket. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::RtspMsgAvailable( const TDesC8& aData ) - { -#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) - if ( aData.Length() > 0 ) - { - LOG1( "CCRRtspPacketSource::RtspMsgAvailable(), aData len: %d", aData.Length() ); - TName d( KNullDesC ); - for( TInt i( 0 ); i < aData.Length(); i++ ) - { - TChar c = aData[i]; - d.Append( c ); - if ( ( i > 0 ) && ( i % 80 ) == 0 ) - { - LOG1( ">%S<", &d ); - d.Zero(); - } - } - - LOG1( ">%S<", &d ); - } -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - - TRAPD( err, ProcessRtspResponseL( aData ) ); - if ( err ) - { - LOG1( "CCRRtspPacketSource::RtspMsgAvailable(), ProcessRtspResponseL Leaved, err: %d", err ); - if ( err == KErrNotSupported ) - { - // The response did not look like rtsp response at all. - // some servers decide to send rtsp commands to us so lets - // try interpreting it as a command - err = KErrNone; - TRAP( err, ProcessRTSPCommandL( aData ) ) - if ( err ) - { - iOwningSession.SourceStop(); - } - } - else - { - iOwningSession.SourceStop(); - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SockStatusChange -// This is called when socket status changes. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SockStatusChange( - TInt aSockId, - CCRSock::TCRSockStatus aStatus, - TInt aError ) - { -#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) - if ( aStatus == CCRSock::EFailed ) - { - LOG3( "CCRRtspPacketSource::SockStatusChange(), aSockId: %d, aStatus: %d, aError: %d", - aSockId, aStatus, aError ); - } -#else // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - ( void )aSockId; - ( void )aError; -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - - if ( aStatus == CCRSock::EFailed ) - { - // Ask session to perform cleanup - iOwningSession.SourceStop(); - - if ( iStage == ERTSPInit && aSockId == ERTPControl && aError == KErrCouldNotConnect ) - { - // map error to different error id, so we can know that showing reconnect query is pointless. - aError = KErrEof; - } - - // Inform the observer that there is a problem. Exclude case where we're closing - // and the error is KErrEof - if ( ! ( iStage == ERTSPTearDownSent && aError == KErrEof ) ) - { - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), ECRConnectionError, aError ); - } - } - else - { - LOG( "CCRRtspPacketSource::SockStatusChange(), eof in closing: normal" ); - } - } - else if ( aSockId == ERTPControl && aStatus == CCRSock::EIdle && - iStage == ERTSPInit ) - { - // Called once from here for lifetime of this object - TRAPD( err, SendRtspCommandL() ); - if ( err ) - { - LOG1( "CCRRtspPacketSource::SockStatusChange(), SendRtspCommandL Leaved: %d", err ); - - // Ask session to perform cleanup - iOwningSession.SourceStop(); - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::RtpTcpPacketAvailable -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::RtpTcpPacketAvailable( - TInt aChannel, - const TDesC8& aPacket ) - { - // Map embedded TCP channel to streamid: - // video: channel=(0,1) --> id=(2,3) - // audio: channel=(2,3) --> id=(0,1) when video present - // audio: channel=(0,1) --> id=(0,1) when audio only - TInt mappedChannel( ( iSdpParser->VideoControlAddr().Length() )? - ( aChannel + 2 ) % 4: aChannel ); - MCRPacketSource::TCRPacketStreamId streamid( - ( MCRPacketSource::TCRPacketStreamId )( mappedChannel ) ); - - iBuffer->AddPacket( streamid, aPacket ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ForwardRtpTcpChunk -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ForwardRtpTcpChunck( const TDesC8& aChunk ) - { - if ( iRtspSock ) - { - iRtspSock->SendData( aChunk ); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::TimerExpired -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::TimerExpired( CCRTimer* ) - { - LOG( "CCRRtspPacketSource::TimerExpired: RTP/UDP timer expired, switching to RTP/TCP" ); - - if ( !iUdpFound ) - { - // Signal heuristic for TCP streaming - LOG( "CCRRtspPacketSource::TimerExpired - Switch to TCP" ); - iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, ETrue ); - } - else - { - // We had UDP before in this session but now it is lost for some reason. - // Try UDP again. - - // Flag UDP found away - iUdpFound = EFalse; - iTrafficFound = EFalse; - - // Clear stream followup - iReceiveStreams.Reset(); - - LOG( "CCRRtspPacketSource::TimerExpired - Trying UDP again" ); - } - - // Notify client to close us and start a new session - if ( iObserver ) - { - // Notify client - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), ECRSwitchingToTcp, KErrNone ); - } - else - { - // If no client observer, teardown and cleanup ourselves - iPostPonedPlay = EFalse; - TRAPD( err, SendTearDownCommandL() ); - if ( err != KErrNone ) - { - LOG1( "CCRRtspPacketSource::TimerExpired() Send TEARDOWN failed: %d", err ); - } - - CleanUp(); - iSessionObs.StatusChanged( MCRPacketSource::ERtpStateClosing ); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ProcessRTSPCommandL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ProcessRTSPCommandL( const TDesC8& aData ) - { - LOG1( "CCRRtspPacketSource::ProcessRTSPCommandL(), iStage: %d", ( int )iStage ); - - CCRRtspCommand* cmd = CCRRtspCommand::NewL(); - CleanupStack::PushL( cmd ); - cmd->TryParseL( aData ); - - switch ( cmd->Command() ) - { - case CCRRtspCommand::ERTSPCommandOPTIONS: - iSentData->Des().Format( KCROptionsReply, cmd->CSeq() ); - iRtspSock->SendData( iSentData->Des() ); - break; - - default: - // Server sent us a command and it is not options. - // for sure they want us to stop ; is there - iOwningSession.SourceStop(); - break; - } - - CleanupStack::PopAndDestroy( cmd ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ProcessRtspResponseL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ProcessRtspResponseL( const TDesC8& aData ) - { - LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), iStage: %d", iStage ); - - // Cancel timeout timer - if ( iRtspTimeout ) - { - iRtspTimeout->Cancel(); - } - - // The server responded to our TEARDOWN command. No need to parse the response - // since we don't care what the server said. Ask session to clean us up. - if ( iStage == ERTSPTearDownSent ) - { - iOwningSession.SourceStop(); - return; - } - - // First parse response - CCRRtspResponse* resp = CCRRtspResponse::NewL(); - CleanupStack::PushL( resp ); - resp->TryParseL( aData ); - - // Then find the command that this resp is associated with: - iLastReceivedSeq = resp->CSeq(); - TBool commandFound( EFalse ); - for ( TInt i( 0 ); i < ERTSPLastStage && !commandFound; i++ ) - { - LOG2( "CCRRtspPacketSource:: prevcommand stage: %d cseq: %d", - i, ( iPrevCommands[i] )? iPrevCommands[i]->CSeq(): KErrNotFound ); - - if ( iPrevCommands[i] && ( iPrevCommands[i]->CSeq() == resp->CSeq() ) ) - { - LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), matching command: %d", i ); - LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), cseq was: %d", resp->CSeq() ); - delete iResponses[i]; - CleanupStack::Pop( resp ); - iResponses[i] = resp; - commandFound = ETrue; - if ( i == ERTSPOptSent ) - { - // Process options no further, used only for ping here - return; - } - } - } - - // Delete response if sequency not match - if ( !commandFound ) - { - CleanupStack::PopAndDestroy( resp ); - LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), Command not found, cseq: %d", resp->CSeq() ); - } - else - { - if ( iResponses[iStage]->StatusCode() == CCRRtspResponse::ERTSPRespOK || // 200 - iResponses[iStage]->StatusCode() == CCRRtspResponse::ERTSPRespCreated ) // 201 - { - // Extract useful information from response depending on stage: - switch ( iStage ) - { - case ERTSPSetupAudioSent: // From setups take session id - case ERTSPSetupVideoSent: - if ( !iSessionId.Ptr() ) - { - iResponses[iStage]->SessionId( iSessionId ); - } - // Check for sdp parser and send punch packets for UDP transport - // (TCP or multicast: session setup and PLAY in SendRTSPCommand) - if ( iSdpParser && iTransport == ERTPOverUDP ) - { - // If we see that we don't need to send further setups, - // do send punch packets now. - if ( ( iSdpParser->VideoControlAddr().Length() && // if we have video - iResponses[ERTSPSetupVideoSent] && // and we have video se tup - iSdpParser->AudioControlAddr().Length() && // and we have audio - iResponses[ERTSPSetupAudioSent] ) || // and we have audio set up or... - ( !iSdpParser->VideoControlAddr().Length() && // if we have no video - !iResponses[ERTSPSetupVideoSent] && // and we've video not set up - iSdpParser->AudioControlAddr().Length() && // and it shows we have audio - iResponses[ERTSPSetupAudioSent] ) || // and we've audio set up or... - ( iSdpParser->VideoControlAddr().Length() && // if we have video - iResponses[ERTSPSetupVideoSent] && // and we have video set up - !iSdpParser->AudioControlAddr().Length() && // and we have no audio - !iResponses[ERTSPSetupAudioSent] ) ) // and we have no audio set up - { - SendPunchPacketsL(); - } - } - - // Notify sink that SETUP repply received - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStateSetupRepply ); - break; - - case ERTSPDescSent: // From desc take sdp - if ( iObserver && iResponses[iStage]->ContentLen() <= 0 ) - { - // This should not happen - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), ECRConnectionError, KErrUnderflow ); - } - iOwningSession.SourceStop(); - } - else - { - delete iSdpParser; iSdpParser = NULL; - iSdpParser = CDvrSdpParser::NewL(); - if ( iResponses[iStage]->ContentBase().Length() ) - { - iSdpParser->TryParseL( iResponses[iStage]->Content(), - iResponses[iStage]->ContentBase() ); - } - else - { - iSdpParser->TryParseL( iResponses[iStage]->Content(), - iRtspUri8->Des() ); - } - // Check for multicast address in SDP - if ( iSdpParser->IsMultiCastSdp() ) - { - iTransport = ERTPOverMulticast; - } - if ( iObserver && iSdpParser->IsRealMediaContent() ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRStreamIsRealMedia, KErrNotSupported ); - iOwningSession.SourceStop(); - return; // Make sure we don't continue with SETUP commands - } - else // do not send realmedia sdp to sinks - { - if ( iObserver && iSdpParser->IsLiveStream() ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRStreamIsLiveStream, KErrNone ); - } - - // then check for bandwidth requirements even before we start: - if ( iObserver ) - { - // Unknown bitrate or bandwidth are returned as zero. - // Bitrates in kbit/s - TInt bitrate( iSdpParser->VideoBitrate() + - iSdpParser->AudioBitrate() ); - TInt bandwidth( iConnection.MaximumBandwidth() / 1000 ); - if ( bitrate && bandwidth && bandwidth < bitrate ) - { - LOG2( "CCRRtspPacketSource::ProcessRtspResponseL(), bitrate:%d, bandwidth: %d -> NotEnoughBandwidth", - bitrate, bandwidth); - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRNotEnoughBandwidth, KErrNone ); - return; // Make sure we don't tell sinks anything about - // sdp that has too high bitrate for our network bearer - } - } - - // But if we didn't have realmedia stream and the bandwidth check - // is also all right, then go on and tell the sinks -> - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStateSdpAvailable ); - } - } - break; - - case ERTSPPlaySent: - { - CCRRtspResponse::SRTPInfoHeader rtpInfo; - iResponses[ERTSPPlaySent]->RTPInfoHeader( rtpInfo ); - - TPtrC8 videoAddr ( NULL, 0 ); - if ( iSdpParser->VideoControlAddr().Length() ) - { - videoAddr.Set ( iSdpParser->VideoControlAddr() ); - } - TPtrC8 audioAddr ( NULL , 0 ); - if ( iSdpParser->AudioControlAddr().Length() ) - { - audioAddr.Set ( iSdpParser->AudioControlAddr() ); - } - - if ( iSdpParser->VideoControlAddr().Length() && - rtpInfo.iFirstURL.Length() && - videoAddr.Find( rtpInfo.iFirstURL ) >= 0 ) - { - iRTPTimeStampVideo = rtpInfo.iFirstTS ? rtpInfo.iFirstTS : 1; - iSeqFromRtpInfoForVideo = rtpInfo.iFirstSeq; - } - if ( iSdpParser->VideoControlAddr().Length() && - rtpInfo.iSecondURL.Length() && - videoAddr.Find( rtpInfo.iSecondURL ) >= 0 ) - { - iRTPTimeStampVideo = rtpInfo.iSecondTS ? rtpInfo.iSecondTS : 1; - iSeqFromRtpInfoForVideo = rtpInfo.iSecondSeq; - } - if ( iSdpParser->AudioControlAddr().Length() && - rtpInfo.iFirstURL.Length() && - audioAddr.Find( rtpInfo.iFirstURL) >= 0 ) - { - iRTPTimeStampAudio = rtpInfo.iFirstTS ? rtpInfo.iFirstTS : 1; - iSeqFromRtpInfoForAudio = rtpInfo.iFirstSeq; - } - if ( iSdpParser->AudioControlAddr().Length() && - rtpInfo.iSecondURL.Length() && - audioAddr.Find( rtpInfo.iSecondURL) >= 0 ) - { - iRTPTimeStampAudio = rtpInfo.iSecondTS ? rtpInfo.iSecondTS : 1; - iSeqFromRtpInfoForAudio = rtpInfo.iSecondSeq; - } - - // ok, if we don't have rtp-info header, we don't know yet. - if ( rtpInfo.iFirstURL.Length() == 0 && - rtpInfo.iSecondURL.Length() == 0 ) - { - iNoRtpInfoHeader++; - } - else - { - // We have RTP-info, so control stream is no longer mandatory - // Mark control streams as "found" - StreamFound( EAudioControlStream ); - StreamFound( EVideoControlStream ); - //StreamFound( ESubTitleControlStream ); - - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStateSeqAndTSAvailable ); - } - - // Live state - if ( iResponses[ERTSPPlaySent]->IsLiveStream() || iSdpParser->IsLiveStream() ) - { - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRStreamIsLiveStream, KErrNone ); - } - } - - // Notify seeking - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRReadyToSeek, KErrNone ); - } - } - break; - - default: - // by default extract no information - break; - } - - // Then continue with business: - SendRtspCommandL(); // will change iStage also - } - - // Authentication needed.. - else if ( iResponses[iStage]->StatusCode() == - CCRRtspResponse::ERTSPRespUnauthorized || // 401 - iResponses[iStage]->StatusCode() == - CCRRtspResponse::ERTSPRespProxyAuthenticationRequired ) // 407 - { - iAuthFailedCount++; - if ( iUserName && - iUserName->Length() && - iPassword && - iAuthFailedCount == 1 ) - { - iAuthenticationNeeded = ETrue; - iAuthType = iResponses[iStage]->AuthenticationTypeL().AllocL(); - iRealm = iResponses[iStage]->RealmL().AllocL(); - iOpaque = iResponses[iStage]->OpaqueL().AllocL(); - iNonce = iResponses[iStage]->NonceL().AllocL(); - SendAuthDescribeL(); - } - else - { - iAuthFailedCount = 0; - LOG( "CCRRtspPacketSource::ProcessRtspResponseL() Authentication failure !" ); - - // Cleanup - iOwningSession.SourceStop(); - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRAuthenticationNeeded, KErrNone ); - } - } - } - else if ( iResponses[iStage]->StatusCode() == CCRRtspResponse::ERTSPRespUnsupportedTransport ) // 461 - { - LOG1( "CCRRtspPacketSource::ProcessRtspResponseL() - Unsupported Transport: %d", iTransport ); - - if ( iConnection.GetHeuristic( CCRConnection::EUdpStreamingBlocked ) ) - { - // Using TCP, change to UDP - LOG( "CCRRtspPacketSource::ProcessRtspResponseL() - Change TCP to UDP" ); - iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, EFalse ); - // Notify observer at client side: - ProcessRtspErrorResponseL( iResponses[iStage]->StatusCode() ); - } - else - { - // Using UDP, change to TCP - LOG( "CCRRtspPacketSource::ProcessRtspResponseL() - Change UDP to TCP"); - iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, ETrue ); - // Notify observer at client side: - ProcessRtspErrorResponseL( iResponses[iStage]->StatusCode() ); - } - } - else - { - // before doing cleanup, notify observer at client side: - ProcessRtspErrorResponseL( iResponses[iStage]->StatusCode() ); - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ProcessRtspErrorResponseL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ProcessRtspErrorResponseL( - CCRRtspResponse::TResponseCode aErrorCode ) - { - SCRQueueEntry entry; - entry.iMsg = ECRMsgQueueConnectionError; - - switch ( aErrorCode ) - { - case CCRRtspResponse::ERTSPRespLowOnStorageSpace: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespMultipleChoices: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespMovedPermanently: - entry.iErr = KErrNotFound; - break; - - case CCRRtspResponse::ERTSPRespMovedTemporarily: - entry.iErr = KErrNotFound; - break; - - case CCRRtspResponse::ERTSPRespSeeOther: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespNotModified: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespUseProxy: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespBadRequest: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespPaymentRequired: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespForbidden: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespGone: - case CCRRtspResponse::ERTSPRespConferenceNotFound: - case CCRRtspResponse::ERTSPRespNotFound: - entry.iErr = KErrNotFound; - break; - - case CCRRtspResponse::ERTSPRespMethodNotAllowed: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespNotAcceptable: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespRequestTimeOut: - entry.iErr = KErrTimedOut; - break; - - case CCRRtspResponse::ERTSPRespLengthRequired: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespPreconditionFailed: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespRequestEntityTooLarge: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespRequestURITooLarge: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespParameterNotUnderstood: - entry.iErr = KErrArgument; - break; - - case CCRRtspResponse::ERTSPRespNotEnoughBandwidth: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespSessionNotFound: - entry.iErr = KErrCouldNotConnect; - break; - - case CCRRtspResponse::ERTSPRespMethodNotValidInThisState: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespHeaderFieldNotValidForResource: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespInvalidRange: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespParameterIsReadOnly: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespAggregateOperationNotAllowed: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespOnlyAggregateOperationAllowed: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespUnsupportedTransport: - entry.iErr = KErrCouldNotConnect; - break; - - case CCRRtspResponse::ERTSPRespDestinationUnreachable: - entry.iErr = KErrCouldNotConnect; - break; - - case CCRRtspResponse::ERTSPRespInternalServerError: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespNotImplemented: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespBadGateway: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespServiceUnavailable: - entry.iErr = KErrCouldNotConnect; - break; - - case CCRRtspResponse::ERTSPRespGatewayTimeOut: - entry.iErr = KErrGeneral; - break; - - case CCRRtspResponse::ERTSPRespUnsupportedMediaType: - case CCRRtspResponse::ERTSPRespOptionNotSupported: - case CCRRtspResponse::ERTSPRespRTSPVersionNotSupported: - entry.iErr = KErrNotSupported; - break; - - default: - entry.iErr = KErrGeneral; - break; - } - - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), ECRConnectionError, entry.iErr ); - } - - // Try tear down first - if ( Stop() == KErrDisconnected ) - { - iOwningSession.SourceStop(); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::StartRtspTimeout -// Starts RTSP command response timeout. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::StartRtspTimeout( TTimeIntervalMicroSeconds32 aTime ) - { - // Start a timeout timer to wait for the server to respond. - // If the server doesn't respond in time, cleanup will be initialized. - if ( !iRtspTimeout ) - { - TRAPD( err, iRtspTimeout = - CPeriodic::NewL( CActive::EPriorityStandard ) ); - if ( err != KErrNone ) - { - // Timer creation failed, start cleanup immediately - iOwningSession.SourceStop(); - } - } - else - { - iRtspTimeout->Cancel(); - } - - // Start timeout timer - iRtspTimeout->Start( - aTime, - aTime, - TCallBack( RtspTimeoutCallback, this ) ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::RtspTimeoutCallback -// Callback for RTSP response timeout. Just ask session to start cleanup -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::RtspTimeoutCallback( TAny* aPtr ) - { - LOG( "CCRRtspPacketSource::RtspTimeoutCallback()" ); - - CCRRtspPacketSource* self = static_cast( aPtr ); - self->iRtspTimeout->Cancel(); - self->iOwningSession.SourceStop(); - return 0; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendRtspCommandL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendRtspCommandL() - { - LOG1( "CCRRtspPacketSource::SendRtspCommandL(), iStage: %d", iStage ); - - if ( iPostPonedPlay ) - { - iPostPonedPlay = EFalse; - Play( iStartPos, iEndPos ); - } - else - { - switch ( iStage ) - { - case ERTSPInit: - case ERTSPOptSent: - { - delete iPrevCommands[ERTSPDescSent]; - iPrevCommands[ERTSPDescSent] = NULL; - iPrevCommands[ERTSPDescSent] = CCRRtspCommand::NewL(); - iPrevCommands[ERTSPDescSent]->SetCommand( - CCRRtspCommand::ERTSPCommandDESCRIBE ); - - TPtrC8 uriDes ( iRtspUri8->Des() ); - iPrevCommands[ERTSPDescSent]->SetURL( uriDes ); - iPrevCommands[ERTSPDescSent]->SetCSeq( iCSeq++ ); - if ( iUserAgent ) - { - iPrevCommands[ERTSPDescSent]->SetUserAgentL( *iUserAgent ); - } - if ( iWapProfile ) - { - iPrevCommands[ERTSPDescSent]->SetWapProfileL( *iWapProfile ); - } - if ( iBandwidth ) - { - iPrevCommands[ERTSPDescSent]->SetBandwidth( iBandwidth ); - } - - if ( iRtspSock ) - { - iRtspSock->SendData( iPrevCommands[ERTSPDescSent]->ProduceL() ); - StartRtspTimeout( KCRRtspResponseTimeout ); - iStage = ERTSPDescSent; - } - } - break; - - case ERTSPDescSent: - if ( iSdpParser ) - { - const TInt audio( iSdpParser->MediaIdentifierAudio() ); - const TInt video( iSdpParser->MediaIdentifierVideo() ); - TBool videoExists( iSdpParser->VideoControlAddr().Length() > 0 ); - TBool audioExists( iSdpParser->AudioControlAddr().Length() > 0 ); - - /* If both medias are reported with dynamic payload - * type and audio stream is reported with lower - * payload type, then some servers don't work correctly - * if the SETUP commands are not in correct order, ie. - * we need to first SETUP the audio stream here. - */ - const TBool audioBeforeVideo( - audioExists && audio >= 96 && video >= 96 && audio < video ); - - if ( videoExists && !audioBeforeVideo ) - { - SendSetupCommandL( iSdpParser->VideoControlAddr(), EFalse ); - iStage = ERTSPSetupVideoSent; - } - else if ( audioExists ) - { - SendSetupCommandL( iSdpParser->AudioControlAddr(), ETrue ); - iStage = ERTSPSetupAudioSent; - } - else - { - LOG1( "CCRRtspPacketSource::SendRtspCommand stag %d have no audio nor video", - ( TInt )iStage ); - // no audio, no video, el panique grande - iOwningSession.SourceStop(); - } - } - break; - - case ERTSPSetupAudioSent: - { - const TInt audio( iSdpParser->MediaIdentifierAudio() ); - const TInt video( iSdpParser->MediaIdentifierVideo() ); - - if ( audio >= 96 && video >= 96 && audio < video && - iSdpParser && iSdpParser->VideoControlAddr().Length() ) - { - // Video exists also and has not been setup before, so - // let's setup it now. - - TPtrC8 ctrlAddr ( iSdpParser->VideoControlAddr() ); - SendSetupCommandL( ctrlAddr, EFalse ); - iStage = ERTSPSetupVideoSent; - } - else - { - ConditionallySetupMultiCastOrTcpStreamingL(); - } - } - break; - - case ERTSPSetupVideoSent: - { - const TInt audio( iSdpParser->MediaIdentifierAudio() ); - const TInt video( iSdpParser->MediaIdentifierVideo() ); - - // Check explanation for this in case ERTSPDescSent above. - const TBool audioBeforeVideo( - audio >= 96 && video >= 96 && audio < video ); - - // Then send audio, if applicable: - if ( iSdpParser && iSdpParser->AudioControlAddr().Length() && - !audioBeforeVideo ) - { - TPtrC8 ctrlAddr ( iSdpParser->AudioControlAddr() ); - SendSetupCommandL( ctrlAddr, ETrue ); - iStage = ERTSPSetupAudioSent; - } - else - { - // there is no audio that need setup so lets check also multicast+tcp - ConditionallySetupMultiCastOrTcpStreamingL(); - } - } - break; - - case ERTSPPauseSent: - // If we're paused, do zero the buffer, in tcp streaming case - // some servers seem to send packets even after play.. - break; - - case ERTSPReadyToPlay: - // In these stages send no further commands - break; - - case ERTSPPlaySent: - // Start timer for UDP reception and start streaming - if ( iTransport == ERTPOverUDP ) - { - iUdpReceptionTimer->Cancel(); - iUdpReceptionTimer->After( KCRRtspRtpUdpTimeout ); - } - - iStage = ERTSPPlaying; - if ( !iNoRtpInfoHeader ) - { - iSessionObs.StatusChanged( MCRPacketSource::ERtpStatePlaying ); - } - break; - - case ERTSPPlaying: - // None - break; - - case ERTSPTearDownSent: - iPostPonedPlay = EFalse; - iOwningSession.SourceStop(); - break; - - default: - // By default send no further commands - break; - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendPlayCommandL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendPlayCommandL(void) - { - delete iPrevCommands[ERTSPPlaySent]; - iPrevCommands[ERTSPPlaySent] = NULL; - iPrevCommands[ERTSPPlaySent] = CCRRtspCommand::NewL(); - iPrevCommands[ERTSPPlaySent]->SetCommand ( CCRRtspCommand::ERTSPCommandPLAY ); - TPtrC8 uriDes( iRtspUri8->Des() ); - iPrevCommands[ERTSPPlaySent]->SetURL( uriDes ); - iPrevCommands[ERTSPPlaySent]->SetCSeq( iCSeq ++ ); - iPrevCommands[ERTSPPlaySent]->SetRange( iStartPos , iEndPos ); - - if ( iUserAgent ) - { - iPrevCommands[ERTSPPlaySent]->SetUserAgentL( *iUserAgent ); - } - if ( iSessionId.Ptr() ) - { - iPrevCommands[ERTSPPlaySent]->SetSessionId( iSessionId ); - } - if ( iAuthenticationNeeded ) - { - AddAuthenticationL( ERTSPPlaySent ); - } - - if ( iRtspSock ) - { - iRtspSock->SendData( iPrevCommands[ERTSPPlaySent]->ProduceL() ); - StartRtspTimeout( KCRRtspResponseTimeout ); - iStage = ERTSPPlaySent; - } - - iStartPos = KRealZero; - iEndPos = KRealMinusOne; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendPauseCommandL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendPauseCommandL(void) - { - delete iPrevCommands[ERTSPPauseSent]; - iPrevCommands[ERTSPPauseSent] = NULL; - iPrevCommands[ERTSPPauseSent] = CCRRtspCommand::NewL(); - iPrevCommands[ERTSPPauseSent]->SetCommand ( CCRRtspCommand::ERTSPCommandPAUSE ); - TPtrC8 uriDes( iRtspUri8->Des() ); - iPrevCommands[ERTSPPauseSent]->SetURL( uriDes ); - iPrevCommands[ERTSPPauseSent]->SetCSeq( iCSeq ++ ); - - if ( iUserAgent ) - { - iPrevCommands[ERTSPPauseSent]->SetUserAgentL( *iUserAgent ); - } - if ( iSessionId.Ptr() ) - { - iPrevCommands[ERTSPPauseSent]->SetSessionId( iSessionId ); - } - if ( iAuthenticationNeeded ) - { - AddAuthenticationL( ERTSPPauseSent ); - } - - if ( iRtspSock ) - { - iRtspSock->SendData( iPrevCommands[ERTSPPauseSent]->ProduceL() ); - StartRtspTimeout( KCRRtspResponseTimeout ); - iStage = ERTSPPauseSent; - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendSetupCommandL -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::SendSetupCommandL( - const TDesC8& aControlAddr, - TBool aForAudio ) - { - TCRRTSPStage newStage = aForAudio ? ERTSPSetupAudioSent : ERTSPSetupVideoSent; - - delete iPrevCommands[newStage]; - iPrevCommands[newStage] = NULL; - iPrevCommands[newStage] = CCRRtspCommand::NewL(); - iPrevCommands[newStage]->SetCommand ( CCRRtspCommand::ERTSPCommandSETUP ); - iPrevCommands[newStage]->SetURL( aControlAddr ); - iPrevCommands[newStage]->SetCSeq( iCSeq ++ ); - iPrevCommands[newStage]->SetTransport( iTransport ); - - // Map stream to port number (when streaming over UDP) or channel (over TCP) - // base: iClientPort for UDP, 0 for TCP - // video: (base+0, base+1) - // audio: (base+2, base+3) or (base+0, base+1) when audio only - TInt portbase( ( iTransport == ERTPOverUDP )? iClientPort: 0 ); - TInt portoffset( ( aForAudio && iSdpParser->VideoControlAddr().Length() )? 2: 0 ); - iPrevCommands[newStage]->SetClientPort( portbase + portoffset ); - - if ( iSessionId.Ptr() ) - { - iPrevCommands[newStage]->SetSessionId ( iSessionId ); - } - if ( iAuthenticationNeeded ) - { - AddAuthenticationL( newStage ); - } - if ( iUserAgent ) - { - iPrevCommands[newStage]->SetUserAgentL( *iUserAgent ); - } - if ( iWapProfile ) - { - iPrevCommands[newStage]->SetWapProfileL( *iWapProfile ); - } - - if ( iRtspSock ) - { - iRtspSock->SendData( iPrevCommands[newStage]->ProduceL() ); - StartRtspTimeout( KCRRtspResponseTimeout ); - } - - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendTearDownCommandL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendTearDownCommandL() - { - CCRRtspCommand*& teardowncmd = iPrevCommands[ERTSPTearDownSent]; - iPostPonedPlay = EFalse; - if ( teardowncmd ) - { - delete teardowncmd; teardowncmd = NULL; - } - - teardowncmd = CCRRtspCommand::NewL(); - teardowncmd->SetCommand( CCRRtspCommand::ERTSPCommandTEARDOWN ); - TPtrC8 uri( iRtspUri8->Des() ); - teardowncmd->SetURL( uri ); - teardowncmd->SetCSeq( iCSeq++ ); - - if ( iSessionId.Ptr() ) - { - teardowncmd->SetSessionId( iSessionId ); - } - if ( iUserAgent ) - { - teardowncmd->SetUserAgentL( *iUserAgent ); - } - if ( iAuthenticationNeeded ) - { - AddAuthenticationL( ERTSPTearDownSent ); - } - - if ( iRtspSock ) - { - iRtspSock->SendData( teardowncmd->ProduceL() ); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendOptionsCommandL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendOptionsCommandL(void) - { - delete iPrevCommands[ERTSPOptSent]; - iPrevCommands[ERTSPOptSent] = NULL; - iPrevCommands[ERTSPOptSent] = CCRRtspCommand::NewL(); - iPrevCommands[ERTSPOptSent]->SetCommand ( CCRRtspCommand::ERTSPCommandOPTIONS ); - TPtrC8 uriDes ( iRtspUri8->Des() ); - iPrevCommands[ERTSPOptSent]->SetURL ( uriDes ); - iPrevCommands[ERTSPOptSent]->SetCSeq ( iCSeq ++ ); - - if ( iUserAgent ) - { - iPrevCommands[ERTSPOptSent]->SetUserAgentL( *iUserAgent ); - } - if ( iSessionId.Ptr() ) - { - iPrevCommands[ERTSPOptSent]->SetSessionId ( iSessionId ); - } - if ( iAuthenticationNeeded ) - { - AddAuthenticationL( ERTSPOptSent ); - } - - if ( iRtspSock ) - { - iRtspSock->SendData( iPrevCommands[ERTSPOptSent]->ProduceL() ); - } - // Sending options ping does not change our state - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SetupRTPSessions -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::SetupRTPSessions( void ) - { - TInt retval( KErrNone ); - if ( !iRtspSock ) - { - retval = KErrNotReady; - } - else - { - TInetAddr localAddr( iRtspSock->LocalAddr() ); - TInetAddr remoteAddr( iRtspSock->ConnectedAddr() ); - - // Clear used streams - iReceiveStreams.Reset(); - iTrafficFound = EFalse; - - // First audio: - if ( iRtspSock && iResponses[ERTSPSetupAudioSent] ) - { - if ( iTransport == ERTPOverMulticast ) - { - retval = CreateMulticastSocket( ERTPAudioSend1, - iResponses[ERTSPSetupAudioSent]->Destination(), - iResponses[ERTSPSetupAudioSent]->ClientPort() ); - if ( retval == KErrNone ) - { - retval = CreateMulticastSocket( ERTPAudioSend2, - iResponses[ERTSPSetupAudioSent]->Destination(), - iResponses[ERTSPSetupAudioSent]->ClientPort()+1 ); - } - } - else - { - localAddr.SetPort( iResponses[ERTSPSetupAudioSent]->ClientPort() ); - remoteAddr.SetPort( iResponses[ERTSPSetupAudioSent]->ServerPort() ); - -#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) - TName _addr; - localAddr.Output( _addr ); - LOG2( "localaddr for video is %S:%d", &_addr, localAddr.Port() ); - remoteAddr.Output( _addr ); - LOG2( "remoteAddr for video is %S:%d", &_addr, remoteAddr.Port() ); -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - - retval = CreateUnicastSocket( ERTPAudioSend1, localAddr, remoteAddr ); - if ( retval == KErrNone ) - { - localAddr.SetPort( localAddr.Port()+1 ); - remoteAddr.SetPort( remoteAddr.Port()+1 ); - retval = CreateUnicastSocket( ERTPAudioSend2, localAddr, remoteAddr ); - } - } - - if ( retval == KErrNone ) - { - TRAP( retval, iAudioSession.OpenL( - iRTPSockArr[ERTPAudioSend1]->Socket(), - KAverageExpectedRtpPacketMaxSize, - iRTPSockArr[ERTPAudioSend2]->Socket(), - EPriorityNormal, KCRCName() ) ); - } - - LOG1( "CCRRtspPacketSource::SetupRTPSessions audio sess open: %d", retval ); - if ( !retval ) - { - SetRtpSession( iAudioSession , iSdpParser->AudioTimerGranularity() ); - iAudioSession.SetBandwidth( iSdpParser->AudioBitrate() * 1000 ); - TRAP( retval, iAudioSession.PrivRegisterEventCallbackL( ERtpNewSource, - ( TRtpCallbackFunction )CCRRtspPacketSource::AudioRTPCallBack, this ) ); - - TReceiveStream audioDataStream; - audioDataStream.iStreamType = EAudioStream; - audioDataStream.iDataReceived = EFalse; - iReceiveStreams.Append( audioDataStream ); - LOG( "CCRRtspPacketSource::SetupRTPSessions - AudioStream found" ); - TReceiveStream audioControlStream; - audioControlStream.iStreamType = EAudioControlStream; - audioControlStream.iDataReceived = EFalse; - LOG( "CCRRtspPacketSource::SetupRTPSessions - AudioControlStream found" ); - iReceiveStreams.Append( audioControlStream ); - - LOG2( "CCRRtspPacketSource::SetupRTPSessions audio stat: %d, ts: %u", - retval, ( TUint )iRTPTimeStampAudio ); - } - else - { - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRConnectionError, retval ); - } - iOwningSession.SourceStop(); - } - } - - // Then video - if ( retval == KErrNone && iRtspSock && iResponses[ERTSPSetupVideoSent] ) - { - if ( iTransport==ERTPOverMulticast ) - { - retval = CreateMulticastSocket( ERTPVideoSend1, - iResponses[ERTSPSetupVideoSent]->Destination(), - iResponses[ERTSPSetupVideoSent]->ClientPort() ); - if ( retval==KErrNone ) - { - retval = CreateMulticastSocket( ERTPVideoSend2, - iResponses[ERTSPSetupVideoSent]->Destination(), - iResponses[ERTSPSetupVideoSent]->ClientPort()+1 ); - } - } - else - { - localAddr.SetPort( iResponses[ERTSPSetupVideoSent]->ClientPort() ); - remoteAddr.SetPort( iResponses[ERTSPSetupVideoSent]->ServerPort() ); - -#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) - TName _addr; - localAddr.Output( _addr ); - LOG2( "localaddr for video is %S:%d", &_addr, localAddr.Port() ); - remoteAddr.Output( _addr ); - LOG2( "remoteAddr for video is %S:%d", &_addr, remoteAddr.Port() ); -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - - retval = CreateUnicastSocket( ERTPVideoSend1, localAddr, remoteAddr ); - if ( retval == KErrNone ) - { - localAddr.SetPort( localAddr.Port() + 1 ); - remoteAddr.SetPort( remoteAddr.Port() + 1 ); - retval = CreateUnicastSocket( ERTPVideoSend2, localAddr, remoteAddr ); - } - } - - if ( retval == KErrNone ) - { - TRAP( retval, iVideoSession.OpenL( iRTPSockArr[ERTPVideoSend1]->Socket(), - KAverageExpectedRtpPacketMaxSize, iRTPSockArr[ERTPVideoSend2]->Socket(), - EPriorityNormal, KCRCName() ) ); - } - - LOG1( "CCRRtspPacketSource::SetupRTPSessions video sess open: %d", retval ); - if ( !retval ) - { - SetRtpSession( iVideoSession , iSdpParser->VideoTimerGranularity() ); - iVideoSession.SetBandwidth( iSdpParser->VideoBitrate() * 1000 ); - TRAP( retval, iVideoSession.PrivRegisterEventCallbackL( ERtpNewSource, - ( TRtpCallbackFunction )CCRRtspPacketSource::VideoRTPCallBack, this ) ); - - TReceiveStream videoDataStream; - videoDataStream.iStreamType = EVideoStream; - videoDataStream.iDataReceived = EFalse; - LOG( "CCRRtspPacketSource::SetupRTPSessions - VideoStream found" ); - iReceiveStreams.Append( videoDataStream ); - TReceiveStream videoControlStream; - videoControlStream.iStreamType = EVideoControlStream; - videoControlStream.iDataReceived = EFalse; - LOG( "CCRRtspPacketSource::SetupRTPSessions - VideoControlStream found" ); - iReceiveStreams.Append( videoControlStream ); - - LOG2( "CCRRtspPacketSource::SetupRTPSessions video stat: %d, ts: %u", - retval, ( TUint )iRTPTimeStampVideo ); - } - else - { - if ( iObserver ) - { - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), - ECRConnectionError, retval ); - } - iOwningSession.SourceStop(); - } - } - } - - return retval; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::CreateMulticastSocket -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::CreateMulticastSocket( - TCRRTPSockId aSockId, - const TInetAddr& aGroupAddr, - TInt aPort ) - { - // Alias for socket being created - CCRSock*& sock = iRTPSockArr[aSockId]; - - // Delete if already existing - if ( sock ) - { - delete sock; - sock = NULL; - } - - // Create socket - TRAPD( err, sock = CCRSock::NewL( *this, aSockId, iConnection.Connection(), - iSockServer, EFalse, EFalse) ); - if ( err != KErrNone ) - { - LOG2( "CCRRtspPacketSource::CreateMulticastSocket: CCRSock::NewL FAILED, sockId: %d, err: %d", - aSockId, err ); - return err; - } - - // Bind socket to local UDP port, issue no reads -> handled by RRtpSession - err = sock->ListenPort( aPort ); - if ( err != KErrNone ) - { - LOG2( "CCRRtspPacketSource::CreateMulticastSocket: ListenPort FAILED, port: %d, err: %d", - aPort, err ); - return err; - } - - err = sock->JoinGroup( aGroupAddr ); - if ( err != KErrNone ) - { - LOG1( "CCRRtspPacketSource::CreateMulticastSocket: JoinGroup FAILED, err: %d", err ); - return err; - } - -#if defined(LIVE_TV_FILE_TRACE) || defined(LIVE_TV_RDEBUG_TRACE) - TName group; - aGroupAddr.Output( group ); - LOG3( "CCRRtspPacketSource::CreateMulticastSocket: sockid: %d, group: '%S', port: %d OK", - aSockId, &group, aPort ); -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::CreateUnicastSocket -// ----------------------------------------------------------------------------- -TInt CCRRtspPacketSource::CreateUnicastSocket( - TCRRTPSockId aSockId, - const TInetAddr& aLocalAddr, - const TInetAddr& /*aRemoteAddr*/ ) - { - // Alias for socket being created - CCRSock*& sock = iRTPSockArr[aSockId]; - - // Delete if already existing - if ( sock ) - { - delete sock; - sock = NULL; - } - - // Create socket: EFalse=UDP, EFalse=issue no read (handled by RRtpSession) - TRAPD( err, sock = CCRSock::NewL( *this,aSockId, iConnection.Connection(), - iSockServer, EFalse, EFalse ) ); - if ( err != KErrNone ) - { - LOG2( "CCRRtspPacketSource::CreateUnicastSocket: CCRSock::NewL FAILED, sockId: %d, err: %d", - aSockId, err ); - return err; - } - - // Bind to local port, ignore remote address and port - TInt port = aLocalAddr.Port(); - err = sock->ListenPort( port ); - if ( err != KErrNone ) - { - LOG2( "CCRRtspPacketSource::CreateUnicastSocket: ListenPort FAILED, port: %d, err: %d", - port, err ); - return err; - } - -#if defined(LIVE_TV_FILE_TRACE) || defined(LIVE_TV_RDEBUG_TRACE) - LOG2( "CCRRtspPacketSource::CreateUnicastSocket: sockid: %d, port: %d OK", - aSockId, port ); -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::RTPPayloadProcessor -// This is called from audio and video callbacks when real payload packet -// is received from rtp stack. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::RTPPayloadProcessor( - const TRtpEvent& aEvent, - const TBool aIsAudio ) - { - // If udp traffic hasn't been flagged as found - // keep marking streams as found - if ( !iTrafficFound ) - { - if ( aIsAudio ) - { - StreamFound( EAudioStream ); - } - else - { - StreamFound( EVideoStream ); - } - - // Cancel UDP timer, so as not to trigger TCP streaming - if ( CheckReceiveOfStreams() ) - { - // We have traffic from all needed streams, cancel reception timer - // and set UDP flag. - iUdpReceptionTimer->Cancel(); - iUdpFound = ETrue; - iTrafficFound = ETrue; - } - } - - // Here process packet - RRtpReceivePacket p = aEvent.ReceiveSource().Packet(); - TUint32 flag( 0 ); - BigEndian::Put32( ( TUint8* )&flag, p.Flags() ); - - // Header - TCRRtpMessageHeader packetHeader; - memcpy( &packetHeader, &flag, sizeof( flag ) ); - BigEndian::Put32( ( TUint8* )&packetHeader.iTimestamp, p.Timestamp() ); - BigEndian::Put32( ( TUint8* )&packetHeader.iSSRC, p.SSRC() ); - TPtrC8 rtpHeader( ( TUint8* )&packetHeader, sizeof( packetHeader ) ); - - if ( iNoRtpInfoHeader ) - { - ConstructSeqAndTsForSink( - aIsAudio ? MCRPacketSource::EAudioStream : MCRPacketSource::EVideoStream, - 0 /*nop*/, 0 /*nop*/, 0 /*nop*/, p.SequenceNumber() ); - } - - // Stream - MCRPacketSource::TCRPacketStreamId stream( - ( aIsAudio )? MCRPacketSource::EAudioStream : - MCRPacketSource::EVideoStream ); - iBuffer->AddPacket( stream, rtpHeader, p.Payload() ); - - // Count of packets - if ( aIsAudio ) - { - iAudioBytes += p.Payload( ).Length(); - iAudioPackets ++; - } - else - { - iVideoBytes += p.Payload( ).Length(); - iVideoPackets ++; - } - - p.Close(); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::AudioRTPCallBack -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::AudioRTPCallBack( - CCRRtspPacketSource* aPtr, - const TRtpEvent& aEvent ) - { - switch ( aEvent.Type() ) - { - case ERtpPacketReceived: - static_cast( aPtr )-> - RTPPayloadProcessor( aEvent, ETrue ); - break; - - // RTCP - case ERtpSR: - { - // We have audio control traffic - if ( !aPtr->iTrafficFound ) - { - aPtr->StreamFound( EAudioControlStream ); - if ( aPtr->CheckReceiveOfStreams() ) - { - // Cancel UDP timer, so as not to trigger TCP streaming - aPtr->iUdpReceptionTimer->Cancel(); - aPtr->iUdpFound = ETrue; - aPtr->iTrafficFound = ETrue; - } - } - - // Sender report - SenderReport( aPtr, aEvent, MCRPacketSource::EAudioControlStream ); - } - break; - - case ERtpNewSource: - { - // Handle audio - TRAPD( err, HandleNewSourceL( aPtr, aPtr->iRtpRecvSrcAudio, aEvent, - ( TRtpCallbackFunction )CCRRtspPacketSource::AudioRTPCallBack ) ); - if ( err ) - { - LOG1( "CCRRtspPacketSource::AudioRTPCallBack(), HandleNewSourceL Leaved: %d", err ); - aPtr->iOwningSession.SourceStop(); - } - } - break; - - case ERtpSessionFail: - case ERtpSourceFail: - LOG( "CCRRtspPacketSource::VideoRTPCallBack(), source/session fail" ); - aPtr->iOwningSession.SourceStop(); - if ( aPtr->iObserver ) - { - aPtr->iObserver->ConnectionStatusChange( - aPtr->iOwningSession.SourceChecksum(), - ECRNormalEndOfStream, KErrSessionClosed ); - } - break; - - case ERtpBYE: - LOG( "CCRRtspPacketSource::AudioRTPCallBack(), ERtpBYE" ); - if ( aPtr->iObserver ) - { - aPtr->iObserver->ConnectionStatusChange( - aPtr->iOwningSession.SourceChecksum(), - ECRNormalEndOfStream, KErrNone ); - } - break; - - default: - LOG1( "CCRRtspPacketSource::AudioRTPCallBack default case, type 0x%x", - ( TUint )( aEvent.Type() ) ); - // by do nothing - break; - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::VideoRTPCallBack -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::VideoRTPCallBack( - CCRRtspPacketSource* aPtr, - const TRtpEvent& aEvent ) - { - switch ( aEvent.Type() ) - { - case ERtpPacketReceived: - static_cast( aPtr )-> - RTPPayloadProcessor( aEvent, EFalse ); - break; - - // RTCP - case ERtpSR: - { - // We have video control traffic - if ( !aPtr->iTrafficFound ) - { - aPtr->StreamFound( EVideoControlStream ); - if ( aPtr->CheckReceiveOfStreams() ) - { - // Cancel UDP timer, so as not to trigger TCP streaming - aPtr->iUdpReceptionTimer->Cancel(); - aPtr->iUdpFound = ETrue; - aPtr->iTrafficFound = ETrue; - } - } - - // Sender report - SenderReport( aPtr, aEvent, MCRPacketSource::EVideoControlStream ); - } - break; - - case ERtpNewSource: - { - // Handle video - TRAPD( err, HandleNewSourceL( aPtr, aPtr->iRtpRecvSrcVideo, aEvent, - ( TRtpCallbackFunction )CCRRtspPacketSource::VideoRTPCallBack ) ); - if ( err ) - { - LOG1( "CCRRtspPacketSource::VideoRTPCallBack(), HandleNewSourceL Leaved: %d", err ); - aPtr->iOwningSession.SourceStop(); - } - } - break; - - case ERtpSessionFail: - case ERtpSourceFail: - LOG( "CCRRtspPacketSource::VideoRTPCallBack(), Source/session fail" ); - aPtr->iOwningSession.SourceStop(); - if ( aPtr->iObserver ) - { - aPtr->iObserver->ConnectionStatusChange( - aPtr->iOwningSession.SourceChecksum(), - ECRNormalEndOfStream, KErrSessionClosed ); - } - break; - - case ERtpBYE: - LOG( "CCRRtspPacketSource::VideoRTPCallBack(), ERtpBYE" ); - if ( aPtr->iObserver ) - { - aPtr->iObserver->ConnectionStatusChange( - aPtr->iOwningSession.SourceChecksum(), - ECRNormalEndOfStream, KErrNone ); - } - break; - - default: - LOG1( "CCRRtspPacketSource::VideoRTPCallBack default case, type 0x%x", - ( TUint )( aEvent.Type() ) ); - // By do nothing - break; - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SenderReport -// rfc-1305: -// NTP timestamps are represented as a 64-bit unsigned fixed- -// point number, in seconds relative to 0h on 1 January 1900. -// The integer part is in the first 32 bits and the fraction -// part in the last 32 bits. -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SenderReport( - CCRRtspPacketSource* aPtr, - const TRtpEvent& aEvent, - MCRPacketSource::TCRPacketStreamId aStreamId ) - { - TCRRtpSRReportHeader srReport; - srReport.iVersion = KRtpPacketVersion; // value is 2 - srReport.iPadding = 0; - srReport.iReportCount = 0; - srReport.iPacketType = KSenderReportPacketType; - RRtpReceiveSource source( aEvent.ReceiveSource() ); - BigEndian::Put16( ( TUint8* )&srReport.iLength, 6 ); - BigEndian::Put32( ( TUint8* )&srReport.iSenderSSRC, - source.SSRC() ); - BigEndian::Put32( ( TUint8* )&srReport.iMSWTimestamp, - source.GetSR().iSrPtr.ntp_sec ); - BigEndian::Put32( ( TUint8* )&srReport.iLSWTimestamp, - source.GetSR().iSrPtr.ntp_frac ); - BigEndian::Put32( ( TUint8* )&srReport.iRTPTimestamp, - source.GetSR().RTPTimestamp() ); - BigEndian::Put32( ( TUint8* )&srReport.iSenderPacketCount, - aPtr->iAudioPackets ); - BigEndian::Put32( ( TUint8* )&srReport.iSenderOctetCount, - aPtr->iAudioBytes ); - TPtrC8 rtcpHeader( ( TUint8* )&srReport, sizeof( srReport ) ); - aPtr->iBuffer->AddPacket( aStreamId, rtcpHeader ); - - // Verify Seq and Ts - if ( aPtr->iNoRtpInfoHeader ) - { - aPtr->ConstructSeqAndTsForSink ( - aStreamId, - source.GetSR().iSrPtr.ntp_sec, - source.GetSR().iSrPtr.ntp_frac, - source.GetSR().RTPTimestamp(), - 0 ); // 0 not used - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::HandleNewSourceL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::HandleNewSourceL( - CCRRtspPacketSource* aPtr, - RRtpReceiveSource& aSource, - const TRtpEvent& aEvent, - TRtpCallbackFunction aCallback ) - { - // Cancel UDP timer, so as not to trigger TCP streaming - aPtr->iUdpReceptionTimer->Cancel(); - delete aPtr->iPunchPacketSenderAudio; - aPtr->iPunchPacketSenderAudio = NULL; - if ( aSource.IsOpen() ) - { - aSource.Close(); - } - - // Source - aSource = aEvent.Session().NewReceiveSourceL(); - aSource.PrivRegisterEventCallbackL( ERtpPacketReceived, aCallback, aPtr ); - aSource.PrivRegisterEventCallbackL( ERtpSR, aCallback, aPtr ); - aSource.PrivRegisterEventCallbackL( ERtpBYE, aCallback, aPtr ); - aSource.PrivRegisterEventCallbackL( ERtpSessionFail, aCallback, aPtr ); - aSource.PrivRegisterEventCallbackL( ERtpSourceFail, aCallback, aPtr ); - - // Ping Timer - if ( !aPtr->iRtspPingTimer ) - { - aPtr->iRtspPingTimer = CPeriodic::NewL( CActive::EPriorityLow ); - aPtr->iRtspPingTimer->Start( - KDVR10Seconds, 2 * KDVR10Seconds, TCallBack( SendRtspPing, aPtr ) ); - } - - aEvent.Session().SendAPPL( KCRCName() ); - aEvent.Session().SetRTCPAutoSend( ETrue ); - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendAuthDescribeL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendAuthDescribeL( ) - { - delete iPrevCommands[ERTSPDescSent]; - iPrevCommands[ERTSPDescSent] = NULL; - iPrevCommands[ERTSPDescSent] = CCRRtspCommand::NewL(); - iPrevCommands[ERTSPDescSent]->SetCommand ( - CCRRtspCommand::ERTSPCommandDESCRIBE ); - TPtrC8 uriDes ( iRtspUri8->Des() ); - iPrevCommands[ERTSPDescSent]->SetURL ( uriDes ); - iPrevCommands[ERTSPDescSent]->SetCSeq ( iCSeq ++ ); - - if ( iAuthType ) - { - iPrevCommands[ERTSPDescSent]->SetAuthenticationTypeL( iAuthType->Des() ); - } - if ( iNonce ) - { - iPrevCommands[ERTSPDescSent]->SetNonceL( iNonce->Des() ); - } - if ( iRealm ) - { - iPrevCommands[ERTSPDescSent]->SetRealmL( iRealm->Des() ); - } - if ( iOpaque ) - { - iPrevCommands[ERTSPDescSent]->SetOpaqueL( iOpaque->Des() ); - } - if ( iUserAgent ) - { - iPrevCommands[ERTSPDescSent]->SetUserAgentL( *iUserAgent ); - } - if ( iWapProfile ) - { - iPrevCommands[ERTSPDescSent]->SetWapProfileL( *iWapProfile ); - } - if ( iBandwidth ) - { - iPrevCommands[ERTSPDescSent]->SetBandwidth( iBandwidth ); - } - - iPrevCommands[ERTSPDescSent]->SetUserNameL( iUserName->Des() ); - iPrevCommands[ERTSPDescSent]->SetPassWdL( iPassword->Des() ); - iPrevCommands[ERTSPDescSent]->SetRtspUriL( iRtspUri->Des() ); - iPrevCommands[ERTSPDescSent]->SetAuthentication ( iAuthenticationNeeded ); - if ( iRtspSock ) - { - iRtspSock->SendData( iPrevCommands[ERTSPDescSent]->ProduceL() ); - StartRtspTimeout( KCRRtspResponseTimeout ); - } - iStage = ERTSPDescSent; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::AddAuthenticationL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::AddAuthenticationL( TInt aCommand ) - { - if ( iPrevCommands[aCommand] && iNonce && - iOpaque && iUserName && iPassword ) - { - iPrevCommands[aCommand]->SetAuthenticationTypeL( iAuthType->Des() ); - iPrevCommands[aCommand]->SetNonceL( iNonce->Des() ); - iPrevCommands[aCommand]->SetRealmL( iRealm->Des() ); - iPrevCommands[aCommand]->SetOpaqueL( iOpaque->Des() ); - iPrevCommands[aCommand]->SetUserNameL( iUserName->Des() ); - iPrevCommands[aCommand]->SetPassWdL( iPassword->Des() ); - iPrevCommands[aCommand]->SetRtspUriL( iRtspUri->Des() ); - iPrevCommands[aCommand]->SetAuthentication ( iAuthenticationNeeded ); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::PunchPacketsSent -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::PunchPacketsSent( CCRPunchPacketSender* aPuncher ) - { - if ( iPunchPacketSenderVideo && aPuncher == iPunchPacketSenderVideo ) - { - iPunchPacketSentForVideo = ETrue; - } - if ( iPunchPacketSenderAudio && aPuncher == iPunchPacketSenderAudio ) - { - iPunchPacketSentForAudio = ETrue; - } - if ( ( iPunchPacketSenderVideo && !iPunchPacketSenderAudio && - iPunchPacketSentForVideo ) || - ( !iPunchPacketSenderVideo && iPunchPacketSenderAudio && - iPunchPacketSentForAudio ) || - ( iPunchPacketSenderVideo && iPunchPacketSenderAudio && - iPunchPacketSentForVideo && iPunchPacketSentForAudio ) ) - { - LOG1( "PunchPacketsSent, play readiness: %d", iReadyToPlay ); - SetupSessionsAndPlay(); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SetupSessionsAndPlay -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SetupSessionsAndPlay() - { - // all needed punch packets are sent: - if ( SetupRTPSessions() != KErrNone ) - { - iOwningSession.SourceStop(); - } - else - { - // if we're ready to play, play - if ( iReadyToPlay ) - { - TRAPD( err, SendPlayCommandL() ); - if ( err != KErrNone ) - { - iOwningSession.SourceStop(); - } - } - else - { - iStage = ERTSPReadyToPlay; - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendPunchPackets -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SendPunchPacketsL( void ) - { - LOG( "CCRRtspPacketSource::SendPunchPacketsL in" ); - delete iPunchPacketSenderAudio; - iPunchPacketSenderAudio = NULL; - delete iPunchPacketSenderVideo; - iPunchPacketSenderVideo = NULL; - - if ( iSdpParser &&iRtspSock && iResponses[ERTSPSetupVideoSent] ) - { - TInetAddr localAddr = iRtspSock->LocalAddr(); - TInetAddr remoteAddr = iRtspSock->ConnectedAddr(); - localAddr.SetPort(iResponses[ERTSPSetupVideoSent]->ClientPort()); - remoteAddr.SetPort(iResponses[ERTSPSetupVideoSent]->ServerPort()); - iPunchPacketSenderVideo = CCRPunchPacketSender::NewL( - iConnection.Connection(), iSockServer, - localAddr, remoteAddr, 0, *this ); - } - if ( iSdpParser && iRtspSock && iResponses[ERTSPSetupAudioSent] ) - { - TInetAddr localAddr = iRtspSock->LocalAddr(); - TInetAddr remoteAddr = iRtspSock->ConnectedAddr(); - localAddr.SetPort(iResponses[ERTSPSetupAudioSent]->ClientPort()); - remoteAddr.SetPort(iResponses[ERTSPSetupAudioSent]->ServerPort()); - iPunchPacketSenderAudio = CCRPunchPacketSender::NewL( - iConnection.Connection(), iSockServer, - localAddr, remoteAddr, 0, *this ); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ConnectionStatusChange -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ConnectionStatusChange( - TInt /*aSessionId*/, - TCRConnectionStatus aStatus, - TInt /* aErr */ ) - { - switch( aStatus ) - { - // Connection has gone up or bearer has changed -> check bandwidth - case ECRBearerChanged: - { - LOG( "CCRRtspPacketSource::ConnectionStatusChange: IapUp or IapUp2G" ); - if ( iSdpParser && iObserver ) - { - // Unknown bitrate or bandwidth are returned as zero. Bitrates in kbit/s - TInt bitrate( iSdpParser->VideoBitrate() + - iSdpParser->AudioBitrate() ); - TInt bandwidth( iConnection.MaximumBandwidth() / 1000 ); - if ( bitrate > 0 && bandwidth > 0 && bandwidth < bitrate ) - { - LOG2( "CCRRtspPacketSource::ConnectionStatusChange: clip_bitrate: %d, connection_bandwidth: %d -> NotEnoughBandwidth", - bitrate, bandwidth ); - iObserver->ConnectionStatusChange( - iOwningSession.SourceChecksum(), ECRNotEnoughBandwidth, KErrNone ); - } - } - break; - } - - // Connection has gone down or error occured -> switch back to RTP/UDP transport - case ECRConnectionError: - case ECRIapDown: - { - LOG( "CCRRtspPacketSource::ConnectionStatusChange: IapDown or ConnectionError -> switch to RTP/UDP streaming" ); - iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, EFalse ); - break; - } - - // Nothing to do for: - // ECRConnecting - // ECRAuthenticationNeeded - // ECRNotEnoughBandwidth - // ECRNormalEndOfStream - default: - { - LOG1( "CCRRtspPacketSource::ConnectionStatusChange: unhandled status: %d", aStatus ); - break; - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::RegisterConnectionObs -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::RegisterConnectionObs( MCRConnectionObserver* aObserver ) - { - iObserver = aObserver; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::UnregisterConnectionObs -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::UnregisterConnectionObs( ) - { - iObserver = NULL; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SetRtpSession -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::SetRtpSession( - RRtpSession& aSession, - TReal aGranularity ) - { - // Unit is 1/second - __ASSERT_DEBUG( iSdpParser != NULL, User::Panic( _L( "RTSP source" ), KErrBadHandle ) ); - TUint32 howManyNanoSecondsIsOneTick( - ( TUint32 )( TReal( 1000000000.0L ) / aGranularity ) ); - LOG1( "CCRRtspPacketSource::SetRtpSession clock tick: %u", howManyNanoSecondsIsOneTick ); - aSession.SetRTPTimeConversion( 0, howManyNanoSecondsIsOneTick ); - aSession.SetRtpStreamParameters( KDVRMinSequential, // 1 - KDVRMaxMisorder, // 50 - KDVRMaxDropOut ); // 3000 - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::SendRtspPing -// ----------------------------------------------------------------------------- -// -TInt CCRRtspPacketSource::SendRtspPing( TAny* aSelfPtr ) - { - CCRRtspPacketSource* ptr = static_cast ( aSelfPtr ); - TRAPD( err, ptr->SendOptionsCommandL() ); - return err; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ConstructSeqAndTsForSink -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ConstructSeqAndTsForSink ( - MCRPacketSource::TCRPacketStreamId aStreamId, - TUint32 aMSWTimestamp, - TUint32 aLSWTimestamp, - TUint32 aRTPTimestamp, - TUint aSeq ) - { - switch ( aStreamId ) - { - case EAudioStream: - if ( iRTPTimeStampAudio ) - { - iSeqFromRtpInfoForAudio = aSeq; - if ( iSeqFromRtpInfoForAudio == 0 ) - { - iSeqFromRtpInfoForAudio++; - } - LOG1( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Audio seq: %d ", ( int )aSeq ); - // We may declare that we have seq+ts if we're here and have only audio or - // if we're here and have both audio and video and have also seq for video - if ( ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrAudioOnly ) || - ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrBothAudioAndVideo && - iSeqFromRtpInfoForVideo && iRTPTimeStampVideo ) ) - { - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStateSeqAndTSAvailable ); - iNoRtpInfoHeader = EFalse; - if ( iStage == ERTSPPlaying ) - { - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStatePlaying ); - } - } - } - break; - - case EAudioControlStream: - if ( !iMSWTimestamp ) - { // no wall clock time yet set - iMSWTimestamp = aMSWTimestamp; - iLSWTimestamp = aLSWTimestamp; - iRTPTimeStampAudio = aRTPTimestamp; - if ( iRTPTimeStampAudio == 0 ) - { - iRTPTimeStampAudio++; - } - } - else - { - // Sync audio with video - TInt64 wallClockOfVideo = MAKE_TINT64 ( iMSWTimestamp , iLSWTimestamp ); - TInt64 wallClockOfAudio = MAKE_TINT64 ( aMSWTimestamp , aLSWTimestamp ); - // Then figure out the difference. unit is now difficult ; upper - // 32 bits contain whole seconds, lower contains fraction - TInt64 wallClockDifference( wallClockOfVideo - wallClockOfAudio ); - // Now, the aRTPTimestamp has different scale, declared in SDP. - // first make one second that has same scale as wallClockDifference - TInt64 granularity( MAKE_TINT64( 1, 0 ) ); - // Then divide that one second with the given granularity. variable - // granularity will now contain in its low 32 bits the fraction of the - // second that re-presents one clock tick (e.g. 1/90000 sec for video) - granularity = granularity / static_cast( - iSdpParser->AudioTimerGranularity() ); - // Then divide our difference with this fraction of second - TInt64 wallClockDifferenceGranular = wallClockDifference / granularity; - // unit of wallClockDifferenceGranular is now 2^32 / granularity - TInt32 wallClockDifferenceGranular32 = wallClockDifferenceGranular; - LOG2( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Audio ts: %u adjust by: %d", - aRTPTimestamp , wallClockDifferenceGranular32 ); - iRTPTimeStampAudio = aRTPTimestamp + wallClockDifferenceGranular32; - if ( iRTPTimeStampAudio == 0 ) - { - iRTPTimeStampAudio++; - } - } - break; - - case EVideoStream: - if ( iRTPTimeStampVideo ) - { - iSeqFromRtpInfoForVideo = aSeq; - if ( iSeqFromRtpInfoForVideo == 0 ) - { - iSeqFromRtpInfoForVideo++; - } - LOG1( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Video seq: %d ", - ( int )aSeq ); - - // We may declare that we have seq+ts if we're here and have only video or - // if we're here and have both and have also seq for video - if ( ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrVideoOnly ) || - ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrBothAudioAndVideo && - iSeqFromRtpInfoForAudio && iRTPTimeStampAudio ) ) - { - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStateSeqAndTSAvailable ); - iNoRtpInfoHeader = EFalse; - if ( iStage == ERTSPPlaying ) - { - iSessionObs.StatusChanged( - MCRPacketSource::ERtpStatePlaying ); - } - } - } - break; - - case EVideoControlStream: - if ( !iMSWTimestamp ) - { // No wall clock time yet set - iMSWTimestamp = aMSWTimestamp; - iLSWTimestamp = aLSWTimestamp; - iRTPTimeStampVideo = aRTPTimestamp; - if ( iRTPTimeStampVideo == 0 ) - { - iRTPTimeStampVideo++; - } - } - else - { - // Sync audio with video - TInt64 wallClockOfAudio = MAKE_TINT64 ( iMSWTimestamp , iLSWTimestamp ); - TInt64 wallClockOfVideo = MAKE_TINT64 ( aMSWTimestamp , aLSWTimestamp ); - // Then figure out the difference. unit is now difficult ; upper - // 32 bits contain whole seconds, lower contains fraction - TInt64 wallClockDifference( wallClockOfAudio - wallClockOfVideo ); - // Now, the aRTPTimestamp has different scale, declared in SDP. - // first make one second that has same scale as wallClockDifference - TInt64 granularity( MAKE_TINT64( 1, 0 ) ); - // Then divide that one second with the given granularity. variable - // granularity will now contain in its low 32 bits the fraction of the - // second that re-presents one clock tick (e.g. 1/90000 sec for video) - granularity = granularity / static_cast( - iSdpParser->VideoTimerGranularity()); - // Then divide our difference with this fraction of second - TInt64 wallClockDifferenceGranular = wallClockDifference / granularity; - // Unit of wallClockDifferenceGranular is now 2^32 / granularity - TInt32 wallClockDifferenceGranular32 = wallClockDifferenceGranular; - LOG2( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Video ts: %u adjust by: %d", - aRTPTimestamp , wallClockDifferenceGranular32 ); - iRTPTimeStampVideo = aRTPTimestamp + wallClockDifferenceGranular32; - if ( iRTPTimeStampVideo == 0 ) - { - iRTPTimeStampVideo++; - } - } - break; - - default: - // no thing - break; - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ConditionallySetupMultiCastOrTcpStreamingL -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ConditionallySetupMultiCastOrTcpStreamingL ( void ) - { - // UDP: Punch packets or play sent in ProcessRTSPResponseL, so do nothing. - if ( iTransport == ERTPOverUDP ) - { - } - // Multicast: no punch packets needed but session setup yes - else if ( iTransport == ERTPOverMulticast ) - { - SetupSessionsAndPlay(); - } - - // TCP: no punch packets or session, just send PLAY .. but wait for UI - else if ( iTransport == ERTPOverTCP ) - { - if ( iReadyToPlay ) - { - SendPlayCommandL(); - } - else - { - iStage = ERTSPReadyToPlay; - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::CheckReceiveOfStreams -// ----------------------------------------------------------------------------- -// -TBool CCRRtspPacketSource::CheckReceiveOfStreams() - { - TBool retVal( ETrue ); - - // Go through all streams and check that all streams have receive flag on, - // if not return false. - for ( TInt i = 0 ; i < iReceiveStreams.Count() ; i++ ) - { - if ( iReceiveStreams[i].iDataReceived == EFalse ) - { - LOG1( "CCRRtspPacketSource::CheckReceiveOfStreams - Missing atleast stream %d", iReceiveStreams[i].iStreamType ); - retVal = EFalse; - break; - } - } - - if ( retVal ) - { - LOG( "CCRRtspPacketSource::CheckReceiveOfStreams - Receiving from all streams!" ); - } - - return retVal; - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::StreamFound -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::StreamFound( TCRPacketStreamId aStreamType ) - { - // Go through streams and find correct stream to set the receive flag. - for ( TInt i = 0 ; i < iReceiveStreams.Count(); i++ ) - { - if ( iReceiveStreams[i].iStreamType == aStreamType ) - { - iReceiveStreams[i].iDataReceived = ETrue; - LOG1( "CCRRtspPacketSource::StreamFound - Stream %d found", iReceiveStreams[i].iStreamType ); - break; - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ResetStreamFlags -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ResetStreamFlags( ) - { - // Go through streams and clear receiving flag. - for ( TInt i = 0 ; i < iReceiveStreams.Count() ; i++ ) - { - iReceiveStreams[i].iDataReceived = EFalse; - } - - // We have to check receive again - iTrafficFound = EFalse; - } - -#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) -// ----------------------------------------------------------------------------- -// CCRRtspPacketSource::ShowHeader -// ----------------------------------------------------------------------------- -// -void CCRRtspPacketSource::ShowHeader( - const TDesC8& aRtcpHeader, - const TCRRtpSRReportHeader& aSrReport ) - { - TBuf<100> b( KNullDesC ); - LOG1( "CCRRtspPacketSource::TCP control packet len: %d", aRtcpHeader.Length() ); - for ( TInt j( 0 ); j < 32 && j < aRtcpHeader.Length(); j++ ) - { - b.AppendFormat( _L( "%2X " ), ( unsigned )( aRtcpHeader[j] ) ); - if ( j > 0 && ( ( j % 16 ) == 0 ) ) - { - LOG2( "%d -> %S", j, &b ); - b.Zero(); - } - } - - LOG1( "iVersion %u", ( unsigned )aSrReport.iVersion ); - LOG1( "iPadding %u", ( unsigned )aSrReport.iPadding ); - LOG1( "iReportCount %u",( unsigned )aSrReport.iReportCount ); - LOG1( "iPacketType %u", ( unsigned )aSrReport.iPacketType ); - LOG1( "iLength %u", - ( unsigned)BigEndian::Get16( ( const TUint8* )&aSrReport.iLength ) ); - LOG1( "iSenderSSRC %u", - ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iSenderSSRC ) ); - LOG1( "iMSWTimestamp %u", - ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iMSWTimestamp) ); - LOG1( "iLSWTimestamp %u", - ( unsigned)BigEndian::Get32( ( const TUint8* )&aSrReport.iLSWTimestamp ) ); - LOG1( "iRTPTimestamp %u", - ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iRTPTimestamp ) ); - LOG1( "iSenderPacketCount %u", - ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iSenderPacketCount) ); - LOG1( "iSenderOctetCount %u", - ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iSenderOctetCount ) ); - - } -#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE - -// End of File