🌐 English

    Camera Monitoring API#

    It is called within the scope of the oasis::ui namespace.

    Header File#

    OasisPreview.h

    PreviewFrameObserver Interface#

    A user-defined observer object derived from PreviewFrameObserver can be specified for a Preview object using the setPreviewFrameObserver function.

    The application can obtain video frames displayed on the screen through the onFrame callback function.

    class PreviewFrameObserver : public std::enable_shared_from_this<PreviewFrameObserver>
    {
    public:
        PreviewFrameObserver();
        virtual ~PreviewFrameObserver();
        virtual void onFrame(int32_t camera_id, uint8_t *frame, int32_t stride_width, int32_t width, int32_t height);
        virtual void onNoMediaData(int32_t camera_id);
    };
    
    void onFrame ( int32_t camera_id , uint8_t * frame , int32_t stride_width , int32_t width , int32_t height )
    OasisPreview.h
    Delivers the video frame displayed on the screen.
    Parameters
    camera_id  The camera ID specified in configCameras.
    frame  The frame start pointer.
    stride_width  The frame width stride.
    width  The frame width.
    height  The frame height.

    When the video frame format is YUV420, the Y, U, and V channels can be obtained using the formula below:

    uint8_t *y = frame;
    uint8_t *u = frame + stride_width * height;
    uint8_t *v = u + stride_width * height / 4;
    
    void onNoMediaData ( int32_t camera_id )
    OasisPreview.h
    Occurs when video information cannot be obtained from the camera device for a certain period of time.
    Parameters
    camera_id  The camera ID specified in configCameras.

    Functions#

    PreviewRef createPreview ( int32_t display_id , key_value_map_t & parameters )
    OasisPreview.h
    Creates a Preview object.
    Parameters
    display_id  The Display device ID. Specify "0".
    parameters  The key-value map required for creating a Preview object.
    Return Value
    Returns a Preview object on success, and returns nullptr on failure.
    Key
    Default
    M
    Description
    rotation
    0
     
    Specifies the video rotation angle. Specify one of the values 0, 90, 270, 180. Used when specifying rotation globally, and the rotation angle can be specified for each individual video channel with the channel<N>-rotation key value.
    channel-count
    The number of channels (camera devices) to monitor.
    primary-channel
    Specifies the primary channel number. The starting number is 1.

    The key-value map values for each video channel are prefixed with channel<N>- before each key name. <N> starts from 1 and increases by 1.

    Key
    Default
    M
    Description
    channel<N>-camera-id
    The camera device ID to be monitored, specified in configCameras.
    channel<N>-ise-id
    -1
     
    The ISE device ID, a key value exclusive to AllWinner.
    channel<N>-rotation
    0
     
    Specifies the video channel rotation angle. Specify one of the values 0, 90, 270, 180.
    channel<N>-x
    Specifies the x coordinate of the video channel.
    channel<N>-y
    Specifies the y coordinate of the video channel.
    channel<N>-width
    Specifies the width of the video channel.
    channel<N>-height
    Specifies the height of the video channel.
    channel<N>-zorder
    0
     
    Specifies the display sequence of the video channel. A higher value appears further in front.
    channel<N>-enable-adas
    0
     
    Specifies whether to activate ADAS. Allowed on only a single video channel.
    channel<N>-adas-inference-model-names
     
    The list of inference models to be applied to ADAS.
    int32_t setPreviewFrameObserver ( const PreviewRef & preview , const std::shared_ptr<PreviewFrameObserver> & observer )
    OasisPreview.h
    Specifies a user-defined observer object derived from PreviewFrameObserver for a Preview object.
    Parameters
    preview  The Preview object created via createPreview.
    observer 
    Return Value
    • 0: Success
    • -1: Failure
    int32_t destroyPreview ( const PreviewRef & preview )
    OasisPreview.h
    Releases the Preview object.
    Parameters
    preview  The Preview object created via createPreview.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewStart ( const PreviewRef & preview )
    OasisPreview.h
    Starts the Preview. It uses the key-value map passed when calling createPreview.
    Parameters
    preview  The Preview object created via createPreview.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewStop ( const PreviewRef & preview )
    OasisPreview.h
    Stops the Preview.
    Parameters
    preview  The Preview object created via createPreview.
    Return Value
    • 0: Success
    • -1: Failure
    bool previewIsRunning ( const PreviewRef & preview )
    OasisPreview.h
    Verifies whether the Preview is operating.
    Parameters
    preview  The Preview object created via createPreview.
    Return Value
    • true: Operating.
    • false: Not operating.
    int32_t previewGetCameraIdOfChannel ( const PreviewRef & preview , const char * channel_id )
    OasisPreview.h
    Obtains the camera device ID connected to the channel of the Preview object.
    Parameters
    preview  The Preview object created via createPreview.
    channel_id  The channel ID string. For channel 1, specify "channel1".
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewShowCameraStream ( const PreviewRef & preview , int32_t camera_id , bool show )
    OasisPreview.h
    Makes the video output from the camera device visible or invisible for the Preview object.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    show  Makes the camera video visible if true, and makes the camera video invisible if false.
    Return Value
    • 0: Success
    • -1: Failure
    bool previewIsCameraStreamShown ( const PreviewRef & preview , int32_t camera_id )
    OasisPreview.h
    Verifies whether the camera video is configured to be visible.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    Return Value
    • true: The camera video is configured to be visible.
    • false: The camera video is configured to be invisible.
    int32_t previewAlign ( const PreviewRef & preview , int32_t camera_id , PositionType horz_position , PositionType vert_position , bool show = true )
    OasisPreview.h
    Adjusts the position of the camera video window.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    horz_position  The horizontal position value. Specify one of left, center, right.
    vert_position  The vertical position value. Specify one of top, center, bottom.
    show  The video is shown if true, and the video is not shown if false.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetPos ( const PreviewRef & preview , int32_t camera_id , int32_t x , int32_t y )
    OasisPreview.h
    Specifies the position where the camera video is shown. If it exceeds the display size, it appears clipped.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    x  The left position of the camera video.
    y  The top position of the camera video.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetSize ( const PreviewRef & preview , int32_t camera_id , int32_t width , int32_t height )
    OasisPreview.h
    Specifies the size of the camera video. If it exceeds the display size range, it appears clipped.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    width  The width of the camera video.
    height  The height of the camera video.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetRect ( const PreviewRef & preview , int32_t camera_id , int32_t left , int32_t top , int32_t width , int32_t height )
    OasisPreview.h
    Specifies the position and size where the camera video is shown. If it exceeds the display size, it appears clipped.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    left  The left position of the camera video.
    top  The top position of the camera video.
    width  The width of the camera video.
    height  The height of the camera video.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetZOrder ( const PreviewRef & preview , int32_t camera_id , int32_t zorder )
    OasisPreview.h
    Specifies the sequence in which the camera video is shown on the screen. A higher value appears further in front.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    zorder  The visibility sequence value. Unrestricted, with a maximum value of INT_MAX.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetVisible ( const PreviewRef & preview , int32_t camera_id , bool show )
    OasisPreview.h
    Configures the camera video to be visible or invisible.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    show  Makes the camera video visible if true, and makes the camera video invisible if false.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewIsVisible ( const PreviewRef & preview , int32_t camera_id )
    OasisPreview.h
    Verifies whether the camera video is currently configured to be visible.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    Return Value
    • 1: Configured to be visible.
    • 0: Configured to be invisible.
    int32_t previewGetCameraFD ( const PreviewRef & preview , int32_t camera_id )
    OasisPreview.h
    When the camera device directly uses a /dev/video<N> device, it obtains the corresponding file descriptor.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    Return Value
    The handle number acquired by Oasis by opening the /dev/video<N> device. Returns -1 on failure.
    int32_t previewGetCameraLuminescenceValue ( const PreviewRef & preview , int32_t camera_id , int32_t * LV )
    OasisPreview.h
    Obtains the luminance value of the camera video. Applied only to AllWinner chipsets.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    LV  OUT Returns the luminance value.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewGetCameraColorTemperature ( const PreviewRef & preview , int32_t camera_id , int32_t * temperature )
    OasisPreview.h
    Obtains the color temperature of the camera video. Applied only to AllWinner chipsets.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    temperature  OUT Returns the temperature value.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewEnableWDR ( const PreviewRef & preview , int32_t camera_id , bool enable )
    OasisPreview.h
    Specifies whether to activate WDR on the camera device. Applied only to AllWinner chipsets.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    enable  Activates WDR if true. Deactivates WDR if false.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetISPCfg ( const PreviewRef & preview , int32_t camera_id , int group , uint32_t flags , void * cfg_data )
    OasisPreview.h
    Configures ISP data on the camera device. Applied only to AllWinner chipsets.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    group  The ISP group number.
    flags  The flag value.
    cfg_data  OUT The data pointer.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewGetISPCfg ( const PreviewRef & preview , int32_t camera_id , int group , uint32_t flags , void * cfg_data )
    OasisPreview.h
    Obtains the ISP configuration applied to the camera device. Applied only to AllWinner chipsets.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    group  The ISP group number.
    flags  The flag value.
    cfg_data  OUT The data pointer.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t previewSetZoom ( const PreviewRef & preview , int32_t camera_id , int32_t x , int32_t y , int32_t width , int32_t height )
    OasisPreview.h
    Zooms in on a specific region in the Preview object. Applied only when Preview is operating. If height or width is negative, the region zoom is released.
    Parameters
    preview  The Preview object created via createPreview.
    camera_id  The camera ID specified in configCameras.
    x  The x coordinate of the region.
    y  The y coordinate of the region.
    width  The width of the region.
    height  The height of the region.
    Return Value
    • 0: Success
    • -1: Failure

    Example#

    Single Camera Monitoring Example#

    Below is an example of monitoring video from the camera device ID 0.

    Initializes Oasis.

    // Does not use the file system.
    
    oasis::key_value_map_t parameters;
    
    parameters["offs-disable"] = "1";
    
    if(oasis::initialize(parameters) < 0) {
        DLOG(DLOG_ERROR, "Oasis init failed\n");
        return -1;
    }
    

    Initializes the camera device. Here, a single camera device is used.

    parameters.clear();
    
    parameters["source-count"] = "1";
    
    parameters["source1-camera-id"] = "0";
    parameters["source1-isp-id"] = "0";
    parameters["source1-isp-wdr-mode"] = "0";
    parameters["source1-capture-format"] = "YUV420";
    parameters["source1-capture-buffers"] = "5";
    parameters["source1-fps"] = "30";
    parameters["source1-subchannel-rotation"] = "0";
    parameters["source1-loc"] = "front";
    parameters["source1-capture-resolution"] = "1080p";
    parameters["source1-sensor-config"] = "./Resource_tp2863/VIC/0/tp2863_1920x1080_ch0.cfg";
    parameters["source1-autoscene-config"] = "./Resource_tp2863/AutoScene/autoscene_conf.cfg";
    parameters["source1-resource-dir"] = "./Resource_tp2863/";
    
    configCameras(parameters);  
    

    Initializes the display device.

    parameters.clear();
    
    parameters["memory-type"] = "ion"; //cma
    parameters["screen-width"] = "480";
    parameters["screen-height"] = "320";
    
    display::setup(parameters);
    

    Configures the GUI. In this example, touch is not used.

    parameters.clear();
    
    parameters["system-font-size"] = "10";
    parameters["system-font-path"] = "/mnt/sd/consola.ttf";
    parameters["display-rotation"] = "0";
    parameters["enable-touch"] = "0";
    
    err = ui::setup(parameters);
    if (err < 0) {
        DLOG(DLOG_ERROR, "Oasis ui::setup failed\n");
        return -1;
    }
    

    Initializes the Preview object.

    parameters.clear();
    
    // Obtains the default screen object and applies its width and height to the media player.
    ui::ScreenRef screen = ui::getDefaultScreen();
    
    int32_t screen_width = ui::screenWidth(screen);
    int32_t screen_height = ui::screenHeight(screen);
    
    
    // Creates a user-defined object derived from ui::PreviewFrameObserver.
    std::shared_ptr<MyPreviewFrameObserver> observer = std::make_shared<MyPreviewFrameObserver>();
    
    parameters["channel-count"] = "1";
    parameters["primary-channel"] = "1";
    
    parameters["channel1-camera-id"] = std::to_string(camera_id);
    parameters["channel1-visible"] = "1";
    parameters["channel1-rotation"] = std::to_string(rotation);
    // Configures the playback screen to full screen.
    parameters["channel1-x"] = "0";
    parameters["channel1-y"] = "0";
    parameters["channel1-width"] = std::to_string(screen_width);
    parameters["channel1-height"] = std::to_string(screen_height);
    parameters["channel1-zorder"] = "0";
    
    ui::PreviewRef preview = ui::createPreview(0, parameters);
    ui::setPreviewFrameObserver(preview, observer);
    

    Configures the screen layout. A Fixed layout container is used inside the top-level Window object, and the video screen is set to full screen.

    ui::WindowRef preview_panel = ui::createWindow("Preview1");
    
    ui::FixedRef fixed_layout = ui::createFixed();
    ui::containerAdd(preview_panel, fixed_layout);
    
    ui::setFixedSize(preview, screen_width, screen_height);
    ui::fixedPut(fixed_layout, preview, 0, 0);
    ui::screenAdd(screen, preview_panel);
    
    ui::setVisible(preview_panel, true);
    

    Starts monitoring.

    ui::previewStart(preview);
    

    An example of modifying the screen position during playback:

    ui::previewSetPos(preview, 0, 100, 100)
    

    Stops monitoring.

    ui::previewStop(preview);
    

    Below is the complete code:

    #include "OasisAPI.h"
    #include "OasisLog.h"
    #include "OasisMedia.h"
    #include "OasisUI.h"
    #include "OasisFS.h"
    #include "OasisUtil.h"
    #include "OasisDisplay.h"
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <dirent.h>
    
    #include <signal.h>
    
    #include <thread>
    #include <mutex>
    #include <memory>
    #include <condition_variable>
    
    using namespace oasis;
    
    
    static bool continue_previewing = true;
    
    void cancel_handler(int signum)
    {
        continue_previewing = false;
    }
    
    class MyPreviewFrameObserver : public ui::PreviewFrameObserver {
    public:
        MyPreviewFrameObserver() {}
        virtual ~MyPreviewFrameObserver() {}
    
        virtual void onFrame(int32_t camera_id, uint8_t *frame, int32_t stride_width, int32_t width, int32_t height) {
        }
        virtual void onNoMediaData(int32_t camera_id) {
            fprintf(stdout, "no media: camera<%d>\n", camera_id);
        }
    };
    
    void printUsage(const char *pgname)
    {
        fprintf(stderr, "USAGE: %s [-r <rotation. 90, 270>] <camera id>\n", pgname);
    }
    
    int main(int argc, char *argv[])
    {
        int32_t err;
        int c;
        int32_t rotation = 0;
        int32_t camera_id = -1;
    
        opterr = 0;
        while ((c = getopt(argc, argv, "r:h")) != -1) {
            switch (c) {
            case 'r':
                if(optarg == nullptr) {
                    fprintf(stderr, "error: bad option argument '%c'\n", optopt);
                    return -1;
                }
                rotation = atoi(optarg);
                if(rotation != 0 && rotation != 90 /*&& rotation != 180*/ && rotation != 270) {
                    fprintf(stderr, "bad rotation: %d\n", rotation);
                    return -1;
                }
                break;
            case 'h':
            default:
                printUsage(argv[0]);
                return -1;
            }
        }
    
        if(argc-optind < 1) {
            fprintf(stderr, "error: invalid or insufficient arguments (%d, %d)\n", argc, optind);
            printUsage(argv[0]);
            return -1;
        }
    
        camera_id = atoi(argv[optind]);
        if(camera_id < 0) {
            fprintf(stderr, "invalid camera id: %d\n", camera_id);
            return -1;
        }
    
    
        signal(SIGINT, cancel_handler);
    
        oasis::key_value_map_t parameters;
    
        ////////////////////////////////////////////////////////////////////////////////////////////
        // init
    
        parameters["offs-disable"] = "1";
    
        if(oasis::initialize(parameters) < 0) {
            DLOG(DLOG_ERROR, "Oasis init failed\n");
            return -1;
        }
    
        ////////////////////////////////////////////////////////////////////////////////////////////
        // camera sources
        parameters.clear();
    
        parameters["source-count"] = "1";
    
        parameters["source1-camera-id"] = "0";
        parameters["source1-isp-id"] = "0";
        parameters["source1-isp-wdr-mode"] = "0";
        parameters["source1-capture-format"] = "YUV420";
        parameters["source1-capture-buffers"] = "5";
        parameters["source1-fps"] = "30";
        parameters["source1-subchannel-rotation"] = "0";
        parameters["source1-loc"] = "front";
        parameters["source1-capture-resolution"] = "1080p";
        parameters["source1-sensor-config"] = "./Resource_tp2863/VIC/0/tp2863_1920x1080_ch0.cfg";
        parameters["source1-autoscene-config"] = "./Resource_tp2863/AutoScene/autoscene_conf.cfg";
        parameters["source1-resource-dir"] = "./Resource_tp2863/";
    
        configCameras(parameters);  
    
        ////////////////////////////////////////////////////////////////////////////////////////////
        // display setup
        parameters.clear();
    
        parameters["memory-type"] = "ion"; //cma
        parameters["screen-width"] = "480";
        parameters["screen-height"] = "320";
    
        display::setup(parameters);
    
    
        //////////////////////////////////////////////////////////////////////////////////////////
        // ui setup
        parameters.clear();
    
        parameters["system-font-size"] = "10";
        parameters["system-font-path"] = "/mnt/sd/consola.ttf";
    
        parameters["display-rotation"] = "0";
        parameters["enable-touch"] = "0";
    
        err = ui::setup(parameters);
        if (err < 0) {
            DLOG(DLOG_ERROR, "Oasis ui::setup failed\n");
            return -1;
        }
    
        /////////////////////////////////////////////////////////////////////////
        // create preview and layout
    
        ui::ScreenRef screen = ui::getDefaultScreen();
    
        int32_t screen_width = ui::screenWidth(screen);
        int32_t screen_height = ui::screenHeight(screen);
    
    
        parameters.clear();
    
    
        //preview_panel
        ui::WindowRef preview_panel = ui::createWindow("Preview1");
    
        ui::FixedRef fixed_layout = ui::createFixed();
        ui::containerAdd(preview_panel, fixed_layout);
    
        std::shared_ptr<MyPreviewFrameObserver> observer = std::make_shared<MyPreviewFrameObserver>();
    
        parameters["channel-count"] = "1";
        parameters["primary-channel"] = "1";
    
        parameters["channel1-camera-id"] = std::to_string(camera_id);
        parameters["channel1-visible"] = "1";
        parameters["channel1-rotation"] = std::to_string(rotation);
        parameters["channel1-x"] = "0";
        parameters["channel1-y"] = "0";
        parameters["channel1-width"] = std::to_string(screen_width);
        parameters["channel1-height"] = std::to_string(screen_height);
        parameters["channel1-zorder"] = "0";
    
        ui::PreviewRef preview = ui::createPreview(0, parameters);
        ui::setPreviewFrameObserver(preview, observer);
    
        ui::setFixedSize(preview, screen_width, screen_height);
        ui::fixedPut(fixed_layout, preview, 0, 0);
        ui::screenAdd(screen, preview_panel);
    
        ui::setVisible(preview_panel, true);
    
        ui::previewStart(preview);
    
        do {
            usleep(100000);
        } while (continue_previewing);
    
        ui::previewStop(preview);
    
        err = ui::cleanup();
    
        oasis::finalize();
    
        return 0;
    }
    

    4 Camera Monitoring and Layout Change Example#

    Initializes 4 camera devices.

    
    parameters["source-count"] = "4";
    
    parameters["source1-camera-id"] = "0";
    parameters["source1-isp-id"] = "0";
    parameters["source1-isp-wdr-mode"] = "0";
    parameters["source1-capture-format"] = "YUV420";
    parameters["source1-capture-buffers"] = "5";
    parameters["source1-fps"] = std::to_string(FPS);
    parameters["source1-subchannel-rotation"] = "0";
    parameters["source1-loc"] = "front";
    parameters["source1-capture-resolution"] = "1080p";
    parameters["source1-sensor-config"] = "./Resource/VIC/0/tp2855_1920x1080_ch0.cfg";
    parameters["source1-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
    parameters["source1-resource-dir"] = "./Resource/";
    
    parameters["source2-camera-id"] = "1";
    parameters["source2-isp-id"] = "0";
    parameters["source2-isp-wdr-mode"] = "0";
    parameters["source2-capture-format"] = "YUV420";
    parameters["source2-capture-buffers"] = "5";
    parameters["source2-fps"] = std::to_string(FPS);
    parameters["source2-subchannel-rotation"] = "0";
    parameters["source2-loc"] = "front";
    parameters["source2-capture-resolution"] = "1080p";
    parameters["source2-sensor-config"] = "./Resource/VIC/1/tp2855_1920x1080_ch1.cfg";
    parameters["source2-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
    parameters["source2-resource-dir"] = "./Resource/";
    
    parameters["source3-camera-id"] = "2";
    parameters["source3-isp-id"] = "0";
    parameters["source3-isp-wdr-mode"] = "0";
    parameters["source3-capture-format"] = "YUV420";
    parameters["source3-capture-buffers"] = "5";
    parameters["source3-fps"] = std::to_string(FPS);
    parameters["source3-subchannel-rotation"] = "0";
    parameters["source3-loc"] = "front";
    parameters["source3-capture-resolution"] = "1080p";
    parameters["source3-sensor-config"] = "./Resource/VIC/2/tp2855_1920x1080_ch2.cfg";
    parameters["source3-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
    parameters["source3-resource-dir"] = "./Resource/";
    
    parameters["source4-camera-id"] = "3";
    parameters["source4-isp-id"] = "0";
    parameters["source4-isp-wdr-mode"] = "0";
    parameters["source4-capture-format"] = "YUV420";
    parameters["source4-capture-buffers"] = "5";
    parameters["source4-fps"] = std::to_string(FPS);
    parameters["source4-subchannel-rotation"] = "0";
    parameters["source4-loc"] = "front";
    parameters["source4-capture-resolution"] = "1080p";
    parameters["source4-sensor-config"] = "./Resource/VIC/3/tp2860_1920x1080_ch3.cfg";
    parameters["source4-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
    parameters["source4-resource-dir"] = "./Resource/";
    
    configCameras(parameters);
    

    Creates the Preview object by configuring all 4 cameras to be monitored.

    The channel<N>-visible for each channel is set to "0" (hidden) upon Preview creation.

    parameters["channel-count"] = "4";
    parameters["primary-channel"] = "1";
    
    parameters["channel1-camera-id"] = "0";
    parameters["channel1-visible"] = "0";
    parameters["channel1-rotation"] = "0";
    parameters["channel1-x"] = "0";
    parameters["channel1-y"] = "0";
    parameters["channel1-width"] = "960";
    parameters["channel1-height"] = "360";
    parameters["channel1-zorder"] = "0";
    
    parameters["channel2-camera-id"] = "1";
    parameters["channel2-visible"] = "0";
    parameters["channel2-rotation"] = "0";
    parameters["channel2-x"] = "0";
    parameters["channel2-y"] = "360";
    parameters["channel2-width"] = "960";
    parameters["channel2-height"] = "360";
    parameters["channel2-zorder"] = "0";
    
    parameters["channel3-camera-id"] = "2";
    parameters["channel3-visible"] = "0";
    parameters["channel3-rotation"] = "0";
    parameters["channel3-x"] = "960";
    parameters["channel3-y"] = "0";
    parameters["channel3-width"] = "960";
    parameters["channel3-height"] = "360";
    parameters["channel3-zorder"] = "0";
    
    parameters["channel4-camera-id"] = "3";
    parameters["channel4-visible"] = "0";
    parameters["channel4-rotation"] = "0";
    parameters["channel4-x"] = "960";
    parameters["channel4-y"] = "360";
    parameters["channel4-width"] = "960";
    parameters["channel4-height"] = "360";
    parameters["channel4-zorder"] = "0";
    
    ui::PreviewRef preview = ui::createPreview(0, parameters);
    

    On a device with a screen resolution of 1920x720, 4 types of layouts are defined as follows.

    struct layout_info {
      int32_t count;
      Rect items[4];
    } layouts[4] = {
      [0] = {
        .count = 1,
        .items = {
          [0] = { 0, 0, 1920, 720}
        }
      },
      [1] = {
        .count = 2,
        .items = {
          [0] = { 0, 0, 960, 720},
          [1] = { 960, 0, 960, 720}
        }
      },
      [2] = {
        .count = 3,
        .items = {
          [0] = { 0, 0, 640, 720},
          [1] = { 640, 0, 640, 720},
          [2] = { 1280, 0, 640, 720}
        }
      },
      [3] = {
        .count = 4,
        .items = {
          [0] = { 0, 0, 960, 360},
          [1] = { 0, 360, 960, 360},
          [2] = { 960, 0, 960, 360},
          [3] = { 960, 360, 960, 360}
        }
      },
    };
    

    It is a maximum of 4 splits, and a camera ID is assigned to each split region. The relationship between the camera ID to be assigned and the region is defined and managed as a map.

    The example below changes the layout using the layout command, and assigns a camera ID to each region using the map command.

    The layout 1 command causes a single camera to occupy the entire screen.

    map 0 1 2 3 assigns a camera ID to each region. Even if the current layout is 1, camera IDs must also be specified for invisible regions.

    The command is executed in the setLayout function.

    int32_t layout_to_camera_map[4] = { 0, 1, 2, 3 };
    int32_t current_layout_index = 0;
    
    static void setLayout(const ui::PreviewRef &preview, int32_t layout_index)
    {
      int32_t i;
      for(i=0; i<layouts[layout_index].count; i++) {
        ui::previewSetRect(preview, layout_to_camera_map[i], layouts[layout_index].items[i].left, layouts[layout_index].items[i].top, layouts[layout_index].items[i].width, layouts[layout_index].items[i].height);
        ui::previewSetVisible(preview, layout_to_camera_map[i], true);
      }
      for(; i<4; i++) {
        ui::previewSetVisible(preview, layout_to_camera_map[i], false);
      }
      current_layout_index = layout_index;
    }
    

    When the example is executed, 4 cameras are shown in 4 split regions respectively.

      setLayout(preview, 3);
    

    The show command makes the Preview screen visible, and the hide command makes it invisible.

    Note

    Since the channel<N>-visible for each channel is set to "0" (hidden) upon Preview creation, you must call setLayout after calling ui::previewStart.

    Below is the complete code.

    #include "OasisAPI.h"
    #include "OasisLog.h"
    #include "OasisMedia.h"
    #include "OasisFS.h"
    #include "OasisUtil.h"
    #include "OasisUI.h"
    #include "OasisDisplay.h"
    
    #include "common.h"
    
    #include <thread>
    #include <mutex>
    #include <memory>
    #include <condition_variable>
    
    #include <signal.h>
    
    #include <iostream>
    #include <sstream>
    #include <cstdio>
    
    #define DLOG_THIS   0x00010000
    
    #undef DLOG_FLAGS
    #define  DLOG_FLAGS (DLOG_FLAGS_DEFAULT/*|DLOG_THIS*/)
    
    #undef DLOG_TAG
    #define DLOG_TAG "PREVIEW4"
    
    #define FPS 30
    #define MAX_LINE 4096
    
    using namespace oasis;
    
    static bool continue_previewing = true;
    
    struct layout_info {
      int32_t count;
      Rect items[4];
    } layouts[4] = {
      [0] = {
        .count = 1,
        .items = {
          [0] = { 0, 0, 1920, 720}
        }
      },
      [1] = {
        .count = 2,
        .items = {
          [0] = { 0, 0, 960, 720},
          [1] = { 960, 0, 960, 720}
        }
      },
      [2] = {
        .count = 3,
        .items = {
          [0] = { 0, 0, 640, 720},
          [1] = { 640, 0, 640, 720},
          [2] = { 1280, 0, 640, 720}
        }
      },
      [3] = {
        .count = 4,
        .items = {
          [0] = { 0, 0, 960, 360},
          [1] = { 0, 360, 960, 360},
          [2] = { 960, 0, 960, 360},
          [3] = { 960, 360, 960, 360}
        }
      },
    };
    
    int32_t layout_to_camera_map[4] = { 0, 1, 2, 3 };
    int32_t current_layout_index = 0;
    
    static void setLayout(const ui::PreviewRef &preview, int32_t layout_index)
    {
      int32_t i;
      for(i=0; i<layouts[layout_index].count; i++) {
        ui::previewSetRect(preview, layout_to_camera_map[i], layouts[layout_index].items[i].left, layouts[layout_index].items[i].top, layouts[layout_index].items[i].width, layouts[layout_index].items[i].height);
        ui::previewSetVisible(preview, layout_to_camera_map[i], true);
      }
      for(; i<4; i++) {
        ui::previewSetVisible(preview, layout_to_camera_map[i], false);
      }
      current_layout_index = layout_index;
    }
    
    class MyPreviewFrameObserver : public ui::PreviewFrameObserver {
    public:
      MyPreviewFrameObserver() {}
      virtual ~MyPreviewFrameObserver() {}
    
      virtual void onFrame(int32_t camera_id, uint8_t *frame, int32_t stride_width, int32_t width, int32_t height) {
      }
      virtual void onNoMediaData(int32_t camera_id) {
        fprintf(stdout, "no media: camera<%d>\n", camera_id);
      }
    };
    
    void print_usage(const char *pname)
    {
    
    }
    
    void cancel_handler(int signum)
    {
      continue_previewing = false;
    }
    
    
    
    
    int main(int argc, char* argv[])
    {
      int32_t c, err;
      char input[MAX_LINE];
    
      oasis::key_value_map_t parameters;
    
      signal(SIGINT, cancel_handler);
    
       ////////////////////////////////////////////////////////////////////////////////////////////
      // init
    
      parameters["offs-disable"] = "1";
      parameters["oasis-log-flags"] = std::to_string(OASIS_LOG_DEBUG/*|OASIS_LOG_ENCODE_BITRATE*/);
    
      if(oasis::initialize(parameters) < 0) {
        DLOG(DLOG_ERROR, "Oasis init failed\n");
        return -1;
      }
    
    
      ////////////////////////////////////////////////////////////////////////////////////////////
      // camera sources
      parameters.clear();
    
      parameters["source-count"] = "4";
    
      parameters["source1-camera-id"] = "0";
      parameters["source1-isp-id"] = "0";
      parameters["source1-isp-wdr-mode"] = "0";
      parameters["source1-capture-format"] = "YUV420";
      parameters["source1-capture-buffers"] = "5";
      parameters["source1-fps"] = std::to_string(FPS);
      parameters["source1-subchannel-rotation"] = "0";
      parameters["source1-loc"] = "front";
      parameters["source1-capture-resolution"] = "1080p";
      parameters["source1-sensor-config"] = "./Resource/VIC/0/tp2855_1920x1080_ch0.cfg";
      parameters["source1-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
      parameters["source1-resource-dir"] = "./Resource/";
    
      parameters["source2-camera-id"] = "1";
      parameters["source2-isp-id"] = "0";
      parameters["source2-isp-wdr-mode"] = "0";
      parameters["source2-capture-format"] = "YUV420";
      parameters["source2-capture-buffers"] = "5";
      parameters["source2-fps"] = std::to_string(FPS);
      parameters["source2-subchannel-rotation"] = "0";
      parameters["source2-loc"] = "front";
      parameters["source2-capture-resolution"] = "1080p";
      parameters["source2-sensor-config"] = "./Resource/VIC/1/tp2855_1920x1080_ch1.cfg";
      parameters["source2-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
      parameters["source2-resource-dir"] = "./Resource/";
    
      parameters["source3-camera-id"] = "2";
      parameters["source3-isp-id"] = "0";
      parameters["source3-isp-wdr-mode"] = "0";
      parameters["source3-capture-format"] = "YUV420";
      parameters["source3-capture-buffers"] = "5";
      parameters["source3-fps"] = std::to_string(FPS);
      parameters["source3-subchannel-rotation"] = "0";
      parameters["source3-loc"] = "front";
      parameters["source3-capture-resolution"] = "1080p";
      parameters["source3-sensor-config"] = "./Resource/VIC/2/tp2855_1920x1080_ch2.cfg";
      parameters["source3-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
      parameters["source3-resource-dir"] = "./Resource/";
    
      parameters["source4-camera-id"] = "3";
      parameters["source4-isp-id"] = "0";
      parameters["source4-isp-wdr-mode"] = "0";
      parameters["source4-capture-format"] = "YUV420";
      parameters["source4-capture-buffers"] = "5";
      parameters["source4-fps"] = std::to_string(FPS);
      parameters["source4-subchannel-rotation"] = "0";
      parameters["source4-loc"] = "front";
      parameters["source4-capture-resolution"] = "1080p";
      parameters["source4-sensor-config"] = "./Resource/VIC/3/tp2860_1920x1080_ch3.cfg";
      parameters["source4-autoscene-config"] = "./Resource/AutoScene/autoscene_conf.cfg";
      parameters["source4-resource-dir"] = "./Resource/";
    
      configCameras(parameters);
    
    
      ////////////////////////////////////////////////////////////////////////////////////////////
      // display setup
      parameters.clear();
    
      parameters["memory-type"] = "ion"; //cma
      parameters["screen-width"] = "720";
      parameters["screen-height"] = "1920";
    
      display::setup(parameters);
    
      //////////////////////////////////////////////////////////////////////////////////////////
      // ui setup
      parameters.clear();
    
      parameters["system-font-size"] = "10";
      parameters["system-font-path"] = "/mnt/flash/leipzig/consola.ttf";
    
      parameters["display-rotation"] = "270";
      parameters["enable-touch"] = "0";
    
      parameters["fb0-hlayer"] = "0:1:0";
      parameters["vi0-hlayer"] = "0:0:0";
    
      err = ui::setup(parameters);
      if (err < 0) {
        DLOG(DLOG_ERROR, "Oasis ui::setup failed\n");
        return -1;
      }
    
    
      /////////////////////////////////////////////////////////////////////////
      // create preview and layout
    
      ui::ScreenRef screen = ui::getDefaultScreen();
      //ASSERT(screen != nullptr);
    
      int32_t screen_width = ui::screenWidth(screen);
      int32_t screen_height = ui::screenHeight(screen);
    
    
      //preview_panel
      ui::WindowRef preview_panel = ui::createWindow("Preview1");
      //ASSERT(preview_panel != nullptr);
    
      ui::FixedRef fixed_layout = ui::createFixed();
      ui::containerAdd(preview_panel, fixed_layout);
    
      std::shared_ptr<MyPreviewFrameObserver> observer = std::make_shared<MyPreviewFrameObserver>();
    
      parameters["channel-count"] = "4";
      parameters["primary-channel"] = "1";
    
      parameters["channel1-camera-id"] = "0";
      parameters["channel1-visible"] = "0";
      parameters["channel1-rotation"] = "0";
      parameters["channel1-x"] = "0";
      parameters["channel1-y"] = "0";
      parameters["channel1-width"] = "960";
      parameters["channel1-height"] = "360";
      parameters["channel1-zorder"] = "0";
    
      parameters["channel2-camera-id"] = "1";
      parameters["channel2-visible"] = "0";
      parameters["channel2-rotation"] = "0";
      parameters["channel2-x"] = "0";
      parameters["channel2-y"] = "360";
      parameters["channel2-width"] = "960";
      parameters["channel2-height"] = "360";
      parameters["channel2-zorder"] = "0";
    
      parameters["channel3-camera-id"] = "2";
      parameters["channel3-visible"] = "0";
      parameters["channel3-rotation"] = "0";
      parameters["channel3-x"] = "960";
      parameters["channel3-y"] = "0";
      parameters["channel3-width"] = "960";
      parameters["channel3-height"] = "360";
      parameters["channel3-zorder"] = "0";
    
      parameters["channel4-camera-id"] = "3";
      parameters["channel4-visible"] = "0";
      parameters["channel4-rotation"] = "0";
      parameters["channel4-x"] = "960";
      parameters["channel4-y"] = "360";
      parameters["channel4-width"] = "960";
      parameters["channel4-height"] = "360";
      parameters["channel4-zorder"] = "0";
    
      ui::PreviewRef preview = ui::createPreview(0, parameters);
      ui::setPreviewFrameObserver(preview, observer);
    
      ui::setFixedSize(preview, screen_width, screen_height);
      ui::fixedPut(fixed_layout, preview, 0, 0);
      ui::screenAdd(screen, preview_panel);
    
      ui::setVisible(preview_panel, true);
    
      ui::previewStart(preview);
    
      setLayout(preview, 3);
    
      do {
        printf("Enter command (h for help. q for quit): ");
        if(fgets(input, sizeof(input), stdin) == nullptr) {
          break;
        }
    
        std::stringstream ss(input);
        std::string token;
        std::vector<std::string> args;
    
        while (ss >> token) {
          args.push_back(token);
        }
    
        if(args.empty()) {
          continue;
        }
    
        if(args[0] == "h") {
          printf("\n");
          printf("layout <layout number>: 1, 2, 3, 4. In case of no arguments, the current layout is printed.\n");
          printf("map <camera id for region 0> <camera id for region 1> <camera id for region 2> <camera id for region 3>\n");
          printf("show: show and start previewing.\n");
          printf("hide: stop and hide previewing.\n");
          printf("\n");
        } else if(args[0] == "q") {
          break;
        } else if(args[0] == "layout") {
          if(args.size() == 1) {
            printf("current layout: %d\n", current_layout_index+1);
          } else {
            int32_t layout_index = atoi(args[1].c_str()) - 1;
            if(layout_index < 0 || layout_index > 3) {
              printf("invalid value: %d\n", layout_index+1);
            } else {
              setLayout(preview, layout_index);
            }
          }
        } else if(args[0] == "map") {
          if(args.size() == 1) {
            printf("current map: ");
            for(int32_t i=0; i<4; i++) {
              printf("%d ", layout_to_camera_map[i]);
            }
            printf("\n");
          } else if(args.size() == 5) {
            bool has_error = false;
            int32_t new_map[4] = { -1, -1, -1, -1 };
            auto is_dup_camera_id = [&](int32_t n, int32_t val) {
              for(int32_t i=0; i<n; i++) {
                if(new_map[i] == val) {
                  return true;
                }
              }
              return false;
            };
            for(int32_t i=0; i<4; i++) {
              int32_t camera_id = atoi(args[i+1].c_str());
              if(camera_id < 0 || camera_id > 3) {
                printf("invalid value: %d\n", camera_id);
                has_error = false;
                break;
              }
              if(is_dup_camera_id(i, camera_id)) {
                printf("duplicate value: %d\n", camera_id);
                has_error = false;
                break;
              }
              new_map[i] = camera_id;
            }
            if(!has_error) {
              printf("map updated\n");
              memcpy(layout_to_camera_map, new_map, sizeof(layout_to_camera_map));
              setLayout(preview, current_layout_index);
            }
          } else {
            printf("insufficent arguments: %d\n", args.size());
          }
        } else if(args[0] == "show") {
          ui::setVisible(preview_panel, true);
          ui::previewStart(preview);
          setLayout(preview, current_layout_index);
        } else if(args[0] == "hide") {
          ui::previewStop(preview);
          ui::setVisible(preview_panel, false);
        }
    
      } while (continue_previewing == true);
    done:
    
      ui::previewStop(preview);
    
      err = ui::cleanup();
    
      oasis::finalize();
    
    
      return 0;
    }