// NOTE, in this code I am purposely ignoring error return codes for the sake of clarity while // walking through the code. Normally, you should check the return codes for errors, as this // will greatly help to isolate bugs. static int init_camera() { camera_error_t err; unsigned int num; unsigned int i; camera_unit_t cams[CAMERA_UNIT_NUM_UNITS]; camera_unit_t unit; // here are 2 ways to determine which cameras are available on a given device... #if 0 // METHOD 1 // inventory the available camera units // NOTE: to just find the number of available cameras: camera_get_cameras(0, &num, NULL); camera_get_supported_cameras(CAMERA_UNIT_NUM_UNITS, &num, cams); for (i=0; i<num; i++) { fprintf(stderr, "found camera unit %d\n", cams[i]); } #else // METHOD 2 // inventory cameras which support a given feature set - in this case PHOTO & BURST camera_feature_t features[] = { CAMERA_FEATURE_PHOTO, CAMERA_FEATURE_BURST }; camera_unit_t next = CAMERA_UNIT_NONE; num = 0; // note that this is an iterating function call which returns only one "next" unit at a time while (camera_find_capable(features, sizeof(features)/sizeof(*features), next, &next) == CAMERA_EOK) { cams[num++] = next; fprintf(stderr, "camera unit %d supports the required features\n", next); } #endif // open the first camera found unit = cams[0]; fprintf(stderr, "selecting camera unit %d\n", unit); err = camera_open(unit, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &handle); if (err != CAMERA_EOK) { fprintf(stderr, "camera_open() failed: %d\n", err); return err; } // This is the minimal required configuration for a viewfinder. // NOTE: we need to enable burst mode when starting the viewfinder. // the maximum burst framerate is 15fps. don't trust me? you can query // camera_get_photo_vf_framerates() to determine the capabilities. err = camera_set_photovf_property(handle, CAMERA_IMGPROP_WIN_GROUPID, vf_group, CAMERA_IMGPROP_WIN_ID, "my_viewfinder", CAMERA_IMGPROP_BURSTMODE, 1, CAMERA_IMGPROP_FRAMERATE, (double)15.0); // max for burst is 15fps. if (err != CAMERA_EOK) { // NOTE: if you need to narrow down which setting is causing an error, // consider breaking the above command down into multiple calls. // be aware that some values must be changed together though (eg. height & width) // in order to pass range-checking fprintf(stderr, "camera_set_photovf_property() failed: %d\n", err); } else { // a valid photovf and photo configuration are required before starting // the viewfinder. // the defaults for both will always be sane, however if certain properties // are changed in one, they may need to be changed in the other. // resolution is one such example (aspect ratios must match). // here is an example configuration for photo properties - setting up the burst divisor. // this is only valid in burst viewfinder mode, and will cause the camera service to // only deliver every 3rd frame. (note that fractional rates are allowed). // why provide a divisor instead of just setting 5fps? camera_set_photo_property(handle, CAMERA_IMGPROP_BURSTDIVISOR, (double)3.0); // DOUBLE! // callbacks are optional, however status callback is useful for detecting asynchronous events // unless your application requires processing of viewfinder frame data, don't bother with // a viewfinder callback, as it incurs some additional ipc overhead. remember, the viewfinder // window itself is already rendered by the camera service, not your app. // NOTE: we are passing main_bps_chid as the void* arg which will then // be delivered to all callbacks. main_bps_chid is already a global variable, // so this isn't necessary, but is just done here to illustrate the convention. err = camera_start_photo_viewfinder(handle, NULL, //&viewfinder_callback, &status_callback, (void*)main_bps_chid); // user-defined arg. if (err != CAMERA_EOK) { fprintf(stderr, "camera_start_photo_viewfinder() failed: %d\n", err); } else { // successfully started viewfinder // if it's a front-facing camera, we should mirror the viewfinder once // we receive it. if (unit == CAMERA_UNIT_FRONT) { shouldmirror = true; } return 0; } } // clean up on error camera_close(handle); handle = CAMERA_HANDLE_INVALID; return err; }
void ActionRecordPicture::execute(ExecutionState* state) { DataModelLogger* RUNLOG = state->getLogger(); camera_unit_t cameraUnit = getParameter("CAMERA", state) == "BACK" ? CAMERA_UNIT_REAR : CAMERA_UNIT_FRONT; if (!state->getRuntimeResources()->isCameraOk( state->getRuntimeResources()->setupCamera(cameraUnit, CAMERA_MODE_RW))) { LOG->error("Failed to get camera"); RUNLOG->error("Failed to get camera"); return; } camera_handle_t camera = state->getRuntimeResources()->getCamera(); if (!state->getRuntimeResources()->isCameraOk( _camera_set_photovf_property(camera, CAMERA_IMGPROP_END))) { LOG->error("Failed to set photo view finder properties"); RUNLOG->error("Failed to set photo view finder properties"); return; } if (!state->getRuntimeResources()->isCameraOk( _camera_set_photo_property(camera, CAMERA_IMGPROP_END))) { LOG->error("Failed to set photo properties"); RUNLOG->error("Failed to set photo properties"); return; } state->getRuntimeResources()->callbackReset(); if (!state->getRuntimeResources()->isCameraOk( camera_start_photo_viewfinder(camera, NULL, viewFinderStatusCallback, (void*) state->getRuntimeResources()))) { LOG->error("Failed to start video viewfinder"); RUNLOG->error("Failed to start video viewfinder"); return; } if (!state->getRuntimeResources()->callbackWait(5000)) { LOG->warning("Timed out waiting for view finder to start"); } std::string flashModeStr = getParameter("FLASH", state); camera_flashmode_t flashMode; if (flashModeStr == "ON") { flashMode = CAMERA_FLASH_ON; } else if (flashModeStr == "OFF") { flashMode = CAMERA_FLASH_OFF; } else { flashMode = CAMERA_FLASH_AUTO; } if (!state->getRuntimeResources()->isCameraOk(camera_config_flash(camera, flashMode))) { LOG->error("Failed to set flash setting"); RUNLOG->error("Failed to set flash setting"); return; } std::string filename; if (isValueTrue(getParameter("APPENDTIME", state))) { filename = state->getRuntimeResources()->uniqueFilename(getParameter("OUTFILE", state)); } else { filename = getParameter("OUTFILE", state); } state->setUserProperty("PICTURE_FILENAME", filename); state->setExecutionProperty("ACTION_ActionRecordPicture_OUTFILE", filename); state->getRuntimeResources()->callbackReset(); if (!state->getRuntimeResources()->isCameraOk( camera_take_photo(camera, NULL, NULL, NULL, photoRecordingStatusCallback, (void*) state, false))) { LOG->error("Failed to take photo"); RUNLOG->error("Failed to take photo"); return; } if (!state->getRuntimeResources()->callbackWait(3000)) { LOG->warning("Timed out waiting for view finder to start"); return; } if (!state->getRuntimeResources()->isCameraOk(camera_stop_photo_viewfinder(camera))) { LOG->error("Failed to stop photo viewfinder"); RUNLOG->error("Failed to stop photo viewfinder"); return; } state->getRuntimeResources()->destroyCamera(); RUNLOG->debug("Photo captured"); }
// NOTE, in this code I am purposely ignoring error return codes for the sake of clarity while // walking through the code. Normally, you should check the return codes for errors, as this // will greatly help to isolate bugs. static int init_camera() { camera_error_t err; unsigned int num; unsigned int i; camera_unit_t cams[CAMERA_UNIT_NUM_UNITS]; camera_unit_t unit; // here are 2 ways to determine which cameras are available on a given device... #if 1 // METHOD 1 // inventory the available camera units // NOTE: to just find the number of available cameras: camera_get_cameras(0, &num, NULL); camera_get_supported_cameras(CAMERA_UNIT_NUM_UNITS, &num, cams); for (i=0; i<num; i++) { fprintf(stderr, "found camera unit %d\n", cams[i]); } #else // METHOD 2 // inventory cameras which support a given feature set - in this case PHOTO & VIDEO camera_feature_t features[] = { CAMERA_FEATURE_PHOTO, CAMERA_FEATURE_VIDEO }; camera_unit_t next = CAMERA_UNIT_NONE; num = 0; // note that this is an iterating function call which returns only one "next" unit at a time while (camera_find_capable(features, sizeof(features)/sizeof(*features), next, &next) == CAMERA_EOK) { cams[num++] = next; fprintf(stderr, "camera unit %d supports the required features\n", next); } #endif // open the first camera found unit = cams[0]; fprintf(stderr, "selecting camera unit %d\n", unit); err = camera_open(unit, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &handle); if (err != CAMERA_EOK) { fprintf(stderr, "camera_open() failed: %d\n", err); return err; } // This is the minimal required configuration for a viewfinder. err = camera_set_photovf_property(handle, CAMERA_IMGPROP_WIN_GROUPID, vf_group, CAMERA_IMGPROP_WIN_ID, "my_viewfinder"); #if 0 // here is a more complex example configuration: err = camera_set_photovf_property(handle, CAMERA_IMGPROP_WIN_GROUPID, vfWndGroupId, CAMERA_IMGPROP_WIN_ID, vfWndWindowId, CAMERA_IMGPROP_WIDTH, w, CAMERA_IMGPROP_HEIGHT, h, CAMERA_IMGPROP_HWOVERLAY, 1, #ifdef DO_PHOTO_180 CAMERA_IMGPROP_ROTATION, (rotation+180) % 360, #else CAMERA_IMGPROP_ROTATION, rotation, #endif #ifdef DO_BURST CAMERA_IMGPROP_BURSTMODE, 1, #endif CAMERA_IMGPROP_FRAMERATE, 15.0); #endif if (err != CAMERA_EOK) { // NOTE: if you need to narrow down which setting is causing an error, // consider breaking the above command down into multiple calls. // be aware that some values must be changed together though (eg. height & width) // in order to pass range-checking fprintf(stderr, "camera_set_photovf_property() failed: %d\n", err); } else { // a valid photovf and photo configuration are required before starting // the viewfinder. // the defaults for both will always be sane, however if certain properties // are changed in one, they may need to be changed in the other. // resolution is one such example (aspect ratios must match). // here is an example configuration for photo properties. (just updating rotation) camera_set_photo_property(handle, CAMERA_IMGPROP_ROTATION, 180); // callbacks are optional, however status callback is useful for detecting asynchronous events // unless your application requires processing of viewfinder frame data, don't bother with // a viewfinder callback, as it incurs some additional ipc overhead. remember, the viewfinder // window itself is already rendered by the camera service, not your app. err = camera_start_photo_viewfinder(handle, &viewfinder_callback, &status_callback, (void*)123); // arbitrary user argument if (err != CAMERA_EOK) { fprintf(stderr, "camera_start_photo_viewfinder() failed: %d\n", err); } else { // successfully started viewfinder // if it's a front-facing camera, we should mirror the viewfinder once // we receive it. if (unit == CAMERA_UNIT_FRONT) { shouldmirror = true; } return 0; } } // clean up on error camera_close(handle); handle = CAMERA_HANDLE_INVALID; return err; }