SDK - CAMAPI Developer options

From edgertronic high speed video camera
Jump to: navigation, search


Home

Debugging




Introduction

CAMAPI

The Camera Application Programming Interface (CAMAPI), consists of a handful of functions, summarized in the table below and explained in detail in the code based documentation and sections below.

CAMAPI
Function
Camera URL Parameters Return value Description
get_camstatus() /get_camstatus None state,
level,
flags,
is_temp,
fpga_temp
Returns all the camera status information, including the camera state, completion level (for states CAMAPI_STATE_RUNNING, CAMAPI_STATE_TRIGGERED, and CAMAPI_STATE_SAVING), bit field flag, image sensor temperature, and FPGA temperature indicating current hardware status.
get_caminfo() /get_caminfo None dictionary Returns all the static camera information including serial number, model, firmware version, etc. The dictionary contents will change after a device update.
get_pretrigger_fill_level() /pretrigger_buffer_fill_level None percent pretrigger buffer filled before trigger event Returns accurate value of the actual pretrigger buffer fill level.
get_storage_info() /get_storage_info mount point dictionary with keys:
available_space: number of available bytes
storage_size: size of device in bytes
mount_point: storage device mount point
Returns dictionary of storage device information.
get_saved_settings() /get_saved_settings None saved camera settings Returns dictionary of saved settings. These are the settings from the last time the run() method was invoked.
get_storage_dir() /get_storage_dir None directory path
or None
Returns mount point of the active storage device. Changes depending what storage devices are installed. Return None if no storage device is available.
format_storage()
deprecated, do not use
/format mount point* ret code Formats active storage device or storage at mount point if specified.
erase_all_files() /erase_all_files mount point* ret code Erases all files on active storage device or storage at mount point if specified. At this point the code blocks erasing files from USB.
get_current_settings() /get_current_settings None current camera settings Returns dictionary that was passed into last call to run() if camera is active, otherwise None.
configure_camera() /configure_camera requested
camera
settings
allowed
camera
settings
Calculates a camera configuration based on the requested values, camera limitations, and a prioritized scheme to to eliminate inconsistencies.
run() /run allowed
camera
settings
ret code Reconfigures the camera to use the allowed values, calibrates the camera using those values, and starts capturing the pretrigger video frames.
trigger()
trigger(base_filename)
/trigger
/trigger?base_filename="mymovie"
base_filename ret code Stops filling the pretrigger buffer and starts filling the posttrigger buffer. When the posttrigger fill is complete, camera will create the video file and metadata file based on the base_filename by adding ".mov" extension and ".txt" extension. If base_filename is not supplied, the camera will create a base_filename that includes a value based on the current time of day.
save_stop() /save_stop None ret code Stop save that is in process, truncating video to the portion saved so far. Rest of captured video data is discarded.
cancel() /cancel None ret code Stops filling the posttrigger buffer.
get_last_saved_filename() /get_last_saved_filename
(with ".mov" appended)
None filename Filename used by the last successful video capture.
Note: this API is deprecated, better to query file system directly.
Device CAMAPI methods only
stop() None ret code Stops capturing and streaming video frames.
Camera URL only
(Not part of CAMAPI)
/ Camera home page. Intended for use with browser that supports javascript
/sync_time Returns camera current time or allows the camera's time to be set.
/reboot Reboots the camera
/download Downloads last saved video marking data with MIME type video/quicktime
/image2 Returns a URL redirect to the actual JPEG image.
/dir_listing ?path= Returns list of files in the specified path or in the active storage video directory if no path is specified.

Note *: For URL, use /format?device=USB or format?device=SD to format device other than the currently active storage device


The following CAMAPI return status values are defined:

Value Symbolic Name Meaning
1 CAMAPI_STATUS_OKAY Method completed without error.
2 CAMAPI_STATUS_INVALID_STATE Attempted action which is not allowed in the current camera state. No action was taken.
3 CAMAPI_STATUS_STORAGE_ERROR The storage subsystem returned an error.
4 CAMAPI_STATUS_CODE_OUT_OF_DATE The FPGA code needs to be updated. Typically power cycling the camera will resolve this issue.
5 CAMAPI_STATUS_INVALID_PARAMETER A parameter passed to the method is invalid. No action was taken.

Python examples

There is a python module hcamapi.py which provides HTTP access to CAMAPI. You can browse to your camera to download the python module and example programs. The HCAMAPI supports the exactly same API as CAMAPI, with the exception you need to pass the camera's IP address or DNS name to the HCAMAPI module.

Here is a simple example:

import hcamapi
cam = hcamapi.HCamapi(opts.address, logger)
(state, level, flags) = cam.get_status()
print "Camera state %d, level %d, flags %d" % (state, level, flags)

saved_settings = cam.get_saved_settings()
cam.run(saved_settings)
cam.trigger()

You can browse to the camera to retrieve hcamapi.py and related example programs written in Python.

 http://10.11.12.13/static/host

replacing 10.11.12.13 with your camera's IP address as necessary.

Shell script command line examples

You can create an application on your host computer to control the camera using HTTP. Here are some simple command line examples:

CAMIP=10.11.12.13
REQ='{"requested_iso":"100","requested_exposure":0.002,"requested_frame_rate":"","requested_vertical":"",\
      "requested_horizontal":"","requested_duration":"","requested_pretrigger":"50","requested_subsample":false}'

# simple shell function to print out the camera status information once a second
# on entry - number of seconds to monitor camera
monitor_cam()
{
    SEC=$1
    for A in `seq 1 $SEC` ; do
        curl $CAMIP/get_status
        echo
        sleep 1
    done
}


ALLOWED=`curl  -H "Content-Type: application/json; charset=utf-8" --data $REQ $CAMIP/configure_camera`
echo $ALLOWED

curl  -H "Content-Type: application/json; charset=utf-8" --data "$ALLOWED" $CAMIP/run
monitor_cam 4

curl $CAMIP/trigger
monitor_cam 6

curl $CAMIP/save_stop
monitor_cam 5

get_status

CAMAPI uses a state machine model to move from pretrigger to trigger to saving and the back to pretrigger again. While doing these three activities, there can be an amount of progress that has occurred, such as how much of the save has completed. In addition, there is device status information, in the form of flags represented as a bit-field.

get_status() returns a dictionary containing

Key Value type Value range Meaning
state int 1 .. 8 Enumeration of current state
level int 0 .. 100 Percentage full or complete. Meaning depends on the state.
flags int 19 bits bit-field encoded device status.

The defined camera states include:

Value Name level Meaning
1 CAMAPI_STATE_UNCONFIGURED N/A CAMAPI run() method hasn't been invoked.
2 CAMAPI_STATE_CALIBRATING N/A Camera is capturing a black frame to be able to subtract the image sensor pixel bias from each video frame. When calibration is done, camera will automatically transition to filling the pretrigger buffer with video frames.
3 CAMAPI_STATE_RUNNING Percentage the pretrigger buffer has filled. The camera is capturing video frames and storing them in the pretrigger buffer.
4 CAMAPI_STATE_TRIGGERED Percentage the posttrigger buffer has filled. The camera is capturing video frames and storing them in the posttrigger buffer. When the posttrigger buffer is full, the camera will automatically transition to saving the capture video.
5 CAMAPI_STATE_SAVING Percentage of captured video frames that have been saved to the file. Camera is reading frames from the pre and posttrigger buffers, encoding the frames, and saving them to a file.
6 CAMAPI_STATE_RUNNING_PRETRIGGER_FULL 100, meaning the pretrigger buffer is full. The camera is capturing video frames and the new frames are overwriting the oldest frame in the pretrigger buffer.
7 CAMAPI_STATE_TRIGGER_CANCELED N/A User canceled the video capture after the camera was triggered. Camera is resetting and will automatically transition to again filling the pretrigger buffer with video frames.
8 CAMAPI_STATE_SAVE_CANCELED N/A User canceled the save video to file. Camera is resetting and will automatically transition to again filling the pretrigger buffer with video frames. This feature has been disabled so the CAMAPI_STATE_SAVE_CANCELED can not be reached.

the defined camera status bit-field values are:

Bit Name Meaning
0 CAMAPI_FLAG_STORAGE_FULL Current storage device does not have room to hold another video file.
1 CAMAPI_FLAG_STORAGE_MISSING No usable storage device is installed.
2 CAMAPI_FLAG_USB_STORAGE_INSTALLED USB storage device is installed.
3 CAMAPI_FLAG_SD_CARD_STORAGE_INSTALLED SD card is installed.
4 CAMAPI_FLAG_USB_STORAGE_FULL USB storage device does not have room to hold another video file.
5 CAMAPI_FLAG_SD_CARD_STORAGE_FULL SD card does not have room to hold another video file.
6 CAMAPI_FLAG_STORAGE_BAD An installed storage device is returning an error.
7 CAMAPI_FLAG_NET_CONFIGURED Setting to allow the camera to connect to a network file system are stored in the camera.
8 CAMAPI_FLAG_NET_UNMOUNTABLE Camera attempted to use the network file system settings to mount the shared resource but the mount failed. Likely the network file system settings are incorrect.
9 CAMAPI_FLAG_NET_FULL The network file system shared storage does not have room to hold more captured videos.
18 CAMAPI_FLAG_GENLOCK_NO_SIGNAL The camera is configured as a genlock slave device and no periodic genlock start-of-exposure signal is detected.
19 CAMAPI_FLAG_GENLOCK_CONFIG_ERROR The camera is configured as a genlock slave device and at least one frame did not have received start-of-exposure signal when expected.

The status (really the camera state) can be obtained at any time. The follow table shows the camera's state transition diagram.

Current state state value Event New state Current state description
CAMAPI_STATE_UNCONFIGURED 1 run CAMAPI_STATE_CALIBRATING The camera has been powered on and is ready to have the camera capture parameters configured.
CAMAPI_STATE_CALIBRATING 2 calibration
complete
CAMAPI_STATE_RUNNING The camera is optimizing image quality by calibrating the sensor
CAMAPI_STATE_RUNNING 3 trigger CAMAPI_STATE_TRIGGERED The camera is filling or overwriting the pretrigger buffer.
pretrigger
buffer full
CAMAPI_STATE_RUNNING_PRETRIGGER_FULL The camera has filled the pretrigger buffer.
CAMAPI_STATE_TRIGGERED 4 posttrigger buffer full CAMAPI_STATE_SAVING The camera is filling the posttrigger buffer.
cancel CAMAPI_STATE_TRIGGER_CANCELED The trigger has been canceled before saving video has started
CAMAPI_STATE_SAVING 5 saving complete CAMAPI_STATE_CALIBRATING The camera is saving the video frames in the pretrigger and posttrigger buffers to a file.
cancel CAMAPI_STATE_SAVE_CANCELED The save video operation has been canceled - no files are created. This feature has been disabled so the CAMAPI_STATE_SAVE_CANCELED state can not be reached.
stop save CAMAPI_STATE_CALIBRATING The save video operation has been stopped with the encoded video frames saved to the file and unprocessed video frames are discarded.
CAMAPI_STATE_RUNNING_PRETRIGGER_FULL 6 The camera is overwriting the pretrigger buffer.
CAMAPI_STATE_TRIGGER_CANCELED 7
CAMAPI_STATE_SAVE_CANCELED 8 This feature has been disabled so the CAMAPI_STATE_SAVE_CANCELED state can not be reached.
CAMAPI state transition diagram

Extend table to show you can call configure_camera in any state.

configure_camera

The configure_camera() function accepts user-supplied requested camera settings, in the form of a python dictionary, and returns a dictionary containing the allowed values. Details of the negotiation are described above.

Note: In addition to the allowed camera settings, configure_camera() also returns additional values that are expected by other CAMAPI functions. Only the values intended to be used external to CAMAPI are documented. The rest should be treated as opaque and not modified by the application using CAMAPI. The opaque values may change at any point in the future.

User settings
Setting
(Dict key)
Units Supported values Description
requested_horizontal pixels 192 .. 1280 Width of image to capture.
requested_vertical pixels 96 .. 1024 Height of image to capture.
requested_frame_rate frames per second 0.1 .. 25000 Number of frames to capture in every second.
requested_exposure seconds 0.000004 .. 0.1 Amount of time the CMOS sensor is integrating the received light.
requested_duration seconds Limited by memory Amount of the video to capture.
requested_pretrigger percentage 0 .. 100 Amount of the video being captured is captured before the trigger event.
requested_iso unitless color: 100 .. 400
mono: 400 .. 1600
sensitivity to light.
requested_subsample int enum 0 - off
1 - on
Controls skipping every other row and column.
requested_force_mono int enum 0 - off
1 - on
Force color sensor video to be processed as monochrome. This is useful for high frame rates where the de-Bayering algorithm might add noise to the image. Note: this doesn't change the ISO range. This feature is not implemented.
requested_genlock int enum 0 - off
1 - master
2 - slave
Camera genlock configuration. Master means the camera is generating the trigger and start-of-exposure timing signals. Slave mean the camera is receiving those signals, via the external trigger connector, from the genlock master camera.
requested_overclock int enum 0 - off
1 - A level
2 - B level
3 - C level
4 - D level
Camera overclock configuration. The amount of overclocking is not specified beyond saying A is the least overclocking and D is the most overclocking.

Run

Once the camera has returned a set of acceptable capture parameters, you can run the camera to activate those values. The camera will take a dark frame to maximize image quality for those particular capture parameters, then it will start filling the pretrigger buffer (if configured).

In addition to filling the pretrigger buffer, live preview is also started, meaning the JPEG file is being updated around five times a second. Other live preview options are possible.

Once the pre-trigger buffer is full, the camera will overwrite the oldest frame in the buffer with the newly captured frame until the camera is triggered.

Trigger and save

The camera can be triggered anytime it is filling the pretrigger buffer, even if the pretrigger buffer is not full. Any future trigger requests are ignored until the camera is again filling the pretrigger buffer (which happens automatically after the save is complete).

Once the trigger occurs, the camera switches from filling the pretrigger buffer to filling the posttrigger buffer. Once the posttrigger buffer is full, the camera automatically switches from capturing video to saving the captured video. Once the video has been saved, the camera automatically switches from saving video to filling the pretrigger buffer and waiting for a trigger event. This simple flow allows the camera to be configured once and then controlled by an external trigger without requiring an external computer.

Stop

Trigger

Cancel

While in state CAMAPI_STATE_TRIGGERED, cancel() will cancel filling the posttrigger buffer.
Note: In normal operation, once the posttrigger buffer has filled, the camera will automatically transition from CAMAPI_STATE_TRIGGERED to CAMAPI_STATE_SAVING. It is possible that the cancel() may be received after this automatic transition has occurred. In that case, the cancel() will have no effect.

CAMAPI warning support

The CAMAPI configure_camera() method accepts user-supplied requested camera settings, in the form of a python dictionary, and returns a dictionary containing the allowed values. In addition, the returned dictionary contains a global warning flag, and if set, one or more setting specific warnings with text describing how to resolve the warning.

The global warning allowed dictionary key is named warning and each setting specific warning allowed dictionary key name is the setting name with _warning appended. For example, if there is a warning for the subsample the key name would be subsample_warning and the value would be a text string, such as Subsample mode may cause alaising and/or other visual artifacts.

Settings supporting warnings

The settings that generate a warning are listed below. To simplify localization, each warning value is unique.

Setting Key Warning Key Warning Value Meaning
iso iso_warning 1 High ISO settings can create increased noise, graininess or other artifacts.
subsample subsample_warning 2 Subsample mode may cause alaising and/or other visual artifacts.
edr edr_warning 3 EDR Mode is less effective at high ISO settings.
4 EDR Mode can cause purple color shift in bright image areas.
overclock overclock_warning 5 High Overclock settings may cause errors or visual artifacts. Use with caution.
genlock genlock_warning 6 In Genlock Slave mode, this camera can only be triggered through the Master and will ignore the external trigger.
force_monochrome force_monochrome_warning 7 Force Monochrome Mode is enabled.
gamma_correction gamma_correction_warning 8 Disabling Gamma may be useful for some video editing workflows, but can cause a loss of shadow detail in normal use.
pipeline pipeline_warning 9 Using a video encode pipeline other than high encode quality may result is video artifacts.

Mac OSX SDK example usage

The camera includes some example python code and a handy host CAMAPI library (hcamapi.py) that you can use to automate camera control. You can see the python module and applications by browsing to your camera http://10.11.2.13/static/host
replacing 10.11.12.13 with your camera's IP address as necessary.
The following are some cut-and-paste commands that should work on a Mac OSX computer with no additional software being added. All commands are run in the Terminal application. To start Terminal either press the COMMAND-SPACE keys at the same time or using Finder to navigate into Applications -> Utilities -> Terminal. Once terminal is running, try out these commands

CAMIP=10.11.12.13                                                                  # set to the IP address of the edgetronic camera

mkdir edgetronic
cd edgetronic
curl http://$CAMIP/static/host/hcamapi.py > hcamapi.py                             # fetch the handy host CAMAPI library
curl http://$CAMIP/static/host/hcamapi_example_usage.py > hcamapi_example_usage.py # fetch example program

python hcamapi_example_usage.py -a $CAMIP

Here is some of the output from running those commands:

lyre-osx:~ tfischer$ CAMIP=10.111.0.35
lyre-osx:~ tfischer$ mkdir edgetronic
lyre-osx:~ tfischer$ cd edgetronic

lyre-osx:edgetronic tfischer$ curl http://$CAMIP/static/host/hcamapi.py > hcamapi.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 21827  100 21827    0     0   533k      0 --:--:-- --:--:-- --:--:--  710k

lyre-osx:edgetronic tfischer$ curl http://$CAMIP/static/host/hcamapi_example_usage.py > hcamapi_example_usage.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12469  100 12469    0     0   366k      0 --:--:-- --:--:-- --:--:--  468k


lyre-osx:edgetronic tfischer$ python hcamapi_example_usage.py -a $CAMIP
Camera state 6, level 100, flags 8
Camera extended status - state 6, level 100, flags 8, IS temp (C) 31, FPGA temp (C) 33
Status string: State: Running pretrigger buffer full; Level: 100; Flags: SD card installed; Empty: 776.8 MB, Storage directory: /mnt/sdcard
Directory path to active storage device:  /mnt/sdcard
Storage information: 814514176 / 1977286656 bytes, mount point: /mnt/sdcard
Camera information:
    Software build date: 20140824092106
    Hardware build date: 20130520
    FPGA version: 70
    Model Number: 1
    Serial Number: 3
    Hardware Revision: 3
    Hardware Configuration: 0
    IR Filter: installed
    Ethernet MAC Address: 00:1B:C5:09:60:03

Saved camera settings:
    Sensitivity: None
    Shutter: 1/500
    Frame Rate: 60
    Horizontal: None
    Vertical: None
    Sub-sampling: On
    Duration: 10
    Pre-trigger: 75

There is a lot more output. The example program hcamapi_example_usage.py uses every exposed edgertronic camera API (CAMAPI).

Enhancing the Web UI look and feel using CAMAPI

Basically there is one webpage that includes a few other HTML files. The sanstreak.html includes the rest of the /home/root/ss-web/templates HTML files. The layout is a viewport for the video (video_image.html) with buttons below it (button_row.html). There are two modal dialog windows, settings (settings_modal.html) and replay (replay_modal.html). Stylesheets, located in /home/root/ss-web/static, control the overall look.

The actions (update live preview, trigger, etc) are supported by JavaScript. The JavaScript code accesses CAMAPI (described below) using JSON / HTTP calls to the caemra. The JSON / HTTP encoding is done by app.py. The source code of app.py is provided as a reference (/home/root/ss-web/static/sdk/camera/app.py).

If you want to enhance the look-and-feel, your ability to control the camera is supported by CAMAPI. First understand CAMAPI and then change the code in /home/root/ss-web to your heart's content.

Media server

GStreamer is used to get video frames from Video4Linux2 (V4L2), encode them in JPEG for live preview or H.264 when saving to file. It is a bit tricky to show the progress of the save operation by occasionally displaying a JPEG encoded frame while the save is in progress. To handle this capability, a media server is used.




Home

Debugging