上篇博文硬件视频编码,在默认参数设置后,编码1000帧640x480 H264文件大小为180m左右,非常大,必须设置参数
测试发现再使能EnableMBRateControl后,编码数据才开始大幅缩小:
这里先将54个控制参数全部初始化 -1,在这54个参数中,包含H264,H263和MPEG视频格式的设置,对每个视频格式仅仅选择对应他的参数即可。这里仅仅测试H264格式
所有控制参数如下:
struct {
int num;
int id;
char *name;
int value;
} ctrls[] = {
{0, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, "force_frame", -1},
{1, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, "frame_skip_mode", -1},
{2, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY, "h264_arc_activity", -1},
{3, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK, "h264_arc_dark", -1},
{4, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH, "h264_arc_smooth", -1},
{5, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC, "h264_arc_static", -1},
{6, V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P, "h264_ref_pic", -1},
{7, V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV, "padding_yuv", -1},
{8, V4L2_CID_MPEG_MFC51_VIDEO_PADDING, "padding"},
{9, V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT, "rc_fixed_target_bit", -1},
{10, V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF, "rc_react_coeff", -1},
{11, V4L2_CID_MPEG_VIDEO_B_FRAMES, "b_frames", -1},
{12, V4L2_CID_MPEG_VIDEO_BITRATE, "bitrate", -1},
{13, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, "intra_refresh_mb", -1},
{14, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, "rc_enable", -1},
{15, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, "gop_closure", -1},
{16, V4L2_CID_MPEG_VIDEO_GOP_SIZE, "gop_size", -1},
{17, V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP, "h263_b_qp", -1},
{18, V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP, "h263_i_qp", -1},
{19, V4L2_CID_MPEG_VIDEO_H263_MAX_QP, "h263_max_qp", -1},
{20, V4L2_CID_MPEG_VIDEO_H263_MIN_QP, "h263_min_qp", -1},
{21, V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, "h263_p_qp"},
{22, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, "h264_8x8_transform", -1},
{23, V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, "h264_b_qp", -1},
{24, V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, "h264_cpb_size", -1},
{25, V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, "h264_entropy", -1},
{26, V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, "h264_i_qp", -1},
{27, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, "h264_i_period", -1},
{28, V4L2_CID_MPEG_VIDEO_H264_LEVEL, "h264_level", -1},
{29, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, "h264_loop_filter_alpha", -1},
{30, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, "h264_loop_filter_beta", -1},
{31, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, "h264_loop_filter_mode", -1},
{32, V4L2_CID_MPEG_VIDEO_H264_MAX_QP, "h264_max_qp", -1},
{33, V4L2_CID_MPEG_VIDEO_H264_MIN_QP, "h264_min_qp", -1},
{34, V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, "h264_p_qp", -1},
{35, V4L2_CID_MPEG_VIDEO_H264_PROFILE, "h264_profile", -1},
{36, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT, "h264_vui_sar_height", -1},
{37, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH, "h264_vui_sar_width", -1},
{38, V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, "h264_vui_sar", -1},
{39, V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC, "h264_vui_sar_idc", -1},
{40, V4L2_CID_MPEG_VIDEO_HEADER_MODE, "header_mode", -1},
{41, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, "mb_rc", -1},
{42, V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP, "mpeg4_b_qp", -1},
{43, V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, "mpeg4_i_qp", -1},
{44, V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, "mpeg4_level", -1},
{45, V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP, "mpeg4_max_qp", -1},
{46, V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP, "mpeg4_min_qp", -1},
{47, V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, "mpeg4_p_qp", -1},
{48, V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, "mpeg4_profile", -1},
{49, V4L2_CID_MPEG_VIDEO_MPEG4_QPEL, "mpeg4_qpel", -1},
{50, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, "slice_max_bytes", -1},
{51, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, "slice_max_mb", -1},
{52, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, "slice_mode", -1},
{53, V4L2_CID_MPEG_VIDEO_VBV_SIZE, "vbv_size", -1},
};
static int mfc_set_control(struct io_dev *dev, int id, int value)
{
struct v4l2_ext_control ctrl;
struct v4l2_ext_controls ctrl_s;
int ret;
ctrl.id = id;
ctrl.value = value;
ctrl_s.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ctrl_s.count = 1;
ctrl_s.controls = &ctrl;
ret = ioctl(dev->fd, VIDIOC_S_EXT_CTRLS, &ctrl_s);
if (ret < 0)
err("Cannot set control %d to %d on %d", id, value, dev->fd);
return ret;
}
H264初始化参数如下:
int h264_param_init(struct io_dev *dev)
{
int i;
ctrls[2].value = 1; //h264_arc_activity, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY, ActivityDisable
ctrls[3].value = 1; //h264_arc_dark, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK, DarkDisable
ctrls[4].value = 1; //h264_arc_smooth, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH, SmoothDisable
ctrls[5].value = 1; //h264_arc_static, V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC, StaticDisable
ctrls[6].value = 2; //h264_ref_pic, V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P, NumberRefForPframes
ctrls[7].value = 0; //padding_yuv, V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV, LumaPadVal, CbPadVal, CrPadVal,
ctrls[8].value = 1; //padding, V4L2_CID_MPEG_MFC51_VIDEO_PADDING, PadControlOn
ctrls[10].value = 120; //rc_react_coeff, V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF, CBRPeriodRf
ctrls[11].value = 2; //b_frames, V4L2_CID_MPEG_VIDEO_B_FRAMES, NumberBFrames(0~2)
ctrls[12].value = 128000; //bitrate, V4L2_CID_MPEG_VIDEO_BITRATE, Bitrate
ctrls[13].value = 0; //intra_refresh_mb, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, RandomIntraMBRefresh
ctrls[14].value = 0; //rc_enable, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, NumberReferenceFrames
ctrls[22].value = 0; //h264_8x8_transform, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, Transform8x8Mode
ctrls[26].value = 20; //h264_i_qp, V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, FrameQp
ctrls[21].value = 20; //h263_p_qp, V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, FrameQp_P
ctrls[23].value = 20; //h264_b_qp, V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, FrameQp_B
ctrls[25].value = 1; //h264_entropy, V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, SymbolMode
ctrls[27].value = 100; //h264_i_period, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod
ctrls[28].value = 11; //h264_level, V4L2_CID_MPEG_VIDEO_H264_LEVEL, 40 LevelIDC
ctrls[29].value = 0; //h264_loop_filter_alpha, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, LoopFilterAlphaC0Offset
ctrls[30].value = 0; //h264_loop_filter_beta, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, LoopFilterBetaOffset
ctrls[31].value = 1; //h264_loop_filter_mode, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, LoopFilterDisable
ctrls[32].value = 51; //h264_max_qp, V4L2_CID_MPEG_VIDEO_H264_MAX_QP, QSCodeMax
ctrls[33].value = 10; //h264_min_qp, V4L2_CID_MPEG_VIDEO_H264_MIN_QP, QSCodeMin
ctrls[35].value = 4; //h264_profile, V4L2_CID_MPEG_VIDEO_H264_PROFILE, ProfileIDC
ctrls[41].value = 1; //mb_rc, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, EnableMBRateControl
ctrls[50].value = 1900; //slice_max_bytes, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, ?????
ctrls[51].value = 1; //slice_max_mb, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, SliceArgument
ctrls[52].value = 0; //slice_mode, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, SliceMode
for (i = 0; i < array_len(ctrls); ++i) {
if(ctrls[i].value != -1)
if(mfc_set_control(dev, ctrls[i].id, ctrls[i].value) < 0) {
err("param:%s error", ctrls[i].name);
return -1;
}
}
return 0;
}
经过测试
640x480 H264 1000帧编码后生成文件为4.6M
1920x1080 H264 1000帧编码后生成文件为29.6M