영상 모니터링 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);
};
void onFrame ( int32_t camera_id , uint8_t * frame , int32_t stride_width , int32_t width , int32_t height )
OasisPreview.h
화면에 보여지는 영상 프레임을 전달합니다.
매개변수
camera_id  configCameras()에서 지정한 카메라 ID입니다.
frame  프레임 시작 포인터입니다.
stride_width  프레임 너비 stride 입니다.
width  프레임 너비입니다.
height  프레임 높이입니다.

영상 프레임 포맷이 YUV420인 경우, 아래와 같은 수식으로 Y,U,V 채널을 얻을 수 있습니다.

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
카메라 장치로 부터 영상 정보를 일정 시간 동안 얻을 수 없을 경우 발생합니다.
매개변수
camera_id  configCameras()에서 지정한 카메라 ID입니다.

함수

PreviewRef createPreview ( int32_t display_id , key_value_map_t & parameters )
OasisPreview.h
Preview 객체를 생성합니다.
매개변수
display_id  Display 장치 ID 입니다. "0"을 지정합니다.
parameters  Preview 객체를 생성하기 위해 필요한 key-value map입니다.
리턴값
성공하면 Preview 객체를 리턴하고, 실패하면 nullptr를 리턴합니다.
기본값
필수
설명
rotation
0
 
영상 회전 각도를 지정합니다. 0, 90, 270, 180 값중 하나를 지정합니다. 일괄적으로 회전을 지정할 경우 사용되며, channel<N>-rotation 키값으로 개별 영상 채널별로 회전 각도를 지정할 수 있습니다.
channel-count
모니터링할 채널(카메라 장치) 개수 입니다.
primary-channel
주 채널 번호를 지정합니다. 시작번호는 1입니다.

각 영상 채널에 대한 key-value map 값은 각 키값 앞에 prefix로 channel<N>- 이 붙습니다. <N>은 1부터 시작하여 1씩 증가합니다.

기본값
필수
설명
channel<N>-camera-id
configCameras에서 지정한 모니터링 할 카메라 장치 ID입니다.
channel<N>-ise-id
-1
 
AllWinner 전용 키 값으로 ISE 장치 ID입니다.
channel<N>-rotation
0
 
영상 채널 회전 각도를 지정합니다. 0, 90, 270, 180 값중 하나를 지정합니다
channel<N>-x
영상 채널의 x좌표를 지정합니다.
channel<N>-y
영상 채널의 y좌표를 지정합니다.
channel<N>-width
영상 채널의 너비를 지정합니다.
channel<N>-height
영상 채널의 높이를 지정합니다.
channel<N>-zorder
0
 
영상 채널의 보여지는 순번을 지정합니다. 높을 수록 앞에 보여집니다.
channel<N>-enable-adas
0
 
ADAS 활성화 여부를 지정합니다. 하나의 영상 채널에서만 가능합니다.
channel<N>-adas-inference-model-names
 
ADAS에 적용할 추론 모델 목록입니다.
int32_t setPreviewFrameObserver ( const PreviewRef & preview , const std::shared_ptr<PreviewFrameObserver> & observer )
OasisPreview.h
Preview 객체에 PreviewFrameObserver에서 유도된 사용자 정의 observer 객체를 지정합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
observer 
리턴값
  • 0: 성공
  • -1: 실패
int32_t destroyPreview ( const PreviewRef & preview )
OasisPreview.h
Preview 객체를 해제합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewStart ( const PreviewRef & preview )
OasisPreview.h
Preview를 시작합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewStop ( const PreviewRef & preview )
OasisPreview.h
Preview를 중지합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
리턴값
  • 0: 성공
  • -1: 실패
bool previewIsRunning ( const PreviewRef & preview )
OasisPreview.h
Preview가 동작 중인지 확인합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
리턴값
  • true: 동작 중입니다.
  • false: 동작 중이 아닙니다.
int32_t previewGetCameraIdOfChannel ( const PreviewRef & preview , const char * channel_id )
OasisPreview.h
Preview 객체의 채널에 연결된 카메라 장치 ID를 얻습니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
channel_id  채널 ID 문자열입니다. 채널 1번인 경우, "channel1"로 지정합니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewShowCameraStream ( const PreviewRef & preview , int32_t camera_id , bool show )
OasisPreview.h
Preview 객체가 카메라 장치로 부터 출력되는 영상을 보거나 보이지게 않게 합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
show  true이면 카메라 영상이 보이게 하고, false이면 카메라 영상이 보이지 않게 합니다.
리턴값
  • 0: 성공
  • -1: 실패
bool previewIsCameraStreamShown ( const PreviewRef & preview , int32_t camera_id )
OasisPreview.h
카메라 영상이 보이도록 설정되었는 지 확인합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
리턴값
  • true: 카메라 영상이 보이도록 설정되었습니다.
  • false: 카메라 영상이 보이지 않도록 설정되었습니다.
int32_t previewAlign ( const PreviewRef & preview , int32_t camera_id , PositionType horz_position , PositionType vert_position , bool show = true )
OasisPreview.h
카메라 영상 창의 위치를 조정합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
horz_position  수평 위치 값입니다. left, center, right 중 하나의 값을 지정합니다.
vert_position  수직 위치 값입니다. top, center, bottom 중 하나의 값을 지정합니다.
show  true이면 영상이 보여지고, false이면 영상이 보이지 않습니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetPos ( const PreviewRef & preview , int32_t camera_id , int32_t x , int32_t y )
OasisPreview.h
카메라 영상이 보여지는 위치를 지정합니다. 디스플레이 크기에 벗어나면 짤려서 보입니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
x  카메라 영상의 왼쪽 위치입니다.
y  카메라 영상의 위쪽 위치입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetSize ( const PreviewRef & preview , int32_t camera_id , int32_t width , int32_t height )
OasisPreview.h
카메라 영상의 크기를 지정합니다. 디스플레이 크기 범위를 벗어난 경우, 짤려서 보입니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
width  카메라 영상의 너비입니다.
height  카메라 영상의 높이입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetRect ( const PreviewRef & preview , int32_t camera_id , int32_t left , int32_t top , int32_t width , int32_t height )
OasisPreview.h
카메라 영상이 보이지는 위치와 크기를 지정합니다. 디스플레이 크기에 벗어나면 짤려서 보입니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
left  카메라 영상의 왼쪽 위치입니다.
top  카메라 영상의 위쪽 위치입니다.
width  카메라 영상의 너비입니다.
height  카메라 영상의 높이입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetZOrder ( const PreviewRef & preview , int32_t camera_id , int32_t zorder )
OasisPreview.h
카메라 영상이 화면에 보이지는 순서를 지정합니다. 높을 수록 앞에 보여집니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
zorder  보이는 순서 값입니다. 최대값에 __INT_MAX__로 제한이 없습니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetVisible ( const PreviewRef & preview , int32_t camera_id , bool show )
OasisPreview.h
카메라 영상을 보이거나 보이지 않도록 설정합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
show  true이면 카메라 영상이 보이게 하고, false이면 카메라 영상이 보이지 않게 합니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewIsVisible ( const PreviewRef & preview , int32_t camera_id )
OasisPreview.h
카메라 영상이 현재 보이도록 설정되었는 지 확인합니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
리턴값
  • 1: 보이도록 설정되었습니다.
  • 0: 보이지 않도록 설정되었습니다.
int32_t previewGetCameraFD ( const PreviewRef & preview , int32_t camera_id )
OasisPreview.h
카메라 장치가 /dev/video<N> 장치를 직접 사용하는 경우, 해당 파일 디스크립터를 얻습니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
리턴값
Oasis가 /dev/video<N> 장치를 열어서 획득한 핸들 번호입니다. 실패하면 -1을 리턴합니다.
int32_t previewGetCameraLuminescenceValue ( const PreviewRef & preview , int32_t camera_id , int32_t * LV )
OasisPreview.h
카메라 영상의 밝기 값을 얻습니다. AllWinner 칩셋에만 적용됩니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
LV  OUT 밝기 값을 리턴합니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewGetCameraColorTemperature ( const PreviewRef & preview , int32_t camera_id , int32_t * temperature )
OasisPreview.h
카메라 영상의 색상온도를 얻습니다. AllWinner 칩셋에만 적용됩니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
temperature  OUT 온도 값을 리턴합니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewEnableWDR ( const PreviewRef & preview , int32_t camera_id , bool enable )
OasisPreview.h
카메라 장치에 WDR 활성화 여부를 지정합니다. AllWinner 칩셋에만 적용됩니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
enable  true이면 WDR 활성화합니다. false이면 비활성화합니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetISPCfg ( const PreviewRef & preview , int32_t camera_id , int group , uint32_t flags , void * cfg_data )
OasisPreview.h
카메라 장치에 ISP 데이터를 설정합니다. AllWinner 칩셋에만 적용됩니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
group  ISP 그룹 번호입니다.
flags  플래그 값입니다.
cfg_data  OUT 데이터 포인터입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewGetISPCfg ( const PreviewRef & preview , int32_t camera_id , int group , uint32_t flags , void * cfg_data )
OasisPreview.h
카메라 장치에 적용된 ISP 설정을 얻습니다. AllWinner 칩셋에만 적용됩니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
group  ISP 그룹 번호입니다.
flags  플래그 값입니다.
cfg_data  OUT 데이터 포인터입니다.
리턴값
  • 0: 성공
  • -1: 실패
int32_t previewSetZoom ( const PreviewRef & preview , int32_t camera_id , int32_t x , int32_t y , int32_t width , int32_t height )
OasisPreview.h
Preview 객체에 특정 영역을 확대해서 보여줍니다. Preview가 동작 중일 때만 적용됩니다. 높이나 너비가 음수인 경우, 영역 확대가 해제됩니다.
매개변수
preview  createPreview로 생성한 Preview 객체입니다.
camera_id  configCameras에서 지정한 카메라 ID입니다.
x  영역의 x좌표입니다.
y  영역의 y좌표입니다.
width  영역의 너비입니다.
height  영역의 높이입니다.
리턴값
  • 0: 성공
  • -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;
}