mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 17:16:50 +08:00
[jpege:] Add q_factor and qtable
Add q_factor and qtalbe interface Signed-off-by: yandong.lin <yandong.lin@rock-chips.com> Change-Id: I6b59d0b2e740e4b2815e7c83ad9a3641fe700e2f
This commit is contained in:
@@ -894,12 +894,18 @@ typedef struct MppEncH265Cfg_t {
|
|||||||
typedef enum MppEncJpegCfgChange_e {
|
typedef enum MppEncJpegCfgChange_e {
|
||||||
/* change on quant parameter */
|
/* change on quant parameter */
|
||||||
MPP_ENC_JPEG_CFG_CHANGE_QP = (1 << 0),
|
MPP_ENC_JPEG_CFG_CHANGE_QP = (1 << 0),
|
||||||
|
MPP_ENC_JPEG_CFG_CHANGE_QTABLE = (1 << 1),
|
||||||
|
MPP_ENC_JPEG_CFG_CHANGE_QFACTOR = (1 << 2),
|
||||||
MPP_ENC_JPEG_CFG_CHANGE_ALL = (0xFFFFFFFF),
|
MPP_ENC_JPEG_CFG_CHANGE_ALL = (0xFFFFFFFF),
|
||||||
} MppEncJpegCfgChange;
|
} MppEncJpegCfgChange;
|
||||||
|
|
||||||
typedef struct MppEncJpegCfg_t {
|
typedef struct MppEncJpegCfg_t {
|
||||||
RK_U32 change;
|
RK_U32 change;
|
||||||
RK_S32 quant;
|
RK_S32 quant;
|
||||||
|
RK_U32 q_factor;
|
||||||
|
RK_U8 *qtable_y;
|
||||||
|
RK_U8 *qtable_u;
|
||||||
|
RK_U8 *qtable_v;
|
||||||
} MppEncJpegCfg;
|
} MppEncJpegCfg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -216,6 +216,10 @@ static const char *cfg_func_names[] = {
|
|||||||
ENTRY(h265, qp_delta_ip, S32, RK_S32, MPP_ENC_H265_CFG_RC_QP_CHANGE, codec.h265, ip_qp_delta) \
|
ENTRY(h265, qp_delta_ip, S32, RK_S32, MPP_ENC_H265_CFG_RC_QP_CHANGE, codec.h265, ip_qp_delta) \
|
||||||
/* jpeg config */ \
|
/* jpeg config */ \
|
||||||
ENTRY(jpeg, quant, S32, RK_S32, MPP_ENC_JPEG_CFG_CHANGE_QP, codec.jpeg, quant) \
|
ENTRY(jpeg, quant, S32, RK_S32, MPP_ENC_JPEG_CFG_CHANGE_QP, codec.jpeg, quant) \
|
||||||
|
ENTRY(jpeg, qtable_y, PTR, RK_U8*, MPP_ENC_JPEG_CFG_CHANGE_QTABLE, codec.jpeg, qtable_y) \
|
||||||
|
ENTRY(jpeg, qtable_u, PTR, RK_U8*, MPP_ENC_JPEG_CFG_CHANGE_QTABLE, codec.jpeg, qtable_u) \
|
||||||
|
ENTRY(jpeg, qtable_v, PTR, RK_U8*, MPP_ENC_JPEG_CFG_CHANGE_QTABLE, codec.jpeg, qtable_v) \
|
||||||
|
ENTRY(jpeg, q_factor, U32, RK_U32, MPP_ENC_JPEG_CFG_CHANGE_QFACTOR, codec.jpeg, q_factor) \
|
||||||
/* split config */ \
|
/* split config */ \
|
||||||
ENTRY(split, mode, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_MODE, split, split_mode) \
|
ENTRY(split, mode, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_MODE, split, split_mode) \
|
||||||
ENTRY(split, arg, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_ARG, split, split_arg)
|
ENTRY(split, arg, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_ARG, split, split_arg)
|
||||||
@@ -232,7 +236,7 @@ RK_S32 const_strlen(const char* str)
|
|||||||
return *str ? 1 + const_strlen(str + 1) : 0;
|
return *str ? 1 + const_strlen(str + 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) + 0;
|
static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) - 23;
|
||||||
|
|
||||||
class MppEncCfgService
|
class MppEncCfgService
|
||||||
{
|
{
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "mpp_log.h"
|
#include "mpp_log.h"
|
||||||
#include "mpp_env.h"
|
#include "mpp_env.h"
|
||||||
#include "mpp_common.h"
|
#include "mpp_common.h"
|
||||||
|
#include "mpp_mem.h"
|
||||||
|
|
||||||
#include "jpege_debug.h"
|
#include "jpege_debug.h"
|
||||||
#include "jpege_api.h"
|
#include "jpege_api.h"
|
||||||
@@ -34,6 +35,33 @@ typedef struct {
|
|||||||
JpegeSyntax syntax;
|
JpegeSyntax syntax;
|
||||||
} JpegeCtx;
|
} JpegeCtx;
|
||||||
|
|
||||||
|
#define QUANTIZE_TABLE_SIZE 64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* from RFC435 spec.
|
||||||
|
*/
|
||||||
|
static const RK_U8 jpege_luma_quantizer[QUANTIZE_TABLE_SIZE] = {
|
||||||
|
16, 11, 10, 16, 24, 40, 51, 61,
|
||||||
|
12, 12, 14, 19, 26, 58, 60, 55,
|
||||||
|
14, 13, 16, 24, 40, 57, 69, 56,
|
||||||
|
14, 17, 22, 29, 51, 87, 80, 62,
|
||||||
|
18, 22, 37, 56, 68, 109, 103, 77,
|
||||||
|
24, 35, 55, 64, 81, 104, 113, 92,
|
||||||
|
49, 64, 78, 87, 103, 121, 120, 101,
|
||||||
|
72, 92, 95, 98, 112, 100, 103, 99
|
||||||
|
};
|
||||||
|
|
||||||
|
static const RK_U8 jpege_chroma_quantizer[QUANTIZE_TABLE_SIZE] = {
|
||||||
|
17, 18, 24, 47, 99, 99, 99, 99,
|
||||||
|
18, 21, 26, 66, 99, 99, 99, 99,
|
||||||
|
24, 26, 56, 99, 99, 99, 99, 99,
|
||||||
|
47, 66, 99, 99, 99, 99, 99, 99,
|
||||||
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
|
99, 99, 99, 99, 99, 99, 99, 99
|
||||||
|
};
|
||||||
|
|
||||||
RK_U32 jpege_debug = 0;
|
RK_U32 jpege_debug = 0;
|
||||||
|
|
||||||
static MPP_RET jpege_init_v2(void *ctx, EncImplCfg *cfg)
|
static MPP_RET jpege_init_v2(void *ctx, EncImplCfg *cfg)
|
||||||
@@ -63,7 +91,15 @@ static MPP_RET jpege_init_v2(void *ctx, EncImplCfg *cfg)
|
|||||||
|
|
||||||
static MPP_RET jpege_deinit_v2(void *ctx)
|
static MPP_RET jpege_deinit_v2(void *ctx)
|
||||||
{
|
{
|
||||||
|
JpegeCtx *p = (JpegeCtx *)ctx;
|
||||||
|
MppEncJpegCfg *jpeg_cfg = &p->cfg->codec.jpeg;
|
||||||
|
|
||||||
jpege_dbg_func("enter ctx %p\n", ctx);
|
jpege_dbg_func("enter ctx %p\n", ctx);
|
||||||
|
|
||||||
|
MPP_FREE(jpeg_cfg->qtable_y);
|
||||||
|
MPP_FREE(jpeg_cfg->qtable_u);
|
||||||
|
MPP_FREE(jpeg_cfg->qtable_v);
|
||||||
|
|
||||||
jpege_dbg_func("leave ctx %p\n", ctx);
|
jpege_dbg_func("leave ctx %p\n", ctx);
|
||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
@@ -208,6 +244,43 @@ static MPP_RET jpege_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* gen quantizer table by q_factor according to RFC435 spec. */
|
||||||
|
static MPP_RET jpege_gen_qt_by_qfactor(MppEncJpegCfg *cfg, RK_U32 *factor)
|
||||||
|
{
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
RK_U8 q = *factor;
|
||||||
|
RK_U32 i;
|
||||||
|
RK_U8 *qtable_y = NULL;
|
||||||
|
RK_U8 *qtable_c = NULL;
|
||||||
|
|
||||||
|
if (!cfg->qtable_y)
|
||||||
|
cfg->qtable_y = mpp_malloc(RK_U8, QUANTIZE_TABLE_SIZE);
|
||||||
|
if (!cfg->qtable_u)
|
||||||
|
cfg->qtable_u = mpp_malloc(RK_U8, QUANTIZE_TABLE_SIZE);
|
||||||
|
|
||||||
|
if (NULL == cfg->qtable_y || NULL == cfg->qtable_u) {
|
||||||
|
mpp_err_f("qtable is null, malloc err");
|
||||||
|
return MPP_ERR_MALLOC;
|
||||||
|
}
|
||||||
|
qtable_y = cfg->qtable_y;
|
||||||
|
qtable_c = cfg->qtable_u;
|
||||||
|
|
||||||
|
if (q < 50)
|
||||||
|
q = 5000 / (*factor);
|
||||||
|
else
|
||||||
|
q = 200 - (*factor << 1);
|
||||||
|
|
||||||
|
for (i = 0; i < QUANTIZE_TABLE_SIZE; i++) {
|
||||||
|
RK_S16 lq = (jpege_luma_quantizer[i] * q + 50) / 100;
|
||||||
|
RK_S16 cq = (jpege_chroma_quantizer[i] * q + 50) / 100;
|
||||||
|
|
||||||
|
/* Limit the quantizers to 1 <= q <= 255 */
|
||||||
|
qtable_y[i] = MPP_CLIP3(1, 255, lq);
|
||||||
|
qtable_c[i] = MPP_CLIP3(1, 255, cq);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static MPP_RET jpege_proc_jpeg_cfg(MppEncJpegCfg *dst, MppEncJpegCfg *src)
|
static MPP_RET jpege_proc_jpeg_cfg(MppEncJpegCfg *dst, MppEncJpegCfg *src)
|
||||||
{
|
{
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
@@ -219,6 +292,52 @@ static MPP_RET jpege_proc_jpeg_cfg(MppEncJpegCfg *dst, MppEncJpegCfg *src)
|
|||||||
if (change & MPP_ENC_JPEG_CFG_CHANGE_QP) {
|
if (change & MPP_ENC_JPEG_CFG_CHANGE_QP) {
|
||||||
dst->quant = src->quant;
|
dst->quant = src->quant;
|
||||||
}
|
}
|
||||||
|
if (change & MPP_ENC_JPEG_CFG_CHANGE_QFACTOR) {
|
||||||
|
if (src->q_factor < 1 || src->q_factor > 99) {
|
||||||
|
mpp_err_f("q_factor out of range, default set 90\n");
|
||||||
|
src->q_factor = 90;
|
||||||
|
}
|
||||||
|
if (dst->q_factor != src->q_factor)
|
||||||
|
ret = jpege_gen_qt_by_qfactor(dst, &src->q_factor);
|
||||||
|
|
||||||
|
dst->q_factor = src->q_factor;
|
||||||
|
|
||||||
|
} else if (change & MPP_ENC_JPEG_CFG_CHANGE_QTABLE) {
|
||||||
|
if (src->qtable_y && src->qtable_u && src->qtable_v) {
|
||||||
|
if (NULL == dst->qtable_y)
|
||||||
|
dst->qtable_y = mpp_malloc(RK_U8, QUANTIZE_TABLE_SIZE);
|
||||||
|
if (NULL == dst->qtable_u)
|
||||||
|
dst->qtable_u = mpp_malloc(RK_U8, QUANTIZE_TABLE_SIZE);
|
||||||
|
|
||||||
|
if (NULL == dst->qtable_y || NULL == dst->qtable_u) {
|
||||||
|
mpp_err_f("qtable is null, malloc err\n");
|
||||||
|
return MPP_ERR_MALLOC;
|
||||||
|
}
|
||||||
|
/* check table value */
|
||||||
|
if (src->qtable_u != src->qtable_v) {
|
||||||
|
RK_U32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < QUANTIZE_TABLE_SIZE; i++) {
|
||||||
|
if (src->qtable_u[i] != src->qtable_v[i]) {
|
||||||
|
RK_U32 j;
|
||||||
|
|
||||||
|
jpege_dbg_input("qtable_u and qtable_v are different, use qtable_u\n");
|
||||||
|
for (j = 0; j < QUANTIZE_TABLE_SIZE; j++)
|
||||||
|
jpege_dbg_input("qtable_u[%d] %d qtable_v[%d] %d\n",
|
||||||
|
j, src->qtable_u[j], j, src->qtable_v[j]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* default use one chroma qtable, select qtable_u */
|
||||||
|
memcpy(dst->qtable_y, src->qtable_y, QUANTIZE_TABLE_SIZE);
|
||||||
|
memcpy(dst->qtable_u, src->qtable_u, QUANTIZE_TABLE_SIZE);
|
||||||
|
} else {
|
||||||
|
mpp_err_f("invalid qtable y %p u %p v %p\n",
|
||||||
|
src->qtable_y, src->qtable_u, src->qtable_v);
|
||||||
|
ret = MPP_ERR_NULL_PTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dst->quant < 0 || dst->quant > 10) {
|
if (dst->quant < 0 || dst->quant > 10) {
|
||||||
mpp_err_f("invalid quality level %d is not in range [0..10] set to default 8\n");
|
mpp_err_f("invalid quality level %d is not in range [0..10] set to default 8\n");
|
||||||
@@ -229,7 +348,8 @@ static MPP_RET jpege_proc_jpeg_cfg(MppEncJpegCfg *dst, MppEncJpegCfg *src)
|
|||||||
mpp_err_f("failed to accept new rc config\n");
|
mpp_err_f("failed to accept new rc config\n");
|
||||||
*dst = bak;
|
*dst = bak;
|
||||||
} else {
|
} else {
|
||||||
mpp_log_f("MPP_ENC_SET_CODEC_CFG jpeg quant set to %d\n", dst->quant);
|
mpp_log_f("MPP_ENC_SET_CODEC_CFG change 0x%x jpeg quant %d q_factor %d\n",
|
||||||
|
change, dst->quant, dst->q_factor);
|
||||||
dst->change = src->change;
|
dst->change = src->change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,6 +359,24 @@ static MPP_RET jpege_proc_jpeg_cfg(MppEncJpegCfg *dst, MppEncJpegCfg *src)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MPP_RET jpege_proc_split_cfg(MppEncSliceSplit *dst, MppEncSliceSplit *src)
|
||||||
|
{
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
RK_U32 change = src->change;
|
||||||
|
|
||||||
|
if (change & MPP_ENC_SPLIT_CFG_CHANGE_MODE) {
|
||||||
|
dst->split_mode = src->split_mode;
|
||||||
|
dst->split_arg = src->split_arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change & MPP_ENC_SPLIT_CFG_CHANGE_ARG)
|
||||||
|
dst->split_arg = src->split_arg;
|
||||||
|
|
||||||
|
dst->change |= change;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param)
|
static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param)
|
||||||
{
|
{
|
||||||
JpegeCtx *p = (JpegeCtx *)ctx;
|
JpegeCtx *p = (JpegeCtx *)ctx;
|
||||||
@@ -264,6 +402,10 @@ static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param)
|
|||||||
ret |= jpege_proc_jpeg_cfg(&cfg->codec.jpeg, &src->codec.jpeg);
|
ret |= jpege_proc_jpeg_cfg(&cfg->codec.jpeg, &src->codec.jpeg);
|
||||||
src->codec.jpeg.change = 0;
|
src->codec.jpeg.change = 0;
|
||||||
}
|
}
|
||||||
|
if (src->split.change) {
|
||||||
|
ret |= jpege_proc_split_cfg(&cfg->split, &src->split);
|
||||||
|
src->split.change = 0;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case MPP_ENC_SET_PREP_CFG : {
|
case MPP_ENC_SET_PREP_CFG : {
|
||||||
ret = jpege_proc_prep_cfg(&cfg->prep, param);
|
ret = jpege_proc_prep_cfg(&cfg->prep, param);
|
||||||
@@ -366,6 +508,8 @@ static MPP_RET jpege_proc_hal(void *ctx, HalEncTask *task)
|
|||||||
syntax->format = prep->format;
|
syntax->format = prep->format;
|
||||||
syntax->color = prep->color;
|
syntax->color = prep->color;
|
||||||
syntax->quality = codec->jpeg.quant;
|
syntax->quality = codec->jpeg.quant;
|
||||||
|
syntax->qtable_y = codec->jpeg.qtable_y;
|
||||||
|
syntax->qtable_c = codec->jpeg.qtable_u;
|
||||||
|
|
||||||
task->valid = 1;
|
task->valid = 1;
|
||||||
task->is_intra = 1;
|
task->is_intra = 1;
|
||||||
|
Reference in New Issue
Block a user