Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba4616b7 authored by Jean-Christophe Trotin's avatar Jean-Christophe Trotin Committed by Mauro Carvalho Chehab
Browse files

[media] st-hva: add H.264 video encoding support



This patch adds the H.264 video encoding capability in the V4L2 HVA
video encoder driver for STMicroelectronics SoC (hva-h264.c).

The main supported features are:
- profile: baseline, main, high, stereo high
- level: up to 4.2
- bitrate mode: CBR, VBR
- entropy mode: CABAC, CAVLC
- video aspect: 1x1 only

Signed-off-by: default avatarYannick Fertre <yannick.fertre@st.com>
Signed-off-by: default avatarJean-Christophe Trotin <jean-christophe.trotin@st.com>
Acked-by: default avatarPeter Griffin <peter.griffin@linaro.org>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 57b2c062
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o
st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o
st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o
+1050 −0

File added.

Preview size limit exceeded, changes collapsed.

+108 −1
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@

/* registry of available encoders */
const struct hva_enc *hva_encoders[] = {
	&nv12h264enc,
	&nv21h264enc,
};

static inline int frame_size(u32 w, u32 h, u32 fmt)
@@ -610,6 +612,49 @@ static int hva_s_ctrl(struct v4l2_ctrl *ctrl)
	case V4L2_CID_MPEG_VIDEO_ASPECT:
		ctx->ctrls.aspect = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
		ctx->ctrls.profile = ctrl->val;
		if (ctx->flags & HVA_FLAG_STREAMINFO)
			snprintf(ctx->streaminfo.profile,
				 sizeof(ctx->streaminfo.profile),
				 "%s profile",
				 v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
		break;
	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
		ctx->ctrls.level = ctrl->val;
		if (ctx->flags & HVA_FLAG_STREAMINFO)
			snprintf(ctx->streaminfo.level,
				 sizeof(ctx->streaminfo.level),
				 "level %s",
				 v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
		break;
	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
		ctx->ctrls.entropy_mode = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
		ctx->ctrls.cpb_size = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
		ctx->ctrls.dct8x8 = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
		ctx->ctrls.qpmin = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
		ctx->ctrls.qpmax = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
		ctx->ctrls.vui_sar = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
		ctx->ctrls.vui_sar_idc = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
		ctx->ctrls.sei_fp = ctrl->val;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
		ctx->ctrls.sei_fp_type = ctrl->val;
		break;
	default:
		dev_dbg(dev, "%s S_CTRL: invalid control (id = %d)\n",
			ctx->name, ctrl->id);
@@ -628,8 +673,10 @@ static int hva_ctrls_setup(struct hva_ctx *ctx)
{
	struct device *dev = ctx_to_dev(ctx);
	u64 mask;
	enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_type =
		V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM;

	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 15);

	v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
			       V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
@@ -652,6 +699,66 @@ static int hva_ctrls_setup(struct hva_ctx *ctx)
			       mask,
			       V4L2_MPEG_VIDEO_ASPECT_1x1);

	mask = ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
		 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
		 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
		 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH));
	v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
			       V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH,
			       mask,
			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);

	v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,
			       V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
			       0,
			       V4L2_MPEG_VIDEO_H264_LEVEL_4_0);

	v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
			       V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
			       V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
			       0,
			       V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC);

	v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
			  V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
			  1, 10000, 1, 3000);

	v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
			  V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
			  0, 1, 1, 0);

	v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
			  V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
			  0, 51, 1, 5);

	v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
			  V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
			  0, 51, 1, 51);

	v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
			  V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
			  0, 1, 1, 1);

	mask = ~(1 << V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
	v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
			       V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1,
			       mask,
			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);

	v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
			  V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING,
			  0, 1, 1, 0);

	mask = ~(1 << sei_fp_type);
	v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
			       V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE,
			       sei_fp_type,
			       mask,
			       sei_fp_type);

	if (ctx->ctrl_handler.error) {
		int err = ctx->ctrl_handler.error;

+30 −5
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@

#define HVA_PREFIX "[---:----]"

extern const struct hva_enc nv12h264enc;
extern const struct hva_enc nv21h264enc;

/**
 * struct hva_frameinfo - information about hva frame
 *
@@ -67,6 +70,17 @@ struct hva_streaminfo {
 * @gop_size:       groupe of picture size
 * @bitrate:        bitrate (in bps)
 * @aspect:         video aspect
 * @profile:        H.264 profile
 * @level:          H.264 level
 * @entropy_mode:   H.264 entropy mode (CABAC or CVLC)
 * @cpb_size:       coded picture buffer size (in kB)
 * @dct8x8:         transform mode 8x8 enable
 * @qpmin:          minimum quantizer
 * @qpmax:          maximum quantizer
 * @vui_sar:        pixel aspect ratio enable
 * @vui_sar_idc:    pixel aspect ratio identifier
 * @sei_fp:         sei frame packing arrangement enable
 * @sei_fp_type:    sei frame packing arrangement type
 */
struct hva_controls {
	struct v4l2_fract					time_per_frame;
@@ -74,6 +88,17 @@ struct hva_controls {
	u32							gop_size;
	u32							bitrate;
	enum v4l2_mpeg_video_aspect				aspect;
	enum v4l2_mpeg_video_h264_profile			profile;
	enum v4l2_mpeg_video_h264_level				level;
	enum v4l2_mpeg_video_h264_entropy_mode			entropy_mode;
	u32							cpb_size;
	bool							dct8x8;
	u32							qpmin;
	u32							qpmax;
	bool							vui_sar;
	enum v4l2_mpeg_video_h264_vui_sar_idc			vui_sar_idc;
	bool							sei_fp;
	enum v4l2_mpeg_video_h264_sei_fp_arrangement_type	sei_fp_type;
};

/**