diff -r 07dea94512a2 -r 381bc1d93c7b dvrengine/CommonRecordingEngine/src/CCRRtpTcpStreamer.cpp --- a/dvrengine/CommonRecordingEngine/src/CCRRtpTcpStreamer.cpp Fri May 28 09:48:00 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,418 +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: RTP/TCP streamer for RTSP source.* -*/ - - - - -// INCLUDE FILES -#include "CCRRtpTcpStreamer.h" -#include "CCRRtpTcpObserver.h" -#include "CCRRtpTcpStream.h" -#include "CRRTSPCommon.h" -#include -#include "videoserviceutilsLogger.h" - -// CONSTANTS -const TInt KCRRtpTcpHeaderLength( 4 ); -const TInt KCRRtpTcpStartMark( 0x24 ); - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::NewL -// ----------------------------------------------------------------------------- -CCRRtpTcpStreamer* CCRRtpTcpStreamer::NewL( MCRRtpTcpObserver& aObserver ) - { - CCRRtpTcpStreamer* self = new( ELeave ) CCRRtpTcpStreamer( aObserver ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::CCRRtpTcpStreamer -// ----------------------------------------------------------------------------- -// -CCRRtpTcpStreamer::CCRRtpTcpStreamer( MCRRtpTcpObserver& aObserver ) - : iObserver( aObserver ), - iMoreExpected( KErrNotFound ), - iIpData( NULL ) - { - // None - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::ConstructL -// ----------------------------------------------------------------------------- -// -void CCRRtpTcpStreamer::ConstructL() - { - // Construct streams - for ( TInt i( 0 ); i < KCRRtpTcpStreamCount; i++ ) - { - iStreams[i] = CCRRtpTcpStream::NewL( iObserver ); - } - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::~CCRRtpTcpStreamer -// ----------------------------------------------------------------------------- -CCRRtpTcpStreamer::~CCRRtpTcpStreamer() - { - // Buffers - if ( iIpData ) - { - delete iIpData; iIpData = NULL; - } - if ( iRtspData ) - { - delete iRtspData; iRtspData = NULL; - } - - // Delete streams - for ( TInt i( 0 ); i < KCRRtpTcpStreamCount; i++ ) - { - if ( iStreams[i] ) - { - delete iStreams[i]; iStreams[i] = NULL; - } - } - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::DataAvailable -// ----------------------------------------------------------------------------- -// -void CCRRtpTcpStreamer::DataAvailable( - const TDesC8& aIpData, - const TBool& aInterleaved ) - { - TPtrC8 data( aIpData ); - if ( iMoreExpected > KErrNotFound && iIpData != NULL ) - { - // More data expected - if ( HandleMoreExpected( data ) ) - { - return; // Need more - } - } - - // Can't be existing IP data at this point - delete iIpData; iIpData = NULL; - iMoreExpected = KErrNotFound; - - // Find out next packet - do - { - // Search for $ (0x24) sign - TBool tcp( EFalse ); - for ( TInt i( 0 ); aInterleaved && tcp == EFalse && - i < data.Length() && i < KCRRtpTcpHeaderLength; i++ ) - { - if ( data[i] == KCRRtpTcpStartMark ) - { - tcp = ETrue; - data.Set( data.Mid( i ) ); - - // Received less than full interleved header (4 bytes) - if ( data.Length() < KCRRtpTcpHeaderLength ) - { - iMoreExpected = KCRRtpTcpHeaderLength - data.Length(); - iIpData = data.Alloc(); - LOG1( "CCRRtpTcpStreamer::DataAvailable(), No interleave header, len: %d", data.Length() ); - return; // Need more - } - } - } - - if ( tcp ) - { - // TCP packet - if ( HandleTcpPacket( data ) ) - { - return; // Need more - } - } - else - { - // RTSP response - if ( HandleRtspResponse( data, aInterleaved ) ) - { - return; // Need more - } - - delete iRtspData; iRtspData = NULL; - } - } - while ( data.Length() > 0 ); - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::HandleMoreExpected -// ----------------------------------------------------------------------------- -// -TBool CCRRtpTcpStreamer::HandleMoreExpected( TPtrC8& aData ) - { - TInt len( aData.Length() ); - int used( len ); - if ( len >= iMoreExpected || iMoreExpected == KMaxTInt ) - { - if ( iMoreExpected >= KCRRtpTcpHeaderLength || - iIpData->Des()[0] != KCRRtpTcpStartMark || - iIpData->Length() >= KCRRtpTcpHeaderLength ) - { - // KMaxTInt is indication of unknow length in RTSP response - if ( iMoreExpected < KMaxTInt ) - { - used = iMoreExpected; - iMoreExpected = KErrNotFound; - } - else - { - // Combine datas and try find out RTSP response - delete iRtspData; iRtspData = NULL; - iRtspData = HBufC8::New( iIpData->Length() + len ); - TPtr8 ptr( iRtspData->Des() ); - ptr.Copy( iIpData->Des() ); - ptr.Append( aData ); - aData.Set( iRtspData->Des() ); - return EFalse; // Continue - } - } - else - { - // Fill interleave header - iIpData = iIpData->ReAlloc( iIpData->Length() + iMoreExpected ); - TPtr8 ptr( iIpData->Des() ); - ptr.Append( aData.Mid( 0, iMoreExpected ) ); - aData.Set( aData.Mid( iMoreExpected ) ); - len = aData.Length(); - used = len; - // Find real wanted packet length - iMoreExpected = ( TInt )BigEndian::Get16( ptr.Ptr() + 2 ); - if ( len == 0 ) - { - return ETrue; // Need more - } - if ( len >= iMoreExpected ) - { - used = iMoreExpected; - iMoreExpected = KErrNotFound; - } - } - } - - // Add new data to iIpData - iIpData = iIpData->ReAlloc( iIpData->Length() + used ); - TPtr8 ptr( iIpData->Des() ); - ptr.Append( aData.Mid( 0, used ) ); - aData.Set( aData.Mid( used ) ); - if ( iMoreExpected == KErrNotFound ) - { - ForwardPacket( ptr ); - if ( used == len ) - { - delete iIpData; iIpData = NULL; - return ETrue; // All handled - } - } - else - { - iMoreExpected -= used; - return ETrue; // Need more - } - - return EFalse; // Continue - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::HandleTcpPacket -// ----------------------------------------------------------------------------- -// -TBool CCRRtpTcpStreamer::HandleTcpPacket( TPtrC8& aData ) - { - const TInt length( KCRRtpTcpHeaderLength + - ( TInt )BigEndian::Get16( aData.Ptr() + 2 ) ); - if ( aData.Length() >= length ) - { - MakePacket( aData, length ); - } - else - { - // Need more data - iMoreExpected = length - aData.Length(); - iIpData = aData.Alloc(); - return ETrue; // Need more - } - - return EFalse; // Continue - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::HandleRtspResponse -// ----------------------------------------------------------------------------- -// -TBool CCRRtpTcpStreamer::HandleRtspResponse( - TPtrC8& aData, - const TBool& aInterleaved ) - { - TInt point( aData.FindC( KCRRTSPReplyHeader ) ); - if ( point > KErrNotFound ) - { - aData.Set( aData.Mid( point ) ); - - // Search for double CRLF combination - TInt crlf2( aData.FindC( KCR2NewLines ) ); - if ( crlf2 > KErrNotFound ) - { - crlf2 += KCR2NewLines().Length(); - } - - // Content length - point = aData.FindC( KCRRTSPContentLength() ); - if ( point > KErrNotFound && crlf2 > KErrNotFound ) - { - point += KCRRTSPContentLength().Length(); - TInt contentLen( KErrNotFound ); - TLex8 contentLenLex( aData.Mid( point, 5 ) ); - if ( contentLenLex.Val( contentLen ) < KErrNone ) - { - LOG1( "CCRRtpTcpStreamer::HandleRtspResponse(), Content length parse failed, Dumped %d bytes !", aData.Length() ); - return ETrue; - } - - LOG1( "CCRRtspCommon::HandleRtspResponse(), contentLen %d", contentLen ); - // Verify that enought data in IP packet - if ( aData.Length() >= ( crlf2 + contentLen ) ) - { - MakePacket( aData, crlf2 + contentLen ); - } - else - { - // Need more - iIpData = aData.Alloc(); - iMoreExpected = crlf2 + contentLen - aData.Length(); - return ETrue; - } - } - else - { - // Content length not defined, RTSP command should end to double CRLF - if ( crlf2 > KErrNotFound ) - { - MakePacket( aData, crlf2 ); - } - else - { - LOG( "CCRRtpTcpStreamer::HandleRtspResponse(), No double CRLF.." ); - - // Look for single CRLF - point = aData.FindC( KCRNewLine ); - if ( point > KErrNotFound ) - { - // If not interleaved, all data belongs to RTSP response - if ( !aInterleaved ) - { - if ( aData.Mid( aData.Length() - KCR2NewLines().Length() ). - FindF( KCRNewLine ) > KErrNotFound ) - { - ForwardPacket( aData ); - return ETrue; - } - - // Not complete but total length unknown - LOG( "CCRRtpTcpStreamer::HandleRtspResponse(), Need more without known length.." ); - iIpData = aData.Alloc(); - iMoreExpected = KMaxTInt; - return ETrue; - } - - // Only one CRLF after RTSP response, find last - point += KCRNewLine().Length(); - for ( TInt i( point ); i < aData.Length(); ) - { - TInt next( aData.Mid( point ).FindC( KCRNewLine ) ); - if ( next > KErrNotFound ) - { - point += ( next + KCRNewLine().Length() ); - i = point; - } - else - { - i = aData.Length(); - } - } - - LOG1( "CCRRtpTcpStreamer::HandleRtspResponse(), Last CRLF at index: %d", point ); - MakePacket( aData, point ); - } - else - { - // Not any CRLF, can not be RTSP response - LOG1( "CCRRtpTcpStreamer::HandleRtspResponse(), No CRLF, Dumped %d bytes !", aData.Length() ); - return ETrue; - } - } - } - } - else - { - LOG1( "CCRRtpTcpStreamer::HandleRtspResponse(), Not RTSP message, Dumped %d bytes !", aData.Length() ); - return ETrue; - } - - return EFalse; - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::MakePacket -// ----------------------------------------------------------------------------- -// -void CCRRtpTcpStreamer::MakePacket( TPtrC8& aData, const TInt aLength ) - { - ForwardPacket( aData.Mid( 0, aLength ) ); - aData.Set( aData.Mid( aLength ) ); - } - -// ----------------------------------------------------------------------------- -// CCRRtpTcpStreamer::ForwardPacket -// ----------------------------------------------------------------------------- -// -void CCRRtpTcpStreamer::ForwardPacket( const TDesC8& aPacket ) - { - if ( aPacket[0] == KCRRtpTcpStartMark ) - { - // 1. Forward (actually return or signal reception of) packet to user - const TInt channel( ( TInt )aPacket[1] ); - iObserver.RtpTcpPacketAvailable( - channel, aPacket.Mid( KCRRtpTcpHeaderLength ) ); - - // 2. Map channel to internal stream, ignore non audio or video - const TInt streamId( channel / 2 ); - if ( streamId >= 0 && streamId < KCRRtpTcpStreamCount ) - { - iStreams[streamId]->PacketAvailable( channel ); - } - } - else - { - // RTSP - iObserver.RtspMsgAvailable( aPacket ); - } - } - -// End of File