multimediacommscontroller/mmcch263payloadformat/src/mcch263oldpayloadencoder.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 "mcch263oldpayloadencoder.h"
       
    23 #include "mcch263formatlogs.h"
       
    24 
       
    25 // ============================ MEMBER FUNCTIONS ===============================
       
    26 
       
    27 
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // CIPMediaVideoSink::NewL()
       
    31 // First stage constructor
       
    32 // (other items were commented in a header).
       
    33 // -----------------------------------------------------------------------------
       
    34 //
       
    35 CMccH263OldPayloadEncoder* CMccH263OldPayloadEncoder::NewL()
       
    36     {
       
    37     return new ( ELeave ) CMccH263OldPayloadEncoder();
       
    38     }
       
    39 
       
    40 CMccH263OldPayloadEncoder::~CMccH263OldPayloadEncoder()
       
    41 	{
       
    42 	}
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CIPMediaVideoSink::WriteBufferL()
       
    46 // Write media buffer
       
    47 // (other items were commented in a header).
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 void CMccH263OldPayloadEncoder::EncodeL( 
       
    51 	CMMFBuffer* aMMFBuffer,
       
    52     RPointerArray<CBufferContainer>& aDesBuffers )
       
    53     {
       
    54     __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, enter")
       
    55 
       
    56     CMMFDataBuffer* buf = static_cast<CMMFDataBuffer*>( aMMFBuffer );
       
    57  	iSendHeader.iMarker = 0;
       
    58 
       
    59 	// Get timestamp to RTP header. conversion to 90kHz clock
       
    60 	TInt64 tmpStamp = ( buf->TimeToPlay().Int64() + iTimeStamp.Int64() ) /  KConst100 * KConst9 ;
       
    61 	iSendHeader.iTimestamp = TRtpTimeStamp( tmpStamp ) ;
       
    62   
       
    63     __H263FORMAT_MEDIA_INT2( "CMccH263OldPayloadEncoder::EncodeL, TimeStamp:", 
       
    64     iSendHeader.iTimestamp, "Length:", buf->BufferSize() )
       
    65     
       
    66     // Reset marker from last frame
       
    67 	iSendHeader.iMarker = 0;
       
    68 	
       
    69 	// Get pointer to raw data
       
    70 	TPtrC8 frame = buf->Data();
       
    71 	
       
    72     // Check that descriptor length is included. 
       
    73     // Missing length causes panic in frame.Mid() function
       
    74     if ( frame.Length() == 0 || buf->BufferSize() != frame.Length() )
       
    75         {
       
    76         __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, ERROR Buffer corrupted")
       
    77         User::Leave( KErrBadDescriptor );
       
    78         }
       
    79         
       
    80 	const TUint8 *dataPtr = buf->Data().Ptr();
       
    81 	// Get buffer length
       
    82 	TUint frameLength = buf->BufferSize();
       
    83     
       
    84     // Get frame header information
       
    85 	GetHeaderInfoL( frame );
       
    86 	
       
    87     // If packet is smaller than max Packet size. Send right away
       
    88     if ( frame.Length() <= TInt( KVideoPacketSize ) )
       
    89         {
       
    90         __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, Sending whole frame...")
       
    91 
       
    92 		// Set marker to indicate last packet of current frame
       
    93         CreateNewBufferL( aMMFBuffer,  
       
    94                           aDesBuffers, 
       
    95                           frame, 
       
    96                           frameLength + KConst4, 
       
    97                           1 );
       
    98 		
       
    99         __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, exit" )
       
   100         return;
       
   101         }
       
   102     
       
   103 	// Initialize splitting variables
       
   104 	TInt lastGOB = 0;
       
   105 	TInt lastsend = 0;
       
   106 	
       
   107 	// Scan frame for GOBs
       
   108 	for( TUint i= 0; i < frameLength; i++ )
       
   109 	    {   
       
   110 		dataPtr += i;
       
   111 		if ( *dataPtr == TUint8( 0x00 ) )
       
   112 		    {
       
   113 			dataPtr++;
       
   114 			if ( *dataPtr == TUint8( 0x00 ) )
       
   115 			    { 
       
   116 				dataPtr++;
       
   117 				if ( TUint8( *dataPtr&0xfc )>0x80 )
       
   118 				    {
       
   119 					if ( ( i - lastsend ) >= KVideoPacketSize && lastGOB )
       
   120 					    {
       
   121                        	__H263FORMAT_MEDIA_INT2("CMccH263OldPayloadEncoder::EncodeL(scan gobs), Sending packet f",
       
   122                        	lastsend, "len", ( lastGOB - lastsend ) )
       
   123 
       
   124 						// Packet size exceeded send new RTP Packet
       
   125 						TPtrC8 packetData = 
       
   126 							frame.Mid( lastsend, ( lastGOB - lastsend ) );
       
   127 							
       
   128 						CreateNewBufferL( aMMFBuffer,  
       
   129                                           aDesBuffers, 
       
   130                                           packetData, 
       
   131                                           packetData.Length() + KConst4, 
       
   132                                           iSendHeader.iMarker );
       
   133 
       
   134 						lastsend = lastGOB;
       
   135 					    }
       
   136 					lastGOB = i;
       
   137 				    }
       
   138 			    }
       
   139 		    } 
       
   140 		// Return pointer to begining of frame
       
   141 		dataPtr = frame.Ptr();
       
   142 	    }
       
   143 	    
       
   144 	// Check that last packet does not exceed packet size
       
   145 	if ( ( frameLength - lastsend ) >= KVideoPacketSize && lastsend != 0 )
       
   146 	    {
       
   147     	__H263FORMAT_MEDIA_INT2("CMccH263OldPayloadEncoder::EncodeL(last packet check), Sending packet f", 
       
   148     	lastsend, "len", ( lastGOB - lastsend ) )
       
   149 
       
   150 		TPtrC8 packetData = 
       
   151 			frame.Mid( lastsend, ( lastGOB - lastsend ) );
       
   152 			
       
   153 	    CreateNewBufferL( aMMFBuffer,  
       
   154                           aDesBuffers, 
       
   155                           packetData, 
       
   156                           packetData.Length() + KConst4, 
       
   157                           iSendHeader.iMarker );
       
   158 		
       
   159 		lastsend = lastGOB;
       
   160 	    }
       
   161 	    
       
   162 	// Send last packet to RTP API
       
   163 	if ( lastsend != 0 )
       
   164 	    {
       
   165 	    __H263FORMAT_MEDIA_INT2("CMccH263OldPayloadEncoder::EncodeL(last packet), Sending packet f", 
       
   166 	    lastsend, "len", ( frameLength - lastsend ) )
       
   167 	
       
   168 		TPtrC8 packetData = 
       
   169 			frame.Mid( lastsend, ( frameLength - lastsend ) );
       
   170 
       
   171 		// Set marker to indicate last packet of current frame
       
   172 	    CreateNewBufferL( aMMFBuffer,  
       
   173                           aDesBuffers, 
       
   174                           packetData, 
       
   175                           packetData.Length() + KConst4, 
       
   176                           1 );
       
   177 		
       
   178 		}
       
   179 		
       
   180 	// Special case no GOBs found try to send whole frame
       
   181 	else
       
   182 	    {       
       
   183         __H263FORMAT_MEDIA_INT1("CMccH263OldPayloadEncoder::EncodeL(no gobs), Sending whole packet len", 
       
   184         frameLength )
       
   185 	    
       
   186 		if ( buf->BufferSize() > TInt( KVideoPacketSize + KConst4 ) )
       
   187             {
       
   188             __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, ERROR, too big frame, exit")
       
   189 
       
   190             return;
       
   191             }
       
   192 
       
   193 		// Set marker to indicate last packet of current frame
       
   194         CreateNewBufferL( aMMFBuffer,  
       
   195                           aDesBuffers, 
       
   196                           frame, 
       
   197                           frameLength + KConst4, 
       
   198                           1 );
       
   199 		
       
   200 		}
       
   201 
       
   202     __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, exit")
       
   203  
       
   204     }
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CMccH263OldPayloadEncoder::WriteHeaderData()
       
   208 // Write payload header information byte
       
   209 // (other items were commented in a header).
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 TUint8 CMccH263OldPayloadEncoder::WriteHeaderData( TInt aByte )
       
   213     {
       
   214     __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::WriteHeaderData")
       
   215 
       
   216     //byte to be written
       
   217     TUint8 wbyte = 0;
       
   218 	//construct needed byte
       
   219     switch ( aByte )
       
   220 	    {
       
   221 	    case 0:
       
   222 		    {
       
   223 			wbyte |= TUint8( headerA.F << KConst7 );
       
   224 			wbyte |= TUint8( headerA.P << KConst6 );
       
   225 			wbyte |= TUint8( headerA.SBIT << KConst3 );
       
   226 			wbyte |= TUint8( headerA.EBIT );
       
   227 		    }break;
       
   228 	    case 1:
       
   229 		    {
       
   230 			wbyte |= TUint8( headerA.SRC << KConst5 );
       
   231 			wbyte |= TUint8( headerA.I << KConst4 );
       
   232 			wbyte |= TUint8( headerA.U << KConst3 );
       
   233 			wbyte |= TUint8( headerA.S << KConst2 );
       
   234 			wbyte |= TUint8( headerA.A << 1 );
       
   235 		    }break;
       
   236 	    case KConst2:
       
   237 		    {
       
   238 			wbyte |= TUint8( headerA.DBQ << KConst3 );
       
   239 			wbyte |= TUint8( headerA.TRB );
       
   240 		    }break;
       
   241 	    case KConst3:
       
   242 		    {
       
   243 			wbyte = headerA.TR;
       
   244 		    }break;
       
   245 	    default:
       
   246 		    {
       
   247 		    }break;
       
   248 	    }
       
   249 	//return constructed byte
       
   250     return wbyte;
       
   251     }
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CMccH263OldPayloadEncoder::GetHeaderInfoL()
       
   255 // Get video frame header information
       
   256 // (other items were commented in a header).
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 void CMccH263OldPayloadEncoder::GetHeaderInfoL( TDesC8& aFrame )
       
   260     {
       
   261     __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::GetHeaderInfoL")
       
   262 
       
   263 	//fill in default values = 0
       
   264 	headerA.F = 0;
       
   265 	headerA.P = 0;
       
   266 	headerA.SBIT = 0;
       
   267 	headerA.EBIT = 0;
       
   268 	headerA.SRC = 0;
       
   269 	headerA.I = 0;
       
   270 	headerA.U = 0;
       
   271 	headerA.S = 0;
       
   272 	headerA.A = 0;
       
   273 	headerA.R = 0;
       
   274 	headerA.DBQ = 0;
       
   275 	headerA.TRB = 0;
       
   276 	headerA.TR = 0;
       
   277 
       
   278 	//A S S U M I N G that aFrame begins with PSC
       
   279 	const TUint8 *help;
       
   280 	help = aFrame.Ptr();
       
   281 	//goto PTYPE-field
       
   282 	help += KConst4;
       
   283 	TUint8 test = 0;
       
   284 	//get SRC
       
   285 	test = TUint8( *help & 0x1c );
       
   286 	test >>= KConst2;
       
   287 	headerA.SRC = test;
       
   288 	if( headerA.SRC == KConst7 )
       
   289 	    {
       
   290         #ifdef LOG
       
   291 	        IPUL_LOGC( 1, "VSink::GetHeaderInfoL> ERROR: Picture format unsupported" );
       
   292         #endif
       
   293 	    }
       
   294 	//get I parameter
       
   295 	test = 0;
       
   296 	test = TUint8( *help & 0x02 );
       
   297 	test >>= 1;
       
   298 	headerA.I = test;
       
   299 	//get U parameter
       
   300 	test = 0;
       
   301 	test = TUint8( *help & 0x01 );
       
   302 	headerA.U = test;
       
   303 	//get S parameter
       
   304 	help++;
       
   305 	test = 0;
       
   306 	test = TUint8( *help & 0x80 );
       
   307 	test >>= KConst7;
       
   308 	headerA.S = test;
       
   309 	//get A parameter
       
   310 	test = 0;
       
   311 	test = TUint8( *help & 0x40 );
       
   312 	test >>= KConst6;
       
   313 	headerA.A = test;
       
   314 	//get P parameter
       
   315 	test = 0;
       
   316 	test = TUint8( *help & 0x20 );
       
   317 	test >>= KConst5;
       
   318 	headerA.P = test;
       
   319 	//check for correct file format
       
   320 	if ( headerA.P != 0 )
       
   321 	    {
       
   322         #ifdef LOG
       
   323 	    IPUL_LOGC( 1 , "VSink::GetHeaderInfoL> ERROR: Unsupported file format" );
       
   324         #endif
       
   325 	    }
       
   326     }
       
   327     
       
   328 // -----------------------------------------------------------------------------
       
   329 // CMccH263OldPayloadEncoder::SetPayloadType()
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CMccH263OldPayloadEncoder::SetPayloadType( TUint8 aPayloadType )
       
   333 	{
       
   334 	__H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::SetPayloadType")
       
   335 	
       
   336 	iSendHeader.iPayloadType = aPayloadType;
       
   337 	}
       
   338 
       
   339 // -----------------------------------------------------------------------------
       
   340 // CMccH263OldPayloadEncoder::CreateNewBufferL()
       
   341 // -----------------------------------------------------------------------------
       
   342 //
       
   343 void CMccH263OldPayloadEncoder::CreateNewBufferL( 
       
   344 	CMMFBuffer* aMMFBuffer,  
       
   345 	RPointerArray<CBufferContainer>& aDesBuffers,
       
   346 	const TDesC8& aPacketData,
       
   347 	TInt aLength,
       
   348 	TInt aMarker )
       
   349 	{
       
   350 	CMMFDataBuffer* newBuffer = 
       
   351 		CMMFDataBuffer::NewL( aLength );                          
       
   352 	CleanupStack::PushL( newBuffer );
       
   353 	newBuffer->Data().Append( WriteHeaderData( 0 ) );
       
   354 	newBuffer->Data().Append( WriteHeaderData( 1 ) );
       
   355 	newBuffer->Data().Append( WriteHeaderData( KConst2 ) );
       
   356 	newBuffer->Data().Append( WriteHeaderData( KConst3 ) );
       
   357 	newBuffer->Data().Append( aPacketData );
       
   358 	newBuffer->SetTimeToPlay( aMMFBuffer->TimeToPlay() );
       
   359 	newBuffer->SetFrameNumber( aMMFBuffer->FrameNumber() + iSequenceNumIncrementer );
       
   360 	
       
   361 	// If frame is divided in several packets, sequence numbers of following
       
   362 	// packets have to be modified
       
   363 	if ( aMarker == 0 )
       
   364 	    {
       
   365 	    iSequenceNumIncrementer++;
       
   366 	    }
       
   367 
       
   368 	CBufferContainer* cont = new (ELeave) CBufferContainer();
       
   369 	CleanupStack::Pop( newBuffer );
       
   370 	cont->iBuffer = newBuffer;
       
   371 	iSendHeader.iMarker = aMarker;
       
   372 	cont->iSendHeader = iSendHeader;
       
   373 	CleanupStack::PushL( cont );	    
       
   374 	aDesBuffers.AppendL( cont );
       
   375 	CleanupStack::Pop( cont );
       
   376     }
       
   377