diff -r 80975da52420 -r 43d09473c595 mmserv/thumbnailengine/TneAPISrc/HXTneserver.cpp --- a/mmserv/thumbnailengine/TneAPISrc/HXTneserver.cpp Mon May 03 12:59:52 2010 +0300 +++ b/mmserv/thumbnailengine/TneAPISrc/HXTneserver.cpp Fri May 14 16:22:35 2010 +0300 @@ -21,6 +21,8 @@ #include"HXTneclientservercommon.h" #include #include +#include // Sqrt +#include // abs static const TInt kDefaultStack = 0x4000; @@ -57,7 +59,7 @@ -const TInt KMaxPacketToDecode = 32; +const TInt KMaxPacketToDecode = 160; // Many clips begin with several seconds of logos / MPAA rating which need to be skipped //////////////Server/////////////// @@ -688,51 +690,126 @@ } } +/* Determines whether a frame contains sufficient data to be considered an useful frame. + * The logic scans a set of pixels to confirm: + * too bright or too dark pixels are not taken into account. Only mid brightness pixels will be considered + * if less than minSamples valid samples the frame is rejected. + * if the mode is more frequent than maxModePrct% the frame is rejected. This is useful to reject the MPAA rating or other simple logos + * if the contrast is too low (max - min) frame is rejected + * if the standard deviation is too low frame is rejected. + */ + TBool CTneSession::IsGoodFrame(TUint8* aYUVDataPtr) { - TInt i; + TInt ySize = iWidth*iHeight; + TUint8 * resetYUVPtr = aYUVDataPtr; + + // only these luminances are taken into account + TInt minSamples = 5; + TInt tooDark = 30; + TInt tooBright = 240; + + // Defines how much data we analyze from the image to analyze its validity + TInt pixelSkips = iHeight; // scans about 1 to 3 pixels per line depending on aspect ratio + + // average luminance profiling + TInt runningSum = 0; + TInt numberOfSamples = 0; + TInt averageValue = 0; + + // contrast profiling TInt minValue = 255; TInt maxValue = 0; + TInt minMaxDeltaThreshold = 20; + + // mode profiling + int mode = 0; + int modeSamples = 0; + int histogram[255] = {0}; + int maxModePrct = 69; + + // standard deviation profiling + TInt minStdDeviation = 5; + TUint32 residualsum = 0; + TReal stdDeviation = 0; + + // Exit value TBool goodFrame = ETrue; - TInt runningSum=0; - TInt averageValue=0; - TInt pixelSkips = 4; - TInt numberOfSamples=0; - TInt minMaxDeltaThreshold = 20; - TInt extremeRegionThreshold = 20; - TInt ySize = iWidth*iHeight; - - // gather image statistics - for(i=0, numberOfSamples=0; i maxValue) - maxValue = *aYUVDataPtr; - if(*aYUVDataPtr < minValue) - minValue = *aYUVDataPtr; + if ( (*aYUVDataPtr>tooDark) && (*aYUVDataPtr maxValue) + maxValue = *aYUVDataPtr; + if(*aYUVDataPtr < minValue) + minValue = *aYUVDataPtr; + histogram[*aYUVDataPtr]++; + numberOfSamples++; + } + } + + if (numberOfSamples < minSamples) + { + //FLOG(_L("CTneSession::IsGoodFrame too few good samples")); + goodFrame = EFalse; } - //VDASSERT(numberOfSamples,10); - if (numberOfSamples == 0) + else { - FLOG(_L("CTneSession::IsGoodFrame numberOfSamples is zero")); - } - else - { - averageValue = runningSum/numberOfSamples; - } + // Find the mode + for (i=0; i<255; i++) + { + if (histogram[i] > modeSamples) + { + modeSamples = histogram[i]; + mode = i; + } + } + // Add the mode and most immediate values, as compression may add artifacts that disperse its value + for (i = mode-2, modeSamples = 0; i < mode+3; i++) + { + modeSamples += histogram[i]; + } - // make decision based statistics - if((maxValue - minValue) < minMaxDeltaThreshold) - goodFrame = EFalse; - else - { - if(averageValue < (minValue + extremeRegionThreshold) || - averageValue > (maxValue - extremeRegionThreshold)) - goodFrame = EFalse; + if (modeSamples * 100 / numberOfSamples > maxModePrct) + { + //FLOG(_L("Mode (%d) in over %d%% of the image\n", mode, modeSamples * 100 / numberOfSamples); + goodFrame = false; + } + else + { + averageValue = runningSum / numberOfSamples; + // Rescan the frame now that we the average value is known + aYUVDataPtr = resetYUVPtr; + + + // Calculate the sum of residuals: (pixel - avgpixel)^2 + for(i=0; itooDark) && (*aYUVDataPtr