Yes, I would definitely go down the IwGx route. s3eSurface can be very slow on modern hardware (e.g. iOS platforms in particular).
Start by creating an instance of CIwTexture, disabling mip maps and making it modifiable.
CIwTexture* lpTexture = new CIwTexture;
lpTexture->SetModifiable(true);
lpTexture->SetMipMapping(false);
Initialise the callback method
s3eCameraRegister(S3E_CAMERA_UPDATE_STREAMING, (s3eCallback) MyFrameDataCallback, NULL);
Start the camera running and ask it to convert to RGB565 when it receives a frame. You should vary the requested size and quality hints depending on your usage. This is a bit trial and error as it depends on what the hardware supports.
s3eCameraStart(S3E_CAMERA_STREAMING_SIZE_HINT_LARGEST, S3E_CAMERA_PIXEL_TYPE_RGB565_CONVERTED, S3E_CAMERA_STREAMING_QUALITY_HINT_HIGH);
Then in the camera frame callback update the texture
lpTexture->CopyFromBuffer(apFrame->m_Width, apFrame->m_Height, CIwImage::RGB_565, apFrame->m_Pitch, (uint8*) apFrame->m_Data, 0);
lpTexture->Upload();
apFrame is the pointer to the s3eCameraFrameData structure that gets passed into the callback function as the first parameter. You'll need to do the copy in the callback as the data will cease to exist once your callback finishes, but you might want to defer the Upload so you only perform it once per loop of your application.
Now all you need to do is create a CIwMaterial, make it use the above texture and render a textured quad onto the screen. I'll leave that code to you as it's pretty straight forward!