Use Screen to show the viewfinder window

By default, the Camera library creates a viewfinder window for you. The Sensor service takes care of creating the Screen window for you and posting the image buffers to that window, which is called a viewfinder window.

Once you have connected the Camera API with Screen, you'll need to handle Screen events. For details about using Screen events, see Event handling chapter in the Screen Developer's Guide. A Screen Create event is emitted when you start the viewfinder (camera_start_viewfinder()). After you handle event, you must perform clean-up and use Screen API calls to show the camera buffers on the display.

Another way to look at this is that the viewfinder property, CAMERA_IMGPROP_CREATEWINDOW is set to one (True). To get access to that viewfinder window, you should create a Screen window and context, then create a Group ID and Window ID to pass to the Camera API using the camera_set_vf_property(). The Camera library uses the GROUP ID that's passed to it and joins the viewfinder window as a child to the parent window for your application. For information and an example of how to setup Screen, see Use Screen with the Camera API.” For more information about parent windows and window groups, see Parents and Window Groups in the Screen Developer's Guide.

After you start the viewfinder you must use the Screen Events Framework get a reference to the viewfinder window. Then using the Screen API, you can make the viewfinder window visible. If you are showing video on the display, this step requires you to catch the event to show the contents of the image buffer.

Here's a summary of what's required in this step:
...
...
camera_handle_t cameraHandle;
uint32_t numSupported;
camera_res_t* supportedResolutions;
camera_vfmode_t modes;
int err;
int i;

screen_context_t context;
screen_window_t window;

// First connect to the camera
camera_open(CAMERA_UNIT_1, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &cameraHandle);
camera_set_vf_mode(cameraHandle, CAMERA_VFMODE_VIDEO);
screen_create_context(&context, 0);

// Create the viewfinder window to put our viewfinder (image buffers) into
// which is filled later. For now, specify native.
int screenUsage = SCREEN_USAGE_NATIVE;
// The format depends on your display - 
// this presumes 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);
// now fill the blue window
    screen_fill(context, screenBuffer, blitInfo);

// Obtain size of the buffer
err = 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);

// Create a unique 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);
// Get Apply the Window ID to the viewfinder window and pass the Group ID
// to the Camera library. You should also set the window ID of the viewfinder windo
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
err = camera_start_viewfinder(cameraHandle, NULL, NULL, NULL);
if (err != CAMERA_EOK) {
    printf("Failed to start viewfinder: err = %d\n", err);
    camera_close(cameraHandle);
    return err;
}


// Need to catch the Create event. Catching it
// gives us the handle to the viewfinder window that
// the Camera library creates for you.
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 its local (client)
if (screen_create_event(&screenEvent) == -1) {
    err = errno;
    printf("Failed to create screen event: err = %d\n", err);
    return err;
}

// Handling the Screen events
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 SCREEN_EVENT_CREATE, which indicates that the viewfinder window has
       // joined your main application window 
       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)) {
            gotEvent = true;
            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
} // end while

//Clean-up memory allocated for the Screen Event;
screen_destroy_event(screenEvent);

if (gotEvent == false) {
  err = errno;
  printf("Didn't get a Screen event...indicates something didn't go as expected");
  //return err;
}

// You now 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. The Camera library takes care of reposting the
//content.
int visible = 1;
screen_set_window_property_iv(*viewfinderHandle,
                               SCREEN_PROPERTY_VISIBLE,
                               &visible);

// Flush the changes to make them take effect.
// This is when you should see the viewfinder window on the display.
screen_flush_context(context, SCREEN_WAIT_IDLE);

//At this point, your application should
//allow the user to do something. In the meantime, your
//image buffers (video stream) from the camera are automatically
//reposted for you on the display.
...
...