영상 모니터링 API#
oasis::ui 네임스페이스 범주에서 호출됩니다.
헤더 파일#
OasisPreview.h
PreviewFrameObserver 인터페이스#
Preview 객체에 setPreviewFrameObserver 함수를 이용하여 PreviewFrameObserver에서 유도된 사용자 정의 observer 객체를 지정할 수 있습니다.
응용 프로그램은 onFrame 콜백 함수를 통해 화면에 보여지는 영상 프레임을 얻을 수 있습니다.
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);
};
configCameras에서 지정한 카메라 ID입니다.
영상 프레임 포맷이 YUV420인 경우, 아래와 같은 수식으로 Y,U,V 채널을 얻을 수 있습니다.
uint8_t *y = frame;
uint8_t *u = frame + stride_width * height;
uint8_t *v = u + stride_width * height / 4;
configCameras에서 지정한 카메라 ID입니다.
함수#
key_value_map_t &
parameters
)
channel<N>-rotation 키값으로 개별 영상 채널별로 회전 각도를 지정할 수 있습니다.각 영상 채널에 대한 key-value map 값은 각 키값 앞에 prefix로 channel<N>- 이 붙습니다. <N>은 1부터 시작하여 1씩 증가합니다.
PreviewFrameObserver> &
observer
)
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
- 0: 성공
- -1: 실패
createPreview 호출 시 전달한 key-value map을 사용합니다.
createPreview로 생성한 Preview 객체입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
- true: 동작 중입니다.
- false: 동작 중이 아닙니다.
createPreview로 생성한 Preview 객체입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
true이면 카메라 영상이 보이게 하고, false이면 카메라 영상이 보이지 않게 합니다.
- 0: 성공
- -1: 실패
- true: 카메라 영상이 보이도록 설정되었습니다.
- false: 카메라 영상이 보이지 않도록 설정되었습니다.
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
true이면 영상이 보여지고, false이면 영상이 보이지 않습니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
true이면 카메라 영상이 보이게 하고, false이면 카메라 영상이 보이지 않게 합니다.
- 0: 성공
- -1: 실패
- 1: 보이도록 설정되었습니다.
- 0: 보이지 않도록 설정되었습니다.
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
true이면 WDR 활성화합니다. false이면 비활성화합니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
createPreview로 생성한 Preview 객체입니다.
configCameras에서 지정한 카메라 ID입니다.
- 0: 성공
- -1: 실패
예제#
카메라 1개 모니터링 예#
아래는 카메라 장치 ID 0 영상을 모니터링하는 예입니다.
Oasis를 초기화 합니다.
// 파일시스템을 사용하지 않습니다.
oasis::key_value_map_t parameters;
parameters["offs-disable"] = "1";
if(oasis::initialize(parameters) < 0) {
DLOG(DLOG_ERROR, "Oasis init failed\n");
return -1;
}
카메라 장치를 초기화 합니다. 여기서는 카메라 장치 한개를 사용합니다.
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);
디스프레이 장치를 초기화 합니다.
parameters.clear();
parameters["memory-type"] = "ion"; //cma
parameters["screen-width"] = "480";
parameters["screen-height"] = "320";
display::setup(parameters);
GUI를 설정합니다. 여기 예에서는 터치를 사용하지 않습니다.
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;
}
Preview 객체를 초기화 합니다.
parameters.clear();
// 기본 스크린 객체를 얻고 너비와 높이를 미디어플레이어에 적용합니다.
ui::ScreenRef screen = ui::getDefaultScreen();
int32_t screen_width = ui::screenWidth(screen);
int32_t screen_height = ui::screenHeight(screen);
// 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);
// 재생 화면을 전체 스크린으로 지정합니다.
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);
화면을 구성합니다. 최상위 Window 객체에 Fixed 레이아웃 컨테이너를 이용하고, 영상화면은 전체화면으로 설정합니다.
ui::WindowRef preview_panel = ui::createWindow("Preview1");
//ASSERT(preview_panel != nullptr);
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);
모니터링을 시작합니다.
ui::previewStart(preview);
재생 중 화면 위치를 변경하는 예입니다.
ui::previewSetPos(preview, 0, 100, 100)
모니터링을 중지합니다.
ui::previewStop(preview);
아래는 전체 코드입니다.
#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();
//ASSERT(screen != nullptr);
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");
//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"] = "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개 모니터링 및 레이아웃 변경 예#
카메라 4개 장치를 초기화합니다.
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);
Preview 객체를 모니터링 할 카메라 4개 모두를 구성하여 생성합니다.
각 채널의 channel<N>-visible 은 Preview 생성 시, "0" (hidden)으로 설정되어 있습니다.
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);
화면 해상도가 1920x720 인 장치에서, 아래와 같이 4가지 레이아웃을 정의합니다.
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}
}
},
};
최대 4분할이며, 각 분할 영역에 카메라 ID가 할당됩니다. 할당될 카메라 ID와 영역 관계를 map 으로 정의하여 관리합니다.
아래 예는 layout 명령으로 레이아웃을 변경하며, map 명령으로 각 영역에 카메라 ID를 할당합니다.
layout 1 명령은 한 개 카메라가 화면 전체를 차지합니다.
map 0 1 2 3 은 각 영역에 카메라 ID를 할당합니다. 현재 레이아웃이 1 이라도, 보이지 않는 영역에도 카메라 ID를 지정해야 합니다.
명령은 setLayout 함수에서 수행됩니다.
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;
}
예를 실행하면, 카메라 4개가 4분할된 영역에 각각 보여집니다.
setLayout(preview, 3);
show 명령은 Preview 화면을 보이게 하고, hide 명령은 보이지 않게 합니다.
Note
각 채널의 channel<N>-visible 은 Preview 생성 시, "0" (hidden)으로 설정되어 있기 때문에, ui::previewStart 호출 후, setLayout 을 호출해야 합니다.
아래는 전체 코드입니다.
#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;
}