summaryrefslogtreecommitdiff
path: root/libavcodec/hevc_filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/hevc_filter.c')
-rw-r--r--libavcodec/hevc_filter.c297
1 files changed, 130 insertions, 167 deletions
diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c
index 443f2223cb..ec7a21187d 100644
--- a/libavcodec/hevc_filter.c
+++ b/libavcodec/hevc_filter.c
@@ -60,7 +60,7 @@ static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
else
offset = s->pps->cr_qp_offset;
- qp_i = av_clip_c(qp_y + offset, 0, 57);
+ qp_i = av_clip(qp_y + offset, 0, 57);
if (qp_i < 30)
qp = qp_i;
else if (qp_i > 43)
@@ -68,7 +68,7 @@ static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
else
qp = qp_c[qp_i - 30];
- idxt = av_clip_c(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
+ idxt = av_clip(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
return tctable[idxt];
}
@@ -477,138 +477,96 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
}
}
-static int boundary_strength(HEVCContext *s, MvField *curr,
- uint8_t curr_cbf_luma, MvField *neigh,
- uint8_t neigh_cbf_luma,
- RefPicList *neigh_refPicList,
- int tu_border)
+static int boundary_strength(HEVCContext *s, MvField *curr, MvField *neigh,
+ RefPicList *neigh_refPicList)
{
- int mvs = curr->pred_flag[0] + curr->pred_flag[1];
-
- if (tu_border) {
- if (curr->is_intra || neigh->is_intra)
- return 2;
- if (curr_cbf_luma || neigh_cbf_luma)
- return 1;
- }
-
- if (mvs == neigh->pred_flag[0] + neigh->pred_flag[1]) {
- if (mvs == 2) {
- // same L0 and L1
- if (s->ref->refPicList[0].list[curr->ref_idx[0]] == neigh_refPicList[0].list[neigh->ref_idx[0]] &&
- s->ref->refPicList[0].list[curr->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]] &&
- neigh_refPicList[0].list[neigh->ref_idx[0]] == neigh_refPicList[1].list[neigh->ref_idx[1]]) {
- if ((abs(neigh->mv[0].x - curr->mv[0].x) >= 4 || abs(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
- abs(neigh->mv[1].x - curr->mv[1].x) >= 4 || abs(neigh->mv[1].y - curr->mv[1].y) >= 4) &&
- (abs(neigh->mv[1].x - curr->mv[0].x) >= 4 || abs(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
- abs(neigh->mv[0].x - curr->mv[1].x) >= 4 || abs(neigh->mv[0].y - curr->mv[1].y) >= 4))
- return 1;
- else
- return 0;
- } else if (neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
- neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
- if (abs(neigh->mv[0].x - curr->mv[0].x) >= 4 || abs(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
- abs(neigh->mv[1].x - curr->mv[1].x) >= 4 || abs(neigh->mv[1].y - curr->mv[1].y) >= 4)
- return 1;
- else
- return 0;
- } else if (neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
- neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
- if (abs(neigh->mv[1].x - curr->mv[0].x) >= 4 || abs(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
- abs(neigh->mv[0].x - curr->mv[1].x) >= 4 || abs(neigh->mv[0].y - curr->mv[1].y) >= 4)
- return 1;
- else
- return 0;
- } else {
+ if (curr->pred_flag == PF_BI && neigh->pred_flag == PF_BI) {
+ // same L0 and L1
+ if (s->ref->refPicList[0].list[curr->ref_idx[0]] == neigh_refPicList[0].list[neigh->ref_idx[0]] &&
+ s->ref->refPicList[0].list[curr->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]] &&
+ neigh_refPicList[0].list[neigh->ref_idx[0]] == neigh_refPicList[1].list[neigh->ref_idx[1]]) {
+ if ((FFABS(neigh->mv[0].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
+ FFABS(neigh->mv[1].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 4) &&
+ (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
+ FFABS(neigh->mv[0].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 4))
return 1;
- }
- } else { // 1 MV
- Mv A, B;
- int ref_A, ref_B;
-
- if (curr->pred_flag[0]) {
- A = curr->mv[0];
- ref_A = s->ref->refPicList[0].list[curr->ref_idx[0]];
- } else {
- A = curr->mv[1];
- ref_A = s->ref->refPicList[1].list[curr->ref_idx[1]];
- }
+ else
+ return 0;
+ } else if (neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
+ neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
+ if (FFABS(neigh->mv[0].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
+ FFABS(neigh->mv[1].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 4)
+ return 1;
+ else
+ return 0;
+ } else if (neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
+ neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
+ if (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
+ FFABS(neigh->mv[0].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 4)
+ return 1;
+ else
+ return 0;
+ } else {
+ return 1;
+ }
+ } else if ((curr->pred_flag != PF_BI) && (neigh->pred_flag != PF_BI)){ // 1 MV
+ Mv A, B;
+ int ref_A, ref_B;
+
+ if (curr->pred_flag & 1) {
+ A = curr->mv[0];
+ ref_A = s->ref->refPicList[0].list[curr->ref_idx[0]];
+ } else {
+ A = curr->mv[1];
+ ref_A = s->ref->refPicList[1].list[curr->ref_idx[1]];
+ }
- if (neigh->pred_flag[0]) {
- B = neigh->mv[0];
- ref_B = neigh_refPicList[0].list[neigh->ref_idx[0]];
- } else {
- B = neigh->mv[1];
- ref_B = neigh_refPicList[1].list[neigh->ref_idx[1]];
- }
+ if (neigh->pred_flag & 1) {
+ B = neigh->mv[0];
+ ref_B = neigh_refPicList[0].list[neigh->ref_idx[0]];
+ } else {
+ B = neigh->mv[1];
+ ref_B = neigh_refPicList[1].list[neigh->ref_idx[1]];
+ }
- if (ref_A == ref_B) {
- if (abs(A.x - B.x) >= 4 || abs(A.y - B.y) >= 4)
- return 1;
- else
- return 0;
- } else
+ if (ref_A == ref_B) {
+ if (FFABS(A.x - B.x) >= 4 || FFABS(A.y - B.y) >= 4)
return 1;
- }
+ else
+ return 0;
+ } else
+ return 1;
}
return 1;
}
void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
- int log2_trafo_size,
- int slice_or_tiles_up_boundary,
- int slice_or_tiles_left_boundary)
+ int log2_trafo_size)
{
+ HEVCLocalContext *lc = s->HEVClc;
MvField *tab_mvf = s->ref->tab_mvf;
int log2_min_pu_size = s->sps->log2_min_pu_size;
int log2_min_tu_size = s->sps->log2_min_tb_size;
int min_pu_width = s->sps->min_pu_width;
int min_tu_width = s->sps->min_tb_width;
int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
- (x0 >> log2_min_pu_size)].is_intra;
+ (x0 >> log2_min_pu_size)].pred_flag == PF_INTRA;
int i, j, bs;
if (y0 > 0 && (y0 & 7) == 0) {
- int yp_pu = (y0 - 1) >> log2_min_pu_size;
- int yq_pu = y0 >> log2_min_pu_size;
- int yp_tu = (y0 - 1) >> log2_min_tu_size;
- int yq_tu = y0 >> log2_min_tu_size;
-
- for (i = 0; i < (1 << log2_trafo_size); i += 4) {
- int x_pu = (x0 + i) >> log2_min_pu_size;
- int x_tu = (x0 + i) >> log2_min_tu_size;
- MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
- MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
- uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
- uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
+ int bd_ctby = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int bd_slice = s->sh.slice_loop_filter_across_slices_enabled_flag ||
+ !(lc->slice_or_tiles_up_boundary & 1);
+ int bd_tiles = s->pps->loop_filter_across_tiles_enabled_flag ||
+ !(lc->slice_or_tiles_up_boundary & 2);
+ if (((bd_slice && bd_tiles) || bd_ctby)) {
+ int yp_pu = (y0 - 1) >> log2_min_pu_size;
+ int yq_pu = y0 >> log2_min_pu_size;
+ int yp_tu = (y0 - 1) >> log2_min_tu_size;
+ int yq_tu = y0 >> log2_min_tu_size;
RefPicList *top_refPicList = ff_hevc_get_ref_list(s, s->ref,
- x0 + i, y0 - 1);
-
- bs = boundary_strength(s, curr, curr_cbf_luma,
- top, top_cbf_luma, top_refPicList, 1);
- if (!s->sh.slice_loop_filter_across_slices_enabled_flag &&
- (slice_or_tiles_up_boundary & 1) &&
- (y0 % (1 << s->sps->log2_ctb_size)) == 0)
- bs = 0;
- else if (!s->pps->loop_filter_across_tiles_enabled_flag &&
- (slice_or_tiles_up_boundary & 2) &&
- (y0 % (1 << s->sps->log2_ctb_size)) == 0)
- bs = 0;
- if (y0 == 0 || s->sh.disable_deblocking_filter_flag == 1)
- bs = 0;
- if (bs)
- s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
- }
- }
-
- // bs for TU internal horizontal PU boundaries
- if (log2_trafo_size > s->sps->log2_min_pu_size && !is_intra)
- for (j = 8; j < (1 << log2_trafo_size); j += 8) {
- int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
- int yq_pu = (y0 + j) >> log2_min_pu_size;
- int yp_tu = (y0 + j - 1) >> log2_min_tu_size;
- int yq_tu = (y0 + j) >> log2_min_tu_size;
+ x0, y0 - 1);
for (i = 0; i < (1 << log2_trafo_size); i += 4) {
int x_pu = (x0 + i) >> log2_min_pu_size;
@@ -617,81 +575,86 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
- RefPicList *top_refPicList = ff_hevc_get_ref_list(s, s->ref,
- x0 + i,
- y0 + j - 1);
-
- bs = boundary_strength(s, curr, curr_cbf_luma,
- top, top_cbf_luma, top_refPicList, 0);
- if (s->sh.disable_deblocking_filter_flag == 1)
- bs = 0;
- if (bs)
- s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
+
+ if (curr->pred_flag == PF_INTRA || top->pred_flag == PF_INTRA)
+ bs = 2;
+ else if (curr_cbf_luma || top_cbf_luma)
+ bs = 1;
+ else
+ bs = boundary_strength(s, curr, top, top_refPicList);
+ s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
}
}
+ }
// bs for vertical TU boundaries
if (x0 > 0 && (x0 & 7) == 0) {
- int xp_pu = (x0 - 1) >> log2_min_pu_size;
- int xq_pu = x0 >> log2_min_pu_size;
- int xp_tu = (x0 - 1) >> log2_min_tu_size;
- int xq_tu = x0 >> log2_min_tu_size;
-
- for (i = 0; i < (1 << log2_trafo_size); i += 4) {
- int y_pu = (y0 + i) >> log2_min_pu_size;
- int y_tu = (y0 + i) >> log2_min_tu_size;
- MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
- MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
-
- uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
- uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
+ int bd_ctbx = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int bd_slice = s->sh.slice_loop_filter_across_slices_enabled_flag ||
+ !(lc->slice_or_tiles_left_boundary & 1);
+ int bd_tiles = s->pps->loop_filter_across_tiles_enabled_flag ||
+ !(lc->slice_or_tiles_left_boundary & 2);
+ if (((bd_slice && bd_tiles) || bd_ctbx)) {
+ int xp_pu = (x0 - 1) >> log2_min_pu_size;
+ int xq_pu = x0 >> log2_min_pu_size;
+ int xp_tu = (x0 - 1) >> log2_min_tu_size;
+ int xq_tu = x0 >> log2_min_tu_size;
RefPicList *left_refPicList = ff_hevc_get_ref_list(s, s->ref,
- x0 - 1, y0 + i);
-
- bs = boundary_strength(s, curr, curr_cbf_luma,
- left, left_cbf_luma, left_refPicList, 1);
- if (!s->sh.slice_loop_filter_across_slices_enabled_flag &&
- (slice_or_tiles_left_boundary & 1) &&
- (x0 % (1 << s->sps->log2_ctb_size)) == 0)
- bs = 0;
- else if (!s->pps->loop_filter_across_tiles_enabled_flag &&
- (slice_or_tiles_left_boundary & 2) &&
- (x0 % (1 << s->sps->log2_ctb_size)) == 0)
- bs = 0;
- if (x0 == 0 || s->sh.disable_deblocking_filter_flag == 1)
- bs = 0;
- if (bs)
+ x0 - 1, y0);
+
+ for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+ int y_pu = (y0 + i) >> log2_min_pu_size;
+ int y_tu = (y0 + i) >> log2_min_tu_size;
+ MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+ MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+ uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
+ uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
+
+ if (curr->pred_flag == PF_INTRA || left->pred_flag == PF_INTRA)
+ bs = 2;
+ else if (curr_cbf_luma || left_cbf_luma)
+ bs = 1;
+ else
+ bs = boundary_strength(s, curr, left, left_refPicList);
s->vertical_bs[(x0 >> 3) + ((y0 + i) >> 2) * s->bs_width] = bs;
+ }
}
}
- // bs for TU internal vertical PU boundaries
- if (log2_trafo_size > log2_min_pu_size && !is_intra)
+ if (log2_trafo_size > log2_min_pu_size && !is_intra) {
+ RefPicList *refPicList = ff_hevc_get_ref_list(s, s->ref,
+ x0,
+ y0);
+ // bs for TU internal horizontal PU boundaries
+ for (j = 8; j < (1 << log2_trafo_size); j += 8) {
+ int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
+ int yq_pu = (y0 + j) >> log2_min_pu_size;
+
+ for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+ int x_pu = (x0 + i) >> log2_min_pu_size;
+ MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
+ MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+
+ bs = boundary_strength(s, curr, top, refPicList);
+ s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
+ }
+ }
+
+ // bs for TU internal vertical PU boundaries
for (j = 0; j < (1 << log2_trafo_size); j += 4) {
int y_pu = (y0 + j) >> log2_min_pu_size;
- int y_tu = (y0 + j) >> log2_min_tu_size;
for (i = 8; i < (1 << log2_trafo_size); i += 8) {
int xp_pu = (x0 + i - 1) >> log2_min_pu_size;
int xq_pu = (x0 + i) >> log2_min_pu_size;
- int xp_tu = (x0 + i - 1) >> log2_min_tu_size;
- int xq_tu = (x0 + i) >> log2_min_tu_size;
MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
- uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
- uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
- RefPicList *left_refPicList = ff_hevc_get_ref_list(s, s->ref,
- x0 + i - 1,
- y0 + j);
-
- bs = boundary_strength(s, curr, curr_cbf_luma,
- left, left_cbf_luma, left_refPicList, 0);
- if (s->sh.disable_deblocking_filter_flag == 1)
- bs = 0;
- if (bs)
- s->vertical_bs[((x0 + i) >> 3) + ((y0 + j) >> 2) * s->bs_width] = bs;
+
+ bs = boundary_strength(s, curr, left, refPicList);
+ s->vertical_bs[((x0 + i) >> 3) + ((y0 + j) >> 2) * s->bs_width] = bs;
}
}
+ }
}
#undef LUMA