1233 lines
34 KiB
C
Executable File
1233 lines
34 KiB
C
Executable File
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/ioctl.h>
|
|
#include <asm/types.h>
|
|
#include <linux/fb.h>
|
|
#include <linux/videodev2.h>
|
|
#include <sys/time.h>
|
|
#include <ion_mem_alloc.h>
|
|
#include <videoOutPort.h>
|
|
#include "yuv_rotate.h"
|
|
|
|
#ifdef __SUNXI_DISPLAY__
|
|
#include "sunxi_display_v1.h"
|
|
#define CHN_NUM 2
|
|
#define ZORDER_MAX 3
|
|
#define ZORDER_MID 1
|
|
#endif
|
|
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
#include "sunxi_display_v2.h"
|
|
#define CHN_NUM 3
|
|
#define ZORDER_MAX 11
|
|
#define ZORDER_MID 5
|
|
#endif
|
|
|
|
#define RET_OK 0
|
|
#define RET_FAIL (-1)
|
|
#define SCREEN_0 0
|
|
#define SCREEN_1 1
|
|
|
|
|
|
#define LYL_NUM 4
|
|
#define HLAY(chn, lyl) (chn*4+lyl)
|
|
#define HD2CHN(hlay) (hlay/4)
|
|
#define HD2LYL(hlay) (hlay%4)
|
|
|
|
#define ZORDER_MIN 0
|
|
#define DISP_DEV_NAME ("/dev/disp")
|
|
|
|
/*#define DISP_DEBUG*/
|
|
#define DISP_CLAR(x) memset(&(x), 0, sizeof(x))
|
|
static unsigned char DISP_LOG = 0;
|
|
#define DISP_DBG_LOG if(DISP_LOG) printf
|
|
|
|
unsigned int mLayerStatus[CHN_NUM][LYL_NUM];
|
|
|
|
static long long GetNowUs() {
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
return (long long)tv.tv_sec * 1000000ll + tv.tv_usec;
|
|
}
|
|
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
static int LayerConfig(int fd, __DISP_t cmd, disp_layer_config *pinfo)
|
|
{
|
|
DISP_DBG_LOG("(%s %d)\n", __FUNCTION__, __LINE__);
|
|
unsigned long args[4] = {0};
|
|
unsigned int ret = RET_OK;
|
|
|
|
args[0] = SCREEN_0;
|
|
args[1] = (unsigned long)pinfo;
|
|
args[2] = 1;
|
|
ret = ioctl(fd, cmd, args);
|
|
if(RET_OK != ret) {
|
|
DISP_DBG_LOG("fail to get para\n");
|
|
ret = RET_FAIL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int LayerGetPara(int disp_fd, disp_layer_config *pinfo)
|
|
{
|
|
return LayerConfig(disp_fd, DISP_LAYER_GET_CONFIG, pinfo);
|
|
}
|
|
|
|
static int LayerSetPara(int disp_fd, disp_layer_config *pinfo)
|
|
{
|
|
return LayerConfig(disp_fd, DISP_LAYER_SET_CONFIG, pinfo);
|
|
}
|
|
|
|
static int LayerRender(int fd, unsigned int hlay, renderBuf *picture)
|
|
{
|
|
int ret;
|
|
disp_layer_config config;
|
|
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(hlay);
|
|
config.layer_id = HD2LYL(hlay);
|
|
LayerGetPara(fd, &config);
|
|
config.info.fb.addr[0] = picture->y_phaddr;
|
|
config.info.fb.addr[1] = picture->u_phaddr;
|
|
config.info.fb.addr[2] = picture->v_phaddr;
|
|
ret = LayerSetPara(fd, &config);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int layer_set_src(int fd, unsigned int hlay, SrcInfo *src)
|
|
{
|
|
unsigned long args[4] = {0};
|
|
disp_layer_config config;
|
|
|
|
DISP_DBG_LOG("(%s %d)\n", __FUNCTION__, __LINE__);
|
|
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(hlay);
|
|
config.layer_id = HD2LYL(hlay);
|
|
LayerGetPara(fd, &config);
|
|
|
|
config.info.fb.crop.x = src->crop_x;
|
|
config.info.fb.crop.y = src->crop_y;
|
|
config.info.fb.crop.width = (src->crop_w);
|
|
config.info.fb.crop.height = (src->crop_h);
|
|
|
|
DISP_DBG_LOG("width: 0x%llx, height: 0x%llx",
|
|
config.info.fb.crop.width, config.info.fb.crop.height);
|
|
|
|
config.info.fb.crop.x = config.info.fb.crop.x << 32;
|
|
config.info.fb.crop.y = config.info.fb.crop.y << 32;
|
|
config.info.fb.crop.width = config.info.fb.crop.width << 32;
|
|
config.info.fb.crop.height = config.info.fb.crop.height << 32;
|
|
|
|
DISP_DBG_LOG("width: 0x%llx, height: 0x%llx\n",
|
|
config.info.fb.crop.width, config.info.fb.crop.height);
|
|
|
|
config.info.fb.size[0].width = src->w;
|
|
config.info.fb.size[0].height = src->h;
|
|
config.info.fb.color_space = (disp_color_space)src->color_space;
|
|
switch(src->format) {
|
|
case VIDEO_PIXEL_FORMAT_YUV_PLANER_420:
|
|
config.info.fb.format = DISP_FORMAT_YUV420_P;
|
|
config.info.fb.size[1].width = src->w/2;
|
|
config.info.fb.size[1].height = src->h/2;
|
|
config.info.fb.size[2].width = src->w/2;
|
|
config.info.fb.size[2].height = src->h/2;
|
|
break;
|
|
|
|
case VIDEO_PIXEL_FORMAT_YV12:
|
|
config.info.fb.format = DISP_FORMAT_YUV420_P;
|
|
config.info.fb.size[1].width = src->w/2;
|
|
config.info.fb.size[1].height = src->h/2;
|
|
config.info.fb.size[2].width = src->w/2;
|
|
config.info.fb.size[2].height = src->h/2;
|
|
break;
|
|
|
|
case VIDEO_PIXEL_FORMAT_NV12:
|
|
config.info.fb.format = DISP_FORMAT_YUV420_SP_UVUV;
|
|
config.info.fb.size[1].width = src->w/2;
|
|
config.info.fb.size[2].width = src->w/2;
|
|
config.info.fb.size[1].height = src->h/2;
|
|
config.info.fb.size[2].height = src->h/2;
|
|
break;
|
|
|
|
case VIDEO_PIXEL_FORMAT_NV21:
|
|
config.info.fb.format = DISP_FORMAT_YUV420_SP_VUVU;
|
|
config.info.fb.size[1].width = src->w/2;
|
|
config.info.fb.size[2].width = src->w/2;
|
|
config.info.fb.size[1].height = src->h/2;
|
|
config.info.fb.size[2].height = src->h/2;
|
|
break;
|
|
|
|
default:
|
|
config.info.fb.format = DISP_FORMAT_ARGB_8888;
|
|
config.info.fb.size[1].width = src->w;
|
|
config.info.fb.size[1].height = src->h;
|
|
config.info.fb.size[2].width = src->w;
|
|
config.info.fb.size[2].height = src->h;
|
|
break;
|
|
}
|
|
DISP_DBG_LOG("set fb.format %d %d, color_space %d end\n",
|
|
src->format, config.info.fb.format, config.info.fb.color_space);
|
|
|
|
return LayerSetPara(fd, &config);
|
|
}
|
|
|
|
int LayerRequest(int *pCh, int *pId)
|
|
{
|
|
DISP_DBG_LOG("(%s %d)\n", __FUNCTION__, __LINE__);
|
|
int ch;
|
|
int id;
|
|
{
|
|
for (id = 0; id < LYL_NUM; id++) {
|
|
for (ch = 0; ch < CHN_NUM; ch++) {
|
|
if (!(mLayerStatus[ch][id] & LAYER_STATUS_REQUESTED)) {
|
|
mLayerStatus[ch][id] |= LAYER_STATUS_REQUESTED;
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
if ((ch == CHN_NUM) && (id == LYL_NUM)) {
|
|
DISP_DBG_LOG("all layer used.");
|
|
return RET_FAIL;
|
|
}
|
|
*pCh = ch;
|
|
*pId = id;
|
|
DISP_DBG_LOG("requested: ch:%d, id:%d\n", ch, id);
|
|
return HLAY(ch, id);
|
|
}
|
|
|
|
int LayerClose(int fd, unsigned int hlay)
|
|
{
|
|
disp_layer_config config;
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(hlay);
|
|
config.layer_id = HD2LYL(hlay);
|
|
LayerGetPara(fd, &config);
|
|
config.enable = 0;
|
|
return LayerSetPara(fd, &config);
|
|
}
|
|
|
|
int LayerRelease(int fd, unsigned int hlay)
|
|
{
|
|
int chn = HD2CHN(hlay);
|
|
int lyl = HD2LYL(hlay);
|
|
int ret = LayerClose(fd, hlay);
|
|
if (RET_OK == ret) {
|
|
if (chn >=0 && lyl >= 0 && mLayerStatus[chn][lyl]) {
|
|
mLayerStatus[chn][lyl] = 0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
#else
|
|
static int LayerConfig(int fd, __disp_cmd_t cmd, unsigned int hlay, disp_layer_info *pinfo)
|
|
{
|
|
unsigned long args[4] = {0};
|
|
unsigned int ret = RET_OK;
|
|
args[0] = SCREEN_0;
|
|
args[1] = HD2CHN(hlay);
|
|
args[2] = (unsigned long)pinfo;
|
|
ret = ioctl(fd, cmd, args);
|
|
if(RET_OK != ret) {
|
|
DISP_DBG_LOG("fail to get para\n");
|
|
ret = RET_FAIL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int LayerGetPara(int disp_fd, unsigned int hlay, disp_layer_info *pinfo)
|
|
{
|
|
return LayerConfig(disp_fd, DISP_CMD_LAYER_GET_INFO, hlay, pinfo);
|
|
}
|
|
|
|
static int LayerSetPara(int disp_fd, unsigned int hlay, disp_layer_info *pinfo)
|
|
{
|
|
return LayerConfig(disp_fd, DISP_CMD_LAYER_SET_INFO, hlay, pinfo);
|
|
}
|
|
|
|
int LayerRequest(int *pCh, int *pId)
|
|
{
|
|
DISP_DBG_LOG("(%s %d)\n", __FUNCTION__, __LINE__);
|
|
int ch;
|
|
int id;
|
|
for (id = 0; id < LYL_NUM; id++) {
|
|
for (ch = 0; ch < CHN_NUM; ch++) {
|
|
if (!(mLayerStatus[ch][id] & LAYER_STATUS_REQUESTED)) {
|
|
mLayerStatus[ch][id] |= LAYER_STATUS_REQUESTED;
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
if ((ch == CHN_NUM) && (id == LYL_NUM)) {
|
|
DISP_DBG_LOG("all layer used.");
|
|
return RET_FAIL;
|
|
}
|
|
*pCh = ch;
|
|
*pId = id;
|
|
DISP_DBG_LOG("requested: ch:%d, id:%d\n", ch, id);
|
|
return HLAY(ch, id);
|
|
}
|
|
|
|
int LayerRelease(int fd, unsigned int hlay)
|
|
{
|
|
int ret;
|
|
int chn = HD2CHN(hlay);
|
|
int lyl = HD2LYL(hlay);
|
|
ret = disp_layer_off(fd, hlay);
|
|
if (chn >=0 && lyl >=0 && mLayerStatus[chn][lyl])
|
|
mLayerStatus[chn][lyl] = 0;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int LayerRender(int fd, unsigned int hlay, renderBuf *picture)
|
|
{
|
|
int ret;
|
|
disp_layer_info config;
|
|
memset(&config, 0, sizeof(disp_layer_info));
|
|
LayerGetPara(fd, hlay, &config);
|
|
config.fb.addr[0] = picture->y_phaddr;
|
|
config.fb.addr[1] = picture->u_phaddr;
|
|
config.fb.addr[2] = picture->v_phaddr;
|
|
ret = LayerSetPara(fd, hlay, &config);
|
|
return ret;
|
|
}
|
|
|
|
int layer_set_src(int fd, unsigned int hlay, SrcInfo *src)
|
|
{
|
|
unsigned long args[4] = {0};
|
|
disp_layer_info layer_info;
|
|
memset(&layer_info, 0, sizeof(disp_layer_info));
|
|
LayerGetPara(fd, hlay, &layer_info);
|
|
layer_info.fb.size.width = src->w;
|
|
layer_info.fb.size.height = src->h;
|
|
layer_info.fb.src_win.x = src->crop_x;
|
|
layer_info.fb.src_win.y = src->crop_y;
|
|
layer_info.fb.src_win.width = src->crop_w;
|
|
layer_info.fb.src_win.height = src->crop_h;
|
|
DISP_DBG_LOG("src:%d,%d,(%d,%d,%dx%d)\n",
|
|
src->w, src->h, src->crop_x, src->crop_y,
|
|
src->crop_w, src->crop_h);
|
|
switch(src->format) {
|
|
case VIDEO_PIXEL_FORMAT_YUV_PLANER_422:
|
|
layer_info.fb.format = DISP_FORMAT_YUV422_P;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_YUV_PLANER_444:
|
|
layer_info.fb.format = DISP_FORMAT_YUV444_P;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_YUV_PLANER_420:
|
|
layer_info.fb.format = DISP_FORMAT_YUV420_P;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_NV21:
|
|
layer_info.fb.format = DISP_FORMAT_YUV420_SP_VUVU;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_NV12:
|
|
layer_info.fb.format = DISP_FORMAT_YUV420_SP_UVUV;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_YV12:
|
|
layer_info.fb.format = DISP_FORMAT_YUV420_P;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_YUV_MB32_420:
|
|
layer_info.fb.format = DISP_FORMAT_YUV420_SP_TILE_UVUV;
|
|
break;
|
|
case VIDEO_PIXEL_FORMAT_YUV_MB32_422:
|
|
layer_info.fb.format = DISP_FORMAT_YUV422_SP_TILE_VUVU;
|
|
break;
|
|
default:
|
|
layer_info.fb.format = DISP_FORMAT_ARGB_8888;
|
|
break;
|
|
}
|
|
return LayerSetPara(fd, hlay, &layer_info);
|
|
}
|
|
|
|
int layer_set_rect(int fd, unsigned int hlay, VoutRect *view)
|
|
{
|
|
unsigned long args[4] = {0};
|
|
disp_layer_info layer_info;
|
|
memset(&layer_info, 0, sizeof(disp_layer_info));
|
|
LayerGetPara(fd, hlay, &layer_info);
|
|
layer_info.screen_win.x = view->x;
|
|
layer_info.screen_win.y = view->y;
|
|
layer_info.screen_win.width = view->width;
|
|
layer_info.screen_win.height = view->height;
|
|
DISP_DBG_LOG("screen rect: (%d,%d, %dx%d)\n",
|
|
view->x, view->y, view->width, view->height);
|
|
return LayerSetPara(fd, hlay, &layer_info);
|
|
}
|
|
|
|
int layer_set_src_rect(int fd, unsigned int hlay, VoutRect *view)
|
|
{
|
|
unsigned long args[4] = {0};
|
|
disp_layer_info layer_info;
|
|
memset(&layer_info, 0, sizeof(disp_layer_info));
|
|
LayerGetPara(fd, hlay, &layer_info);
|
|
layer_info.fb.src_win.x = view->x;
|
|
layer_info.fb.src_win.y = view->y;
|
|
layer_info.fb.src_win.width = view->width;
|
|
layer_info.fb.src_win.height = view->height;
|
|
return LayerSetPara(fd, hlay, &layer_info);
|
|
}
|
|
|
|
static int layer_set_zorder(int fd, unsigned int hlay, int zorder)
|
|
{
|
|
disp_layer_info config;
|
|
videoZorder layer_zorder = (videoZorder)zorder;
|
|
__disp_cmd_t cmd;
|
|
if ((layer_zorder < VIDEO_ZORDER_TOP)
|
|
||(layer_zorder < VIDEO_ZORDER_TOP)) {
|
|
DISP_DBG_LOG("(%s)invalid zorder\n", __FUNCTION__);
|
|
return RET_FAIL;
|
|
}
|
|
memset(&config, 0, sizeof(disp_layer_info));
|
|
LayerGetPara(fd, hlay, &config);
|
|
switch(layer_zorder) {
|
|
case VIDEO_ZORDER_TOP:
|
|
config.zorder = ZORDER_MAX;
|
|
break;
|
|
case VIDEO_ZORDER_BOTTOM:
|
|
config.zorder = ZORDER_MIN;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return LayerSetPara(fd, hlay, &config);
|
|
}
|
|
|
|
int layer_set_colorkey(int fd, unsigned int hlay, unsigned int color)
|
|
{
|
|
unsigned int args[4]={0};
|
|
int ret = RET_OK;
|
|
disp_color_info ck;
|
|
unsigned int r;
|
|
unsigned int g;
|
|
unsigned int b;
|
|
r = (color>>16)&0xff;
|
|
g = (color>>8)&0xff;
|
|
b = (color>>0)&0xff;
|
|
ck.alpha = 0xff;
|
|
ck.red = r;
|
|
ck.green = g;
|
|
ck.blue = b;
|
|
args[0] = SCREEN_0;
|
|
args[1] = (unsigned int)&ck;
|
|
ioctl(fd, DISP_CMD_SET_COLORKEY,(void*)args);
|
|
if(RET_OK != ret) {
|
|
DISP_DBG_LOG("fail to set colorkey\n");
|
|
ret = RET_FAIL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int layer_set_normal(int fd, unsigned int hlay)
|
|
{
|
|
disp_layer_info layer_info;
|
|
LayerGetPara(fd, hlay, &layer_info);
|
|
layer_info.fb.src_win.x = 0;
|
|
layer_info.fb.src_win.y = 0;
|
|
layer_info.fb.src_win.width = 1;
|
|
layer_info.fb.src_win.height = 1;
|
|
layer_info.fb.size.width = 1;
|
|
layer_info.fb.size.height = 1;
|
|
layer_info.screen_win.x = 0;
|
|
layer_info.screen_win.y = 0;
|
|
layer_info.screen_win.width = 1;
|
|
layer_info.screen_win.height = 1;
|
|
layer_info.mode = DISP_LAYER_WORK_MODE_NORMAL;
|
|
LayerSetPara(fd, hlay, &layer_info);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
int disp_layer_on(int dispFd, unsigned int dispLayer)
|
|
{
|
|
int ret = 0;
|
|
unsigned int ioctlParam[4];
|
|
|
|
DISP_CLAR(ioctlParam);
|
|
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = HD2CHN(dispLayer);
|
|
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
ret = ioctl(dispFd, DISP_LAYER_ENABLE, (void*)ioctlParam);
|
|
#else
|
|
ret = ioctl(dispFd, DISP_CMD_LAYER_ENABLE, (void*)ioctlParam);
|
|
#endif
|
|
if(ret < 0){
|
|
DISP_DBG_LOG("%s:ioctl disp disp on failed!\r\n", __func__);
|
|
ret = -1;
|
|
goto errHdl;
|
|
}
|
|
|
|
errHdl:
|
|
return ret;
|
|
}
|
|
|
|
int disp_layer_off(int dispFd, unsigned int dispLayer)
|
|
{
|
|
int ret = 0;
|
|
unsigned int ioctlParam[4];
|
|
|
|
DISP_CLAR(ioctlParam);
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = HD2CHN(dispLayer);
|
|
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
ret = ioctl(dispFd, DISP_LAYER_DISABLE, (void*)ioctlParam);
|
|
#else
|
|
ret = ioctl(dispFd, DISP_CMD_LAYER_DISABLE, (void*)ioctlParam);
|
|
#endif
|
|
if(ret < 0) {
|
|
DISP_DBG_LOG("%s:ioctl disp disp off failed!\r\n", __func__);
|
|
ret = -1;
|
|
goto errHdl;
|
|
}
|
|
|
|
errHdl:
|
|
return ret;
|
|
}
|
|
|
|
static int Yuv2YuvRotate(void *src, void *dest, SrcInfo *srcinfo, rotateDegree degree)
|
|
{
|
|
unsigned int width, height;
|
|
rotateDegree rot_angle;
|
|
VideoPixelFormat fmt;
|
|
|
|
if((!src) || (!dest)||(!srcinfo))
|
|
return -1;
|
|
|
|
rot_angle = degree;
|
|
fmt = srcinfo->format;
|
|
width = srcinfo->w;
|
|
height = srcinfo->h;
|
|
|
|
switch(rot_angle) {
|
|
case ROTATION_ANGLE_90:
|
|
nv_rotage90(width, height,
|
|
(unsigned char*)src, (unsigned char*)dest);
|
|
break;
|
|
case ROTATION_ANGLE_270:
|
|
|
|
nv_rotage270(width, height,
|
|
(unsigned char*)src, (unsigned char*)dest);
|
|
break;
|
|
case ROTATION_ANGLE_180:
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DispAllocateVideoMem(void *hdl, videoParam *param)
|
|
{
|
|
int pixelFormat;
|
|
unsigned int nBufWidth;
|
|
unsigned int nBufHeight;
|
|
int index = 0;
|
|
char* pVirBuf;
|
|
char* pPhyBuf;
|
|
int channel, layer_id;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
|
|
nBufWidth = param->srcInfo.w;
|
|
nBufHeight = param->srcInfo.h;
|
|
|
|
/* Native Window will malloc double buffer */
|
|
pVirBuf = (char*)SunxiMemPalloc(vout_hd->pMemops,
|
|
nBufWidth * nBufHeight * 3/2*2);
|
|
pPhyBuf = (char*)SunxiMemGetPhysicAddressCpu(vout_hd->pMemops,
|
|
pVirBuf);
|
|
if ((NULL == pVirBuf) || (NULL == pPhyBuf)) {
|
|
DISP_DBG_LOG("(%s %d) ION Malloc failed\n",
|
|
__FUNCTION__, __LINE__);
|
|
return RET_FAIL;
|
|
}
|
|
channel = HD2CHN(vout_hd->hlayer);
|
|
vout_hd->renderbuf[channel][0].phy_addr = (unsigned long)pPhyBuf;
|
|
vout_hd->renderbuf[channel][0].vir_addr = (unsigned long)pVirBuf;
|
|
vout_hd->renderbuf[channel][0].y_phaddr = (unsigned long)pPhyBuf;
|
|
vout_hd->renderbuf[channel][0].u_phaddr = (unsigned long)(pPhyBuf
|
|
+ nBufWidth * nBufHeight);
|
|
vout_hd->renderbuf[channel][0].v_phaddr =
|
|
vout_hd->renderbuf[channel][0].u_phaddr
|
|
+ (nBufWidth * nBufHeight)/4;
|
|
|
|
vout_hd->renderbuf[channel][1].phy_addr =
|
|
(unsigned long)(pPhyBuf + nBufWidth * nBufHeight * 3/2);
|
|
vout_hd->renderbuf[channel][1].vir_addr =
|
|
(unsigned long)(pVirBuf + nBufWidth * nBufHeight * 3/2);
|
|
vout_hd->renderbuf[channel][1].y_phaddr =
|
|
(unsigned long)(pPhyBuf + nBufWidth * nBufHeight * 3/2);
|
|
vout_hd->renderbuf[channel][1].u_phaddr =
|
|
vout_hd->renderbuf[channel][1].y_phaddr
|
|
+ nBufWidth * nBufHeight;
|
|
vout_hd->renderbuf[channel][1].v_phaddr =
|
|
vout_hd->renderbuf[channel][1].u_phaddr
|
|
+ (nBufWidth * nBufHeight)/4;
|
|
vout_hd->interBufSet[channel] = 1;
|
|
return RET_OK;
|
|
}
|
|
|
|
int DispFreeVideoMem(void *hdl)
|
|
{
|
|
int channel;
|
|
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
channel = HD2CHN(vout_hd->hlayer);
|
|
SunxiMemPfree(vout_hd->pMemops,
|
|
(void *)vout_hd->renderbuf[channel][0].vir_addr);
|
|
vout_hd->interBufSet[channel] = 0;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
int DispWriteData(void *hdl, void *data, int size, videoParam *param)
|
|
{
|
|
unsigned int nBufWidth;
|
|
unsigned int nBufHeight;
|
|
int channel;
|
|
int index = 0;
|
|
char* pVirBuf;
|
|
char* pPhyBuf;
|
|
renderBuf renderbuf;
|
|
#ifdef DISP_DEBUG
|
|
long long start_tm, end_tm;
|
|
#endif
|
|
SrcInfo src_info;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
|
|
if (!data)
|
|
return -1;
|
|
|
|
#ifdef DISP_DEBUG
|
|
start_tm = GetNowUs();
|
|
#endif
|
|
channel= HD2CHN(vout_hd->hlayer);
|
|
nBufWidth = param->srcInfo.w;
|
|
nBufHeight = param->srcInfo.h;
|
|
if ((nBufWidth <= 0) || (nBufHeight <=0)
|
|
||(param->srcInfo.crop_w <=0)
|
|
||(param->srcInfo.crop_h <= 0)) {
|
|
DISP_DBG_LOG("(%s %d) Bad parameter\n",
|
|
__FUNCTION__, __LINE__);
|
|
return RET_FAIL;
|
|
}
|
|
|
|
if (nBufWidth * nBufHeight * 3/2 > size)
|
|
return -1;
|
|
|
|
if (vout_hd->interBufSet[channel]) {
|
|
index = (vout_hd->bufindex[channel] == 1) ? 1 : 0;
|
|
pVirBuf = (char *)vout_hd->renderbuf[channel][index].vir_addr;
|
|
pPhyBuf = (char *)vout_hd->renderbuf[channel][index].phy_addr;
|
|
vout_hd->bufindex[channel] = (vout_hd->bufindex[channel] == 1) ? 0 : 1;
|
|
} else {
|
|
DISP_DBG_LOG("(%s %d) No Video memory\n",
|
|
__FUNCTION__, __LINE__);
|
|
|
|
return RET_FAIL;
|
|
}
|
|
memset(&src_info, 0, sizeof(SrcInfo));
|
|
switch(vout_hd->route){
|
|
case VIDEO_SRC_FROM_ISP:
|
|
case VIDEO_SRC_FROM_CAM:
|
|
case VIDEO_SRC_FROM_FILE:
|
|
if ((vout_hd->rotate == ROTATION_ANGLE_90)
|
|
||(vout_hd->rotate == ROTATION_ANGLE_270)) {
|
|
Yuv2YuvRotate(data, pVirBuf,
|
|
¶m->srcInfo, vout_hd->rotate);
|
|
src_info.w = param->srcInfo.h;
|
|
src_info.h = param->srcInfo.w;
|
|
src_info.crop_x = param->srcInfo.crop_x;
|
|
src_info.crop_y= param->srcInfo.crop_y;
|
|
src_info.crop_w = param->srcInfo.crop_h;
|
|
src_info.crop_h = param->srcInfo.crop_w;
|
|
src_info.format = param->srcInfo.format;
|
|
src_info.color_space = param->srcInfo.color_space;
|
|
} else {
|
|
src_info.w = param->srcInfo.w;
|
|
src_info.h = param->srcInfo.h;
|
|
src_info.crop_x = param->srcInfo.crop_x;
|
|
src_info.crop_y= param->srcInfo.crop_y;
|
|
src_info.crop_w = param->srcInfo.crop_w;
|
|
src_info.crop_h = param->srcInfo.crop_h;
|
|
src_info.format = param->srcInfo.format;
|
|
src_info.color_space = param->srcInfo.color_space;
|
|
memcpy(pVirBuf, data, nBufWidth * nBufHeight * 3/2);
|
|
}
|
|
break;
|
|
case VIDEO_SRC_FROM_VE:
|
|
if ((vout_hd->rotate == ROTATION_ANGLE_90)
|
|
||(vout_hd->rotate == ROTATION_ANGLE_270)) {
|
|
Yuv2YuvRotate(data, pVirBuf,
|
|
¶m->srcInfo, vout_hd->rotate);
|
|
src_info.w = param->srcInfo.h;
|
|
src_info.h = param->srcInfo.w;
|
|
src_info.crop_x = param->srcInfo.crop_x;
|
|
src_info.crop_y= param->srcInfo.crop_y;
|
|
src_info.crop_w = param->srcInfo.crop_h;
|
|
src_info.crop_h = param->srcInfo.crop_w;
|
|
src_info.format = param->srcInfo.format;
|
|
src_info.color_space = param->srcInfo.color_space;
|
|
} else {
|
|
src_info.w = param->srcInfo.w;
|
|
src_info.h = param->srcInfo.h;
|
|
src_info.crop_x = param->srcInfo.crop_x;
|
|
src_info.crop_y= param->srcInfo.crop_y;
|
|
src_info.crop_w = param->srcInfo.crop_w;
|
|
src_info.crop_h = param->srcInfo.crop_h;
|
|
src_info.format = param->srcInfo.format;
|
|
src_info.color_space = param->srcInfo.color_space;
|
|
memcpy(pVirBuf, data, nBufWidth * nBufHeight * 3/2);
|
|
}
|
|
break;
|
|
default:
|
|
DISP_DBG_LOG("(%s %d) Not support disp src\n",
|
|
__FUNCTION__, __LINE__);
|
|
break;
|
|
}
|
|
SunxiMemFlushCache(vout_hd->pMemops, pVirBuf, nBufWidth * nBufHeight*3/2);
|
|
renderbuf.y_phaddr = (unsigned long)pPhyBuf;
|
|
if (src_info.format == VIDEO_PIXEL_FORMAT_YV12) {
|
|
renderbuf.v_phaddr = (unsigned long)(pPhyBuf + nBufWidth * nBufHeight);
|
|
renderbuf.u_phaddr = renderbuf.v_phaddr + (nBufWidth * nBufHeight)/4;
|
|
} else {
|
|
renderbuf.u_phaddr = (unsigned long)(pPhyBuf + nBufWidth * nBufHeight);
|
|
renderbuf.v_phaddr = renderbuf.u_phaddr + (nBufWidth * nBufHeight)/4;
|
|
}
|
|
layer_set_src(vout_hd->disp_fd, vout_hd->hlayer, &src_info);
|
|
LayerRender(vout_hd->disp_fd, vout_hd->hlayer, &renderbuf);
|
|
#ifdef DISP_DEBUG
|
|
end_tm = GetNowUs();
|
|
DISP_DBG_LOG("%s cost %lld us, pts:%lld\n",
|
|
__FUNCTION__, end_tm - start_tm, start_tm);
|
|
#endif
|
|
return RET_OK;
|
|
}
|
|
|
|
int DispDequeue(void *hdl, renderBuf *rBuf)
|
|
{
|
|
int channel;
|
|
int index = 0;
|
|
char *pVirBuf;
|
|
char *pPhyBuf;
|
|
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
channel= HD2CHN(vout_hd->hlayer);
|
|
|
|
if (vout_hd->interBufSet[channel]) {
|
|
index = (vout_hd->bufindex[channel] == 1) ? 1 : 0;
|
|
pVirBuf = (char *)vout_hd->renderbuf[channel][index].vir_addr;
|
|
pPhyBuf = (char *)vout_hd->renderbuf[channel][index].phy_addr;
|
|
vout_hd->bufindex[channel] = (vout_hd->bufindex[channel] == 1) ? 0 : 1;
|
|
} else {
|
|
DISP_DBG_LOG("(%s %d) No Video memory\n",
|
|
__FUNCTION__, __LINE__);
|
|
return RET_FAIL;
|
|
}
|
|
|
|
rBuf->isExtPhy = VIDEO_USE_INTERN_ALLOC_BUF;
|
|
rBuf->phy_addr = (unsigned long)pPhyBuf;
|
|
rBuf->vir_addr = (unsigned long)pVirBuf;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
int DispQueueToDisplay(void *hdl, int size, videoParam *param, renderBuf *rBuf)
|
|
{
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
unsigned int nBufWidth;
|
|
unsigned int nBufHeight;
|
|
renderBuf renderbuf;
|
|
SrcInfo src_info;
|
|
|
|
nBufWidth = param->srcInfo.w;
|
|
nBufHeight = param->srcInfo.h;
|
|
|
|
if (nBufWidth * nBufHeight * 3/2 > size)
|
|
return -1;
|
|
|
|
memset(&src_info, 0, sizeof(SrcInfo));
|
|
switch(vout_hd->route){
|
|
case VIDEO_SRC_FROM_ISP:
|
|
case VIDEO_SRC_FROM_CAM:
|
|
case VIDEO_SRC_FROM_FILE:
|
|
case VIDEO_SRC_FROM_VE:
|
|
default:
|
|
src_info.w = param->srcInfo.w;
|
|
src_info.h = param->srcInfo.h;
|
|
src_info.crop_x = param->srcInfo.crop_x;
|
|
src_info.crop_y= param->srcInfo.crop_y;
|
|
src_info.crop_w = param->srcInfo.crop_w;
|
|
src_info.crop_h = param->srcInfo.crop_h;
|
|
src_info.format = param->srcInfo.format;
|
|
src_info.color_space = param->srcInfo.color_space;
|
|
DISP_DBG_LOG("(%s %d)default src mode\n",
|
|
__FUNCTION__, __LINE__);
|
|
break;
|
|
}
|
|
|
|
if (rBuf->isExtPhy == VIDEO_USE_EXTERN_ION_BUF ){
|
|
renderbuf.y_phaddr = (unsigned long)rBuf->y_phaddr;
|
|
if (src_info.format == VIDEO_PIXEL_FORMAT_YV12) {
|
|
renderbuf.u_phaddr = (unsigned long)(rBuf->v_phaddr);
|
|
renderbuf.v_phaddr = (unsigned long)(rBuf->u_phaddr);
|
|
} else {
|
|
renderbuf.u_phaddr = (unsigned long)(rBuf->u_phaddr);
|
|
renderbuf.v_phaddr = (unsigned long)(rBuf->v_phaddr);
|
|
}
|
|
} else {
|
|
SunxiMemFlushCache(vout_hd->pMemops, rBuf->vir_addr, nBufWidth * nBufHeight*3/2);
|
|
renderbuf.y_phaddr = (unsigned long)rBuf->phy_addr;
|
|
if (src_info.format == VIDEO_PIXEL_FORMAT_YV12) {
|
|
renderbuf.v_phaddr = (unsigned long)(rBuf->phy_addr + nBufWidth * nBufHeight);
|
|
renderbuf.u_phaddr = renderbuf.v_phaddr + (nBufWidth * nBufHeight)/4;
|
|
} else {
|
|
renderbuf.u_phaddr = (unsigned long)(rBuf->phy_addr + nBufWidth * nBufHeight);
|
|
renderbuf.v_phaddr = renderbuf.u_phaddr + (nBufWidth * nBufHeight)/4;
|
|
}
|
|
}
|
|
|
|
layer_set_src(vout_hd->disp_fd, vout_hd->hlayer, &src_info);
|
|
LayerRender(vout_hd->disp_fd, vout_hd->hlayer, &renderbuf);
|
|
#else
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
unsigned int nBufWidth;
|
|
unsigned int nBufHeight;
|
|
renderBuf renderbuf;
|
|
SrcInfo src_info;
|
|
nBufWidth = param->srcInfo.w;
|
|
nBufHeight = param->srcInfo.h;
|
|
if (nBufWidth * nBufHeight * 3/2 > size)
|
|
return -1;
|
|
memset(&src_info, 0, sizeof(SrcInfo));
|
|
switch(vout_hd->route){
|
|
case VIDEO_SRC_FROM_ISP:
|
|
case VIDEO_SRC_FROM_CAM:
|
|
case VIDEO_SRC_FROM_FILE:
|
|
case VIDEO_SRC_FROM_VE:
|
|
default:
|
|
src_info.w = param->srcInfo.w;
|
|
src_info.h = param->srcInfo.h;
|
|
src_info.crop_x = param->srcInfo.crop_x;
|
|
src_info.crop_y= param->srcInfo.crop_y;
|
|
src_info.crop_w = param->srcInfo.crop_w;
|
|
src_info.crop_h = param->srcInfo.crop_h;
|
|
src_info.format = param->srcInfo.format;
|
|
src_info.color_space = param->srcInfo.color_space;
|
|
break;
|
|
}
|
|
if (rBuf->isExtPhy == VIDEO_USE_EXTERN_ION_BUF ){
|
|
renderbuf.y_phaddr = (unsigned long)rBuf->y_phaddr;
|
|
if (src_info.format == VIDEO_PIXEL_FORMAT_YV12) {
|
|
renderbuf.u_phaddr = (unsigned long)(rBuf->v_phaddr);
|
|
renderbuf.v_phaddr = (unsigned long)(rBuf->u_phaddr);
|
|
} else {
|
|
renderbuf.u_phaddr = (unsigned long)(rBuf->u_phaddr);
|
|
renderbuf.v_phaddr = (unsigned long)(rBuf->v_phaddr);
|
|
}
|
|
} else {
|
|
SunxiMemFlushCache(vout_hd->pMemops, rBuf->vir_addr, nBufWidth * nBufHeight*3/2);
|
|
renderbuf.y_phaddr = (unsigned long)rBuf->phy_addr;
|
|
if (src_info.format == VIDEO_PIXEL_FORMAT_YV12) {
|
|
renderbuf.v_phaddr = (unsigned long)(rBuf->phy_addr + nBufWidth * nBufHeight);
|
|
renderbuf.u_phaddr = renderbuf.v_phaddr + (nBufWidth * nBufHeight)/4;
|
|
} else {
|
|
renderbuf.u_phaddr = (unsigned long)(rBuf->phy_addr + nBufWidth * nBufHeight);
|
|
renderbuf.v_phaddr = renderbuf.u_phaddr + (nBufWidth * nBufHeight)/4;
|
|
}
|
|
}
|
|
layer_set_src(vout_hd->disp_fd, vout_hd->hlayer, &src_info);
|
|
LayerRender(vout_hd->disp_fd, vout_hd->hlayer, &renderbuf);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
int DispSetEnable(void *hdl, int enable)
|
|
{
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
disp_layer_config config;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(vout_hd->hlayer);
|
|
config.layer_id = HD2LYL(vout_hd->hlayer);
|
|
LayerGetPara(vout_hd->disp_fd, &config);
|
|
|
|
config.enable = enable;
|
|
//vout_hd->enable = enable;
|
|
return LayerSetPara(vout_hd->disp_fd, &config);
|
|
#else
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
if(enable)
|
|
disp_layer_on(vout_hd->disp_fd ,vout_hd->hlayer);
|
|
else
|
|
disp_layer_off(vout_hd->disp_fd ,vout_hd->hlayer);
|
|
#endif
|
|
}
|
|
|
|
int DispSetSrcRect(void *hdl, VoutRect *src_rect)
|
|
{
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
disp_layer_config config;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(vout_hd->hlayer);
|
|
config.layer_id = HD2LYL(vout_hd->hlayer);
|
|
LayerGetPara(vout_hd->disp_fd, &config);
|
|
|
|
config.info.fb.crop.x = src_rect->x;
|
|
config.info.fb.crop.y = src_rect->y;
|
|
config.info.fb.crop.width = (src_rect->width);
|
|
config.info.fb.crop.height = (src_rect->height);
|
|
|
|
DISP_DBG_LOG("width: 0x%llx, height: 0x%llx",
|
|
config.info.fb.crop.width, config.info.fb.crop.height);
|
|
|
|
config.info.fb.crop.x = config.info.fb.crop.x << 32;
|
|
config.info.fb.crop.y = config.info.fb.crop.y << 32;
|
|
config.info.fb.crop.width = config.info.fb.crop.width << 32;
|
|
config.info.fb.crop.height = config.info.fb.crop.height << 32;
|
|
|
|
return LayerSetPara(vout_hd->disp_fd, &config);
|
|
#else
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
return layer_set_src_rect(vout_hd->disp_fd, vout_hd->hlayer, src_rect);
|
|
#endif
|
|
}
|
|
|
|
int DispSetRect(void *hdl, VoutRect *rect)
|
|
{
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
disp_layer_config config;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(vout_hd->hlayer);
|
|
config.layer_id = HD2LYL(vout_hd->hlayer);
|
|
LayerGetPara(vout_hd->disp_fd, &config);
|
|
|
|
config.info.screen_win.x = rect->x;
|
|
config.info.screen_win.y = rect->y;
|
|
config.info.screen_win.width = rect->width;
|
|
config.info.screen_win.height = rect->height;
|
|
return LayerSetPara(vout_hd->disp_fd, &config);
|
|
#else
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
return layer_set_rect(vout_hd->disp_fd, vout_hd->hlayer, rect);
|
|
#endif
|
|
}
|
|
|
|
int DispSetRotateAngel(void *hdl, int degree)
|
|
{
|
|
int ret = RET_OK;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
rotateDegree rot_deg = (rotateDegree)degree;
|
|
|
|
/*unsigned long args[4]={0};
|
|
args[0] = SCREEN_0;
|
|
args[1] = degree;
|
|
ret = ioctl(vout_hd->disp_fd, DISP_ROTATION_SW_SET_ROT, args);
|
|
*/
|
|
vout_hd->rotate = rot_deg;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int DispSetRoute(void *hdl, int route)
|
|
{
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
vout_hd->route = (videoSource)route;
|
|
return RET_OK;
|
|
}
|
|
int DispSetZorder(void *hdl, int zorder)
|
|
{
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
disp_layer_config config;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
videoZorder layer_zorder = (videoZorder)zorder;
|
|
if ((layer_zorder < VIDEO_ZORDER_TOP)
|
|
||(layer_zorder < VIDEO_ZORDER_TOP)) {
|
|
DISP_DBG_LOG("(%s)invalid zorder\n", __FUNCTION__);
|
|
return RET_FAIL;
|
|
}
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
config.channel = HD2CHN(vout_hd->hlayer);
|
|
config.layer_id = HD2LYL(vout_hd->hlayer);
|
|
LayerGetPara(vout_hd->disp_fd, &config);
|
|
switch(layer_zorder) {
|
|
case VIDEO_ZORDER_TOP:
|
|
config.info.zorder = ZORDER_MAX;
|
|
break;
|
|
case VIDEO_ZORDER_MIDDLE:
|
|
config.info.zorder = ZORDER_MID;
|
|
break;
|
|
case VIDEO_ZORDER_BOTTOM:
|
|
config.info.zorder = ZORDER_MIN;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return LayerSetPara(vout_hd->disp_fd, &config);
|
|
#else
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
return layer_set_zorder(vout_hd->disp_fd, vout_hd->hlayer, zorder);
|
|
#endif
|
|
}
|
|
int DispGetScreenWidth(void *hdl)
|
|
{
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
unsigned int ioctlParam[4];
|
|
unsigned int width;
|
|
|
|
DISP_CLAR(ioctlParam);
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = 0;
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
width = ioctl(vout_hd->disp_fd, DISP_GET_SCN_WIDTH, ioctlParam);
|
|
#else
|
|
width = ioctl(vout_hd->disp_fd, DISP_CMD_GET_SCN_WIDTH, ioctlParam);
|
|
#endif
|
|
return width;
|
|
}
|
|
|
|
int DispGetScreenHeight(void *hdl)
|
|
{
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
unsigned int ioctlParam[4];
|
|
unsigned int height;
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
DISP_CLAR(ioctlParam);
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = 0;
|
|
height = ioctl(vout_hd->disp_fd, DISP_GET_SCN_HEIGHT, ioctlParam);
|
|
#else
|
|
DISP_CLAR(ioctlParam);
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = 0;
|
|
height = ioctl(vout_hd->disp_fd, DISP_CMD_GET_SCN_HEIGHT, ioctlParam);
|
|
#endif
|
|
return height;
|
|
}
|
|
|
|
int DispSetIoctl(void *hdl, unsigned int cmd, unsigned long para)
|
|
{
|
|
int ret = 0;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
unsigned int ioctlParam[4];
|
|
unsigned int disp_cmd;
|
|
DISP_CLAR(ioctlParam);
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
switch(cmd) {
|
|
case VIDEO_CMD_SET_BRIGHTNESS:
|
|
disp_cmd = DISP_LCD_SET_BRIGHTNESS;
|
|
break;
|
|
case VIDEO_CMD_SET_CONTRAST:
|
|
case VIDEO_CMD_SET_HUE:
|
|
case VIDEO_CMD_SET_SATURATION:
|
|
break;
|
|
case VIDEO_CMD_SET_VEDIO_ENHANCE_DEFAULT:
|
|
disp_cmd = DISP_ENHANCE_SET_MODE;
|
|
break;
|
|
}
|
|
#else
|
|
switch(cmd) {
|
|
case VIDEO_CMD_SET_BRIGHTNESS:
|
|
disp_cmd = DISP_CMD_LCD_SET_BRIGHTNESS;
|
|
break;
|
|
case VIDEO_CMD_SET_CONTRAST:
|
|
disp_cmd = DISP_CMD_LAYER_SET_CONTRAST;
|
|
break;
|
|
case VIDEO_CMD_SET_HUE:
|
|
disp_cmd = DISP_CMD_LAYER_SET_HUE;
|
|
break;
|
|
case VIDEO_CMD_SET_SATURATION:
|
|
disp_cmd = DISP_CMD_LAYER_SET_SATURATION;
|
|
break;
|
|
case VIDEO_CMD_SET_VEDIO_ENHANCE_DEFAULT:
|
|
disp_cmd = DISP_CMD_SET_ENHANCE_MODE;
|
|
break;
|
|
}
|
|
#endif
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = 0;
|
|
ret = ioctl(vout_hd->disp_fd, cmd, (void*)ioctlParam);
|
|
if(ret < 0){
|
|
DISP_DBG_LOG("%s: fail to open backlight!\r\n", __func__);
|
|
ret = -2;
|
|
goto errHdl;
|
|
}
|
|
errHdl:
|
|
return ret;
|
|
}
|
|
|
|
int DispInit(void *hdl, int enable, int rotate, VoutRect *rect)
|
|
{
|
|
int ret = 0;
|
|
int hlay;
|
|
int ch, id;
|
|
unsigned int width, height;
|
|
unsigned int ioctlParam[4];
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
disp_layer_config config;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
|
|
vout_hd->disp_fd = open(DISP_DEV_NAME, O_RDWR);
|
|
if(vout_hd->disp_fd < 0){
|
|
DISP_DBG_LOG("%s:open disp handle error!\r\n", __func__);
|
|
goto errHdl;
|
|
}
|
|
DISP_CLAR(ioctlParam);
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = 0;
|
|
width = ioctl(vout_hd->disp_fd, DISP_GET_SCN_WIDTH, ioctlParam);
|
|
height = ioctl(vout_hd->disp_fd, DISP_GET_SCN_HEIGHT, ioctlParam);
|
|
|
|
memset(&config, 0, sizeof(disp_layer_config));
|
|
hlay = LayerRequest(&ch, &id);
|
|
config.channel = ch;
|
|
config.layer_id = id;
|
|
config.enable = enable;
|
|
config.info.screen_win.x = 0;
|
|
config.info.screen_win.y = 0;
|
|
config.info.screen_win.width = width;
|
|
config.info.screen_win.height = height;
|
|
config.info.mode = LAYER_MODE_BUFFER;
|
|
config.info.alpha_mode = 0;
|
|
config.info.alpha_value = 0x80;
|
|
config.info.fb.flags = DISP_BF_NORMAL;
|
|
config.info.fb.scan = DISP_SCAN_PROGRESSIVE;
|
|
config.info.fb.color_space = (rect->height < 720)?DISP_BT601:DISP_BT709;
|
|
config.info.zorder = HLAY(ch, id);
|
|
LayerSetPara(vout_hd->disp_fd, &config);
|
|
|
|
DISP_DBG_LOG("hlay:%d, zorder=%d,", hlay, config.info.zorder);
|
|
|
|
vout_hd->hlayer = hlay;
|
|
vout_hd->enable = enable;
|
|
vout_hd->rotate = (rotateDegree)rotate;
|
|
vout_hd->rect.x = rect->x;
|
|
vout_hd->rect.y = rect->y;
|
|
vout_hd->rect.width = rect->width;
|
|
vout_hd->rect.height = rect->height;
|
|
vout_hd->pMemops = GetMemAdapterOpsS();
|
|
SunxiMemOpen(vout_hd->pMemops);
|
|
|
|
errHdl:
|
|
return ret;
|
|
#else
|
|
disp_layer_info config;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
vout_hd->disp_fd = open(DISP_DEV_NAME, O_RDWR);
|
|
if(vout_hd->disp_fd < 0){
|
|
DISP_DBG_LOG("%s:open disp handle error!\r\n", __func__);
|
|
goto errHdl;
|
|
}
|
|
DISP_CLAR(ioctlParam);
|
|
ioctlParam[0] = SCREEN_0;
|
|
ioctlParam[1] = 0;
|
|
width = ioctl(vout_hd->disp_fd, DISP_CMD_GET_SCN_WIDTH, ioctlParam);
|
|
height = ioctl(vout_hd->disp_fd, DISP_CMD_GET_SCN_HEIGHT, ioctlParam);
|
|
memset(&config, 0, sizeof(disp_layer_info));
|
|
config.fb.src_win.x = 0;
|
|
config.fb.src_win.y = 0;
|
|
config.fb.src_win.width = 1;
|
|
config.fb.src_win.height = 1;
|
|
config.fb.size.width = width;
|
|
config.fb.size.height = height;
|
|
config.screen_win.x = 0;
|
|
config.screen_win.y = 0;
|
|
config.screen_win.width = width;
|
|
config.screen_win.height = height;
|
|
config.alpha_mode = 0;
|
|
config.fb.pre_multiply = 0;
|
|
config.alpha_value = 0xff;
|
|
hlay = LayerRequest(&ch, &id);
|
|
config.zorder = 0;
|
|
config.mode = DISP_LAYER_WORK_MODE_SCALER;
|
|
config.pipe = 0;
|
|
DISP_DBG_LOG("hlay:%d, zorder=%d,", hlay, config.zorder);
|
|
LayerSetPara(vout_hd->disp_fd, hlay, &config);
|
|
disp_layer_off(vout_hd->disp_fd ,hlay);
|
|
vout_hd->hlayer = hlay;
|
|
vout_hd->enable = enable;
|
|
vout_hd->rotate = (rotateDegree)rotate;
|
|
vout_hd->rect.x = rect->x;
|
|
vout_hd->rect.y = rect->y;
|
|
vout_hd->rect.width = rect->width;
|
|
vout_hd->rect.height = rect->height;
|
|
vout_hd->pMemops = GetMemAdapterOpsS();
|
|
SunxiMemOpen(vout_hd->pMemops);
|
|
errHdl:
|
|
return ret;
|
|
#endif
|
|
}
|
|
|
|
int DispDeinit(void *hdl)
|
|
{
|
|
#ifdef __SUNXI_DISPLAY2__
|
|
int ret = 0;
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
LayerRelease(vout_hd->disp_fd, vout_hd->hlayer);
|
|
|
|
ret = close(vout_hd->disp_fd);
|
|
if(ret != 0){
|
|
DISP_DBG_LOG("%s:close disp handle failed!\r\n", __func__);
|
|
goto errHdl;
|
|
}
|
|
SunxiMemClose(vout_hd->pMemops);
|
|
errHdl:
|
|
return ret;
|
|
#else
|
|
dispOutPort *vout_hd = (dispOutPort *)hdl;
|
|
LayerRelease(vout_hd->disp_fd, vout_hd->hlayer);
|
|
if(vout_hd->disp_fd)
|
|
close(vout_hd->disp_fd);
|
|
if(vout_hd->pMemops)
|
|
SunxiMemClose(vout_hd->pMemops);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
dispOutPort *CreateVideoOutport(int index)
|
|
{
|
|
dispOutPort *voutport = (dispOutPort *)malloc(sizeof(dispOutPort));
|
|
if(voutport == NULL)
|
|
return NULL;
|
|
voutport->init = DispInit;
|
|
voutport->deinit = DispDeinit;
|
|
voutport->writeData = DispWriteData;
|
|
voutport->dequeue = DispDequeue;
|
|
voutport->queueToDisplay = DispQueueToDisplay;
|
|
voutport->setEnable = DispSetEnable;
|
|
voutport->setRect = DispSetRect;
|
|
voutport->setRotateAngel = DispSetRotateAngel;
|
|
voutport->getScreenWidth = DispGetScreenWidth;
|
|
voutport->getScreenHeight = DispGetScreenHeight;
|
|
voutport->setRoute = DispSetRoute;
|
|
voutport->SetZorder= DispSetZorder;
|
|
voutport->allocateVideoMem = DispAllocateVideoMem;
|
|
voutport->freeVideoMem = DispFreeVideoMem;
|
|
voutport->setSrcRect = DispSetSrcRect;
|
|
voutport->setIoctl = DispSetIoctl;
|
|
return voutport;
|
|
}
|
|
|
|
int DestroyVideoOutport(dispOutPort *hdl)
|
|
{
|
|
if(hdl != NULL)
|
|
free(hdl);
|
|
}
|