#include "vicodec-codec.h"
#define ALL_ZEROS 15
-#define DEADZONE_WIDTH 20
static const uint8_t zigzag[64] = {
0,
3, 3, 3, 6, 6, 9, 9, 10,
};
-static void quantize_intra(s16 *coeff, s16 *de_coeff)
+static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp)
{
const int *quant = quant_table;
int i, j;
for (j = 0; j < 8; j++) {
for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
*coeff >>= *quant;
- if (*coeff >= -DEADZONE_WIDTH &&
- *coeff <= DEADZONE_WIDTH)
+ if (*coeff >= -qp && *coeff <= qp)
*coeff = *de_coeff = 0;
else
*de_coeff = *coeff << *quant;
*coeff <<= *quant;
}
-static void quantize_inter(s16 *coeff, s16 *de_coeff)
+static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp)
{
const int *quant = quant_table_p;
int i, j;
for (j = 0; j < 8; j++) {
for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
*coeff >>= *quant;
- if (*coeff >= -DEADZONE_WIDTH &&
- *coeff <= DEADZONE_WIDTH)
+ if (*coeff >= -qp && *coeff <= qp)
*coeff = *de_coeff = 0;
else
*de_coeff = *coeff << *quant;
deltablock, width, input_step);
if (is_intra || blocktype == IBLOCK) {
fwht(input, cf->coeffs, width, input_step, 1);
- quantize_intra(cf->coeffs, cf->de_coeffs);
+ quantize_intra(cf->coeffs, cf->de_coeffs,
+ cf->i_frame_qp);
blocktype = IBLOCK;
} else {
/* inter code */
encoding |= FRAME_PCODED;
fwht16(deltablock, cf->coeffs, 8, 0);
- quantize_inter(cf->coeffs, cf->de_coeffs);
+ quantize_inter(cf->coeffs, cf->de_coeffs,
+ cf->p_frame_qp);
}
if (!next_is_intra) {
ifwht(cf->de_coeffs, cf->de_fwht, blocktype);
spinlock_t *lock;
struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *ctrl_gop_size;
unsigned int gop_size;
unsigned int gop_cnt;
+ u16 i_frame_qp;
+ u16 p_frame_qp;
/* Abort requested by m2m */
int aborting;
cf.width = q_data->width;
cf.height = q_data->height;
+ cf.i_frame_qp = ctx->i_frame_qp;
+ cf.p_frame_qp = ctx->p_frame_qp;
cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr));
encoding = encode_frame(&rf, &ctx->ref_frame, &cf, !ctx->gop_cnt,
ctx->gop_cnt == ctx->gop_size - 1);
if (encoding != FRAME_PCODED)
ctx->gop_cnt = 0;
- if (++ctx->gop_cnt == ctx->gop_size)
+ if (++ctx->gop_cnt >= ctx->gop_size)
ctx->gop_cnt = 0;
p_hdr = (struct cframe_hdr *)p_out;
ctx->ref_frame.cr = ctx->ref_frame.cb + size / 4;
ctx->last_src_buf = NULL;
ctx->last_dst_buf = NULL;
- v4l2_ctrl_grab(ctx->ctrl_gop_size, true);
- ctx->gop_size = v4l2_ctrl_g_ctrl(ctx->ctrl_gop_size);
ctx->gop_cnt = 0;
ctx->cur_buf_offset = 0;
ctx->comp_size = 0;
kvfree(ctx->ref_frame.luma);
kvfree(ctx->compressed_frame);
- v4l2_ctrl_grab(ctx->ctrl_gop_size, false);
}
static const struct vb2_ops vicodec_qops = {
return vb2_queue_init(dst_vq);
}
+#define VICODEC_CID_CUSTOM_BASE (V4L2_CID_MPEG_BASE | 0xf000)
+#define VICODEC_CID_I_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 0)
+#define VICODEC_CID_P_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 1)
+
+static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vicodec_ctx *ctx = container_of(ctrl->handler,
+ struct vicodec_ctx, hdl);
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ ctx->gop_size = ctrl->val;
+ return 0;
+ case VICODEC_CID_I_FRAME_QP:
+ ctx->i_frame_qp = ctrl->val;
+ return 0;
+ case VICODEC_CID_P_FRAME_QP:
+ ctx->p_frame_qp = ctrl->val;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops vicodec_ctrl_ops = {
+ .s_ctrl = vicodec_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vicodec_ctrl_i_frame = {
+ .ops = &vicodec_ctrl_ops,
+ .id = VICODEC_CID_I_FRAME_QP,
+ .name = "FWHT I-Frame QP Value",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 1,
+ .max = 31,
+ .def = 20,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config vicodec_ctrl_p_frame = {
+ .ops = &vicodec_ctrl_ops,
+ .id = VICODEC_CID_P_FRAME_QP,
+ .name = "FWHT P-Frame QP Value",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 1,
+ .max = 31,
+ .def = 20,
+ .step = 1,
+};
+
/*
* File operations
*/
ctx->dev = dev;
hdl = &ctx->hdl;
v4l2_ctrl_handler_init(hdl, 4);
- ctx->ctrl_gop_size = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- 1, 16, 1, 10);
+ v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ 1, 16, 1, 10);
+ v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_i_frame, NULL);
+ v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_p_frame, NULL);
if (hdl->error) {
rc = hdl->error;
v4l2_ctrl_handler_free(hdl);