sdk-hwV1.3/lichee/linux-4.9/drivers/media/rt-media/component/rt_venc_component.c

3224 lines
114 KiB
C

#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/g2d_driver.h>
#include <linux/fs.h>
#include "vin_video_api.h"
#define LOG_TAG "rt_venc_comp"
#include "rt_common.h"
#include "rt_venc_component.h"
#include "rt_message.h"
#include <uapi_rt_media.h>
#define TEST_ENCODER_BY_SELF (0)
#define DEBUG_VBV_CACHE_TIME (4) // unit:seconds, exp:1,2,3,4...
#define ENABLE_SAVE_NATIVE_OVERLAY_DATA (0)
DEFINE_MUTEX(venc_mutex);
extern int g2d_blit_h_new(g2d_blt_h *para);
extern int g2d_open(struct inode *inode, struct file *file);
extern int g2d_release(struct inode *inode, struct file *file);
extern void g2d_ioctl_mutex_lock(void);
extern void g2d_ioctl_mutex_unlock(void);
typedef struct catch_jpeg_cxt {
int enable;
int encoder_finish_flag;
VideoEncoder *vencoder;
int width;
int height;
int qp;
wait_queue_head_t wait_enc_finish;
unsigned int wait_enc_finish_condition;
} catch_jpeg_cxt;
typedef struct venc_comp_ctx {
int vencoder_init_flag;
VideoEncoder *vencoder;
comp_state_type state;
struct task_struct *venc_thread;
message_queue_t msg_queue;
comp_callback_type *callback;
void *callback_data;
rt_component_type *self_comp;
wait_queue_head_t wait_reply[WAIT_REPLY_NUM];
unsigned int wait_reply_condition[WAIT_REPLY_NUM];
venc_inbuf_manager in_buf_manager;
venc_outbuf_manager out_buf_manager;
comp_tunnel_info in_port_tunnel_info;
comp_tunnel_info out_port_tunnel_info;
venc_comp_base_config base_config;
venc_comp_normal_config normal_config;
int actual_en_encpp_sharp; ///< indicate if actually enable encpp sharp on venc.
unsigned char *vbvStartAddr;
catch_jpeg_cxt jpeg_cxt;
int is_first_frame;
VencCbType vencCallBack;
VencOverlayInfoS *venc_overlayInfo;
int mActiveDropNum; // for COMP_COMMAND_VENC_DROP_FRAME.
eCameraStatus camera_move_status;
RTDynamicProcSettings st_dynamic_proc_set;
} venc_comp_ctx;
#define GLOBAL_OSD_MAX_NUM (3)
typedef struct native_osd_info {
VencOverlayInfoS sOverlayInfo;
unsigned int ori_frame_w;
unsigned int ori_frame_h;
struct mem_interface *memops;
/* the g2d_in_buf will not release at all, so it can setup to vencoder immediately when start */
unsigned char *g2d_in_ion_vir_addr[GLOBAL_OSD_MAX_NUM];
unsigned int g2d_in_buf_size[GLOBAL_OSD_MAX_NUM];
} native_osd_info;
//static native_osd_info *global_osd_info;
static int thread_process_venc(void *param);
int adjust_native_overlay_info(venc_comp_ctx *venc_comp);
static int config_VencOutputBuffer_by_videostream(venc_comp_ctx *venc_comp,
VencOutputBuffer *output_buffer,
video_stream_s *video_stream)
{
if (venc_comp->vbvStartAddr == NULL) {
RT_LOGE("venc_comp->vbvStartAddr is null");
return -1;
}
output_buffer->nID = video_stream->id;
output_buffer->nPts = video_stream->pts;
output_buffer->nFlag = video_stream->flag;
output_buffer->nSize0 = video_stream->size0;
output_buffer->nSize1 = video_stream->size1;
output_buffer->nSize2 = video_stream->size2;
output_buffer->pData0 = venc_comp->vbvStartAddr + video_stream->offset0;
output_buffer->pData1 = venc_comp->vbvStartAddr + video_stream->offset1;
output_buffer->pData2 = venc_comp->vbvStartAddr + video_stream->offset2;
output_buffer->pData0 = video_stream->data0;
output_buffer->pData1 = video_stream->data1;
output_buffer->pData2 = video_stream->data2;
RT_LOGD("request stream: pData0 =%p, %p, id = %d",
video_stream->data0, output_buffer->pData0, output_buffer->nID);
return 0;
}
static int config_videostream_by_VencOutputBuffer(venc_comp_ctx *venc_comp,
VencOutputBuffer *output_buffer,
video_stream_s *video_stream)
{
if (venc_comp->vbvStartAddr == NULL) {
RT_LOGE("venc_comp->vbvStartAddr is null");
return -1;
}
video_stream->id = output_buffer->nID;
video_stream->pts = output_buffer->nPts;
video_stream->flag = output_buffer->nFlag;
video_stream->size0 = output_buffer->nSize0;
video_stream->size1 = output_buffer->nSize1;
video_stream->size2 = output_buffer->nSize2;
video_stream->offset0 = output_buffer->pData0 - venc_comp->vbvStartAddr;
if (output_buffer->pData1)
video_stream->offset1 = output_buffer->pData1 - venc_comp->vbvStartAddr;
if (output_buffer->pData2)
video_stream->offset2 = output_buffer->pData2 - venc_comp->vbvStartAddr;
video_stream->data0 = output_buffer->pData0;
video_stream->data1 = output_buffer->pData1;
video_stream->data2 = output_buffer->pData2;
RT_LOGD("reqeust stream: pData0 =%p, %p, id = %d",
video_stream->data0, output_buffer->pData0,
output_buffer->nID);
if (video_stream->flag & VENC_BUFFERFLAG_KEYFRAME)
video_stream->keyframe_flag = 1;
else
video_stream->keyframe_flag = 0;
return 0;
}
#if NEI_TEST_CODE
static int init_default_encpp_param(sEncppSharpParamDynamic *pSharpParamDynamic,
sEncppSharpParamStatic *pSharpParamStatic, s3DfilterParam *p3DfilterParam, s2DfilterParam *p2DfilterParam)
{
p3DfilterParam->enable_3d_filter = 1;
p3DfilterParam->adjust_pix_level_enable = 0;
p3DfilterParam->smooth_filter_enable = 1;
p3DfilterParam->max_pix_diff_th = 6;
p3DfilterParam->max_mad_th = 8;
p3DfilterParam->max_mv_th = 8;
p3DfilterParam->min_coef = 15;
p3DfilterParam->max_coef = 16;
p2DfilterParam->enable_2d_filter = 1;
p2DfilterParam->filter_strength_uv = 46;
p2DfilterParam->filter_strength_y = 46;
p2DfilterParam->filter_th_uv = 3;
p2DfilterParam->filter_th_y = 2;
pSharpParamDynamic->ss_ns_lw = 0; //[0,255];
pSharpParamDynamic->ss_ns_hi = 0; //[0,255];
pSharpParamDynamic->ls_ns_lw = 0; //[0,255];
pSharpParamDynamic->ls_ns_hi = 0; //[0,255];
pSharpParamDynamic->ss_lw_cor = 180; //[0,255];
pSharpParamDynamic->ss_hi_cor = 255; //[0,255];
pSharpParamDynamic->ls_lw_cor = 120; //[0,255];
pSharpParamDynamic->ls_hi_cor = 255; //[0,255];
pSharpParamDynamic->ss_blk_stren = 552; //[0,4095];
pSharpParamDynamic->ss_wht_stren = 423; //[0,4095];
pSharpParamDynamic->ls_blk_stren = 1408; //[0,4095];
pSharpParamDynamic->ls_wht_stren = 952; //[0,4095];
pSharpParamDynamic->ss_avg_smth = 0; //[0,255];
pSharpParamDynamic->ss_dir_smth = 0; //[0,16];
pSharpParamDynamic->dir_smth[0] = 0; //[0,16];
pSharpParamDynamic->dir_smth[1] = 0; //[0,16];
pSharpParamDynamic->dir_smth[2] = 0; //[0,16];
pSharpParamDynamic->dir_smth[3] = 0; //[0,16];
pSharpParamDynamic->hfr_smth_ratio = 0; //[0,32];
pSharpParamDynamic->hfr_hf_wht_stren = 0; //[0,4095];
pSharpParamDynamic->hfr_hf_blk_stren = 0; //[0,4095];
pSharpParamDynamic->hfr_mf_wht_stren = 0; //[0,4095];
pSharpParamDynamic->hfr_mf_blk_stren = 0; //[0,4095];
pSharpParamDynamic->hfr_hf_cor_ratio = 0; //[0,255];
pSharpParamDynamic->hfr_mf_cor_ratio = 0; //[0,255];
pSharpParamDynamic->hfr_hf_mix_ratio = 390; //[0,1023];
pSharpParamDynamic->hfr_mf_mix_ratio = 390; //[0,1023];
pSharpParamDynamic->hfr_hf_mix_min_ratio = 0; //[0,255];
pSharpParamDynamic->hfr_mf_mix_min_ratio = 0; //[0,255];
pSharpParamDynamic->hfr_hf_wht_clp = 32; //[0,255];
pSharpParamDynamic->hfr_hf_blk_clp = 32; //[0,255];
pSharpParamDynamic->hfr_mf_wht_clp = 32; //[0,255];
pSharpParamDynamic->hfr_mf_blk_clp = 32; //[0,255];
pSharpParamDynamic->wht_clp_para = 256; //[0,1023];
pSharpParamDynamic->blk_clp_para = 256; //[0,1023];
pSharpParamDynamic->wht_clp_slp = 16; //[0,63];
pSharpParamDynamic->blk_clp_slp = 8; //[0,63];
pSharpParamDynamic->max_clp_ratio = 64; //[0,255];
pSharpParamDynamic->sharp_edge_lum[0] = 0;
pSharpParamDynamic->sharp_edge_lum[1] = 14;
pSharpParamDynamic->sharp_edge_lum[2] = 25;
pSharpParamDynamic->sharp_edge_lum[3] = 32;
pSharpParamDynamic->sharp_edge_lum[4] = 39;
pSharpParamDynamic->sharp_edge_lum[5] = 51;
pSharpParamDynamic->sharp_edge_lum[6] = 65;
pSharpParamDynamic->sharp_edge_lum[7] = 80;
pSharpParamDynamic->sharp_edge_lum[8] = 99;
pSharpParamDynamic->sharp_edge_lum[9] = 124;
pSharpParamDynamic->sharp_edge_lum[10] = 152;
pSharpParamDynamic->sharp_edge_lum[11] = 179;
pSharpParamDynamic->sharp_edge_lum[12] = 203;
pSharpParamDynamic->sharp_edge_lum[13] = 224;
pSharpParamDynamic->sharp_edge_lum[14] = 237;
pSharpParamDynamic->sharp_edge_lum[15] = 245;
pSharpParamDynamic->sharp_edge_lum[16] = 271;
pSharpParamDynamic->sharp_edge_lum[17] = 336;
pSharpParamDynamic->sharp_edge_lum[18] = 428;
pSharpParamDynamic->sharp_edge_lum[19] = 526;
pSharpParamDynamic->sharp_edge_lum[20] = 623;
pSharpParamDynamic->sharp_edge_lum[21] = 709;
pSharpParamDynamic->sharp_edge_lum[22] = 767;
pSharpParamDynamic->sharp_edge_lum[23] = 782;
pSharpParamDynamic->sharp_edge_lum[24] = 772;
pSharpParamDynamic->sharp_edge_lum[25] = 761;
pSharpParamDynamic->sharp_edge_lum[26] = 783;
pSharpParamDynamic->sharp_edge_lum[27] = 858;
pSharpParamDynamic->sharp_edge_lum[28] = 941;
pSharpParamDynamic->sharp_edge_lum[29] = 988;
pSharpParamDynamic->sharp_edge_lum[30] = 1006;
pSharpParamDynamic->sharp_edge_lum[31] = 1016;
pSharpParamDynamic->sharp_edge_lum[32] = 1023;
pSharpParamStatic->ss_shp_ratio = 0; //[0,255];
pSharpParamStatic->ls_shp_ratio = 0; //[0,255];
pSharpParamStatic->ss_dir_ratio = 64; //[0,1023];
pSharpParamStatic->ls_dir_ratio = 255; //[0,1023];
pSharpParamStatic->ss_crc_stren = 0; //[0,1023];
pSharpParamStatic->ss_crc_min = 16; //[0,255];
pSharpParamStatic->wht_sat_ratio = 64;
pSharpParamStatic->blk_sat_ratio = 64;
pSharpParamStatic->wht_slp_bt = 1;
pSharpParamStatic->blk_slp_bt = 1;
pSharpParamStatic->sharp_ss_value[0] = 262;
pSharpParamStatic->sharp_ss_value[1] = 375;
pSharpParamStatic->sharp_ss_value[2] = 431;
pSharpParamStatic->sharp_ss_value[3] = 395;
pSharpParamStatic->sharp_ss_value[4] = 316;
pSharpParamStatic->sharp_ss_value[5] = 250;
pSharpParamStatic->sharp_ss_value[6] = 206;
pSharpParamStatic->sharp_ss_value[7] = 179;
pSharpParamStatic->sharp_ss_value[8] = 158;
pSharpParamStatic->sharp_ss_value[9] = 132;
pSharpParamStatic->sharp_ss_value[10] = 107;
pSharpParamStatic->sharp_ss_value[11] = 91;
pSharpParamStatic->sharp_ss_value[12] = 79;
pSharpParamStatic->sharp_ss_value[13] = 67;
pSharpParamStatic->sharp_ss_value[14] = 56;
pSharpParamStatic->sharp_ss_value[15] = 50;
pSharpParamStatic->sharp_ss_value[16] = 39;
pSharpParamStatic->sharp_ss_value[17] = 19;
pSharpParamStatic->sharp_ss_value[18] = 0;
pSharpParamStatic->sharp_ss_value[19] = 0;
pSharpParamStatic->sharp_ss_value[20] = 0;
pSharpParamStatic->sharp_ss_value[21] = 1;
pSharpParamStatic->sharp_ss_value[22] = 0;
pSharpParamStatic->sharp_ss_value[23] = 0;
pSharpParamStatic->sharp_ss_value[24] = 0;
pSharpParamStatic->sharp_ss_value[25] = 0;
pSharpParamStatic->sharp_ss_value[26] = 0;
pSharpParamStatic->sharp_ss_value[27] = 0;
pSharpParamStatic->sharp_ss_value[28] = 0;
pSharpParamStatic->sharp_ss_value[29] = 0;
pSharpParamStatic->sharp_ss_value[30] = 0;
pSharpParamStatic->sharp_ss_value[31] = 0;
pSharpParamStatic->sharp_ss_value[32] = 0;
pSharpParamStatic->sharp_ls_value[0] = 341;
pSharpParamStatic->sharp_ls_value[1] = 489;
pSharpParamStatic->sharp_ls_value[2] = 564;
pSharpParamStatic->sharp_ls_value[3] = 515;
pSharpParamStatic->sharp_ls_value[4] = 395;
pSharpParamStatic->sharp_ls_value[5] = 254;
pSharpParamStatic->sharp_ls_value[6] = 90;
pSharpParamStatic->sharp_ls_value[7] = 56;
pSharpParamStatic->sharp_ls_value[8] = 54;
pSharpParamStatic->sharp_ls_value[9] = 52;
pSharpParamStatic->sharp_ls_value[10] = 51;
pSharpParamStatic->sharp_ls_value[11] = 48;
pSharpParamStatic->sharp_ls_value[12] = 42;
pSharpParamStatic->sharp_ls_value[13] = 36;
pSharpParamStatic->sharp_ls_value[14] = 31;
pSharpParamStatic->sharp_ls_value[15] = 28;
pSharpParamStatic->sharp_ls_value[16] = 23;
pSharpParamStatic->sharp_ls_value[17] = 11;
pSharpParamStatic->sharp_ls_value[18] = 0;
pSharpParamStatic->sharp_ls_value[19] = 0;
pSharpParamStatic->sharp_ls_value[20] = 0;
pSharpParamStatic->sharp_ls_value[21] = 1;
pSharpParamStatic->sharp_ls_value[22] = 0;
pSharpParamStatic->sharp_ls_value[23] = 0;
pSharpParamStatic->sharp_ls_value[24] = 0;
pSharpParamStatic->sharp_ls_value[25] = 0;
pSharpParamStatic->sharp_ls_value[26] = 0;
pSharpParamStatic->sharp_ls_value[27] = 0;
pSharpParamStatic->sharp_ls_value[28] = 0;
pSharpParamStatic->sharp_ls_value[29] = 0;
pSharpParamStatic->sharp_ls_value[30] = 0;
pSharpParamStatic->sharp_ls_value[31] = 0;
pSharpParamStatic->sharp_ls_value[32] = 0;
pSharpParamStatic->sharp_hsv[0] = 287;
pSharpParamStatic->sharp_hsv[1] = 286;
pSharpParamStatic->sharp_hsv[2] = 283;
pSharpParamStatic->sharp_hsv[3] = 276;
pSharpParamStatic->sharp_hsv[4] = 265;
pSharpParamStatic->sharp_hsv[5] = 256;
pSharpParamStatic->sharp_hsv[6] = 256;
pSharpParamStatic->sharp_hsv[7] = 269;
pSharpParamStatic->sharp_hsv[8] = 290;
pSharpParamStatic->sharp_hsv[9] = 314;
pSharpParamStatic->sharp_hsv[10] = 336;
pSharpParamStatic->sharp_hsv[11] = 361;
pSharpParamStatic->sharp_hsv[12] = 397;
pSharpParamStatic->sharp_hsv[13] = 446;
pSharpParamStatic->sharp_hsv[14] = 492;
pSharpParamStatic->sharp_hsv[15] = 514;
pSharpParamStatic->sharp_hsv[16] = 498;
pSharpParamStatic->sharp_hsv[17] = 457;
pSharpParamStatic->sharp_hsv[18] = 411;
pSharpParamStatic->sharp_hsv[19] = 376;
pSharpParamStatic->sharp_hsv[20] = 352;
pSharpParamStatic->sharp_hsv[21] = 336;
pSharpParamStatic->sharp_hsv[22] = 324;
pSharpParamStatic->sharp_hsv[23] = 315;
pSharpParamStatic->sharp_hsv[24] = 307;
pSharpParamStatic->sharp_hsv[25] = 299;
pSharpParamStatic->sharp_hsv[26] = 290;
pSharpParamStatic->sharp_hsv[27] = 281;
pSharpParamStatic->sharp_hsv[28] = 272;
pSharpParamStatic->sharp_hsv[29] = 261;
pSharpParamStatic->sharp_hsv[30] = 247;
pSharpParamStatic->sharp_hsv[31] = 230;
pSharpParamStatic->sharp_hsv[32] = 215;
pSharpParamStatic->sharp_hsv[33] = 209;
pSharpParamStatic->sharp_hsv[34] = 215;
pSharpParamStatic->sharp_hsv[35] = 229;
pSharpParamStatic->sharp_hsv[36] = 243;
pSharpParamStatic->sharp_hsv[37] = 252;
pSharpParamStatic->sharp_hsv[38] = 257;
pSharpParamStatic->sharp_hsv[39] = 258;
pSharpParamStatic->sharp_hsv[40] = 257;
pSharpParamStatic->sharp_hsv[41] = 256;
pSharpParamStatic->sharp_hsv[42] = 256;
pSharpParamStatic->sharp_hsv[43] = 260;
pSharpParamStatic->sharp_hsv[44] = 266;
pSharpParamStatic->sharp_hsv[45] = 289;
return 0;
}
#endif
static int venc_comp_event_handler(VideoEncoder *pEncoder, void *pAppData, VencEventType eEvent,
unsigned int nData1, unsigned int nData2, void *pEventData)
{
venc_comp_ctx *venc_comp = (venc_comp_ctx *)pAppData;
if (VencEvent_UpdateIspToVeParam == eEvent) {
int i = 0;
int vipp_id = venc_comp->base_config.channel_id;
int en_encpp = 0;
int final_en_encpp_sharp = 0;
int ae_env_lv, ae_weight_lum;
sIspAeStatus isp_ae_status;
sEncppSharpParam mSharpParam;
sEncppSharpParamDynamic dynamic_sharp;
sEncppSharpParamStatic static_sharp;
VencIsp2VeParam *isp2ve_param = (VencIsp2VeParam *)pEventData;
int encpp_sharp_atten_coef_per = venc_comp->base_config.encpp_sharp_atten_coef_per;
if (venc_comp->base_config.skip_sharp_param_frame_num <= 0) {
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_EN, &en_encpp);
RT_LOGI("vencoder:%p, codec_type:%d, en_encpp %d %d",
venc_comp->vencoder, venc_comp->base_config.codec_type, en_encpp,
venc_comp->base_config.en_encpp_sharp);
final_en_encpp_sharp = en_encpp && venc_comp->base_config.en_encpp_sharp;
if (venc_comp->actual_en_encpp_sharp != final_en_encpp_sharp) {
RT_LOGW("Be careful! vencoder:%p, codec_type:%d, en_encpp change:%d->%d(%d,%d)",
venc_comp->vencoder, venc_comp->base_config.codec_type,
venc_comp->actual_en_encpp_sharp, final_en_encpp_sharp,
en_encpp, venc_comp->base_config.en_encpp_sharp);
venc_comp->actual_en_encpp_sharp = final_en_encpp_sharp;
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableEncppSharp,
(void *)&venc_comp->actual_en_encpp_sharp);
}
if (venc_comp->actual_en_encpp_sharp) {
memset(&dynamic_sharp, 0, sizeof(sEncppSharpParamDynamic));
memset(&static_sharp, 0, sizeof(sEncppSharpParamStatic));
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_DYNAMIC_CFG, &dynamic_sharp);
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_STATIC_CFG, &static_sharp);
RT_LOGI("hfr_hf_wht_clp %d max_clp_ratio %d", dynamic_sharp.hfr_hf_wht_clp,
dynamic_sharp.max_clp_ratio);
RT_LOGI("ls_dir_ratio %d ss_dir_ratio %d", static_sharp.ls_dir_ratio,
static_sharp.ss_dir_ratio);
if (encpp_sharp_atten_coef_per) {
dynamic_sharp.ss_blk_stren = dynamic_sharp.ss_blk_stren * encpp_sharp_atten_coef_per / 100;
dynamic_sharp.ss_wht_stren = dynamic_sharp.ss_wht_stren * encpp_sharp_atten_coef_per / 100;
dynamic_sharp.ls_blk_stren = dynamic_sharp.ls_blk_stren * encpp_sharp_atten_coef_per / 100;
dynamic_sharp.ls_wht_stren = dynamic_sharp.ls_wht_stren * encpp_sharp_atten_coef_per / 100;
RT_LOGI("enable encpp sharp param stren decrease");
}
memcpy(&isp2ve_param->mSharpParam.mDynamicParam, &dynamic_sharp, sizeof(sEncppSharpParamDynamic));
memcpy(&isp2ve_param->mSharpParam.mStaticParam, &static_sharp, sizeof(sEncppSharpParamStatic));
}
} else {
venc_comp->base_config.skip_sharp_param_frame_num--;
RT_LOGI("skip set ve encpp sharp param");
}
if (!venc_comp->base_config.enable_ve_isp_linkage)
return 0;
memset(&isp_ae_status, 0, sizeof(isp_ae_status));
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_AE_STATS, isp_ae_status.avg);
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_AE_ENV_LV, &ae_env_lv);
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_AE_WEIGHT_LUM, &ae_weight_lum);
RT_LOGI("ve isp linkage EnvLv %d AeWeightLum %d CameraMoveStatus %d",
ae_env_lv, ae_weight_lum, venc_comp->camera_move_status);
memcpy(&isp2ve_param->mIspAeStatus, &isp_ae_status, sizeof(sIspAeStatus));
isp2ve_param->mEnvLv = ae_env_lv;
isp2ve_param->mAeWeightLum = ae_weight_lum;
isp2ve_param->mEnCameraMove = venc_comp->camera_move_status;
} else if (VencEvent_UpdateVeToIspParam == eEvent) {
if (!venc_comp->base_config.enable_ve_isp_linkage)
return 0;
VencVe2IspParam *s_ve2isp_param = (VencVe2IspParam *)pEventData;
RTIspCfgAttrData rt_isp_cfg;
RT_LOGI("d2d_level %d %d", s_ve2isp_param->d2d_level, s_ve2isp_param->d3d_level);
memset(&rt_isp_cfg, 0, sizeof(RTIspCfgAttrData));
//set 2d param
/*rt_isp_cfg.cfg_id = RT_ISP_CTRL_DN_STR;
rt_isp_cfg.denoise_level = s_ve2isp_param->d2d_level;
vin_set_isp_attr_cfg_special(venc_comp->base_config.channel_id, &rt_isp_cfg);*/
//set 3d param
/*rt_isp_cfg.cfg_id = RT_ISP_CTRL_3DN_STR;
rt_isp_cfg.tdf_level = s_ve2isp_param->d3d_level;
vin_set_isp_attr_cfg_special(venc_comp->base_config.channel_id, &rt_isp_cfg);*/
rt_isp_cfg.cfg_id = RT_ISP_CTRL_VENC2ISP_PARAM;
memcpy(&rt_isp_cfg.VencVe2IspParam, s_ve2isp_param, sizeof(VencVe2IspParam));
vin_set_isp_attr_cfg_special(venc_comp->base_config.channel_id, &rt_isp_cfg);
}
return 0;
}
static int setup_vbv_buffer_size(venc_comp_ctx *venc_comp)
{
unsigned int vbv_size = venc_comp->base_config.vbv_buf_size;
int min_size;
unsigned int thresh_size = venc_comp->base_config.vbv_thresh_size;
unsigned int bit_rate = venc_comp->base_config.bit_rate;
min_size = venc_comp->base_config.dst_width * venc_comp->base_config.dst_height * 3 / 2;
RT_LOGD("vbv_size %d %d", vbv_size, thresh_size);
if (!vbv_size || !thresh_size) {
if (bit_rate) {
thresh_size = bit_rate / 8 / venc_comp->base_config.frame_rate * 15;
} else {
thresh_size = venc_comp->base_config.dst_width * venc_comp->base_config.dst_height;
}
if (thresh_size > 7 * 1024 * 1024) {
RT_LOGW("Be careful! threshSize[%d]bytes too large, reduce to 7MB", thresh_size);
thresh_size = 7 * 1024 * 1024;
}
if (bit_rate > 0) {
vbv_size = bit_rate / 8 * DEBUG_VBV_CACHE_TIME + thresh_size;
} else {
vbv_size = min_size;
}
}
vbv_size = RT_ALIGN(vbv_size, 1024);
if (vbv_size <= thresh_size) {
RT_LOGE("fatal error! vbv_size[%d] <= thresh_size[%d]", vbv_size, thresh_size);
}
if (vbv_size > 12 * 1024 * 1024) {
RT_LOGE("Be careful! vbv_size[%d] too large, exceed 24M byte", vbv_size);
vbv_size = 12 * 1024 * 1024;
}
RT_LOGD("bit rate is %d bytes, set encode vbv size %d, frame length threshold %d, minSize = %d",
bit_rate, vbv_size, thresh_size, min_size);
if (venc_comp->base_config.dst_width >= 3840) {
vbv_size = 2 * 1024 * 1024;
thresh_size = 1 * 1024 * 1024;
RT_LOGW("the size is too large[%d x %d], so we reset vbv size and thresh_size to: %d, %d",
venc_comp->base_config.dst_width, venc_comp->base_config.dst_height,
vbv_size, thresh_size);
}
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetVbvSize, &vbv_size);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetFrameLenThreshold, &thresh_size);
UNLOCK_MUTEX(&venc_mutex);
return 0;
}
static int vencoder_create(venc_comp_ctx *venc_comp)
{
int ret = 0;
VENC_CODEC_TYPE type = VENC_CODEC_H264;
/* map codec type */
switch (venc_comp->base_config.codec_type) {
case RT_VENC_CODEC_H264: {
type = VENC_CODEC_H264;
break;
}
case RT_VENC_CODEC_H265: {
type = VENC_CODEC_H265;
break;
}
case RT_VENC_CODEC_JPEG: {
type = VENC_CODEC_JPEG;
break;
}
default: {
RT_LOGE("nor support codec type: %d", venc_comp->base_config.codec_type);
return ERROR_TYPE_ILLEGAL_PARAM;
break;
}
}
LOCK_MUTEX(&venc_mutex);
venc_comp->vencoder = VencCreate(type);
if (venc_comp->vencoder) {
if (RT_VENC_CODEC_H264 == type || RT_VENC_CODEC_H265 == type) {
if (PRODUCT_NUM <= venc_comp->base_config.product_mode ||
0 == venc_comp->base_config.bit_rate || 0 == venc_comp->base_config.frame_rate ||
0 == venc_comp->base_config.dst_width || 0 == venc_comp->base_config.dst_height) {
RT_LOGW("fatal error! channel[%d] invalid params, product_mode=%d, bitrate=%d, frame_rate=%d, dst_wxh=%dx%d",
venc_comp->base_config.channel_id, venc_comp->base_config.product_mode, venc_comp->base_config.bit_rate,
venc_comp->base_config.frame_rate, venc_comp->base_config.dst_width, venc_comp->base_config.dst_height);
UNLOCK_MUTEX(&venc_mutex);
return ERROR_TYPE_ILLEGAL_PARAM;
}
VencProductModeInfo ProductInfo;
memset(&ProductInfo, 0, sizeof(VencProductModeInfo));
ProductInfo.eProductMode = venc_comp->base_config.product_mode;
ProductInfo.nBitrate = venc_comp->base_config.bit_rate;
ProductInfo.nFrameRate = venc_comp->base_config.frame_rate;
ProductInfo.nDstWidth = venc_comp->base_config.dst_width;
ProductInfo.nDstHeight = venc_comp->base_config.dst_height;
ret = VencSetParameter(venc_comp->vencoder, VENC_IndexParamProductCase, (void *)&ProductInfo);
if (ret)
RT_LOGE("fatal error! channel[%d] set ProductCase failed, ret=%d", venc_comp->base_config.channel_id, ret);
}
}
UNLOCK_MUTEX(&venc_mutex);
return ret;
}
static int vencoder_init(venc_comp_ctx *venc_comp)
{
VencBaseConfig base_config;
int en_encpp = 0;
int vipp_id = venc_comp->base_config.channel_id;
memset(&base_config, 0, sizeof(VencBaseConfig));
base_config.bOnlineMode = 1; //venc_comp->base_config.bOnlineMode;
base_config.bOnlineChannel = venc_comp->base_config.bOnlineChannel;
base_config.nOnlineShareBufNum = venc_comp->base_config.share_buf_num;
base_config.bEncH264Nalu = 0;
base_config.nInputWidth = venc_comp->base_config.src_width;
base_config.nInputHeight = venc_comp->base_config.src_height;
base_config.nDstWidth = venc_comp->base_config.dst_width;
base_config.nDstHeight = venc_comp->base_config.dst_height;
base_config.nStride = RT_ALIGN(base_config.nInputWidth, 16);
base_config.eInputFormat = venc_comp->base_config.pixelformat;
base_config.eOutputFormat = venc_comp->base_config.outputformat;
base_config.bOnlyWbFlag = 0;
base_config.memops = NULL;
base_config.veOpsS = NULL;
base_config.bLbcLossyComEnFlag2x = 0;
base_config.bLbcLossyComEnFlag2_5x = 0;
base_config.bIsVbvNoCache = 1;
base_config.channel_id = venc_comp->base_config.channel_id;
if (venc_comp->base_config.pixelformat == RT_PIXEL_LBC_25X) {
base_config.eInputFormat = VENC_PIXEL_LBC_AW;
base_config.bLbcLossyComEnFlag2_5x = 1;
} else if (venc_comp->base_config.pixelformat == RT_PIXEL_LBC_2X) {
base_config.eInputFormat = VENC_PIXEL_LBC_AW;
base_config.bLbcLossyComEnFlag2x = 1;
}
RT_LOGW("channel_id %d bOnlineChannel %d input format = %d, 2_5x_flag = %d, enable_ve_isp_linkage = %d",
venc_comp->base_config.channel_id, base_config.bOnlineChannel, base_config.eInputFormat,
base_config.bLbcLossyComEnFlag2_5x, venc_comp->base_config.enable_ve_isp_linkage);
vin_get_encpp_cfg(vipp_id, RT_CTRL_ENCPP_EN, &en_encpp);
RT_LOGW("vencoder:%p, codec_type:%d, en_encpp %d %d", venc_comp->vencoder, venc_comp->base_config.codec_type, en_encpp, venc_comp->base_config.en_encpp_sharp);
venc_comp->actual_en_encpp_sharp = en_encpp && venc_comp->base_config.en_encpp_sharp;
RT_LOGD("vencoder:%p skip_sharp_param_frame_num %d encpp_sharp_atten_coef_per %d",
venc_comp->vencoder, venc_comp->base_config.skip_sharp_param_frame_num, venc_comp->base_config.encpp_sharp_atten_coef_per);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableEncppSharp, (void *)&venc_comp->actual_en_encpp_sharp);
/*int64_t time_start = get_cur_time();*/
LOCK_MUTEX(&venc_mutex);
VencInit(venc_comp->vencoder, &base_config);
UNLOCK_MUTEX(&venc_mutex);
if (venc_comp->base_config.s_wbyuv_param.bEnableWbYuv) {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableWbYuv, &venc_comp->base_config.s_wbyuv_param);
UNLOCK_MUTEX(&venc_mutex);
}
/*
int64_t time_end = get_cur_time();
RT_LOGD("time of VideoEncInit: %lld",(time_end - time_start));
*/
RT_LOGD("VencInit finish");
#if TEST_ENCODER_BY_SELF
VencAllocateBufferParam bufferParam;
memset(&bufferParam, 0, sizeof(VencAllocateBufferParam));
bufferParam.nSizeY = base_config.nInputWidth * base_config.nInputHeight;
bufferParam.nSizeC = base_config.nInputWidth * base_config.nInputHeight / 2;
bufferParam.nBufferNum = 1;
AllocInputBuffer(venc_comp->vencoder, &bufferParam);
#endif
return 0;
}
static VENC_H264PROFILETYPE match_h264_profile(int src_profile)
{
VENC_H264PROFILETYPE h264_profile = VENC_H264ProfileHigh;
switch (src_profile) {
case AW_Video_H264ProfileBaseline:
case AW_Video_H264ProfileMain:
case AW_Video_H264ProfileHigh:
h264_profile = src_profile;
break;
default: {
RT_LOGW("can not match the h264 profile: %d, use defaut: %d", src_profile, h264_profile);
break;
}
}
return h264_profile;
}
static VENC_H264LEVELTYPE match_h264_level(int src_level)
{
VENC_H264LEVELTYPE h264_level = VENC_H264Level51;
switch (src_level) {
case AW_Video_H264Level1:
case AW_Video_H264Level11:
case AW_Video_H264Level12:
case AW_Video_H264Level13:
case AW_Video_H264Level2:
case AW_Video_H264Level21:
case AW_Video_H264Level22:
case AW_Video_H264Level3:
case AW_Video_H264Level31:
case AW_Video_H264Level32:
case AW_Video_H264Level4:
case AW_Video_H264Level41:
case AW_Video_H264Level42:
case AW_Video_H264Level5:
case AW_Video_H264Level51:
h264_level = src_level;
break;
default: {
RT_LOGW("can not match the h264 level: %d, defaut: %d", src_level, h264_level);
break;
}
}
return h264_level;
}
static VENC_H265PROFILETYPE match_h265_profile(int src_profile)
{
VENC_H265PROFILETYPE h265_profile = VENC_H265ProfileMain;
switch (src_profile) {
case AW_Video_H265ProfileMain:
case AW_Video_H265ProfileMain10:
case AW_Video_H265ProfileMainStill:
h265_profile = src_profile;
break;
default: {
RT_LOGW("can not match the h265 profile: %d, defaut: %d", src_profile, h265_profile);
break;
}
}
return h265_profile;
}
static VENC_H265LEVELTYPE match_h265_level(int src_level)
{
VENC_H265LEVELTYPE h265_level = VENC_H265Level51;
switch (src_level) {
case AW_Video_H265Level1:
case AW_Video_H265Level2:
case AW_Video_H265Level21:
case AW_Video_H265Level3:
case AW_Video_H265Level31:
case AW_Video_H265Level41:
case AW_Video_H265Level5:
case AW_Video_H265Level51:
case AW_Video_H265Level52:
case AW_Video_H265Level6:
case AW_Video_H265Level61:
case AW_Video_H265Level62:
h265_level = src_level;
break;
default: {
RT_LOGW("can not match the h265 level: %d, defaut: %d", src_level, h265_level);
break;
}
}
return h265_level;
}
static int set_param_h264(venc_comp_ctx *venc_comp)
{
VencH264VideoTiming video_time;
VencH264Param param_h264;
memset(&param_h264, 0, sizeof(VencH264Param));
param_h264.sProfileLevel.nProfile = match_h264_profile(venc_comp->base_config.profile);
param_h264.sProfileLevel.nLevel = match_h264_level(venc_comp->base_config.level);
param_h264.bEntropyCodingCABAC = 1;
param_h264.sQPRange.nMinqp = venc_comp->base_config.qp_range.i_min_qp;
param_h264.sQPRange.nMaxqp = venc_comp->base_config.qp_range.i_max_qp;
param_h264.sQPRange.nMinPqp = venc_comp->base_config.qp_range.p_min_qp;
param_h264.sQPRange.nMaxPqp = venc_comp->base_config.qp_range.p_max_qp;
param_h264.sQPRange.nQpInit = venc_comp->base_config.qp_range.i_init_qp;
param_h264.sQPRange.bEnMbQpLimit = venc_comp->base_config.qp_range.enable_mb_qp_limit;
param_h264.nFramerate = venc_comp->base_config.frame_rate;
param_h264.nSrcFramerate = venc_comp->base_config.frame_rate;
param_h264.nBitrate = venc_comp->base_config.bit_rate;
param_h264.nMaxKeyInterval = venc_comp->base_config.max_keyframe_interval;
param_h264.nCodingMode = VENC_FRAME_CODING;
param_h264.sGopParam.bUseGopCtrlEn = 1;
param_h264.sGopParam.eGopMode = AW_NORMALP;
param_h264.breduce_refrecmem = venc_comp->base_config.breduce_refrecmem;
if (venc_comp->base_config.rc_mode == VENC_COMP_RC_MODE_CBR)
param_h264.sRcParam.eRcMode = AW_CBR;
else if (venc_comp->base_config.rc_mode == VENC_COMP_RC_MODE_VBR) {
param_h264.sRcParam.eRcMode = AW_VBR;
param_h264.sRcParam.sVbrParam.uMaxBitRate = venc_comp->base_config.vbr_param.uMaxBitRate;
param_h264.sRcParam.sVbrParam.nMovingTh = venc_comp->base_config.vbr_param.nMovingTh;
param_h264.sRcParam.sVbrParam.nQuality = venc_comp->base_config.vbr_param.nQuality;
param_h264.sRcParam.sVbrParam.nIFrmBitsCoef = venc_comp->base_config.vbr_param.nIFrmBitsCoef;
param_h264.sRcParam.sVbrParam.nPFrmBitsCoef = venc_comp->base_config.vbr_param.nPFrmBitsCoef;
} else {
RT_LOGW("not support the rc_mode: %d", venc_comp->base_config.rc_mode);
}
RT_LOGI("h264 param: profile = %d, level = %d, min_qp = %d, max_qp = %d",
param_h264.sProfileLevel.nProfile,
param_h264.sProfileLevel.nLevel,
param_h264.sQPRange.nMinqp,
param_h264.sQPRange.nMaxqp);
memset(&video_time, 0, sizeof(VencH264VideoTiming));
video_time.num_units_in_tick = 1;
video_time.time_scale = 32;
video_time.fixed_frame_rate_flag = 1;
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264Param, &param_h264);
//VideoEncSetParameter(venc_comp->vencoder, VENC_IndexParamH264VideoTiming, &video_time);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264VideoSignal, &venc_comp->base_config.venc_video_signal);
UNLOCK_MUTEX(&venc_mutex);
return 0;
}
static int set_param_h265(venc_comp_ctx *venc_comp)
{
VencH265Param h265Param;
memset(&h265Param, 0, sizeof(VencH265Param));
h265Param.sGopParam.bUseGopCtrlEn = 1;
h265Param.sGopParam.eGopMode = AW_NORMALP;
h265Param.nBitrate = venc_comp->base_config.bit_rate;
h265Param.nFramerate = venc_comp->base_config.frame_rate;
h265Param.nQPInit = 35;
h265Param.idr_period = venc_comp->base_config.max_keyframe_interval;
h265Param.nGopSize = h265Param.idr_period;
h265Param.nIntraPeriod = h265Param.idr_period;
h265Param.sProfileLevel.nProfile = match_h265_profile(venc_comp->base_config.profile);
h265Param.sProfileLevel.nLevel = match_h265_level(venc_comp->base_config.level);
h265Param.sQPRange.nMinqp = venc_comp->base_config.qp_range.i_min_qp;
h265Param.sQPRange.nMaxqp = venc_comp->base_config.qp_range.i_max_qp;
h265Param.sQPRange.nMinPqp = venc_comp->base_config.qp_range.p_min_qp;
h265Param.sQPRange.nMaxPqp = venc_comp->base_config.qp_range.p_max_qp;
h265Param.sQPRange.nQpInit = venc_comp->base_config.qp_range.i_init_qp;
h265Param.sQPRange.bEnMbQpLimit = venc_comp->base_config.qp_range.enable_mb_qp_limit;
h265Param.breduce_refrecmem = venc_comp->base_config.breduce_refrecmem;
if (venc_comp->base_config.rc_mode == VENC_COMP_RC_MODE_CBR)
h265Param.sRcParam.eRcMode = AW_CBR;
else if (venc_comp->base_config.rc_mode == VENC_COMP_RC_MODE_VBR) {
h265Param.sRcParam.eRcMode = AW_VBR;
h265Param.sRcParam.sVbrParam.uMaxBitRate = venc_comp->base_config.vbr_param.uMaxBitRate;
h265Param.sRcParam.sVbrParam.nMovingTh = venc_comp->base_config.vbr_param.nMovingTh;
h265Param.sRcParam.sVbrParam.nQuality = venc_comp->base_config.vbr_param.nQuality;
h265Param.sRcParam.sVbrParam.nIFrmBitsCoef = venc_comp->base_config.vbr_param.nIFrmBitsCoef;
h265Param.sRcParam.sVbrParam.nPFrmBitsCoef = venc_comp->base_config.vbr_param.nPFrmBitsCoef;
} else {
RT_LOGW("not support the rc_mode: %d", venc_comp->base_config.rc_mode);
}
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH265Param, &h265Param);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamVUIVideoSignal, &venc_comp->base_config.venc_video_signal);
UNLOCK_MUTEX(&venc_mutex);
return 0;
}
static int set_param_jpeg(venc_comp_ctx *venc_comp)
{
VencJpegVideoSignal sVideoSignal;
int rotate_angle = venc_comp->base_config.rotate_angle;
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamJpegEncMode, &venc_comp->base_config.jpg_mode);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamJpegQuality,
&venc_comp->base_config.quality);
if (venc_comp->base_config.jpg_mode) {//mjpg
VencSetParameter(venc_comp->vencoder, VENC_IndexParamBitrate, &venc_comp->base_config.bit_rate);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamFramerate, &venc_comp->base_config.frame_rate);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetBitRateRange, &venc_comp->base_config.bit_rate_range);
}
memset(&sVideoSignal, 0, sizeof(VencJpegVideoSignal));
sVideoSignal.src_colour_primaries = venc_comp->base_config.venc_video_signal.src_colour_primaries;
sVideoSignal.dst_colour_primaries = venc_comp->base_config.venc_video_signal.dst_colour_primaries;
RT_LOGD("src_colour_primaries %d %d", sVideoSignal.src_colour_primaries, sVideoSignal.dst_colour_primaries);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamJpegVideoSignal, &sVideoSignal);
if (rotate_angle == 90 || rotate_angle == 180 || rotate_angle == 270) {
VencSetParameter(venc_comp->vencoder, VENC_IndexParamRotation, &rotate_angle);
}
RT_LOGI("jpg param %d %d %d %d %d %d", venc_comp->base_config.jpg_mode, venc_comp->base_config.quality, venc_comp->base_config.frame_rate,
venc_comp->base_config.bit_rate, venc_comp->base_config.bit_rate_range.bitRateMin,
venc_comp->base_config.bit_rate_range.bitRateMax);
UNLOCK_MUTEX(&venc_mutex);
return 0;
}
static void check_qp_value(video_qp_range *qp_range)
{
int min_qp = qp_range->i_min_qp;
int max_qp = qp_range->i_max_qp;
if (!(min_qp >= 1 && min_qp <= 51)) {
min_qp = 25;
}
if (!(max_qp >= min_qp && max_qp >= 1 && max_qp <= 51)) {
max_qp = 45;
}
qp_range->i_min_qp = min_qp;
qp_range->i_max_qp = max_qp;
min_qp = qp_range->p_min_qp;
max_qp = qp_range->p_max_qp;
if (!(min_qp >= 1 && min_qp <= 51)) {
min_qp = 25;
}
if (!(max_qp >= min_qp && max_qp >= 1 && max_qp <= 51)) {
max_qp = 45;
}
qp_range->p_min_qp = min_qp;
qp_range->p_max_qp = max_qp;
if (qp_range->i_init_qp <= 0 || qp_range->i_init_qp > 51)
qp_range->i_init_qp = 35;
}
static int vencoder_set_param(venc_comp_ctx *venc_comp)
{
// file g2d_file;
check_qp_value(&venc_comp->base_config.qp_range);
RT_LOGI("i_qp = %d~%d, p_qp = %d~%d",
venc_comp->base_config.qp_range.i_min_qp, venc_comp->base_config.qp_range.i_max_qp,
venc_comp->base_config.qp_range.p_min_qp, venc_comp->base_config.qp_range.p_max_qp);
if (venc_comp->base_config.codec_type == RT_VENC_CODEC_H264)
set_param_h264(venc_comp);
else if (venc_comp->base_config.codec_type == RT_VENC_CODEC_H265)
set_param_h265(venc_comp);
else if (venc_comp->base_config.codec_type == RT_VENC_CODEC_JPEG)
set_param_jpeg(venc_comp);
#if defined(CONFIG_DEBUG_FS)
VeProcSet sVeProcInfo;
int channel_id = 0;
memset(&sVeProcInfo, 0, sizeof(VeProcSet));
sVeProcInfo.bProcEnable = 1;
sVeProcInfo.nProcFreq = 10;
channel_id = venc_comp->base_config.channel_id;
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamChannelNum, &channel_id);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamProcSet, &sVeProcInfo);
UNLOCK_MUTEX(&venc_mutex);
#endif
setup_vbv_buffer_size(venc_comp);
if (venc_comp->vencoder_init_flag == 0) {
vencoder_init(venc_comp);
venc_comp->vencoder_init_flag = 1;
}
#if ENABLE_SAVE_NATIVE_OVERLAY_DATA
RT_LOGW("enable_overlay = %d", venc_comp->base_config.enable_overlay);
if (venc_comp->base_config.enable_overlay == 1) {
if (adjust_native_overlay_info(venc_comp) == 0) {
LOCK_MUTEX(&venc_mutex);
g2d_open(0, &g2d_file);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetOverlay, &global_osd_info->sOverlayInfo);
g2d_release(0, &g2d_file);
UNLOCK_MUTEX(&venc_mutex);
}
}
#endif
return 0;
}
static int commond_process(struct venc_comp_ctx *venc_comp, message_t *msg)
{
int cmd_error = 0;
int cmd = msg->command;
wait_queue_head_t *wait_reply = (wait_queue_head_t *)msg->wait_queue;
unsigned int *wait_condition = (unsigned int *)msg->wait_condition;
RT_LOGI("cmd process: cmd = %d, state = %d, wait_reply = %p, wait_condition = %p",
cmd, venc_comp->state, wait_reply, wait_condition);
if (cmd == COMP_COMMAND_INIT) {
if (venc_comp->state != COMP_STATE_IDLE) {
cmd_error = 1;
} else {
vencoder_create(venc_comp);
venc_comp->state = COMP_STATE_INITIALIZED;
}
} else if (cmd == COMP_COMMAND_START) {
if (venc_comp->state != COMP_STATE_INITIALIZED && venc_comp->state != COMP_STATE_PAUSE) {
cmd_error = 1;
} else {
venc_comp->state = COMP_STATE_EXECUTING;
}
} else if (cmd == COMP_COMMAND_PAUSE) {
venc_comp->state = COMP_STATE_PAUSE;
} else if (cmd == COMP_COMMAND_STOP) {
if ((COMP_STATE_EXECUTING == venc_comp->state) || (COMP_STATE_PAUSE == venc_comp->state)) {
mutex_lock(&venc_comp->in_buf_manager.mutex);
if (!list_empty(&venc_comp->in_buf_manager.using_frame_list)) {
int cnt = 0; struct list_head *pList; list_for_each(pList, &venc_comp->in_buf_manager.using_frame_list) { cnt++; }
RT_LOGW("Be careful! vencChn[%d] stop, but need wait [%d] frames sent to venclib return!", venc_comp->base_config.channel_id, cnt);
}
if (!list_empty(&venc_comp->in_buf_manager.valid_frame_list)) {
int cnt = 0; struct list_head *pList; list_for_each(pList, &venc_comp->in_buf_manager.valid_frame_list) { cnt++; }
RT_LOGW("Be careful! vencChn[%d] stop, but need release [%d] frames in valid_frame_list!", venc_comp->base_config.channel_id, cnt);
}
mutex_unlock(&venc_comp->in_buf_manager.mutex);
venc_comp->state = COMP_STATE_IDLE;
} else {
RT_LOGW("Be careful! rt_venc_comp state[%d]->idle.", venc_comp->state);
venc_comp->state = COMP_STATE_IDLE;
}
} else if (cmd == COMP_COMMAND_VENC_DROP_FRAME) {
if (venc_comp->mActiveDropNum != 0) {
RT_LOGW("Be careful! activeDropNum[%d] still != 0, increase %d frames again!", venc_comp->mActiveDropNum, msg->para0);
}
venc_comp->mActiveDropNum += msg->para0;
}
if (cmd_error == 1) {
venc_comp->callback->EventHandler(
venc_comp->self_comp,
venc_comp->callback_data,
COMP_EVENT_CMD_ERROR,
COMP_COMMAND_INIT,
0,
NULL);
} else {
venc_comp->callback->EventHandler(
venc_comp->self_comp,
venc_comp->callback_data,
COMP_EVENT_CMD_COMPLETE,
cmd,
0,
NULL);
}
if (wait_reply) {
RT_LOGD("wait up: cmd = %d, state = %d", cmd, venc_comp->state);
*wait_condition = 1;
wake_up(wait_reply);
}
return 0;
}
/* the input buffer had been used, return it*/
/* valid_list --> empty_list */
static int venc_empty_in_buffer_done(void *venc_comp,
void *frame_info)
{
struct venc_comp_ctx *pvenc_comp = (struct venc_comp_ctx *)venc_comp;
video_frame_s *pframe_info = (video_frame_s *)frame_info;
comp_buffer_header_type buffer_header;
memset(&buffer_header, 0, sizeof(comp_buffer_header_type));
buffer_header.private = pframe_info;
if (pvenc_comp->in_port_tunnel_info.valid_flag == 0) {
pvenc_comp->callback->empty_in_buffer_done(
pvenc_comp->self_comp,
pvenc_comp->callback_data,
&buffer_header);
} else {
comp_fill_this_out_buffer(pvenc_comp->in_port_tunnel_info.tunnel_comp, &buffer_header);
}
RT_LOGI("venc_comp %p channel id %d release input FrameId[%d]", venc_comp, pvenc_comp->base_config.channel_id, pframe_info->id);
return ERROR_TYPE_OK;
}
static int VencCompInputBufferDone(VideoEncoder *pEncoder, void *pAppData,
VencCbInputBufferDoneInfo *pBufferDoneInfo)
{
struct venc_comp_ctx *pvenc_comp = NULL;
VencInputBuffer *pInputBuffer = NULL;
struct vin_buffer *vin_buf = NULL;
rt_component_type *pcomp_type = NULL;
video_frame_s mvideo_stream;
int ret = ERROR_TYPE_OK;
if (pAppData == NULL || pBufferDoneInfo == NULL) {
RT_LOGE("parama is null");
return ERROR_TYPE_ERROR;
}
pvenc_comp = (struct venc_comp_ctx *)pAppData;
pInputBuffer = pBufferDoneInfo->pInputBuffer;
mutex_lock(&pvenc_comp->in_buf_manager.mutex);
if (!list_empty(&pvenc_comp->in_buf_manager.using_frame_list)) {
video_frame_node *pFrameNode = list_first_entry(&pvenc_comp->in_buf_manager.using_frame_list, video_frame_node, mList);
if (pInputBuffer->nID != pFrameNode->video_frame.id) {
RT_LOGE("fatal error! rtVencChn[%d] input buf ID is NOT match[%ld!=%d]", pvenc_comp->base_config.channel_id, pInputBuffer->nID, pFrameNode->video_frame.id);
}
mutex_unlock(&pvenc_comp->in_buf_manager.mutex);
ret = venc_empty_in_buffer_done(pvenc_comp, &pFrameNode->video_frame);
//static int sBufferCnt = 0; sBufferCnt++; if(sBufferCnt%40 == 0) {
if (pBufferDoneInfo->nResult != VENC_RESULT_OK) {
static int stream_full_cnt;
if (pBufferDoneInfo->nResult != VENC_RESULT_BITSTREAM_IS_FULL)
RT_LOGE("Be careful! vencChn[%d] encode fail:%d", pvenc_comp->base_config.channel_id, pBufferDoneInfo->nResult);
if (pBufferDoneInfo->nResult == VENC_RESULT_BITSTREAM_IS_FULL) {
stream_full_cnt++;
if (stream_full_cnt % 500 == 0)
RT_LOGW("ch %d bit stream is full 500 cnt, please check! toal cnt %d", pvenc_comp->base_config.channel_id, stream_full_cnt);
}
pvenc_comp->callback->EventHandler(
pvenc_comp->self_comp,
pvenc_comp->callback_data,
COMP_EVENT_VENC_DROP_FRAME,
0,
0,
NULL);
}
mutex_lock(&pvenc_comp->in_buf_manager.mutex);
list_move_tail(&pFrameNode->mList, &pvenc_comp->in_buf_manager.empty_frame_list);
pvenc_comp->in_buf_manager.empty_num++;
}
mutex_unlock(&pvenc_comp->in_buf_manager.mutex);
return ret;
}
/* empty_list --> valid_list */
static int venc_fill_out_buffer_done(struct venc_comp_ctx *venc_comp,
VencOutputBuffer *out_buffer)
{
video_stream_node *stream_node = NULL;
error_type error = ERROR_TYPE_OK;
comp_buffer_header_type buffer_header;
video_stream_s mvideo_stream;
memset(&mvideo_stream, 0, sizeof(video_stream_s));
memset(&buffer_header, 0, sizeof(comp_buffer_header_type));
mutex_lock(&venc_comp->out_buf_manager.mutex);
stream_node = list_first_entry(&venc_comp->out_buf_manager.empty_stream_list, video_stream_node, mList);
config_videostream_by_VencOutputBuffer(venc_comp, out_buffer, &stream_node->video_stream);
memcpy(&mvideo_stream, &stream_node->video_stream, sizeof(video_stream_s));
venc_comp->out_buf_manager.empty_num--;
list_move_tail(&stream_node->mList, &venc_comp->out_buf_manager.valid_stream_list);
mutex_unlock(&venc_comp->out_buf_manager.mutex);
buffer_header.private = &mvideo_stream;
if (venc_comp->out_port_tunnel_info.valid_flag == 0) {
venc_comp->callback->fill_out_buffer_done(
venc_comp->self_comp,
venc_comp->callback_data,
&buffer_header);
} else {
comp_empty_this_in_buffer(venc_comp->out_port_tunnel_info.tunnel_comp, &buffer_header);
}
RT_LOGD(" id = %d", mvideo_stream.id);
return error;
}
#if NEI_TEST_CODE
static void init_jpeg_exif(EXIFInfo *exifinfo)
{
exifinfo->ThumbWidth = 640;
exifinfo->ThumbHeight = 480;
strcpy((char *)exifinfo->CameraMake, "allwinner make test");
strcpy((char *)exifinfo->CameraModel, "allwinner model test");
strcpy((char *)exifinfo->DateTime, "2014:02:21 10:54:05");
strcpy((char *)exifinfo->gpsProcessingMethod, "allwinner gps");
exifinfo->Orientation = 0;
exifinfo->ExposureTime.num = 2;
exifinfo->ExposureTime.den = 1000;
exifinfo->FNumber.num = 20;
exifinfo->FNumber.den = 10;
exifinfo->ISOSpeed = 50;
exifinfo->ExposureBiasValue.num = -4;
exifinfo->ExposureBiasValue.den = 1;
exifinfo->MeteringMode = 1;
exifinfo->FlashUsed = 0;
exifinfo->FocalLength.num = 1400;
exifinfo->FocalLength.den = 100;
exifinfo->DigitalZoomRatio.num = 4;
exifinfo->DigitalZoomRatio.den = 1;
exifinfo->WhiteBalance = 1;
exifinfo->ExposureMode = 1;
exifinfo->enableGpsInfo = 1;
exifinfo->gps_latitude = 23.2368;
exifinfo->gps_longitude = 24.3244;
exifinfo->gps_altitude = 1234.5;
exifinfo->gps_timestamp = 0;
strcpy((char *)exifinfo->CameraSerialNum, "123456789");
strcpy((char *)exifinfo->ImageName, "exif-name-test");
strcpy((char *)exifinfo->ImageDescription, "exif-descriptor-test");
}
#endif
static int catch_jpeg_encoder(venc_comp_ctx *venc_comp, VencInputBuffer *in_buf)
{
catch_jpeg_cxt *jpeg_cxt = &venc_comp->jpeg_cxt;
int result = 0;
result = VencQueueInputBuf(jpeg_cxt->vencoder, in_buf);
if (result != 0) {
RT_LOGE("fatal error! VencQueueInputBuf fail[%d]", result);
}
LOCK_MUTEX(&venc_mutex);
result = encodeOneFrame(jpeg_cxt->vencoder);
UNLOCK_MUTEX(&venc_mutex);
RT_LOGI("encoder result = %d", result);
jpeg_cxt->wait_enc_finish_condition = 1;
wake_up(&jpeg_cxt->wait_enc_finish);
jpeg_cxt->encoder_finish_flag = 1;
return 0;
}
static int catch_jpeg_start(venc_comp_ctx *venc_comp, catch_jpeg_config *jpeg_config)
{
catch_jpeg_cxt *jpeg_cxt = &venc_comp->jpeg_cxt;
VENC_CODEC_TYPE type = VENC_CODEC_JPEG;
VencBaseConfig base_config;
unsigned int vbv_size = jpeg_config->width * jpeg_config->height / 2;
unsigned int quality = jpeg_config->qp;
jpeg_cxt->width = jpeg_config->width;
jpeg_cxt->height = jpeg_config->height;
jpeg_cxt->qp = jpeg_config->qp;
LOCK_MUTEX(&venc_mutex);
jpeg_cxt->vencoder = VencCreate(type);
UNLOCK_MUTEX(&venc_mutex);
if (!jpeg_cxt->vencoder) {
RT_LOGE("create vencoder failed");
return -1;
}
/* setup exif */
#if NEI_TEST_CODE
EXIFInfo exif_info;
memset(&exif_info, 0, sizeof(EXIFInfo));
init_jpeg_exif(&exif_info);
VencSetParameter(jpeg_cxt->vencoder, VENC_IndexParamJpegExifInfo, &exif_info);
#endif
VencSetParameter(jpeg_cxt->vencoder, VENC_IndexParamSetVbvSize, &vbv_size);
VencSetParameter(jpeg_cxt->vencoder, VENC_IndexParamJpegQuality, &quality);
memset(&base_config, 0, sizeof(VencBaseConfig));
base_config.bEncH264Nalu = 0;
base_config.nInputWidth = venc_comp->base_config.src_width;
base_config.nInputHeight = venc_comp->base_config.src_height;
base_config.nDstWidth = jpeg_cxt->width;
base_config.nDstHeight = jpeg_cxt->height;
base_config.nStride = RT_ALIGN(base_config.nInputWidth, 16);
base_config.eInputFormat = venc_comp->base_config.pixelformat;
base_config.eOutputFormat = venc_comp->base_config.outputformat;
base_config.bOnlyWbFlag = 0;
base_config.memops = NULL;
base_config.veOpsS = NULL;
base_config.bLbcLossyComEnFlag2x = 0;
base_config.bLbcLossyComEnFlag2_5x = 0;
if (venc_comp->base_config.pixelformat == RT_PIXEL_LBC_25X) {
base_config.eInputFormat = VENC_PIXEL_LBC_AW;
base_config.bLbcLossyComEnFlag2_5x = 1;
} else if (venc_comp->base_config.pixelformat == RT_PIXEL_LBC_2X) {
base_config.eInputFormat = VENC_PIXEL_LBC_AW;
base_config.bLbcLossyComEnFlag2x = 1;
}
LOCK_MUTEX(&venc_mutex);
VencInit(jpeg_cxt->vencoder, &base_config);
UNLOCK_MUTEX(&venc_mutex);
/* timeout is 2000 ms: HZ is 100, HZ == 1s, so 1 jiffies is 10 ms */
jpeg_cxt->wait_enc_finish_condition = 0;
jpeg_cxt->enable = 1;
wait_event_timeout(jpeg_cxt->wait_enc_finish, jpeg_cxt->wait_enc_finish_condition, 200);
if (jpeg_cxt->wait_enc_finish_condition == 0) {
RT_LOGE("wait for enc finish timeout");
return -1;
}
return 0;
}
static int catch_jpeg_stop(venc_comp_ctx *venc_comp)
{
catch_jpeg_cxt *jpeg_cxt = &venc_comp->jpeg_cxt;
if (jpeg_cxt->vencoder) {
LOCK_MUTEX(&venc_mutex);
VencDestroy(jpeg_cxt->vencoder);
jpeg_cxt->vencoder = NULL;
UNLOCK_MUTEX(&venc_mutex);
} else {
RT_LOGE("the jpeg_cxt->vencoder is null");
return -1;
}
jpeg_cxt->enable = 0;
return 0;
}
static int catch_jpeg_get_data(venc_comp_ctx *venc_comp, void *user_buf_info)
{
int result = 0;
VencOutputBuffer out_buffer;
catch_jpeg_cxt *jpeg_cxt = &venc_comp->jpeg_cxt;
catch_jpeg_buf_info src_buf_info;
if (jpeg_cxt->enable == 0 || !jpeg_cxt->vencoder) {
RT_LOGE("error: enable = %d, vencoder = %p", jpeg_cxt->enable, jpeg_cxt->vencoder);
return -1;
}
memset(&src_buf_info, 0, sizeof(catch_jpeg_buf_info));
memset(&out_buffer, 0, sizeof(VencOutputBuffer));
if (copy_from_user(&src_buf_info, (void __user *)user_buf_info, sizeof(struct catch_jpeg_buf_info))) {
RT_LOGE("IOCTL_CATCH_JPEG_START copy_from_user fail\n");
return -EFAULT;
}
result = VencDequeueOutputBuf(jpeg_cxt->vencoder, &out_buffer);
if (result != 0) {
RT_LOGE("have no bitstream");
return -1;
}
RT_LOGI("data_size = %d, max_size = %d",
out_buffer.nSize0, src_buf_info.buf_size);
if (out_buffer.nSize0 > src_buf_info.buf_size) {
RT_LOGE("buf_size overflow: %d > %d", out_buffer.nSize0, src_buf_info.buf_size);
result = -1;
goto catch_jpeg_get_data_exit;
}
if (copy_to_user((void *)src_buf_info.buf, out_buffer.pData0, out_buffer.nSize0)) {
RT_LOGE(" copy_to_user fail\n");
result = -1;
goto catch_jpeg_get_data_exit;
}
if (copy_to_user((void *)user_buf_info, &out_buffer.nSize0, sizeof(unsigned int))) {
RT_LOGE(" copy_to_user fail\n");
result = -1;
goto catch_jpeg_get_data_exit;
}
catch_jpeg_get_data_exit:
VencQueueOutputBuf(jpeg_cxt->vencoder, &out_buffer);
return result;
}
typedef struct osd_convert_dst_info {
unsigned int dst_ext_buf_size;
unsigned int dst_w_ext;
unsigned int dst_h_ext;
unsigned int dst_crop_x;
unsigned int dst_crop_y;
unsigned int dst_crop_w;
unsigned int dst_crop_h;
unsigned int dst_start_x;
unsigned int dst_start_y;
} osd_convert_dst_info;
typedef struct osd_convert_src_info {
unsigned int start_x;
unsigned int start_y;
unsigned int widht;
unsigned int height;
} osd_convert_src_info;
#if NEI_TEST_CODE
static int convert_osd_pos_info(venc_comp_ctx *venc_comp, osd_convert_dst_info *dst_info, osd_convert_src_info *src_info)
{
/* 1X: 100 */
unsigned int w_ratio = 100;
unsigned int h_ratio = 100;
unsigned int is_left_corner = 0;
if (global_osd_info->ori_frame_w != venc_comp->base_config.dst_width || global_osd_info->ori_frame_h != venc_comp->base_config.dst_height) {
w_ratio = venc_comp->base_config.dst_width * 100 / global_osd_info->ori_frame_w;
h_ratio = venc_comp->base_config.dst_height * 100 / global_osd_info->ori_frame_h;
RT_LOGI("ori_w&h = %d, %d, cur_w&h = %d, %d; w_ratio = %d, h_ratio = %d",
global_osd_info->ori_frame_w, global_osd_info->ori_frame_h,
venc_comp->base_config.dst_width, venc_comp->base_config.dst_height,
w_ratio, h_ratio);
}
if (src_info->start_x > 160)
is_left_corner = 0;
else
is_left_corner = 1;
/* compulte the scale ratio */
if (is_left_corner == 1) {
dst_info->dst_start_x = 0;
dst_info->dst_start_y = 0;
dst_info->dst_w_ext = src_info->start_x + src_info->widht;
dst_info->dst_h_ext = src_info->start_y + src_info->height;
dst_info->dst_crop_x = src_info->start_x;
dst_info->dst_crop_y = src_info->start_y;
dst_info->dst_crop_w = src_info->widht;
dst_info->dst_crop_h = src_info->height;
dst_info->dst_w_ext = dst_info->dst_w_ext * w_ratio / 100;
dst_info->dst_h_ext = dst_info->dst_h_ext * h_ratio / 100;
dst_info->dst_crop_x = dst_info->dst_crop_x * w_ratio / 100;
dst_info->dst_crop_y = dst_info->dst_crop_y * h_ratio / 100;
dst_info->dst_crop_w = dst_info->dst_crop_w * w_ratio / 100;
dst_info->dst_crop_h = dst_info->dst_crop_h * h_ratio / 100;
} else {
dst_info->dst_start_y = 0;
dst_info->dst_start_x = src_info->start_x;
dst_info->dst_start_x = (dst_info->dst_start_x / 16) * 16;
dst_info->dst_w_ext = global_osd_info->ori_frame_w - dst_info->dst_start_x;
dst_info->dst_h_ext = src_info->start_y + src_info->height;
dst_info->dst_crop_x = src_info->start_x - dst_info->dst_start_x;
dst_info->dst_crop_y = src_info->start_y;
dst_info->dst_crop_w = src_info->widht;
dst_info->dst_crop_h = src_info->height;
if (w_ratio != 100) {
unsigned int dst_start_x_ori = 0;
dst_start_x_ori = dst_info->dst_start_x * w_ratio / 100;
dst_info->dst_w_ext = dst_info->dst_w_ext * w_ratio / 100;
dst_info->dst_h_ext = dst_info->dst_h_ext * h_ratio / 100;
dst_info->dst_start_x = (dst_start_x_ori / 16) * 16;
dst_info->dst_w_ext = venc_comp->base_config.dst_width - dst_info->dst_start_x;
dst_info->dst_crop_x = dst_info->dst_crop_x * w_ratio / 100;
dst_info->dst_crop_y = dst_info->dst_crop_y * h_ratio / 100;
dst_info->dst_crop_w = dst_info->dst_crop_w * w_ratio / 100;
dst_info->dst_crop_h = dst_info->dst_crop_h * h_ratio / 100;
dst_info->dst_crop_x += dst_start_x_ori - dst_info->dst_start_x;
}
}
dst_info->dst_w_ext = RT_ALIGN(dst_info->dst_w_ext, 16);
dst_info->dst_h_ext = RT_ALIGN(dst_info->dst_h_ext, 16);
dst_info->dst_ext_buf_size = dst_info->dst_w_ext * dst_info->dst_h_ext * 4;
RT_LOGI("is_left = %d, dst_w&h_e = %d, %d; crop = %d, %d, %d, %d; ratio = %d, %d",
is_left_corner, dst_info->dst_w_ext, dst_info->dst_h_ext,
dst_info->dst_crop_x, dst_info->dst_crop_y, dst_info->dst_crop_w, dst_info->dst_crop_h,
w_ratio, h_ratio);
return 0;
}
#endif
#if ENABLE_SAVE_NATIVE_OVERLAY_DATA
int convert_overlay_info_native(venc_comp_ctx *venc_comp, VencOverlayInfoS *pvenc_osd, VideoInputOSD *user_osd_info)
{
int i = 0;
VencOverlayHeaderS *dst_item = NULL;
OverlayItemInfo *src_item = NULL;
int align_end_x = 0;
int align_end_y = 0;
struct mem_param param;
unsigned int in_phy_addr = 0;
osd_convert_dst_info osd_dst_info;
osd_convert_src_info osd_src_info;
memset(&osd_dst_info, 0, sizeof(osd_convert_dst_info));
memset(&osd_src_info, 0, sizeof(osd_convert_src_info));
if (global_osd_info == NULL) {
RT_LOGW("the global_osd_info is null");
return -1;
}
if (global_osd_info->memops == NULL) {
global_osd_info->memops = mem_create(MEM_TYPE_ION, param);
if (global_osd_info->memops == NULL) {
RT_LOGE("mem_create failed\n");
return -1;
}
}
if (global_osd_info->ori_frame_w == 0 || global_osd_info->ori_frame_h == 0) {
global_osd_info->ori_frame_w = venc_comp->base_config.dst_width;
global_osd_info->ori_frame_h = venc_comp->base_config.dst_height;
}
pvenc_osd->blk_num = user_osd_info->osd_num;
pvenc_osd->argb_type = user_osd_info->argb_type;
pvenc_osd->is_user_buf_flag = 0;
for (i = 0; i < pvenc_osd->blk_num; i++) {
if (i >= GLOBAL_OSD_MAX_NUM) {
RT_LOGW("osd num overlay: blk_num = %d, GLOBAL_OSD_MAX_NUM = %d",
pvenc_osd->blk_num, GLOBAL_OSD_MAX_NUM);
break;
}
dst_item = &pvenc_osd->overlayHeaderList[i];
src_item = &user_osd_info->item_info[i];
/* copy osd data to native */
if (global_osd_info->g2d_in_ion_vir_addr[i] == NULL || global_osd_info->g2d_in_buf_size[i] < src_item->data_size) {
if (global_osd_info->g2d_in_ion_vir_addr[i])
cdc_mem_pfree(global_osd_info->memops, global_osd_info->g2d_in_ion_vir_addr[i]);
global_osd_info->g2d_in_ion_vir_addr[i] = cdc_mem_palloc(global_osd_info->memops, src_item->data_size);
global_osd_info->g2d_in_buf_size[i] = src_item->data_size;
}
if (copy_from_user(global_osd_info->g2d_in_ion_vir_addr[i], (void __user *)src_item->data_buf, src_item->data_size)) {
RT_LOGE("g2d_scale copy_from_user fail\n");
return -1;
}
cdc_mem_flush_cache(global_osd_info->memops, global_osd_info->g2d_in_ion_vir_addr[i], src_item->data_size);
in_phy_addr = cdc_mem_get_phy(global_osd_info->memops, global_osd_info->g2d_in_ion_vir_addr[i]);
memset(&osd_dst_info, 0, sizeof(osd_convert_dst_info));
memset(&osd_src_info, 0, sizeof(osd_convert_src_info));
osd_src_info.start_x = src_item->start_x;
osd_src_info.start_y = src_item->start_y;
osd_src_info.widht = src_item->widht;
osd_src_info.height = src_item->height;
convert_osd_pos_info(venc_comp, &osd_dst_info, &osd_src_info);
align_end_x = osd_dst_info.dst_start_x + osd_dst_info.dst_w_ext;
align_end_y = osd_dst_info.dst_start_y + osd_dst_info.dst_h_ext;
dst_item->start_mb_x = osd_dst_info.dst_start_x / 16;
dst_item->start_mb_y = osd_dst_info.dst_start_y / 16;
dst_item->end_mb_x = align_end_x / 16 - 1;
dst_item->end_mb_y = align_end_y / 16 - 1;
dst_item->overlay_blk_addr = src_item->data_buf;
dst_item->bitmap_size = osd_dst_info.dst_ext_buf_size;
dst_item->overlay_type = NORMAL_OVERLAY;
dst_item->extra_alpha_flag = 0;
dst_item->bforce_reverse_flag = 0;
RT_LOGI("osd item[%d]: s_x&y = %d, %d; e_x&y = %d, %d, size = %d, buf = %p",
i, dst_item->start_mb_x, dst_item->start_mb_y, dst_item->end_mb_x,
dst_item->end_mb_y, dst_item->bitmap_size, dst_item->overlay_blk_addr);
}
return 0;
}
static int adjust_native_overlay_info(venc_comp_ctx *venc_comp)
{
int i = 0;
VencOverlayHeaderS *dst_item = NULL;
int align_end_x = 0;
int align_end_y = 0;
osd_convert_dst_info osd_dst_info;
osd_convert_src_info osd_src_info;
memset(&osd_dst_info, 0, sizeof(osd_convert_dst_info));
memset(&osd_src_info, 0, sizeof(osd_convert_src_info));
if (global_osd_info == NULL) {
RT_LOGW("the global_osd_info is null");
return -1;
}
for (i = 0; i < global_osd_info->sOverlayInfo.blk_num; i++) {
dst_item = &global_osd_info->sOverlayInfo.overlayHeaderList[i];
memset(&osd_dst_info, 0, sizeof(osd_convert_dst_info));
memset(&osd_src_info, 0, sizeof(osd_convert_src_info));
convert_osd_pos_info(venc_comp, &osd_dst_info, &osd_src_info);
align_end_x = osd_dst_info.dst_start_x + osd_dst_info.dst_w_ext;
align_end_y = osd_dst_info.dst_start_y + osd_dst_info.dst_h_ext;
dst_item->start_mb_x = osd_dst_info.dst_start_x / 16;
dst_item->start_mb_y = osd_dst_info.dst_start_y / 16;
dst_item->end_mb_x = align_end_x / 16 - 1;
dst_item->end_mb_y = align_end_y / 16 - 1;
dst_item->bitmap_size = osd_dst_info.dst_ext_buf_size;
RT_LOGI("osd item[%d]: s_x&y = %d, %d; e_x&y = %d, %d, size = %d, buf = %p",
i, dst_item->start_mb_x, dst_item->start_mb_y, dst_item->end_mb_x,
dst_item->end_mb_y, dst_item->bitmap_size, dst_item->overlay_blk_addr);
}
return 0;
}
#else
static int convert_overlay_info(VencOverlayInfoS *pvenc_osd, VideoInputOSD *user_osd_info)
{
int i = 0;
VencOverlayHeaderS *dst_item = NULL;
OverlayItemInfo *src_item = NULL;
int align_start_x = 0;
int align_start_y = 0;
int align_end_x = 0;
int align_end_y = 0;
pvenc_osd->blk_num = user_osd_info->osd_num;
pvenc_osd->argb_type = user_osd_info->argb_type;
pvenc_osd->is_user_buf_flag = 0;
pvenc_osd->invert_mode = user_osd_info->invert_mode;
pvenc_osd->invert_threshold = user_osd_info->invert_threshold;
for (i = 0; i < pvenc_osd->blk_num; i++) {
dst_item = &pvenc_osd->overlayHeaderList[i];
src_item = &user_osd_info->item_info[i];
align_start_x = RT_ALIGN(src_item->start_x, 16);
align_start_y = RT_ALIGN(src_item->start_y, 16);
align_end_x = align_start_x + src_item->widht;
align_end_y = align_start_y + src_item->height;
if (src_item->data_buf && src_item->data_size
&& src_item->osd_type != RT_COVER_OSD) {
if (dst_item->overlay_blk_addr
&& src_item->data_size > dst_item->bitmap_size) {
vfree(dst_item->overlay_blk_addr);
dst_item->overlay_blk_addr = NULL;
RT_LOGI("update overlay[%d] buf size[%d]->[%d]",
i, dst_item->bitmap_size, src_item->data_size);
}
if (!dst_item->overlay_blk_addr) {
dst_item->overlay_blk_addr = vmalloc(src_item->data_size);
memset(dst_item->overlay_blk_addr, 0, src_item->data_size);
}
if (dst_item->overlay_blk_addr) {
if (copy_from_user(dst_item->overlay_blk_addr, (void __user *)src_item->data_buf, src_item->data_size)) {
RT_LOGE("copy_from_user fail\n");
return -EFAULT;
}
}
} else {
dst_item->overlay_blk_addr = NULL;
}
dst_item->bitmap_size = src_item->data_size;
dst_item->start_mb_x = align_start_x / 16;
dst_item->start_mb_y = align_start_y / 16;
dst_item->end_mb_x = align_end_x / 16 - 1;
dst_item->end_mb_y = align_end_y / 16 - 1;
dst_item->overlay_type = src_item->osd_type;
if (dst_item->overlay_type == COVER_OVERLAY)
memcpy(&dst_item->cover_yuv, &src_item->cover_yuv, sizeof(VencOverlayCoverYuvS));
dst_item->extra_alpha_flag = 0;
dst_item->bforce_reverse_flag = 0;
RT_LOGI("osd item[%d]: s_x = %d, s_y = %d, e_x = %d, e_y = %d, size = %d, buf = %p",
i, dst_item->start_mb_x, dst_item->start_mb_y, dst_item->end_mb_x,
dst_item->end_mb_y, dst_item->bitmap_size, dst_item->overlay_blk_addr);
}
return 0;
}
#endif
/**
release frames in valid_frame_list.
frames in using_frame_list will not be released because vencLib are using them.
*/
static int flush_in_buffer(venc_comp_ctx *venc_comp)
{
video_frame_node *frame_node = NULL;
video_frame_s cur_video_frame;
memset(&cur_video_frame, 0, sizeof(video_frame_s));
mutex_lock(&venc_comp->in_buf_manager.mutex);
if (!list_empty(&venc_comp->in_buf_manager.using_frame_list)) {
int cnt = 0; struct list_head *pList; list_for_each(pList, &venc_comp->in_buf_manager.using_frame_list) { cnt++; }
RT_LOGW("Be careful! vencChn[%d] flush frames, but [%d] frames have been sent to venclib, these frames are not released here!",
venc_comp->base_config.channel_id, cnt);
}
while (!list_empty(&venc_comp->in_buf_manager.valid_frame_list)) {
frame_node = list_first_entry(&venc_comp->in_buf_manager.valid_frame_list, video_frame_node, mList);
memcpy(&cur_video_frame, &frame_node->video_frame, sizeof(video_frame_s));
list_move_tail(&frame_node->mList, &venc_comp->in_buf_manager.empty_frame_list);
venc_comp->in_buf_manager.empty_num++;
RT_LOGW("flush in frame buf, frame_node = %p", frame_node);
mutex_unlock(&venc_comp->in_buf_manager.mutex);
venc_empty_in_buffer_done(venc_comp, &cur_video_frame);
mutex_lock(&venc_comp->in_buf_manager.mutex);
}
mutex_unlock(&venc_comp->in_buf_manager.mutex);
return 0;
}
static error_type config_dynamic_param(
venc_comp_ctx *venc_comp,
comp_index_type index,
void *param_data)
{
error_type error = ERROR_TYPE_OK;
int ret = 0;
if (venc_comp->vencoder == NULL) {
RT_LOGW("vencoder is not be created when config dynamic param");
return ERROR_TYPE_ERROR;
}
switch (index) {
case COMP_INDEX_VENC_CONFIG_Dynamic_ForceKeyFrame: {
RT_LOGI("*****ForceKeyFrame***** ");
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamForceKeyFrame, param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_CATCH_JPEG_START: {
catch_jpeg_config *jpeg_config = (catch_jpeg_config *)param_data;
if (catch_jpeg_start(venc_comp, jpeg_config) != 0)
error = ERROR_TYPE_ERROR;
break;
}
case COMP_INDEX_VENC_CONFIG_CATCH_JPEG_STOP: {
if (catch_jpeg_stop(venc_comp) != 0)
error = ERROR_TYPE_ERROR;
break;
}
case COMP_INDEX_VENC_CONFIG_CATCH_JPEG_GET_DATA: {
if (catch_jpeg_get_data(venc_comp, param_data) != 0)
error = ERROR_TYPE_ERROR;
break;
}
case COMP_INDEX_VENC_CONFIG_SET_OSD: {
#if ENABLE_SAVE_NATIVE_OVERLAY_DATA
VencOverlayInfoS *pOverlayInfo = &global_osd_info->sOverlayInfo;
VideoInputOSD inputOsd;
struct file g2d_file;
memset(pOverlayInfo, 0, sizeof(VencOverlayInfoS));
memset(&inputOsd, 0, sizeof(VideoInputOSD));
if (copy_from_user(&inputOsd, (void __user *)param_data, sizeof(VideoInputOSD))) {
RT_LOGE("set osd copy_from_user fail\n");
return -EFAULT;
}
convert_overlay_info_native(venc_comp, pOverlayInfo, &inputOsd);
LOCK_MUTEX(&venc_mutex);
g2d_open(0, &g2d_file);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetOverlay, pOverlayInfo);
g2d_release(0, &g2d_file);
UNLOCK_MUTEX(&venc_mutex);
#else
VideoInputOSD inputOsd;
int i = 0;
if (!venc_comp->venc_overlayInfo) {
venc_comp->venc_overlayInfo = kmalloc(sizeof(VencOverlayInfoS), GFP_KERNEL);
memset(venc_comp->venc_overlayInfo, 0, sizeof(VencOverlayInfoS));
}
memset(&inputOsd, 0, sizeof(VideoInputOSD));
if (copy_from_user(&inputOsd, (void __user *)param_data, sizeof(VideoInputOSD))) {
RT_LOGE("set osd copy_from_user fail\n");
return -EFAULT;
}
if (!inputOsd.osd_num) {
RT_LOGI("user want to disable all venc osd");
for (i = 0; i < venc_comp->venc_overlayInfo->blk_num; i++) {
if (venc_comp->venc_overlayInfo->overlayHeaderList[i].overlay_blk_addr) {
venc_comp->venc_overlayInfo->overlayHeaderList[i].bitmap_size = 0;
vfree(venc_comp->venc_overlayInfo->overlayHeaderList[i].overlay_blk_addr);
venc_comp->venc_overlayInfo->overlayHeaderList[i].overlay_blk_addr = NULL;
}
}
}
convert_overlay_info(venc_comp->venc_overlayInfo, &inputOsd);
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetOverlay, venc_comp->venc_overlayInfo);
UNLOCK_MUTEX(&venc_mutex);
#endif
RT_LOGI("ENABLE_SAVE_NATIVE_OVERLAY_DATA = %d", ENABLE_SAVE_NATIVE_OVERLAY_DATA);
break;
}
// case COMP_INDEX_VENC_CONFIG_ENABLE_BIN_IMAGE: {
// rt_venc_bin_image_param *bin_param = (rt_venc_bin_image_param *)param_data;
// VencBinImageParam venc_bin_param;
//
// venc_bin_param.enable = bin_param->enable;
// venc_bin_param.moving_th = bin_param->moving_th;
//
// RT_LOGI("COMP_INDEX_VENC_CONFIG_ENABLE_BIN_IMAGE: enable = %d, th = %d",
// venc_bin_param.enable, venc_bin_param.moving_th);
// VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableGetBinImage, &venc_bin_param);
// break;
// }
// case COMP_INDEX_VENC_CONFIG_ENABLE_MV_INFO: {
// VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableMvInfo, param_data);
// break;
// }
case COMP_INDEX_VENC_CONFIG_FLUSH_IN_BUFFER: {
flush_in_buffer(venc_comp);
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_SET_QP_RANGE: {
VencQPRange mVencQpRange;
video_qp_range *pQp_range = (video_qp_range *)param_data;
RT_LOGW("SET_QP_RANGE: i_qp = %d ~ %d, p_qp = %d ~ %d, bEnMbQpLimit = %d",
pQp_range->i_min_qp, pQp_range->i_max_qp,
pQp_range->p_min_qp, pQp_range->p_max_qp, pQp_range->enable_mb_qp_limit);
mVencQpRange.nMinqp = pQp_range->i_min_qp;
mVencQpRange.nMaxqp = pQp_range->i_max_qp;
mVencQpRange.nMinPqp = pQp_range->p_min_qp;
mVencQpRange.nMaxPqp = pQp_range->p_max_qp;
mVencQpRange.nQpInit = pQp_range->i_init_qp;
mVencQpRange.bEnMbQpLimit = pQp_range->enable_mb_qp_limit;
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264QPRange, &mVencQpRange);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_H264_TIMING: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264VideoTiming, param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_H265_TIMING: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH265Timing, param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_FIX_QP: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264FixQP, param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_JPG_QUALITY: {
int nQuality = (int)param_data;
RT_LOGI("nQuality = %d", nQuality);
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamJpegQuality, &nQuality);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_MB_MOVE_STATUS: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnIFrmMbRcMoveStatus, param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_SET_BITRATE: {
int bitrate = (int)param_data;
RT_LOGI("SET_BITRATE: bitrate = %d", bitrate);
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamBitrate, &bitrate);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_SET_FPS: {
int fps = (int)param_data;
RT_LOGI("SET_FPS: fps = %d", fps);
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamFramerate, &fps);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_SET_VBR_PARAM: {
RTVencVbrParam *rt_vbr_param = (RTVencVbrParam *)param_data;
VencVbrParam mVbrParam;
memset(&mVbrParam, 0, sizeof(VencVbrParam));
mVbrParam.uMaxBitRate = rt_vbr_param->uMaxBitRate * 1024;
mVbrParam.nMovingTh = rt_vbr_param->nMovingTh;
mVbrParam.nQuality = rt_vbr_param->nQuality;
mVbrParam.nIFrmBitsCoef = rt_vbr_param->nIFrmBitsCoef;
mVbrParam.nPFrmBitsCoef = rt_vbr_param->nPFrmBitsCoef;
RT_LOGI("SET_VBR_PARAM: uMaxBitRate = %d, nMovingTh = %d, nQuality = %d, coef = %d, %d",
mVbrParam.uMaxBitRate, mVbrParam.nMovingTh,
mVbrParam.nQuality, mVbrParam.nIFrmBitsCoef, mVbrParam.nPFrmBitsCoef);
LOCK_MUTEX(&venc_mutex);
ret = VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetVbrParam, &mVbrParam);
if (ret != 0)
error = ERROR_TYPE_ERROR;
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_GET_SUM_MB_INFO: {
//RTVencMBSumInfo *prt_mb_sum = (RTVencMBSumInfo *)param_data;
VencMBSumInfo venc_mb_sum;
memset(&venc_mb_sum, 0, sizeof(VencMBSumInfo));
ret = VencGetParameter(venc_comp->vencoder, VENC_IndexParamMBSumInfoOutput, &venc_mb_sum);
if (ret != 0)
error = ERROR_TYPE_ERROR;
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_SET_IS_NIGHT_CASE: {
int is_night_case = *(int *)param_data;
RT_LOGW("is_night_case = %d", is_night_case);
if (venc_comp->vencoder) {
LOCK_MUTEX(&venc_mutex);
ret = VencSetParameter(venc_comp->vencoder, VENC_IndexParamIsNightCaseFlag, &is_night_case);
if (ret != 0)
error = ERROR_TYPE_ERROR;
UNLOCK_MUTEX(&venc_mutex);
}
break;
}
case COMP_INDEX_VENC_CONFIG_Dynamic_SET_SUPER_FRAME_PARAM: {
VencSuperFrameConfig *pconfig = (VencSuperFrameConfig *)param_data;
if (venc_comp->vencoder) {
LOCK_MUTEX(&venc_mutex);
ret = VencSetParameter(venc_comp->vencoder, VENC_IndexParamSuperFrameConfig, pconfig);
if (ret != 0)
error = ERROR_TYPE_ERROR;
UNLOCK_MUTEX(&venc_mutex);
}
break;
}
case COMP_INDEX_VENC_CONFIG_SET_SHARP: {
// RTsEncppSharp mSharp;
// RTsEncppSharpParamDynamic dynamic_sharp;
// RTsEncppSharpParamStatic static_sharp;
//
// if (copy_from_user(&mSharp, (void __user *)param_data, sizeof(RTsEncppSharp))) {
// RT_LOGE("COMP_INDEX_VENC_CONFIG_SET_SHARP copy_from_user fail\n");
// return -EFAULT;
// }
//
// if (copy_from_user(&dynamic_sharp, (void __user *)mSharp.sEncppSharpParam.pDynamicParam, sizeof(sEncppSharpParamDynamic))) {
// RT_LOGE("pDynamicParam copy_from_user fail\n");
// return -EFAULT;
// }
// if (copy_from_user(&static_sharp, (void __user *)mSharp.sEncppSharpParam.pStaticParam, sizeof(sEncppSharpParamStatic))) {
// RT_LOGE("pStaticParam copy_from_user fail\n");
// return -EFAULT;
// }
//
// mSharp.sEncppSharpParam.pDynamicParam = &dynamic_sharp;
// mSharp.sEncppSharpParam.pStaticParam = &static_sharp;
//
// RT_LOGD("hfr_hf_wht_clp %d max_clp_ratio %d", mSharp.sEncppSharpParam.pDynamicParam->hfr_hf_wht_clp, mSharp.sEncppSharpParam.pDynamicParam->max_clp_ratio);
// RT_LOGD("ls_dir_ratio %d ss_dir_ratio %d", mSharp.sEncppSharpParam.pStaticParam->ls_dir_ratio, mSharp.sEncppSharpParam.pStaticParam->ss_dir_ratio);
//
// VencSetParameter(venc_comp->vencoder, VENC_IndexParamSharpConfig, &mSharp.sEncppSharpParam);
int bSharp = *(int *)param_data;
if (venc_comp->base_config.en_encpp_sharp != bSharp) {
int vipp_id = venc_comp->base_config.channel_id;
RT_LOGW("vipp:%d,venc_type:%d: en_encpp_sharp base config change:%d->%d", vipp_id, venc_comp->base_config.codec_type, venc_comp->base_config.en_encpp_sharp, bSharp);
venc_comp->base_config.en_encpp_sharp = bSharp;
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableEncppSharp, (void *)&venc_comp->base_config.en_encpp_sharp);
}
break;
}
case COMP_INDEX_VENC_CONFIG_CAMERA_MOVE_STATUS: {
if (!venc_comp->base_config.enable_ve_isp_linkage)
break;
eCameraStatus camera_move_status = *(eCameraStatus *)param_data;
RT_LOGI("set camera move status %d", camera_move_status);
venc_comp->camera_move_status = camera_move_status;
break;
}
case COMP_INDEX_VENC_CONFIG_TARGET_BITS_CLIP_PARAM: {
VencTargetBitsClipParam venc_target_bits_clip_param;
RT_VENC_TARGET_BITS_CLIP_PARAM *rt_venc_target_bits_clip_param = (RT_VENC_TARGET_BITS_CLIP_PARAM *)param_data;
memset(&venc_target_bits_clip_param, 0, sizeof(VencTargetBitsClipParam));
venc_target_bits_clip_param.dis_default_para = rt_venc_target_bits_clip_param->dis_default_para;
venc_target_bits_clip_param.mode = rt_venc_target_bits_clip_param->mode;
venc_target_bits_clip_param.en_gop_clip = rt_venc_target_bits_clip_param->en_gop_clip;
memcpy(venc_target_bits_clip_param.gop_bit_ratio_th, rt_venc_target_bits_clip_param->gop_bit_ratio_th,
sizeof(rt_venc_target_bits_clip_param->gop_bit_ratio_th));
memcpy(venc_target_bits_clip_param.coef_th, rt_venc_target_bits_clip_param->coef_th,
sizeof(rt_venc_target_bits_clip_param->coef_th));
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamTargetBitsClipParam, &venc_target_bits_clip_param);
UNLOCK_MUTEX(&venc_mutex);
break;
}
default: {
RT_LOGE("nor support config index");
return ERROR_TYPE_ILLEGAL_PARAM;
break;
}
}
return error;
}
static int post_msg_and_wait(venc_comp_ctx *venc_comp, int cmd_id)
{
message_t cmd_msg;
memset(&cmd_msg, 0, sizeof(message_t));
cmd_msg.command = cmd_id;
cmd_msg.wait_queue = (char *)&venc_comp->wait_reply[cmd_id];
cmd_msg.wait_condition = (char *)&venc_comp->wait_reply_condition[cmd_id];
venc_comp->wait_reply_condition[cmd_id] = 0;
put_message(&venc_comp->msg_queue, &cmd_msg);
RT_LOGD("wait for : cmd[%d], start", cmd_id);
wait_event(venc_comp->wait_reply[cmd_id],
venc_comp->wait_reply_condition[cmd_id]);
RT_LOGD("wait for : cmd[%d], finish", cmd_id);
return 0;
}
error_type venc_comp_init(
PARAM_IN comp_handle component)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_init: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
post_msg_and_wait(venc_comp, COMP_COMMAND_INIT);
return error;
}
error_type venc_comp_start(
PARAM_IN comp_handle component)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_start: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
post_msg_and_wait(venc_comp, COMP_COMMAND_PAUSE);
/* set param for vencoder here as:
* vencoder_set_param will palloc vbv-buf, and we must make sure the pid
* of 'palloc vbv-buf' code is the same as ioctl-calling, to valid ion share
* between user and kenrl.
*/
vencoder_set_param(venc_comp);
venc_comp->vencCallBack.EventHandler = venc_comp_event_handler;
if (venc_comp->base_config.bOnlineChannel == 0)
venc_comp->vencCallBack.InputBufferDone = VencCompInputBufferDone;
VencSetCallbacks(venc_comp->vencoder, &venc_comp->vencCallBack, venc_comp);
VencStart(venc_comp->vencoder);
post_msg_and_wait(venc_comp, COMP_COMMAND_START);
return error;
}
error_type venc_comp_pause(
PARAM_IN comp_handle component)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_start: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
RT_LOGD("Ryan VencPause");
VencPause(venc_comp->vencoder);
post_msg_and_wait(venc_comp, COMP_COMMAND_PAUSE);
return error;
}
error_type venc_comp_stop(
PARAM_IN comp_handle component)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_stop: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
RT_LOGD("Ryan VencDestroy");
//VencDestroy(venc_comp->vencoder);
post_msg_and_wait(venc_comp, COMP_COMMAND_STOP);
return error;
}
error_type venc_comp_destroy(
PARAM_IN comp_handle component)
{
int i = 0;
int free_frame_cout = 0;
int free_stream_cout = 0;
video_stream_node *stream_node = NULL;
video_frame_node *frame_node = NULL;
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_destroy: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
/*should make sure the thread do nothing importent */
if (venc_comp->venc_thread)
kthread_stop(venc_comp->venc_thread);
message_destroy(&venc_comp->msg_queue);
if (venc_comp->vencoder) {
LOCK_MUTEX(&venc_mutex);
VencDestroy(venc_comp->vencoder);
UNLOCK_MUTEX(&venc_mutex);
}
while ((!list_empty(&venc_comp->in_buf_manager.empty_frame_list))) {
frame_node = list_first_entry(&venc_comp->in_buf_manager.empty_frame_list, video_frame_node, mList);
if (frame_node) {
list_del(&frame_node->mList);
free_frame_cout++;
kfree(frame_node);
}
}
if (!list_empty(&venc_comp->in_buf_manager.using_frame_list)) {
int nUsingNum = 0;
video_frame_node *tmp_node;
list_for_each_entry_safe (frame_node, tmp_node, &venc_comp->in_buf_manager.using_frame_list, mList) {
if (frame_node) {
list_del(&frame_node->mList);
free_frame_cout++;
nUsingNum++;
kfree(frame_node);
}
}
RT_LOGE("fatal error! vencChn[%d] in_buf using frame list has %d frames", venc_comp->base_config.channel_id, nUsingNum);
}
int nValidNum = 0;
while ((!list_empty(&venc_comp->in_buf_manager.valid_frame_list))) {
frame_node = list_first_entry(&venc_comp->in_buf_manager.valid_frame_list, video_frame_node, mList);
if (frame_node) {
list_del(&frame_node->mList);
free_frame_cout++;
kfree(frame_node);
}
nValidNum++;
}
if (nValidNum > 0) {
RT_LOGE("fatal error! vencChn[%d] in_buf valid frame list has %d frames", venc_comp->base_config.channel_id, nValidNum);
}
if (free_frame_cout != VENC_IN_BUFFER_LIST_NODE_NUM)
RT_LOGE("free num of frame node is not match: %d, %d", free_frame_cout, VENC_IN_BUFFER_LIST_NODE_NUM);
RT_LOGD("free_frame_cout = %d", free_frame_cout);
while ((!list_empty(&venc_comp->out_buf_manager.empty_stream_list))) {
stream_node = list_first_entry(&venc_comp->out_buf_manager.empty_stream_list, video_stream_node, mList);
if (stream_node) {
list_del(&stream_node->mList);
free_stream_cout++;
kfree(stream_node);
}
}
while ((!list_empty(&venc_comp->out_buf_manager.valid_stream_list))) {
stream_node = list_first_entry(&venc_comp->out_buf_manager.valid_stream_list, video_stream_node, mList);
if (stream_node) {
list_del(&stream_node->mList);
free_stream_cout++;
kfree(stream_node);
}
}
if (free_stream_cout != VENC_OUT_BUFFER_LIST_NODE_NUM)
RT_LOGE("free num of stream node is not match: %d, %d", free_stream_cout, VENC_OUT_BUFFER_LIST_NODE_NUM);
if (venc_comp->venc_overlayInfo) {
for (i = 0; i < venc_comp->venc_overlayInfo->blk_num; i++) {
if (venc_comp->venc_overlayInfo->overlayHeaderList[i].overlay_blk_addr) {
vfree(venc_comp->venc_overlayInfo->overlayHeaderList[i].overlay_blk_addr);
venc_comp->venc_overlayInfo->overlayHeaderList[i].overlay_blk_addr = NULL;
}
}
kfree(venc_comp->venc_overlayInfo);
}
RT_LOGD("free_stream_cout = %d", free_stream_cout);
kfree(venc_comp);
return error;
}
error_type venc_comp_get_config(
PARAM_IN comp_handle component,
PARAM_IN comp_index_type index,
PARAM_INOUT void *param_data)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_get_config: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
RT_LOGD("venc_comp_get_config : %d, start", index);
switch (index) {
case COMP_INDEX_VENC_CONFIG_GET_WBYUV: {
RTVencThumbInfo *p_wb_info = (RTVencThumbInfo *)param_data;
VencThumbInfo s_venc_thumb_info;
memset(&s_venc_thumb_info, 0, sizeof(VencThumbInfo));
s_venc_thumb_info.nThumbSize = p_wb_info->nThumbSize;
s_venc_thumb_info.pThumbBuf = p_wb_info->pThumbBuf;
LOCK_MUTEX(&venc_mutex);
error = VencGetParameter(venc_comp->vencoder, VENC_IndexParamGetThumbYUV, &s_venc_thumb_info);
UNLOCK_MUTEX(&venc_mutex);
RT_LOGD("nThumbSize %d %p", p_wb_info->nThumbSize, p_wb_info->pThumbBuf);
break;
}
case COMP_INDEX_VENC_CONFIG_GET_VBV_BUF_INFO: {
KERNEL_VBV_BUFFER_INFO *param_vbv = (KERNEL_VBV_BUFFER_INFO *)param_data;
VbvInfo vbv_info;
int share_fd = 0;
memset(&vbv_info, 0, sizeof(VbvInfo));
if (venc_comp->vencoder_init_flag == 0) {
RT_LOGD("get vbv info: vencoder not init");
return ERROR_TYPE_ERROR;
}
VencGetParameter(venc_comp->vencoder, VENC_IndexParamVbvInfo, &vbv_info);
param_vbv->size = vbv_info.vbv_size;
VencGetParameter(venc_comp->vencoder, VENC_IndexParamGetVbvShareFd, &share_fd);
param_vbv->share_fd = share_fd;
RT_LOGW("get vbv info: share_fd = %d, size = %d", param_vbv->share_fd, param_vbv->size);
break;
}
case COMP_INDEX_VENC_CONFIG_GET_STREAM_HEADER: {
venc_comp_header_data *header_data = (venc_comp_header_data *)param_data;
VencHeaderData sps_pps_data;
memset(&sps_pps_data, 0, sizeof(VencHeaderData));
if (venc_comp->base_config.codec_type == RT_VENC_CODEC_H264) {
VencGetParameter(venc_comp->vencoder, VENC_IndexParamH264SPSPPS, &sps_pps_data);
} else if (venc_comp->base_config.codec_type == RT_VENC_CODEC_H265) {
VencGetParameter(venc_comp->vencoder, VENC_IndexParamH265Header, &sps_pps_data);
} else {
RT_LOGW("not support COMP_INDEX_VENC_CONFIG_GET_VBV_BUF_INFO yet");
return ERROR_TYPE_ERROR;
}
RT_LOGD("1 get stream header = %d, data = %x %x %x %x %x %x %x %x", sps_pps_data.nLength,
sps_pps_data.pBuffer[0],
sps_pps_data.pBuffer[1],
sps_pps_data.pBuffer[2],
sps_pps_data.pBuffer[3],
sps_pps_data.pBuffer[4],
sps_pps_data.pBuffer[5],
sps_pps_data.pBuffer[6],
sps_pps_data.pBuffer[7]);
RT_LOGD("2 get stream header size = %d, data = %x %x %x %x %x %x %x %x", sps_pps_data.nLength,
sps_pps_data.pBuffer[8],
sps_pps_data.pBuffer[9],
sps_pps_data.pBuffer[10],
sps_pps_data.pBuffer[11],
sps_pps_data.pBuffer[12],
sps_pps_data.pBuffer[13],
sps_pps_data.pBuffer[14],
sps_pps_data.pBuffer[15]);
RT_LOGD("3 get stream header size = %d, data = %x %x %x %x %x %x %x", sps_pps_data.nLength,
sps_pps_data.pBuffer[16],
sps_pps_data.pBuffer[17],
sps_pps_data.pBuffer[18],
sps_pps_data.pBuffer[19],
sps_pps_data.pBuffer[20],
sps_pps_data.pBuffer[21],
sps_pps_data.pBuffer[22]);
header_data->pBuffer = sps_pps_data.pBuffer;
header_data->nLength = sps_pps_data.nLength;
break;
}
#if NEI_TEST_CODE
case COMP_INDEX_VENC_CONFIG_GET_BIN_IMAGE_DATA:
{
VencGetBinImageBufInfo venc_bin_buf_info;
VideoGetBinImageBufInfo bin_buf_info;
RT_LOGI("COMP_INDEX_VENC_CONFIG_GET_BIN_IMAGE_DATA ");
memset(&bin_buf_info, 0, sizeof(VideoGetBinImageBufInfo));
memset(&venc_bin_buf_info, 0, sizeof(VencGetBinImageBufInfo));
if (copy_from_user(&bin_buf_info, (void __user *)param_data, sizeof(struct VideoGetBinImageBufInfo))) {
RT_LOGE("COMP_INDEX_VENC_CONFIG_GET_BIN_IMAGE_DATA copy_from_user fail\n");
return -EFAULT;
}
venc_bin_buf_info.buf = bin_buf_info.buf;
venc_bin_buf_info.max_size = bin_buf_info.max_size;
return VencGetParameter(venc_comp->vencoder, VENC_IndexParamGetBinImageData, &venc_bin_buf_info);
}
case COMP_INDEX_VENC_CONFIG_GET_MV_INFO_DATA:
{
VencGetMvInfoBufInfo venc_mv_buf_info;
VideoGetMvInfoBufInfo mv_buf_info;
RT_LOGI("COMP_INDEX_VENC_CONFIG_GET_MV_INFO_DATA");
memset(&mv_buf_info, 0, sizeof(VideoGetMvInfoBufInfo));
memset(&venc_mv_buf_info, 0, sizeof(VencGetMvInfoBufInfo));
if (copy_from_user(&mv_buf_info, (void __user *)param_data, sizeof(struct VideoGetMvInfoBufInfo))) {
RT_LOGE("COMP_INDEX_VENC_CONFIG_GET_BIN_IMAGE_DATA copy_from_user fail\n");
return -EFAULT;
}
venc_mv_buf_info.buf = mv_buf_info.buf;
venc_mv_buf_info.max_size = mv_buf_info.max_size;
return VencGetParameter(venc_comp->vencoder, VENC_IndexParamGetMvInfoData, &venc_mv_buf_info);
}
#endif
case COMP_INDEX_VENC_CONFIG_Dynamic_GET_MOTION_SEARCH_RESULT: {
VencMotionSearchResult *motion_result = (VencMotionSearchResult *)param_data;
RT_LOGI("COMP_INDEX_VENC_CONFIG_Dynamic_GET_MOTION_SEARCH_RESULT");
return VencGetParameter(venc_comp->vencoder, VENC_IndexParamMotionSearchResult, motion_result);
}
case COMP_INDEX_VENC_CONFIG_Dynamic_GET_REGION_D3D_RESULT: {
VencRegionD3DResult *pRegionD3DResult = (VencRegionD3DResult *)param_data;
error = VencGetParameter(venc_comp->vencoder, VENC_IndexParamRegionD3DResult, pRegionD3DResult);
break;
}
case COMP_INDEX_VENC_CONFIG_GET_INSERT_DATA_BUF_STATUS: {
VENC_BUF_STATUS *pStatus = (VENC_BUF_STATUS *)param_data;
error = VencGetParameter(venc_comp->vencoder, VENC_IndexParamInsertDataBufStatus, pStatus);
break;
}
default: {
RT_LOGW("get config: not support the index = 0x%x", index);
break;
}
}
RT_LOGD("venc_comp_get_config : %d, finish", index);
return error;
}
error_type venc_comp_set_config(
PARAM_IN comp_handle component,
PARAM_IN comp_index_type index,
PARAM_IN void *param_data)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_set_config: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
switch (index) {
case COMP_INDEX_VENC_CONFIG_RESET_VE_INOUT_BUFFER: {
RT_LOGD("VencBufferReset");
VencReset(venc_comp->vencoder);
break;
}
case COMP_INDEX_VENC_CONFIG_Base: {
venc_comp_base_config *base_config = (venc_comp_base_config *)param_data;
memcpy(&venc_comp->base_config, base_config, sizeof(venc_comp_base_config));
break;
}
case COMP_INDEX_VENC_CONFIG_Normal: {
venc_comp_normal_config *normal_config = (venc_comp_normal_config *)param_data;
memcpy(&venc_comp->normal_config, normal_config, sizeof(venc_comp_normal_config));
break;
}
case COMP_INDEX_VENC_CONFIG_SET_MOTION_SEARCH_PARAM: {
if (venc_comp->base_config.codec_type == RT_VENC_CODEC_H264
|| venc_comp->base_config.codec_type == RT_VENC_CODEC_H265) {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamMotionSearchParam, (VencMotionSearchParam *)param_data);
UNLOCK_MUTEX(&venc_mutex);
}
break;
}
case COMP_INDEX_VENC_CONFIG_SET_ROI: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamROIConfig, (VencROIConfig *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_GDC: {
if (rt_is_format422(venc_comp->base_config.pixelformat)) {
RT_LOGE("422 not support gdc, please disable gdc");
break;
}
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamGdcConfig, (sGdcParam *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_ROTATE: {
if (venc_comp->base_config.pixelformat == RT_PIXEL_LBC_25X || venc_comp->base_config.pixelformat == RT_PIXEL_LBC_2X) {
RT_LOGW("lbc format not support rotate!");
break;
}
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamRotation, (unsigned int *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_REC_REF_LBC_MODE: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamSetRecRefLbcMode, (eVeLbcMode *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_WEAK_TEXT_TH: {
LOCK_MUTEX(&venc_mutex);
venc_comp->st_dynamic_proc_set.weak_text_th = *((float *)param_data);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamWeakTextTh, (float *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_REGION_D3D_PARAM: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamRegionD3DParam, (VencRegionD3DParam *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_CHROMA_QP_OFFSET: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamChromaQPOffset, (int *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_ENC_AND_DEC_CASE: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEncAndDecCase, (int *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_H264_CONSTRAINT_FLAG: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264ConstraintFlag, (VencH264ConstraintFlag *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_VE2ISP_D2D_LIMIT: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamVe2IspD2DLimit, (VencVe2IspD2DLimit *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_EN_SMALL_SEARCH_RANGE: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnSmallSearchRange, (int *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_FORCE_CONF_WIN: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamForceConfWin, (VencForceConfWin *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_ROT_VE2ISP: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamRotVe2Isp, (VencRotVe2Isp *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_INSERT_DATA: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamInsertData, (VencInsertData *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_GRAY: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamChmoraGray, (unsigned int *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_WBYUV: {
RTsWbYuvParam *p_wbyuv_param = (RTsWbYuvParam *)param_data;
if (p_wbyuv_param->bEnableWbYuv && !venc_comp->vencoder_init_flag) {//en wbyuv will set int venc_init.
memcpy(&venc_comp->base_config.s_wbyuv_param, p_wbyuv_param, sizeof(RTsWbYuvParam));
} else {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamEnableWbYuv, (RTsWbYuvParam *)param_data);
UNLOCK_MUTEX(&venc_mutex);
}
break;
}
case COMP_INDEX_VENC_CONFIG_SET_2DNR: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParam2DFilter, (s2DfilterParam *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_3DNR: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParam3DFilterNew, (s3DfilterParam *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_CYCLE_INTRA_REFRESH: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamH264CyclicIntraRefresh, (VencCyclicIntraRefresh *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_P_FRAME_INTRA: {
LOCK_MUTEX(&venc_mutex);
VencSetParameter(venc_comp->vencoder, VENC_IndexParamPFrameIntraEn, (unsigned int *)param_data);
UNLOCK_MUTEX(&venc_mutex);
break;
}
case COMP_INDEX_VENC_CONFIG_DROP_FRAME: {
message_t msg;
memset(&msg, 0, sizeof(message_t));
msg.command = COMP_COMMAND_VENC_DROP_FRAME;
msg.para0 = *(int *)param_data;
put_message(&venc_comp->msg_queue, &msg);
break;
}
case COMP_INDEX_VENC_CONFIG_SET_CROP: {
memcpy(&venc_comp->base_config.s_crop_info, param_data, sizeof(RTCropInfo));
break;
}
default: {
error = config_dynamic_param(venc_comp, index, param_data);
break;
}
}
return error;
}
error_type venc_comp_get_state(
PARAM_IN comp_handle component,
PARAM_OUT comp_state_type *pState)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_get_state: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
*pState = venc_comp->state;
return error;
}
/* empty_list --> valid_list */
error_type venc_comp_empty_this_in_buffer(
PARAM_IN comp_handle component,
PARAM_IN comp_buffer_header_type *buffer_header)
{
video_frame_node *pNode = NULL;
video_frame_s *src_frame = NULL;
video_frame_node *first_node = NULL;
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
message_t msg;
static int cnt_1 = 1;
memset(&msg, 0, sizeof(message_t));
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_empty_this_in_buffer: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
if (venc_comp->state != COMP_STATE_EXECUTING) {
RT_LOGW("channel %d submit inbuf when venc state[0x%x] isn not executing",
venc_comp->base_config.channel_id, venc_comp->state);
}
src_frame = (video_frame_s *)buffer_header->private;
if (src_frame == NULL) {
RT_LOGE("submit in buf: frame is null");
error = ERROR_TYPE_ILLEGAL_PARAM;
goto submit_exit;
}
RT_LOGI("empty buf: pts = %lld", src_frame->pts);
mutex_lock(&venc_comp->in_buf_manager.mutex);
if (list_empty(&venc_comp->in_buf_manager.empty_frame_list)) {
RT_LOGW("Low probability! venc idle frame is empty!");
if (venc_comp->in_buf_manager.empty_num != 0) {
RT_LOGE("fatal error! empty_num must be zero!");
}
pNode = kmalloc(sizeof(video_frame_node), GFP_KERNEL);
if (NULL == pNode) {
RT_LOGE("fatal error! kmalloc fail!");
error = ERROR_TYPE_NOMEM;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
goto submit_exit;
}
memset(pNode, 0, sizeof(video_frame_node));
list_add_tail(&pNode->mList, &venc_comp->in_buf_manager.empty_frame_list);
venc_comp->in_buf_manager.empty_num++;
}
first_node = list_first_entry(&venc_comp->in_buf_manager.empty_frame_list, video_frame_node, mList);
memcpy(&first_node->video_frame, src_frame, sizeof(video_frame_s));
venc_comp->in_buf_manager.empty_num--;
list_move_tail(&first_node->mList, &venc_comp->in_buf_manager.valid_frame_list);
#if 1
if (cnt_1) {
cnt_1 = 0;
RT_LOGW("channel %d first time add buffer_node to valid_frame_list, time: %lld",
venc_comp->base_config.channel_id, get_cur_time());
}
#endif
if (venc_comp->in_buf_manager.no_frame_flag) {
venc_comp->in_buf_manager.no_frame_flag = 0;
msg.command = COMP_COMMAND_VENC_INPUT_FRAME_VALID;
put_message(&venc_comp->msg_queue, &msg);
}
mutex_unlock(&venc_comp->in_buf_manager.mutex);
submit_exit:
return error;
}
/* valid_list --> empty_list */
error_type venc_comp_fill_this_out_buffer(
PARAM_IN comp_handle component,
PARAM_IN comp_buffer_header_type *pBuffer)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
video_stream_s *src_stream = NULL;
video_stream_node *stream_node = NULL;
VencOutputBuffer output_buffer;
memset(&output_buffer, 0, sizeof(VencOutputBuffer));
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_fill_this_out_buffer: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
src_stream = (video_stream_s *)pBuffer->private;
RT_LOGD(" id = %d", src_stream->id);
/* get the ready frame */
mutex_lock(&venc_comp->out_buf_manager.mutex);
if (list_empty(&venc_comp->out_buf_manager.valid_stream_list)) {
RT_LOGE("the valid stream list is empty when return out buffer");
mutex_unlock(&venc_comp->out_buf_manager.mutex);
return ERROR_TYPE_ERROR;
}
stream_node = list_first_entry(&venc_comp->out_buf_manager.valid_stream_list, video_stream_node, mList);
if (src_stream->id != stream_node->video_stream.id) {
RT_LOGE("fill this out buf: buf is not match, id = %d ,%d",
src_stream->id, stream_node->video_stream.id);
mutex_unlock(&venc_comp->out_buf_manager.mutex);
return -1;
}
memcpy(&stream_node->video_stream, src_stream, sizeof(video_stream_s));
/* free bitstream frame to vencoder */
config_VencOutputBuffer_by_videostream(venc_comp, &output_buffer, &stream_node->video_stream);
LOCK_MUTEX(&venc_mutex);
VencQueueOutputBuf(venc_comp->vencoder, &output_buffer);
UNLOCK_MUTEX(&venc_mutex);
list_move_tail(&stream_node->mList, &venc_comp->out_buf_manager.empty_stream_list);
venc_comp->out_buf_manager.empty_num++;
mutex_unlock(&venc_comp->out_buf_manager.mutex);
return error;
}
error_type venc_comp_set_callbacks(
PARAM_IN comp_handle component,
PARAM_IN comp_callback_type *callback,
PARAM_IN void *callback_data)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL) {
RT_LOGE("venc_comp_set_callbacks: param error");
return ERROR_TYPE_ILLEGAL_PARAM;
}
venc_comp->callback = callback;
venc_comp->callback_data = callback_data;
return error;
}
error_type venc_comp_setup_tunnel(
PARAM_IN comp_handle component,
PARAM_IN comp_port_type port_type,
PARAM_IN comp_handle tunnel_comp,
PARAM_IN int connect_flag)
{
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)rt_component->component_private;
if (rt_component == NULL || venc_comp == NULL || tunnel_comp == NULL) {
RT_LOGE("venc_comp_set_callbacks, param error: %p, %p, %p",
rt_component, venc_comp, tunnel_comp);
error = ERROR_TYPE_ILLEGAL_PARAM;
goto setup_tunnel_exit;
}
if (port_type == COMP_INPUT_PORT) {
if (connect_flag == 1) {
if (venc_comp->in_port_tunnel_info.valid_flag == 1) {
RT_LOGE("in port tunnel had setuped !!");
error = ERROR_TYPE_ERROR;
goto setup_tunnel_exit;
} else {
venc_comp->in_port_tunnel_info.valid_flag = 1;
venc_comp->in_port_tunnel_info.tunnel_comp = tunnel_comp;
}
} else {
if (venc_comp->in_port_tunnel_info.valid_flag == 1 && venc_comp->in_port_tunnel_info.tunnel_comp == tunnel_comp) {
venc_comp->in_port_tunnel_info.valid_flag = 0;
venc_comp->in_port_tunnel_info.tunnel_comp = NULL;
} else {
RT_LOGE("disconnect in tunnel failed: valid_flag = %d, tunnel_comp = %p, %p",
venc_comp->in_port_tunnel_info.valid_flag,
venc_comp->in_port_tunnel_info.tunnel_comp, tunnel_comp);
error = ERROR_TYPE_ERROR;
}
}
} else if (port_type == COMP_OUTPUT_PORT) {
if (connect_flag == 1) {
if (venc_comp->out_port_tunnel_info.valid_flag == 1) {
RT_LOGE("out port tunnel had setuped !!");
error = ERROR_TYPE_ERROR;
goto setup_tunnel_exit;
} else {
venc_comp->out_port_tunnel_info.valid_flag = 1;
venc_comp->out_port_tunnel_info.tunnel_comp = tunnel_comp;
}
} else {
if (venc_comp->out_port_tunnel_info.valid_flag == 1 && venc_comp->out_port_tunnel_info.tunnel_comp == tunnel_comp) {
venc_comp->out_port_tunnel_info.valid_flag = 0;
venc_comp->out_port_tunnel_info.tunnel_comp = NULL;
} else {
RT_LOGE("disconnect out tunnel failed: valid_flag = %d, tunnel_comp = %p, %p",
venc_comp->out_port_tunnel_info.valid_flag,
venc_comp->out_port_tunnel_info.tunnel_comp, tunnel_comp);
error = ERROR_TYPE_ERROR;
}
}
}
setup_tunnel_exit:
return error;
}
error_type venc_comp_component_init(PARAM_IN comp_handle component, const rt_media_config_s *pmedia_config)
{
int i = 0;
int ret = 0;
error_type error = ERROR_TYPE_OK;
rt_component_type *rt_component = (rt_component_type *)component;
struct venc_comp_ctx *venc_comp = NULL;
venc_comp = kmalloc(sizeof(struct venc_comp_ctx), GFP_KERNEL);
if (venc_comp == NULL) {
RT_LOGE("kmalloc for venc_comp failed");
error = ERROR_TYPE_NOMEM;
goto EXIT;
}
memset(venc_comp, 0, sizeof(struct venc_comp_ctx));
#if ENABLE_SAVE_NATIVE_OVERLAY_DATA
if (global_osd_info == NULL) {
global_osd_info = kmalloc(sizeof(struct native_osd_info), GFP_KERNEL);
if (global_osd_info == NULL) {
RT_LOGW("kmalloc for global_osd_info failed, size = %d", sizeof(struct native_osd_info));
error = ERROR_TYPE_NOMEM;
goto EXIT;
} else
memset(global_osd_info, 0, sizeof(struct native_osd_info));
/* force set ori size to 2560x1440*/
global_osd_info->ori_frame_w = 2560;
global_osd_info->ori_frame_h = 1440;
RT_LOGI("ori_frame_w = %d, h = %d", global_osd_info->ori_frame_w, global_osd_info->ori_frame_h);
}
#endif
ret = message_create(&venc_comp->msg_queue);
if (ret < 0) {
RT_LOGE("message create failed");
error = ERROR_TYPE_ERROR;
goto EXIT;
}
rt_component->component_private = venc_comp;
rt_component->init = venc_comp_init;
rt_component->start = venc_comp_start;
rt_component->pause = venc_comp_pause;
rt_component->stop = venc_comp_stop;
rt_component->destroy = venc_comp_destroy;
rt_component->get_config = venc_comp_get_config;
rt_component->set_config = venc_comp_set_config;
rt_component->get_state = venc_comp_get_state;
rt_component->empty_this_in_buffer = venc_comp_empty_this_in_buffer;
rt_component->fill_this_out_buffer = venc_comp_fill_this_out_buffer;
rt_component->set_callbacks = venc_comp_set_callbacks;
rt_component->setup_tunnel = venc_comp_setup_tunnel;
venc_comp->base_config.channel_id = pmedia_config->channelId;
venc_comp->self_comp = rt_component;
venc_comp->state = COMP_STATE_IDLE;
for (i = 0; i < WAIT_REPLY_NUM; i++) {
init_waitqueue_head(&venc_comp->wait_reply[i]);
}
init_waitqueue_head(&venc_comp->jpeg_cxt.wait_enc_finish);
/* init in buf manager*/
mutex_init(&venc_comp->in_buf_manager.mutex);
venc_comp->in_buf_manager.empty_num = VENC_IN_BUFFER_LIST_NODE_NUM;
INIT_LIST_HEAD(&venc_comp->in_buf_manager.empty_frame_list);
INIT_LIST_HEAD(&venc_comp->in_buf_manager.valid_frame_list);
INIT_LIST_HEAD(&venc_comp->in_buf_manager.using_frame_list);
for (i = 0; i < VENC_IN_BUFFER_LIST_NODE_NUM; i++) {
video_frame_node *pNode = kmalloc(sizeof(video_frame_node), GFP_KERNEL);
if (NULL == pNode) {
RT_LOGE("fatal error! kmalloc fail!");
error = ERROR_TYPE_NOMEM;
goto EXIT;
}
memset(pNode, 0, sizeof(video_frame_node));
list_add_tail(&pNode->mList, &venc_comp->in_buf_manager.empty_frame_list);
}
/* init out buf manager*/
mutex_init(&venc_comp->out_buf_manager.mutex);
venc_comp->out_buf_manager.empty_num = VENC_OUT_BUFFER_LIST_NODE_NUM;
INIT_LIST_HEAD(&venc_comp->out_buf_manager.empty_stream_list);
INIT_LIST_HEAD(&venc_comp->out_buf_manager.valid_stream_list);
for (i = 0; i < VENC_OUT_BUFFER_LIST_NODE_NUM; i++) {
video_stream_node *pNode = kmalloc(sizeof(video_stream_node), GFP_KERNEL);
if (NULL == pNode) {
RT_LOGE("fatal error! kmalloc fail!");
error = ERROR_TYPE_NOMEM;
goto EXIT;
}
memset(pNode, 0, sizeof(video_stream_node));
list_add_tail(&pNode->mList, &venc_comp->out_buf_manager.empty_stream_list);
}
venc_comp->camera_move_status = CAMERA_ADAPTIVE_STATIC;
RT_LOGS("channel_id %d venc_comp %p create thread_process_venc", venc_comp->base_config.channel_id, venc_comp);
venc_comp->venc_thread = kthread_create(thread_process_venc,
venc_comp, "venc comp thread");
wake_up_process(venc_comp->venc_thread);
EXIT:
return error;
}
#if TEST_ENCODER_BY_SELF
static void loop_encode_one_frame(struct venc_comp_ctx *venc_comp)
{
VencInputBuffer in_buf;
video_frame_s cur_video_frame;
video_frame_node *frame_node = NULL;
int result = 0;
if (venc_comp->is_first_frame == 0) {
mutex_lock(&venc_comp->in_buf_manager.mutex);
if (list_empty(&venc_comp->in_buf_manager.valid_frame_list)) {
RT_LOGD("valid frame list is null, wait for it start");
venc_comp->in_buf_manager.no_frame_flag = 1;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
TMessage_WaitQueueNotEmpty(&venc_comp->msg_queue, 200);
RT_LOGD("valid frame list is null, wait for it finish");
return;
}
frame_node = list_first_entry(&venc_comp->in_buf_manager.valid_frame_list, video_frame_node, mList);
memcpy(&cur_video_frame, &frame_node->video_frame, sizeof(video_frame_s));
mutex_unlock(&venc_comp->in_buf_manager.mutex);
GetOneAllocInputBuffer(venc_comp->vencoder, &in_buf);
memcpy(in_buf.pAddrVirY, cur_video_frame.vir_addr[0], cur_video_frame.buf_size);
FlushCacheAllocInputBuffer(venc_comp->vencoder, &in_buf);
VencQueueInputBuf(venc_comp->vencoder, &in_buf);
result = encodeOneFrame(venc_comp->vencoder);
RT_LOGW("first encode, ret = %d, buf_size = %d, vir_addr = %p, %p",
result, cur_video_frame.buf_size,
in_buf.pAddrVirY, cur_video_frame.vir_addr[0]);
mutex_lock(&venc_comp->in_buf_manager.mutex);
list_move_tail(&frame_node->mList, &venc_comp->in_buf_manager.empty_frame_list);
venc_comp->in_buf_manager.empty_num++;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
venc_empty_in_buffer_done(venc_comp, &cur_video_frame);
venc_comp->is_first_frame = 1;
} else {
GetOneAllocInputBuffer(venc_comp->vencoder, &in_buf);
//int y_size = venc_comp->base_config.src_width*venc_comp->base_config.src_height;
//memset(in_buf.pAddrVirY, 0x80, y_size);
//memset(in_buf.pAddrVirC, 0x10, y_size/2);
//FlushCacheAllocInputBuffer(venc_comp->vencoder, &in_buf);
VencQueueInputBuf(venc_comp->vencoder, &in_buf);
result = encodeOneFrame(venc_comp->vencoder);
if (result != 0)
msleep(20);
RT_LOGD("**test copy encoder, result = %d", result);
}
}
#endif
static int venc_comp_stream_buffer_to_valid_list(struct venc_comp_ctx *venc_comp, VencOutputBuffer *p_out_buffer)
{
int result = 0;
mutex_lock(&venc_comp->out_buf_manager.mutex);
if (list_empty(&venc_comp->out_buf_manager.empty_stream_list)) {
if (list_empty(&venc_comp->out_buf_manager.empty_stream_list))
RT_LOGI("venc_comp %p channel_id %d empty list is null", venc_comp, venc_comp->base_config.channel_id);
mutex_unlock(&venc_comp->out_buf_manager.mutex);
return -1;
}
mutex_unlock(&venc_comp->out_buf_manager.mutex);
LOCK_MUTEX(&venc_mutex);
result = VencDequeueOutputBuf(venc_comp->vencoder, p_out_buffer);
UNLOCK_MUTEX(&venc_mutex);
if (result != 0) {
RT_LOGD(" have no bitstream, result = %d", result);
return -1;
}
RT_LOGI(" get bitstream , result = %d, pts = %lld", result, p_out_buffer->nPts);
if (venc_comp->vbvStartAddr == NULL) {
VbvInfo vbv_info;
memset(&vbv_info, 0, sizeof(VbvInfo));
VencGetParameter(venc_comp->vencoder, VENC_IndexParamVbvInfo, &vbv_info);
venc_comp->vbvStartAddr = vbv_info.start_addr;
}
venc_fill_out_buffer_done(venc_comp, p_out_buffer);
return 0;
}
static int check_ve_proc_dynamic_setting(struct venc_comp_ctx *venc_comp)
{
ve_proc_setting_info proc_ve_info;
int ch_id = venc_comp->base_config.channel_id;
memset(&proc_ve_info, 0, sizeof(ve_proc_setting_info));
cedar_get_ve_setting_info(&proc_ve_info, ch_id);
if (proc_ve_info.bdynamic_set) {
if (proc_ve_info.weak_text_th != venc_comp->st_dynamic_proc_set.weak_text_th) {
LOCK_MUTEX(&venc_mutex);
venc_comp->st_dynamic_proc_set.weak_text_th = proc_ve_info.weak_text_th;
VencSetParameter(venc_comp->vencoder, VENC_IndexParamWeakTextTh, &proc_ve_info.weak_text_th);
RT_LOGW("change proc_ve_info.weak_text_th %f", proc_ve_info.weak_text_th);
UNLOCK_MUTEX(&venc_mutex);
}
cedar_close_ve_dynamic_setting(ch_id);
}
return 0;
}
static int thread_process_venc(void *param)
{
struct venc_comp_ctx *venc_comp = (struct venc_comp_ctx *)param;
message_t cmd_msg;
int result = 0;
video_frame_node *frame_node = NULL;
VencOutputBuffer out_buffer;
VencInputBuffer in_buf;
//int64_t time_start = 0;
//int64_t time_finish = 0;
video_frame_s cur_video_frame;
memset(&cur_video_frame, 0, sizeof(video_frame_s));
memset(&out_buffer, 0, sizeof(VencOutputBuffer));
RT_LOGS("channel_id %d thread_process_venc start !", venc_comp->base_config.channel_id);
while (1) {
process_message:
if (kthread_should_stop())
break;
if (get_message(&venc_comp->msg_queue, &cmd_msg) == 0) {
commond_process(venc_comp, &cmd_msg);
/* continue process message */
continue;
}
if (venc_comp->state == COMP_STATE_EXECUTING) {
/* get the ready frame */
#if TEST_ENCODER_BY_SELF
loop_encode_one_frame(venc_comp);
#else
#if DEBUG_SHOW_ENCODE_TIME
static int cnt_0 = 1;
if (cnt_0 && venc_comp->base_config.channel_id == 0) {
cnt_0 = 0;
RT_LOGW("channel %d first time in execution state, time: %lld", venc_comp->base_config.channel_id, get_cur_time());
}
static int cnt_01 = 1;
if (cnt_01 && venc_comp->base_config.channel_id == 1) {
cnt_01 = 0;
RT_LOGW("channel %d first time in execution state, time: %lld", venc_comp->base_config.channel_id, get_cur_time());
}
#endif
if (venc_comp->base_config.codec_type == RT_VENC_CODEC_JPEG
&& VencGetValidOutputBufNum(venc_comp->vencoder)) {
result = venc_comp_stream_buffer_to_valid_list(venc_comp, &out_buffer);
RT_LOGD("ValidOutputBufNum %d result %d", VencGetValidOutputBufNum(venc_comp->vencoder), result);
}
/* get frame from valid_list */
if (venc_comp->base_config.bOnlineChannel == 0) {
mutex_lock(&venc_comp->in_buf_manager.mutex);
if (list_empty(&venc_comp->in_buf_manager.valid_frame_list)) {
static int count;
if (count % 100 == 0)
RT_LOGD("valid frame list is null, wait for it start");
venc_comp->in_buf_manager.no_frame_flag = 1;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
TMessage_WaitQueueNotEmpty(&venc_comp->msg_queue, 200);
if (count % 100 == 0) {
RT_LOGD("valid frame list is null, wait for it finish");
}
count++;
goto process_message;
}
#if DEBUG_SHOW_ENCODE_TIME
static int cnt_1 = 1;
if (cnt_1 && venc_comp->base_config.channel_id == 0) {
cnt_1 = 0;
RT_LOGW("channel %d first time found valid frame buffer, time: %lld",
venc_comp->base_config.channel_id, get_cur_time());
}
static int cnt_11 = 1;
if (cnt_11 && venc_comp->base_config.channel_id == 1) {
cnt_11 = 0;
RT_LOGW("channel %d first time found valid frame buffer, time: %lld",
venc_comp->base_config.channel_id, get_cur_time());
}
#endif
frame_node = list_first_entry(&venc_comp->in_buf_manager.valid_frame_list, video_frame_node, mList);
memcpy(&cur_video_frame, &frame_node->video_frame, sizeof(video_frame_s));
list_move_tail(&frame_node->mList, &venc_comp->in_buf_manager.using_frame_list);
//venc_comp->in_buf_manager.empty_num++;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
if (0 == venc_comp->mActiveDropNum) {
/*process frame start*/
memset(&in_buf, 0, sizeof(VencInputBuffer));
in_buf.nID = cur_video_frame.id;
in_buf.nPts = cur_video_frame.pts;
in_buf.nFlag = 0;
in_buf.pAddrPhyY = (unsigned char *)cur_video_frame.phy_addr[0];
in_buf.pAddrPhyC = (unsigned char *)cur_video_frame.phy_addr[1];
in_buf.pAddrVirY = (unsigned char *)cur_video_frame.vir_addr[0];
in_buf.pAddrVirC = (unsigned char *)cur_video_frame.vir_addr[1];
if (venc_comp->base_config.s_crop_info.enable_crop) {
in_buf.bEnableCorp = venc_comp->base_config.s_crop_info.enable_crop;
in_buf.sCropInfo.nLeft = venc_comp->base_config.s_crop_info.s_crop_rect.nLeft;
in_buf.sCropInfo.nTop = venc_comp->base_config.s_crop_info.s_crop_rect.nTop;
in_buf.sCropInfo.nWidth = venc_comp->base_config.s_crop_info.s_crop_rect.nWidth;
in_buf.sCropInfo.nHeight = venc_comp->base_config.s_crop_info.s_crop_rect.nHeight;
RT_LOGI("Ryan should set crop: %d %d %d %d", in_buf.sCropInfo.nLeft, in_buf.sCropInfo.nTop,
in_buf.sCropInfo.nWidth, in_buf.sCropInfo.nHeight);
}
RT_LOGI("phyY = %p, phyC = %p, %p, %p", in_buf.pAddrPhyY, in_buf.pAddrPhyC,
in_buf.pAddrVirY, in_buf.pAddrVirC);
if (venc_comp->jpeg_cxt.enable == 1 && venc_comp->jpeg_cxt.encoder_finish_flag == 0) {
catch_jpeg_encoder(venc_comp, &in_buf);
}
result = VencQueueInputBuf(venc_comp->vencoder, &in_buf);
if (result != 0) {
RT_LOGE("fatal error! VencQueueInputBuf fail[%d]. must return frame", result);
venc_empty_in_buffer_done(venc_comp, &cur_video_frame);
mutex_lock(&venc_comp->in_buf_manager.mutex);
list_move_tail(&frame_node->mList, &venc_comp->in_buf_manager.empty_frame_list);
venc_comp->in_buf_manager.empty_num++;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
}
/* process frame end */
} else {
venc_empty_in_buffer_done(venc_comp, &cur_video_frame);
mutex_lock(&venc_comp->in_buf_manager.mutex);
list_move_tail(&frame_node->mList, &venc_comp->in_buf_manager.empty_frame_list);
venc_comp->in_buf_manager.empty_num++;
mutex_unlock(&venc_comp->in_buf_manager.mutex);
venc_comp->mActiveDropNum--;
RT_LOGD("vencChn[%d] actively drop one frame, left [%d]frames to drop", venc_comp->base_config.channel_id, venc_comp->mActiveDropNum);
}
#endif
}
/* get bitstream */
while (1) {
result = -1;
if (VencGetValidOutputBufNum(venc_comp->vencoder))
result = venc_comp_stream_buffer_to_valid_list(venc_comp, &out_buffer);
if (result != 0) {
break;
}
}
} else {
static int count = 0;
count++;
if (count % 50 == 0) {
RT_LOGD("TMessage_WaitQueueNotEmpty !");
}
TMessage_WaitQueueNotEmpty(&venc_comp->msg_queue, 200);
}
}
RT_LOGD("thread_process_venc finish !");
return 0;
}