videoeditorengine/avcedit/src/vedavceditimp.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 7 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "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 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Implementation class for AVC editing operations.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include <e32svr.h>  
       
    22 #include <mmf/devVideo/avc.h>
       
    23 
       
    24 #include "biblin.h"
       
    25 #include "bitbuffer.h"
       
    26 #include "vld.h"
       
    27 #include "vedavceditimp.h"
       
    28 
       
    29 // Debug print macro
       
    30 #ifdef _DEBUG   
       
    31 #include <e32svr.h>
       
    32 #define PRINT(x) RDebug::Print x;
       
    33 #else
       
    34 #define PRINT(x)
       
    35 #endif
       
    36 
       
    37 // An assertion macro wrapper to clean up the code a bit
       
    38 #define VPASSERT(x) __ASSERT_DEBUG(x, User::Panic(_L("CVedAVCEdit"), -10000))
       
    39 
       
    40 // ================= MEMBER FUNCTIONS =======================
       
    41 
       
    42 // Two-phased constructor
       
    43 CVedAVCEditImp* CVedAVCEditImp::NewL()
       
    44 {
       
    45     CVedAVCEditImp* self = new (ELeave) CVedAVCEditImp();
       
    46     CleanupStack::PushL(self);
       
    47     self->ConstructL();
       
    48     CleanupStack::Pop();    
       
    49     return self;    
       
    50 }
       
    51 
       
    52 // C++ default constructor
       
    53 CVedAVCEditImp::CVedAVCEditImp()
       
    54     {    
       
    55     }
       
    56 
       
    57 // Symbian OS default constructor can leave
       
    58 void CVedAVCEditImp::ConstructL()
       
    59     {
       
    60     
       
    61     iAvcDecoder = avcdOpen();
       
    62     
       
    63     if (!iAvcDecoder)
       
    64         {
       
    65         User::Leave(KErrNoMemory);
       
    66         }
       
    67 
       
    68 #ifdef VIDEOEDITORENGINE_AVC_EDITING
       
    69 	iNalLengthSize = 4;
       
    70 	iOutputLevel = 10;
       
    71 #endif
       
    72     
       
    73     }
       
    74 
       
    75 // Destructor
       
    76 CVedAVCEditImp::~CVedAVCEditImp()
       
    77     {
       
    78     avcdClose(iAvcDecoder);
       
    79     }
       
    80 
       
    81 
       
    82 // ---------------------------------------------------------7
       
    83 // AVCEditParser::ProcessAVCBitStream
       
    84 // Process one input AVC frame, i.e., convert to MDF NAL unit
       
    85 // (other items were commented in a header).
       
    86 // ---------------------------------------------------------
       
    87 //				
       
    88 void CVedAVCEditImp::ProcessAVCBitStreamL(TDes8& aBuf, TInt& aFrameLen, TInt aDecInfoSize, TBool aFirstFrame)
       
    89     {
       
    90     
       
    91     TUint8* dataBuffer = (TUint8*)(aBuf.Ptr());        
       
    92 
       
    93     // Calculate NAL header start offset
       
    94     TInt offset = (((aFrameLen - 1) / 4) + 1) * 4;     // Align at 32-bit boundrary
       
    95     TInt numNALUnits = 0;        
       
    96 
       
    97     if (aFirstFrame)    // There are several NAL units: decoder info and the frame
       
    98         {
       
    99         // how many bytes used for length
       
   100         iFrameLengthBytes = ( dataBuffer[4] & 0x3 ) + 1;
       
   101         
       
   102         // Index where to read configuration data
       
   103         TInt index = 5;     // Skip version and length information                        
       
   104         
       
   105         TInt numOfSPS = dataBuffer[index] & 0x1f;
       
   106         index++;
       
   107         
       
   108         // Loop all SPS units
       
   109         for (TInt i = 0; i < numOfSPS; ++i)
       
   110             {
       
   111             TInt SPSSize = (dataBuffer[index] << 8) + dataBuffer[index + 1];
       
   112             index += 2;
       
   113             
       
   114             // Set NAL start offset
       
   115             dataBuffer[offset + 0] = TUint8(index & 0xff);
       
   116             dataBuffer[offset + 1] = TUint8((index >> 8) & 0xff);
       
   117             dataBuffer[offset + 2] = TUint8((index >> 16) & 0xff);
       
   118             dataBuffer[offset + 3] = TUint8((index >> 24) & 0xff);
       
   119             
       
   120             // Set NAL size
       
   121             dataBuffer[offset + 4] = TUint8(SPSSize & 0xff);
       
   122             dataBuffer[offset + 5] = TUint8((SPSSize >> 8) & 0xff);
       
   123             dataBuffer[offset + 6] = TUint8((SPSSize >> 16) & 0xff);
       
   124             dataBuffer[offset + 7] = TUint8((SPSSize >> 24) & 0xff);
       
   125             
       
   126             offset += 8;
       
   127             index += SPSSize;
       
   128             numNALUnits++;
       
   129             }
       
   130             
       
   131         TInt numOfPPS = dataBuffer[index];
       
   132         index++;
       
   133         
       
   134         // Loop all PPS units
       
   135         for (TInt i = 0; i < numOfPPS; ++i)
       
   136             {
       
   137             TInt PPSSize = (dataBuffer[index] << 8) + dataBuffer[index + 1];
       
   138             index += 2;
       
   139             
       
   140             // Set NAL start offset
       
   141             dataBuffer[offset + 0] = TUint8(index & 0xff);
       
   142             dataBuffer[offset + 1] = TUint8((index >> 8) & 0xff);
       
   143             dataBuffer[offset + 2] = TUint8((index >> 16) & 0xff);
       
   144             dataBuffer[offset + 3] = TUint8((index >> 24) & 0xff);
       
   145             
       
   146             // Set NAL size
       
   147             dataBuffer[offset + 4] = TUint8(PPSSize & 0xff);
       
   148             dataBuffer[offset + 5] = TUint8((PPSSize >> 8) & 0xff);
       
   149             dataBuffer[offset + 6] = TUint8((PPSSize >> 16) & 0xff);
       
   150             dataBuffer[offset + 7] = TUint8((PPSSize >> 24) & 0xff);
       
   151             
       
   152             offset += 8;
       
   153             index += PPSSize;
       
   154             numNALUnits++;
       
   155             }
       
   156         
       
   157         TInt totalFrameSize = aFrameLen;
       
   158         TInt currentProcessed = aDecInfoSize + 4; // skip DCR & length
       
   159         TUint8* frameLenPtr = const_cast<TUint8*>(aBuf.Ptr()) + aDecInfoSize;
       
   160         
       
   161         TInt frameSize = 0;
       
   162         
       
   163         // loop all slice NAL units
       
   164         while (currentProcessed < totalFrameSize)
       
   165             {                                        
       
   166                 
       
   167             // Set the NAL start offset
       
   168             dataBuffer[offset + 0] = TUint8(currentProcessed & 0xff);
       
   169             dataBuffer[offset + 1] = TUint8((currentProcessed >> 8) & 0xff);
       
   170             dataBuffer[offset + 2] = TUint8((currentProcessed >> 16) & 0xff);
       
   171             dataBuffer[offset + 3] = TUint8((currentProcessed >> 24) & 0xff);
       
   172             
       
   173             frameSize = (frameLenPtr[0] << 24) + (frameLenPtr[1] << 16) +
       
   174                         (frameLenPtr[2] << 8) + frameLenPtr[3];
       
   175             
       
   176             // Set the NAL size
       
   177             dataBuffer[offset + 4] = TUint8(frameSize & 0xff);
       
   178             dataBuffer[offset + 5] = TUint8((frameSize >> 8) & 0xff);
       
   179             dataBuffer[offset + 6] = TUint8((frameSize >> 16) & 0xff);
       
   180             dataBuffer[offset + 7] = TUint8((frameSize >> 24) & 0xff);
       
   181             
       
   182             frameLenPtr += (4 + frameSize);
       
   183             currentProcessed += (4 + frameSize);
       
   184             offset += 8;    
       
   185             numNALUnits++;
       
   186             
       
   187             }
       
   188         
       
   189         // Set Number of NAL units
       
   190         dataBuffer[offset + 0] = TUint8(numNALUnits & 0xff);
       
   191         dataBuffer[offset + 1] = TUint8((numNALUnits >> 8) & 0xff);
       
   192         dataBuffer[offset + 2] = TUint8((numNALUnits >> 16) & 0xff);
       
   193         dataBuffer[offset + 3] = TUint8((numNALUnits >> 24) & 0xff);
       
   194         
       
   195         aFrameLen = offset + 4;
       
   196         }
       
   197     else
       
   198         {  // process just the frame
       
   199 
       
   200         TInt totalFrameSize = aFrameLen;
       
   201         TInt currentProcessed = 4;  // skip length
       
   202         TUint8* frameLenPtr = const_cast<TUint8*>(aBuf.Ptr());
       
   203         
       
   204         TInt frameSize = 0;
       
   205         
       
   206         // loop all slice NAL units
       
   207         while (currentProcessed < totalFrameSize)
       
   208             {
       
   209             // Set the NAL start offset
       
   210             dataBuffer[offset + 0] = TUint8(currentProcessed & 0xff);
       
   211             dataBuffer[offset + 1] = TUint8((currentProcessed >> 8) & 0xff);
       
   212             dataBuffer[offset + 2] = TUint8((currentProcessed >> 16) & 0xff);
       
   213             dataBuffer[offset + 3] = TUint8((currentProcessed >> 24) & 0xff);
       
   214             
       
   215             frameSize = (frameLenPtr[0] << 24) + (frameLenPtr[1] << 16) +
       
   216                         (frameLenPtr[2] << 8) + frameLenPtr[3];
       
   217             
       
   218             // Set the NAL size
       
   219             dataBuffer[offset + 4] = TUint8(frameSize & 0xff);
       
   220             dataBuffer[offset + 5] = TUint8((frameSize >> 8) & 0xff);
       
   221             dataBuffer[offset + 6] = TUint8((frameSize >> 16) & 0xff);
       
   222             dataBuffer[offset + 7] = TUint8((frameSize >> 24) & 0xff);
       
   223             
       
   224             frameLenPtr += (4 + frameSize);
       
   225             currentProcessed += (4 + frameSize);
       
   226             offset += 8;    
       
   227             numNALUnits++;
       
   228             }
       
   229                
       
   230         // Number of NAL units
       
   231         dataBuffer[offset + 0] = TUint8(numNALUnits & 0xff);
       
   232         dataBuffer[offset + 1] = TUint8((numNALUnits >> 8) & 0xff);
       
   233         dataBuffer[offset + 2] = TUint8((numNALUnits >> 16) & 0xff);
       
   234         dataBuffer[offset + 3] = TUint8((numNALUnits >> 24) & 0xff);
       
   235         
       
   236         aFrameLen = offset + 4;
       
   237         }
       
   238     //iDataLength = iCurrentFrameLength;
       
   239     }
       
   240     
       
   241 // ---------------------------------------------------------
       
   242 // CVedAVCEditImp::GetMaxAVCFrameBuffering
       
   243 // Calculate maximum amount of buffered AVC frames 
       
   244 // (other items were commented in a header).
       
   245 // ---------------------------------------------------------
       
   246 //				
       
   247 TInt CVedAVCEditImp::GetMaxAVCFrameBuffering(TInt aLevel, TSize aResolution)
       
   248     {
       
   249 
       
   250     TReal maxDPB = 0.0;    
       
   251     switch (aLevel)
       
   252         {
       
   253         case 11:        
       
   254             maxDPB = 337.5;        
       
   255             break;
       
   256                         
       
   257         case 12:
       
   258             maxDPB = 891.0;
       
   259             break;
       
   260         
       
   261         case 10:
       
   262         case 101:
       
   263         default:
       
   264             maxDPB = 148.5;
       
   265             break;
       
   266         }
       
   267     
       
   268     TInt mbWidth = aResolution.iWidth / 16;
       
   269     TInt mbHeight = aResolution.iHeight / 16;
       
   270     
       
   271     TInt maxDPBSize = TInt( ( TReal(1024.0) * maxDPB ) / ( TReal(mbWidth*mbHeight*384.0) ) );
       
   272  
       
   273     maxDPBSize = min(maxDPBSize, 16);
       
   274  
       
   275     return maxDPBSize;
       
   276     }
       
   277     
       
   278 // ---------------------------------------------------------
       
   279 // CVedAVCEditImp::GetLevel   
       
   280 // Get input bitstream level from SPS
       
   281 // ---------------------------------------------------------
       
   282 //
       
   283 TInt CVedAVCEditImp::GetLevel(TDesC8& aBuf, TInt& aLevel)
       
   284     {
       
   285     TUint8* buffer = (TUint8*)(aBuf.Ptr());
       
   286 
       
   287     TInt index = 5;     // Skip version and length information                        
       
   288     
       
   289 #ifdef _DEBUG
       
   290     TInt numOfSPS = buffer[index] & 0x1f;
       
   291     VPASSERT(numOfSPS == 1);
       
   292 #endif
       
   293     
       
   294     index++;
       
   295     
       
   296     TUint SPSSize = (buffer[index] << 8) + buffer[index + 1];
       
   297     index += 2;
       
   298     
       
   299     TInt error = avcdParseLevel(iAvcDecoder, (void*)&buffer[index], &SPSSize, aLevel);
       
   300     
       
   301     if (error != KErrNone)
       
   302         return error;
       
   303 
       
   304     return KErrNone;
       
   305     }
       
   306 
       
   307 
       
   308 // ---------------------------------------------------------
       
   309 // CVedAVCEditImp::GetResolution   
       
   310 // Get input bitstream resolution from SPS
       
   311 // ---------------------------------------------------------
       
   312 //
       
   313 TInt CVedAVCEditImp::GetResolution(TDesC8& aBuf, TSize& aResolution)
       
   314 {
       
   315 
       
   316     TUint8* buffer = (TUint8*)(aBuf.Ptr());
       
   317 
       
   318     TInt index = 5;     // Skip version and length information                        
       
   319     
       
   320 #ifdef _DEBUG
       
   321     TInt numOfSPS = buffer[index] & 0x1f;
       
   322     VPASSERT(numOfSPS == 1);
       
   323 #endif
       
   324     
       
   325     index++;
       
   326     
       
   327     TUint SPSSize = (buffer[index] << 8) + buffer[index + 1];
       
   328     index += 2;
       
   329     
       
   330     TInt error = avcdParseResolution(iAvcDecoder, (void*)&buffer[index], &SPSSize, 
       
   331                                      aResolution.iWidth, aResolution.iHeight);
       
   332     
       
   333     if (error != KErrNone)
       
   334         return error;
       
   335 
       
   336     return KErrNone;
       
   337 }
       
   338 
       
   339 
       
   340 
       
   341 #ifdef VIDEOEDITORENGINE_AVC_EDITING
       
   342 // ---------------------------------------------------------
       
   343 // AVCEditParser::SaveAVCDecoderConfigurationRecordL
       
   344 // Saves SPS/PPS Nal units from AVCDecoderConfigurationRecord
       
   345 // (other items were commented in a header).
       
   346 // ---------------------------------------------------------
       
   347 //
       
   348 void CVedAVCEditImp::SaveAVCDecoderConfigurationRecordL(TDes8& aBuf, TBool aFromEncoder)
       
   349     {
       
   350 
       
   351     TUint8* buffer = (TUint8*)(aBuf.Ptr());
       
   352 
       
   353     TInt index = 5;     // Skip version and length information                        
       
   354     
       
   355     TInt numOfSPS = buffer[index] & 0x1f;
       
   356     index++;
       
   357     
       
   358     // Loop all SPS units
       
   359     for (TInt i = 0; i < numOfSPS; ++i)
       
   360         {
       
   361         TUint SPSSize = (buffer[index] << 8) + buffer[index + 1];
       
   362         index += 2;
       
   363         
       
   364         // feed NAL for saving to ParseParameterSet()        
       
   365         User::LeaveIfError( ParseParameterSet( (void*)&buffer[index], &SPSSize, aFromEncoder ) );
       
   366         index += SPSSize;                        
       
   367         
       
   368         }
       
   369         
       
   370     TInt numOfPPS = buffer[index];
       
   371     index++;
       
   372     
       
   373     // Loop all PPS units
       
   374     for (TInt i = 0; i < numOfPPS; ++i)
       
   375         {
       
   376         TUint PPSSize = (buffer[index] << 8) + buffer[index + 1];
       
   377         index += 2;
       
   378         
       
   379         // feed NAL for saving to ParseParameterSet()        
       
   380         User::LeaveIfError( ParseParameterSet( (void*)&buffer[index], &PPSSize, aFromEncoder ) );
       
   381         index += PPSSize;
       
   382         
       
   383         }
       
   384   
       
   385     }
       
   386 
       
   387 // ---------------------------------------------------------
       
   388 // CVedAVCEditImp::ConvertAVCHeader  
       
   389 // Convert AVC specific decoder config info to 
       
   390 // AVCDecoderConfigurationRecord -format
       
   391 // (other items were commented in a header).
       
   392 // ---------------------------------------------------------
       
   393 //				
       
   394 void CVedAVCEditImp::ConvertAVCHeaderL( TDesC8& aSrcBuf, TDes8& aDstBuf )
       
   395     {
       
   396     
       
   397 	TUint8* inputPtr = (TUint8*)(aSrcBuf.Ptr());
       
   398     TUint8* outputPtr = (TUint8*)(aDstBuf.Ptr());
       
   399     TUint8* spsPtr;
       
   400     TUint8* ppsPtr;
       
   401     
       
   402     TUint numSPS = 0;
       
   403     TUint numPPS = 0;
       
   404     
       
   405     TUint totalSPSLength = 0;
       
   406     TUint totalPPSLength = 0;
       
   407     
       
   408     TUint headerLength = aSrcBuf.Length();
       
   409     TUint endIndex = headerLength;
       
   410     
       
   411    	TInt nalType = 0;
       
   412    	TUint nalLength;
       
   413    	TUint nalIndex;
       
   414     TUint nalOffset;        
       
   415 
       
   416    	// Allocate memory for the temporary buffers
       
   417    	HBufC8* temp1 = (HBufC8*) HBufC8::NewLC(1000);
       
   418    	HBufC8* temp2 = (HBufC8*) HBufC8::NewLC(5000);
       
   419 
       
   420     spsPtr = const_cast<TUint8*>( temp1->Des().Ptr() );
       
   421     ppsPtr = const_cast<TUint8*>( temp2->Des().Ptr() );
       
   422 
       
   423     TUint numNalUnits = inputPtr[endIndex-4] + (inputPtr[endIndex-3]<<8) + (inputPtr[endIndex-2]<<16) + (inputPtr[endIndex-1]<<24);
       
   424 
       
   425 	// Move endIndex to point to the first NAL unit's offset information    
       
   426     endIndex = headerLength - numNalUnits*8 - 4;
       
   427     
       
   428 	nalIndex = 0;    
       
   429 	
       
   430 	TUint8* copyPtr = inputPtr;
       
   431 
       
   432 	while (nalIndex < numNalUnits)
       
   433         {
       
   434     	nalIndex++;
       
   435     	
       
   436     	TInt tmp1 = inputPtr[endIndex++];
       
   437         TInt tmp2 = inputPtr[endIndex++]<<8;
       
   438         TInt tmp3 = inputPtr[endIndex++]<<16;
       
   439         TInt tmp4 = inputPtr[endIndex++]<<24;    	    	
       
   440 
       
   441     	nalOffset = tmp1 + tmp2 + tmp3 + tmp4;
       
   442     	
       
   443     	tmp1 = inputPtr[endIndex++];
       
   444         tmp2 = inputPtr[endIndex++]<<8;
       
   445         tmp3 = inputPtr[endIndex++]<<16;
       
   446         tmp4 = inputPtr[endIndex++]<<24;
       
   447     	
       
   448     	nalLength = tmp1 + tmp2 + tmp3 + tmp4;    	
       
   449 
       
   450 	   	nalType = inputPtr[nalOffset] & 0x1F;
       
   451   			
       
   452 	   	if(nalType == 7)
       
   453 		    {
       
   454 	   		numSPS++;	   			   			   		
       
   455 
       
   456 		    // First store the SPS unit length with two bytes
       
   457    			spsPtr[totalSPSLength] = (nalLength >> 8) & 0xFF;
       
   458     		spsPtr[totalSPSLength+1] = nalLength & 0xFF;	    			    		    		    		
       
   459 			
       
   460 			// Copy the SPS unit to the buffer    
       
   461 			Mem::Copy(&spsPtr[totalSPSLength+2], copyPtr , nalLength);
       
   462 										
       
   463 			totalSPSLength += nalLength + 2;	// Two more for the size
       
   464 		    }
       
   465   		else if(nalType == 8)
       
   466    		    {
       
   467 			numPPS++;
       
   468 
       
   469 		    // First store the SPS unit length with two bytes
       
   470    			ppsPtr[totalPPSLength] = (nalLength >> 8) & 0xFF;
       
   471     		ppsPtr[totalPPSLength+1] = nalLength & 0xFF;
       
   472 	
       
   473 			// Copy the SPS unit to the buffer    
       
   474 			Mem::Copy(&ppsPtr[totalPPSLength+2], copyPtr , nalLength);
       
   475 	
       
   476 			totalPPSLength += nalLength + 2;	// Two more for the size
       
   477 	   	    }
       
   478 		else
       
   479    		    {
       
   480 			// [KW]: Check later if this is an error!!!
       
   481    		    }
       
   482    		
       
   483    		copyPtr += nalLength;
       
   484         }
       
   485     
       
   486 	// When the header has been parsed, form the AVCDecoderConfigurationRecord
       
   487 	outputPtr[0] = 0x01;	// configurationVersion 
       
   488 	outputPtr[1] = 0x42;	// Profile indicator
       
   489 	// Profile compatibility, i.e. all 4 constrain set flags + reserved 4 zero bits
       
   490 	outputPtr[2] = 0x80;	// Bitstream obeys all baseline constraints
       
   491 	if ( iOutputLevel == 101 )
       
   492 	{
       
   493 		// For level 1b, the 4th bit shall be == 1, otherwise it must be zero
       
   494 		outputPtr[2] |= 0x10;
       
   495 	} 
       
   496 	else
       
   497 	{
       
   498 	    outputPtr[2] &= 0xEF;   
       
   499 	}
       
   500 	
       
   501 	outputPtr[3] = (iOutputLevel == 101) ? 11 : iOutputLevel;  // level
       
   502 		
       
   503 	outputPtr[4] = 0x03;	// lengthSizeMinusOne		
       
   504     outputPtr[4] |= 0x0FC; // 6 reserved bits (all 1)	
       
   505 		
       
   506 	outputPtr[5] = numSPS;		
       
   507     outputPtr[5] |= 0xE0;  // 3 reserved bits (all 1)
       
   508 
       
   509 	TInt len = 6;
       
   510 	
       
   511 	// Copy the SPS unit(s) to the buffer    
       
   512 	Mem::Copy(&outputPtr[6], spsPtr , totalSPSLength);
       
   513 	
       
   514 	len += totalSPSLength;
       
   515 
       
   516 	outputPtr[6+totalSPSLength] = numPPS;
       
   517 	
       
   518 	len += 1;
       
   519 		
       
   520 	// Copy the PPS unit(s) to the buffer    
       
   521 	Mem::Copy(&outputPtr[6+totalSPSLength+1], ppsPtr , totalPPSLength);
       
   522 	
       
   523 	len += totalPPSLength;	
       
   524 	
       
   525 	aDstBuf.SetLength(len);
       
   526 	
       
   527 	CleanupStack::Pop(2);
       
   528 	
       
   529 	// Free the temporary buffers
       
   530 	delete temp1;
       
   531 	delete temp2;	
       
   532 }
       
   533 
       
   534 
       
   535 // ---------------------------------------------------------
       
   536 // CVedAVCEditImp::ParseOneNAL  
       
   537 // Saves one SPS/PPS NAL unit for later use
       
   538 // ---------------------------------------------------------
       
   539 //				
       
   540 TInt CVedAVCEditImp::ParseParameterSet(void *aNalUnitData, TUint* aNalUnitLength, TBool aFromEncoder)
       
   541     {
       
   542     	TInt retCode;
       
   543     	
       
   544 		// Pass the information about the frame origin to the decoder 
       
   545 		FrameIsFromEncoder(iAvcDecoder, aFromEncoder);
       
   546 		// Just call the decoder's parser function
       
   547 		retCode = avcdParseParameterSet(iAvcDecoder, aNalUnitData, aNalUnitLength);
       
   548 		
       
   549 		return retCode;
       
   550     }
       
   551 
       
   552 TInt CVedAVCEditImp::ParseOneNAL(void *aNalUnitData, TUint* aNalUnitLength, TBool aFromEncoder)
       
   553     {
       
   554     	TInt retCode;
       
   555     	
       
   556 		// Pass the information about the frame origin to the decoder 
       
   557 		FrameIsFromEncoder(iAvcDecoder, aFromEncoder);
       
   558 		// Just call the decoder's parser function
       
   559 		retCode = avcdParseOneNal(iAvcDecoder, aNalUnitData, aNalUnitLength);
       
   560 		
       
   561 		return retCode;
       
   562     }
       
   563 
       
   564 // ---------------------------------------------------------
       
   565 // CVedAVCEditImp::ParseFrame  
       
   566 // Update slice header information
       
   567 // ---------------------------------------------------------
       
   568 //				
       
   569 TInt CVedAVCEditImp::ParseFrame(HBufC8*& aBuf, TBool aContainsDCR, TBool aFromEncoder)
       
   570 {
       
   571     TUint nalSize;
       
   572     TUint nalOrigSize = 0;
       
   573 	TUint nalLengthSize = 0;
       
   574 //	TInt nalType;
       
   575 //	TInt nalRefIdc;
       
   576 	TInt skip = 0;
       
   577 	TUint bufferLength = aBuf->Length();
       
   578     TPtr8 bufferPtr(aBuf->Des());    
       
   579 	TUint8* srcPtr = (TUint8*)(bufferPtr.Ptr());
       
   580 	
       
   581 	TInt error;
       
   582 	HBufC8* temp1 = 0;
       
   583   	TRAP( error, temp1 = (HBufC8*) HBufC8::NewL(10) );
       
   584   	
       
   585   	if (error != KErrNone)
       
   586   	    return error;
       
   587   	  	  	
       
   588   	TPtr8 tempPtr(temp1->Des());
       
   589 //	TUint tmpLength1;
       
   590 //	TUint tmpLength2;
       
   591     TUint8* tempData1;	
       
   592 
       
   593   	tempPtr.Append(5);
       
   594 
       
   595 	// Jump over the AVC decoder information if it's included
       
   596     if(aContainsDCR)
       
   597     {
       
   598 		// skip 4 bytes for 
       
   599 		// configVersion, profile, profile compatibility and Level
       
   600 		skip += 4;
       
   601 	
       
   602 		// skip 1 byte for lengthSizeMinusOne
       
   603 		skip += 1;
       
   604 	
       
   605 		// skip 1 byte for number of sequence parameter sets
       
   606 		TInt numOfSSP = 0x1F & srcPtr[skip];
       
   607 		skip += 1;
       
   608 	
       
   609 		for (TInt i = 0; i < numOfSSP; i++)
       
   610 	    {
       
   611 	      	TInt sspSize = srcPtr[skip]*256 + srcPtr[skip+1];
       
   612    			skip += 2;
       
   613 	        skip += sspSize;
       
   614 	    }
       
   615 
       
   616 		TInt numOfPSP = srcPtr[skip];
       
   617 		skip += 1;
       
   618 
       
   619 		for (TInt i = 0; i < numOfPSP; i++)
       
   620 	    {
       
   621    			TInt pspSize = srcPtr[skip]*256 + srcPtr[skip+1];
       
   622 	       	skip += 2;
       
   623        		skip += pspSize;
       
   624 	    }
       
   625     }
       
   626 
       
   627  	while (skip < bufferLength)
       
   628  	{
       
   629  	   
       
   630  	    TInt retVal = 0; 			    
       
   631 
       
   632 		nalLengthSize = iNalLengthSize;
       
   633 		switch (nalLengthSize)
       
   634 		{
       
   635 			case 1:
       
   636 				nalOrigSize = nalSize = srcPtr[skip];
       
   637 				skip += 1;
       
   638 				break;
       
   639 			case 2:
       
   640 				nalOrigSize = nalSize = (srcPtr[skip] << 8)  + srcPtr[skip+1];
       
   641 				skip += 2;
       
   642 				break;
       
   643 			case 4:
       
   644 				nalOrigSize = nalSize = (srcPtr[skip] << 24) + (srcPtr[skip+1] << 16) + 
       
   645                           (srcPtr[skip+2] << 8) + srcPtr[skip+3];  
       
   646 				
       
   647 				skip += 4;
       
   648 				break;
       
   649 		}
       
   650 		
       
   651 //	   	nalType   = srcPtr[skip] & 0x1F;
       
   652 //		nalRefIdc = srcPtr[skip] & 0x60;	
       
   653 
       
   654 		// [KW]: Alloc memory here instead of sequence.cpp
       
   655 	  	tempData1 = (TUint8*) User::Alloc(nalOrigSize+100);   
       
   656 
       
   657 		if (tempData1 == 0)
       
   658 		{
       
   659 		    User::Free(temp1);
       
   660 			return KErrNoMemory;
       
   661 		}
       
   662 
       
   663 		Mem::Copy(tempData1, &srcPtr[skip], nalOrigSize*sizeof(TUint8));
       
   664 
       
   665 		Mem::FillZ(&tempData1[nalOrigSize], 100*sizeof(TUint8));
       
   666 
       
   667 		// Call ParseOneNaL function
       
   668 		retVal = ParseOneNAL(tempData1, &nalSize, aFromEncoder);
       
   669 		
       
   670 		if (retVal != KErrNone)
       
   671 		{
       
   672             User::Free(tempData1);
       
   673         	User::Free(temp1);
       
   674 		    return retVal;   
       
   675 		}
       
   676 		
       
   677 		// Copy data back to the srcPtr
       
   678 		Mem::Copy(&srcPtr[skip],tempData1,nalOrigSize*sizeof(TUint8));
       
   679 		
       
   680 //		tmpLength1 = aBuf->Length();
       
   681 		if(nalSize > nalOrigSize)
       
   682 		{
       
   683 			TUint diff = nalSize - nalOrigSize;
       
   684 		
       
   685 			for (TInt i=0; i<diff; i++)
       
   686 			{
       
   687 				tempPtr.Delete(0,1);
       
   688 				tempPtr.Append(tempData1[nalOrigSize+i]);
       
   689 //				tmpLength2 = tempPtr.Length();
       
   690 
       
   691 				// Insert byte(s) into the buffer
       
   692     			if((bufferPtr.Length() + 1) > bufferPtr.MaxLength()) 
       
   693     			{
       
   694         			// extend buffer size
       
   695 		        	TUint newSize = bufferPtr.Length() + 1;
       
   696 		        	
       
   697         			// round up to the next full kilobyte       
       
   698         			newSize = (newSize + 1023) & (~1023);
       
   699         			TRAP(error, (aBuf = aBuf->ReAllocL(newSize)) );
       
   700         
       
   701         			if (error != KErrNone)
       
   702         			{
       
   703         				User::Free(tempData1);
       
   704         				User::Free(temp1);
       
   705             			return error;
       
   706         			}
       
   707         
       
   708         			bufferPtr.Set(aBuf->Des());
       
   709     			}        
       
   710     			
       
   711 				bufferPtr.Insert(skip+nalOrigSize+i,tempPtr);
       
   712 //				tmpLength1 = aBuf->Length();
       
   713 			}
       
   714 			bufferLength += diff;
       
   715 		}
       
   716 		else if(nalSize < nalOrigSize)
       
   717 		{
       
   718 			TUint diff = nalOrigSize - nalSize;
       
   719 		
       
   720 			// Delete diff bytes from the buffer
       
   721 			bufferPtr.Delete(skip+nalOrigSize-diff,diff);
       
   722 			
       
   723 			bufferLength -= diff;
       
   724 		}
       
   725 		
       
   726 		// Update the NAL unit's size information in the buffer
       
   727         srcPtr[skip-4] = TUint8((nalSize >> 24) & 0xff);
       
   728         srcPtr[skip-3] = TUint8((nalSize >> 16) & 0xff);
       
   729         srcPtr[skip-2] = TUint8((nalSize >> 8) & 0xff);
       
   730         srcPtr[skip-1] = TUint8(nalSize & 0xff);
       
   731 
       
   732 		// Free the temporary data        
       
   733         User::Free(tempData1);
       
   734 		
       
   735 		skip += nalSize;
       
   736     }
       
   737     
       
   738     User::Free(temp1);
       
   739     
       
   740     return KErrNone;
       
   741 }
       
   742 
       
   743 // ---------------------------------------------------------
       
   744 // CVedAVCEditImp::ConstructAVCDecoderConfigurationRecordL   
       
   745 // Constructs AVCDecoderConfigurationRecord for output
       
   746 // ---------------------------------------------------------
       
   747 //				
       
   748 void CVedAVCEditImp::ConstructAVCDecoderConfigurationRecordL( TDes8& aDstBuf )
       
   749     {
       
   750     
       
   751     TUint8* outputPtr = (TUint8*)(aDstBuf.Ptr());
       
   752     TUint8* spsPtr;
       
   753     TUint8* ppsPtr;
       
   754     
       
   755     TUint numSPS = 0;
       
   756     TUint numPPS = 0;
       
   757     
       
   758     TUint totalSPSLength = 0;
       
   759     TUint totalPPSLength = 0;
       
   760     
       
   761     TInt i;
       
   762     TUint spsLength;
       
   763     TUint ppsLength;
       
   764 	TInt len = 6;
       
   765 	TUint8* copyPtr;
       
   766          
       
   767 
       
   768    	// Allocate memory for the temporary buffers
       
   769    	HBufC8* temp1 = (HBufC8*) HBufC8::NewLC(1000);
       
   770    	HBufC8* temp2 = (HBufC8*) HBufC8::NewLC(5000);
       
   771 
       
   772     spsPtr = const_cast<TUint8*>( temp1->Des().Ptr() );
       
   773     ppsPtr = const_cast<TUint8*>( temp2->Des().Ptr() );        
       
   774 
       
   775     numSPS = ReturnNumSPS(iAvcDecoder);
       
   776     numPPS = ReturnNumPPS(iAvcDecoder);
       
   777     
       
   778     for (i=0; i<numSPS; i++)
       
   779     {
       
   780     	copyPtr = ReturnSPSSet(iAvcDecoder,i,&spsLength);
       
   781 
       
   782 	    // First store the SPS unit length with two bytes
       
   783 		spsPtr[totalSPSLength] = (spsLength >> 8) & 0xFF;
       
   784   		spsPtr[totalSPSLength+1] = spsLength & 0xFF;
       
   785 
       
   786 		// Copy the SPS unit to the buffer    
       
   787 		Mem::Copy(&spsPtr[totalSPSLength+2], copyPtr , spsLength);
       
   788 		
       
   789 		totalSPSLength += spsLength + 2;	// Two more for the size
       
   790     }
       
   791     
       
   792     
       
   793     for (i=0; i<numPPS; i++)
       
   794     {
       
   795     	copyPtr = ReturnPPSSet(iAvcDecoder,i,&ppsLength);
       
   796 
       
   797 	    // First store the PPS unit length with two bytes
       
   798 		ppsPtr[totalPPSLength] = (ppsLength >> 8) & 0xFF;
       
   799   		ppsPtr[totalPPSLength+1] = ppsLength & 0xFF;
       
   800 
       
   801 		// Copy the PPS unit to the buffer    
       
   802 		Mem::Copy(&ppsPtr[totalPPSLength+2], copyPtr , ppsLength);
       
   803 
       
   804 		totalPPSLength += ppsLength + 2;	// Two more for the size
       
   805     }
       
   806     
       
   807     
       
   808     
       
   809 	// When the header has been parsed, form the AVCDecoderConfigurationRecord
       
   810 	outputPtr[0] = 0x01;	
       
   811 	outputPtr[1] = 0x42;	// Profile indicator, baseline profile
       
   812 	
       
   813 	// Profile compatibility, i.e. all 4 constrain set flags + reserved 4 zero bits
       
   814 	outputPtr[2] = 0x80;	// Bitstream obeys all baseline constraints
       
   815 	if ( iOutputLevel == 101 )
       
   816 	{
       
   817 		// For level 1b, the 4th bit shall be == 1, otherwise it must be zero
       
   818 		outputPtr[2] |= 0x10;		
       
   819 	} 
       
   820 	else
       
   821 	{
       
   822 	    outputPtr[2] &= 0xEF;
       
   823 	}
       
   824 	
       
   825 	outputPtr[3] = (iOutputLevel == 101) ? 11 : iOutputLevel;  // level
       
   826 	outputPtr[4] = 0x03;	// lengthSizeMinusOne		
       
   827 	outputPtr[5] = numSPS;		
       
   828 
       
   829 	
       
   830 	// Copy the SPS unit(s) to the buffer    
       
   831 	Mem::Copy(&outputPtr[6], spsPtr , totalSPSLength);
       
   832 	
       
   833 	len += totalSPSLength;
       
   834 
       
   835 	outputPtr[6+totalSPSLength] = numPPS;
       
   836 	
       
   837 	len += 1;
       
   838 		
       
   839 	// Copy the PPS unit(s) to the buffer    
       
   840 	Mem::Copy(&outputPtr[6+totalSPSLength+1], ppsPtr , totalPPSLength);
       
   841 	
       
   842 	len += totalPPSLength;	
       
   843 	
       
   844 	aDstBuf.SetLength(len);
       
   845 	
       
   846 	CleanupStack::Pop(2);
       
   847 	// Free the temporary buffers
       
   848 	delete temp1;
       
   849 	delete temp2;	
       
   850     }
       
   851     
       
   852 
       
   853 // ---------------------------------------------------------
       
   854 // CVedAVCEditImp::EncodeUntilIDR   
       
   855 // Returns whether frames have to be encoded until next IDR frame
       
   856 // ---------------------------------------------------------
       
   857 //	
       
   858 TBool CVedAVCEditImp::EncodeUntilIDR()
       
   859 {
       
   860     if (iAvcDecoder)
       
   861     {
       
   862 		return (ReturnEncodeUntilIDR(iAvcDecoder));
       
   863     }
       
   864     else
       
   865     {
       
   866     	return EFalse;
       
   867     }
       
   868 }
       
   869 
       
   870 
       
   871 // ---------------------------------------------------------
       
   872 // CVedAVCEditImp::IsNALUnitIDR   
       
   873 // Returns whether passed frame is an IDR frame
       
   874 // ---------------------------------------------------------
       
   875 //
       
   876 TBool CVedAVCEditImp::IsNALUnitIDR( TDes8& aNalBuf )
       
   877 {
       
   878     TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
       
   879 	
       
   880 	// skip 4 bytes of length information
       
   881 	if((bufferPtr[4] & 0x1F) == 5)
       
   882 		return ETrue;
       
   883 	else
       
   884 		return EFalse;
       
   885 }
       
   886 
       
   887 // ---------------------------------------------------------
       
   888 // CVedAVCEditImp::StoreCurrentPPSId
       
   889 // Stores the PPS id of passed frame for later use
       
   890 // ---------------------------------------------------------
       
   891 //
       
   892 void CVedAVCEditImp::StoreCurrentPPSId( TDes8& aNalBuf )
       
   893 {
       
   894     TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
       
   895     TUint bufferLength = aNalBuf.Length();
       
   896 
       
   897 	switch (iNalLengthSize)
       
   898 	{
       
   899 		case 1:
       
   900 			bufferLength = bufferPtr[0];
       
   901 			bufferPtr += 1;
       
   902 			break;
       
   903 		case 2:
       
   904 			bufferLength = (bufferPtr[0] << 8)  + bufferPtr[1];
       
   905 			bufferPtr += 2;
       
   906 			break;
       
   907 		case 4:
       
   908 			bufferLength = (bufferPtr[0] << 24) + (bufferPtr[1] << 16) + 
       
   909                          (bufferPtr[2] << 8) + bufferPtr[3];  
       
   910 			
       
   911 			bufferPtr += 4;
       
   912 			break;
       
   913 	}
       
   914 	avcdStoreCurrentPPSId(iAvcDecoder, bufferPtr, bufferLength);
       
   915 }
       
   916 
       
   917 // ---------------------------------------------------------
       
   918 // CVedAVCEditImp::GenerateNotCodedFrame
       
   919 // Generates a not coded (empty) frame
       
   920 // ---------------------------------------------------------
       
   921 //
       
   922 TInt CVedAVCEditImp::GenerateNotCodedFrame( TDes8& aNalBuf, TUint aFrameNumber )
       
   923 {
       
   924     TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
       
   925     TUint bufferLength = aNalBuf.Length();
       
   926     TInt frameLength = 0;
       
   927 	
       
   928   	frameLength = avcdGenerateNotCodedFrame(iAvcDecoder, bufferPtr, bufferLength, aFrameNumber);
       
   929 	
       
   930 	if(frameLength > 0)	
       
   931 	{
       
   932     	TInt i;
       
   933     
       
   934   		// Make room for iNalLengthSize bytes of length information to the start
       
   935   		for (i=frameLength-1; i>=0; i--)
       
   936   		{
       
   937   			bufferPtr[i+iNalLengthSize] = bufferPtr[i];
       
   938   		}
       
   939 
       
   940 		// Add the NAL size information to the buffer
       
   941 		switch (iNalLengthSize)
       
   942 		{
       
   943 			case 1:
       
   944     			bufferPtr[0] = TUint8(frameLength & 0xff);
       
   945     			frameLength++;
       
   946 				break;
       
   947 			case 2:
       
   948 		    	bufferPtr[0] = TUint8((frameLength >> 8) & 0xff);
       
   949     			bufferPtr[1] = TUint8(frameLength & 0xff);
       
   950     			frameLength += 2;
       
   951 				break;
       
   952 			case 4:
       
   953 		    	bufferPtr[0] = TUint8((frameLength >> 24) & 0xff);
       
   954     			bufferPtr[1] = TUint8((frameLength >> 16) & 0xff);
       
   955     			bufferPtr[2] = TUint8((frameLength >> 8) & 0xff);
       
   956     			bufferPtr[3] = TUint8(frameLength & 0xff);
       
   957     			frameLength += 4;
       
   958 				break;
       
   959 		}
       
   960 		
       
   961 	  	return frameLength;
       
   962 	}
       
   963 	else
       
   964 		return 0;
       
   965 }
       
   966 
       
   967 // ---------------------------------------------------------
       
   968 // CVedAVCEditImp::ModifyFrameNumber
       
   969 // Modifies the frame number of input NAL unit
       
   970 // ---------------------------------------------------------
       
   971 //
       
   972 void CVedAVCEditImp::ModifyFrameNumber( TDes8& aNalBuf, TUint aFrameNumber )
       
   973 {
       
   974     TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
       
   975     TUint bufferLength = aNalBuf.Length();
       
   976 
       
   977 	switch (iNalLengthSize)
       
   978 	{
       
   979 		case 1:
       
   980 			bufferLength = bufferPtr[0];
       
   981 			bufferPtr += 1;
       
   982 			break;
       
   983 		case 2:
       
   984 			bufferLength = (bufferPtr[0] << 8)  + bufferPtr[1];
       
   985 			bufferPtr += 2;
       
   986 			break;
       
   987 		case 4:
       
   988 			bufferLength = (bufferPtr[0] << 24) + (bufferPtr[1] << 16) + 
       
   989                          (bufferPtr[2] << 8) + bufferPtr[3];  
       
   990 			
       
   991 			bufferPtr += 4;
       
   992 			break;
       
   993 	}
       
   994 	
       
   995 	if (bufferPtr[0]==0x01 && bufferPtr[1]==0x42)
       
   996 		return;
       
   997 	
       
   998 	avcdModifyFrameNumber(iAvcDecoder, bufferPtr, bufferLength, aFrameNumber);
       
   999 }
       
  1000 
       
  1001 #endif
       
  1002 
       
  1003 // End of file   
       
  1004 
       
  1005