multimediacommscontroller/mmcch263payloadformat/src/mcch263newpayloadencoder.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006 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 "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:    
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ============================ INCLUDES =======================================
       
    21 
       
    22 #include "mcch263newpayloadencoder.h"
       
    23 #include "mcch263formatlogs.h"
       
    24 
       
    25 // ============================ MEMBER FUNCTIONS ===============================
       
    26 
       
    27 // -----------------------------------------------------------------------------
       
    28 // CMccH263NewPayloadEncoder::NewL()
       
    29 // First stage constructor
       
    30 // (other items were commented in a header).
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 CMccH263NewPayloadEncoder* CMccH263NewPayloadEncoder::NewL()
       
    34     {
       
    35     return new ( ELeave ) CMccH263NewPayloadEncoder();
       
    36     }
       
    37     
       
    38 CMccH263NewPayloadEncoder::~CMccH263NewPayloadEncoder()
       
    39 	{	
       
    40 	}
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CMccH263NewPayloadEncoder::WriteBufferL()
       
    44 // Write media buffer
       
    45 // (other items were commented in a header).
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 void CMccH263NewPayloadEncoder::EncodeL( 
       
    49 	CMMFBuffer* aMMFBuffer,  
       
    50 	RPointerArray<CBufferContainer>& aDesBuffers  )
       
    51 	{
       
    52 	__H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL, enter")
       
    53 	
       
    54 	const TInt KMccValZero = 0;
       
    55 	const TInt KMccValOne = 1;
       
    56 
       
    57     CMMFDataBuffer* buf = static_cast<CMMFDataBuffer*>( aMMFBuffer );
       
    58  	iSendHeader.iMarker = 0;
       
    59 
       
    60     // Get timestamp to RTP header. conversion to 90kHz clock
       
    61 	TInt64 tmpStamp = 
       
    62 	    ( buf->TimeToPlay().Int64() + iTimeStamp.Int64() ) / KConst100 * KConst9 ;
       
    63 	iSendHeader.iTimestamp = TRtpTimeStamp( tmpStamp ) ;
       
    64 
       
    65     __H263FORMAT_MEDIA_INT2("CMccH263NewPayloadEncoder::EncodeL > TimeStamp:",
       
    66     iSendHeader.iTimestamp, "Length:", buf->BufferSize())
       
    67    
       
    68     // Reset marker from last frame
       
    69 	iSendHeader.iMarker = 0;
       
    70 	// Get pointer to raw data
       
    71 	TPtrC8 frame = buf->Data();
       
    72     
       
    73     // Check that descriptor length is included. 
       
    74     // Missing length causes panic in frame.Mid() function
       
    75     if ( frame.Length() == 0 || buf->BufferSize() != frame.Length() )
       
    76         {
       
    77         __H263FORMAT_MEDIA ("CMccH263NewPayloadEncoder::EncodeL, ERROR Buffer corrupted")
       
    78         User::Leave( KErrBadDescriptor );
       
    79         }
       
    80 	const TUint8 *dataPtr = buf->Data().Ptr();
       
    81 	
       
    82 	// Get buffer length
       
    83 	TUint frameLength = buf->BufferSize();
       
    84 	
       
    85     // Initialize splitting variables
       
    86 	TInt lastGOB = 0;
       
    87 	TInt lastsend = 0;
       
    88 	TPtrC8 packetData;
       
    89 	
       
    90 	// Scan frame for GOBs
       
    91 	for( TUint i= 0; i < frameLength - KConst2; i++ )
       
    92 	    {   
       
    93 		dataPtr += i;
       
    94 		if ( *dataPtr == TUint8( 0x00 ) )
       
    95 		    {
       
    96 			dataPtr++;
       
    97 			if ( *dataPtr == TUint8( 0x00 ) )
       
    98 			    { 
       
    99 				dataPtr++;
       
   100 				if ( TUint8( *dataPtr&0xfc ) > 0x80 )
       
   101 				    {	
       
   102 				    if ( ( i - lastsend ) >= KVideoPacketSize && 
       
   103 				         ( i - lastsend ) <= KMaxPacketSize &&
       
   104 				         lastGOB )
       
   105 					    {
       
   106                         __H263FORMAT_MEDIA_INT2(
       
   107                         "CMccH263NewPayloadEncoder::EncodeL(scan gobs), Sending packet f:",
       
   108                         lastsend, "len:", ( lastGOB - lastsend ) )
       
   109 
       
   110 						// Packet size exceeded send new RTP Packet
       
   111 				        // +2 exclude first 2 0-bytes
       
   112 						packetData.Set( 
       
   113 						    frame.Mid( ( lastsend + KConst2 ), 
       
   114 						               ( lastGOB - lastsend ) - KConst2 ) );
       
   115 						
       
   116                         CreateNewBufferL( aMMFBuffer,  
       
   117                                           aDesBuffers, 
       
   118                                           packetData, 
       
   119                                           packetData.Length() + KConst4, 
       
   120                                           KMccValZero,
       
   121                                           KMccValZero,
       
   122                                           KMccValOne );
       
   123 						
       
   124 						lastsend = lastGOB;
       
   125 					    }
       
   126 					    
       
   127 					lastGOB = i;
       
   128 				    }
       
   129 			    }
       
   130 		    } 
       
   131 		// Return pointer to begining of frame
       
   132 		dataPtr = frame.Ptr();
       
   133 	    }
       
   134 	    
       
   135     // Check that last packet does not exceed packet size
       
   136 	if ( ( frameLength - lastsend ) >= KVideoPacketSize && lastsend != 0 )
       
   137 	    {
       
   138         __H263FORMAT_MEDIA_INT2(
       
   139         "CMccH263NewPayloadEncoder::EncodeL(last packet check), Sending packet f:",
       
   140         lastsend, "len:", ( lastGOB - lastsend ) )
       
   141 
       
   142          // +2 exlude first 2 0-bytes
       
   143 		packetData.Set(
       
   144 			frame.Mid( ( lastsend + KConst2 ), ( lastGOB - lastsend ) - KConst2 ) );
       
   145  		
       
   146  		CreateNewBufferL( aMMFBuffer,  
       
   147  		                  aDesBuffers, 
       
   148  		                  packetData, 
       
   149  		                  packetData.Length() + KConst4, 
       
   150  		                  KMccValZero,
       
   151  		                  KMccValZero,
       
   152  		                  KMccValOne );
       
   153 		
       
   154 		lastsend = lastGOB;
       
   155 	    }
       
   156 	    
       
   157 	// Send last packet to RTP API
       
   158 	if ( lastsend != 0 )
       
   159 	    {
       
   160 	    __H263FORMAT_MEDIA_INT2(
       
   161 	    "CMccH263NewPayloadEncoder::EncodeL(last packet), Sending packet f:", 
       
   162 	    lastsend, "len:", ( frameLength - lastsend ) )
       
   163 
       
   164 	    // +2 exlude first 2 0-bytes
       
   165 		packetData.Set(
       
   166 			frame.Mid( ( lastsend + KConst2 ),( frameLength - lastsend ) - KConst2 ) ); 
       
   167 		
       
   168 		// Set marker to indicate last packet of current frame
       
   169         CreateNewBufferL( aMMFBuffer,  
       
   170                           aDesBuffers, 
       
   171                           packetData, 
       
   172                           packetData.Length() + KConst4, 
       
   173                           KMccValOne,
       
   174                           KMccValZero,
       
   175                           KMccValOne );
       
   176 		
       
   177 		}
       
   178 		
       
   179 	// Special case no GOBs found try to send whole frame
       
   180 	else
       
   181 	    {
       
   182 		if ( buf->BufferSize() > TInt( KVideoPacketSize + KConst2 ) )
       
   183             {
       
   184             __H263FORMAT_MEDIA(
       
   185             "CMccH263NewPayloadEncoder::EncodeL(no gobs), divide to multiple packets")
       
   186             
       
   187             // First packet            
       
   188             // 2 exlude first 2 0-bytes
       
   189             packetData.Set( frame.Mid( KConst2, ( KVideoPacketSize - KConst2 ) ) );
       
   190             
       
   191             // Set marker to indicate last packet of current frame
       
   192             CreateNewBufferL( aMMFBuffer,  
       
   193                               aDesBuffers, 
       
   194                               packetData, 
       
   195                               KVideoPacketSize, 
       
   196                               KMccValZero,
       
   197                               KMccValZero,
       
   198                               KMccValOne );
       
   199 
       
   200 	        // Other pieces
       
   201             TUint index = KVideoPacketSize, size;
       
   202     	    while (index < buf->BufferSize())
       
   203 	            {
       
   204 	            __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL(no gobs), looping")
       
   205 	            
       
   206 	            size= buf->BufferSize() - index;
       
   207                 packetData.Set(
       
   208                 	frame.Mid( index, Min( TInt( KVideoPacketSize - KConst2 ), size ) ) );
       
   209 
       
   210     	        // Set marker to indicate last packet of current frame
       
   211     	        TInt marker = size > TInt( KVideoPacketSize ) ? KMccValZero : KMccValOne;
       
   212 
       
   213 	            CreateNewBufferL( aMMFBuffer,  
       
   214 	                              aDesBuffers, 
       
   215 	                              packetData, 
       
   216 	                              Min( TInt( KVideoPacketSize ), size + KConst2 ), 
       
   217 	                              marker,
       
   218 	                              KMccValOne,
       
   219 	                              KMccValOne );
       
   220 
       
   221                 index += KVideoPacketSize - KConst2;
       
   222 	            }
       
   223             }
       
   224          else 
       
   225             {
       
   226             __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL(no gobs), fits one packet")
       
   227             
       
   228             // 2 exlude first 2 0-bytes
       
   229             packetData.Set( frame.Mid( KConst2, ( frameLength - KConst2 ) ) );
       
   230 
       
   231 			CreateNewBufferL( aMMFBuffer, 
       
   232 			                  aDesBuffers, 
       
   233 			                  packetData,frameLength, 
       
   234 			                  KMccValOne,
       
   235 			                  KMccValZero,
       
   236 			                  KMccValOne );
       
   237 
       
   238             }
       
   239 	    }
       
   240 
       
   241 	__H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL, exit")
       
   242   
       
   243     }
       
   244 // -----------------------------------------------------------------------------
       
   245 // CMccH263NewPayloadEncoder::WriteHeaderData()
       
   246 // Write payload header information byte
       
   247 // (other items were commented in a header).
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 TUint8 CMccH263NewPayloadEncoder::WriteHeaderData( TInt aByte )
       
   251     {
       
   252     __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::WriteHeaderData")
       
   253 
       
   254     TUint8 wbyte = 0;
       
   255     switch ( aByte )
       
   256     {
       
   257     case 0:
       
   258         {
       
   259         wbyte |= TUint8( 1 << KConst2 ); //indicate that fist 2 0-bytes are excluded
       
   260         }break;                    //from start codes
       
   261     case 1:
       
   262         {
       
   263         }break;
       
   264     default:
       
   265         {
       
   266         }break;
       
   267     }
       
   268     return wbyte;
       
   269     }
       
   270 // -----------------------------------------------------------------------------
       
   271 // CMccH263NewPayloadEncoder::SetPayloadType()
       
   272 // -----------------------------------------------------------------------------
       
   273 //
       
   274 void CMccH263NewPayloadEncoder::SetPayloadType( TUint8 aPayloadType )
       
   275 	{
       
   276 	__H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::SetPayloadType")
       
   277 	iSendHeader.iPayloadType = aPayloadType;
       
   278 	}
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CMccH263NewPayloadEncoder::CreateNewBufferL()
       
   282 // -----------------------------------------------------------------------------
       
   283 //
       
   284 void CMccH263NewPayloadEncoder::CreateNewBufferL( 
       
   285 	CMMFBuffer* aMMFBuffer,  
       
   286 	RPointerArray<CBufferContainer>& aDesBuffers,
       
   287 	const TDesC8& aPacketData,
       
   288 	TInt aLength,
       
   289 	TInt aMarker,
       
   290 	TInt aHeaderDataByteOne,
       
   291 	TInt aHeaderDataByteTwo )
       
   292 	{
       
   293 	CMMFDataBuffer* newBuffer = 
       
   294 		CMMFDataBuffer::NewL( aLength );                          
       
   295 	CleanupStack::PushL( newBuffer );
       
   296 	newBuffer->Data().Append( WriteHeaderData( aHeaderDataByteOne ) );
       
   297 	newBuffer->Data().Append( WriteHeaderData( aHeaderDataByteTwo ) );
       
   298 	newBuffer->Data().Append( aPacketData );
       
   299 	newBuffer->SetTimeToPlay( aMMFBuffer->TimeToPlay() );
       
   300 	newBuffer->SetFrameNumber( aMMFBuffer->FrameNumber() + iSequenceNumIncrementer );
       
   301 	
       
   302 	// If frame is divided in several packets, sequence numbers of following
       
   303 	// packets have to be modified
       
   304 	if ( aMarker == 0 )
       
   305 	    {
       
   306 	    iSequenceNumIncrementer++;
       
   307 	    }
       
   308 
       
   309 	CBufferContainer* cont = new (ELeave) CBufferContainer();
       
   310 	CleanupStack::Pop( newBuffer );
       
   311 	cont->iBuffer = newBuffer;
       
   312 	iSendHeader.iMarker = aMarker;
       
   313 	cont->iSendHeader = iSendHeader;
       
   314 	CleanupStack::PushL( cont );	    
       
   315 	aDesBuffers.AppendL( cont );
       
   316 	CleanupStack::Pop( cont );
       
   317     }
       
   318