mmserv/thumbnailengine/TneAPISrc/HXTNEVideoClipInfoImp.cpp
changeset 0 71ca22bcf22a
child 43 9894ed580e4a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     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:   TNE Video Clip Implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "HXTNEVideoClipInfoImp.h"
       
    22 #include <e32base.h>
       
    23 
       
    24 
       
    25 #include <fbs.h>
       
    26 #include <coemain.h>
       
    27 #include <ecom/ecom.h>
       
    28 
       
    29 
       
    30 #include "yuv2rgb12.h"
       
    31 #include "yuv2rgb16.h"
       
    32 #include "yuv2rgb24.h"
       
    33 
       
    34 #include <flogger.h>
       
    35 
       
    36 // PRINT macro
       
    37 #ifdef _DEBUG
       
    38 #include <e32svr.h>
       
    39 #define PRINT(x) RDebug::Print x
       
    40 #else
       
    41 #define PRINT(x)
       
    42 #endif
       
    43 
       
    44 #ifdef _DEBUG
       
    45 #define ENABLE_S60_TNE_LOGGING 1
       
    46 #endif
       
    47 
       
    48 //implementation
       
    49 #ifdef ENABLE_S60_TNE_LOGGING
       
    50 #define FLOG FileLog
       
    51 inline static void FileLog(TRefByValue<const TDesC16> aFmt,...)
       
    52 {
       
    53     VA_LIST  args;
       
    54     VA_START (args, aFmt);
       
    55     RFileLogger::WriteFormat(_L("tne"), _L("S60tne.log"), 
       
    56                         EFileLoggingModeAppend, aFmt, args);
       
    57 }
       
    58 
       
    59 #else // logging is disabled
       
    60 #define FLOG LogFNull
       
    61 inline static void LogFNull(TRefByValue<const TDesC16> aFmt,...){}
       
    62 
       
    63 #endif // enable logging
       
    64 
       
    65 //server details
       
    66 const TUint kDefaultMessageSlots=4;
       
    67 
       
    68 
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CTNEVideoClipInfo::NewL
       
    72 // API exposed by TNE to 
       
    73 // TNEVideoClipInfo using RFile handle
       
    74 // -----------------------------------------------------------------------------
       
    75 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewL(const RFile& aFileHandle,
       
    76                                                     MTNEVideoClipInfoObserver& aObserver)
       
    77 {
       
    78     FLOG(_L("CTNEVideoClipInfo::NewL"));
       
    79 
       
    80      CHXTNEVideoClipInfoImp* self = ( CHXTNEVideoClipInfoImp*)NewLC(aFileHandle, aObserver);
       
    81 
       
    82 
       
    83     FLOG(_L("CTNEVideoClipInfo::NewL out"));
       
    84     return self;
       
    85 }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CTNEVideoClipInfo::NewL
       
    89 // API exposed by TNE to create TNEVideoClipInfo using file name
       
    90 // -----------------------------------------------------------------------------
       
    91 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewL(const TDesC& aFileName,
       
    92                                                     MTNEVideoClipInfoObserver& aObserver)
       
    93 {
       
    94     FLOG(_L("CTNEVideoClipInfo::NewL"));
       
    95 
       
    96      CHXTNEVideoClipInfoImp* self = ( CHXTNEVideoClipInfoImp*)NewLC(aFileName, aObserver);
       
    97 
       
    98 
       
    99     FLOG(_L("CTNEVideoClipInfo::NewL out"));
       
   100     return self;
       
   101 }
       
   102 
       
   103 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewLC(const RFile& aFileHandle,
       
   104                                                      MTNEVideoClipInfoObserver& aObserver)
       
   105 {
       
   106      	
       
   107     CHXTNEVideoClipInfoImp* self = new (ELeave)  CHXTNEVideoClipInfoImp();
       
   108     CleanupStack::PushL(self);
       
   109     self->ConstructL(aFileHandle, aObserver);   
       
   110     CleanupStack::Pop();
       
   111     return self;
       
   112 }
       
   113 
       
   114     
       
   115 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewLC(const TDesC& aFileName,
       
   116                                                      MTNEVideoClipInfoObserver& aObserver)
       
   117 {
       
   118     
       
   119      CHXTNEVideoClipInfoImp* self = new (ELeave)  CHXTNEVideoClipInfoImp();
       
   120     CleanupStack::PushL(self);
       
   121     self->ConstructL(aFileName, aObserver);   
       
   122      CleanupStack::Pop();
       
   123     return self;
       
   124 }
       
   125 
       
   126 
       
   127 
       
   128 
       
   129 CTNEVideoClipInfo*  CHXTNEVideoClipInfoImp::NewL(const RFile& aFileHandle, 
       
   130                                               MTNEVideoClipInfoObserver& aObserver)
       
   131 {
       
   132      CHXTNEVideoClipInfoImp* self = new (ELeave)  CHXTNEVideoClipInfoImp();
       
   133     CleanupStack::PushL(self);
       
   134     self->ConstructL(aFileHandle, aObserver);
       
   135     CleanupStack::Pop(self);
       
   136     return self;
       
   137 }
       
   138 
       
   139 //constructor
       
   140 
       
   141  CHXTNEVideoClipInfoImp::CHXTNEVideoClipInfoImp()
       
   142  {
       
   143  	//empty constructor
       
   144  
       
   145  }
       
   146 
       
   147 
       
   148 //destructor
       
   149 
       
   150 
       
   151  CHXTNEVideoClipInfoImp::~CHXTNEVideoClipInfoImp()
       
   152 {
       
   153     FLOG(_L("CTNEVideoClipInfo::~ CHXTNEVideoClipInfoImp in"));
       
   154     
       
   155         
       
   156     
       
   157     RSessionBase::Close();
       
   158     iServerThread.Close(); 
       
   159    
       
   160     if (iServerName)
       
   161    {
       
   162     	delete iServerName;
       
   163     	iServerName = NULL;
       
   164     }
       
   165     if (iObserver)
       
   166     {
       
   167         delete iObserver;
       
   168         iObserver = NULL;
       
   169     }
       
   170     
       
   171     if (iCloseHandle)
       
   172     {    	
       
   173         iCloseHandle = EFalse;
       
   174     	iFileHandle.Close();	
       
   175     }
       
   176         		           		    
       
   177     if (iOutBitmap)
       
   178     {
       
   179         delete iOutBitmap;
       
   180         iOutBitmap = 0;
       
   181     }
       
   182             
       
   183     
       
   184     if(iFs)
       
   185     {
       
   186 	    iFs->Close();
       
   187 	    delete iFs;
       
   188 	    iFs = NULL;
       
   189     }
       
   190     
       
   191     if (iEnhancer)
       
   192     {
       
   193         delete iEnhancer;
       
   194         iEnhancer = NULL;
       
   195     }
       
   196     
       
   197     FLOG(_L("CTNEVideoClipInfo::~ CHXTNEVideoClipInfoImp out"));    
       
   198 }
       
   199 
       
   200 void  CHXTNEVideoClipInfoImp::ConstructL(const RFile& aFileHandle,
       
   201                                       MTNEVideoClipInfoObserver& aObserver)
       
   202 {
       
   203     FLOG(_L("CTNEVideoClipInfo::ConstructL in this=%x"), this);
       
   204     iObserver = CTNEClientObserver::NewL(this);
       
   205 	iClipInfoObserver = &aObserver;
       
   206 
       
   207 		
       
   208 	User::LeaveIfError(CreateServer());
       
   209 	iFileHandle.Duplicate(aFileHandle);
       
   210 	iCloseHandle = ETrue;
       
   211 	User::LeaveIfError(OpenFile(iFileHandle, 0));
       
   212     
       
   213     FLOG(_L("CTNEVideoClipInfo::ConstructL out this=%x"), this);
       
   214     
       
   215  }
       
   216 
       
   217 void  CHXTNEVideoClipInfoImp::ConstructL(const TDesC& aFileName,
       
   218                                       MTNEVideoClipInfoObserver& aObserver)
       
   219 {
       
   220     FLOG(_L("CTNEVideoClipInfo::ConstructL in this=%x"), this);
       
   221     iObserver = CTNEClientObserver::NewL(this);
       
   222    	iClipInfoObserver = &aObserver;
       
   223    	iFileName.Copy(aFileName);
       
   224    
       
   225     User::LeaveIfError(CreateServer());
       
   226 	
       
   227     User::LeaveIfError(OpenFile(0));
       
   228    
       
   229     
       
   230     FLOG(_L("CTNEVideoClipInfo::ConstructL out this=%x"), this);
       
   231 }
       
   232 
       
   233 TInt  CHXTNEVideoClipInfoImp::CreateServer()
       
   234 {
       
   235 	TInt err = KErrNoMemory;	
       
   236 	FLOG(_L("CHXTNEVideoClipInfoImp::CreateServer in"));    
       
   237 	 TRAP(err,iServerName = HBufC::NewL(KMaxFileName));
       
   238 	
       
   239 	if (iServerName && err == KErrNone)
       
   240 	{ 
       
   241 		 TPtr ptr = iServerName->Des();
       
   242     ptr.Copy(KTneServerName);
       
   243     ptr.AppendNum(Math::Random(), EHex);
       
   244 	
       
   245 		err = StartThread(iServerThread, iServerName);
       
   246 	}		
       
   247 	
       
   248     if ( err == KErrNone)
       
   249     {
       
   250        //server name FIXME
       
   251        err = CreateSession(*iServerName, Version(), kDefaultMessageSlots);
       
   252     }
       
   253                      
       
   254     FLOG(_L("CHXTNEVideoClipInfoImp::CreateServer out err=%d"), err);   
       
   255     return(err); 
       
   256   
       
   257 }
       
   258 
       
   259 TVersion CHXTNEVideoClipInfoImp::Version(void) const
       
   260     {
       
   261     return(TVersion(KTNEServMajorVersionNumber,KTNEServMinorVersionNumber,KTNEServBuildVersionNumber));
       
   262     }
       
   263 
       
   264 
       
   265 //SendRecieve() commands to server
       
   266 
       
   267 TInt CHXTNEVideoClipInfoImp::OpenFile(const RFile& aFileHandle, TInt aPosition)
       
   268 
       
   269 {
       
   270    FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile in"));
       
   271    c_State = EStartGettingMetadata;
       
   272    iObserver->Activate();
       
   273    SendReceive(EOpenFileRFmsg,TIpcArgs(&aFileHandle,aPosition), iObserver->iStatus);    
       
   274    FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile out"));
       
   275    return KErrNone;
       
   276  }
       
   277 
       
   278 TInt CHXTNEVideoClipInfoImp::OpenFile(TInt aPosition)
       
   279 
       
   280 {
       
   281    FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile in"));
       
   282    c_State = EStartGettingMetadata;
       
   283    iObserver->Activate();
       
   284    SendReceive(EOpenFIleNamemsg,TIpcArgs(&iFileName,aPosition), iObserver->iStatus);    
       
   285    FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile out"));
       
   286    return KErrNone;
       
   287  }
       
   288 
       
   289 void CHXTNEVideoClipInfoImp::GetThumbL(MTNEVideoClipThumbObserver& aObserver, 
       
   290                                      TInt aIndex,
       
   291                                      TSize* const aResolution,
       
   292                                      TDisplayMode aDisplayMode,
       
   293                                      TBool aEnhance,
       
   294                                      TInt aPriority)
       
   295                                      
       
   296 {
       
   297         FLOG(_L("CHXTNEVideoClipInfoImp::GetThumbL in"));
       
   298         
       
   299         iThumbObserver               = &aObserver;
       
   300         iThumbIndex                    = aIndex;
       
   301         iThumbEnhance               = aEnhance;	
       
   302         iThumbDisplayMode         = aDisplayMode; 
       
   303         iPriority                            = aPriority;                
       
   304         iThumbRequestData.iIndex =  aIndex;
       
   305         
       
   306         if (aResolution)
       
   307         {    	    
       
   308             iOutputThumbResolution = *aResolution;
       
   309         }
       
   310         else
       
   311         {    	                            	
       
   312             iOutputThumbResolution.iHeight = iMetaData.iHeight;
       
   313             iOutputThumbResolution.iWidth = iMetaData.iWidth;         
       
   314         }
       
   315         
       
   316         iThumbRequestData.iYUVBuffer = NULL;                
       
   317         c_State = EStartGettingThumbNail;
       
   318         iObserver->Activate();
       
   319         SendReceive(EGetThumbmsg, TIpcArgs(&iThumbRequestData), iObserver->iStatus);    
       
   320         FLOG(_L("CHXTNEVideoClipInfoImp::GetThumbL out"));
       
   321  }
       
   322   
       
   323 
       
   324 void CHXTNEVideoClipInfoImp::CancelThumb()
       
   325 {
       
   326     FLOG(_L("CHXTNEVideoClipInfoImp::CancelThumb in"));
       
   327     c_State = ECancelling;
       
   328     SendReceive(ECancelThumbmsg);    
       
   329     FLOG(_L("CHXTNEVideoClipInfoImp::CancelThumb out"));
       
   330 }
       
   331   
       
   332   TPtrC CHXTNEVideoClipInfoImp::FileName() const
       
   333 {
       
   334     TFileName fileName;
       
   335 	if (iCloseHandle)
       
   336 	{
       
   337 		iFileHandle.FullName(fileName);
       
   338 	}
       
   339 
       
   340     return fileName;
       
   341 }
       
   342 
       
   343 TInt CHXTNEVideoClipInfoImp::VideoFrameCount() const
       
   344 {
       
   345 	return (TInt)iMetaData.iFrameCount ;
       
   346 
       
   347 }
       
   348   
       
   349 
       
   350 // Called from Observer after a Complete() from Server
       
   351 
       
   352 void  CHXTNEVideoClipInfoImp::ServiceCompleted(TInt aError)
       
   353 {
       
   354 	FLOG(_L("CHXTNEVideoClipInfoImp::ServiceCompleted in aError=%d c_State=%d"),
       
   355 	            aError, c_State);
       
   356     switch(c_State)
       
   357     {
       
   358         case EStartGettingMetadata:			                        
       
   359             FetchAndSendMetaData(aError);            
       
   360             break;
       
   361         case EStartGettingThumbNail:
       
   362             if (aError == KErrNone)
       
   363             {
       
   364                 GenerateThumbNail();
       
   365             }
       
   366             else
       
   367             {
       
   368                 if (iOutBitmap)
       
   369                 {
       
   370                     delete iOutBitmap;
       
   371                     iOutBitmap = NULL;
       
   372                 }
       
   373                 m_LastError = aError;
       
   374             }
       
   375             
       
   376 			NotifyIfGetThumbPending(m_LastError, iOutBitmap);
       
   377 			break;
       
   378 		case ECancelling:
       
   379         default:
       
   380             break;
       
   381     }
       
   382     
       
   383     FLOG(_L("CHXTNEVideoClipInfoImp::ServiceCompleted out"));
       
   384     
       
   385 }
       
   386 
       
   387 void CHXTNEVideoClipInfoImp::FetchAndSendMetaData(TInt aError)
       
   388 {
       
   389     FLOG(_L("CHXTNEVideoClipInfoImp::FetchAndSendMetaData in"));
       
   390     if (aError == KErrNone)
       
   391     {
       
   392         aError = SendReceive(EGetMetaDatamsg, TIpcArgs(&iMetaData));
       
   393     }
       
   394     if(c_State== EStartGettingMetadata)
       
   395     {
       
   396     CTNEVideoClipInfo *pInfo = (CTNEVideoClipInfo *) this;
       
   397     iClipInfoObserver->NotifyVideoClipInfoReady(*pInfo, aError);  
       
   398     }
       
   399     FLOG(_L("CHXTNEVideoClipInfoImp::FetchAndSendMetaData out and state = %d"), c_State);
       
   400 
       
   401 }
       
   402 
       
   403 // ownership of pBitMap will be passed to Observer
       
   404 void CHXTNEVideoClipInfoImp::NotifyIfGetThumbPending(TInt aError, CFbsBitmap *&pBitMap) 
       
   405 {
       
   406     FLOG(_L("CHXTNEVideoClipInfoImp::NotifyIfGetThumbPending in"));
       
   407 	if (iThumbObserver)
       
   408 	{				
       
   409         CFbsBitmap* pTmpBitmap = pBitMap;
       
   410         pBitMap = NULL;
       
   411 		iThumbObserver->NotifyVideoClipThumbCompleted(*this, aError, pTmpBitmap);
       
   412 	}
       
   413 	FLOG(_L("CHXTNEVideoClipInfoImp::NotifyIfGetThumbPending out"));
       
   414 }
       
   415 
       
   416 void CHXTNEVideoClipInfoImp::GenerateThumbNail()
       
   417 {
       
   418 	FLOG(_L("CHXTNEVideoClipInfoImp::GenerateThumbNail in"));
       
   419     TInt bytesPerPixel = 0;           
       
   420     TInt error = KErrNone;
       
   421     
       
   422     if ( !iRgbBuf )
       
   423     {
       
   424         TSize inputFrameResolution(iMetaData.iWidth,iMetaData.iHeight);
       
   425                        
       
   426         // rgb specs
       
   427         TUint thumbLength = iMetaData.iWidth * iMetaData.iHeight; 
       
   428         TUint thumbUVLength = thumbLength>>2;	
       
   429         
       
   430        // VPASSERT(iYuvBuf);
       
   431         // assign yuv pointers 
       
   432         TUint8* yBuf = iThumbRequestData.iYUVBuffer;
       
   433         TUint8* uBuf = yBuf + thumbLength;
       
   434         TUint8* vBuf = uBuf + thumbUVLength;	
       
   435       
       
   436   	   // convert to no enhabnce if 64K is selected as thumb display mode
       
   437   	 	if(iThumbDisplayMode == EColor64K)
       
   438   	    iThumbEnhance = EFalse;
       
   439   	   
       
   440         // check validity of thumbnail and associated operation
       
   441         if(iThumbEnhance)		// for saving to file
       
   442         {			
       
   443                 iThumbDisplayMode = EColor16M;				// 24-bit color image for enhancement
       
   444           
       
   445             // no enhancements if clip is too small.
       
   446             if (iOutputThumbResolution.iWidth < 16 || iOutputThumbResolution.iHeight < 16)
       
   447             {
       
   448             	iThumbEnhance = EFalse;            	
       
   449             }
       
   450         }
       
   451         else								// for screen display
       
   452         {
       
   453             if(iThumbDisplayMode == ENone)					// if no preference
       
   454                 iThumbDisplayMode = EColor64K;				// 16-bit image
       
   455         }
       
   456         
       
   457         // determine proper bit depth for the bitmap
       
   458         if(iThumbDisplayMode == EColor16M)
       
   459             bytesPerPixel = 3; // 24-bit rgb takes 3 bytes, stored as bbbbbbbb gggggggg rrrrrrrr
       
   460         else if(iThumbDisplayMode == EColor64K || iThumbDisplayMode == EColor4K)
       
   461             bytesPerPixel = 2; // 12-bit rgb takes 2 bytes, stored as ggggbbbb xxxxrrrr                            
       
   462         else
       
   463         {
       
   464             HandleThumbnailError(KErrNotSupported);
       
   465             return;					// support for 12-, 16- and 24-bit color images only
       
   466         }
       
   467         
       
   468         // create output rgb buffer
       
   469         TRAP(error, iRgbBuf = (TUint8*) User::AllocL(thumbLength * bytesPerPixel));
       
   470         if (HandleThumbnailError(error))
       
   471             return;                                
       
   472         
       
   473         TInt scanLineLength;
       
   474         
       
   475         // convert yuv to rgb
       
   476         switch (iThumbDisplayMode)
       
   477         {
       
   478             
       
   479         case EColor4K:
       
   480             {
       
   481                 TInt error;
       
   482                 CYuv2Rgb12* yuvConverter = NULL; 
       
   483                 TRAP(error, yuvConverter = new(ELeave) CYuv2Rgb12);
       
   484                 if (HandleThumbnailError(error))
       
   485                     return;
       
   486                 scanLineLength = inputFrameResolution.iWidth * bytesPerPixel;                 
       
   487                 TRAP(error, yuvConverter->ConstructL(inputFrameResolution.iWidth, inputFrameResolution.iHeight, inputFrameResolution.iWidth, inputFrameResolution.iHeight));
       
   488                 if (HandleThumbnailError(error))
       
   489                     return;
       
   490                 yuvConverter->Convert(yBuf, uBuf, vBuf, inputFrameResolution.iWidth, inputFrameResolution.iHeight, iRgbBuf, scanLineLength);                
       
   491                 delete yuvConverter;		
       
   492                 yuvConverter=0;         
       
   493             }
       
   494             break;
       
   495             
       
   496         default:
       
   497         case EColor64K:
       
   498             {
       
   499                 TInt error;
       
   500                 CYuv2Rgb16* yuvConverter = NULL; 
       
   501                 TRAP(error, yuvConverter = new(ELeave) CYuv2Rgb16);
       
   502                 if (HandleThumbnailError(error))
       
   503                     return;                
       
   504                 scanLineLength = inputFrameResolution.iWidth * bytesPerPixel; 
       
   505                 TRAP(error, yuvConverter->ConstructL(inputFrameResolution.iWidth, inputFrameResolution.iHeight, inputFrameResolution.iWidth, inputFrameResolution.iHeight);)
       
   506                 if (HandleThumbnailError(error))
       
   507                     return;
       
   508                 yuvConverter->Convert(yBuf, uBuf, vBuf, inputFrameResolution.iWidth, inputFrameResolution.iHeight, iRgbBuf, scanLineLength);                
       
   509                 delete yuvConverter;		
       
   510                 yuvConverter=0; 
       
   511             }
       
   512             break;
       
   513             
       
   514         case EColor16M:
       
   515             {
       
   516                 TInt error;
       
   517                 CYuv2Rgb24* yuvConverter = NULL; 
       
   518                 TRAP(error, yuvConverter = new(ELeave) CYuv2Rgb24);
       
   519                 if (HandleThumbnailError(error))
       
   520                     return;                                
       
   521                 scanLineLength = inputFrameResolution.iWidth * bytesPerPixel;                 
       
   522                 TRAP(error, yuvConverter->ConstructL(inputFrameResolution.iWidth, inputFrameResolution.iHeight, inputFrameResolution.iWidth, inputFrameResolution.iHeight))
       
   523                 if (HandleThumbnailError(error))
       
   524                     return;                
       
   525                 yuvConverter->Convert(yBuf, uBuf, vBuf, inputFrameResolution.iWidth, inputFrameResolution.iHeight, iRgbBuf, scanLineLength);                
       
   526                 delete yuvConverter;		
       
   527                 yuvConverter=0; 
       
   528             }
       
   529             break;
       
   530         }        
       
   531     }
       
   532 
       
   533 	if(!iThumbEnhance)
       
   534 	{
       
   535         TSize inputFrameResolution(iMetaData.iWidth,iMetaData.iHeight);
       
   536 		    
       
   537 		/* Pre-calculate pixel indices for horizontal scaling. */
       
   538 		// inputFrameResolution is the resolution of the image read from video clip.
       
   539 		// iOutputThumbResolution is the final resolution desired by the caller.
       
   540 		
       
   541 		TInt OutW = (iOutputThumbResolution.iWidth + 3 )/4 * 4;
       
   542 		TInt OutH = (iOutputThumbResolution.iHeight + 3 )/4 * 4;
       
   543 		
       
   544 		TSize roundedsize = TSize (OutW,OutH);
       
   545 		
       
   546 		TInt xIncrement = inputFrameResolution.iWidth * OutW;
       
   547 		TInt xBoundary =  OutW * OutW;
       
   548 		
       
   549 		TInt* xIndices = 0;
       
   550 		TRAPD(xIndicesErr, xIndices = new (ELeave) TInt[OutW]);
       
   551 		if (xIndicesErr == KErrNone)
       
   552 		{
       
   553 			TInt xDecision = xIncrement / bytesPerPixel; // looks like they changed here - orig was /2
       
   554 			TInt sourceIndex = 0;
       
   555 			for (TInt x = 0; x < OutW; x++)
       
   556 			{
       
   557 				while (xDecision > xBoundary)
       
   558 				{
       
   559 					xDecision -= xBoundary;
       
   560 					sourceIndex += bytesPerPixel;
       
   561 				}
       
   562 				
       
   563 				xIndices[x] = sourceIndex;
       
   564 				xDecision += xIncrement;
       
   565 			}
       
   566 		}
       
   567 		else
       
   568 		{		    
       
   569 		    HandleThumbnailError(xIndicesErr);
       
   570 		    return;
       
   571 		}
       
   572 		
       
   573 		/* Initialize bitmap. */
       
   574 		TRAPD(bitmapErr, iOutBitmap = new (ELeave) CFbsBitmap);
       
   575 		if ((xIndicesErr == KErrNone) && (bitmapErr == KErrNone))
       
   576 		{
       
   577 			bitmapErr = iOutBitmap->Create(roundedsize, iThumbDisplayMode/*EColor64K*/);
       
   578 			if (bitmapErr == KErrNone)
       
   579 			{
       
   580                 // Lock the heap to prevent the FBS server from invalidating the address
       
   581                 iOutBitmap->LockHeap();
       
   582 
       
   583 				/* Scale to desired iOutputThumbResolution and copy to bitmap. */
       
   584 				TUint8* dataAddress = (TUint8*)iOutBitmap->DataAddress(); // fix
       
   585 				
       
   586 				TInt yIncrement = inputFrameResolution.iHeight * OutH;
       
   587 				TInt yBoundary =  OutH * OutH;
       
   588 				
       
   589 				TInt targetIndex = 0;
       
   590 				TInt sourceRowIndex = 0;
       
   591 				TInt yDecision = yIncrement / 2; 
       
   592 				for (TInt y = 0; y < OutH; y++)
       
   593 				{
       
   594 					while (yDecision > yBoundary)
       
   595 					{
       
   596 						yDecision -= yBoundary;
       
   597 						sourceRowIndex += (inputFrameResolution.iWidth * bytesPerPixel); 
       
   598 					}
       
   599 					yDecision += yIncrement;
       
   600 
       
   601 
       
   602 					for (TInt x = 0; x < OutW; x++)					
       
   603 					{
       
   604                         for (TInt i = 0; i < bytesPerPixel; ++i)
       
   605                         {
       
   606                             const TInt firstPixelSourceIndex = sourceRowIndex + xIndices[x] + i;
       
   607                             dataAddress[targetIndex] = iRgbBuf[firstPixelSourceIndex];
       
   608                             targetIndex++;
       
   609                         }
       
   610                     }
       
   611 				}
       
   612                 iOutBitmap->UnlockHeap();
       
   613                 
       
   614                 // resing to original if odd values were input
       
   615                if(roundedsize != iOutputThumbResolution)
       
   616                {
       
   617                
       
   618                	TInt err ;
       
   619                	err = iOutBitmap->Resize(iOutputThumbResolution);
       
   620                	if(err!= KErrNone)
       
   621                		HandleThumbnailError(err);	
       
   622                	
       
   623                }
       
   624                 
       
   625 			} 
       
   626 			
       
   627 			else
       
   628 			{			    
       
   629 				delete iOutBitmap; iOutBitmap = 0;
       
   630 				HandleThumbnailError(bitmapErr);
       
   631 				return;
       
   632 			}
       
   633 		}
       
   634 		else
       
   635 		{
       
   636 		    HandleThumbnailError(bitmapErr);
       
   637 		    delete[] xIndices; xIndices = 0;
       
   638 		    return;
       
   639 		}
       
   640 		
       
   641 		delete[] xIndices;
       
   642 		xIndices = 0;
       
   643 	}
       
   644 	else		// enhance
       
   645 	{
       
   646 		TInt i,j;
       
   647 		// create input bitmap and buffer
       
   648 		CFbsBitmap* inBitmap = 0;
       
   649 		TRAPD(inBitmapErr, inBitmap = new (ELeave) CFbsBitmap);
       
   650 		if( inBitmapErr == KErrNone )
       
   651         {
       
   652 		    // create bitmaps
       
   653 		    TSize originalResolution(iMetaData.iWidth, iMetaData.iHeight);
       
   654 		    inBitmapErr = inBitmap->Create(originalResolution, iThumbDisplayMode/*EColor16M*/); 
       
   655 		
       
   656             if( inBitmapErr == KErrNone )
       
   657             {
       
   658 		        // fill image from rgb buffer to input bitmap buffer 
       
   659 		        TPtr8 linePtr(0,0); 
       
   660         		TInt lineLength = inBitmap->ScanLineLength(originalResolution.iWidth, iThumbDisplayMode); 
       
   661 		        for(j=0, i=0; j<originalResolution.iHeight; j++, i+=lineLength)
       
   662 		        {
       
   663         			linePtr.Set(iRgbBuf+i, lineLength, lineLength);
       
   664 		        	inBitmap->SetScanLine((TDes8&)linePtr,j); 
       
   665 		        }
       
   666 		
       
   667         		// create output bitmap 
       
   668 		        TRAPD(outBitmapErr, iOutBitmap = new (ELeave) CFbsBitmap);
       
   669                 if( outBitmapErr == KErrNone )
       
   670                 {
       
   671 		            outBitmapErr = iOutBitmap->Create(iOutputThumbResolution, iThumbDisplayMode/*EColor16M*/); // same size as input frame
       
   672 		
       
   673                     if( outBitmapErr == KErrNone )
       
   674                     {
       
   675 		                // post-processing enhancement 
       
   676 		                TRAP(outBitmapErr, EnhanceThumbnailL((const CFbsBitmap*)inBitmap, (CFbsBitmap*)iOutBitmap));
       
   677 
       
   678                     }
       
   679                     else
       
   680                     {
       
   681                         delete inBitmap; inBitmap = 0;   
       
   682                         delete iOutBitmap; iOutBitmap = 0;
       
   683                         HandleThumbnailError(outBitmapErr);
       
   684                         return;
       
   685                     }
       
   686                 }
       
   687                 else
       
   688                 {
       
   689                      delete inBitmap; inBitmap = 0;
       
   690                      HandleThumbnailError(outBitmapErr);
       
   691                      return;
       
   692                 }
       
   693             }
       
   694             else
       
   695             {
       
   696                 delete inBitmap; inBitmap = 0;
       
   697                 HandleThumbnailError(inBitmapErr);
       
   698                 return;                
       
   699             }
       
   700 		
       
   701 		    // delete input bitmap 
       
   702 		    delete inBitmap;
       
   703 		    inBitmap = 0;
       
   704         }
       
   705         else
       
   706         {
       
   707             HandleThumbnailError(inBitmapErr);
       
   708             return;
       
   709         }
       
   710 	}
       
   711 
       
   712     delete iRgbBuf;
       
   713     iRgbBuf = 0;
       
   714     FLOG(_L("CHXTNEVideoClipInfoImp::GenerateThumbNail out"));
       
   715 }
       
   716 
       
   717 
       
   718 TBool CHXTNEVideoClipInfoImp::HandleThumbnailError(TInt aError)
       
   719 {
       
   720     if (aError != KErrNone)
       
   721     {
       
   722     	m_LastError = aError;
       
   723    
       
   724         return ETrue;
       
   725     }
       
   726        
       
   727     return EFalse;    
       
   728 }
       
   729 
       
   730 
       
   731 void CHXTNEVideoClipInfoImp::EnhanceThumbnailL(const CFbsBitmap* aInBitmap, 
       
   732 											CFbsBitmap* aTargetBitmap) 
       
   733 {
       
   734     FLOG(_L("CHXTNEVideoClipInfoImp::EnhanceThumbnailL in"));
       
   735   // create enhancement object
       
   736 	if(!iEnhancer)
       
   737     iEnhancer = (CDisplayChain*) CDisplayChain::NewL();
       
   738 
       
   739 	// enhance image
       
   740 	iEnhancer->ProcessL(aInBitmap, aTargetBitmap); 
       
   741 
       
   742 	// clear enhancement object
       
   743 	delete iEnhancer;
       
   744 	iEnhancer=0;
       
   745 	FLOG(_L("CHXTNEVideoClipInfoImp::EnhanceThumbnailL out"));
       
   746 
       
   747 }