Permalink
Browse files

Update camera samples to work with 10.0.6

  • Loading branch information...
1 parent 96e588c commit 0dab64d79b7704f82975b03ed76ae2e720a7e900 Sean McVeigh committed Jul 18, 2012
View
4 HelloCamera/.project
@@ -18,7 +18,7 @@
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
- <value>Device-Release</value>
+ <value>Device-Debug</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
@@ -50,7 +50,7 @@
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
- <value>Device-Release</value>
+ <value>Device-Debug</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
View
91 HelloCamera/src/hellocameraapp.cpp
@@ -35,18 +35,35 @@ HelloCameraApp::HelloCameraApp() :
qDebug() << "HelloCameraApp";
// create our foreign window
- // NOTE: there is a bug in 10.0.4 which forces us to re-create the
- // foreign window whenever the backing screen window is detached.
// Using .id() in the builder is equivalent to mViewfinderWindow->setWindowId()
mViewfinderWindow = ForeignWindow::create()
.id(QString("cameraViewfinder"));
+ // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby the
+ // SCREEN_PROPERTY_SOURCE_SIZE is updated when windows are attached.
+ // We don't want this to happen, so we are disabling WindowFrameUpdates.
+ // What this means is that if the ForeignWindow geometry is changed, then
+ // the underlying screen window properties are not automatically updated to
+ // match. You will have to manually do so by listening for controlFrameChanged
+ // signals. This is outside of the scope of this sample.
+ mViewfinderWindow->setWindowFrameUpdateEnabled(false);
+
QObject::connect(mViewfinderWindow,
SIGNAL(windowAttached(unsigned long,
const QString &, const QString &)),
this,
SLOT(onWindowAttached(unsigned long,
const QString &,const QString &)));
+ // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby
+ // when a window is detached, it's windowHandle is not reset to 0.
+ // We need to connect a detach handler to implement a workaround.
+ QObject::connect(mViewfinderWindow,
+ SIGNAL(windowDetached(unsigned long,
+ const QString &, const QString &)),
+ this,
+ SLOT(onWindowDetached(unsigned long,
+ const QString &,const QString &)));
+
// create a bunch of camera control buttons
// NOTE: some of these buttons are not initially visible
mStartFrontButton = Button::create("Front Camera");
@@ -106,16 +123,36 @@ void HelloCameraApp::onWindowAttached(unsigned long handle,
{
qDebug() << "onWindowAttached: " << handle << ", " << group << ", " << id;
screen_window_t win = (screen_window_t)handle;
- // make the window visible. by default, the camera creates an invisible
- // viewfinder, so that the user can decide when and where to place it
- int i = 1;
- screen_set_window_property_iv(win, SCREEN_PROPERTY_VISIBLE, &i);
// set screen properties to mirror if this is the front-facing camera
- i = (mCameraUnit == CAMERA_UNIT_FRONT);
+ int i = (mCameraUnit == CAMERA_UNIT_FRONT);
screen_set_window_property_iv(win, SCREEN_PROPERTY_MIRROR, &i);
// put the viewfinder window behind the cascades window
i = -1;
screen_set_window_property_iv(win, SCREEN_PROPERTY_ZORDER, &i);
+ // make the window visible. by default, the camera creates an invisible
+ // viewfinder, so that the user can decide when and where to place it
+ i = 1;
+ screen_set_window_property_iv(win, SCREEN_PROPERTY_VISIBLE, &i);
+ // There is a bug in ForeignWindow in 10.0.6 which defers window context
+ // flushing until some future UI update. As a result, the window will
+ // not actually be visible until someone flushes the context. This is
+ // fixed in the next release. For now, we will just manually flush the
+ // window context.
+ screen_context_t ctx;
+ screen_get_window_property_pv(win, SCREEN_PROPERTY_CONTEXT, (void**)&ctx);
+ screen_flush_context(ctx, 0);
+}
+
+
+void HelloCameraApp::onWindowDetached(unsigned long handle,
+ const QString &group,
+ const QString &id)
+{
+ qDebug() << "onWindowDetached: " << handle << ", " << group << ", " << id;
+ // There is a bug in ForeignWindow in 10.0.6 whereby the windowHandle is not
+ // reset to 0 when a detach event happens. We must forcefully zero it here
+ // in order for a re-attach to work again in the future.
+ mViewfinderWindow->setWindowHandle(0);
}
@@ -136,6 +173,7 @@ int HelloCameraApp::createViewfinder(camera_unit_t cameraUnit,
return EIO;
}
qDebug() << "camera opened";
+ // configure viewfinder properties so our ForeignWindow can find the resulting screen window
if (camera_set_photovf_property(mCameraHandle,
CAMERA_IMGPROP_WIN_GROUPID, group.toStdString().c_str(),
CAMERA_IMGPROP_WIN_ID, id.toStdString().c_str()) == CAMERA_EOK) {
@@ -163,8 +201,18 @@ void HelloCameraApp::shutterCallback(camera_handle_t handle,
{
qDebug() << "shutterCallback";
- // LEGAL REQUIREMENTS DICTATE THAT ALL CAMERA APPS MUST PRODUCE AN AUDIBLE
- // SHUTTER SOUND. DO THIS, OR YOUR APP WILL BE PULLED FROM APP WORLD.
+ // THE CAMERA SERVICE DOES NOT PLAY SOUNDS WHEN PICTURES ARE TAKEN OR
+ // VIDEOS ARE RECORDED. IT IS THE APP DEVELOPER'S RESPONSIBILITY TO
+ // PLAY AN AUDIBLE SHUTTER SOUND WHEN A PICTURE IS TAKEN AND WHEN VIDEO
+ // RECORDING STARTS AND STOPS. NOTE THAT WHILE YOU MAY CHOOSE TO MUTE
+ // SUCH SOUNDS, YOU MUST ENSURE THAT YOUR APP ADHERES TO ALL LOCAL LAWS
+ // OF REGIONS WHERE IT IS DISTRIBUTED. FOR EXAMPLE, IT IS ILLEGAL TO
+ // MUTE OR MODIFY THE SHUTTER SOUND OF A CAMERA APPLICATION IN JAPAN OR
+ // KOREA.
+ // TBD:
+ // RIM will be providing clarification of this policy as part of the
+ // NDK developer agreement and App World guidelines. A link will
+ // be provided when the policy is publicly available.
soundplayer_play_sound("event_camera_shutter");
// this is just here to silence a compiler warning
@@ -211,7 +259,6 @@ void HelloCameraApp::onStartFront()
{
qDebug() << "onStartFront";
if (mViewfinderWindow) {
- // create a window and see if we can catch the join
if (createViewfinder(CAMERA_UNIT_FRONT,
mViewfinderWindow->windowGroup().toStdString().c_str(),
mViewfinderWindow->windowId().toStdString().c_str()) == EOK) {
@@ -224,7 +271,6 @@ void HelloCameraApp::onStartRear()
{
qDebug() << "onStartRear";
if (mViewfinderWindow) {
- // create a window and see if we can catch the join
if (createViewfinder(CAMERA_UNIT_REAR,
mViewfinderWindow->windowGroup().toStdString().c_str(),
mViewfinderWindow->windowId().toStdString().c_str()) == EOK) {
@@ -237,27 +283,11 @@ void HelloCameraApp::onStopCamera()
{
qDebug() << "onStopCamera";
if (mCameraHandle != CAMERA_HANDLE_INVALID) {
+ // NOTE that closing the camera causes the viewfinder to stop.
+ // When the viewfinder stops, it's window is destroyed and the
+ // ForeignWindow object will emit a windowDetached signal.
camera_close(mCameraHandle);
mCameraHandle = CAMERA_HANDLE_INVALID;
- // This is a HACK
- // ForeignWindow currently does not properly handle detach events,
- // so there is no way to disconnect and reconnect a screen window to it.
- // Instead, we have to delete the old ForeignWindow instance, and dynamically
- // create a new one to replace it.
- // We can use Container::replace() to do this.
- ForeignWindow *oldViewfinderWindow = mViewfinderWindow;
- mViewfinderWindow = ForeignWindow::create()
- .id(QString("viewfinderWindow"));
- mViewfinderWindow->setWindowId(QString("cameraViewfinder"));
- Container *container = (Container*)oldViewfinderWindow->parent();
- container->replace(container->indexOf(oldViewfinderWindow), mViewfinderWindow);
- delete oldViewfinderWindow;
- QObject::connect(mViewfinderWindow,
- SIGNAL(windowAttached(unsigned long,
- const QString &, const QString &)),
- this,
- SLOT(onWindowAttached(unsigned long,
- const QString &,const QString &)));
// reset button visibility
mTakePictureButton->setVisible(false);
mStopButton->setVisible(false);
@@ -269,6 +299,7 @@ void HelloCameraApp::onStopCamera()
void HelloCameraApp::onTakePicture()
{
+ int x[2];
qDebug() << "onTakePicture";
if (mCameraHandle != CAMERA_HANDLE_INVALID) {
camera_take_photo(mCameraHandle,
View
3 HelloCamera/src/hellocameraapp.hpp
@@ -33,6 +33,9 @@ public slots:
void onWindowAttached(unsigned long handle,
const QString &group,
const QString &id);
+ void onWindowDetached(unsigned long handle,
+ const QString &group,
+ const QString &id);
void onStartFront();
void onStartRear();
void onStopCamera();
View
1 HelloVideoCamera/.cproject
@@ -206,4 +206,5 @@
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
</storageModule>
+ <storageModule moduleId="refreshScope"/>
</cproject>
View
92 HelloVideoCamera/src/hellovideocameraapp.cpp
@@ -38,18 +38,35 @@ HelloVideoCameraApp::HelloVideoCameraApp() :
qDebug() << "HelloVideoCameraApp";
// create our foreign window
- // NOTE: there is a bug in 10.0.4 which forces us to re-create the
- // foreign window whenever the backing screen window is detached.
// Using .id() in the builder is equivalent to mViewfinderWindow->setWindowId()
mViewfinderWindow = ForeignWindow::create()
.id(QString("cameraViewfinder"));
+ // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby the
+ // SCREEN_PROPERTY_SOURCE_SIZE is updated when windows are attached.
+ // We don't want this to happen, so we are disabling WindowFrameUpdates.
+ // What this means is that if the ForeignWindow geometry is changed, then
+ // the underlying screen window properties are not automatically updated to
+ // match. You will have to manually do so by listening for controlFrameChanged
+ // signals. This is outside of the scope of this sample.
+ mViewfinderWindow->setWindowFrameUpdateEnabled(false);
+
QObject::connect(mViewfinderWindow,
SIGNAL(windowAttached(unsigned long,
const QString &, const QString &)),
this,
SLOT(onWindowAttached(unsigned long,
const QString &,const QString &)));
+ // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby
+ // when a window is detached, it's windowHandle is not reset to 0.
+ // We need to connect a detach handler to implement a workaround.
+ QObject::connect(mViewfinderWindow,
+ SIGNAL(windowDetached(unsigned long,
+ const QString &, const QString &)),
+ this,
+ SLOT(onWindowDetached(unsigned long,
+ const QString &,const QString &)));
+
// create a bunch of camera control buttons
// NOTE: some of these buttons are not initially visible
mStartFrontButton = Button::create("Front Camera");
@@ -107,8 +124,8 @@ HelloVideoCameraApp::~HelloVideoCameraApp()
void HelloVideoCameraApp::onWindowAttached(unsigned long handle,
- const QString &group,
- const QString &id)
+ const QString &group,
+ const QString &id)
{
qDebug() << "onWindowAttached: " << handle << ", " << group << ", " << id;
screen_window_t win = (screen_window_t)handle;
@@ -122,12 +139,33 @@ void HelloVideoCameraApp::onWindowAttached(unsigned long handle,
// viewfinder, so that the user can decide when and where to place it
i = 1;
screen_set_window_property_iv(win, SCREEN_PROPERTY_VISIBLE, &i);
+ // There is a bug in ForeignWindow in 10.0.6 which defers window context
+ // flushing until some future UI update. As a result, the window will
+ // not actually be visible until someone flushes the context. This is
+ // fixed in the next release. For now, we will just manually flush the
+ // window context.
+ screen_context_t ctx;
+ screen_get_window_property_pv(win, SCREEN_PROPERTY_CONTEXT, (void**)&ctx);
+ screen_flush_context(ctx, 0);
}
+void HelloVideoCameraApp::onWindowDetached(unsigned long handle,
+ const QString &group,
+ const QString &id)
+{
+ qDebug() << "onWindowDetached: " << handle << ", " << group << ", " << id;
+ // There is a bug in ForeignWindow in 10.0.6 whereby the windowHandle is not
+ // reset to 0 when a detach event happens. We must forcefully zero it here
+ // in order for a re-attach to work again in the future.
+ mViewfinderWindow->setWindowHandle(0);
+}
+
+
+
int HelloVideoCameraApp::createViewfinder(camera_unit_t cameraUnit,
- const QString &group,
- const QString &id)
+ const QString &group,
+ const QString &id)
{
qDebug() << "createViewfinder";
if (mCameraHandle != CAMERA_HANDLE_INVALID) {
@@ -142,7 +180,7 @@ int HelloVideoCameraApp::createViewfinder(camera_unit_t cameraUnit,
return EIO;
}
qDebug() << "camera opened";
- // set bitrate - it has no sane default presently
+ // configure viewfinder properties so our ForeignWindow can find the resulting screen window
if (camera_set_videovf_property(mCameraHandle,
CAMERA_IMGPROP_WIN_GROUPID, group.toStdString().c_str(),
CAMERA_IMGPROP_WIN_ID, id.toStdString().c_str()) == CAMERA_EOK) {
@@ -170,7 +208,6 @@ void HelloVideoCameraApp::onStartFront()
{
qDebug() << "onStartFront";
if (mViewfinderWindow) {
- // create a window and see if we can catch the join
if (createViewfinder(CAMERA_UNIT_FRONT,
mViewfinderWindow->windowGroup().toStdString().c_str(),
mViewfinderWindow->windowId().toStdString().c_str()) == EOK) {
@@ -184,7 +221,6 @@ void HelloVideoCameraApp::onStartRear()
{
qDebug() << "onStartRear";
if (mViewfinderWindow) {
- // create a window and see if we can catch the join
if (createViewfinder(CAMERA_UNIT_REAR,
mViewfinderWindow->windowGroup().toStdString().c_str(),
mViewfinderWindow->windowId().toStdString().c_str()) == EOK) {
@@ -198,32 +234,17 @@ void HelloVideoCameraApp::onStopCamera()
{
qDebug() << "onStopCamera";
if (mCameraHandle != CAMERA_HANDLE_INVALID) {
+ // NOTE that closing the camera causes the viewfinder to stop.
+ // When the viewfinder stops, it's window is destroyed and the
+ // ForeignWindow object will emit a windowDetached signal.
camera_close(mCameraHandle);
mCameraHandle = CAMERA_HANDLE_INVALID;
- // This is a HACK
- // ForeignWindow currently does not properly handle detach events,
- // so there is no way to disconnect and reconnect a screen window to it.
- // Instead, we have to delete the old ForeignWindow instance, and dynamically
- // create a new one to replace it.
- // We can use Container::replace() to do this.
- ForeignWindow *oldViewfinderWindow = mViewfinderWindow;
- mViewfinderWindow = ForeignWindow::create()
- .id(QString("viewfinderWindow"));
- mViewfinderWindow->setWindowId(QString("cameraViewfinder"));
- Container *container = (Container*)oldViewfinderWindow->parent();
- container->replace(container->indexOf(oldViewfinderWindow), mViewfinderWindow);
- delete oldViewfinderWindow;
- QObject::connect(mViewfinderWindow,
- SIGNAL(windowAttached(unsigned long,
- const QString &, const QString &)),
- this,
- SLOT(onWindowAttached(unsigned long,
- const QString &,const QString &)));
// reset button visibility
mStartStopButton->setVisible(false);
mStopButton->setVisible(false);
mStartFrontButton->setVisible(true);
mStartRearButton->setVisible(true);
+
}
}
@@ -237,9 +258,18 @@ void HelloVideoCameraApp::onStartStopRecording()
// otherwise, it is treated as a "stop" button.
if (mVideoFileDescriptor == -1) {
- // LEGAL REQUIREMENTS DICTATE THAT ALL CAMERA APPS MUST PRODUCE AN AUDIBLE
- // TONE WHEN RECORDING FUNCTION IS STARTED. DO THIS OR YOUR APP WILL BE
- // PULLED FROM APP WORLD.
+ // THE CAMERA SERVICE DOES NOT PLAY SOUNDS WHEN PICTURES ARE TAKEN OR
+ // VIDEOS ARE RECORDED. IT IS THE APP DEVELOPER'S RESPONSIBILITY TO
+ // PLAY AN AUDIBLE SHUTTER SOUND WHEN A PICTURE IS TAKEN AND WHEN VIDEO
+ // RECORDING STARTS AND STOPS. NOTE THAT WHILE YOU MAY CHOOSE TO MUTE
+ // SUCH SOUNDS, YOU MUST ENSURE THAT YOUR APP ADHERES TO ALL LOCAL LAWS
+ // OF REGIONS WHERE IT IS DISTRIBUTED. FOR EXAMPLE, IT IS ILLEGAL TO
+ // MUTE OR MODIFY THE SHUTTER SOUND OF A CAMERA APPLICATION IN JAPAN OR
+ // KOREA.
+ // TBD:
+ // RIM will be providing clarification of this policy as part of the
+ // NDK developer agreement and App World guidelines. A link will
+ // be provided when the policy is publicly available.
soundplayer_play_sound("event_video_record_start_sound");
char filename[CAMERA_ROLL_NAMELEN];
View
3 HelloVideoCamera/src/hellovideocameraapp.hpp
@@ -34,6 +34,9 @@ public slots:
void onWindowAttached(unsigned long handle,
const QString &group,
const QString &id);
+ void onWindowDetached(unsigned long handle,
+ const QString &group,
+ const QString &id);
void onStartFront();
void onStartRear();
void onStopCamera();
View
1 NativeCamera/.cproject
@@ -479,4 +479,5 @@
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
</storageModule>
+ <storageModule moduleId="refreshScope"/>
</cproject>
View
2 NativeCamera/.project
@@ -27,7 +27,7 @@
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
- <value>${workspace_loc:/NativeCamera/Device-Release}</value>
+ <value>${workspace_loc:/NativeCamera/Device-Debug}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
View
23 NativeCamera/src/main.c
@@ -25,9 +25,6 @@
#include <bps/soundplayer.h>
-// an arbitrary ZORDER for our application window.
-#define APP_ZORDER (100)
-
typedef enum {
STATE_STARTUP = 0,
STATE_VIEWFINDER,
@@ -75,7 +72,8 @@ handle_screen_event(bps_event_t *event)
int i = (shouldmirror?1:0);
screen_set_window_property_iv(vf_win, SCREEN_PROPERTY_MIRROR, &i);
// place viewfinder in front of the black application background window
- i = APP_ZORDER + 1;
+ // child window z-orders are relative to their parent, not absolute.
+ i = +1;
screen_set_window_property_iv(vf_win, SCREEN_PROPERTY_ZORDER, &i);
// make viewfinder window visible
i = 1;
@@ -143,8 +141,18 @@ static void
shutter_callback(camera_handle_t handle,
void* arg)
{
- // LEGAL REQUIREMENTS DICTATE THAT ALL CAMERA APPS MUST PRODUCE AN AUDIBLE
- // SHUTTER SOUND. DO THIS, OR YOUR APP WILL BE PULLED FROM APP WORLD.
+ // THE CAMERA SERVICE DOES NOT PLAY SOUNDS WHEN PICTURES ARE TAKEN OR
+ // VIDEOS ARE RECORDED. IT IS THE APP DEVELOPER'S RESPONSIBILITY TO
+ // PLAY AN AUDIBLE SHUTTER SOUND WHEN A PICTURE IS TAKEN AND WHEN VIDEO
+ // RECORDING STARTS AND STOPS. NOTE THAT WHILE YOU MAY CHOOSE TO MUTE
+ // SUCH SOUNDS, YOU MUST ENSURE THAT YOUR APP ADHERES TO ALL LOCAL LAWS
+ // OF REGIONS WHERE IT IS DISTRIBUTED. FOR EXAMPLE, IT IS ILLEGAL TO
+ // MUTE OR MODIFY THE SHUTTER SOUND OF A CAMERA APPLICATION IN JAPAN OR
+ // KOREA.
+ // TBD:
+ // RIM will be providing clarification of this policy as part of the
+ // NDK developer agreement and App World guidelines. A link will
+ // be provided when the policy is publicly available.
soundplayer_play_sound("event_camera_shutter");
}
@@ -288,9 +296,6 @@ main(int argc, char **argv)
int attribs[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
screen_fill(screen_ctx, screen_buf, attribs);
screen_post_window(screen_win, screen_buf, 1, rect, 0);
- // position the window at an arbitrary z-order
- int i = APP_ZORDER;
- screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ZORDER, &i);
// Signal bps library that navigator and screen events will be requested
bps_initialize();

0 comments on commit 0dab64d

Please sign in to comment.