Commit 4b508ed1 authored by Michael Tretter's avatar Michael Tretter Committed by Mauro Carvalho Chehab
Browse files

media: allegro: create new struct for channel parameters



Add a new struct for the channel parameters that is contained in the
CREATE_CHANNEL message. This is in preparation for newer firmwares that
pass the channel parameters in a dedicated buffer instead of embedding
the parameters into the CREATE_CHANNEL message.

Signed-off-by: default avatarMichael Tretter <m.tretter@pengutronix.de>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 6412d226
Loading
Loading
Loading
Loading
+73 −61
Original line number Diff line number Diff line
@@ -859,80 +859,92 @@ static s16 get_qp_delta(int minuend, int subtrahend)
		return minuend - subtrahend;
}

static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
					   struct allegro_channel *channel)
static int fill_create_channel_param(struct allegro_channel *channel,
				     struct create_channel_param *param)
{
	struct mcu_msg_create_channel msg;
	int i_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_i_frame_qp);
	int p_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp);
	int b_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_b_frame_qp);
	int bitrate_mode = v4l2_ctrl_g_ctrl(channel->mpeg_video_bitrate_mode);

	param->width = channel->width;
	param->height = channel->height;
	param->format = v4l2_pixelformat_to_mcu_format(channel->pixelformat);
	param->colorspace =
		v4l2_colorspace_to_mcu_colorspace(channel->colorspace);
	param->src_mode = 0x0;
	param->profile = v4l2_profile_to_mcu_profile(channel->profile);
	param->constraint_set_flags = BIT(1);
	param->codec = v4l2_pixelformat_to_mcu_codec(channel->codec);
	param->level = v4l2_level_to_mcu_level(channel->level);
	param->tier = 0;
	param->sps_param = BIT(20) | 0x4a;
	param->pps_param = BIT(2);
	param->enc_option = AL_OPT_RDO_COST_MODE | AL_OPT_LF_X_TILE |
			    AL_OPT_LF_X_SLICE | AL_OPT_LF;
	param->beta_offset = -1;
	param->tc_offset = -1;
	param->num_slices = 1;
	param->me_range[0] = 8;
	param->me_range[1] = 8;
	param->me_range[2] = 16;
	param->me_range[3] = 16;
	param->max_cu_size = ilog2(SIZE_MACROBLOCK);
	param->min_cu_size = ilog2(8);
	param->max_tu_size = 2;
	param->min_tu_size = 2;
	param->max_transfo_depth_intra = 1;
	param->max_transfo_depth_inter = 1;

	param->prefetch_auto = 0;
	param->prefetch_mem_offset = 0;
	param->prefetch_mem_size = 0;

	param->rate_control_mode = channel->frame_rc_enable ?
		v4l2_bitrate_mode_to_mcu_mode(bitrate_mode) : 0;

	param->cpb_size = v4l2_cpb_size_to_mcu(channel->cpb_size,
					       channel->bitrate_peak);
	/* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */
	param->initial_rem_delay = param->cpb_size;
	param->framerate = DIV_ROUND_UP(channel->framerate.numerator,
					channel->framerate.denominator);
	param->clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000;
	param->target_bitrate = channel->bitrate;
	param->max_bitrate = channel->bitrate_peak;
	param->initial_qp = i_frame_qp;
	param->min_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_min_qp);
	param->max_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_max_qp);
	param->ip_delta = get_qp_delta(i_frame_qp, p_frame_qp);
	param->pb_delta = get_qp_delta(p_frame_qp, b_frame_qp);
	param->golden_ref = 0;
	param->golden_delta = 2;
	param->golden_ref_frequency = 10;
	param->rate_control_option = 0x00000000;

	param->gop_ctrl_mode = 0x00000000;
	param->freq_idr = channel->gop_size;
	param->freq_lt = 0;
	param->gdr_mode = 0x00000000;
	param->gop_length = channel->gop_size;
	param->subframe_latency = 0x00000000;

	return 0;
}

static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
					   struct allegro_channel *channel)
{
	struct mcu_msg_create_channel msg;

	memset(&msg, 0, sizeof(msg));

	msg.header.type = MCU_MSG_TYPE_CREATE_CHANNEL;
	msg.header.length = sizeof(msg) - sizeof(msg.header);

	msg.user_id = channel->user_id;
	msg.width = channel->width;
	msg.height = channel->height;
	msg.format = v4l2_pixelformat_to_mcu_format(channel->pixelformat);
	msg.colorspace = v4l2_colorspace_to_mcu_colorspace(channel->colorspace);
	msg.src_mode = 0x0;
	msg.profile = v4l2_profile_to_mcu_profile(channel->profile);
	msg.constraint_set_flags = BIT(1);
	msg.codec = v4l2_pixelformat_to_mcu_codec(channel->codec);
	msg.level = v4l2_level_to_mcu_level(channel->level);
	msg.tier = 0;
	msg.sps_param = BIT(20) | 0x4a;
	msg.pps_param = BIT(2);
	msg.enc_option = AL_OPT_RDO_COST_MODE | AL_OPT_LF_X_TILE |
			 AL_OPT_LF_X_SLICE | AL_OPT_LF;
	msg.beta_offset = -1;
	msg.tc_offset = -1;
	msg.num_slices = 1;
	msg.me_range[0] = 8;
	msg.me_range[1] = 8;
	msg.me_range[2] = 16;
	msg.me_range[3] = 16;
	msg.max_cu_size = ilog2(SIZE_MACROBLOCK);
	msg.min_cu_size = ilog2(8);
	msg.max_tu_size = 2;
	msg.min_tu_size = 2;
	msg.max_transfo_depth_intra = 1;
	msg.max_transfo_depth_inter = 1;

	if (channel->frame_rc_enable)
		msg.rate_control_mode =
			v4l2_bitrate_mode_to_mcu_mode(bitrate_mode);
	else
		msg.rate_control_mode = 0;

	msg.cpb_size = v4l2_cpb_size_to_mcu(channel->cpb_size,
					    channel->bitrate_peak);
	/* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */
	msg.initial_rem_delay = msg.cpb_size;
	msg.framerate = DIV_ROUND_UP(channel->framerate.numerator,
				     channel->framerate.denominator);
	msg.clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000;
	msg.target_bitrate = channel->bitrate;
	msg.max_bitrate = channel->bitrate_peak;
	msg.initial_qp = i_frame_qp;
	msg.min_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_min_qp);
	msg.max_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_max_qp);
	msg.ip_delta = get_qp_delta(i_frame_qp, p_frame_qp);
	msg.pb_delta = get_qp_delta(p_frame_qp, b_frame_qp);
	msg.golden_ref = 0;
	msg.golden_delta = 2;
	msg.golden_ref_frequency = 10;
	msg.rate_control_option = 0x00000000;

	msg.gop_ctrl_mode = 0x00000000;
	msg.freq_idr = channel->gop_size;
	msg.freq_lt = 0;
	msg.gdr_mode = 0x00000000;
	msg.gop_length = channel->gop_size;
	msg.subframe_latency = 0x00000000;
	fill_create_channel_param(channel, &msg.param);

	allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));
	allegro_mcu_interrupt(dev);
+7 −3
Original line number Diff line number Diff line
@@ -40,9 +40,7 @@ struct mcu_msg_init_response {
	u32 reserved0;
} __attribute__ ((__packed__));

struct mcu_msg_create_channel {
	struct mcu_msg_header header;
	u32 user_id;
struct create_channel_param {
	u16 width;
	u16 height;
	u32 format;
@@ -131,6 +129,12 @@ struct mcu_msg_create_channel {
	u32 unknown41;
} __attribute__ ((__packed__));

struct mcu_msg_create_channel {
	struct mcu_msg_header header;
	u32 user_id;
	struct create_channel_param param;
} __attribute__ ((__packed__));

struct mcu_msg_create_channel_response {
	struct mcu_msg_header header;
	u32 channel_id;