Showing posts with label BREW. Show all posts
Showing posts with label BREW. Show all posts

Monday, August 28, 2006

BREW: ICamera Interface

I have been meaning to write this post for quiet some time now and finally got around to finishing it. I am including a few tid bits in this post about the BREW ICamera Interface. The post is not meant to be a tutorial but could provide you a starting block if you are looking to add the camera functionality into your BREW Applet and then some.
For tutorials, I recommend the following:

  • Devx:Camera-enable Your Applications with BREW's ICamera APIs by Ray Rischpater.
    A nice short tutorial to get you started with the ICamera Interface. In case the above link is broken, try searching on Google or Devx.com for the article.
  • BREW forums
    If the above link does not work, search for ICamera and you will get plenty of posts with issues about the interface and also notes on how to solve them.
Ok ... Now that you have the links, lets check out the ICamera interface.

Determine Device Support:
The ICamera interface was introduced in BREW version 2.1. The support for the interface was slow initially but now pretty much any camera phone coming out supports the interface. To check for support before actually buying the device, take a look at the BREW specs (Data Sheet) for the device available through the Qualcomm BREW developer website. Usually there is a section called "Camera" in the spec sheet dedicated to camera access that provides information about:



  • Camera Available to BREW Applet.
  • Resolution (usually the native camera resolution).
  • Access to native photo directory.
  • Path of the native photo directory.

Creating the ICamera Interface Instance:
Let's start with the header files:

  • AEECamera.h: Provides the definitions of the ICamera interface and will have to be included in your build.
  • AEEBitmap.h: Provides the definitions of the IBitmap interface. The frame captured by the camera is returned as IBitmap, so this is important.
  • AEEMimeTypes.h: Contains the definitions of the mime types etc and you might need this if you are planning on taking snapshots etc...
To create an Instance of ICamera, we resort to the trusty ISHELL interface.
ICamera *m_pICamera = NULL;
int nRet = EBADPARM;
nRet = ISHELL_CreateInstance(pMe->iShell, AEECLSID_CAMERA, (void **)&m_pICamera);
If access to camera is supported and an instance was instantiated, the function returns SUCCESS. Other common codes returned include:
  • EBADPARM: Check the pointers you are passing to the function.
  • EUNSUPPORTED: You should really check the specs on the device before trying to instantiate the ICamera interface.
  • EPRIVLEVEL: This is weird but happens on certain devices. To avoid getting this return code, you can try adding a dependency for the camera in your MIF. More details on this here.
Once we have our instance of ICamera, the next thing to do would be to register a Callback function. All a developer has to do is to have a function that corresponds to the PFNCAMERANOTIFY specification.

typedef void (*PFNCAMERANOTIFY)(void* pUser, AEECameraNotify * pNotify);

The implementation of ICamera interface is Asynchronous similar to the other interfaces like IMedia and IWeb. The operation of the camera and the access to it revolves around the BREW layer notifying the Applet via the callback function. More information on this can be found in the BREW SDK documentation.The RegisterNotify function is used to register the Callback function.
/*Registering the callback function.
m_pICamera: Instance of ICamera created above
_CameraNotify: Callback Function
pMe: Pointer to the instance of the Applet.
You can pass anything here. This ptr will be returned in the
callback as the void pointer pUser. */
nRet = ICAMERA_RegisterNotify(m_pCamera, _CameraNotify, pMe);
For more details on the AEECameraNotify structure, refer to the BREW SDK documentation. I usually use the following members of the structure to determine the corresponding action in the callback function.
nStatus : The current status.
nCmd and nSubcmd: Gives an indication of the current camera mode.
//Generic Implementation of the callback function.void _CameraNotify(void * pUser, AEECameraNotify * pn)
{
//Get a handle to the reference pointer.
MyObj* pMe = (MyObj *) pUser;
if(!pMe !pn)
return;
//Handling based on Status passed.
switch(pn->nStatus)
{
case CAM_STATUS_START:
/*Sent when Preview or Record operation is started.*/
if(pn->nSubCmd == CAM_MODE_PREVIEW && pn->nCmd == CAM_CMD_START)
{
/*preview Mode has started.*/
}
if(pn->nSubCmd == CAM_MODE_SNAPSHOT &&pn->nCmd == CAM_CMD_START)
{
/* This is the first callback recieved when you initiate the Snapshot mode.*/
}
break;
case CAM_STATUS_DONE:
/* [Preview/Record/SetParm/GetParm/EncodeSnapshot]
Operation completed successfully.
For RecordSnapShot, pData = TRUE/FALSE = > Defered encode enabled/disabled
*/
if(pn->nSubCmd == CAM_MODE_PREVIEW && pn->nCmd == CAM_CMD_START)
{
/*Preview Mode has completed.*/
}
else if(pn->nSubCmd == CAM_MODE_SNAPSHOT && pn->nCmd == CAM_CMD_START)
{
/* Snapshot has been taken. In defer mode, the bitmap captured can be accessed here.
In default mode, you can wait for the snapshot encoding to finish.
if(pn->nSubcmd = = CAM_CMD_ENCODESNAPSHOT)*/
}
if(pn->nCmd == CAM_CMD_SETPARM)
{
/* When a parm such as Zoom etc has been set.*/
}
break;
case CAM_STATUS_FAIL:
/* [Preview/Record/SetParm/GetParm/EncodeSnapshot]
Operation failed pData = CAM_EXXX error code.
You can use the pn->nCmd andpn->nSubCmd to see exactly what operation failed. */
break;
case CAM_STATUS_ABORT:
/*The last operation was aborted. The camera is now in the ready state.*/
break;
case CAM_STATUS_FRAME:
/* [Any] Frame captured by camera. The frame can be accessed using ICAMERA_GetFrame()*/
break;
case CAM_STATUS_PAUSE:
/* [Preview/Record] Record movie paused.
This status is returned when you call ICAMERA_Pause()*/
break;
case CAM_STATUS_RESUME:
/* [Preview/Record] Record movie resumed.
AEECameraNotify::pData is IBitmap pointer representing the snapshot*/
break;
case CAM_STATUS_DATA_IO_DELAY:
/* [Preview/Record] Operation being delayed by data i/o access*/
break;
case CAM_STATUS_SPACE_WARNING:
/* [Record] Memory available to store recording running low.
To Do: Check if this applies to Snapshots too. Havent really checked this yet.*/
break;
}
}
Now that we have the different status codes that are returned in the Callback, lets check out the modes.

Starting the Camera (PREVIEW Mode)
J2ME developers will find the approach a bit different, there is NO Videocontrol :-). The developer is responsible for getting the captured frame from the instance and then blitting it on the LCD. The approach is very similar to the Series 60 API's and maybe microsoft smart phones (I am not sure).
Things to do:

  • Set the Size of the Preview Frame.
  • Start the Preview Mode.

Offcourse, there are bunch of Optional things you can do before starting the preview mode but remember, just cause its stated in the API, doesn't mean its supported on the phone.

The BREW API provides the developer a way to query the supported resolution for rendering the preview frames. Again, not all phones will support this method. The simplest way to set the size for the preview frames is to use the device LCD size. Since the frame has to be rendered on the device screen, might as well use this size(Japanese phones from KDDI do provide a preview frame of size larger than the LCD. But the frame is scaled when you blit it on the entire screen.). Using the device screen size gives the default preview size for the device.

static void initDisplaySizes(cameratest * pMe)
{
AEESize *ltSize;
int loop;
boolean bRet= FALSE;
int nRet = EFAILED;
//Get the Resolution available for the Preview Mode.
ltSize = (AEESize *)CAM_MODE_PREVIEW;
nRet = ICAMERA_GetDisplaySizeList(pMe->m_pICamera, if(SUCCESS != nRet)
{
// There was an error in getting the sizes. use the screen size.
return;
}
// Got the available sizes.
// Run through the loop and get the
// best resolution possible.
for(loop = 0 ; ltSize[loop].cx != NULL && ltSize[loop].cy != NULL ; loop++)
{
// Width: ltSize[loop].cx
// Height: ltSize[loop].cy
}
}
To start capturing and displaying the frames:
static void cameratest_DisplayCameraPreview(cameratest * pMe)
{
int nRet;
AEESize az;
// Setting the Display Size. Using Screen Size.
az.cx = pMe->cxScreen;
az.cy = pMe->cyScreen;
ICAMERA_SetDisplaySize(pMe->m_pICamera, &az);
// Start the Preview mode.
// This call will start the messages to be
// sent to the callback function.
nRet = ICAMERA_Preview(pMe->m_pICamera);
}
Once the Preview mode has started, a notification with the status CAM_STATUS_START is sent to the callback function. In case of error, a corresponding error status is sent. The individual frames captured by the camera are sent with the status CAM_STATUS_FRAME. The developer must implement logic here to display the frames on the screen.
void _CameraNotify(void *pUser, AEECameraNotify *pn)
{
cameratest * pMe = (cameratest *) pUser;
if(!pMe !pn)
return;
switch(pn->nStatus)
{
case CAM_STATUS_START:
//Preview mode has started. Do any applet specific
// stuff here.

break;
case CAM_STATUS_FRAME:
// A frame has been captured by the camera and
// is now available for rendering on the LCD.
IBitmap * pFrame; AEEBitmapInfo bi;
//Get the captured frame
ICAMERA_GetFrame(pMe->m_pICamera, &pFrame);
if (!pFrame)
break; //Error
//Get the bitmap info...
//IBITMAP_GetInfo(pFrame, &bi, sizeof(bi));
//Blitting the frame on theLCD from (0,0)
IDISPLAY_BitBlt(pMe->pIDisplay,0, 0,pMe->cxScreen, pMe->cyScreen, pFrame, 0, 0, AEE_RO_COPY);
// Release the Bitmap instance
IBITMAP_Release(pFrame);
//Update the Display
IDISPLAY_Update(pMe->pIDisplay);
break;
case CAM_STATUS_DONE:
// The camera has stopped the preview mode
// and has entered the ready state.

break;
}
}
To stop the camera in preview mode, use the ICAMERA_Stop() function. This will send the CAM_STATUS_DONE status to the callback function.

Adjusting Parameters:
Now that the camera is running in the preview mode, lets take a look at some of the control parameters available to the developer. Digital Zoom, Brightness, Contrast etc. Are some of the control parameters that are available through the BREW api. For the complete list check the SDK documentation. The SDK provides wrapper functions for adjusting these parameters and also checking if they are supported (ICAMERA_IsBrightness). I personally prefer using the ICAMERA_SetParm and ICAMERA_GetParm methods eventhough I am probably replicating code :-).
#define _CAM_MOV_UP 1 // Move one Step Up
#define _CAM_MOV_DOWN 2 // Move one Step down
#define _CAM_MOV_HIGH 4 // Move to highest
#define _CAM_MOV_LOW 8 // Move to the lowest

#define ADJUST_QUALITY(po, pDir) adjustParm(po, pDir,CAM_PARM_QUALITY)
#define ADJUST_ZOOM(po, pDir) adjustParm(po, pDir,CAM_PARM_ZOOM)
#define ADJUST_BRIGHTNESS(po, pDir) adjustParm(po, pDir,CAM_PARM_BRIGHTNESS)
#define ADJUST_CONTRAST(po, pDir) adjustParm(po, pDir,CAM_PARM_CONTRAST)
#define ADJUST_SHARPNESS(po, pDir) adjustParm(po, pDir,CAM_PARM_SHARPNESS)

static int adjustParm(cameratest * pMe, int pDirection, int parmID)
{
int nRet;
AEEParmInfo pi;
int32 p1;
int adj = 0; //Adjusted Value
//Get the Parm Value
nRet = ICAMERA_GetParm(pMe->m_pCamera,(int16) parmID, &p1,(int32 *)&pi);
/**@TODO: Handle CAM_PENDING */
if(SUCCESS = = nRet)
{
//Calculate the next step
switch(pDirection)
{
case _CAM_MOV_UP:
adj = pi.nCurrent + pi.nStep;
break;
case _CAM_MOV_DOWN:
adj = pi.nCurrent - pi.nStep;
break;
case _CAM_MOV_HIGH:
adj = pi.nMax;
break;
case _CAM_MOV_LOW:
adj = pi.nMin;
break;
default:
return EUNSUPPORTED;
}
//Set the New Value
nRet = ICAMERA_SetParm(pMe->m_pCamera,(int16) parmID,(int32) adj, 0);
}
return nRet;
}
To increase the digital zoom all I have to do is call ADJUST_ZOOM macro. I am uploading a zip file containing the source code of the application for the preview mode and also the ARM binaries. My development environment is Microsoft Windows .NET 2003. In case the link below does not work, shoot me an email and I will send you the zip file.
Download Sample Application 1

Taking Pictures:
The most obvious use of the ICAMERA interface in any applet is to take snapshots. The SNAPSHOT mode of the interface allows you to do this. One thing to remember is that the ICamera instance MUST be in the READY state for the operation to succeed.
Things to do:

  • Make sure the camera is in READY state. If you are in preview mode then call the ICAMERA_Stop() function to get there.
  • Set the Media data (ICAMERA_SetMediaData()).
  • Set the size of the picture to be taken (ICAMERA_SetSize()).
  • Set the encoding for the image (ICAMERA_SetVideoEncode()).
  • Adjust the quality of the picture to be taken (ICAMERA_SetQuality()).
  • Initiate the picture taking operation (ICAMERA_RecordSnapshot()).

Taking a snapshot is a 2 stage operation, the first step is the actual capturing of the frame and the second step deals with encoding the snapshot. Another mode, ENCODESNAPSHOT maintains the camera state when the encoding is being done.


static void takePicture(cameratest * pMe)
{
AEESize sz;
// 1) Set Media Data
pMe->md.clsData = MMD_FILE_NAME;
pMe->md.pData = "snap.jpeg" ; //Store the picture in the applet directory
pMe->md.dwSize = 0 ;
ICAMERA_SetMediaData(pMe->m_pICamera, &pMe->md , MT_JPEG);

// 2) Set the Size of the picture.
sz.cx = 320;
sz.cy = 240;
ICAMERA_SetSize(pMe->m_pICamera, &sz);

// 3) Adjust the Quality.
ADJUST_QUALITY(pMe, _CAM_MOV_HIGH);

// When needed set the Defer Encode mode. This will allow you
// to display the captured bitmap to the user before encoding it.
//ICAMERA_DeferEncode(pMe->m_pICamera, TRUE);

//Take a shot.
ICAMERA_Start(pMe->m_pICamera, CAM_MODE_SNAPSHOT, 0);
}
Since the Camera must be in the ready state when the snapshot mode has to be invoked, I recommend maintaining a applet level flag that is set when the user initiates the snapshot by pressing a key. Only the preview mode is stopped by the key press and the call to take the snapshot is made in the callback function when the CAM_STATUS_DONE for preview mode is returned.

Using the Defer Encode Mode:
The defer encode mode is a neat feature of the ICamera interface. It allows the developer to break down the taking picture operation into 2 distinct steps. When set, the picture taking operation stops after a frame has been captured by the camera. The applet can access the frame captured possibly to display a preview to the user or add some sort of graphics to it. To complete the picture taking operation, call the ICAMERA_EncodeSnapshot() method to finish the encoding.

To set the defer mode on, call ICAMERA_DeferEncode(pMe->m_pICamera, TRUE) method before invoking the snapshot. The captured frame can be accessed in the Callback function by calling the ICAMERA_GetFrame() function.

I am uploading a zip file containing the source code of the application for taking pictures and storing them in the applet directory on the device.Download Sample Application 2

Handling Suspend and Resume:
A brew Applet maybe suspended any time due an incoming call or ... Its completely upto the developer how he or she wants to handle this. Personally, I release the instance of ICamera when my applet is suspended and create it back again when the applet is resumed. Using the Pause mode of ICamera is another possibility however, I had some disturbing experiences with the pause mode earlier on and then never experimented.

One thing to keep in mind is In-comming calls while your applet has the ICamera interface in preview mode. The ringtone of the device does get distorted. I guess this has something to with the execution queue but not sure why. I have a Post on this that you can refer to for more details. I am looking for a better way to handle this, if you have any suggestions, please post them in the comments.

Movie Mode:
To be honest, haven't really found a phone that supports the movie mode. Its been some time since I actually was actively looking. If you know any device that allows a BREW applet to execute ICamera in movie mode then please do post it in the comments section of the post.

ICamera on the BREW Emulator:
The BREW SDK 2.1 emulators return EUNSUPPORTED while instantiating the ICamera interface. I did hear from someone that the 3.1 SDK's supported ICamera interface on the emulators using a webcam. Not sure about this. If some one did get this to work, then please do post your experience in the comments section.

Tuesday, August 02, 2005

ICAMERA_Pause() and ICAMERA_Resume()

Last week I was playing around with an applet that required me to pause the camera while it was in preview mode on a key press. Sounds simple enough !!!

To Pause the Camera

1) Check if the camera is in preview mode.

if(SUCCESS != ICAMERA_GetMode(pMe->m_pCamera, &lMode, &bPaused))
return;
if (CAM_MODE_PREVIEW == lMode && !bPaused)

{
//Pause the Camera
ICAMERA_Pause(pMe->m_pCamera);
}


2) The above call should return the status of CAM_STATUS_PAUSE in the callback
Function of the camera control. The AEECameraNotify structure will contain the following values.

nStatus = CAM_STATUS_PAUSE
nCmd = CAM_CMD_START
nSubCmd = CAM_MODE_PREVIEW


Do any thing that you want to do while the camera is paused here.


To Resume the Camera

1) The resume call will place the camera back in the preview mode. The process is similar to the call to the Pause function.

if(SUCCESS != ICAMERA_GetMode(pMe->m_pCamera, &lMode, &bPaused))
return;
if(CAM_MODE_PREVIEW == lMode && bPaused) //check for pause
{
//Resume the Camera
ICAMERA_Resume(pMe->m_pCamera);
}


2) The above call returns the status CAM_STATUS_RESUME in the callback function of the camera control. The AEECameraNotify structure will contain the following values.

nStatus = CAM_STATUS_RESUME
nCmd = CAM_CMD_START
nSubCmd = CAM_MODE_PREVIEW

Once you receive this callback, the applet should automatically start receiving the callbacks with CAM_STATUS_FRAME.

Handling Suspend (EVT_SUSPEND) and Resume (EVT_RESUME) Events.

Conventional wisdom dictates stopping the camera altogether and releasing the reference to the ICamera interface when your applet receives a EVT_SUSPEND event.

NEVER NEVER NEVER let your applet release the reference to the ICamera interface when the camera is in paused state. When you receive the EVT_SUSPEND event make sure the camera is not in the paused state, if it is then put in a call to ICAMERA_Resume(). Do not know if this is a bug or a feature (J) in the ICamera but once you put the camera in the pause state and release the reference, you need to restart the device to be able to use the camera again.

case EVT_SUSPEND:
if(SUCCESS == ICAMERA_GetMode(pMe->m_pCamera, &lMode, &bPaused))
{

if(CAM_MODE_PREVIEW == lMode && bPaused)
{
ICAMERA_Resume(pMe->m_pCamera);
}
}
//you could call ICamera_Stop(), but it works without it.
ICAMERA_Release(pMe->m_pCamera);
pMe->m_pCamera = NULL;
//Always a good idea to null it out.
return TRUE;

Friday, July 01, 2005

ICamera Preview Mode: Recieve SMS or In coming call

Got my app back from NSTL stating this bug:
" If the application has the camera in the preview mode and an incoming voice call is received, then the handset’s ringer is distorted. "


For some reason when the ICamera is in the preview mode, it shuts off the ringer on Moto V265. Havent actually figured out why this is happening ... dont know how I can figure this out either. The native camera application on the handset does exhibit the same behavior. My application displays the notification on the screen but just shuts of the ringer.
This is something I will have to look at in the future and try it out with the other handsets but for now a temporary fix ( thanks to Ilho) has done the job. When I start the camera I register for a notification:


ISHELL_RegisterNotify(pMe->pIShell, AEECLSID_MYAPPLET_ID,AEECLSID_TAPI, NMASK_TAPI_STATUS NMASK_TAPI_SMS_TEXT);


and when I stop the camera internally, I unregister for the notification:

ISHELL_RegisterNotify(pMe->pIShell, AEECLSID_MYAPPLET_ID, AEECLSID_TAPI, 0);


In my main applet handle event function I have dumped in some code to shutt off the camera as soon as you get an incoming SMS or Phone call.


case EVT_NOTIFY: {

AEENotify * ns = (AEENotify *)dwParam;

if(NMASK_TAPI_STATUS == ns->dwMask NMASK_TAPI_SMS_TEXT == ns->dwMask){

//Shut off the camera and show a pause screeen

// If user accepts the incoming call or reads the message then the applet

// will recieve a EVT_SUSPEND event. Else have the Select key ready to

// activate the camera on the pause screen.

}
return TRUE;
}


Note: Set the privelege level in the MIF to have access to TAPI.

Monday, May 09, 2005

KDDI devices Rock

Have been playing around a KDDI device ( W2SSA) for the last week or so and I am just wonder struck right now. The implementation of the BREW API speically the ICamera interface is just perferct. Havent seen a device yet that supported so many of the parameters that are mentioned in the BREW API. The specs too are very detailed, the only down side ... all the info available on the phone is in Japanese. Its been tough trying to translate the Japanese into English using the google language translator service.

Here are a few titbits... the default size to run the preview mode is 320 * 240 pixels ... snaps go upto 1280 *960 pixel resolution. The camera on the device has a autofocus that can be controlled through the code.

For a complete list of the device refer to http://www.au.kddi.com/english/product/index.html

Tuesday, March 01, 2005

LGE VX8000 and ICamera (Brew)

Have been trying to get my app working on LGE VX8000 and was facing all sorts of issues starting with finding the drivers for the USB cable. For some reason the drivers for LG VX6000 dont work too well with the VX 8000. Got hold of the drivers for VX 7000 from LG(Click on the link for USB Modem Driver) website and it works like a charm now.

But another issue was that I couldn't get ICamera to work on the phone. The device kept throwing out the error code EPRIVLEVEL when I tried to create an instance of ICamera in my code. Finally found out how to avoid that. In the MIF a dependency has to be added to the class Id AEECLSID_CAMERA. All I had to do was create a bid file camera.bid and add that to the MIF file in the dependencies tab. I have included the text of camera.bid below:

-------------Camera.bid--------

#ifndef CAMERA_BID#define CAMERA_BID
#define AEECLSID_CAMERA 0x01002013
#endif //CAMERA_BID

--------------------------------------

Feels good to finally be able to play around with the phone. The device has a lot of promise and the screen size is as big as the series 60 devices. Will post more about the phone in the days to come.

Wednesday, February 23, 2005

IHtmlViewer - Input Mode for Data (Brew)

My frustration continues with IHtmlViewer in my BREW application. I have a HTML Form that I want the user to fill out. Some of the fields can be only numeric and it becomes a pain if the user has to use the Multi- tap input mode for this.

The viewer operates in 2 modes - the Inline edit mode and the normal mode (Each field opens up in another window). In the second mode it does allow the user to change the input mode but I would prefer using the inline edit mode.

Have searched through the API and I cannot seem to find a single method that would set the Input mode. Offcourse I can do that for a ITextCtl that I create but not for IHTMLViewer. I can see why it was designed in such a way but that doesnt help me :-(.

Thursday, January 06, 2005

Dynamic Interfaces with IHtmlViewer (Brew)

Was playing around with generating a different User interface generating different user interfaces dynamically using the IHTMLVIEWER interface. I must say I wish there was a similar class in J2ME and Series 60. Its just to easy. Have the HTML file on the server. When the applet launches for the first time, download and store the html code in a file on the handset. Now that you have the html file, load it into an instance of the viewer and set it to active. Walah ! you have a complete display that can be altered based on the html file that you download.

There are other ways to do it but this way is just so dam simple. Took me about half a day to set up for my purpose. There are a few limitations though - In forms you cannot set the input mode for text boxes and the html tag list is only HTML 3.2 compliant. There might be others but these are the ones I noticed so far. Just glad to have got the job done with so little effort. :-)...

looking forward to a weekend at my sisters place... great food and no worries!

Saturday, December 11, 2004

ICamera Interface - Preview Mode

The preview mode is well documented in the documentation provided along with the QualComm SDK. I prefer using the API documentation provided in the PDF format rather than the compiled help in .chm format. The sample code provided in the .chm file that came with my copy of the SDK(2.1) had some errors in it specially the ICAMERA_GetFrame() function.
To implement it in my applet I just the took the code from the SDK documentation to get started. I added a pointer to the ICamera interface in my Applet structure. I prefer not to have a AEEDeviceInfo structure in my applet so I just include the width and height of the screen in the applet.





typedef struct _cameratest{
AEEApplet a;// First element of this structure must be AEEApplet
IDisplay *pIDisplay;
IShell *pIShell;
EAppStateType m_eAppState; // Current Application State
EAppStateType m_ePrevState;
uint16 cxScreen;// Width of the handset screen
uint16 cyScreen;// Height of the handset screen
IMenuCtl *m_pMainMenu;
ICamera *m_pICamera; // ptr to the camera
} cameratest;

To Start the Camera I use a function that will initialize the parameters and start the camera in the preview mode. Most important thing is to initialize a callback and pass the AEECameraNotify structure. Since Camera access is done asynchronously in BREW (very much like other platforms) the callback serves an important role.




static void cameratest_DisplayCameraPreview(cameratest * pMe)
{
int nErr;
AEESize az;
pMe->m_eAppState = APP_STATE_CAM_PREVIEW;
if (ISHELL_CreateInstance(pMe->pIShell, AEECLSID_CAMERA , (void**)(&pMe->m_pICamera)) != SUCCESS)
return;
// Register callback notification function.
nErr = ICAMERA_RegisterNotify(pMe->m_pICamera, cameratest_CameraNotify, pMe);
if (nErr)
{
DBGPRINTF("ERROR IN REGISTERING CALL BACK %d", nErr);
Cameratest_goBack(pMe->m_eAppState);
return;
}
az.cx = pMe->cxScreen;
az.cy = pMe->cyScreen;
ICAMERA_SetDisplaySize(pMe->m_pICamera, &az);
nErr = ICAMERA_Preview(pMe->m_pICamera);
if (nErr)
{
DBGPRINTF("ERROR in initiating preview %d", nErr);
return;
}
}

Every display function must have a hide function. To stop the Preview mode all we need to do is call the ICAMERA_Stop() function.





static void cameratest_HideCameraPreview(cameratest * pMe)
{
if(ICAMERA_Stop(pMe->m_pICamera) == SUCCESS)
DBGPRINTF("STOP COMMAND ACCEPTED");
}

The call back function is where the real stuff happens. Once the Camera is ready the OS will call the callback function that we had registered earlier. The AEECameraNotify structure contains a bunch of info about the callback. In the preview mode the first callback will have the status CAM_STATUS_START with nCmd = CAM_CMD_START and nSubCmd = CAM_MODE_PREVIEW. The frames captured from the camera are sent to the callback at regular intervals ( depends on the fps) and you can capture the frame of data using ICAMERA_GetFrame() function. The interface does not display the frames on the screen much like the API in series 60 so you have to display them yourself.




static void cameratest_CameraNotify(void * pUser, AEECameraNotify * pn)
{
cameratest * pMe = (cameratest *)pUser;
if (!pMe !pn)
return;
switch (pn->nStatus)
{
case CAM_STATUS_START:
// Preview has begun...
break;
case CAM_STATUS_FRAME:
{
IBitmap * pFrame;
AEEBitmapInfo bi; // // IMPORTANT NOTE: You need to do IBITMAP_Release(pFrame) after you're done with pFrame.
pFrame = ICAMERA_GetFrame(pMe->m_pICamera, &pFrame);
if (!pFrame)
{
DBGPRINTF("DID not get FRAME");
break;
}
// Get the bitmap info...this can be saved in app global structure.
IBITMAP_GetInfo(pFrame, &bi, sizeof(bi));
// Display the frame at (0, 0) location of the screen
IDISPLAY_BitBlt(pMe->pIDisplay, 2, 2, bi.cx, bi.cy, pFrame, 0, 0, AEE_RO_COPY);
IBITMAP_Release(pFrame);
IDISPLAY_Update(pMe->pIDisplay);
}
break;
case CAM_STATUS_DONE:
break;
case CAM_STATUS_ABORT:
// Preview got aborted.
break;
}
}

Off course in the production version of the code you will have to take care of some additional things. The documentation advises to make sure that when the applet receives a EVT_PAUSE event – make sure you shut down the preview mode. Also it would be a wise move to put in some code for the other status codes in the callback like CAM_STATUS_ABORT, CAM_STATUS_DATA_IO_DELAY etc.

ICamera Interface .....

ICamera interface provides access to the camera features of the handset. It is can be used in devices that support BREW version 2.1 and above. There is a catch to it though some devices are version 2.1 and above and have a onboard camera but the ICamera interface is blocked ( mostly due to carrier influence? don?t want to share the picture messaging revenue).

In States we recently have a few devices(Not all of them might be out)
Moto V265(This is the one that I have),LG VX7000,Moto V710 and LG VX8000. These do support the ICamera interface and are available with Verizon wireless? There might be others ..but haven?t had a chance to look at them.


Spent the last couple of days working on it. There are three modes that the ICamera interface can be used in Preview Mode, SnapShot Mode, Movie Mode. Havent tried out the movie mode .. but played around with the Preview mode and the snapshot mode and thanks to the some help by folks at the Qualcomm Brew forums have some code ready.


Sunday, November 21, 2004

Issues with installing Hello World Applet on the phone

Well .. I am nearly at the end of the development cycle in my project. Have all the GUI and logic figured out. Now, all that’s left is the Camera module. Unfortunately the ICamera interface cannot be instantiated on the emulator. I have tried with the V625 ( the device I am developing for) emulator and it doesn’t work.

So the next step will be to port my app on the device and test and debug from there. I found this excellent thread at the BREW forums with all the info required to create the mod file. Hats off to Tyndal.

You can access the thread
here.

The only thing stopping me from actually deploying a Applet on the phone now is the drivers for the data cable for the Moto v26x series. The OS detects that it’s a device from the V26x series but just doesn’t find the drivers anywhere. I haven’t been able to find them anywhere on the web either.

Just cant wait to have a complete BREW applet run on the device. They say it gets easier after the first one. Its been three weeks since i started coding in BREW and though the programming part is something that i have gotten used to (its really just C) the other part about the device and stuff is a royal pain in the A**.