videoeditorengine/vedengine/videoprocessor/src/mp4composer.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 5 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 *
       
    17 */
       
    18 
       
    19 
       
    20 //FC Based on Cmp4parser
       
    21 
       
    22 
       
    23 // INCLUDE FILES
       
    24 #include <f32file.h>
       
    25 #include "mp4composer.h"
       
    26 #include "vedvideosettings.h"
       
    27 #include "vedavcedit.h"
       
    28 
       
    29 
       
    30 // ASSERTIONS
       
    31 //#define MPASSERT(x) __ASSERT_DEBUG(x, User::Panic(_L("CVideoProcessorImpl"), EInternalAssertionFailure))
       
    32 
       
    33 
       
    34 // MACROS
       
    35 //#define ?macro ?macro_def
       
    36 
       
    37 #ifdef _DEBUG
       
    38 #include <e32svr.h>
       
    39 #define PRINT(x) RDebug::Print x;
       
    40 #else
       
    41 #define PRINT(x)
       
    42 #endif
       
    43 
       
    44 // LOCAL CONSTANTS AND MACROS
       
    45 
       
    46 const TUint KFreeDiskSpaceCounter = 10;        // Interval when to find out real free disk space
       
    47 const TUint KMaxComposeBufferSize = 512000;    // : Adjust buffer size dynamically
       
    48 
       
    49 #ifdef _DEBUG
       
    50 const TInt KLeaveCode = CComposer::EComposerFailure;
       
    51 #else
       
    52 const TInt KLeaveCode = KErrGeneral;
       
    53 #endif
       
    54 
       
    55 // ============================= LOCAL FUNCTIONS ===============================
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // RateIndex: converts sample rate to rate index used in decoder config info
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 static TUint8 RateIndex(TInt aRate)
       
    62     {
       
    63     switch ( aRate )
       
    64         {
       
    65         case 96000:
       
    66             return 0x0;
       
    67         case 88200:
       
    68             return 0x1;
       
    69         case 64000:
       
    70             return 0x2;
       
    71         case 48000:
       
    72             return 0x3;
       
    73         case 44100:
       
    74             return 0x4;
       
    75         case 32000:
       
    76             return 0x5;
       
    77         case 24000:
       
    78             return 0x6;
       
    79         case 22050:
       
    80             return 0x7;
       
    81         case 16000:
       
    82             return 0x8;
       
    83         case 12000:
       
    84             return 0x9;
       
    85         case 11025:
       
    86             return 0xa;
       
    87         case 8000:
       
    88             return 0xb;
       
    89         case 7350:
       
    90             return 0xc;
       
    91         default:
       
    92             return 0xf;
       
    93         }
       
    94     }
       
    95 
       
    96 
       
    97 // ================= MEMBER FUNCTIONS =======================
       
    98 
       
    99 // C++ default constructor can NOT contain any code, that
       
   100 // might leave.
       
   101 //
       
   102 
       
   103 CMP4Composer::CMP4Composer()
       
   104 {
       
   105 	iMP4Handle = 0;	
       
   106     iFreeDiskSpace = 0;
       
   107     iFreeDiskSpaceCounter = 0;
       
   108 	iFirstWrite = ETrue;
       
   109     iFsOpened = EFalse;
       
   110 }
       
   111 
       
   112 // Two-phased constructor. 
       
   113 CMP4Composer* CMP4Composer::NewL(const TDesC &aFileName, 
       
   114                                  CParser::TVideoFormat aVideoFormat, 
       
   115                                  CParser::TAudioFormat aAudioFormat,
       
   116                                  CVedAVCEdit *aAvcEdit)
       
   117 {
       
   118 	CMP4Composer *self = new (ELeave) CMP4Composer;
       
   119 	CleanupStack::PushL(self);
       
   120 	self->ConstructL(aFileName, aVideoFormat, aAudioFormat, aAvcEdit);
       
   121 	CleanupStack::Pop();  // self 
       
   122 	return self;
       
   123 }
       
   124 
       
   125 CMP4Composer* CMP4Composer::NewL(RFile* aFileHandle, 
       
   126                                  CParser::TVideoFormat aVideoFormat, 
       
   127                                  CParser::TAudioFormat aAudioFormat,
       
   128                                  CVedAVCEdit *aAvcEdit)
       
   129 {
       
   130 	CMP4Composer *self = new (ELeave) CMP4Composer;
       
   131 	CleanupStack::PushL(self);
       
   132 	self->ConstructL(aFileHandle, aVideoFormat, aAudioFormat, aAvcEdit);
       
   133 	CleanupStack::Pop();  // self 
       
   134 	return self;
       
   135 }
       
   136 
       
   137 // Symbian OS default constructor can leave.
       
   138 void CMP4Composer::ConstructL(const TDesC &aFileName,
       
   139 							  CParser::TVideoFormat aVideoFormat, 
       
   140                               CParser::TAudioFormat aAudioFormat,
       
   141                               CVedAVCEdit *aAvcEdit)
       
   142 {
       
   143 	TUint mediaType = 0;	
       
   144 	
       
   145     iOutputMovieFileName = TFileName(aFileName);
       
   146     iFileHandle = NULL;
       
   147 
       
   148 	iAvcEdit = aAvcEdit;
       
   149 	
       
   150     // open MP4 library	
       
   151 	
       
   152     TBuf<258> temp(aFileName);
       
   153     temp.ZeroTerminate();        
       
   154         
       
   155     MP4FileName name = reinterpret_cast<MP4FileName>( const_cast<TUint16*>(temp.Ptr()) );
       
   156     
       
   157     SetMediaOptions(aVideoFormat, aAudioFormat, mediaType);
       
   158     
       
   159     MP4Err error;
       
   160     
       
   161     // if the filename length is greater 0, then compose to file else buffer
       
   162     if(aFileName.Length() > 0)   
       
   163     {
       
   164         error = MP4ComposeOpen(&iMP4Handle, name, mediaType);		
       
   165     }
       
   166     else
       
   167     {								
       
   168         // initialize to compose to buffer
       
   169         iComposeBuffer = (TUint8*)HBufC::NewL( KMaxComposeBufferSize );
       
   170         iComposedSize = KMaxComposeBufferSize;
       
   171         error = MP4ComposeOpenToBuffer(&iMP4Handle, mediaType,(mp4_u8*)iComposeBuffer,&iComposedSize);
       
   172     }
       
   173     
       
   174     if ( error != MP4_OK )
       
   175         User::Leave(KLeaveCode);
       
   176     
       
   177     SetComposerOptionsL(aVideoFormat, aAudioFormat);
       
   178     
       
   179 }
       
   180 
       
   181 void CMP4Composer::ConstructL(RFile* aFileHandle,
       
   182 							  CParser::TVideoFormat aVideoFormat, 
       
   183                               CParser::TAudioFormat aAudioFormat,
       
   184                               CVedAVCEdit *aAvcEdit)
       
   185 {
       
   186 	TUint mediaType = 0;	
       
   187 	
       
   188 	iOutputMovieFileName.Zero();
       
   189     iFileHandle = aFileHandle;
       
   190 
       
   191 	iAvcEdit = aAvcEdit;
       
   192 	    	        
       
   193     SetMediaOptions(aVideoFormat, aAudioFormat, mediaType);
       
   194     
       
   195     // open MP4 library	    
       
   196     MP4Err error;
       
   197 
       
   198     error = MP4ComposeOpenFileHandle(&iMP4Handle, aFileHandle, EDriveC, mediaType);
       
   199 
       
   200     if ( error != MP4_OK )
       
   201         User::Leave(KLeaveCode);
       
   202     
       
   203     SetComposerOptionsL(aVideoFormat, aAudioFormat);
       
   204     
       
   205 }
       
   206 
       
   207 
       
   208 void CMP4Composer::SetMediaOptions(CParser::TVideoFormat aVideoFormat, 
       
   209                                    CParser::TAudioFormat aAudioFormat,
       
   210                                    TUint& aMediaFlags)
       
   211                                  
       
   212 {
       
   213 
       
   214 	if ( (aVideoFormat == CParser::EVideoFormatH263Profile0Level10) ||  
       
   215 		 (aVideoFormat == CParser::EVideoFormatH263Profile0Level45) )
       
   216 	{
       
   217 		aMediaFlags = MP4_TYPE_H263_PROFILE_0;
       
   218 		iVideoType = MP4_TYPE_H263_PROFILE_0;    
       
   219 	}
       
   220 	
       
   221 #ifdef VIDEOEDITORENGINE_AVC_EDITING
       
   222 	else if (aVideoFormat == CParser::EVideoFormatAVCProfileBaseline)
       
   223 	{
       
   224 		aMediaFlags = MP4_TYPE_AVC_PROFILE_BASELINE;
       
   225 		iVideoType = MP4_TYPE_AVC_PROFILE_BASELINE;    
       
   226 	}
       
   227 #endif
       
   228 	else
       
   229 	{
       
   230 		aMediaFlags = MP4_TYPE_MPEG4_VIDEO;
       
   231 		iVideoType = MP4_TYPE_MPEG4_VIDEO;
       
   232 	}
       
   233 
       
   234     if ( aAudioFormat == CParser::EAudioFormatAMR )
       
   235 	{
       
   236 		aMediaFlags |= MP4_TYPE_AMR_NB;
       
   237 		iAudioType = MP4_TYPE_AMR_NB;
       
   238 	}
       
   239 
       
   240 	else if ( aAudioFormat == CParser::EAudioFormatAAC )
       
   241 	{
       
   242 		aMediaFlags |= MP4_TYPE_MPEG4_AUDIO;   // added for AAC support. 
       
   243 		iAudioType = MP4_TYPE_MPEG4_AUDIO;
       
   244 	}
       
   245 	
       
   246 }
       
   247 
       
   248 void CMP4Composer::SetComposerOptionsL(CParser::TVideoFormat aVideoFormat,
       
   249                                        CParser::TAudioFormat aAudioFormat)
       
   250 {
       
   251 
       
   252     MP4Err error;
       
   253 
       
   254     TBool videoMpeg4OrAvc = ( aVideoFormat == CParser::EVideoFormatMPEG4 ||
       
   255                               aVideoFormat == CParser::EVideoFormatAVCProfileBaseline );
       
   256 
       
   257     mp4_u32 flags = 0;
       
   258     flags |= MP4_FLAG_LARGEFILEBUFFER;  // Note: What does this do when using RFile ?
       
   259 	flags |= MP4_FLAG_METADATALAST;	
       
   260     
       
   261 	// generate MP4 file format if MPEG-4/AVC video & AAC audio
       
   262 	if ( (videoMpeg4OrAvc && aAudioFormat == CParser::EAudioFormatAAC) ||
       
   263 		 (videoMpeg4OrAvc && aAudioFormat == CParser::EAudioFormatNone) ||
       
   264 		 (aVideoFormat == CParser::EVideoFormatNone && aAudioFormat == CParser::EAudioFormatAAC) )
       
   265 	{
       
   266 		flags |= MP4_FLAG_GENERATE_MP4;
       
   267 	}
       
   268     	 
       
   269     error = MP4ComposeSetFlags(iMP4Handle, flags);
       
   270     
       
   271     if (error != MP4_OK)
       
   272     	if (error == MP4_OUT_OF_MEMORY)
       
   273     		{
       
   274 				User::LeaveNoMemory();
       
   275     		}
       
   276     	else
       
   277     		{
       
   278         User::Leave(KLeaveCode);
       
   279     		}
       
   280 
       
   281     // set buffer sizes; only composer buffer settings are effective for this instance
       
   282     error = MP4SetCustomFileBufferSizes(iMP4Handle, K3gpMp4ComposerWriteBufferSize, K3gpMp4ComposerNrOfWriteBuffers, K3gpMp4ParserReadBufferSize );
       
   283 
       
   284     if (error == MP4_OUT_OF_MEMORY)
       
   285     {
       
   286         User::Leave(KErrNoMemory);
       
   287     }
       
   288     else if ( error != MP4_OK )
       
   289     {
       
   290         User::Leave(KLeaveCode);
       
   291     }
       
   292 }
       
   293 
       
   294 
       
   295 // Destructor
       
   296 CMP4Composer::~CMP4Composer()
       
   297 {
       
   298     if (iMP4Handle)
       
   299     {
       
   300         MP4ComposeClose(iMP4Handle);
       
   301     }
       
   302 
       
   303 	if(iComposeBuffer)			// added for Buffer support
       
   304 	{
       
   305 		User::Free(iComposeBuffer);
       
   306 		iComposeBuffer=0;
       
   307 	}
       
   308 
       
   309     iMP4Handle = 0;
       
   310 
       
   311     if (iFsOpened) 
       
   312     {        
       
   313         iFS.Close();
       
   314         iFsOpened = EFalse;        
       
   315     }    
       
   316 	
       
   317 
       
   318 }
       
   319 
       
   320 // ---------------------------------------------------------
       
   321 // CMP4Composer::WriteFrames
       
   322 // Write the next frame(s) to file
       
   323 // ---------------------------------------------------------
       
   324 //
       
   325 TInt CMP4Composer::WriteFrames(TDesC8& aSrcBuffer, TInt aFrameSize,
       
   326 							   TInt aDuration, TInt aKeyFrame, 
       
   327 							   TInt aNumberOfFrames, TInt aFrameType)
       
   328 {
       
   329 	MP4Err error = KErrNone;
       
   330 	
       
   331 	// get the parameters 
       
   332 	TUint32	frameSize = aFrameSize;
       
   333 	TUint32	duration = aDuration;
       
   334 	mp4_bool keyframe = (mp4_bool)aKeyFrame; 
       
   335 	TInt numberOfFrames = aNumberOfFrames; 
       
   336 	TFrameType	frameType = (aFrameType>0 ? (aFrameType==1 ? EFrameTypeAudio : EFrameTypeVideo) 
       
   337         : EFrameTypeNone); 
       
   338     
       
   339     if (frameType == EFrameTypeVideo)
       
   340     {            
       
   341         error = MP4ComposeWriteVideoFrame(iMP4Handle, (mp4_u8*)(aSrcBuffer.Ptr()),
       
   342             frameSize, duration, keyframe);
       
   343         if ( error != MP4_OK )
       
   344             return KLeaveCode;		
       
   345     }
       
   346     
       
   347     else if (frameType == EFrameTypeAudio)
       
   348     {
       
   349         error = MP4ComposeWriteAudioFrames(iMP4Handle,(mp4_u8*)(aSrcBuffer.Ptr()),
       
   350             frameSize, numberOfFrames, duration);
       
   351         if ( error != MP4_OK )
       
   352             return KLeaveCode;		
       
   353     }
       
   354     else 
       
   355         User::Panic(_L("CMovieProcessorImpl"), EComposerFailure);
       
   356     
       
   357     return KErrNone;
       
   358 		
       
   359 }
       
   360 
       
   361 
       
   362 TInt CMP4Composer::WriteFrames(TDesC8& aSrcBuffer, TInt aFrameSize,
       
   363 							   TInt aDuration, TInt aKeyFrame, 
       
   364 							   TInt aNumberOfFrames, TInt aFrameType,
       
   365                                TInt& aMP4Size, TBool aModeChanged,
       
   366 							   TBool aFirstFrameOfClip, TInt aMode, TBool /*aFromEncoder*/)
       
   367 {
       
   368 	MP4Err error = KErrNone;
       
   369 	
       
   370 	// get the parameters 
       
   371 	TUint32	frameSize = aFrameSize;
       
   372 	TUint32	duration = aDuration;
       
   373 	mp4_bool keyframe = ( aKeyFrame ) ? ETrue : EFalse;
       
   374 	TInt numberOfFrames = aNumberOfFrames; 
       
   375 	TFrameType	frameType = (aFrameType > 0 ? (aFrameType == 1 ? EFrameTypeAudio : EFrameTypeVideo) 
       
   376 		: EFrameTypeNone); 
       
   377 	TUint8* dataPtr = (TUint8*)(aSrcBuffer.Ptr());
       
   378 	TInt tmpSize = 0;
       
   379 	
       
   380 	// call this only for the first frame of every clip 
       
   381 	if ( aFirstFrameOfClip && (iVideoType == MP4_TYPE_MPEG4_VIDEO) && (aMP4Size == 0)) 
       
   382 	{
       
   383 		if ((tmpSize = GetMp4SpecificSize(aSrcBuffer,aModeChanged,aMode)) != 0)
       
   384 			aMP4Size = tmpSize;	//This will be the new Mp4Size as it will be consider and since by reference it is maintained
       
   385 	}
       
   386 	
       
   387 	if (frameType == EFrameTypeVideo)
       
   388 	{            
       
   389 		if ( iVideoType == MP4_TYPE_MPEG4_VIDEO )
       
   390 		{
       
   391 			if ( iFirstWrite )
       
   392 			{
       
   393 				// VOS
       
   394 				error = MP4ComposeWriteVideoDecoderSpecificInfo( iMP4Handle,
       
   395 					(mp4_u8*)(dataPtr/*aSrcBuffer.Ptr()*/), aMP4Size );
       
   396 				iFirstWrite = EFalse;
       
   397 				
       
   398 				error = MP4ComposeWriteVideoFrame(iMP4Handle, (mp4_u8*)(dataPtr/*aSrcBuffer.Ptr()*/ + aMP4Size),
       
   399 					( frameSize - aMP4Size ), duration, keyframe);
       
   400 			}
       
   401 			else
       
   402 			{
       
   403 				// for MPEG4 - check the first 32 bits to make sure we don't 
       
   404 				// have VOS pre-pended to VOP data
       
   405 				if (dataPtr[0] == 0x00 && dataPtr[1] == 0x00 && dataPtr[2] == 0x01 && dataPtr[3] == 0xb0) 
       
   406 				{	// since intermediate Vos set to proper value
       
   407 					// Not Short Header may have User Data space problem with PSC
       
   408 					if ((tmpSize = GetMp4SpecificSize(aSrcBuffer,aModeChanged,aMode)) != 0)
       
   409 						aMP4Size = tmpSize;	//This will be the new Mp4Size as it will be considered		
       
   410 					dataPtr += aMP4Size;
       
   411 					frameSize -= aMP4Size;
       
   412 				}
       
   413 
       
   414                 if (frameSize == 0)
       
   415                     return KErrWrite;
       
   416 
       
   417 				error = MP4ComposeWriteVideoFrame(iMP4Handle, (mp4_u8*)(dataPtr),
       
   418 					frameSize, duration, keyframe);
       
   419 			}
       
   420 		} 
       
   421 		
       
   422 #ifdef VIDEOEDITORENGINE_AVC_EDITING
       
   423 		else if ( iVideoType == MP4_TYPE_AVC_PROFILE_BASELINE )
       
   424 		{
       
   425 		
       
   426 			if ( iFirstWrite || aFirstFrameOfClip)
       
   427 			{
       
   428 				if(iFirstWrite)
       
   429 				{				    
       
   430 					iFrameNumber = 0;
       
   431 					iFirstWrite = EFalse;
       
   432 				}
       
   433 				
       
   434 				aMP4Size = 0;
       
   435 				error = MP4ComposeWriteVideoFrame(iMP4Handle, (mp4_u8*)(dataPtr/*aSrcBuffer.Ptr()*/ + aMP4Size),
       
   436 					( frameSize - aMP4Size ), duration, keyframe);
       
   437 			}
       
   438 			else
       
   439 			{
       
   440 				error = MP4ComposeWriteVideoFrame(iMP4Handle, (mp4_u8*)(dataPtr),
       
   441 					frameSize, duration, keyframe);
       
   442 			}
       
   443 			
       
   444 			iFrameNumber++;
       
   445 		}
       
   446 #endif
       
   447 		
       
   448 		else // H.263
       
   449 		{
       
   450 			error = MP4ComposeWriteVideoFrame(iMP4Handle, (mp4_u8*)(dataPtr/*aSrcBuffer.Ptr()*/),
       
   451 				frameSize, duration, keyframe);
       
   452 				
       
   453 		}
       
   454 		if ( error != MP4_OK )
       
   455 			return KLeaveCode;		
       
   456 	}
       
   457 	else if (frameType == EFrameTypeAudio)
       
   458 	{
       
   459 		error = MP4ComposeWriteAudioFrames(iMP4Handle,(mp4_u8*)(dataPtr/*aSrcBuffer.Ptr()*/),
       
   460 			frameSize, numberOfFrames, duration);
       
   461 		if ( error != MP4_OK )
       
   462 			return KLeaveCode;          
       
   463 	}
       
   464 	else 
       
   465 		User::Panic(_L("CMovieProcessorImpl"), EComposerFailure);
       
   466 	
       
   467 	return KErrNone;
       
   468 }
       
   469 
       
   470 
       
   471 
       
   472 // ---------------------------------------------------------
       
   473 // CMP4Composer::ComposeHeaderL
       
   474 // Get relevant stream parameters by calling mp4 library functions
       
   475 // (other items were commented in a header).
       
   476 // ---------------------------------------------------------
       
   477 //
       
   478 
       
   479 
       
   480 void CMP4Composer::ComposeHeaderL(CComposer::TStreamParameters& aStreamParameters, TInt aOutputVideoTimeScale, 
       
   481                                   TInt aOutputAudioTimeScale, TInt aAudioFramesInSample)
       
   482 {
       
   483     MP4Err iError=KErrNone;	
       
   484 	
       
   485 	TInt width = aStreamParameters.iVideoWidth;
       
   486 	TInt height = aStreamParameters.iVideoHeight;
       
   487 	TInt avgbitrate = aStreamParameters.iStreamBitrate;
       
   488 	TInt maxbitrate = avgbitrate; 
       
   489 	TInt audioFramesPerSample = aAudioFramesInSample;//aStreamParameters.iAudioFramesInSample;       
       
   490 	TInt audioTimescale = aOutputAudioTimeScale;    
       
   491 	TInt modeSet=0x8180; 
       
   492 
       
   493 	if(iAudioType == MP4_TYPE_MPEG4_AUDIO)		// added for AAC support 
       
   494 	{	
       
   495 		// reset for AAC audio according to the code sent for AAC support.
       
   496 		audioFramesPerSample = 0;
       
   497 		modeSet = 0;
       
   498 	}
       
   499 
       
   500 	// set this to first clip's time scale 
       
   501 	TInt timescale = aOutputVideoTimeScale;
       
   502         
       
   503     iError = MP4ComposeAddAudioDescription(iMP4Handle,(mp4_u32)audioTimescale,
       
   504         (mp4_u8)audioFramesPerSample,(mp4_u16)modeSet); 
       
   505     if (iError != MP4_OK)
       
   506         User::Leave(KLeaveCode);
       
   507 		
       
   508     // write video description
       
   509     iError = MP4ComposeAddVideoDescription(iMP4Handle,(mp4_u32)timescale,
       
   510         (mp4_u16)width,(mp4_u16)height,(mp4_u32)maxbitrate,(mp4_u32)avgbitrate);
       
   511     
       
   512     if (iError != MP4_OK)
       
   513         User::Leave(KLeaveCode);
       
   514 
       
   515 	if ( aStreamParameters.iVideoFormat == EVideoFormatH263Profile0Level10 )
       
   516 	{
       
   517 		TVideoClipProperties prop;
       
   518 		prop.iH263Level = 10;
       
   519 		MP4ComposeSetVideoClipProperties(iMP4Handle, prop);
       
   520 	}
       
   521 
       
   522 	else if ( aStreamParameters.iVideoFormat == EVideoFormatH263Profile0Level45 )
       
   523 	{
       
   524 		TVideoClipProperties prop;
       
   525 		prop.iH263Level = 45;
       
   526 		MP4ComposeSetVideoClipProperties(iMP4Handle, prop);
       
   527 	}
       
   528 	
       
   529 	if (!iFsOpened) // Check if file server is open already
       
   530         {        
       
   531             User::LeaveIfError(iFS.Connect());        
       
   532             iFsOpened = ETrue;
       
   533         }
       
   534 
       
   535     if (iFileHandle == 0)
       
   536     {
       
   537         // get target drive number
       
   538         TParse fp;
       
   539         User::LeaveIfError(iFS.Parse(iOutputMovieFileName, fp));
       
   540         TPtrC driveletter = fp.Drive();
       
   541         TChar drl = driveletter[0];
       
   542         User::LeaveIfError(RFs::CharToDrive(drl, iDriveNumber));
       
   543     } 
       
   544     else
       
   545     {
       
   546         // get target drive number
       
   547         TDriveInfo info;
       
   548         TInt error = iFileHandle->Drive(iDriveNumber, info);
       
   549     }
       
   550 }
       
   551 
       
   552 // -----------------------------------------------------------------------------
       
   553 // CMP4Composer::DriveFreeSpaceL
       
   554 // Calculate free space on a drive in bytes.
       
   555 // (other items were commented in a header).
       
   556 // -----------------------------------------------------------------------------
       
   557 //
       
   558 TInt64 CMP4Composer::DriveFreeSpaceL()
       
   559 {
       
   560     TVolumeInfo volumeinfo;
       
   561 
       
   562     if (iFreeDiskSpaceCounter % KFreeDiskSpaceCounter == 0)
       
   563         {
       
   564         User::LeaveIfError(iFS.Volume(volumeinfo, iDriveNumber));
       
   565         iFreeDiskSpace = volumeinfo.iFree;
       
   566         }
       
   567 
       
   568     iFreeDiskSpaceCounter++;
       
   569     return iFreeDiskSpace;
       
   570 
       
   571 }
       
   572 
       
   573 // -----------------------------------------------------------------------------
       
   574 // CMP4Composer::GetComposedBuffer New Function added for Buffer support 
       
   575 // Gets the Composed buffer from the composer 
       
   576 // (other items were commented in a header).
       
   577 // -----------------------------------------------------------------------------
       
   578 //
       
   579 TUint8* CMP4Composer::GetComposedBuffer()
       
   580 {
       
   581 	return iComposeBuffer;
       
   582 }
       
   583 
       
   584 // -----------------------------------------------------------------------------
       
   585 // CMP4Composer::GetComposedBufferSize New Function added for Buffer support 
       
   586 // Gets the Composed buffer size from the composer 
       
   587 // (other items were commented in a header).
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 TUint CMP4Composer::GetComposedBufferSize()
       
   591 {
       
   592 	return iComposedSize;
       
   593 }
       
   594 
       
   595 // ---------------------------------------------------------
       
   596 // CMP4Composer::Close
       
   597 // Closes the composer instance & creates the output 3gp file 
       
   598 // (other items were commented in a header).
       
   599 // ---------------------------------------------------------
       
   600 //
       
   601 TInt CMP4Composer::Close()
       
   602 {
       
   603 
       
   604 #ifdef VIDEOEDITORENGINE_AVC_EDITING
       
   605 
       
   606     if (iVideoType == MP4_TYPE_AVC_PROFILE_BASELINE)
       
   607     {
       
   608         HBufC8* AVCDCR = NULL;
       
   609     	TInt error;
       
   610 
       
   611     	TRAP(error, AVCDCR = (HBufC8*) HBufC8::NewL(16384));
       
   612     	if (error != KErrNone)
       
   613     	    return error;
       
   614 
       
   615         TPtr8 ptr = AVCDCR->Des();    
       
   616         
       
   617         // Construct AVC Decoder Configuration Record from the SPS / PPS sets
       
   618         TRAP(error, iAvcEdit->ConstructAVCDecoderConfigurationRecordL(ptr));
       
   619         if (error != KErrNone)
       
   620         {
       
   621             delete AVCDCR;        
       
   622     	    return error;
       
   623         }                       
       
   624 
       
   625     	// Pass the AVC Decoder Configuration Record to the 3GPMP4 library
       
   626     	MP4Err mp4Error = MP4ComposeWriteVideoDecoderSpecificInfo( iMP4Handle,
       
   627     											    (mp4_u8*)(ptr.Ptr()), ptr.Length());    	    	
       
   628 
       
   629         delete AVCDCR;
       
   630         
       
   631         if (mp4Error != MP4_OK)
       
   632             return EComposerFailure;
       
   633     }
       
   634     
       
   635 #endif
       
   636 
       
   637     MP4Err error = MP4ComposeClose(iMP4Handle);
       
   638 
       
   639     iMP4Handle = 0;
       
   640 
       
   641     if (error != MP4_OK)
       
   642         return EComposerFailure;
       
   643 
       
   644     if (iFsOpened) 
       
   645     {        
       
   646         iFS.Close();
       
   647         iFsOpened = EFalse;        
       
   648     }
       
   649     
       
   650     return KErrNone;
       
   651 }
       
   652 
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // CMP4Composer::GetMp4SpecificSize
       
   656 // Gets the length of MPEG-4 decoder specific info in aSrcBuf
       
   657 // (other items were commented in a header).
       
   658 // -----------------------------------------------------------------------------
       
   659 //
       
   660 TInt CMP4Composer::GetMp4SpecificSize(TDesC8& aSrcBuf,TBool aModeChange,TInt aStreamMode)
       
   661 {
       
   662 	TUint8* dtPtr = (TUint8*)(aSrcBuf.Ptr());
       
   663 	TInt mp4size =0;
       
   664 	TInt bufSize;
       
   665 	TInt flag;
       
   666 
       
   667 	if (!aModeChange && (aStreamMode == 2)) //2 indicates short header in VedCommon
       
   668 	{
       
   669 		bufSize = aSrcBuf.Size()-3;
       
   670 		for(TInt i=0;i<bufSize;i++)
       
   671 		{
       
   672 			flag = (dtPtr[i+2]>>2)<<2;
       
   673 			if (dtPtr[i] == 0x00 && dtPtr[i+1] == 0x00 && flag == 0x80)	// user data ????????????
       
   674 			{
       
   675 				mp4size=i;
       
   676 				break;
       
   677 			}
       
   678 		}
       
   679 	}
       
   680 	else
       
   681 	{
       
   682 		bufSize = aSrcBuf.Size()-4;
       
   683 		for(TInt i=0;i<bufSize;i++)
       
   684 		{
       
   685 			if ((dtPtr[i] == 0x00 && dtPtr[i+1] == 0x00 && dtPtr[i+2] == 0x01 && dtPtr[i+3] == 0xb3) ||
       
   686 				(dtPtr[i] == 0x00 && dtPtr[i+1] == 0x00 && dtPtr[i+2] == 0x01 && dtPtr[i+3] == 0xb6))
       
   687 			{
       
   688 				mp4size=i;
       
   689 				break;
       
   690 			}
       
   691 		}
       
   692 	}
       
   693 
       
   694 	// MP4 specific size will be zero, if there is a GOV or VOP header in the
       
   695 	// very beginning of the buffer	
       
   696 	
       
   697 	return mp4size;
       
   698 }
       
   699 
       
   700 
       
   701 // ---------------------------------------------------------
       
   702 // CMP4Composer::WriteAudioSpecificInfo
       
   703 // Writes the Audio decoder Specific info required in case of AAC
       
   704 // Decoder specific info is provided externally
       
   705 // (other items were commented in a header).
       
   706 // decoder info is provided externally
       
   707 // ---------------------------------------------------------
       
   708 //
       
   709 // added to Support AAC audio files	
       
   710 TInt CMP4Composer::WriteAudioSpecificInfo(HBufC8*& aSrcBuf)
       
   711 {
       
   712 	TInt error = KErrNone;
       
   713 	mp4_u8* aSrcB = const_cast<mp4_u8*>(aSrcBuf->Ptr());
       
   714 	error = MP4ComposeWriteAudioDecoderSpecificInfo(iMP4Handle, aSrcB, aSrcBuf->Size());
       
   715 	
       
   716 	if (error != MP4_OK)
       
   717 		return KErrGeneral;
       
   718 
       
   719 	return KErrNone;
       
   720 }
       
   721 
       
   722 // ---------------------------------------------------------
       
   723 // CMP4Composer::WriteAudioSpecificInfo
       
   724 // Writes the Audio decoder Specific info required in case of AAC
       
   725 // Decoder specific info is derived from samplerate and # of channels
       
   726 // (other items were commented in a header).
       
   727 // ---------------------------------------------------------
       
   728 //
       
   729 // added to Support AAC audio files	
       
   730 TInt CMP4Composer::WriteAudioSpecificInfo(TInt aSampleRate, TInt aNumChannels)
       
   731 {
       
   732 	TInt error = KErrNone;
       
   733 	
       
   734     TUint8 data[2];
       
   735 
       
   736     data[0] = 2<<3; // AAC-LC
       
   737     TUint8 rate = RateIndex(aSampleRate);
       
   738     data[0] |= rate>>1;
       
   739     data[1] = TUint8(rate<<7);
       
   740     data[1] |= TUint8(aNumChannels<<3);
       
   741 
       
   742     error = MP4ComposeWriteAudioDecoderSpecificInfo(iMP4Handle, data, 2);
       
   743 	
       
   744 	if (error != MP4_OK)
       
   745 		return KErrGeneral;
       
   746 
       
   747 	return KErrNone;
       
   748 }
       
   749 
       
   750 
       
   751 // -----------------------------------------------------------------------------
       
   752 // CMP4Composer::GetAVCDecoderSpecificInfoSize
       
   753 // Gets the length of AVC decoder specific info in aSrcBuf
       
   754 // (other items were commented in a header).
       
   755 // -----------------------------------------------------------------------------
       
   756 //
       
   757 TInt CMP4Composer::GetAVCDecoderSpecificInfoSize(TDesC8& aSrcBuf)
       
   758 {
       
   759 	TUint8* srcPtr = (TUint8*)(aSrcBuf.Ptr());
       
   760 	TInt skip = 0;
       
   761 //	TInt error = KErrNone;
       
   762 
       
   763 	// skip 4 bytes for 
       
   764 	// configVersion, profile, profile compatibility and Level
       
   765 	skip += 4;
       
   766 	
       
   767 	// skip 1 bytes for lengthSizeMinusOne
       
   768 	skip += 1;
       
   769 	
       
   770 	// skip 1 bytes for num of seq Param sets
       
   771 	TInt numOfSSP = 0x1F & srcPtr[skip];
       
   772 	skip += 1;
       
   773 	
       
   774 	for (TInt i = 0; i < numOfSSP; i++)
       
   775     {
       
   776       	TInt sspSize = srcPtr[skip]*256 + srcPtr[skip+1];      	
       
   777        	skip += 2;
       
   778         skip += sspSize;
       
   779     }
       
   780 
       
   781 	TInt numOfPSP = srcPtr[skip];
       
   782 	skip += 1;
       
   783 
       
   784 	for (TInt i = 0; i < numOfPSP; i++)
       
   785     {
       
   786       	TInt pspSize = srcPtr[skip]*256 + srcPtr[skip+1];      	
       
   787        	skip += 2;
       
   788         skip += pspSize;
       
   789     }
       
   790 
       
   791 	return skip;
       
   792 }
       
   793 
       
   794 
       
   795 
       
   796 // End of File