1
mirror of https://git.videolan.org/git/ffmpeg.git synced 2024-07-17 09:51:38 +02:00

hevc: eliminate unnecessary cbf_c{b,r} arrays

- They are be replaced by passing additional parameters to the transform
functions.
- Adaptation to 4:2:2

Signed-off-by: Mickaël Raulet <mraulet@insa-rennes.fr>
cherry picked from commit f518bb22531c648f1c37f978b0c7ad2e71e04c25
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Anton Khirnov 2014-07-27 21:56:05 +02:00 committed by Michael Niedermayer
parent 772f7f4edd
commit 77ef9fd1e9
2 changed files with 37 additions and 64 deletions

View File

@ -859,7 +859,7 @@ static int hls_cross_component_pred(HEVCContext *s, int idx) {
static int hls_transform_unit(HEVCContext *s, int x0, int y0,
int xBase, int yBase, int cb_xBase, int cb_yBase,
int log2_cb_size, int log2_trafo_size,
int trafo_depth, int blk_idx)
int trafo_depth, int blk_idx, int *cbf_cb, int *cbf_cr)
{
HEVCLocalContext *lc = s->HEVClc;
const int log2_trafo_size_c = log2_trafo_size - s->sps->hshift[1];
@ -872,20 +872,14 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
s->hpc.intra_pred[log2_trafo_size - 2](s, x0, y0, 0);
}
if (lc->tt.cbf_luma ||
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) ||
(s->sps->chroma_format_idc == 2 &&
(SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << log2_trafo_size_c)) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << log2_trafo_size_c))))) {
if (lc->tt.cbf_luma || cbf_cb[0] || cbf_cr[0] ||
(s->sps->chroma_format_idc == 2 && (cbf_cb[1] || cbf_cr[1]))) {
int scan_idx = SCAN_DIAG;
int scan_idx_c = SCAN_DIAG;
int cbf_luma = lc->tt.cbf_luma;
int cbf_chroma = SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) ||
int cbf_chroma = cbf_cb[0] || cbf_cr[0] ||
(s->sps->chroma_format_idc == 2 &&
(SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << log2_trafo_size_c)) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << log2_trafo_size_c))));
(cbf_cb[1] || cbf_cr[1]));
if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {
lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);
@ -964,7 +958,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 1);
}
if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (i << log2_trafo_size_c)))
if (cbf_cb[i])
ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),
log2_trafo_size_c, scan_idx_c, 1);
else
@ -993,7 +987,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 2);
}
if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (i << log2_trafo_size_c)))
if (cbf_cr[i])
ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),
log2_trafo_size_c, scan_idx_c, 2);
else
@ -1022,7 +1016,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 1);
}
if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase + (i << log2_trafo_size_c)))
if (cbf_cb[i])
ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),
log2_trafo_size, scan_idx_c, 1);
}
@ -1032,7 +1026,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 2);
}
if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase + (i << log2_trafo_size_c)))
if (cbf_cr[i])
ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),
log2_trafo_size, scan_idx_c, 2);
}
@ -1087,33 +1081,18 @@ static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_si
static int hls_transform_tree(HEVCContext *s, int x0, int y0,
int xBase, int yBase, int cb_xBase, int cb_yBase,
int log2_cb_size, int log2_trafo_size,
int trafo_depth, int blk_idx)
int trafo_depth, int blk_idx, int *base_cbf_cb, int *base_cbf_cr)
{
HEVCLocalContext *lc = s->HEVClc;
uint8_t split_transform_flag;
int cbf_cb[2];
int cbf_cr[2];
int ret;
if (trafo_depth > 0 && log2_trafo_size == 2) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase);
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase);
if (s->sps->chroma_format_idc == 2) {
int xBase_cb = xBase & ((1 << log2_trafo_size) - 1);
int yBase_cb = yBase & ((1 << log2_trafo_size) - 1);
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
SAMPLE_CBF2(lc->tt.cbf_cb[trafo_depth - 1], xBase_cb, yBase_cb + (1 << (log2_trafo_size)));
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
SAMPLE_CBF2(lc->tt.cbf_cr[trafo_depth - 1], xBase_cb, yBase_cb + (1 << (log2_trafo_size)));
}
} else {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) = 0;
if (s->sps->chroma_format_idc == 2) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) = 0;
}
}
cbf_cb[0] = base_cbf_cb[0];
cbf_cb[1] = base_cbf_cb[1];
cbf_cr[0] = base_cbf_cr[0];
cbf_cr[1] = base_cbf_cr[1];
if (lc->cu.intra_split_flag) {
if (trafo_depth == 1) {
@ -1151,24 +1130,24 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
}
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
if (trafo_depth == 0 ||
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase)) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (trafo_depth == 0 || cbf_cb[0]) {
cbf_cb[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
cbf_cb[1] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
}
} else if (trafo_depth == 0) {
cbf_cb[0] =
cbf_cb[1] = 0;
}
if (trafo_depth == 0 ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase)) {
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (trafo_depth == 0 || cbf_cr[0]) {
cbf_cr[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
cbf_cr[1] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
}
} else if (trafo_depth == 0) {
cbf_cr[0] =
cbf_cr[1] = 0;
}
}
@ -1178,22 +1157,22 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
ret = hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase,
log2_cb_size, log2_trafo_size - 1,
trafo_depth + 1, 0);
trafo_depth + 1, 0, cbf_cb, cbf_cr);
if (ret < 0)
return ret;
ret = hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase,
log2_cb_size, log2_trafo_size - 1,
trafo_depth + 1, 1);
trafo_depth + 1, 1, cbf_cb, cbf_cr);
if (ret < 0)
return ret;
ret = hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase,
log2_cb_size, log2_trafo_size - 1,
trafo_depth + 1, 2);
trafo_depth + 1, 2, cbf_cb, cbf_cr);
if (ret < 0)
return ret;
ret = hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase,
log2_cb_size, log2_trafo_size - 1,
trafo_depth + 1, 3);
trafo_depth + 1, 3, cbf_cb, cbf_cr);
if (ret < 0)
return ret;
} else {
@ -1202,17 +1181,14 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
int min_tu_width = s->sps->min_tb_width;
if (lc->cu.pred_mode == MODE_INTRA || trafo_depth != 0 ||
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) ||
(s->sps->chroma_format_idc == 2 &&
(SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1)))))) {
cbf_cb[0] || cbf_cr[0] ||
(s->sps->chroma_format_idc == 2 && (cbf_cb[1] || cbf_cr[1]))) {
lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth);
}
ret = hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
log2_cb_size, log2_trafo_size, trafo_depth,
blk_idx);
blk_idx, cbf_cb, cbf_cr);
if (ret < 0)
return ret;
// TODO: store cbf_luma somewhere else
@ -2105,12 +2081,13 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
lc->cu.rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(s);
}
if (lc->cu.rqt_root_cbf) {
int cbf[2] = { 0 };
lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?
s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
s->sps->max_transform_hierarchy_depth_inter;
ret = hls_transform_tree(s, x0, y0, x0, y0, x0, y0,
log2_cb_size,
log2_cb_size, 0, 0);
log2_cb_size, 0, 0, cbf, cbf);
if (ret < 0)
return ret;
} else {

View File

@ -82,8 +82,6 @@
*/
#define SAMPLE(tab, x, y) ((tab)[(y) * s->sps->width + (x)])
#define SAMPLE_CTB(tab, x, y) ((tab)[(y) * min_cb_width + (x)])
#define SAMPLE_CBF(tab, x, y) ((tab)[((y) & ((1<<log2_trafo_size)-1)) * MAX_CU_SIZE + ((x) & ((1<<log2_trafo_size)-1))])
#define SAMPLE_CBF2(tab, x, y) ((tab)[(y) * MAX_CU_SIZE + (x)])
#define IS_IDR(s) ((s)->nal_unit_type == NAL_IDR_W_RADL || (s)->nal_unit_type == NAL_IDR_N_LP)
#define IS_BLA(s) ((s)->nal_unit_type == NAL_BLA_W_RADL || (s)->nal_unit_type == NAL_BLA_W_LP || \
@ -686,8 +684,6 @@ typedef struct PredictionUnit {
} PredictionUnit;
typedef struct TransformTree {
uint8_t cbf_cb[MAX_TRANSFORM_DEPTH][MAX_CU_SIZE * MAX_CU_SIZE];
uint8_t cbf_cr[MAX_TRANSFORM_DEPTH][MAX_CU_SIZE * MAX_CU_SIZE];
uint8_t cbf_luma;
// Inferred parameters