Connect Screen with the Camera API

Updated: April 19, 2023

If you want to show video on your display, you need to use the Screen Graphics Subsystem (Screen).

Screen is required to show the image buffer on the display. Specifically, your application must set up Screen and then use window buffers from Screen to handle image buffers from the Camera API.

As part of the setup to connect Screen with the Camera API, your application must create a Screen window group and window within that group. This window is necessary to make the image buffers streamed from the camera visible. Because it's a queued operation, just after you create a window group, you must call screen_flush_context(). Then, you must call camera_set_vf_property() to pass in the handle to the camera, the Group ID, and the Window ID. From here, the Sensor service takes care of ensuring that the image buffers are sent to Screen.

We provide a few examples of how to use Screen with the Camera Library. For more detailed information about using Screen, see the Screen Developer's Guide.

To set up Screen, you must:
  1. Create a Screen context and a window.
  2. Set Screen's usage to be SCREEN_USAGE_NATIVE and set the screen format (e.g., RBGA8888).
  3. Get access to the window buffers. These buffers are the Application window buffers that contain the child window. The child window is used to show actual video (image buffers) from the camera.
  4. Optionally fill the window with default content (e.g., blue screen) in the buffer and make the buffer visible.
  5. Create a unique window group and get its ID. Screen creates a unique group ID for you when you pass NULL to it.
  6. Set the window group ID and window ID properties for the camera, to connect Screen with the Camera API.
Here's a code snippet of what your code can look like. For brevity, we've omitted error checking and handling, but in your production application code, be sure to perform the appropriate error handling.
...
...
screen_context_t screenContext = NULL;
screen_window_t appWindow = NULL;
screen_buffer_t screenBuffer;

int screenUsage = SCREEN_USAGE_NATIVE;
int screenFormat = SCREEN_FORMAT_RGBA8888;

// Variables to fill the window with blue
int size[2];
int blitInfo[] = {SCREEN_BLIT_COLOR, (int) 0xff0000ff, SCREEN_BLIT_END};

// 1. Create the context and an application window
screen_create_context(&screenContext, 0);
screen_create_window(&appWindow, screenContext);

// 2. Set the usage and format properties for the window
screen_set_window_property_iv(appWindow, SCREEN_PROPERTY_USAGE, &screenUsage);
screen_set_window_property_iv(appWindow, SCREEN_PROPERTY_FORMAT, &screenFormat);

// 3. Get access to the application window buffers, and get the buffer size,
// which is the buffer's width and height, in pixels
screen_get_window_property_pv(appWindow, SCREEN_PROPERTY_RENDER_BUFFERS,
                                         (void **)&screenBuffer);
screen_get_window_property_iv(appWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);

// 4. Fill the window with blue color
screen_fill(screenContext, screenBuffer, blitInfo);

// Get the size of the window and use it to define the rendering area,
// then make the window content visible
screen_get_window_property_iv(appWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);
int rects[4] = {0};
rects[2] = size[0];
rects[3] = size[1];
screen_post_window(appWindow, screenBuffer, 1, rects, 0);

// 5. Create a window group and retrieve it. 
// Screen creates a unique group ID for you when you pass NULL to it (recommended).
char groupId[64];
screen_create_window_group(appWindow, NULL);
screen_get_window_property_cv(appWindow, SCREEN_PROPERTY_GROUP, 64, groupId);

// Then you must flush the context since creating a window group is a queued operation
screen_flush_context(screenContext, SCREEN_WAIT_IDLE);

// 6. Set the Group ID and Window ID for the camera
char windowId[64];
snprintf(windowId, sizeof(windowId), "viewfinder_window_%x", cameraHandle);

camera_set_vf_property(cameraHandle, 
                       CAMERA_IMGPROP_WIN_GROUPID, groupId, 
                       CAMERA_IMGPROP_WIN_ID, windowId);
...
...