Skip to content

Commit

Permalink
media: coda: encoder parameter change support
Browse files Browse the repository at this point in the history
Add support for dynamically changing the GOP size, bitrate, frame rate,
constant intra quantization parameter, number of intra refresh macro
blocks and slice mode parameters.

Signed-off-by: Philipp Zabel <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
pH5 authored and mchehab committed Jun 24, 2019
1 parent 0414b47 commit b152a40
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
83 changes: 83 additions & 0 deletions drivers/media/platform/coda/coda-bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,79 @@ static u32 coda_slice_mode(struct coda_ctx *ctx)
((1 & CODA_SLICING_MODE_MASK) << CODA_SLICING_MODE_OFFSET);
}

static int coda_enc_param_change(struct coda_ctx *ctx)
{
struct coda_dev *dev = ctx->dev;
u32 change_enable = 0;
u32 success;
int ret;

if (ctx->params.gop_size_changed) {
change_enable |= CODA_PARAM_CHANGE_RC_GOP;
coda_write(dev, ctx->params.gop_size,
CODA_CMD_ENC_PARAM_RC_GOP);
ctx->gopcounter = ctx->params.gop_size - 1;
ctx->params.gop_size_changed = false;
}
if (ctx->params.h264_intra_qp_changed) {
coda_dbg(1, ctx, "parameter change: intra Qp %u\n",
ctx->params.h264_intra_qp);

if (ctx->params.bitrate) {
change_enable |= CODA_PARAM_CHANGE_RC_INTRA_QP;
coda_write(dev, ctx->params.h264_intra_qp,
CODA_CMD_ENC_PARAM_RC_INTRA_QP);
}
ctx->params.h264_intra_qp_changed = false;
}
if (ctx->params.bitrate_changed) {
coda_dbg(1, ctx, "parameter change: bitrate %u kbit/s\n",
ctx->params.bitrate);
change_enable |= CODA_PARAM_CHANGE_RC_BITRATE;
coda_write(dev, ctx->params.bitrate,
CODA_CMD_ENC_PARAM_RC_BITRATE);
ctx->params.bitrate_changed = false;
}
if (ctx->params.framerate_changed) {
coda_dbg(1, ctx, "parameter change: frame rate %u/%u Hz\n",
ctx->params.framerate & 0xffff,
(ctx->params.framerate >> 16) + 1);
change_enable |= CODA_PARAM_CHANGE_RC_FRAME_RATE;
coda_write(dev, ctx->params.framerate,
CODA_CMD_ENC_PARAM_RC_FRAME_RATE);
ctx->params.framerate_changed = false;
}
if (ctx->params.intra_refresh_changed) {
coda_dbg(1, ctx, "parameter change: intra refresh MBs %u\n",
ctx->params.intra_refresh);
change_enable |= CODA_PARAM_CHANGE_INTRA_MB_NUM;
coda_write(dev, ctx->params.intra_refresh,
CODA_CMD_ENC_PARAM_INTRA_MB_NUM);
ctx->params.intra_refresh_changed = false;
}
if (ctx->params.slice_mode_changed) {
change_enable |= CODA_PARAM_CHANGE_SLICE_MODE;
coda_write(dev, coda_slice_mode(ctx),
CODA_CMD_ENC_PARAM_SLICE_MODE);
ctx->params.slice_mode_changed = false;
}

if (!change_enable)
return 0;

coda_write(dev, change_enable, CODA_CMD_ENC_PARAM_CHANGE_ENABLE);

ret = coda_command_sync(ctx, CODA_COMMAND_RC_CHANGE_PARAMETER);
if (ret < 0)
return ret;

success = coda_read(dev, CODA_RET_ENC_PARAM_CHANGE_SUCCESS);
if (success != 1)
coda_dbg(1, ctx, "parameter change failed: %u\n", success);

return 0;
}

static phys_addr_t coda_iram_alloc(struct coda_iram_info *iram, size_t size)
{
phys_addr_t ret;
Expand Down Expand Up @@ -1143,6 +1216,9 @@ static int coda_start_encoding(struct coda_ctx *ctx)
}

if (ctx->params.bitrate) {
ctx->params.bitrate_changed = false;
ctx->params.h264_intra_qp_changed = false;

/* Rate control enabled */
value = (ctx->params.bitrate & CODA_RATECONTROL_BITRATE_MASK)
<< CODA_RATECONTROL_BITRATE_OFFSET;
Expand Down Expand Up @@ -1397,6 +1473,13 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
u32 rot_mode = 0;
u32 dst_fourcc;
u32 reg;
int ret;

ret = coda_enc_param_change(ctx);
if (ret < 0) {
v4l2_warn(&ctx->dev->v4l2_dev, "parameter change failed: %d\n",
ret);
}

src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
Expand Down
7 changes: 7 additions & 0 deletions drivers/media/platform/coda/coda-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,7 @@ static int coda_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
tpf = &a->parm.output.timeperframe;
coda_approximate_timeperframe(tpf);
ctx->params.framerate = coda_timeperframe_to_frate(tpf);
ctx->params.framerate_changed = true;

return 0;
}
Expand Down Expand Up @@ -2033,12 +2034,14 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_MPEG_VIDEO_BITRATE:
ctx->params.bitrate = ctrl->val / 1000;
ctx->params.bitrate_changed = true;
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
ctx->params.gop_size = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
ctx->params.h264_intra_qp = ctrl->val;
ctx->params.h264_intra_qp_changed = true;
break;
case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
ctx->params.h264_inter_qp = ctrl->val;
Expand Down Expand Up @@ -2086,17 +2089,21 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
ctx->params.slice_mode = ctrl->val;
ctx->params.slice_mode_changed = true;
break;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
ctx->params.slice_max_mb = ctrl->val;
ctx->params.slice_mode_changed = true;
break;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
ctx->params.slice_max_bits = ctrl->val * 8;
ctx->params.slice_mode_changed = true;
break;
case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
break;
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
ctx->params.intra_refresh = ctrl->val;
ctx->params.intra_refresh_changed = true;
break;
case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
ctx->params.force_ipicture = true;
Expand Down
7 changes: 7 additions & 0 deletions drivers/media/platform/coda/coda.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ struct coda_params {
u32 slice_max_bits;
u32 slice_max_mb;
bool force_ipicture;
bool gop_size_changed;
bool bitrate_changed;
bool framerate_changed;
bool h264_intra_qp_changed;
bool intra_refresh_changed;
bool slice_mode_changed;
};

struct coda_buffer_meta {
Expand Down Expand Up @@ -254,6 +260,7 @@ struct coda_ctx {
u32 bit_stream_param;
u32 frm_dis_flg;
u32 frame_mem_ctrl;
u32 para_change;
int display_idx;
struct dentry *debugfs_entry;
bool use_bit;
Expand Down
18 changes: 18 additions & 0 deletions drivers/media/platform/coda/coda_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,24 @@
#define CODA_CMD_ENC_SEQ_JPG_THUMB_SIZE 0x1a4
#define CODA_CMD_ENC_SEQ_JPG_THUMB_OFFSET 0x1a8

/* Encoder Parameter Change */
#define CODA_CMD_ENC_PARAM_CHANGE_ENABLE 0x180
#define CODA_PARAM_CHANGE_RC_GOP BIT(0)
#define CODA_PARAM_CHANGE_RC_INTRA_QP BIT(1)
#define CODA_PARAM_CHANGE_RC_BITRATE BIT(2)
#define CODA_PARAM_CHANGE_RC_FRAME_RATE BIT(3)
#define CODA_PARAM_CHANGE_INTRA_MB_NUM BIT(4)
#define CODA_PARAM_CHANGE_SLICE_MODE BIT(5)
#define CODA_PARAM_CHANGE_HEC_MODE BIT(6)
#define CODA_CMD_ENC_PARAM_RC_GOP 0x184
#define CODA_CMD_ENC_PARAM_RC_INTRA_QP 0x188
#define CODA_CMD_ENC_PARAM_RC_BITRATE 0x18c
#define CODA_CMD_ENC_PARAM_RC_FRAME_RATE 0x190
#define CODA_CMD_ENC_PARAM_INTRA_MB_NUM 0x194
#define CODA_CMD_ENC_PARAM_SLICE_MODE 0x198
#define CODA_CMD_ENC_PARAM_HEC_MODE 0x19c
#define CODA_RET_ENC_PARAM_CHANGE_SUCCESS 0x1c0

/* Encoder Picture Run */
#define CODA9_CMD_ENC_PIC_SRC_INDEX 0x180
#define CODA9_CMD_ENC_PIC_SRC_STRIDE 0x184
Expand Down

0 comments on commit b152a40

Please sign in to comment.