[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: Yannick Fertre <yannick.fertre@st.com>
Signed-off-by: Jean-Christophe Trotin <jean-christophe.trotin@st.com>
Acked-by: Peter Griffin <peter.griffin@linaro.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Jean-Christophe Trotin 2016-09-05 11:06:30 -03:00 committed by Mauro Carvalho Chehab
parent 57b2c0628b
commit ba4616b7d9
4 changed files with 1189 additions and 7 deletions

View File

@ -1,2 +1,2 @@
obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o 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

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,8 @@
/* registry of available encoders */ /* registry of available encoders */
const struct hva_enc *hva_encoders[] = { const struct hva_enc *hva_encoders[] = {
&nv12h264enc,
&nv21h264enc,
}; };
static inline int frame_size(u32 w, u32 h, u32 fmt) 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: case V4L2_CID_MPEG_VIDEO_ASPECT:
ctx->ctrls.aspect = ctrl->val; ctx->ctrls.aspect = ctrl->val;
break; 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: default:
dev_dbg(dev, "%s S_CTRL: invalid control (id = %d)\n", dev_dbg(dev, "%s S_CTRL: invalid control (id = %d)\n",
ctx->name, ctrl->id); ctx->name, ctrl->id);
@ -628,8 +673,10 @@ static int hva_ctrls_setup(struct hva_ctx *ctx)
{ {
struct device *dev = ctx_to_dev(ctx); struct device *dev = ctx_to_dev(ctx);
u64 mask; 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_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
V4L2_CID_MPEG_VIDEO_BITRATE_MODE, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
@ -652,6 +699,66 @@ static int hva_ctrls_setup(struct hva_ctx *ctx)
mask, mask,
V4L2_MPEG_VIDEO_ASPECT_1x1); 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) { if (ctx->ctrl_handler.error) {
int err = ctx->ctrl_handler.error; int err = ctx->ctrl_handler.error;

View File

@ -23,6 +23,9 @@
#define HVA_PREFIX "[---:----]" #define HVA_PREFIX "[---:----]"
extern const struct hva_enc nv12h264enc;
extern const struct hva_enc nv21h264enc;
/** /**
* struct hva_frameinfo - information about hva frame * struct hva_frameinfo - information about hva frame
* *
@ -67,6 +70,17 @@ struct hva_streaminfo {
* @gop_size: groupe of picture size * @gop_size: groupe of picture size
* @bitrate: bitrate (in bps) * @bitrate: bitrate (in bps)
* @aspect: video aspect * @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 hva_controls {
struct v4l2_fract time_per_frame; struct v4l2_fract time_per_frame;
@ -74,6 +88,17 @@ struct hva_controls {
u32 gop_size; u32 gop_size;
u32 bitrate; u32 bitrate;
enum v4l2_mpeg_video_aspect aspect; 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;
}; };
/** /**