3224 lines
114 KiB
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(¶m_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, ¶m_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;
|
|
}
|