mmserv/thumbnailengine/TneAPISrc/HXTneserver.cpp
changeset 16 43d09473c595
parent 0 71ca22bcf22a
child 25 6f7ceef7b1d1
equal deleted inserted replaced
14:80975da52420 16:43d09473c595
    19 
    19 
    20 #include"HXTneserver.h"
    20 #include"HXTneserver.h"
    21 #include"HXTneclientservercommon.h"
    21 #include"HXTneclientservercommon.h"
    22 #include <flogger.h>
    22 #include <flogger.h>
    23 #include <f32file64.h>
    23 #include <f32file64.h>
       
    24 #include <e32math.h> // Sqrt
       
    25 #include <stdlib.h> // abs
    24 static const TInt kDefaultStack = 0x4000;
    26 static const TInt kDefaultStack = 0x4000;
    25 
    27 
    26 
    28 
    27 
    29 
    28 // PRINT macro
    30 // PRINT macro
    55 #endif // enable logging
    57 #endif // enable logging
    56 
    58 
    57 
    59 
    58 
    60 
    59 
    61 
    60 const TInt KMaxPacketToDecode = 32;
    62 const TInt KMaxPacketToDecode = 160; // Many clips begin with several seconds of logos / MPAA rating which need to be skipped
    61 
    63 
    62 //////////////Server///////////////
    64 //////////////Server///////////////
    63 
    65 
    64 
    66 
    65 CTneServer::CTneServer(CActive::TPriority aActiveObjectPriority)
    67 CTneServer::CTneServer(CActive::TPriority aActiveObjectPriority)
   686         {
   688         {
   687             MetaDataReady(KErrCompletion);
   689             MetaDataReady(KErrCompletion);
   688         }
   690         }
   689 }
   691 }
   690 
   692 
       
   693 /* Determines whether a frame contains sufficient data to be considered an useful frame.
       
   694  * The logic scans a set of pixels to confirm:
       
   695  * too bright or too dark pixels are not taken into account. Only mid brightness pixels will be considered
       
   696  * if less than minSamples valid samples the frame is rejected. 
       
   697  * if the mode is more frequent than maxModePrct% the frame is rejected. This is useful to reject the MPAA rating or other simple logos
       
   698  * if the contrast is too low (max - min) frame is rejected
       
   699  * if the standard deviation is too low frame is rejected.
       
   700  */
       
   701 
   691 TBool CTneSession::IsGoodFrame(TUint8* aYUVDataPtr)
   702 TBool CTneSession::IsGoodFrame(TUint8* aYUVDataPtr)
   692 {
   703 {
   693 	
       
   694  	TInt i;
   704  	TInt i;
       
   705     TInt ySize = iWidth*iHeight; 
       
   706     TUint8 * resetYUVPtr = aYUVDataPtr;
       
   707 
       
   708     // only these luminances are taken into account
       
   709     TInt minSamples = 5;
       
   710     TInt tooDark = 30;
       
   711     TInt tooBright = 240;
       
   712 
       
   713     // Defines how much data we analyze from the image to analyze its validity
       
   714     TInt pixelSkips = iHeight;  // scans about 1 to 3 pixels per line depending on aspect ratio 
       
   715 
       
   716     // average luminance profiling
       
   717     TInt runningSum = 0;
       
   718     TInt numberOfSamples = 0;
       
   719     TInt averageValue = 0;
       
   720 
       
   721     // contrast profiling
   695     TInt minValue = 255;
   722     TInt minValue = 255;
   696     TInt maxValue = 0;
   723     TInt maxValue = 0;
       
   724     TInt minMaxDeltaThreshold = 20;
       
   725 
       
   726     // mode profiling
       
   727     int mode = 0;
       
   728     int modeSamples = 0;
       
   729     int histogram[255] = {0};
       
   730     int maxModePrct = 69;
       
   731 
       
   732     // standard deviation profiling
       
   733     TInt minStdDeviation = 5;
       
   734     TUint32 residualsum = 0;
       
   735     TReal stdDeviation = 0;
       
   736 
       
   737     // Exit value
   697     TBool goodFrame = ETrue;
   738     TBool goodFrame = ETrue;
   698     TInt runningSum=0;
   739 
   699     TInt averageValue=0;
   740     for(i=0, numberOfSamples=0; i<ySize; i+=pixelSkips, aYUVDataPtr+=pixelSkips)
   700     TInt pixelSkips = 4;
   741     {
   701     TInt numberOfSamples=0;
   742         if ( (*aYUVDataPtr>tooDark) && (*aYUVDataPtr<tooBright) )
   702     TInt minMaxDeltaThreshold = 20; 
   743         {
   703     TInt extremeRegionThreshold = 20; 
   744             runningSum += *aYUVDataPtr;
   704     TInt ySize = iWidth*iHeight; 
   745             if(*aYUVDataPtr > maxValue)
   705     
   746                 maxValue = *aYUVDataPtr;
   706     // gather image statistics
   747             if(*aYUVDataPtr < minValue)
   707     for(i=0, numberOfSamples=0; i<ySize; i+=pixelSkips, aYUVDataPtr+=pixelSkips, numberOfSamples++)
   748                 minValue = *aYUVDataPtr;
   708     {
   749             histogram[*aYUVDataPtr]++;
   709         
   750             numberOfSamples++;
   710         
   751         }
   711         runningSum += *aYUVDataPtr;
   752     }
   712         if(*aYUVDataPtr > maxValue)
   753 
   713             maxValue = *aYUVDataPtr;
   754     if (numberOfSamples < minSamples)
   714         if(*aYUVDataPtr < minValue)
   755     {
   715             minValue = *aYUVDataPtr;
   756         //FLOG(_L("CTneSession::IsGoodFrame too few good samples"));
   716     }
       
   717     //VDASSERT(numberOfSamples,10);
       
   718     if (numberOfSamples == 0)
       
   719     {
       
   720         FLOG(_L("CTneSession::IsGoodFrame numberOfSamples is zero")); 
       
   721     }
       
   722     else 
       
   723     {
       
   724         averageValue = runningSum/numberOfSamples;
       
   725     }
       
   726     
       
   727     // make decision based statistics
       
   728     if((maxValue - minValue) < minMaxDeltaThreshold)
       
   729         goodFrame = EFalse;
   757         goodFrame = EFalse;
   730     else 
   758     }
   731     {
   759     else
   732         if(averageValue < (minValue + extremeRegionThreshold) || 
   760     {
   733             averageValue > (maxValue - extremeRegionThreshold))
   761         // Find the mode
   734             goodFrame = EFalse;
   762         for (i=0; i<255; i++)
   735     }
   763         {
       
   764             if (histogram[i] > modeSamples)
       
   765             {
       
   766                 modeSamples = histogram[i];
       
   767                 mode = i;
       
   768             }
       
   769         }
       
   770         // Add the mode and most immediate values, as compression may add artifacts that disperse its value
       
   771         for (i = mode-2, modeSamples = 0; i < mode+3; i++)
       
   772         {
       
   773             modeSamples += histogram[i];
       
   774         }
       
   775     
       
   776         if (modeSamples * 100 / numberOfSamples > maxModePrct)
       
   777         {
       
   778             //FLOG(_L("Mode (%d) in over %d%% of the image\n", mode, modeSamples * 100 / numberOfSamples);
       
   779             goodFrame = false;
       
   780         }
       
   781         else 
       
   782         {
       
   783             averageValue = runningSum / numberOfSamples;
       
   784             // Rescan the frame now that we the average value is known
       
   785             aYUVDataPtr = resetYUVPtr;
       
   786     
       
   787     
       
   788             // Calculate the sum of residuals: (pixel - avgpixel)^2
       
   789             for(i=0; i<ySize; i+=pixelSkips, aYUVDataPtr+=pixelSkips)
       
   790             {
       
   791                 if ( (*aYUVDataPtr>tooDark) && (*aYUVDataPtr<tooBright) )
       
   792                 {
       
   793                     residualsum += (*aYUVDataPtr - averageValue) * (*aYUVDataPtr - averageValue);
       
   794                 }
       
   795             }
       
   796     
       
   797             // Get the standard deviation
       
   798             Math::Sqrt(stdDeviation , residualsum / numberOfSamples);
       
   799     
       
   800             if (stdDeviation < minStdDeviation)
       
   801             {
       
   802                 //FLOG(_L("CTneSession::IsGoodFrame too low StdDeviation: %f"), stdDeviation);
       
   803                 goodFrame = EFalse;
       
   804             }
       
   805             else if((maxValue - minValue) < minMaxDeltaThreshold)
       
   806             {
       
   807                 //FLOG(_L("CTneSession::IsGoodFrame too little difference between brightest and darkest pixel"));
       
   808                 goodFrame = EFalse;
       
   809             }
       
   810         }
       
   811     }
       
   812 
   736     return goodFrame;
   813     return goodFrame;
   737 }
   814 }
   738 
   815 
   739 TInt CTneSession::GetStartingTime(TUint &uStartingTime)
   816 TInt CTneSession::GetStartingTime(TUint &uStartingTime)
   740 {	
   817 {