1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
7.7 KiB

/*
* Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "RgaCropScale.h"
#include <utils/Singleton.h>
#include <RockchipRga.h>
#include "CameraHal.h"
namespace android {
namespace camera2 {
#if (defined(TARGET_RK32) || defined(TARGET_RK3368))
#define RGA_VER (2.0)
#define RGA_ACTIVE_W (4096)
#define RGA_VIRTUAL_W (4096)
#define RGA_ACTIVE_H (4096)
#define RGA_VIRTUAL_H (4096)
#else
#define RGA_VER (1.0)
#define RGA_ACTIVE_W (2048)
#define RGA_VIRTUAL_W (4096)
#define RGA_ACTIVE_H (2048)
#define RGA_VIRTUAL_H (2048)
#endif
int RgaCropScale::CropScaleNV12Or21(struct Params* in, struct Params* out)
{
rga_info_t src, dst;
memset(&src, 0, sizeof(rga_info_t));
memset(&dst, 0, sizeof(rga_info_t));
if (!in || !out)
return -1;
if((out->width > RGA_VIRTUAL_W) || (out->height > RGA_VIRTUAL_H)){
ALOGE("%s(%d): out wxh %dx%d beyond rga capability",
__FUNCTION__, __LINE__,
out->width, out->height);
return -1;
}
if ((in->fmt != HAL_PIXEL_FORMAT_YCrCb_NV12 &&
in->fmt != HAL_PIXEL_FORMAT_YCrCb_420_SP) ||
(out->fmt != HAL_PIXEL_FORMAT_YCrCb_NV12 &&
out->fmt != HAL_PIXEL_FORMAT_YCrCb_420_SP)) {
ALOGE("%s(%d): only accept NV12 or NV21 now. in fmt %d, out fmt %d",
__FUNCTION__, __LINE__,
in->fmt, out->fmt);
return -1;
}
RockchipRga& rkRga(RockchipRga::get());
if (in->fd == -1) {
src.fd = -1;
src.virAddr = (void*)in->vir_addr;
} else {
src.fd = in->fd;
}
src.mmuFlag = ((2 & 0x3) << 4) | 1 | (1 << 8) | (1 << 10);
if (out->fd == -1 ) {
dst.fd = -1;
dst.virAddr = (void*)out->vir_addr;
} else {
dst.fd = out->fd;
}
dst.mmuFlag = ((2 & 0x3) << 4) | 1 | (1 << 8) | (1 << 10);
rga_set_rect(&src.rect,
in->offset_x,
in->offset_y,
in->width,
in->height,
in->width_stride,
in->height_stride,
in->fmt);
rga_set_rect(&dst.rect,
out->offset_x,
out->offset_y,
out->width,
out->height,
out->width_stride,
out->height_stride,
out->fmt);
if (in->mirror)
src.rotation = DRM_RGA_TRANSFORM_FLIP_H;
if (rkRga.RkRgaBlit(&src, &dst, NULL)) {
ALOGE("%s:rga blit failed", __FUNCTION__);
return -1;
}
return 0;
}
int RgaCropScale::rga_nv12_scale_crop(
int src_width, int src_height,
unsigned long src_fd, unsigned long dst_fd,
int dst_width, int dst_height,
int src_fmt, int dst_fmt,
int zoom_val, int rotation, bool mirror, bool isNeedCrop,
bool is16Align, bool isViraddr)
{
int ret = 0;
rga_info_t src,dst;
int zoom_cropW,zoom_cropH;
int ratio = 0;
int zoom_top_offset=0,zoom_left_offset=0;
int tmp = 0;
dst_width = (dst_width + 15) & (~15);
dst_height = (dst_height + 15) & (~15);
RockchipRga& rkRga(RockchipRga::get());
memset(&src, 0, sizeof(rga_info_t));
memset(&dst, 0, sizeof(rga_info_t));
if (isViraddr) {
src.fd = -1;
src.virAddr = (void*)src_fd;
dst.fd = -1;
dst.virAddr = (void*)dst_fd;
} else {
src.fd = src_fd;
dst.fd = dst_fd;
}
src.mmuFlag = ((2 & 0x3) << 4) | 1 | (1 << 8) | (1 << 10);
dst.mmuFlag = ((2 & 0x3) << 4) | 1 | (1 << 8) | (1 << 10);
if((dst_width > RGA_VIRTUAL_W) || (dst_height > RGA_VIRTUAL_H)){
ALOGE("(dst_width > RGA_VIRTUAL_W) || (dst_height > RGA_VIRTUAL_H), switch to arm ");
ret = -1;
goto END;
}
//need crop ? when cts FOV,don't crop
if(isNeedCrop && (src_width*100/src_height) != (dst_width*100/dst_height)) {
ratio = ((src_width*100/dst_width) >= (src_height*100/dst_height))?
(src_height*100/dst_height):
(src_width*100/dst_width);
zoom_cropW = (ratio*dst_width/100) & (~0x01);
zoom_cropH = (ratio*dst_height/100) & (~0x01);
zoom_left_offset=((src_width-zoom_cropW)>>1) & (~0x01);
zoom_top_offset=((src_height-zoom_cropH)>>1) & (~0x01);
}else{
zoom_cropW = src_width;
zoom_cropH = src_height;
zoom_left_offset=0;
zoom_top_offset=0;
}
if(zoom_val > 100){
zoom_cropW = zoom_cropW*100/zoom_val & (~0x01);
zoom_cropH = zoom_cropH*100/zoom_val & (~0x01);
zoom_left_offset = ((src_width-zoom_cropW)>>1) & (~0x01);
zoom_top_offset= ((src_height-zoom_cropH)>>1) & (~0x01);
}
if (rotation != 0) {
switch (rotation) {
case 90:
src.rotation = DRM_RGA_TRANSFORM_ROT_90;
tmp = dst_width;
dst_width = dst_height;
dst_height = tmp;
break;
case 180:
src.rotation = DRM_RGA_TRANSFORM_ROT_180;
break;
case 270:
src.rotation = DRM_RGA_TRANSFORM_ROT_270;
tmp = dst_width;
dst_width = dst_height;
dst_height = tmp;
break;
}
}
//usb camera height align to 16,the extra eight rows need to be croped.
if(!is16Align){
zoom_top_offset = zoom_top_offset & (~0x07);
}
rga_set_rect(&src.rect, zoom_left_offset, zoom_top_offset,
zoom_cropW, zoom_cropH, src_width,
src_height, src_fmt/*HAL_PIXEL_FORMAT_RGBA_8888*/);
rga_set_rect(&dst.rect, 0,0,dst_width,dst_height,
dst_width,dst_height,
dst_fmt/*HAL_PIXEL_FORMAT_RGBA_8888*/);
if (mirror)
src.rotation |= DRM_RGA_TRANSFORM_FLIP_H;
//TODO:sina,cosa,scale_mode,render_mode
ret = rkRga.RkRgaBlit(&src, &dst, NULL);
if (ret) {
ALOGE("%s:rga blit failed", __FUNCTION__);
goto END;
}
END:
return ret;
}
int RgaCropScale::rga_simple(
int src_width, int src_height,
unsigned long src_fd, unsigned long dst_fd,
int dst_width, int dst_height,
int src_fmt, int dst_fmt, bool isFd)
{
int ret = 0;
rga_info_t src,dst;
RockchipRga& rkRga(RockchipRga::get());
memset(&src, 0, sizeof(rga_info_t));
memset(&dst, 0, sizeof(rga_info_t));
if(!isFd){
src.fd = -1;
src.virAddr = (void*)src_fd;
dst.fd = -1;
dst.virAddr = (void*)dst_fd;
}else
{
src.fd = src_fd;
dst.fd = dst_fd;
}
LOGD("%s:%d: rga simple src fd %d dst fd %d \n", __FUNCTION__, __LINE__, src.fd, dst.fd);
src.mmuFlag = ((2 & 0x3) << 4) | 1 | (1 << 8) | (1 << 10);
dst.mmuFlag = ((2 & 0x3) << 4) | 1 | (1 << 8) | (1 << 10);
src.rotation = DRM_RGA_TRANSFORM_FLIP_H;
rga_set_rect(&src.rect, 0, 0,
src_width, src_height, src_width,
src_height, src_fmt);
rga_set_rect(&dst.rect, 0,0,dst_width,dst_height,
dst_width,dst_height,
dst_fmt);
//TODO:sina,cosa,scale_mode,render_mode
ret = rkRga.RkRgaBlit(&src, &dst, NULL);
if (ret) {
ALOGE("%s:rga blit failed", __FUNCTION__);
goto END;
}
END:
return ret;
}
} /* namespace camera2 */
} /* namespace android */