dvrengine/CommonRecordingEngine/DvrSdpParser/src/CDvrSdpParser.cpp
branchRCL_3
changeset 47 826cea16efd9
parent 45 798ee5f1972c
child 48 13a33d82ad98
equal deleted inserted replaced
45:798ee5f1972c 47:826cea16efd9
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    Parses SDP file.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <ipvideo/CDvrSdpParser.h>
       
    22 #include <in_sock.h>
       
    23 #include "videoserviceutilsLogger.h"
       
    24 
       
    25 // CONSTANTS
       
    26 _LIT8( KKeyIpv4Addr, "c=IN IP4 " );
       
    27 _LIT8( KKeyIpv6Addr, "c=IN IP6 " );
       
    28 _LIT8( KKeyAttribute, "a=" );
       
    29 _LIT8( KKeyMedia, "m=" );
       
    30 _LIT8( KKeyMediaAudio, "m=audio " );
       
    31 _LIT8( KKeyMediaVideo, "m=video " );
       
    32 _LIT8( KKeyMediaTitle, "m=title " );
       
    33 _LIT8( KKeyDataStream, "m=data " );
       
    34 _LIT8( KKeyClockRate, "a=rtpmap:" );
       
    35 _LIT8( KKeyControl, "a=control:" ); 
       
    36 //_LIT8( KKeyStreamId, "a=control:streamid=" );
       
    37 _LIT8( KRealMediaIndicator, "/x-pn-real" ); 
       
    38 _LIT8( KKeyBandWidth, "b=AS:" );
       
    39 _LIT8( KCRSDPRtspUriBegin, "rtsp://" );
       
    40 _LIT8( KSPStr, " ");
       
    41 _LIT8( KCRStr, "\r");
       
    42 _LIT8( KLFStr, "\n");
       
    43 _LIT8( KCRLFStr, "\r\n");
       
    44 _LIT8( KSLStr, "/" );
       
    45 _LIT8( KSdpLiveStream, "a=LiveStream:integer;1");
       
    46 _LIT8( KSdpRangeHeaderLiveStream, "a=range:npt=now-" );
       
    47 
       
    48 // ============================ MEMBER FUNCTIONS ===============================
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // CDvrSdpParser::NewL
       
    52 // Two-phased constructor.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 EXPORT_C CDvrSdpParser* CDvrSdpParser::NewL()
       
    56     {
       
    57     CDvrSdpParser* self = CDvrSdpParser::NewLC();
       
    58     CleanupStack::Pop( self );
       
    59     return self;
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CDvrSdpParser::NewLC
       
    64 // Two-phased constructor.
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 EXPORT_C CDvrSdpParser* CDvrSdpParser::NewLC()
       
    68     {
       
    69     CDvrSdpParser* self = new( ELeave ) CDvrSdpParser();
       
    70     CleanupStack::PushL( self );
       
    71     self->ConstructL();
       
    72     return self;
       
    73     }
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CDvrSdpParser::CDvrSdpParser
       
    77 // C++ default constructor can NOT contain any code, that might leave.
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 CDvrSdpParser::CDvrSdpParser()
       
    81   : iAudioPort( KErrNotFound ),
       
    82     iVideoPort( KErrNotFound ),
       
    83     iTitlePort( KErrNotFound ),
       
    84     iAudioBitrate( KErrNotFound ),
       
    85     iVideoBitrate( KErrNotFound ),
       
    86     iAudioStreamId( KErrNotFound ),
       
    87     iVideoStreamId( KErrNotFound ),
       
    88     iVideoTimerGranularity( KMaxTUint32 ),
       
    89     iAudioTimerGranularity( KMaxTUint32 )
       
    90     {
       
    91     // None
       
    92     }
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CDvrSdpParser::ConstructL
       
    96 // Symbian 2nd phase constructor can leave.
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 void CDvrSdpParser::ConstructL()
       
   100     {
       
   101     LOG( "CDvrSdpParser::ConstructL()" );
       
   102     }
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // CDvrSdpParser::~CDvrSdpParser
       
   106 // Destructor.
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 EXPORT_C CDvrSdpParser::~CDvrSdpParser()
       
   110     {
       
   111     LOG( "CDvrSdpParser::~CDvrSdpParser()" );
       
   112     delete iBaseUrl; iBaseUrl = NULL; 
       
   113     DeleteVariables();
       
   114     }
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CDvrSdpParser::TryParseL
       
   118 // 
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 EXPORT_C void CDvrSdpParser::TryParseL( const TDesC8& aSdp, const TDesC8& aBaseUrl ) 
       
   122     {
       
   123 #if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE )
       
   124     HBufC* baseLog = HBufC::NewLC( aBaseUrl.Length() );
       
   125     TPtr ptr = baseLog->Des();
       
   126     ptr.Copy( aBaseUrl );
       
   127     LOG2( "CDvrSdpParser::TryParseL(), aSdp length: %d, aBaseUrl: %S",
       
   128                                        aSdp.Length(), &ptr );
       
   129     CleanupStack::PopAndDestroy( baseLog );
       
   130 #endif
       
   131     
       
   132     if ( aBaseUrl.Length() ) 
       
   133         {
       
   134         delete iBaseUrl; iBaseUrl = NULL; 
       
   135         iBaseUrl = aBaseUrl.AllocL(); 
       
   136         }
       
   137 
       
   138     TryParseL( aSdp ); 
       
   139     }
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // CDvrSdpParser::TryParseL
       
   143 //
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 EXPORT_C void CDvrSdpParser::TryParseL( const TDesC8& aSdp )
       
   147     {
       
   148     LOG1( "CDvrSdpParser::TryParseL(), aSdp length: %d", aSdp.Length() );
       
   149     
       
   150     // Find medias
       
   151     FindMediasL( aSdp );
       
   152     
       
   153     // Append found medias to the array
       
   154     for ( TInt i( 0 ); i < iMediaBuf.Count(); i++ )
       
   155         {
       
   156         TInt port( KErrNotFound );
       
   157         TPtrC8 ptr( iMediaBuf[i] );
       
   158 
       
   159         // Audio media info found ?
       
   160         port = GetIntL( ptr, KKeyMediaAudio );    
       
   161         if ( port != KErrNotFound )
       
   162             {
       
   163             iAudioPort = port;
       
   164             LOG1( "CDvrSdpParser::TryParseL(), iAudioPort: %d", iAudioPort );
       
   165             UpdateMediaInfoL( ptr, iAudioIpAddr );
       
   166             // Stream id (Helix takes medias in appearance order)
       
   167             iAudioStreamId = i;
       
   168             // Audio clock rate
       
   169             iAudioTimerGranularity = GetClockRateL( ptr );
       
   170             iAudioBitrate = GetIntL( ptr, KKeyBandWidth ); 
       
   171             // Audio attributes
       
   172             FindAttributesL( ptr, iAudioAttributes ); 
       
   173             // Audio control
       
   174             GetControlL( ptr, iAudioControlAddr );
       
   175             // Find media id 97 from a=rtpmap:97 MP4A-LATM/32000/2
       
   176             iMediaIdentifierAudio = GetIntL( ptr, KKeyClockRate ); 
       
   177             }
       
   178         else
       
   179             {
       
   180             // Video media info found ?
       
   181             port = GetIntL( ptr, KKeyMediaVideo );
       
   182             if ( port != KErrNotFound )
       
   183                 {
       
   184                 iVideoPort = port;
       
   185                 LOG1( "CDvrSdpParser::TryParseL(), iVideoPort: %d", iVideoPort );
       
   186                 UpdateMediaInfoL( ptr, iVideoIpAddr );
       
   187                 // Stream id (Helix takes medias in appearance order)
       
   188                 iVideoStreamId = i; 
       
   189                 // Video clock rate
       
   190                 iVideoTimerGranularity = GetClockRateL( ptr );
       
   191                 iVideoBitrate = GetIntL( ptr, KKeyBandWidth ); 
       
   192                 // Video attributes
       
   193                 FindAttributesL( ptr, iVideoAttributes );
       
   194                 // Video control
       
   195                 GetControlL( ptr, iVideoControlAddr );
       
   196                 // Find media id 96 from a=rtpmap:96 H264/90000 line
       
   197 	            iMediaIdentifierVideo = GetIntL( ptr, KKeyClockRate );
       
   198                 }
       
   199             else
       
   200                 {
       
   201                 port = GetIntL( ptr, KKeyMediaTitle );
       
   202                 if ( port != KErrNotFound )
       
   203                     {
       
   204                     iTitlePort = port;
       
   205                     LOG1( "CDvrSdpParser::TryParseL(), iTitlePort: %d", iTitlePort );
       
   206                     }
       
   207                 }
       
   208             }
       
   209         }
       
   210 
       
   211     iMediaBuf.Reset();
       
   212     delete iBaseUrl; iBaseUrl = NULL; 
       
   213     delete iCommonIp; iCommonIp = NULL;
       
   214     }
       
   215 
       
   216 // -----------------------------------------------------------------------------
       
   217 // CDvrSdpParser::NewLineL
       
   218 // 
       
   219 // -----------------------------------------------------------------------------
       
   220 //
       
   221 EXPORT_C void CDvrSdpParser::NewLineL(
       
   222     const TInt aStreamId,
       
   223     const TDesC8& aLine ) 
       
   224     {
       
   225     User::LeaveIfNull( iSdp );
       
   226     const TInt newLen( iSdp->Length() + aLine.Length() + KCRLFStr().Length() );
       
   227     LOG2( "CDvrSdpParser::NewLineL(), aStreamId: %d, New sdp length: %d",
       
   228                                       aStreamId, newLen );
       
   229     switch( aStreamId )
       
   230         {
       
   231         case KErrNotFound: // Common
       
   232             {
       
   233             // Alloc more room
       
   234             iSdp = iSdp->ReAllocL( newLen );
       
   235             TPtr8 ptr( iSdp->Des() );
       
   236             
       
   237             // Find first attribute for new line point
       
   238             const TInt insertPoint( ptr.Find( KKeyAttribute ) );
       
   239             User::LeaveIfError( insertPoint );
       
   240             ptr.Insert( insertPoint, KCRLFStr );
       
   241             ptr.Insert( insertPoint, aLine );
       
   242             }
       
   243             break;
       
   244             
       
   245         case 0: // Audio (usually)
       
   246         case 1: // Video (usually)
       
   247             {
       
   248             iSdp = iSdp->ReAllocL( newLen );
       
   249             InserNewLineL( aStreamId, aLine );
       
   250             }
       
   251             break;
       
   252         
       
   253         default:
       
   254             User::Leave( KErrCompletion );
       
   255         }
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CDvrSdpParser::GetSdp
       
   260 // 
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 EXPORT_C TInt CDvrSdpParser::GetSdp( TPtrC8& aSdp ) 
       
   264     {
       
   265     if ( iSdp )
       
   266         {
       
   267         aSdp.Set( iSdp->Des() );
       
   268         return KErrNone;
       
   269         }
       
   270     
       
   271     return KErrNotFound;
       
   272     }
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CDvrSdpParser::SupportedContent
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 EXPORT_C CDvrSdpParser::TDvrPacketProvidings CDvrSdpParser::SupportedContent( void )
       
   279     {
       
   280     TDvrPacketProvidings retval( EDvrNoProgramAtAll );
       
   281 
       
   282     if ( iAudioPort > KErrNotFound && iVideoPort > KErrNotFound )
       
   283         {
       
   284         retval = EDvrBothAudioAndVideo;
       
   285         }
       
   286     else if ( iAudioPort > KErrNotFound && iVideoPort <= KErrNotFound )
       
   287         {
       
   288         retval = EDvrAudioOnly;
       
   289         }
       
   290     else if ( iVideoPort > KErrNotFound && iAudioPort <= KErrNotFound )
       
   291         {
       
   292         retval = EDvrVideoOnly;
       
   293         }
       
   294     else
       
   295         {
       
   296         LOG( "CDvrSdpParser::SupportedContent(), No media !" );
       
   297         }
       
   298     
       
   299     return retval;
       
   300     }
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // CDvrSdpParser::SessionAttributes
       
   304 // 
       
   305 // -----------------------------------------------------------------------------
       
   306 //
       
   307 EXPORT_C RArray<TPtrC8>& CDvrSdpParser::SessionAttributes( void ) 
       
   308     {
       
   309     return iSessionAttributes; 
       
   310     }
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // CDvrSdpParser::AudioAttributes
       
   314 // 
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 EXPORT_C RArray<TPtrC8>& CDvrSdpParser::AudioAttributes( void ) 
       
   318     {
       
   319     return iAudioAttributes; 
       
   320     }
       
   321 
       
   322 // -----------------------------------------------------------------------------
       
   323 // CDvrSdpParser::VideoAttributes
       
   324 // 
       
   325 // -----------------------------------------------------------------------------
       
   326 //
       
   327 EXPORT_C RArray<TPtrC8>& CDvrSdpParser::VideoAttributes( void ) 
       
   328     {
       
   329     return iVideoAttributes; 
       
   330     }
       
   331 
       
   332 // -----------------------------------------------------------------------------
       
   333 // CDvrSdpParser::DataStreams
       
   334 // 
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 EXPORT_C RArray<TPtrC8>& CDvrSdpParser::DataStreams( void ) 
       
   338     {
       
   339     return iDataStreams; 
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CDvrSdpParser::IsIpv4Sdp
       
   344 // Checks if Ipv4 address in use.
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 EXPORT_C TBool CDvrSdpParser::IsIpv4Sdp( void ) 
       
   348     {
       
   349     return iIsIpv4;
       
   350     }   
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // CDvrSdpParser::IsMultiCastSdp
       
   354 // Checks if c= line did specify a multicast addr
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 EXPORT_C TBool CDvrSdpParser::IsMultiCastSdp( void ) 
       
   358     {
       
   359     return iIsMulticast;
       
   360     }   
       
   361 
       
   362 // -----------------------------------------------------------------------------
       
   363 // CDvrSdpParser::AudioControlAddr
       
   364 // 
       
   365 // -----------------------------------------------------------------------------
       
   366 //
       
   367 EXPORT_C TPtrC8 CDvrSdpParser::AudioControlAddr( void ) 
       
   368     {
       
   369     return ( iAudioControlAddr )? TPtrC8( *iAudioControlAddr ): 
       
   370                                   TPtrC8( KNullDesC8 );     
       
   371     }
       
   372 
       
   373 // -----------------------------------------------------------------------------
       
   374 // CDvrSdpParser::VideoControlAddr
       
   375 // 
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 EXPORT_C TPtrC8 CDvrSdpParser::VideoControlAddr( void ) 
       
   379     {
       
   380     return ( iVideoControlAddr )? TPtrC8( *iVideoControlAddr ):
       
   381                                   TPtrC8( KNullDesC8 );     
       
   382     }   
       
   383 
       
   384 // -----------------------------------------------------------------------------
       
   385 // CDvrSdpParser::AudioIpAddr
       
   386 // 
       
   387 // -----------------------------------------------------------------------------
       
   388 //
       
   389 EXPORT_C TPtrC8 CDvrSdpParser::AudioIpAddr( void ) 
       
   390     {
       
   391     return ( iAudioIpAddr )? TPtrC8( *iAudioIpAddr ): TPtrC8( KNullDesC8 );     
       
   392     }   
       
   393 
       
   394 // -----------------------------------------------------------------------------
       
   395 // CDvrSdpParser::VideoIpAddr
       
   396 // 
       
   397 // -----------------------------------------------------------------------------
       
   398 //
       
   399 EXPORT_C TPtrC8 CDvrSdpParser::VideoIpAddr( void ) 
       
   400     {
       
   401     return ( iVideoIpAddr )? TPtrC8( *iVideoIpAddr ): TPtrC8( KNullDesC8 );     
       
   402     }
       
   403 
       
   404 // -----------------------------------------------------------------------------
       
   405 // CDvrSdpParser::AudioPort
       
   406 // 
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 EXPORT_C TInt CDvrSdpParser::AudioPort( void ) 
       
   410     {
       
   411     return iAudioPort;
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CDvrSdpParser::VideoPort
       
   416 // 
       
   417 // -----------------------------------------------------------------------------
       
   418 //
       
   419 EXPORT_C TInt CDvrSdpParser::VideoPort( void ) 
       
   420     {
       
   421     return iVideoPort;
       
   422     }
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // CDvrSdpParser::AudioBitrate
       
   426 // 
       
   427 // -----------------------------------------------------------------------------
       
   428 //
       
   429 EXPORT_C TInt CDvrSdpParser::AudioBitrate( void ) 
       
   430     {
       
   431     return iAudioBitrate;
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CDvrSdpParser::VideoBitrate
       
   436 // 
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 EXPORT_C TInt CDvrSdpParser::VideoBitrate( void ) 
       
   440     {
       
   441     return iVideoBitrate;   
       
   442     }
       
   443 
       
   444 // -----------------------------------------------------------------------------
       
   445 // CDvrSdpParser::AudioStreamId
       
   446 // 
       
   447 // -----------------------------------------------------------------------------
       
   448 //
       
   449 EXPORT_C TInt CDvrSdpParser::AudioStreamId( void ) 
       
   450     {
       
   451     return iAudioStreamId;
       
   452     }
       
   453 
       
   454 // -----------------------------------------------------------------------------
       
   455 // CDvrSdpParser::VideoStreamId
       
   456 // 
       
   457 // -----------------------------------------------------------------------------
       
   458 //
       
   459 EXPORT_C TInt CDvrSdpParser::VideoStreamId( void ) 
       
   460     {
       
   461     return iVideoStreamId;
       
   462     }
       
   463 
       
   464 // -----------------------------------------------------------------------------
       
   465 // CDvrSdpParser::VideoTimerGranularity
       
   466 // 
       
   467 // -----------------------------------------------------------------------------
       
   468 //
       
   469 EXPORT_C TUint32 CDvrSdpParser::VideoTimerGranularity( void )  
       
   470     {
       
   471     return iVideoTimerGranularity; 
       
   472     }       
       
   473 
       
   474 // -----------------------------------------------------------------------------
       
   475 // CDvrSdpParser::AudioTimerGranularity
       
   476 // 
       
   477 // -----------------------------------------------------------------------------
       
   478 //
       
   479 EXPORT_C TUint32 CDvrSdpParser::AudioTimerGranularity( void ) 
       
   480     {
       
   481     return iAudioTimerGranularity; 
       
   482     }       
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CDvrSdpParser::IsRealMediaContent
       
   486 // Check for realmedia content.
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 EXPORT_C TBool CDvrSdpParser::IsRealMediaContent( void ) 
       
   490     {
       
   491     if ( iSdp && iSdp->Des().Find( KRealMediaIndicator ) != KErrNotFound )
       
   492         {
       
   493         LOG( "CDvrSdpParser::IsRealMediaContent(), Yes" );
       
   494         return ETrue;
       
   495         }   
       
   496         
       
   497     return EFalse;
       
   498     }
       
   499 
       
   500 // -----------------------------------------------------------------------------
       
   501 // CDvrSdpParser::MediaIdentifierAudio
       
   502 // 
       
   503 // -----------------------------------------------------------------------------
       
   504 //
       
   505 EXPORT_C TInt CDvrSdpParser::MediaIdentifierAudio( void )
       
   506 	{
       
   507 	return iMediaIdentifierAudio ;
       
   508 	}
       
   509 	
       
   510 // -----------------------------------------------------------------------------
       
   511 // CDvrSdpParser::MediaIdentifierVideo
       
   512 // 
       
   513 // -----------------------------------------------------------------------------
       
   514 //
       
   515 EXPORT_C TInt CDvrSdpParser::MediaIdentifierVideo( void )
       
   516 	{
       
   517 	return iMediaIdentifierVideo ;
       
   518 	}
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // CDvrSdpParser::IsLiveStream
       
   522 // 
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 EXPORT_C TBool CDvrSdpParser::IsLiveStream( void ) 
       
   526     {
       
   527     TBool isLiveStream = EFalse;
       
   528     if ( iSdp &&
       
   529        ( iSdp->Des().Find( KSdpLiveStream ) != KErrNotFound || 
       
   530          iSdp->Des().Find( KSdpRangeHeaderLiveStream ) != KErrNotFound ) )
       
   531         {
       
   532         LOG( "CDvrSdpParser::IsLiveStream(), Yes" );
       
   533         isLiveStream = ETrue;
       
   534         }
       
   535         
       
   536     return isLiveStream;
       
   537     }
       
   538     
       
   539 // -----------------------------------------------------------------------------
       
   540 // CDvrSdpParser::FindMediasL
       
   541 //
       
   542 // -----------------------------------------------------------------------------
       
   543 //
       
   544 void CDvrSdpParser::FindMediasL( const TDesC8& aSdp ) 
       
   545     {
       
   546     LOG1( "CDvrSdpParser::FindMediasL(), aSdp length: %d", aSdp.Length() );
       
   547 
       
   548     // Find medias from SDP
       
   549     DeleteVariables();
       
   550     iSdp = aSdp.AllocL();
       
   551     RArray<SMediaPoint> points;
       
   552     CleanupClosePushL( points );
       
   553     FindMediaPointsL( points );
       
   554     MakeMediaBuffersL( points );
       
   555     FindSessionAttributesL( points );
       
   556     CleanupStack::PopAndDestroy( &points );
       
   557     FindDataStreamsL( iSdp->Des(), iDataStreams );
       
   558     }
       
   559 
       
   560 // -----------------------------------------------------------------------------
       
   561 // CDvrSdpParser::FindMediaPointsL
       
   562 // Find points of all medias.
       
   563 // -----------------------------------------------------------------------------
       
   564 //
       
   565 void CDvrSdpParser::FindMediaPointsL( RArray<SMediaPoint>& aPoints )
       
   566     {
       
   567     TInt lastPoint( 0 );
       
   568     User::LeaveIfNull( iSdp );
       
   569     TPtrC8 ptr( iSdp->Des() );
       
   570     TInt start( MediaSectionStart( ptr ) );
       
   571     
       
   572     // Loop all media sections
       
   573     while ( start > KErrNotFound && lastPoint < iSdp->Length() )
       
   574         {
       
   575         // Find whole media section, up to next media or EOF
       
   576         start += lastPoint;
       
   577         TInt len( MediaSectionStart( ptr.Mid( start + KKeyMedia().Length() ) ) );
       
   578         len = ( len > KErrNotFound )? len + KKeyMedia().Length() - 1:
       
   579                                       ptr.Length() - start - 1;
       
   580         // New media point
       
   581         SMediaPoint point;
       
   582         point.iStart = start;
       
   583         point.iLength = len;
       
   584         lastPoint = ( start + len );
       
   585         User::LeaveIfError( aPoints.Append( point ) );
       
   586         LOG3( "CDvrSdpParser::FindMediaPointsL(), start: %d, len: %d, lastPoint: %d",
       
   587                                                   start, len, lastPoint );
       
   588         // Next section
       
   589         start = MediaSectionStart( ptr.Mid( lastPoint ) );
       
   590         }
       
   591     }
       
   592 
       
   593 // -----------------------------------------------------------------------------
       
   594 // CDvrSdpParser::MediaSectionStart
       
   595 //
       
   596 // -----------------------------------------------------------------------------
       
   597 //
       
   598 TInt CDvrSdpParser::MediaSectionStart( const TDesC8& aPtr ) 
       
   599     {
       
   600     TInt start( aPtr.Find( KKeyMedia ) );
       
   601     while ( start > KErrNotFound )
       
   602         {
       
   603         // Verify that not data stream keyword? ( i.e not 'm=data' )
       
   604         const TInt keywordlen( KKeyDataStream().Length() );
       
   605         TPtrC8 ptr( aPtr.Mid( start, keywordlen ) );
       
   606         if ( ptr.Find( KKeyDataStream ) == KErrNotFound )
       
   607             {
       
   608             // Audio, video or subtitle
       
   609             return start;
       
   610             }
       
   611         
       
   612         start += keywordlen;
       
   613         const TInt next( aPtr.Mid( start ).Find( KKeyMedia ) );
       
   614         start = ( next > KErrNotFound )? start + next: KErrNotFound;
       
   615         }
       
   616     
       
   617     return start;
       
   618     }
       
   619 
       
   620 // -----------------------------------------------------------------------------
       
   621 // CDvrSdpParser::MakeMediaBuffersL
       
   622 // Make media buffers
       
   623 // -----------------------------------------------------------------------------
       
   624 //
       
   625 void CDvrSdpParser::MakeMediaBuffersL( RArray<SMediaPoint>& aPoints )
       
   626     {
       
   627     User::LeaveIfNull( iSdp );
       
   628     for ( TInt i( 0 ); i < aPoints.Count(); i++ )
       
   629         {
       
   630         TPtrC8 media( iSdp->Des().Mid( aPoints[i].iStart, aPoints[i].iLength ) );
       
   631         User::LeaveIfError( iMediaBuf.Append( media ) );
       
   632         }
       
   633     }
       
   634 
       
   635 // -----------------------------------------------------------------------------
       
   636 // CDvrSdpParser::FindSessionAttributesL
       
   637 // Find session attributes (common section before any media) 
       
   638 // -----------------------------------------------------------------------------
       
   639 //
       
   640 void CDvrSdpParser::FindSessionAttributesL( RArray<SMediaPoint>& aPoints ) 
       
   641     {
       
   642     User::LeaveIfNull( iSdp );
       
   643     if ( aPoints.Count() )
       
   644         {
       
   645         TPtrC8 common( iSdp->Des().Left( aPoints[0].iStart ) );
       
   646         FindAttributesL( common, iSessionAttributes ); 
       
   647         
       
   648         // IP in common section
       
   649         delete iCommonIp; iCommonIp = NULL;
       
   650         iCommonIp = GetIpAddrL( common );
       
   651         }
       
   652     }
       
   653         
       
   654 // -----------------------------------------------------------------------------
       
   655 // CDvrSdpParser::InserNewLineL
       
   656 //
       
   657 // -----------------------------------------------------------------------------
       
   658 //
       
   659 void CDvrSdpParser::InserNewLineL(
       
   660     TInt aStreamId,
       
   661     const TDesC8& aLine )
       
   662     {
       
   663     RArray<SMediaPoint> points;
       
   664     CleanupClosePushL( points );
       
   665     FindMediaPointsL( points );
       
   666 
       
   667     // Add new line to first after media description
       
   668     if ( aStreamId >= 0 && aStreamId < points.Count() )
       
   669         {
       
   670         User::LeaveIfNull( iSdp );
       
   671         TPtr8 ptr( iSdp->Des() );
       
   672         TInt insertPoint( GetLen( ptr.Mid( points[aStreamId].iStart,
       
   673                                            points[aStreamId].iLength ), ETrue ) );
       
   674         User::LeaveIfError( insertPoint );
       
   675         ptr.Insert( insertPoint, aLine );
       
   676         ptr.Insert( insertPoint, KCRLFStr );
       
   677         }
       
   678     else
       
   679         {
       
   680         User::Leave( KErrCompletion );
       
   681         }
       
   682 
       
   683     CleanupStack::PopAndDestroy( &points );
       
   684     }
       
   685 
       
   686 // -----------------------------------------------------------------------------
       
   687 // CDvrSdpParser::UpdateMediaInfoL
       
   688 //
       
   689 // -----------------------------------------------------------------------------
       
   690 //
       
   691 void CDvrSdpParser::UpdateMediaInfoL(
       
   692     const TDesC8& aMediaPtr,
       
   693     HBufC8*& aAddress )
       
   694     {
       
   695     // Search for IP address (Ipv6/Ipv4)
       
   696     aAddress = GetIpAddrL( aMediaPtr );
       
   697     if ( !aAddress && iCommonIp )
       
   698         {
       
   699         aAddress = iCommonIp->AllocL();
       
   700         }
       
   701     User::LeaveIfNull( aAddress );
       
   702     TPtr8 ptr( aAddress->Des() );
       
   703 
       
   704     // IP Address
       
   705     if ( iIsIpv4 )
       
   706         {
       
   707         LOG( "CDvrSdpParser::UpdateMediaInfoL(), Removing v4 subnet mask" );
       
   708         // Remove possible subnet mask (e.g. c=IN IP4 225.0.1.15/64)
       
   709         const TInt maskPos( aAddress->Find( KSLStr ) ); 
       
   710         if ( maskPos != KErrNotFound )
       
   711             {
       
   712             ptr.SetLength( maskPos );
       
   713             }
       
   714         }
       
   715 
       
   716 #if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE )
       
   717     TName buf; buf.Copy( ptr );
       
   718     LOG1( "CDvrSdpParser::UpdateMediaInfoL(), aAddress: %S", &buf );
       
   719 #endif // LIVE_TV_RDEBUG_TRACE || LIVE_TV_FILE_TRACE
       
   720 
       
   721     /* Stream Id
       
   722     const TInt streamId( GetIntL( aMediaPtr, KKeyStreamId ) );
       
   723     LOG1( "CDvrSdpParser::UpdateMediaInfoL(), Stream Id: %d", streamId );
       
   724     return streamId;
       
   725     */
       
   726     }
       
   727     
       
   728 // -----------------------------------------------------------------------------
       
   729 // CDvrSdpParser::GetIpAddrL
       
   730 //
       
   731 // -----------------------------------------------------------------------------
       
   732 //
       
   733 HBufC8* CDvrSdpParser::GetIpAddrL( const TDesC8& aPtr ) 
       
   734     {
       
   735     iIsIpv4 = EFalse;
       
   736     HBufC8* ipAddr = GetStringL( aPtr, KKeyIpv6Addr );
       
   737     if ( !ipAddr )
       
   738         {
       
   739         ipAddr = GetStringL( aPtr, KKeyIpv4Addr );
       
   740         if ( ipAddr )
       
   741             {
       
   742             iIsIpv4 = ETrue;
       
   743             }
       
   744         }
       
   745         
       
   746     // Verify multicast
       
   747     if ( ipAddr )
       
   748         {
       
   749         TPtrC8 addr( ipAddr->Des() );
       
   750         if ( addr.Length() <= KMaxName )
       
   751             {
       
   752             CheckForMulticast( addr ); 
       
   753             }
       
   754         else
       
   755             {
       
   756             LOG1( "Ipaddress length too long: %d, leaving....", addr.Length() );
       
   757             delete ipAddr; ipAddr = NULL;
       
   758             User::Leave( KErrOverflow );
       
   759             }   
       
   760         }
       
   761     
       
   762     return ipAddr;
       
   763     }
       
   764 
       
   765 // -----------------------------------------------------------------------------
       
   766 // CDvrSdpParser::GetClockRateL
       
   767 //
       
   768 // -----------------------------------------------------------------------------
       
   769 //
       
   770 TUint CDvrSdpParser::GetClockRateL( const TDesC8& aPtr )
       
   771     {
       
   772     // Find clock rate keyword
       
   773     TInt start( FindStart( aPtr, KKeyClockRate ) );
       
   774     User::LeaveIfError( start );
       
   775 
       
   776     // Len up to first slash ( i.e: rtpmap:97 MP4A-LATM/32000/2 )
       
   777     TInt slash( aPtr.Mid( start ).Find( KSLStr ) ); 
       
   778     User::LeaveIfError( slash );
       
   779     start += ( slash + KSLStr().Length() );
       
   780     TInt len( GetLen( aPtr, start ) );
       
   781     
       
   782     // Len up to second slash ( i.e: rtpmap:97 MP4A-LATM/32000/2 )
       
   783     slash = aPtr.Mid( start, len ).Find( KSLStr );
       
   784     len = ( slash != KErrNotFound )? slash: len;
       
   785     return StrToUint( aPtr.Mid( start, len ) );
       
   786     }
       
   787     
       
   788 // -----------------------------------------------------------------------------
       
   789 // CDvrSdpParser::GetControlL() 
       
   790 // Checks if a=control line specifies a control for media.
       
   791 // -----------------------------------------------------------------------------
       
   792 //
       
   793 void CDvrSdpParser::GetControlL( const TDesC8& aMediaPtr, HBufC8*& aControlAddr )
       
   794     {
       
   795     delete aControlAddr; aControlAddr = NULL;
       
   796     HBufC8* control = GetStringL( aMediaPtr, KKeyControl ); 
       
   797     if ( control ) 
       
   798         {
       
   799         CleanupStack::PushL( control ); 
       
   800         if ( control->Des().FindC( KCRSDPRtspUriBegin ) == KErrNotFound )
       
   801             { 
       
   802             // relative url
       
   803             if ( iBaseUrl ) 
       
   804                 {
       
   805                 aControlAddr = HBufC8::NewL( iBaseUrl->Des().Length() + 
       
   806                                              control->Des().Length() + 
       
   807                                              KSLStr().Length() );
       
   808                 aControlAddr->Des().Append ( iBaseUrl->Des() ); 
       
   809                 aControlAddr->Des().Append ( KSLStr ) ; 
       
   810                 aControlAddr->Des().Append ( control->Des() );
       
   811                 }
       
   812             }
       
   813         else
       
   814             { 
       
   815             // absolute url
       
   816             aControlAddr = control->Des().AllocL();                     
       
   817             }
       
   818         
       
   819         CleanupStack::PopAndDestroy( control ); 
       
   820         }
       
   821     }
       
   822                 
       
   823 // -----------------------------------------------------------------------------
       
   824 // CDvrSdpParser::CheckForMulticast() 
       
   825 // Checks if c= line specifies a multicast addr
       
   826 // -----------------------------------------------------------------------------
       
   827 //
       
   828 void CDvrSdpParser::CheckForMulticast( const TDesC8& aLine )
       
   829     {
       
   830     TInetAddr controladdr;
       
   831     TName addr( KNullDesC );
       
   832     addr.Copy( aLine ); 
       
   833     TInt err( controladdr.Input( addr ) );
       
   834     if ( err != KErrNone )
       
   835         {
       
   836         LOG1( "CDvrSdpParser: invalid control address in SDP connection line '%S'", &addr );
       
   837         }
       
   838     else
       
   839         {
       
   840         // just do check for multicast, actual address is taken from SETUP response
       
   841         iIsMulticast = controladdr.IsMulticast();
       
   842 
       
   843 #if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE )
       
   844         /* Commented out, for some reason can crash with RTP playback in debug.
       
   845         if ( iIsMulticast )
       
   846             { 
       
   847             LOG1( "CDvrSdpParser: detected MULTICAST (%S) control address in SDP", &addr );
       
   848             }
       
   849         else
       
   850             {
       
   851             LOG1( "CDvrSdpParser: detected unicast (%S) control address in SDP", &addr );
       
   852             }
       
   853         */
       
   854 #endif // LIVE_TV_RDEBUG_TRACE || LIVE_TV_FILE_TRACE
       
   855         }
       
   856     }   
       
   857 
       
   858 // -----------------------------------------------------------------------------
       
   859 // CDvrSdpParser::FindAttributesL
       
   860 // 
       
   861 // -----------------------------------------------------------------------------
       
   862 //  
       
   863 void CDvrSdpParser::FindAttributesL(
       
   864     const TDesC8& aSdpSection,
       
   865     RArray<TPtrC8>& aAttributeList ) 
       
   866     {
       
   867     TInt last( 0 );
       
   868     TInt start( KErrNotFound );
       
   869     do
       
   870         {
       
   871         // Rest of the SDP section
       
   872         TPtrC8 rest( aSdpSection.Mid( last ) );
       
   873         start = rest.Find( KKeyAttribute );
       
   874         if ( start > KErrNotFound )
       
   875             {
       
   876             last += start;
       
   877             TInt len( GetLen( rest, start, ETrue ) );
       
   878             if ( len > 0 )
       
   879                 { 
       
   880                 // Add other than control attribute
       
   881                 if ( rest.Mid( start, len ).Find( KKeyControl ) == KErrNotFound )
       
   882                     {
       
   883                     TPtrC8 ptr( rest.Mid( start, len ) );
       
   884                     User::LeaveIfError( aAttributeList.Append( ptr ) ); 
       
   885                     }
       
   886                 
       
   887                 last += len;
       
   888                 }
       
   889             }
       
   890         }
       
   891         while( start > KErrNotFound );
       
   892     }                           
       
   893                                
       
   894 // -----------------------------------------------------------------------------
       
   895 // CDvrSdpParser::FindDataStreamsL
       
   896 // 
       
   897 // -----------------------------------------------------------------------------
       
   898 //  
       
   899 void CDvrSdpParser::FindDataStreamsL(
       
   900     const TDesC8& aSdpSection,
       
   901     RArray<TPtrC8>& aStreamsList )
       
   902     {
       
   903     TInt last( 0 );
       
   904     TInt start( KErrNotFound );
       
   905     do
       
   906         {
       
   907         // Rest of the SDP block
       
   908         TPtrC8 rest( aSdpSection.Mid( last ) );
       
   909         start = rest.Find( KKeyDataStream );
       
   910         if ( start > KErrNotFound )
       
   911             {
       
   912             last += start;
       
   913             TInt len( GetLen( rest, start, ETrue ) );
       
   914             if ( len > 0 )
       
   915                 { 
       
   916                 TPtrC8 ptr( rest.Mid( start, len ) );
       
   917                 User::LeaveIfError( aStreamsList.Append( ptr ) ); 
       
   918                 last += len;
       
   919                 }
       
   920             }
       
   921         }
       
   922         while( start > KErrNotFound );
       
   923     }                           
       
   924                                
       
   925 // -----------------------------------------------------------------------------
       
   926 // CDvrSdpParser::GetIntL
       
   927 //
       
   928 // -----------------------------------------------------------------------------
       
   929 //
       
   930 TInt CDvrSdpParser::GetIntL( const TDesC8& aPtr, const TDesC8& aKeyword ) 
       
   931     {
       
   932     TInt ret( KErrNotFound );
       
   933     HBufC8* buf = GetStringL( aPtr, aKeyword );
       
   934     if ( buf )
       
   935         {
       
   936         ret = StrToUint( buf->Des() );
       
   937         delete buf;
       
   938         }
       
   939    
       
   940     return ret;
       
   941     }
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // CDvrSdpParser::GetStringL
       
   945 //
       
   946 // -----------------------------------------------------------------------------
       
   947 //
       
   948 HBufC8* CDvrSdpParser::GetStringL( const TDesC8& aPtr, const TDesC8& aKeyword ) 
       
   949     {
       
   950     const TInt start( FindStart( aPtr, aKeyword ) );
       
   951     const TInt len( GetLen( aPtr, start ) );
       
   952 
       
   953     HBufC8* buf = NULL;
       
   954     if ( start > KErrNotFound && len > 0 && ( start + len ) <= aPtr.Length() )
       
   955         {
       
   956         buf = aPtr.Mid( start, len ).AllocL();
       
   957         }
       
   958     
       
   959     return buf;
       
   960     }
       
   961 
       
   962 // -----------------------------------------------------------------------------
       
   963 // CDvrSdpParser::FindStart
       
   964 //
       
   965 // -----------------------------------------------------------------------------
       
   966 //
       
   967 TInt CDvrSdpParser::FindStart( const TDesC8& aPtr, const TDesC8& aKeyword ) 
       
   968     {
       
   969     TInt start( aPtr.Find( aKeyword ) ); 
       
   970     
       
   971     if ( start > KErrNotFound )
       
   972         {
       
   973         start += aKeyword.Length();
       
   974         }
       
   975     
       
   976     return start;
       
   977     }
       
   978 
       
   979 // -----------------------------------------------------------------------------
       
   980 // CDvrSdpParser::GetLen
       
   981 //
       
   982 // -----------------------------------------------------------------------------
       
   983 //
       
   984 TInt CDvrSdpParser::GetLen(
       
   985     const TDesC8& aPtr,
       
   986     const TInt aStart,
       
   987     const TBool aIgnoreSpace )
       
   988     {
       
   989     if ( aStart > KErrNotFound && aStart < aPtr.Length() )
       
   990         {
       
   991         // Find next LF, CR or CRLF combination
       
   992         TInt len1( MinNonError( aPtr.Mid( aStart ).Find( KLFStr ),
       
   993                                 aPtr.Mid( aStart ).Find( KCRStr ) ) );
       
   994         // Find space
       
   995         TInt len2( ( aIgnoreSpace )? KErrNotFound: 
       
   996                                      aPtr.Mid( aStart ).Find( KSPStr ) );
       
   997 
       
   998         if ( len1 == KErrNotFound && len2 == KErrNotFound )
       
   999             {
       
  1000             // Rest of the buffer
       
  1001             return ( aPtr.Length() - aStart );
       
  1002             }
       
  1003         else
       
  1004             {
       
  1005             // CRLF or space
       
  1006             return MinNonError( len1, len2 );
       
  1007             }
       
  1008         }
       
  1009     
       
  1010     return KErrNotFound;
       
  1011     }
       
  1012 
       
  1013 // -----------------------------------------------------------------------------
       
  1014 // CDvrSdpParser::MinNonError
       
  1015 //
       
  1016 // -----------------------------------------------------------------------------
       
  1017 //
       
  1018 TInt CDvrSdpParser::MinNonError( const TInt aValue1, const TInt aValue2 )
       
  1019     {
       
  1020     if ( aValue1 > KErrNotFound && aValue2 > KErrNotFound )
       
  1021         {
       
  1022         return Min( aValue1, aValue2 );
       
  1023         }
       
  1024 
       
  1025     return ( ( aValue1 > KErrNotFound )? aValue1: 
       
  1026              ( aValue2 > KErrNotFound )? aValue2: KErrNotFound );
       
  1027     }
       
  1028     
       
  1029 // -----------------------------------------------------------------------------
       
  1030 // CDvrSdpParser::StrToUint
       
  1031 // Convert string to integer.
       
  1032 // -----------------------------------------------------------------------------
       
  1033 //
       
  1034 TUint CDvrSdpParser::StrToUint( const TDesC8& aString ) 
       
  1035     {
       
  1036     TLex8 templex;
       
  1037     templex.Assign( aString );
       
  1038     TUint ret( KMaxTUint );
       
  1039     templex.Val( ret );
       
  1040     return ret;
       
  1041     }
       
  1042 
       
  1043 // -----------------------------------------------------------------------------
       
  1044 // CDvrSdpParser::DeleteVariables
       
  1045 // 
       
  1046 // -----------------------------------------------------------------------------
       
  1047 //
       
  1048 void CDvrSdpParser::DeleteVariables( void )
       
  1049     {
       
  1050     delete iSdp; iSdp = NULL;
       
  1051     delete iCommonIp; iCommonIp = NULL;
       
  1052     iMediaBuf.Reset();
       
  1053     iSessionAttributes.Reset();
       
  1054     iAudioAttributes.Reset();
       
  1055     iVideoAttributes.Reset();
       
  1056     iDataStreams.Reset();
       
  1057     delete iAudioControlAddr; iAudioControlAddr = NULL;
       
  1058     delete iVideoControlAddr; iVideoControlAddr = NULL;
       
  1059     delete iAudioIpAddr; iAudioIpAddr = NULL;
       
  1060     delete iVideoIpAddr; iVideoIpAddr = NULL;
       
  1061     }
       
  1062 
       
  1063 //  End of File