/* * Copyright (c) XMEDIA. All rights reserved. */ #include #include #include #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; }