843 lines
27 KiB
C
843 lines
27 KiB
C
/*
|
|
* Copyright (c) XMEDIA. All rights reserved.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
|
|
#include "sample_comm.h"
|
|
#include "sample_comm_vpss.h"
|
|
#include "sample_comm_vi.h"
|
|
#include "sample_comm_sys.h"
|
|
#include "sample_comm_isp.h"
|
|
|
|
#include "xmedia_sys.h"
|
|
#include "xmedia_mmz.h"
|
|
#include "xmedia_vb.h"
|
|
#include "xmedia_vpss.h"
|
|
#include "xmedia_vgs.h"
|
|
|
|
#include "video_stream.h"
|
|
#include "sample_video.h"
|
|
#include "sample_video_yuv.h"
|
|
|
|
#include "venc_log.h"
|
|
#include "frame_cache.h"
|
|
#include "debug.h"
|
|
|
|
#define v4l2_fourcc(a, b, c, d) \
|
|
((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
|
|
|
|
#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
|
|
#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
|
|
#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
|
|
#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
|
|
#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YUV 4:2:0 */
|
|
|
|
static int g_tag_fmt = V4L2_PIX_FMT_YUYV;
|
|
|
|
static pthread_t g_recv_pid;
|
|
static int g_start = 0;
|
|
static int g_recv = 0;
|
|
static xmedia_u32 g_vpss_depth_flag = 0;
|
|
//static xmedia_u32 g_vpss_ori_depth = 0;
|
|
|
|
//common
|
|
static sample_comm_sensor_type g_sensor_type = SENSOR0_TYPE;
|
|
static sample_comm_video_param g_video_param = {0};
|
|
|
|
// vi config
|
|
static xmedia_s32 g_vi_dev = 0; /* 0:单板SENSOR0; 2:单板SENSOR2 */
|
|
static xmedia_s32 g_vi_chn = 0;
|
|
static xmedia_s32 g_vi_pipe = 0;
|
|
static xmedia_u32 g_vgs_pool_id = 0;
|
|
static sample_vi_config g_vi_config = {0};
|
|
|
|
// isp config
|
|
static sample_isp_param g_isp_param = {0};
|
|
|
|
// vpss config
|
|
static xmedia_s32 g_vpss_pipe = 0;
|
|
static xmedia_s32 g_vpss_ichn = 0;
|
|
static xmedia_s32 g_vpss_ochn = 0;
|
|
static sample_vpss_config g_vpss_config = {0};
|
|
static xmedia_video_frame_info g_vpss_frame_info = {0};
|
|
|
|
static int sample_yuv_create_yuyv_pool(void)
|
|
{
|
|
xmedia_vb_pool_config pool_config;
|
|
vi_sensor_info sensor_info = {0};
|
|
|
|
sample_comm_vi_get_sensor_info(g_sensor_type, &sensor_info);
|
|
|
|
pool_config.block_cnt = 1;
|
|
pool_config.block_size = sensor_info.width * sensor_info.height * 2;
|
|
pool_config.map_mode = XMEDIA_VB_MAP_MODE_NONE;
|
|
g_vgs_pool_id = xmedia_vb_create_pool(&pool_config);
|
|
if (g_vgs_pool_id == -1) {
|
|
venc_logd("resolution: w(%d) x h(%d).\n", sensor_info.width, sensor_info.height);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static int vgs_nv12_to_yuyv(xmedia_video_frame_info* vpss_frame, xmedia_video_frame_info* scale_frame)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_vgs_frame_info task_info;
|
|
xmedia_s32 job_handle;
|
|
xmedia_handle vb_handle;
|
|
vi_sensor_info sensor_info = {0};
|
|
xmedia_vb_base_info base_info = {0};
|
|
xmedia_vb_cal_cfg vb_cal_cfg = {0};
|
|
|
|
sample_comm_vi_get_sensor_info(g_sensor_type, &sensor_info);
|
|
|
|
base_info.width = vpss_frame->frame.width;
|
|
base_info.height = vpss_frame->frame.height;
|
|
base_info.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YUYV_PACKAGE_422; //XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422;
|
|
base_info.bit_width = vpss_frame->frame.bit_width;
|
|
base_info.cmp_mode = vpss_frame->frame.compress_mode;
|
|
base_info.align = 8;
|
|
xmedia_vb_get_buffer_config(&base_info, &vb_cal_cfg);
|
|
|
|
vb_handle = xmedia_vb_get_block(g_vgs_pool_id, sensor_info.width * sensor_info.height * 2, XMEDIA_NULL);
|
|
if (vb_handle == VB_INVALID_HANDLE) {
|
|
SAMPLE_PRT("xmedia_vb_get_block(size:%d) failed!\n", sensor_info.width * sensor_info.height * 2);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
ret = xmedia_vgs_init();
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("vgs init failed\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = xmedia_vgs_create_job(&job_handle);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("create vgs job failed\n");
|
|
xmedia_vgs_exit();
|
|
goto EXIT1;
|
|
}
|
|
|
|
memset(scale_frame, 0, sizeof(xmedia_video_frame_info));
|
|
scale_frame->pool_id = g_vgs_pool_id;
|
|
scale_frame->frame.width = vpss_frame->frame.width;
|
|
scale_frame->frame.height = vpss_frame->frame.height;
|
|
scale_frame->frame.dynamic_range = XMEDIA_VIDEO_DYNAMIC_RANGE_SDR;
|
|
scale_frame->frame.color_info.color_gamut = XMEDIA_VIDEO_COLOR_GAMUT_BT709;
|
|
scale_frame->frame.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YUYV_PACKAGE_422; //XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422; XMEDIA_VIDEO_PIXEL_FMT_YUYV_PACKAGE_422
|
|
scale_frame->frame.pts = vpss_frame->frame.pts;
|
|
scale_frame->frame.compress_mode = vpss_frame->frame.compress_mode;
|
|
scale_frame->frame.video_fmt = vpss_frame->frame.video_fmt;
|
|
scale_frame->frame.bit_width = vpss_frame->frame.bit_width;
|
|
scale_frame->mod_id = MOD_ID_USER;
|
|
scale_frame->frame.addr.y_head_phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
|
|
scale_frame->frame.addr.c_head_phy_addr = scale_frame->frame.addr.y_head_phy_addr + vb_cal_cfg.head_y_size;
|
|
scale_frame->frame.stride.y_head_stride = vb_cal_cfg.head_y_stride;
|
|
scale_frame->frame.stride.c_head_stride = vb_cal_cfg.head_c_stride;
|
|
scale_frame->frame.addr.y_phy_addr = scale_frame->frame.addr.y_head_phy_addr + vb_cal_cfg.head_size;
|
|
scale_frame->frame.addr.c_phy_addr = scale_frame->frame.addr.y_head_phy_addr + vb_cal_cfg.main_y_size;
|
|
scale_frame->frame.stride.y_stride = vb_cal_cfg.main_stride;
|
|
scale_frame->frame.stride.c_stride = vb_cal_cfg.main_stride;
|
|
|
|
memcpy(&task_info.img_in, vpss_frame, sizeof(xmedia_video_frame_info));
|
|
memcpy(&task_info.img_out, scale_frame, sizeof(xmedia_video_frame_info));
|
|
ret = xmedia_vgs_add_task_scale(job_handle, &task_info, XMEDIA_VIDEO_SCALE_MODE_NORMAL);
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
xmedia_vgs_cancel_job(job_handle);
|
|
SAMPLE_PRT("xmedia_vgs_add_task_scale failed!\n");
|
|
goto EXIT2;
|
|
}
|
|
|
|
ret = xmedia_vgs_submit_job(job_handle);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("submit vgs job failed\n");
|
|
goto EXIT2;
|
|
}
|
|
|
|
ret = xmedia_vgs_wait_job(job_handle, 2000);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("wait vgs job failed\n");
|
|
goto EXIT1;
|
|
}
|
|
|
|
xmedia_vgs_exit();
|
|
|
|
return XMEDIA_SUCCESS;
|
|
|
|
EXIT2:
|
|
xmedia_vgs_cancel_job(job_handle);
|
|
EXIT1:
|
|
xmedia_vgs_exit();
|
|
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
static int sample_yuv_sys_init(int sensor_type)
|
|
{
|
|
xmedia_s32 ret, idx;
|
|
xmedia_s32 blk_size = 0;
|
|
vi_sensor_info sensor_info = {0};
|
|
xmedia_video_size pic_size = {0};
|
|
sample_sys_config sys_config = {0};
|
|
|
|
func_entry();
|
|
|
|
g_video_param.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
|
|
g_video_param.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420; /* NV21 */
|
|
g_video_param.data_width = XMEDIA_VIDEO_DATA_WIDTH_8;
|
|
g_video_param.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
|
|
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
|
|
|
|
// sys init
|
|
sys_config.sys_conf.pipe_mode[g_vi_pipe].vicap_viproc_mode = XMEDIA_WORK_MODE_ONLINE;
|
|
sys_config.sys_conf.pipe_mode[g_vi_pipe].viproc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[g_vi_pipe].gdc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
|
|
sys_config.vb_conf.max_pool_cnt = 25;
|
|
|
|
pic_size.width = sensor_info.width;
|
|
pic_size.height = sensor_info.height;
|
|
|
|
venc_logd("sensor resolution: w(%d) x h(%d).\n", pic_size.width, pic_size.height);
|
|
|
|
idx = 0;
|
|
|
|
if (sys_config.sys_conf.pipe_mode[g_vi_pipe].vicap_viproc_mode == XMEDIA_WORK_MODE_OFFLINE) {
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, g_video_param.video_fmt, sensor_info.pixel_format,
|
|
sensor_info.bit_width, g_video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[idx].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[idx].block_cnt = 2;
|
|
|
|
idx++;
|
|
}
|
|
|
|
if (sys_config.sys_conf.pipe_mode[g_vi_pipe].viproc_vpss_mode == XMEDIA_WORK_MODE_OFFLINE) {
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, g_video_param.video_fmt, g_video_param.pixel_fmt,
|
|
g_video_param.data_width, g_video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[idx].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[idx].block_cnt = 3;
|
|
|
|
idx++;
|
|
}
|
|
|
|
get_user_format(NULL, &pic_size, NULL);
|
|
venc_logi("user resolution: %d(w) x %d(h)\n", pic_size.width, pic_size.height);
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, g_video_param.video_fmt, g_video_param.pixel_fmt,
|
|
g_video_param.data_width, g_video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[idx].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[idx].block_cnt = 3;
|
|
|
|
sys_config.vb_conf.supplement_config = 1;
|
|
|
|
ret = sample_comm_sys_init(&sys_config);
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_sys_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
//in online-online mode,vi and vpss must be reset at the same time
|
|
ret = sample_comm_vi_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_vi_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_comm_vpss_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_vpss_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
func_success();
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static int sample_yuv_sys_deinit(void)
|
|
{
|
|
sample_comm_vpss_exit();
|
|
|
|
sample_comm_vi_exit();
|
|
|
|
sample_comm_sys_exit();
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 vpss_ochn_dump_transform_format(xmedia_video_frame_info *frame_in,
|
|
xmedia_video_frame_info *tmp_frame, xmedia_video_frame_info *frame_out)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_vgs_frame_info task_info;
|
|
xmedia_s32 job_handle;
|
|
|
|
ret = xmedia_vgs_init();
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("vgs init failed\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = xmedia_vgs_create_job(&job_handle);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("create vgs job failed\n");
|
|
xmedia_vgs_exit();
|
|
goto EXIT1;
|
|
}
|
|
|
|
if (frame_in->frame.video_fmt == XMEDIA_VIDEO_FMT_TILE_16x4) {
|
|
memcpy(&task_info.img_in, frame_in, sizeof(xmedia_video_frame_info));
|
|
memcpy(&task_info.img_out, tmp_frame, sizeof(xmedia_video_frame_info));
|
|
ret = xmedia_vgs_add_task_rotation(job_handle, &task_info, XMEDIA_VIDEO_ROTATION_0);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("add vgs task failed\n");
|
|
goto EXIT2;
|
|
}
|
|
}
|
|
|
|
memcpy(&task_info.img_in, tmp_frame, sizeof(xmedia_video_frame_info));
|
|
memcpy(&task_info.img_out, frame_out, sizeof(xmedia_video_frame_info));
|
|
ret = xmedia_vgs_add_task_rotation(job_handle, &task_info, XMEDIA_VIDEO_ROTATION_0);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("add vgs task failed\n");
|
|
goto EXIT2;
|
|
}
|
|
|
|
ret = xmedia_vgs_submit_job(job_handle);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("submit vgs job failed\n");
|
|
goto EXIT2;
|
|
}
|
|
|
|
ret = xmedia_vgs_wait_job(job_handle, 2000);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("wait vgs job failed\n");
|
|
goto EXIT1;
|
|
}
|
|
|
|
xmedia_vgs_exit();
|
|
|
|
return XMEDIA_SUCCESS;
|
|
|
|
EXIT2:
|
|
xmedia_vgs_cancel_job(job_handle);
|
|
EXIT1:
|
|
xmedia_vgs_exit();
|
|
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
static int nv21_to_nv21(unsigned char* src_nv21, unsigned int width, unsigned int height,
|
|
unsigned char* nv21, unsigned int nv21_len)
|
|
{
|
|
int copy_size;
|
|
|
|
copy_size = width * height * 3 / 2;
|
|
if (copy_size > nv21_len) {
|
|
return 0;
|
|
}
|
|
|
|
memcpy(nv21, src_nv21, copy_size);
|
|
|
|
return copy_size;
|
|
}
|
|
|
|
static int nv21_to_yuyv(unsigned char* nv21, unsigned int width, unsigned int height,
|
|
unsigned char* yuyv, unsigned int yuyv_len)
|
|
{
|
|
int copy_size;
|
|
|
|
copy_size = width * height * 2;
|
|
if (copy_size > yuyv_len) {
|
|
return 0;
|
|
}
|
|
|
|
memcpy(yuyv, nv21, copy_size);
|
|
|
|
return copy_size;
|
|
}
|
|
|
|
static void sample_yuv_save_data(unsigned char* yuv, unsigned int src_fmt,
|
|
unsigned int width, unsigned int height)
|
|
{
|
|
unsigned int copy_size = 0;
|
|
uvc_cache_t *uvc_cache = uvc_cache_get();
|
|
frame_node_t *fnode = NULL;
|
|
|
|
if (uvc_cache) {
|
|
get_node_from_queue(uvc_cache->free_queue, &fnode);
|
|
}
|
|
|
|
if (!fnode) {
|
|
venc_logd("drop frame.\n");
|
|
return;
|
|
}
|
|
|
|
switch (g_tag_fmt) {
|
|
case V4L2_PIX_FMT_YUYV:
|
|
copy_size = nv21_to_yuyv(yuv, width, height, fnode->mem, fnode->length);
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_NV21:
|
|
copy_size = nv21_to_nv21(yuv, width, height, fnode->mem, fnode->length);
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_NV12:
|
|
case V4L2_PIX_FMT_YUV420:
|
|
case V4L2_PIX_FMT_YVU420:
|
|
default:
|
|
venc_logw("send default format NV21.\n");
|
|
copy_size = nv21_to_nv21(yuv, width, height, fnode->mem, fnode->length);
|
|
break;
|
|
}
|
|
|
|
|
|
if (copy_size == 0) {
|
|
venc_loge("cache size is to small.\n");
|
|
}
|
|
|
|
fnode->used = copy_size;
|
|
|
|
venc_logd("send size(%u)\n", fnode->used);
|
|
|
|
put_node_to_queue(uvc_cache->ok_queue, fnode);
|
|
}
|
|
|
|
//static int flag = 0;
|
|
static void sample_yuv_save_frame(xmedia_video_frame_info vpss_frame)
|
|
{
|
|
char* virt_addr_y;
|
|
xmedia_u64 phy_addr;
|
|
xmedia_u32 size;
|
|
xmedia_char* page_addr[2];
|
|
xmedia_video_frame *video_frame = &vpss_frame.frame;
|
|
xmedia_video_pixel_format pixel_fmt = video_frame->pixel_fmt;
|
|
xmedia_video_frame_info scale_frame;
|
|
|
|
if (g_tag_fmt == V4L2_PIX_FMT_YUYV) {
|
|
vgs_nv12_to_yuyv(&vpss_frame, &scale_frame);
|
|
}
|
|
|
|
if (video_frame->compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
|
|
video_frame->stride.y_stride = video_frame->width;
|
|
video_frame->stride.c_stride = video_frame->width;
|
|
}
|
|
|
|
if ((pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) ||
|
|
(pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420)) {
|
|
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
|
|
} else if (pixel_fmt == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
|
|
size = video_frame->stride.y_stride * video_frame->height;
|
|
} else {
|
|
size = video_frame->stride.y_stride * video_frame->height * 3 / 2;
|
|
}
|
|
|
|
if (g_tag_fmt == V4L2_PIX_FMT_YUYV) {
|
|
phy_addr = scale_frame.frame.addr.y_phy_addr;
|
|
size = video_frame->stride.y_stride * video_frame->height * 2;
|
|
pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YUYV_PACKAGE_422; //XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422;
|
|
} else {
|
|
phy_addr = video_frame->addr.y_phy_addr;
|
|
}
|
|
|
|
page_addr[0] = (xmedia_char*)xmedia_mmz_map(phy_addr, size, XMEDIA_FALSE);
|
|
if (XMEDIA_NULL == page_addr[0]) {
|
|
venc_loge("xmedia_mmz_map failed.\n");
|
|
return;
|
|
}
|
|
|
|
virt_addr_y = page_addr[0];
|
|
|
|
debug_dump_frame((char*)virt_addr_y, size, "frame_vpss.yuv");
|
|
sample_yuv_save_data((unsigned char*)virt_addr_y, pixel_fmt,
|
|
video_frame->stride.y_stride, video_frame->height);
|
|
|
|
xmedia_mmz_unmap(page_addr[0]);
|
|
page_addr[0] = XMEDIA_NULL;
|
|
if (g_tag_fmt == V4L2_PIX_FMT_YUYV) {
|
|
xmedia_vb_release_block(xmedia_vb_phy_addr_to_handle(scale_frame.frame.addr.y_head_phy_addr));
|
|
}
|
|
}
|
|
|
|
void* sample_yuv_stream_proc(void* arg)
|
|
{
|
|
int ret;
|
|
xmedia_vb_base_info base_info;
|
|
xmedia_vb_cal_cfg cal_cfg;
|
|
xmedia_s32 millisec = -1;
|
|
xmedia_handle vb_handle = VB_INVALID_HANDLE;
|
|
xmedia_handle tmp_handle = VB_INVALID_HANDLE;
|
|
xmedia_video_frame_info tmp_frame = {0};
|
|
xmedia_video_frame_info frame_out = {0};
|
|
|
|
g_vpss_depth_flag = 1;
|
|
|
|
while (g_recv) {
|
|
memset(&g_vpss_frame_info, 0, sizeof(xmedia_video_frame_info));
|
|
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
|
|
|
|
ret = xmedia_vpss_acquire_ochn_frame(g_vpss_pipe, g_vpss_ochn, &g_vpss_frame_info, millisec);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_logi("piipe(%d) ochn(%d) get frame failed!\n", g_vpss_pipe, g_vpss_ochn);
|
|
usleep(1000);
|
|
continue;
|
|
}
|
|
|
|
venc_logd("pipe(%d) ochn(%d) video_fmt(%d) save frame!\n", g_vpss_pipe, g_vpss_ochn,
|
|
g_vpss_frame_info.frame.video_fmt);
|
|
|
|
if (g_vpss_frame_info.frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
|
|
memset(&base_info, 0, sizeof(xmedia_vb_base_info));
|
|
base_info.align = 0;
|
|
base_info.bit_width = g_vpss_frame_info.frame.bit_width;
|
|
base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
base_info.width = g_vpss_frame_info.frame.width;
|
|
base_info.height = g_vpss_frame_info.frame.height;
|
|
base_info.pixel_fmt = g_vpss_frame_info.frame.pixel_fmt;
|
|
|
|
if (g_vpss_frame_info.frame.video_fmt == XMEDIA_VIDEO_FMT_TILE_16x4) {
|
|
base_info.video_fmt = XMEDIA_VIDEO_FMT_TILE_64x4;
|
|
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_logw("get buffer config failed with 0x%x\n", ret);
|
|
continue;
|
|
}
|
|
|
|
tmp_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, NULL);
|
|
if (tmp_handle == VB_INVALID_HANDLE) {
|
|
venc_logw("get block failed\n");
|
|
continue;
|
|
}
|
|
|
|
memcpy(&tmp_frame, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
|
|
tmp_frame.pool_id = xmedia_vb_handle_to_pool_id(tmp_handle);
|
|
tmp_frame.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(tmp_handle);
|
|
tmp_frame.frame.addr.y_head_phy_addr = tmp_frame.frame.addr.y_phy_addr;
|
|
tmp_frame.frame.addr.c_phy_addr = tmp_frame.frame.addr.y_phy_addr + cal_cfg.main_y_size;
|
|
tmp_frame.frame.stride.y_stride = cal_cfg.main_stride;
|
|
tmp_frame.frame.stride.c_stride = cal_cfg.main_stride;
|
|
tmp_frame.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
tmp_frame.frame.video_fmt = XMEDIA_VIDEO_FMT_TILE_64x4;
|
|
} else {
|
|
memcpy(&tmp_frame, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
|
|
}
|
|
|
|
base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
|
|
ret = xmedia_vb_get_buffer_config(&base_info, &cal_cfg);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
if (tmp_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(tmp_handle);
|
|
tmp_handle = VB_INVALID_HANDLE;
|
|
}
|
|
venc_logw("get buffer config failed with 0x%x\n", ret);
|
|
continue;
|
|
}
|
|
|
|
vb_handle = xmedia_vb_get_block(-1, cal_cfg.vb_size, NULL);
|
|
if (vb_handle == VB_INVALID_HANDLE) {
|
|
if (tmp_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(tmp_handle);
|
|
tmp_handle = VB_INVALID_HANDLE;
|
|
}
|
|
venc_logw("get block failed\n");
|
|
continue;
|
|
}
|
|
|
|
memcpy(&frame_out, &tmp_frame, sizeof(xmedia_video_frame_info));
|
|
frame_out.pool_id = xmedia_vb_handle_to_pool_id(vb_handle);
|
|
frame_out.frame.addr.y_phy_addr = xmedia_vb_handle_to_phy_addr(vb_handle);
|
|
frame_out.frame.addr.y_head_phy_addr = frame_out.frame.addr.y_phy_addr;
|
|
frame_out.frame.addr.c_phy_addr = frame_out.frame.addr.y_phy_addr + cal_cfg.main_y_size;
|
|
frame_out.frame.stride.y_stride = cal_cfg.main_stride;
|
|
frame_out.frame.stride.c_stride = cal_cfg.main_stride;
|
|
frame_out.frame.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
frame_out.frame.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
|
|
|
|
ret = vpss_ochn_dump_transform_format(&g_vpss_frame_info, &tmp_frame, &frame_out);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
if (tmp_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(tmp_handle);
|
|
tmp_handle = VB_INVALID_HANDLE;
|
|
}
|
|
|
|
if (vb_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(vb_handle);
|
|
vb_handle = VB_INVALID_HANDLE;
|
|
}
|
|
venc_logw("pipe %d ochn %d vpss_ochn_dump_transform_format failed\n", g_vpss_pipe, g_vpss_ochn);
|
|
continue;
|
|
}
|
|
} else {
|
|
memcpy(&frame_out, &g_vpss_frame_info, sizeof(xmedia_video_frame_info));
|
|
}
|
|
|
|
sample_yuv_save_frame(frame_out);
|
|
|
|
if (tmp_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(tmp_handle);
|
|
tmp_handle = VB_INVALID_HANDLE;
|
|
}
|
|
|
|
if (vb_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(vb_handle);
|
|
vb_handle = VB_INVALID_HANDLE;
|
|
}
|
|
|
|
ret = xmedia_vpss_release_ochn_frame(g_vpss_pipe, g_vpss_ochn, &g_vpss_frame_info);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("pipe(%d) ochn(%d) release frame failed!\n", g_vpss_pipe, g_vpss_ochn);
|
|
}
|
|
}
|
|
|
|
g_vpss_frame_info.pool_id = VB_INVALID_POOLID;
|
|
|
|
if (tmp_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(tmp_handle);
|
|
tmp_handle = VB_INVALID_HANDLE;
|
|
}
|
|
|
|
if (vb_handle != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(vb_handle);
|
|
vb_handle = VB_INVALID_HANDLE;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int sample_yuv_start_get_stream(int venc_chn, int cnt)
|
|
{
|
|
int rc;
|
|
|
|
g_recv = 1;
|
|
|
|
rc = pthread_create(&g_recv_pid, NULL, sample_yuv_stream_proc, NULL);
|
|
if (rc < 0) {
|
|
venc_loge("Create sample_yuv_stream_proc failed.\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sample_yuv_stop_get_stream(void)
|
|
{
|
|
|
|
if (g_recv == 1) {
|
|
g_recv = 0;
|
|
pthread_join(g_recv_pid, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sample_yuv_normalp_classic(void)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
|
|
xmedia_u32 framerate = 0, fps_user = 0;
|
|
xmedia_video_size pic_size = {0};
|
|
xmedia_video_size vpss_ochn_size = {0};
|
|
xmedia_isp_config isp_config = {0};
|
|
xmedia_payload_type en_payload = PT_MJPEG;
|
|
vi_sensor_info sensor_info = {0};
|
|
|
|
g_vi_config.dev_info[g_vi_dev].dev_en = XMEDIA_TRUE;
|
|
g_vi_config.dev_info[g_vi_dev].dev_no = g_vi_dev;
|
|
g_vi_config.dev_info[g_vi_dev].sensor_type = g_sensor_type;
|
|
g_vi_config.pipe_info[g_vi_pipe].pipe_en = XMEDIA_TRUE;
|
|
g_vi_config.pipe_info[g_vi_pipe].pipe_no = g_vi_pipe;
|
|
g_vi_config.pipe_info[g_vi_pipe].chn_info[g_vi_chn].chn_en = XMEDIA_TRUE;
|
|
g_vi_config.pipe_info[g_vi_pipe].chn_info[g_vi_chn].chn_no = g_vi_chn;
|
|
g_vi_config.dev_bind_pipe[g_vi_dev].pipe[0] = g_vi_pipe;
|
|
g_vi_config.dev_bind_pipe[g_vi_dev].pipe[1] = -1;
|
|
|
|
sample_comm_vi_get_sensor_info(g_sensor_type, &sensor_info);
|
|
sample_comm_vi_get_framerate_by_sensor(g_sensor_type, &framerate);
|
|
|
|
get_user_format(NULL, NULL, &fps_user);
|
|
if (fps_user > framerate) {
|
|
venc_logw("User framerate(%d) > sensor framerate(%d), used sensor framerate\n", fps_user, framerate);
|
|
} else {
|
|
framerate = fps_user;
|
|
}
|
|
|
|
venc_logi("isp framerate(%d)\n", framerate);
|
|
isp_config.fps = framerate;
|
|
isp_config.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
|
|
isp_config.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
|
|
isp_config.mode_config.master_mode.slave_num = 0;
|
|
isp_config.pixel_fmt = sensor_info.pixel_format;
|
|
isp_config.size.height = sensor_info.height;
|
|
isp_config.size.width = sensor_info.width;
|
|
pic_size.height = sensor_info.height;
|
|
pic_size.width = sensor_info.width;
|
|
isp_config.wdr_mode = sensor_info.wdr_mode;
|
|
|
|
// isp pipe init
|
|
g_isp_param.pipe[g_vi_pipe] = g_vi_pipe;
|
|
g_isp_param.isp_info[g_vi_pipe].sensor_type = g_sensor_type;
|
|
g_isp_param.isp_info[g_vi_pipe].flip = XMEDIA_FALSE;
|
|
g_isp_param.isp_info[g_vi_pipe].mirror = XMEDIA_FALSE;
|
|
g_isp_param.isp_info[g_vi_pipe].isp_pipe_en = XMEDIA_TRUE;
|
|
g_isp_param.isp_info[g_vi_pipe].isp_sensor_en = XMEDIA_TRUE;
|
|
|
|
memcpy(&(g_isp_param.isp_info[g_vi_pipe].isp_config), &isp_config, sizeof(xmedia_isp_config));
|
|
|
|
// isp init
|
|
ret = sample_comm_isp_init(&g_isp_param, &g_vi_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("isp init failed!\n");
|
|
goto exit0;
|
|
}
|
|
|
|
// vi start
|
|
ret = sample_comm_vi_start(&g_vi_config, &g_video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("start vi failed!\n");
|
|
goto exit1;
|
|
}
|
|
|
|
// isp start
|
|
ret = sample_comm_isp_start(&g_isp_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("start isp failed!\n");
|
|
goto exit2;
|
|
}
|
|
|
|
// vpss config
|
|
ret = sample_comm_vpss_get_default_pipe_cfg(&g_vpss_config.pipe_info[g_vpss_pipe].pipe_config, pic_size, &g_video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("get default pipe cfg failed !\n");
|
|
goto exit2;
|
|
}
|
|
|
|
get_user_format(&en_payload, &pic_size, NULL);
|
|
#if 0
|
|
vpss_ochn_size.width = sensor_info.width;
|
|
vpss_ochn_size.height = sensor_info.height;
|
|
#else
|
|
vpss_ochn_size.width = pic_size.width;
|
|
vpss_ochn_size.height = pic_size.height;
|
|
#endif
|
|
|
|
g_vpss_config.pipe_info[g_vpss_pipe].pipe_en = XMEDIA_TRUE;
|
|
g_vpss_config.pipe_info[g_vpss_pipe].pipe_no = g_vpss_pipe;
|
|
|
|
g_vpss_config.pipe_info[g_vpss_pipe].chn_info[g_vpss_ochn].chn_en = XMEDIA_TRUE;
|
|
g_vpss_config.pipe_info[g_vpss_pipe].chn_info[g_vpss_ochn].chn_no = g_vpss_ochn;
|
|
ret = sample_comm_vpss_get_default_ochn_cfg(&g_vpss_config.pipe_info[g_vpss_pipe].chn_info[g_vpss_ochn].chn_config,
|
|
vpss_ochn_size, &g_video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("get default pipe cfg failed !\n");
|
|
goto exit2;
|
|
}
|
|
#if 0
|
|
ret = sample_comm_vpss_set_ochn_wrap(&g_vpss_config.pipe_info[g_vpss_pipe].chn_info[g_vpss_ochn]);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("get default pipe cfg failed !\n");
|
|
goto exit2;
|
|
}
|
|
#endif
|
|
|
|
// vpss start
|
|
ret = sample_comm_vpss_start(&g_vpss_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("vpss start failed !\n");
|
|
goto exit2;
|
|
}
|
|
|
|
ret = sample_comm_sys_vi_bind_vpss(g_vi_pipe, g_vi_chn, g_vpss_pipe, g_vpss_ichn);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("vi bind vpss failed !\n");
|
|
goto exit3;
|
|
}
|
|
|
|
return 0;
|
|
|
|
exit3:
|
|
sample_comm_vpss_stop(&g_vpss_config);
|
|
exit2:
|
|
sample_comm_isp_stop(&g_isp_param);
|
|
exit1:
|
|
sample_comm_vi_stop(&g_vi_config);
|
|
exit0:
|
|
sample_comm_isp_exit(&g_isp_param);
|
|
|
|
sample_yuv_sys_deinit();
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*******************************************************
|
|
* Processing Unit Operation Functions
|
|
*******************************************************/
|
|
|
|
/* Processing Unit Operation Functions End */
|
|
|
|
/*******************************************************
|
|
* Input Terminal Operation Functions
|
|
*******************************************************/
|
|
|
|
/* Input Terminal Operation Functions End */
|
|
|
|
/*******************************************************
|
|
* Stream Control Operation Functions
|
|
*******************************************************/
|
|
int sample_yuv_set_idr(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int sample_yuv_init(void)
|
|
{
|
|
g_sensor_type = SENSOR0_TYPE;
|
|
sample_yuv_sys_init(g_sensor_type);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sample_yuv_startup(int fmt)
|
|
{
|
|
g_start = 1;
|
|
|
|
if (sample_yuv_normalp_classic() < 0) {
|
|
return -1;
|
|
}
|
|
|
|
g_tag_fmt = fmt;
|
|
if (g_tag_fmt == V4L2_PIX_FMT_YUYV) {
|
|
sample_yuv_create_yuyv_pool();
|
|
}
|
|
sample_yuv_start_get_stream(g_vpss_ochn, 1);
|
|
return 0;
|
|
}
|
|
|
|
int sample_yuv_shutdown(void)
|
|
{
|
|
if (!g_start) {
|
|
return 0;
|
|
}
|
|
|
|
sample_yuv_stop_get_stream();
|
|
|
|
sample_comm_sys_vi_unbind_vpss(g_vi_pipe, g_vi_chn, g_vpss_pipe, g_vpss_ichn);
|
|
|
|
sample_comm_vpss_stop(&g_vpss_config);
|
|
|
|
sample_comm_isp_stop(&g_isp_param);
|
|
|
|
sample_comm_vi_stop(&g_vi_config);
|
|
|
|
sample_comm_isp_exit(&g_isp_param);
|
|
|
|
sample_yuv_sys_deinit();
|
|
|
|
g_start = 0;
|
|
|
|
return 0;
|
|
}
|