--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/multimedia/t_camera_display.cpp Wed Sep 01 12:34:56 2010 +0100
@@ -0,0 +1,388 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\multimedia\t_camera_display.cpp
+//
+//
+
+#include <e32test.h>
+#include <e32svr.h>
+#include <u32hal.h>
+#include <videodriver.h>
+#include "t_camera_display.h"
+
+_LIT(KFrameSizeConfTitle,"Current frame size :");
+_LIT(KFrameSize, " %d x %d");
+
+#define CLIP(a) if (a < 0) a = 0; else if (a > 255) a = 255;
+
+/**
+Constructor
+*/
+TCamDisplayHandler::TCamDisplayHandler()
+ {}
+
+/**
+Initialise the display handler.
+@return KErrNone if write was successful, otherwise one of the other system wide error codes.
+*/
+TInt TCamDisplayHandler::Init()
+ {
+ TScreenInfoV01 screenInfo;
+ TPckg<TScreenInfoV01> screenInfoBuf(screenInfo);
+ UserSvr::ScreenInfo(screenInfoBuf);
+ iVideoAddress = (TUint8*) screenInfo.iScreenAddress;
+ iScreenWidth = screenInfo.iScreenSize.iWidth;
+ iScreenHeight = screenInfo.iScreenSize.iHeight;
+
+ TPckgBuf<TVideoInfoV01> videoInfoBuf;
+ UserSvr::HalFunction(EHalGroupDisplay, EDisplayHalCurrentModeInfo, &videoInfoBuf, NULL);
+ iBitsPerPixel = videoInfoBuf().iBitsPerPixel;
+
+ return(KErrNone);
+ }
+
+TInt TCamDisplayHandler::Min(TInt aA, TInt aB)
+ {
+ return (aA < aB) ? aA : aB;
+ }
+
+TInt TCamDisplayHandler::SetConfig(const SDevCamFrameSize& aSize,const SDevCamPixelFormat& aPixelFormat)
+ {
+ if (aPixelFormat.iPixelFormat==EUidPixelFormatYUV_422Interleaved || aPixelFormat.iPixelFormat==EUidPixelFormatRGB_565)
+ iPixelFormat=aPixelFormat;
+ else
+ return(KErrArgument);
+
+ iWidth = aSize.iWidth;
+ iHeight = aSize.iHeight;
+
+ return(KErrNone);
+ }
+
+/**
+Post process a received image.
+@return KErrNone if write was successful, otherwise one of the other system wide error codes.
+*/
+TInt TCamDisplayHandler::Process(TUint8* aImageBaseAddress)
+ {
+ switch (iPixelFormat.iPixelFormat)
+ {
+ case EUidPixelFormatYUV_422Interleaved:
+ return(ProcessYUV422(aImageBaseAddress));
+ case EUidPixelFormatRGB_565:
+ return(ProcessRGB565(aImageBaseAddress));
+ default:
+ return(KErrNotSupported);
+ }
+ }
+
+/**
+Post process a received RGB565 image.
+@return KErrNone if write was successful, otherwise one of the other system wide error codes.
+*/
+TInt TCamDisplayHandler::ProcessRGB565(TUint8* aImageBaseAddress)
+ {
+ TUint16* source = (TUint16*) aImageBaseAddress;
+ TUint16 pixel;
+ TInt sourceModulo, destModulo, width, height;
+ TInt r = KErrNone;
+
+ // Determine whether the screen or the picture to display is the widest, and calculate modulos
+ // and clipping sizes appropriately
+ if (iWidth < iScreenWidth)
+ {
+ width = iWidth;
+ sourceModulo = 0;
+ destModulo = (iScreenWidth - iWidth);
+ }
+ else
+ {
+ width = iScreenWidth;
+ sourceModulo = (iWidth - iScreenWidth);
+ destModulo = 0;
+ }
+
+ // Determine whether the screen or the picture to display is the highest
+ height = (iHeight < iScreenHeight) ? iHeight : iScreenHeight;
+
+ if (iBitsPerPixel == 16)
+ {
+ TUint16* dest = (TUint16*) iVideoAddress;
+
+ // Loop around and copy the data directly onto the screen
+ for (TInt line = 0; line < height; ++line)
+ {
+ for (TInt x = 0; x < width; ++x)
+ {
+ *dest++ = *source++;
+ }
+
+ source += sourceModulo;
+ dest += destModulo;
+ }
+ }
+ else if (iBitsPerPixel == 32)
+ {
+ TUint8* dest = iVideoAddress;
+
+ destModulo *= 4;
+
+ // Loop around and convert whatever part of the picture will fit onto the screen into BGRA,
+ // writing it directly onto the screen
+ for (TInt line = 0; line < height; ++line)
+ {
+ for (TInt x = 0; x < width; ++x)
+ {
+ pixel = *source++;
+ *dest++= (TUint8) ((pixel & 0x001f) << 3);
+ *dest++= (TUint8) ((pixel & 0x07e0) >> 3);
+ *dest++= (TUint8) ((pixel & 0xf800) >> 8);
+ *dest++ = 0xff;
+ }
+
+ source += sourceModulo;
+ dest += destModulo;
+ }
+ }
+ else
+ {
+ r = KErrNotSupported;
+ }
+
+ return r;
+ }
+
+/**
+Post process a received YUV422 image.
+@return KErrNone if write was successful, otherwise one of the other system wide error codes.
+*/
+TInt TCamDisplayHandler::ProcessYUV422(TUint8* aImageBaseAddress)
+ {
+ TUint16* dest16 = (TUint16*) iVideoAddress;
+ TUint32* dest32 = (TUint32*) iVideoAddress;
+ TUint8* source = aImageBaseAddress;
+ TInt y, u, v, r, g, b, sourceModulo, destModulo, width, height;
+ TInt retVal = KErrNone;
+
+ // Determine whether the screen or the picture to display is the widest, and calculate modulos
+ // and clipping sizes appropriately
+ if (iWidth < iScreenWidth)
+ {
+ width = (iWidth / 2);
+ sourceModulo = 0;
+ destModulo = (iScreenWidth - iWidth);
+ }
+ else
+ {
+ width = (iScreenWidth / 2);
+ sourceModulo = ((iWidth - iScreenWidth) * 2);
+ destModulo = 0;
+ }
+
+ // Determine whether the screen or the picture to display is the highest
+ height = (iHeight < iScreenHeight) ? iHeight : iScreenHeight;
+
+ // Only 16 and 32 bits per pixel are supported. It is also assumed that 16 bit will be RGB565 and
+ // 32 bit will be BGRA. You will need to add support for new formats if required
+ if ((iBitsPerPixel == 16) || (iBitsPerPixel == 32))
+ {
+ // Loop around and convert whatever part of the picture will fit onto the screen into RGB565 or BGRA,
+ // writing it directly onto the screen
+ for (TInt line = 0; line < height; ++line)
+ {
+ for (TInt x = 0; x < width; ++x)
+ {
+ u = (source[0] - 128);
+ v = (source[2] - 128);
+ y = (source[3] - 16);
+
+ r = ((298 * y + 409 * u) / 256);
+ g = ((298 * y - 100 * v - 208 * u) / 256);
+ b = ((298 * y + 516 * v) / 256);
+
+ CLIP(r);
+ CLIP(g);
+ CLIP(b);
+
+ if (iBitsPerPixel == 16)
+ {
+ *dest16++ = (TUint16) (((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3));
+ }
+ else
+ {
+ *dest32++ = (0xff000000 | (r << 16) | (g << 8) | b);
+ }
+
+ y = (source[1] - 16);
+
+ r = ((298 * y + 409 * u) / 256);
+ g = ((298 * y - 100 * v - 208 * u) / 256);
+ b = ((298 * y + 516 * v) / 256);
+
+ CLIP(r);
+ CLIP(g);
+ CLIP(b);
+
+ if (iBitsPerPixel == 16)
+ {
+ *dest16++ = (TUint16) (((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3));
+ }
+ else
+ {
+ *dest32++ = (0xff000000 | (r << 16) | (g << 8) | b);
+ }
+
+ source += 4;
+ }
+
+ source += sourceModulo;
+ dest16 += destModulo;
+ dest32 += destModulo;
+ }
+ }
+ else
+ {
+ retVal = KErrNotSupported;
+ }
+
+ return retVal;
+ }
+
+/**
+Appends a string representing a pixel format UID onto a descriptor.
+@param aBuffer Reference to the descriptor into which to append the string. It is up to the
+ caller to ensure that this is large enough.
+@param aPixelFormat UID of the pixel format to be converted into a string.
+*/
+void AppendPixelFormat(TDes& aBuffer, TUidPixelFormat aPixelFormat)
+ {
+ if (aPixelFormat == EUidPixelFormatRGB_565)
+ aBuffer.Append(KPixelFormatRGB_565);
+ else if (aPixelFormat == EUidPixelFormatYUV_422Interleaved)
+ aBuffer.Append(KPixelFormatYUV_422Interleaved);
+ else if (aPixelFormat == EUidPixelFormatSpeedTaggedJPEG)
+ aBuffer.Append(KPixelFormatSpeedTaggedJPEG);
+ else if (aPixelFormat == EUidPixelFormatJPEG)
+ aBuffer.Append(KPixelFormatJPEG);
+ else
+ aBuffer.Append(KPixelFormatUnknown);
+ }
+
+void PrintCamModes(TCameraCapsV02* aCaps,RTest& aTest)
+ {
+ TBuf<80> buf;
+
+ // Display the supported capture modes
+ buf.Zero();
+ buf.Append(KCaptureModeCapsTitle);
+ if (aCaps->iNumImagePixelFormats)
+ buf.Append(KCaptureModeImage);
+ if (aCaps->iNumVideoPixelFormats)
+ buf.Append(KCaptureModeVideo);
+ if (aCaps->iNumViewFinderPixelFormats)
+ buf.Append(KCaptureModeViewFinder);
+ buf.Append(_L("\r\n"));
+ aTest.Printf(buf);
+
+ // Display the supported video pixel formats
+ TUint i;
+ SDevCamPixelFormat* pixelFormat;
+ if (aCaps->iNumImagePixelFormats)
+ {
+ buf.Zero();
+ buf.Append(KPixelFormatCapsTitle);
+ buf.Append(KCaptureModeImage);
+ pixelFormat = (SDevCamPixelFormat*) (aCaps + 1);
+ for (i = 0; i < aCaps->iNumImagePixelFormats; i++)
+ {
+ AppendPixelFormat(buf, pixelFormat->iPixelFormat);
+ pixelFormat++;
+ }
+ buf.Append(_L("\r\n"));
+ aTest.Printf(buf);
+ }
+
+ if (aCaps->iNumVideoPixelFormats)
+ {
+ buf.Zero();
+ buf.Append(KPixelFormatCapsTitle);
+ buf.Append(KCaptureModeVideo);
+ pixelFormat = (SDevCamPixelFormat*) (aCaps + 1);
+ for (i = aCaps->iNumImagePixelFormats; i < (aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats); i++)
+ {
+ AppendPixelFormat(buf, pixelFormat->iPixelFormat);
+ pixelFormat++;
+ }
+ buf.Append(_L("\r\n"));
+ aTest.Printf(buf);
+ }
+
+ if (aCaps->iNumViewFinderPixelFormats)
+ {
+ buf.Zero();
+ buf.Append(KPixelFormatCapsTitle);
+ buf.Append(KCaptureModeViewFinder);
+ pixelFormat = (SDevCamPixelFormat*) (aCaps + 1);
+ i = aCaps->iNumImagePixelFormats + aCaps->iNumImagePixelFormats + 1;
+ for (i = aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats; i < (aCaps->iNumImagePixelFormats + aCaps->iNumVideoPixelFormats + aCaps->iNumViewFinderPixelFormats); i++)
+ {
+ AppendPixelFormat(buf, pixelFormat->iPixelFormat);
+ pixelFormat++;
+ }
+ buf.Append(_L("\r\n"));
+ aTest.Printf(buf);
+ }
+ }
+
+void PrintCamConf(TCameraConfigV02& aConf,RTest& aTest)
+ {
+ TBuf<80> buf;
+
+ // Display the current frame size
+ buf.Zero();
+ buf.Append(KFrameSizeConfTitle);
+ buf.AppendFormat(KFrameSize, aConf.iFrameSize.iWidth, aConf.iFrameSize.iHeight);
+ buf.Append(_L("\r\n"));
+ aTest.Printf(buf);
+
+ // Display the current pixel format
+ buf.Zero();
+ buf.Append(KPixelFormatConfTitle);
+ AppendPixelFormat(buf, aConf.iPixelFormat.iPixelFormat);
+ buf.Append(_L("\r\n"));
+ aTest.Printf(buf);
+
+ // Display the current frame rate
+ buf.Zero();
+ buf.Format(_L("Current frame rate : %d fps\r\n"),aConf.iFrameRate);
+ aTest.Printf(buf);
+ }
+
+void PrintBufferConf(TMmSharedChunkBufConfig& aBufConf,RTest& aTest)
+ {
+ TBuf<80> buf(0);
+
+ SBufSpecList* tempSpec = aBufConf.iSpec;
+
+ // Display the buffer configuration
+ buf.Format(_L("Buffer Config : NumBufs:%d Size:%xH\r\n"),aBufConf.iNumBuffers,aBufConf.iBufferSizeInBytes);
+ aTest.Printf(buf);
+ if (aBufConf.iFlags & KScFlagBufOffsetListInUse)
+ {
+ buf.Format(_L(" Offsets[%08xH,%08xH,%08xH,%08xH]\r\n"),tempSpec[0].iBufferOffset,tempSpec[1].iBufferOffset,tempSpec[2].iBufferOffset,tempSpec[3].iBufferOffset);
+ aTest.Printf(buf);
+ buf.Format(_L(" Offsets[%08xH,%08xH,%08xH,%08xH]\r\n"),tempSpec[4].iBufferOffset,tempSpec[5].iBufferOffset,tempSpec[6].iBufferOffset,tempSpec[7].iBufferOffset);
+ aTest.Printf(buf);
+ }
+ }