/* * Copyright 2015 Rockchip Electronics Co. LTD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __MPI_ENC_H__ #define __MPI_ENC_H__ #ifdef __cplusplus extern "C" { #endif #if defined(_WIN32) #include "vld.h" #endif #define MODULE_TAG "mpi_enc" #include #include #include #include #include #include //#include "mpp_env.h" //#include "mpp_mem.h" //#include "printf.h" //#include "mpp_time.h" #include "mpp_common.h" #if USE_RK_AISERVER #include "mpp_osd.h" #endif //#include "utils.h" #define BIT(n) (1<<(n)) #define MAX_FILE_NAME_LENGTH 256 #define RK_MPP_VERSION_DEFAULT 1 #define RK_MPP_USE_FULL_RANGE 0 #define RK_MPP_H264_FORCE_IDR_COUNT 5 #define RK_MPP_H264_FORCE_IDR_PERIOD 5 //must >=1 #define RK_MPP_ENC_TEST_NATIVE 0 #define RK_MPP_USE_ZERO_COPY 1 #if RK_MPP_USE_ZERO_COPY #if !RK_MPP_ENC_TEST_NATIVE #define RK_MPP_USE_UVC_VIDEO_BUFFER #endif extern struct uvc_encode uvc_enc; #endif #define RK_MPP_DYNAMIC_DEBUG_ON 1 //release version can set to 0 #define RK_MPP_RANGE_DEBUG_ON 1 //release version can set to 0 #define RK_MPP_DYNAMIC_DEBUG_OUT_CHECK "/tmp/uvc_enc_out" #define RK_MPP_DYNAMIC_DEBUG_IN_CHECK "/tmp/uvc_enc_in" //open it will lower the fps #define RK_MPP_RANGE_DEBUG_IN_CHECK "/tmp/uvc_range_in" #define RK_MPP_OUT_LEN_DEBUG_CHECK "/tmp/uvc_out_len" #define RK_MPP_CLOSE_FRM_LOSS_DEBUG_CHECK "/tmp/uvc_frm_loss" #define RK_MPP_ENABLE_UVC_H265 "/tmp/use_encodec_h265" #define RK_MPP_DEBUG_OUT_FILE "/uvc_enc_out.bin" #define RK_MPP_DEBUG_IN_FILE "/uvc_enc_in.bin" #define RK_MPP_ENC_CFG_ORIGINAL_PATH "/etc/mpp_enc_cfg.conf" #define RK_MPP_ENC_CFG_MODIFY_PATH "/data/mpp_enc_cfg.conf" #ifdef USE_ARM64 #define RK_MPP_MJPEG_FPS_CONTROL 0 #else #define RK_MPP_MJPEG_FPS_CONTROL 1 #endif //#define DEBUG_OUTPUT 1 #if RK_MPP_ENC_TEST_NATIVE extern struct uvc_encode uvc_enc; extern int uvc_encode_init(struct uvc_encode *e, int width, int height, int fcc, int h265, unsigned int fps); #define TEST_ENC_TPYE V4L2_PIX_FMT_H264 //V4L2_PIX_FMT_MJPEG #endif #define MPP_ENC_CFG_MIN_FPS 0 // 0 means use host set fps #define MPP_ENC_CFG_MAX_FPS 100 #define MPP_ENC_CFG_MIN_BPS 2 * 1000 #define MPP_ENC_CFG_MAX_BPS 98 * 1000 * 1000 #define MPP_ENC_MJPEG_CFG_MAX_BPS 150 * 1024 * 1024 #define MPP_ENC_CFG_H264_DEFAULT_PROFILE 100 #define MPP_ENC_CFG_H264_DEFAULT_LEVEL 40 #define MPP_ENC_MJPEG_FRC_USE_MPP 0 //**********for simple frc************// #define MJPEG_FRC_BPS_MAX 150*1024*1024 #define MJPEG_FRC_BPS_MIN 100*1024*1024 #define MJPEG_FRC_BPS_PER_STEP 1*1024*1024 #define MJPEG_FRC_QUANT_MAX 10 #define MJPEG_FRC_QUANT_MIN 6 #define MJPEG_FRC_QFACTOR_MAX 99 #define MJPEG_FRC_QFACTOR_MIN 70 #define MPP_FRC_WAIT_TIME_MS 2 #define MPP_FRC_WAIT_TIME_US (MPP_FRC_WAIT_TIME_MS * 1000) #define MPP_FRC_WAIT_COUNT_MIN (18 / MPP_FRC_WAIT_TIME_MS) // in high resolution, the frame rate is not enough to lower this #define MPP_MJPEG_HIGH_FPS_FRC_WAIT_COUNT_MIN (6 / MPP_FRC_WAIT_TIME_MS) // in high resolution, the frame rate is not enough to lower this #define MPP_FRC_UP_FRM_SET_INIT 1000 #define MPP_FRC_UP_FRM_SET_MIN MPP_FRC_UP_FRM_SET_INIT #define MPP_FRC_UP_FRM_SET_MAX 0x40000000 #define MPP_FRC_WAIT_COUNT_OFFSET 5 // bit rate control is too low to increase this //***************ROI*********************// #define MPP_ENC_ROI_ENABLE 1 #define UPALIGNTO(value, align) ((value + align - 1) & (~(align - 1))) #define UPALIGNTO16(value) UPALIGNTO(value, 16) #define VALUE_SCOPE_CHECK(X, MIN, MAX) assert((X >= MIN) && (X <= MAX)) typedef struct { uint16_t x; /**< horizontal position of top left corner */ uint16_t y; /**< vertical position of top left corner */ uint16_t w; /**< width of ROI rectangle */ uint16_t h; /**< height of ROI rectangle */ uint16_t intra; /**< flag of forced intra macroblock */ int16_t quality; /**< qp of macroblock */ uint16_t qp_area_idx; /**< qp min max area select*/ uint8_t area_map_en; /**< enable area map */ uint8_t abs_qp_en; /**< absolute qp enable flag*/ } EncROIRegion; //***************GOP MODE*********************// typedef enum { GOP_MODE_NORMALP = 0, // normal p mode GOP_MODE_TSVC2, // tsvc: 2 layer GOP_MODE_TSVC3, // tsvc: 3 layer GOP_MODE_TSVC4, // tsvc: 4 layer GOP_MODE_SMARTP, // smart p mode } MpiEncGopMode; //************************************// enum SIMPLE_FRC_MODE { FRC_OFF = 0, FRC_ONLY_LOW, FRC_BOTH_UP_LOW, }; //**********************// typedef struct { MppCodingType type; RK_U32 width; RK_U32 height; MppFrameFormat format; RK_U32 debug; RK_U32 num_frames; RK_U32 fps; RK_U32 have_output; } MpiEncTestCmd; typedef struct { RK_U32 init; RK_U32 max; RK_U32 min; RK_U32 step; RK_U32 max_i_qp; RK_U32 min_i_qp; } MpiEncQqCfg; /********************do not change the order below*******************/ #define MPP_ENC_CFG_CHANGE_BIT(x) (1 << x) #define MPP_STREAM_SAVE_DIR_LEN 32 typedef struct { RK_U32 change; RK_U32 fbc; RK_U32 split_mode;// 1 RK_U32 split_arg;// 2 RK_U32 force_idr_count; // 3 RK_U32 force_idr_period;// 4 RK_U32 frc_fps;// 5 enum SIMPLE_FRC_MODE frc_mode; // 6 MppEncRotationCfg rotation;// 7 RK_U32 enc_time; RK_U32 try_count; } MpiEncCommonCfg; typedef struct { RK_U32 change; RK_U32 frc_quant; // RK_S32 frc_qfactor; // RK_U32 frc_bps; RK_U32 quant; //bit0 1- 10 default:7 MppFrameColorRange range; // bit1 full:MPP_FRAME_RANGE_JPEG limit:MPP_FRAME_RANGE_MPEG; RK_U32 qfactor; // bit2 0-99 priprity option this. set 0 is close this and set use quant RK_S32 qfactor_min; // 3 RK_S32 qfactor_max; // 4 RK_U32 gop; // 5 MppEncRcMode rc_mode; // 6 RK_U32 bps; // 7 RK_U32 framerate; // 8 RK_U32 enc_mode; //enc_mode no have change bit 0:mean auto select 1:close the mjpeg_frc 2: use mjpeg_frc RK_U32 qfactor_frc_min; MppEncSeiMode sei; // 11 } MpiEncMjpegCfg; typedef struct { RK_U32 change; RK_U32 gop; //0 RK_U32 gop_normal; //0 MppEncRcMode rc_mode; RK_U32 framerate; ////simple to set. MppFrameColorRange range; // full: MPP_FRAME_RANGE_JPEG limit:MPP_FRAME_RANGE_MPEG; MppEncHeaderMode head_each_idr; MppEncSeiMode sei;//5 MpiEncQqCfg qp;//6-9 RK_U32 profile;//10 RK_U32 cabac_en; RK_U32 cabac_idc; RK_U32 trans_8x8;// RK_U32 level; RK_U32 bps;//15 RK_U32 idr_bps;//16 RK_U32 vi_len;//17 MpiEncGopMode gop_mode; //18 } MpiEncH264Cfg; typedef struct { RK_U32 change; RK_U32 gop; //0 RK_U32 gop_normal; //0 MppEncRcMode rc_mode; RK_U32 framerate; MppFrameColorRange range; //full: MPP_FRAME_RANGE_JPEG limit:MPP_FRAME_RANGE_MPEG; MppEncHeaderMode head_each_idr; MppEncSeiMode sei;//5 MpiEncQqCfg qp;//6-11 RK_U32 bps;//12 RK_U32 idr_bps;//13 RK_U32 vi_len;//14 MpiEncGopMode gop_mode; // 15 } MpiEncH265Cfg; #if MPP_ENC_OSD_ENABLE #define MPP_ENC_OSD_IMAGE_PATH_LEN 32 typedef struct { bool set_ok; bool enable; //dynamic on/off set this enum OSD_REGION_TYPE type; RK_U32 start_x; RK_U32 start_y; char image_path[MPP_ENC_OSD_IMAGE_PATH_LEN];//*image_path;// // for mjpeg rga osd RK_U32 width; RK_U32 height; int rga_osd_fd; unsigned int handle; // for drm handle uint8_t *buffer; int drm_size; // for mjpeg rga osd } MpiEncOSDCfg; #endif /***************************o not change the order above**************************************/ typedef struct MppBuffNode { MppFrame frame; MppPacket packet; MppBuffer buf; MppBuffer pkt_buf_out; int buf_fd; bool init; } MppBuffInfo; #define IN_BUF_COUNT_MAX 10 #define OUT_BUF_COUNT_MAX 3 #if RK_MPP_MJPEG_FPS_CONTROL #define MJPEG_FPS_CONTROL_V2 1 #endif typedef struct { #if RK_MPP_MJPEG_FPS_CONTROL void *fps_handle; #endif RK_U32 fps; RK_U32 loss_frm; RK_U32 continuous_frm; RK_U32 frc_up_frm_set; bool set_frc_low; bool fps_ctr_enable; MpiEncCommonCfg common_cfg; MpiEncMjpegCfg mjpeg_cfg; MpiEncH264Cfg h264_cfg; MpiEncH265Cfg h265_cfg; // global flow control flag RK_U32 frm_eos; RK_U32 pkt_eos; RK_U32 frame_count; RK_U64 stream_size; #if RK_MPP_RANGE_DEBUG_ON #define RANGE_PATH_MAX_LEN 128 FILE *fp_range_path; FILE *fp_range_file; char *range_path; #endif // src and dst FILE *fp_input; FILE *fp_output; char streamin_save_dir[MPP_STREAM_SAVE_DIR_LEN]; char streamout_save_dir[MPP_STREAM_SAVE_DIR_LEN]; // base flow context MppCtx ctx; MppApi *mpi; RK_U32 use_legacy_cfg; MppEncCfg cfg; MppEncPrepCfg prep_cfg; MppEncRcCfg rc_cfg; MppEncCodecCfg codec_cfg; MppEncSliceSplit split_cfg; #if MPP_ENC_OSD_ENABLE /* * osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). * for general use, 1/8 Y buffer is enough. */ MppEncOSDPltCfg osd_plt_cfg; MppEncOSDPlt osd_plt; MppEncOSDData osd_data; MppBuffer osd_idx_buf; size_t osd_idx_size; RK_U32 osd_count; bool osd_enable; bool osd_plt_user; bool osd_index_enable[OSD_REGIONS_CNT]; MpiEncOSDCfg osd_cfg[OSD_REGIONS_CNT]; RK_U32 plt_table[PALETTE_TABLE_LEN]; //ayuv map int rga_osd_drm_fd; #endif #if MPP_ENC_ROI_ENABLE RK_U32 roi_enable; RK_U32 roi_number; MppEncROIRegion *roi_region; MppEncROICfg roi_cfg; #endif // input / output MppBuffer frm_buf; MppEncSeiMode sei_mode; MppEncHeaderMode header_mode; // paramter for resource malloc RK_U32 width; RK_U32 height; RK_U32 hor_stride; RK_U32 ver_stride; MppFrameFormat fmt; MppCodingType type; RK_S32 num_frames; RK_S32 loop_times; // resources size_t header_size; size_t frame_size; /* NOTE: packet buffer may overflow */ size_t packet_size; RK_U32 split_mode; RK_U32 split_arg; RK_U32 user_data_enable; // rate control runtime parameter RK_S32 gop; RK_S32 fps_in_flex; RK_S32 fps_in_den; RK_S32 fps_in_num; RK_S32 fps_out_flex; RK_S32 fps_out_den; RK_S32 fps_out_num; RK_S32 bps; MppFrame frame; MppPacket packet; void *enc_data; size_t enc_len; RK_U32 enc_version; RK_U32 h2645_frm_count; #if RK_MPP_USE_ZERO_COPY MppBufferGroup pkt_grp; MppBuffer pkt_buf; #endif pthread_t check_cfg_change_hd; int cfg_notify_fd; int cfg_notify_wd; MppBuffInfo out_buff_info[OUT_BUF_COUNT_MAX]; MppBuffInfo in_buff_info[IN_BUF_COUNT_MAX]; int yuv_rotation_drm_fd; int yuv_rotation_fd; unsigned int yuv_rotation_handle; // for drm handle int yuv_rotation_drm_size; MppEncUserData user_data; } MpiEncTestData; typedef struct MPP_ENC_INFO { int fd; size_t size; RK_U32 pts; RK_U32 seq; } MPP_ENC_INFO_DEF; MPP_RET mpi_enc_test_init(MpiEncTestCmd *cmd, MpiEncTestData **data); MPP_RET mpi_enc_test_run(MpiEncTestData **data, MPP_ENC_INFO_DEF *info); MPP_RET mpi_enc_test_deinit(MpiEncTestData **data); MPP_RET mpi_enc_inbuf_deinit(MpiEncTestData *data); void mpi_enc_cmd_config(MpiEncTestCmd *cmd, int width, int height, int fcc, int h265, unsigned int fps); void mpi_enc_cmd_config_mjpg(MpiEncTestCmd *cmd, int width, int height); void mpi_enc_cmd_config_h264(MpiEncTestCmd *cmd, int width, int height); void mpi_enc_set_format(MppFrameFormat format); int mpi_enc_get_h264_extra(MpiEncTestData *p, void *buffer, size_t *size); RK_S32 mpi_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value); MPP_RET mpp_enc_cfg_set_s32(MppEncCfg cfg, const char *name, RK_S32 val); MPP_RET mpp_enc_cfg_set_u32(MppEncCfg cfg, const char *name, RK_U32 val); MPP_RET mpp_enc_cfg_set_s64(MppEncCfg cfg, const char *name, RK_S64 val); MPP_RET mpp_enc_cfg_set_u64(MppEncCfg cfg, const char *name, RK_U64 val); MPP_RET mpp_enc_cfg_set_ptr(MppEncCfg cfg, const char *name, void *val); MPP_RET mpp_enc_cfg_get_s32(MppEncCfg cfg, const char *name, RK_S32 *val); MPP_RET mpp_enc_cfg_get_u32(MppEncCfg cfg, const char *name, RK_U32 *val); MPP_RET mpp_enc_cfg_get_s64(MppEncCfg cfg, const char *name, RK_S64 *val); MPP_RET mpp_enc_cfg_get_u64(MppEncCfg cfg, const char *name, RK_U64 *val); #ifdef RK_MPP_USE_UVC_VIDEO_BUFFER struct uvc_buffer *uvc_buffer_write_get(int id); void uvc_buffer_read_set(int id, struct uvc_buffer *buf); void uvc_user_lock(); void uvc_user_unlock(); struct uvc_buffer *uvc_buffer_write_get_nolock(int id); void uvc_buffer_read_set_nolock(int id, struct uvc_buffer *buf); #endif #ifdef __cplusplus } #endif #endif