1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/multimedia/t_camera_display.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,388 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\multimedia\t_camera_display.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32test.h>
1.22 +#include <e32svr.h>
1.23 +#include <u32hal.h>
1.24 +#include <videodriver.h>
1.25 +#include "t_camera_display.h"
1.26 +
1.27 +_LIT(KFrameSizeConfTitle,"Current frame size :");
1.28 +_LIT(KFrameSize, " %d x %d");
1.29 +
1.30 +#define CLIP(a) if (a < 0) a = 0; else if (a > 255) a = 255;
1.31 +
1.32 +/**
1.33 +Constructor
1.34 +*/
1.35 +TCamDisplayHandler::TCamDisplayHandler()
1.36 + {}
1.37 +
1.38 +/**
1.39 +Initialise the display handler.
1.40 +@return KErrNone if write was successful, otherwise one of the other system wide error codes.
1.41 +*/
1.42 +TInt TCamDisplayHandler::Init()
1.43 + {
1.44 + TScreenInfoV01 screenInfo;
1.45 + TPckg<TScreenInfoV01> screenInfoBuf(screenInfo);
1.46 + UserSvr::ScreenInfo(screenInfoBuf);
1.47 + iVideoAddress = (TUint8*) screenInfo.iScreenAddress;
1.48 + iScreenWidth = screenInfo.iScreenSize.iWidth;
1.49 + iScreenHeight = screenInfo.iScreenSize.iHeight;
1.50 +
1.51 + TPckgBuf<TVideoInfoV01> videoInfoBuf;
1.52 + UserSvr::HalFunction(EHalGroupDisplay, EDisplayHalCurrentModeInfo, &videoInfoBuf, NULL);
1.53 + iBitsPerPixel = videoInfoBuf().iBitsPerPixel;
1.54 +
1.55 + return(KErrNone);
1.56 + }
1.57 +
1.58 +TInt TCamDisplayHandler::Min(TInt aA, TInt aB)
1.59 + {
1.60 + return (aA < aB) ? aA : aB;
1.61 + }
1.62 +
1.63 +TInt TCamDisplayHandler::SetConfig(const SDevCamFrameSize& aSize,const SDevCamPixelFormat& aPixelFormat)
1.64 + {
1.65 + if (aPixelFormat.iPixelFormat==EUidPixelFormatYUV_422Interleaved || aPixelFormat.iPixelFormat==EUidPixelFormatRGB_565)
1.66 + iPixelFormat=aPixelFormat;
1.67 + else
1.68 + return(KErrArgument);
1.69 +
1.70 + iWidth = aSize.iWidth;
1.71 + iHeight = aSize.iHeight;
1.72 +
1.73 + return(KErrNone);
1.74 + }
1.75 +
1.76 +/**
1.77 +Post process a received image.
1.78 +@return KErrNone if write was successful, otherwise one of the other system wide error codes.
1.79 +*/
1.80 +TInt TCamDisplayHandler::Process(TUint8* aImageBaseAddress)
1.81 + {
1.82 + switch (iPixelFormat.iPixelFormat)
1.83 + {
1.84 + case EUidPixelFormatYUV_422Interleaved:
1.85 + return(ProcessYUV422(aImageBaseAddress));
1.86 + case EUidPixelFormatRGB_565:
1.87 + return(ProcessRGB565(aImageBaseAddress));
1.88 + default:
1.89 + return(KErrNotSupported);
1.90 + }
1.91 + }
1.92 +
1.93 +/**
1.94 +Post process a received RGB565 image.
1.95 +@return KErrNone if write was successful, otherwise one of the other system wide error codes.
1.96 +*/
1.97 +TInt TCamDisplayHandler::ProcessRGB565(TUint8* aImageBaseAddress)
1.98 + {
1.99 + TUint16* source = (TUint16*) aImageBaseAddress;
1.100 + TUint16 pixel;
1.101 + TInt sourceModulo, destModulo, width, height;
1.102 + TInt r = KErrNone;
1.103 +
1.104 + // Determine whether the screen or the picture to display is the widest, and calculate modulos
1.105 + // and clipping sizes appropriately
1.106 + if (iWidth < iScreenWidth)
1.107 + {
1.108 + width = iWidth;
1.109 + sourceModulo = 0;
1.110 + destModulo = (iScreenWidth - iWidth);
1.111 + }
1.112 + else
1.113 + {
1.114 + width = iScreenWidth;
1.115 + sourceModulo = (iWidth - iScreenWidth);
1.116 + destModulo = 0;
1.117 + }
1.118 +
1.119 + // Determine whether the screen or the picture to display is the highest
1.120 + height = (iHeight < iScreenHeight) ? iHeight : iScreenHeight;
1.121 +
1.122 + if (iBitsPerPixel == 16)
1.123 + {
1.124 + TUint16* dest = (TUint16*) iVideoAddress;
1.125 +
1.126 + // Loop around and copy the data directly onto the screen
1.127 + for (TInt line = 0; line < height; ++line)
1.128 + {
1.129 + for (TInt x = 0; x < width; ++x)
1.130 + {
1.131 + *dest++ = *source++;
1.132 + }
1.133 +
1.134 + source += sourceModulo;
1.135 + dest += destModulo;
1.136 + }
1.137 + }
1.138 + else if (iBitsPerPixel == 32)
1.139 + {
1.140 + TUint8* dest = iVideoAddress;
1.141 +
1.142 + destModulo *= 4;
1.143 +
1.144 + // Loop around and convert whatever part of the picture will fit onto the screen into BGRA,
1.145 + // writing it directly onto the screen
1.146 + for (TInt line = 0; line < height; ++line)
1.147 + {
1.148 + for (TInt x = 0; x < width; ++x)
1.149 + {
1.150 + pixel = *source++;
1.151 + *dest++= (TUint8) ((pixel & 0x001f) << 3);
1.152 + *dest++= (TUint8) ((pixel & 0x07e0) >> 3);
1.153 + *dest++= (TUint8) ((pixel & 0xf800) >> 8);
1.154 + *dest++ = 0xff;
1.155 + }
1.156 +
1.157 + source += sourceModulo;
1.158 + dest += destModulo;
1.159 + }
1.160 + }
1.161 + else
1.162 + {
1.163 + r = KErrNotSupported;
1.164 + }
1.165 +
1.166 + return r;
1.167 + }
1.168 +
1.169 +/**
1.170 +Post process a received YUV422 image.
1.171 +@return KErrNone if write was successful, otherwise one of the other system wide error codes.
1.172 +*/
1.173 +TInt TCamDisplayHandler::ProcessYUV422(TUint8* aImageBaseAddress)
1.174 + {
1.175 + TUint16* dest16 = (TUint16*) iVideoAddress;
1.176 + TUint32* dest32 = (TUint32*) iVideoAddress;
1.177 + TUint8* source = aImageBaseAddress;
1.178 + TInt y, u, v, r, g, b, sourceModulo, destModulo, width, height;
1.179 + TInt retVal = KErrNone;
1.180 +
1.181 + // Determine whether the screen or the picture to display is the widest, and calculate modulos
1.182 + // and clipping sizes appropriately
1.183 + if (iWidth < iScreenWidth)
1.184 + {
1.185 + width = (iWidth / 2);
1.186 + sourceModulo = 0;
1.187 + destModulo = (iScreenWidth - iWidth);
1.188 + }
1.189 + else
1.190 + {
1.191 + width = (iScreenWidth / 2);
1.192 + sourceModulo = ((iWidth - iScreenWidth) * 2);
1.193 + destModulo = 0;
1.194 + }
1.195 +
1.196 + // Determine whether the screen or the picture to display is the highest
1.197 + height = (iHeight < iScreenHeight) ? iHeight : iScreenHeight;
1.198 +
1.199 + // Only 16 and 32 bits per pixel are supported. It is also assumed that 16 bit will be RGB565 and
1.200 + // 32 bit will be BGRA. You will need to add support for new formats if required
1.201 + if ((iBitsPerPixel == 16) || (iBitsPerPixel == 32))
1.202 + {
1.203 + // Loop around and convert whatever part of the picture will fit onto the screen into RGB565 or BGRA,
1.204 + // writing it directly onto the screen
1.205 + for (TInt line = 0; line < height; ++line)
1.206 + {
1.207 + for (TInt x = 0; x < width; ++x)
1.208 + {
1.209 + u = (source[0] - 128);
1.210 + v = (source[2] - 128);
1.211 + y = (source[3] - 16);
1.212 +
1.213 + r = ((298 * y + 409 * u) / 256);
1.214 + g = ((298 * y - 100 * v - 208 * u) / 256);
1.215 + b = ((298 * y + 516 * v) / 256);
1.216 +
1.217 + CLIP(r);
1.218 + CLIP(g);
1.219 + CLIP(b);
1.220 +
1.221 + if (iBitsPerPixel == 16)
1.222 + {
1.223 + *dest16++ = (TUint16) (((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3));
1.224 + }
1.225 + else
1.226 + {
1.227 + *dest32++ = (0xff000000 | (r << 16) | (g << 8) | b);
1.228 + }
1.229 +
1.230 + y = (source[1] - 16);
1.231 +
1.232 + r = ((298 * y + 409 * u) / 256);
1.233 + g = ((298 * y - 100 * v - 208 * u) / 256);
1.234 + b = ((298 * y + 516 * v) / 256);
1.235 +
1.236 + CLIP(r);
1.237 + CLIP(g);
1.238 + CLIP(b);
1.239 +
1.240 + if (iBitsPerPixel == 16)
1.241 + {
1.242 + *dest16++ = (TUint16) (((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3));
1.243 + }
1.244 + else
1.245 + {
1.246 + *dest32++ = (0xff000000 | (r << 16) | (g << 8) | b);
1.247 + }
1.248 +
1.249 + source += 4;
1.250 + }
1.251 +
1.252 + source += sourceModulo;
1.253 + dest16 += destModulo;
1.254 + dest32 += destModulo;
1.255 + }
1.256 + }
1.257 + else
1.258 + {
1.259 + retVal = KErrNotSupported;
1.260 + }
1.261 +
1.262 + return retVal;
1.263 + }
1.264 +
1.265 +/**
1.266 +Appends a string representing a pixel format UID onto a descriptor.
1.267 +@param aBuffer Reference to the descriptor into which to append the string. It is up to the
1.268 + caller to ensure that this is large enough.
1.269 +@param aPixelFormat UID of the pixel format to be converted into a string.
1.270 +*/
1.271 +void AppendPixelFormat(TDes& aBuffer, TUidPixelFormat aPixelFormat)
1.272 + {
1.273 + if (aPixelFormat == EUidPixelFormatRGB_565)
1.274 + aBuffer.Append(KPixelFormatRGB_565);
1.275 + else if (aPixelFormat == EUidPixelFormatYUV_422Interleaved)
1.276 + aBuffer.Append(KPixelFormatYUV_422Interleaved);
1.277 + else if (aPixelFormat == EUidPixelFormatSpeedTaggedJPEG)
1.278 + aBuffer.Append(KPixelFormatSpeedTaggedJPEG);
1.279 + else if (aPixelFormat == EUidPixelFormatJPEG)
1.280 + aBuffer.Append(KPixelFormatJPEG);
1.281 + else
1.282 + aBuffer.Append(KPixelFormatUnknown);
1.283 + }
1.284 +
1.285 +void PrintCamModes(TCameraCapsV02* aCaps,RTest& aTest)
1.286 + {
1.287 + TBuf<80> buf;
1.288 +
1.289 + // Display the supported capture modes
1.290 + buf.Zero();
1.291 + buf.Append(KCaptureModeCapsTitle);
1.292 + if (aCaps->iNumImagePixelFormats)
1.293 + buf.Append(KCaptureModeImage);
1.294 + if (aCaps->iNumVideoPixelFormats)
1.295 + buf.Append(KCaptureModeVideo);
1.296 + if (aCaps->iNumViewFinderPixelFormats)
1.297 + buf.Append(KCaptureModeViewFinder);
1.298 + buf.Append(_L("\r\n"));
1.299 + aTest.Printf(buf);
1.300 +
1.301 + // Display the supported video pixel formats
1.302 + TUint i;
1.303 + SDevCamPixelFormat* pixelFormat;
1.304 + if (aCaps->iNumImagePixelFormats)
1.305 + {
1.306 + buf.Zero();
1.307 + buf.Append(KPixelFormatCapsTitle);
1.308 + buf.Append(KCaptureModeImage);
1.309 + pixelFormat = (SDevCamPixelFormat*) (aCaps + 1);
1.310 + for (i = 0; i < aCaps->iNumImagePixelFormats; i++)
1.311 + {
1.312 + AppendPixelFormat(buf, pixelFormat->iPixelFormat);
1.313 + pixelFormat++;
1.314 + }
1.315 + buf.Append(_L("\r\n"));
1.316 + aTest.Printf(buf);
1.317 + }
1.318 +
1.319 + if (aCaps->iNumVideoPixelFormats)
1.320 + {
1.321 + buf.Zero();
1.322 + buf.Append(KPixelFormatCapsTitle);
1.323 + buf.Append(KCaptureModeVideo);
1.324 + pixelFormat = (SDevCamPixelFormat*) (aCaps + 1);
1.325 + for (i = aCaps->iNumImagePixelFormats; i < (aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats); i++)
1.326 + {
1.327 + AppendPixelFormat(buf, pixelFormat->iPixelFormat);
1.328 + pixelFormat++;
1.329 + }
1.330 + buf.Append(_L("\r\n"));
1.331 + aTest.Printf(buf);
1.332 + }
1.333 +
1.334 + if (aCaps->iNumViewFinderPixelFormats)
1.335 + {
1.336 + buf.Zero();
1.337 + buf.Append(KPixelFormatCapsTitle);
1.338 + buf.Append(KCaptureModeViewFinder);
1.339 + pixelFormat = (SDevCamPixelFormat*) (aCaps + 1);
1.340 + i = aCaps->iNumImagePixelFormats + aCaps->iNumImagePixelFormats + 1;
1.341 + for (i = aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats; i < (aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats + aCaps->iNumViewFinderPixelFormats); i++)
1.342 + {
1.343 + AppendPixelFormat(buf, pixelFormat->iPixelFormat);
1.344 + pixelFormat++;
1.345 + }
1.346 + buf.Append(_L("\r\n"));
1.347 + aTest.Printf(buf);
1.348 + }
1.349 + }
1.350 +
1.351 +void PrintCamConf(TCameraConfigV02& aConf,RTest& aTest)
1.352 + {
1.353 + TBuf<80> buf;
1.354 +
1.355 + // Display the current frame size
1.356 + buf.Zero();
1.357 + buf.Append(KFrameSizeConfTitle);
1.358 + buf.AppendFormat(KFrameSize, aConf.iFrameSize.iWidth, aConf.iFrameSize.iHeight);
1.359 + buf.Append(_L("\r\n"));
1.360 + aTest.Printf(buf);
1.361 +
1.362 + // Display the current pixel format
1.363 + buf.Zero();
1.364 + buf.Append(KPixelFormatConfTitle);
1.365 + AppendPixelFormat(buf, aConf.iPixelFormat.iPixelFormat);
1.366 + buf.Append(_L("\r\n"));
1.367 + aTest.Printf(buf);
1.368 +
1.369 + // Display the current frame rate
1.370 + buf.Zero();
1.371 + buf.Format(_L("Current frame rate : %d fps\r\n"),aConf.iFrameRate);
1.372 + aTest.Printf(buf);
1.373 + }
1.374 +
1.375 +void PrintBufferConf(TMmSharedChunkBufConfig& aBufConf,RTest& aTest)
1.376 + {
1.377 + TBuf<80> buf(0);
1.378 +
1.379 + SBufSpecList* tempSpec = aBufConf.iSpec;
1.380 +
1.381 + // Display the buffer configuration
1.382 + buf.Format(_L("Buffer Config : NumBufs:%d Size:%xH\r\n"),aBufConf.iNumBuffers,aBufConf.iBufferSizeInBytes);
1.383 + aTest.Printf(buf);
1.384 + if (aBufConf.iFlags & KScFlagBufOffsetListInUse)
1.385 + {
1.386 + buf.Format(_L(" Offsets[%08xH,%08xH,%08xH,%08xH]\r\n"),tempSpec[0].iBufferOffset,tempSpec[1].iBufferOffset,tempSpec[2].iBufferOffset,tempSpec[3].iBufferOffset);
1.387 + aTest.Printf(buf);
1.388 + buf.Format(_L(" Offsets[%08xH,%08xH,%08xH,%08xH]\r\n"),tempSpec[4].iBufferOffset,tempSpec[5].iBufferOffset,tempSpec[6].iBufferOffset,tempSpec[7].iBufferOffset);
1.389 + aTest.Printf(buf);
1.390 + }
1.391 + }