This example shows you how to connect to the configured camera of SENSOR_UNIT_1 to show the viewfinder window and show a video stream from a camera.
In this case, the camera can be live camera or prerecorded video.
Here's sample code for showing a viewfinder window using the Camera library:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <screen/screen.h>
#include <camera/camera_api.h>
#include <camera/camera_encoder.h>
#include <camera/camera_3a.h>
main()
{
camera_handle_t cameraHandle;
int err;
// Must use Screen to use the Camera library
screen_context_t context;
screen_window_t window;
// Create a screen context and a window
screen_create_context(&context, 0);
//Create the viewfinder window to put our viewfinder (image buffers) into
int screenUsage = SCREEN_USAGE_NATIVE;
// depends on your display - this requires that you know what formats are
// supported
int screenFormat = SCREEN_FORMAT_RGBA8888;
//Create a window for filling in with color
screen_create_window(&window, context);
screen_set_window_property_iv(window, SCREEN_PROPERTY_USAGE, &screenUsage);
screen_set_window_property_iv(window, SCREEN_PROPERTY_FORMAT, &screenFormat);
// Create buffers for the window - mem associated with window
screen_create_window_buffers(window, 1);
screen_buffer_t screenBuffer;
int size[2];
int blitInfo[] = {SCREEN_BLIT_COLOR, (int) 0xff00ffff, SCREEN_BLIT_END};
// Get a buffer
screen_get_window_property_pv(window, SCREEN_PROPERTY_RENDER_BUFFERS,
(void **)&screenBuffer);
// Fill the window a nice torquiose shade
screen_fill(context, screenBuffer, blitInfo);
// Get the size of the buffer
screen_get_window_property_iv(window, SCREEN_PROPERTY_BUFFER_SIZE, size);
// Post the changes to the display to position 0, 0
// and with the screen size of 720, 1280
int rects[4] = {0,0,720,1280};
screen_post_window(window, screenBuffer, 1, rects, 0);
// Set the group ID
char groupId[64];
snprintf(groupId, sizeof(groupId), "camera_unique_group_%x_%x",
getpid(), cameraHandle);
screen_create_window_group(window, groupId);
screen_flush_context(context, SCREEN_WAIT_IDLE);
//Connect to the camera configured as CAMERA_UNIT_1
camera_open(CAMERA_UNIT_1, CAMERA_MODE_RW | CAMERA_MODE_ROLL,
&cameraHandle);
// Set the viewfinder image stream mode
camera_set_vf_mode(cameraHandle, CAMERA_VFMODE_VIDEO);
// Set viewfinder window properties and pass the group ID
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);
// Start the viewfinder
camera_start_viewfinder(cameraHandle, NULL, NULL, NULL);
// After you start the viewfinder, a SCREEN_CREATE event is
// emitted when the viewfinder window is joined with the parent window.
// You need to catch the create event
screen_event_t screenEvent;
bool gotEvent = false;
screen_window_t viewfinder;
// This is the viewfinder (image buffer contents) window's that's passed to you.
screen_window_t *viewfinderHandle = NULL;
screen_stream_t *streamHandle =NULL;
viewfinderHandle = &viewfinder;
if (viewfinderHandle) {
*viewfinderHandle = NULL;
}
if (streamHandle){
*streamHandle = NULL;
}
// Application is created to hold the event so it's local to the application
// Screen doesn't manage this for you.
if (screen_create_event(&screenEvent) == -1) {
err = errno;
printf("Failed to create screen event: err = %d\n", err);
return;
}
// Handle events from Screen
while (screen_get_event(context, screenEvent, -1) == 0) {
int eventType;
int objectType;
if (screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_TYPE, &eventType) == -1) {
printf("Failed to get type of screen event: err = %d\n", err);
screen_destroy_event(screenEvent);
break;
}
if (eventType == SCREEN_EVENT_PROPERTY) {
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_OBJECT_TYPE,
&objectType);
}
else if (eventType == SCREEN_EVENT_CREATE) {
// Got the Create event
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_OBJECT_TYPE,
&objectType);
//Get a reference to the Stream object from the Camera service
if (streamHandle && (objectType == SCREEN_OBJECT_TYPE_STREAM)) {
screen_get_event_property_pv(screenEvent, SCREEN_PROPERTY_STREAM,
(void**)streamHandle);
}
else if (viewfinderHandle && (objectType == SCREEN_OBJECT_TYPE_WINDOW)) {
screen_get_event_property_pv(screenEvent, SCREEN_PROPERTY_WINDOW,
(void**)viewfinderHandle);
}
//You now have references to the memory that Screen allocated for you.
//You're responsible for cleaning this up!
if ((!streamHandle || *streamHandle) &&
(!viewfinderHandle || *viewfinderHandle)) {
break;
}
}
else if (eventType == SCREEN_EVENT_CLOSE) {
// Got a close event, make sure it is for a window close
if (screen_get_event_property_iv(screenEvent,
SCREEN_PROPERTY_OBJECT_TYPE,
&objectType) == - 1) {
err = errno;
printf("Failed to get object type of screen event: err = %d\n", err);
break;
}
if (objectType == SCREEN_OBJECT_TYPE_WINDOW) {
// Get child window handle
if (screen_get_event_property_pv(screenEvent, SCREEN_PROPERTY_WINDOW,
(void **)&viewfinderHandle) == -1) {
err = errno;
printf("Failed to get screen event window: err = %d\n", err);
break;
}
// Call destroy on this window handle to free a small bit
// of memory allocated on our behalf or you'll have a
// memory leak
if (screen_destroy_window(*viewfinderHandle) == -1) {
err = errno;
printf("Failed to destroy window remnants: err = %d\n", err);
break;
}
}// end else if
}//end eventType == SCREEN_EVENT_CLOSE
}
//Ensure you do cleanup so there isn't a memory leak;
screen_destroy_event(screenEvent);
// We should have a handle to the viewfinder window. Let's
// make it visible.
int vsize[2] = {1280, 720 };
int vposition[2]={0,0};
screen_set_window_property_iv(*viewfinderHandle, SCREEN_PROPERTY_SIZE, vsize);
screen_set_window_property_iv(*viewfinderHandle, SCREEN_PROPERTY_BUFFER_SIZE, vsize);
screen_set_window_property_iv(*viewfinderHandle, SCREEN_PROPERTY_SOURCE_SIZE, vsize);
screen_set_window_property_iv(*viewfinderHandle, SCREEN_PROPERTY_POSITION, vposition);
//Make the window visible by changing the focus.
int visible = 1;
screen_set_window_property_iv(*viewfinderHandle, SCREEN_PROPERTY_VISIBLE, &visible);
// Flush the changes to make them take effect.
// This is where you should see the viewfinder window on the display.
screen_flush_context(context, SCREEN_WAIT_IDLE);
//Press x to stop streaming the video
int exitExample = 0;
static char userString[80];
while (exitExample == 0) {
printf("\tPress x to exit:\n");
fgets(userString, sizeof(userString), stdin);
if ( (userString[0] == 'x') || (userString[0] == 'X') ) {
exitExample = 1;
}
}
//Stop streaming image buffers from the camera
camera_stop_viewfinder(cameraHandle);
//Deallocate resources and release the handle from the camera
camera_close(cameraHandle);
screen_destroy_window(viewfinder);
screen_destroy_window(window);
screen_destroy_context(context);
return 0;
}