Hello Paul,
Sorry for late response. It was a busy week.
OnDraw()/OnUpdate() approach is the best fit for my application. I can have full fps from camera stream. We already designed a new hardware with ARGB8888 camera stream. Hope it will give me more CPU time for other tasks.
At this point, my question is answered perfectly.
Only problem is syncing the video stream and EW copy operation. I am having some issues because of VSYNC problems. I beleive I can solve this problem with double buffering..
I add my code snippets as a reference for others.
Thnx.
Aykut
C Code (ew_bsp_camera.h)
/*
* ew_bsp_camera.h
*
*/
#ifndef EW_BSP_CAMERA_H_
#define EW_BSP_CAMERA_H_
#include "ewrte.h"
#include "ewgfxdriver.h"
#include "ewgfx.h"
#include "ewextgfx.h"
#include "ewgfxdefs.h"
#include "ewextpxl_RGBA8888.h"
#include "ewlocale.h"
#include <string.h>
#include "Graphics.h"
#include "Application.h"
#include "ew_bsp_graphics.h"
#include "camera.h"
typedef struct {
XPoint Size;
XRect lockArea;
XRect updateArea;
XBitmapLock* lock;
unsigned long LastTime;
int NeedUpdate;
} ew_bsp_camera_t;
XHandle *CameraInit(XPoint aSize);
XRect* CameraUpdate(XHandle * aCamera);
XHandle *CameraProgress(XHandle *aCamera);
XBitmap* CameraGetBitmap(XHandle * aCamera);
void CameraDraw(XHandle aCamera, GraphicsCanvas aCanvas, XRect aClip,
XRect aDstRect, XColor aColorTL, XColor aColorTR, XColor aColorBR,
XColor aColorBL, XBool aBlend);
void CameraDone(XHandle * aCamera);
uint32_t guiGetFramePeriod(void);
#endif /* EW_BSP_CAMERA_H_ */
C Code (ew_bsp_camera.c)
/* Include necessary header files */
#include "ew_bsp_camera.h"
volatile uint32_t gui_frame_time = 0;
volatile uint32_t gui_frame_period = 0;
XHandle *CameraInit(XPoint aSize) {
/* Reserve memory for the new camera instance */
ew_bsp_camera_t* camera = EwAlloc(sizeof(ew_bsp_camera_t));
if (!camera) {
if (camera)
EwFree(camera);
return 0;
}
/* ... and initialize it */
camera->Size = aSize;
camera->LastTime = 0;
camera->NeedUpdate = 1;
camera->updateArea.Point1.X = 0;
camera->updateArea.Point1.Y = 0;
camera->updateArea.Point2.X = 0;
camera->updateArea.Point2.Y = 0;
camera->lockArea.Point1.X = 0;
camera->lockArea.Point1.Y = 0;
cameraInit(CAMERA_FRAME_BUFFER, 384, 480, FRAME_BUFFER_ADDR,
FRAME_BUFFER_WIDTH, FRAME_BUFFER_HEIGHT, 208, 0);
camera->lockArea.Point2.X = cameraGetHeight();
camera->lockArea.Point2.Y = cameraGetWidth();
cameraContinuousStart(CAMERA_FRAME_BUFFER);
return (XHandle *) camera;
}
XRect* CameraUpdate(XHandle * aCamera) {
ew_bsp_camera_t* camera = (ew_bsp_camera_t*) aCamera;
if (cameraIsNewFrame() && !camera->NeedUpdate) {
camera->NeedUpdate = true;
return &(camera->lockArea); //update
}
return &(camera->updateArea); // Do not update
}
void CameraDone(XHandle * aCamera) {
ew_bsp_camera_t* camera = (ew_bsp_camera_t*) aCamera;
if (camera) {
EwFree(camera);
}
cameraSuspend();
cameraStop();
}
void CameraDraw(XHandle aCamera, GraphicsCanvas aCanvas, XRect aClip,
XRect aDstRect, XColor aColorTL, XColor aColorTR, XColor aColorBR,
XColor aColorBL, XBool aBlend) {
ew_bsp_camera_t* camera = (ew_bsp_camera_t*) aCamera;
/* Lock the entire bitmap for write operation */
gui_frame_period = HAL_GetTick() - gui_frame_time;
gui_frame_time += gui_frame_period;
{
cameraWaitVsync();
camera->lock = EwLockBitmap((XBitmap*) (aCanvas->Super1.bitmap), 0,
camera->lockArea, 0, 1);
cameraChangeDisplayFrameBufferAddress(camera->lock->Pixel1);
void *buf = (void *) camera->lock->Pixel1;
uint32_t line_offset = FRAME_BUFFER_WIDTH - aDstRect.Point2.Y
+ aDstRect.Point1.Y;
EwBspGraphicsCopy((uint32_t) buf, cameraGetFrameBuffer(), line_offset,
0, 384, 480, DMA2D_ARGB8888, DMA2D_INPUT_RGB565);
EwUnlockBitmap(camera->lock);
}
camera->NeedUpdate = false;
}
uint32_t guiGetFramePeriod(void) {
return gui_frame_period;
}
Chora Code
class CameraAppletClass : Views::Applet
{
$rect <460,200,600,240>
inherited method OnDraw()
{
$if (!$prototyper)
native
{
CameraDraw(aHandle,aCanvas,aClip,aDstRect,aColorTL,aColorTR,aColorBR,aColorBL,aBlend);
}
$else
aHandle;
aColorTL;
aColorTR;
aColorBR;
aColorBL;
aBlend;
// If the applet appears in a separate layer - a transparent gap in the UI layer
// is needed in order to make the separate layer visible
aCanvas.FillRectangle( aClip, aDstRect, #00000000, #00000000, #00000000,
#00000000, false );
$endif
}
$rect <460,150,610,190>
inherited method OnUpdate()
{
$if (!$prototyper)
var rect area = <0,0,0,0>;
native ( aHandle, area )
{
XRect *t = (XRect *)CameraUpdate(aHandle );
area.Point1.X = t->Point1.X;
area.Point1.Y = t->Point1.Y;
area.Point2.X = t->Point2.X;
area.Point2.Y = t->Point2.Y;
}
return area;
$else
return this.Bounds.area;
$endif
}
$rect <10,60,160,100>
inherited method OnDestroy()
{
// TO DO: Write your code here ...
native {
CameraDone(aHandle);
}
}
$rect <10,10,160,50>
inherited method OnCreate()
{
var handle p=null;
native (aSize)
{
p = CameraInit(aSize);
};
this.ProgressTimer.Period=10;
this.ProgressTimer.Enabled=true;
return p;
}
// The Done() destructor forces the deinitialization of the infrastructure inherited \
// from the base class Views::Applet.
$rect <160,140,380,180>
method void Done()
{
// When the object is disposed - destroy the embedded application
//
// Destroy() will then call the OnDestroy() method.
Destroy();
}
// The Init() constructor forces the initialization of the infrastructure inherited \
// from the Views::Applet class.
$rect <160,100,380,140>
method void Init( arg uint32 aArg )
{
// After the object has been created - initialize the external 'C' application.
//
// Create() will then call the OnCreate() method.
Create();
}
}
$rect <730,20,930,60>
inline Inline
{
#include "ew_bsp_camera_ext.h"
}