Ladies and Gentlemen -

After much struggle, for anybody who's trying to get the SDK 2.0 CameraApp sample to work on the 6600, 6260, etc., here's some help:

1. You can't use the vanilla 2.0 SDK. You have to have at least the Nokia 6600 Camera Plugin (n6600_camera_plugin.zip). You can build the application perfectly fine with the 2.0 SDK, and it will run perfectly in the emulator, but it will crap and die on real phones. (This particular item has cost me three days of frustration on my own app. I finally backed off and fiddled the CameraApp to eliminate issues in my own code, and this was what I found out was "wrong" with my own app - the SDK, not the code.)

The Plugin seems to have later versions of the "ecam" libraries, DLL's, etc. If you already have the 2.0 SDK installed, that's OK - in fact, the plugin's documentation says that it needs it as a prerequisite. I don't know why, since it seems to include a full SDK of its own, but ours is not to question why...

Here's the environmentswitch section I use:
Code:
 <environment name="Nokia SDK 2.0 Camera 6600 Plug-in"> 
   <env key="EPOCROOT" action="replace" value="\Symbian\7.0s\Nokia_6600_Camera_Plugin\" registry="yes"/> 
   <env key="Path" action="append" value=";C:\Program Files\Microsoft Visual Studio\VC98\Bin;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin" registry="yes"/>
   <command value="devices -setdefault @Nokia_6600_Camera_Plugin:com.nokia.Nokia_6600_Camera_Plugin" binding="entry" outputwindow="yes"/> 
   <command value="devices -setdefault @Series60_v20:com.nokia.series60" binding="entry" outputwindow="yes"/> 
   <command value="cmd.exe /k title Series60 v2.0 Camera" directory="c:\Symbian\7.0s\Nokia_6600_Camera_Plugin\" binding="middlebutton"/> 
   <command value="cmd.exe /k title Series60 v2.0 Camera" directory="C:\Symbian\7.0s\Nokia_6600_Camera_Plugin\" binding="menu" caption="Shell"/> 
   <command value="epoc.exe -wins" binding="menu" caption="EPOC emulator"/> 
   <command value="msdev.exe" binding="menu" caption="VC++ 6.0"/> 
 </environment>
You don't have to use environmentswitch - when you install the plugin, it give you the option of making it the default SDK. I'm dealing with an app that I have to have run on both ecam and cameraserv implementations, so I have multiple SDK's that I switch back and forth between.

2. Nokia hard coded a path to a sound file in the application. The path points into the phone's ROM, and not all the phones have this file. (This was the topic of another thread here, so I can't take credit for that.) You can fix this by going into cameraappcontroller.cpp, and finding CreateSoundPlayerL, which is at about line 411. My solution to this was simply to #ifdef out the lines that actually tried to create the sound:

Code:
#if 0
    iSoundPlayer = (STATIC_CAST(CAknAppUi*,CEikonEnv::Static()->AppUi()))->KeySounds();
    if ( iSoundPlayer )
    {
        iSoundPlayer->AddAppSoundInfoListL( R_CAMERA_SNAP_SOUND );
    }
#else
    iSoundPlayer = NULL;
#endif
Other code in the class only actually uses the iSoundPlayer variable if it's non-null, so this quick fix keeps the program from barfing when it doesn't find the sound file, at the cost of the sample not playing a sound when you take a picture. Alternately, you could find your own sound, modify CameraApp.pkg to include it, and change the KCameraSoundFile item in CameraApp.rss to point to your sound file instead.

Another point about the ecam library that isn't well documented, but can be derived by examining the code - as far as I can see, when you're running in ViewFinder mode, the CFbsBitmap that you get passed via ViewFinderFrameReady() remains "owned" by the CCamera implementation, and gets re-used. Thus, if you hold on to a pointer to this, it will change on you, and you shouldn't delete on it. If you need a static copy of it, you'll have to copy it to another CFbsBitmap.

On the other hand, the CFbsBitmap that you are handed by ImageReady() becomes owned by you, and you're responsible for delete-ing it.

With CameraServ, you always provided the bitmap into which the camera server copied the result, so if you're adapting an app from CameraServ to Ecam this is something you'll have to watch out for.

FYI, what I did to manage the differences between the two versions in my app was to create an abstract class CCameraManager that represents my camera interface, and then created two derived concrete classes, one for CameraServ and one for Ecam. I then used a trick posted elsewhere on the forum:

Code:
#include <AknUtils.h>

#ifdef __SYMBIAN_6_
#include <cameraserv.h>
#else
#include <ecam.h>
#endif

#ifdef __CAMERA_SERV__
... CameraServ concrete class
#endif

#ifdef __ECAM_H__
... Ecam concrete class
#endif

CCameraManager* CCameraManager::NewL()
{
#ifdef __CAMERA_SERV__
        return(CameraServConcreteClass::NewL());
#else
        return(EcamConcreteClass::NewL());
#endif
}
The #ifdefs allow the particular platform to direct which version is compiled in. You still need different mmp files for the two versions, since there you need to link to different libraries, but at least you can use a single source set. You might be able to manage that by using multiple mmp files and combining them using #ifdefs in bld.inf, but I haven't mastered that yet.

Hopefully the above will help other people from suffering through the same pain that I did.