*/
#include "hevc.h"
+#include "hevcdec.h"
static const uint8_t l0_l1_cand_idx[12][2] = {
{ 0, 1, },
int nPbW, int nPbH)
{
HEVCLocalContext *lc = &s->HEVClc;
- int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
- int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int x0b = x0 & ((1 << s->ps.sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->ps.sps->log2_ctb_size) - 1);
lc->na.cand_up = (lc->ctb_up_flag || y0b);
lc->na.cand_left = (lc->ctb_left_flag || x0b);
lc->na.cand_up_left = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up;
lc->na.cand_up_right_sap =
- ((x0b + nPbW) == (1 << s->sps->log2_ctb_size)) ?
+ ((x0b + nPbW) == (1 << s->ps.sps->log2_ctb_size)) ?
lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
lc->na.cand_up_right =
- ((x0b + nPbW) == (1 << s->sps->log2_ctb_size) ?
+ ((x0b + nPbW) == (1 << s->ps.sps->log2_ctb_size) ?
lc->ctb_up_right_flag && !y0b : lc->na.cand_up )
&& (x0 + nPbW) < lc->end_of_tiles_x;
lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
int xN, int yN)
{
#define MIN_TB_ADDR_ZS(x, y) \
- s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
- int Curr = MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_tb_size,
- yCurr >> s->sps->log2_min_tb_size);
+ s->ps.pps->min_tb_addr_zs[(y) * s->ps.sps->min_tb_width + (x)]
+ int Curr = MIN_TB_ADDR_ZS(xCurr >> s->ps.sps->log2_min_tb_size,
+ yCurr >> s->ps.sps->log2_min_tb_size);
int N;
if (xN < 0 || yN < 0 ||
- xN >= s->sps->width ||
- yN >= s->sps->height)
+ xN >= s->ps.sps->width ||
+ yN >= s->ps.sps->height)
return 0;
- N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_tb_size,
- yN >> s->sps->log2_min_tb_size);
+ N = MIN_TB_ADDR_ZS(xN >> s->ps.sps->log2_min_tb_size,
+ yN >> s->ps.sps->log2_min_tb_size);
return N <= Curr;
}
return z_scan_block_avail(s, x0, y0, xA1, yA1);
}
-//check if the two luma locations belong to the same mostion estimation region
+//check if the two luma locations belong to the same motion estimation region
static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP)
{
- uint8_t plevel = s->pps->log2_parallel_merge_level;
+ uint8_t plevel = s->ps.pps->log2_parallel_merge_level;
return xN >> plevel == xP >> plevel &&
yN >> plevel == yP >> plevel;
}
+#define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x))
#define MATCH(x) (A.x == B.x)
// check if the mv's and refidx are the same between A and B
static int compareMVrefidx(struct MvField A, struct MvField B)
{
if (A.pred_flag[0] && A.pred_flag[1] && B.pred_flag[0] && B.pred_flag[1])
- return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y) &&
- MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y);
+ return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) &&
+ MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
if (A.pred_flag[0] && !A.pred_flag[1] && B.pred_flag[0] && !B.pred_flag[1])
- return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y);
+ return MATCH(ref_idx[0]) && MATCH_MV(mv[0]);
if (!A.pred_flag[0] && A.pred_flag[1] && !B.pred_flag[0] && B.pred_flag[1])
- return MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y);
+ return MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
return 0;
}
{
int tx, scale_factor;
- td = av_clip_int8_c(td);
- tb = av_clip_int8_c(tb);
+ td = av_clip_int8(td);
+ tb = av_clip_int8(tb);
tx = (0x4000 + abs(td / 2)) / td;
- scale_factor = av_clip_c((tb * tx + 32) >> 6, -4096, 4095);
- dst->x = av_clip_int16_c((scale_factor * src->x + 127 +
+ scale_factor = av_clip((tb * tx + 32) >> 6, -4096, 4095);
+ dst->x = av_clip_int16((scale_factor * src->x + 127 +
(scale_factor * src->x < 0)) >> 8);
- dst->y = av_clip_int16_c((scale_factor * src->y + 127 +
+ dst->y = av_clip_int16((scale_factor * src->y + 127 +
(scale_factor * src->y < 0)) >> 8);
}
MvField *tab_mvf;
MvField temp_col;
int x, y, x_pu, y_pu;
- int min_pu_width = s->sps->min_pu_width;
+ int min_pu_width = s->ps.sps->min_pu_width;
int availableFlagLXCol = 0;
int colPic;
HEVCFrame *ref = s->ref->collocated_ref;
- if (!ref)
+ if (!ref) {
+ memset(mvLXCol, 0, sizeof(*mvLXCol));
return 0;
+ }
tab_mvf = ref->tab_mvf;
colPic = ref->poc;
x = x0 + nPbW;
y = y0 + nPbH;
- ff_thread_await_progress(&ref->tf, y, 0);
if (tab_mvf &&
- (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
- y < s->sps->height &&
- x < s->sps->width) {
+ (y0 >> s->ps.sps->log2_ctb_size) == (y >> s->ps.sps->log2_ctb_size) &&
+ y < s->ps.sps->height &&
+ x < s->ps.sps->width) {
x &= ~15;
y &= ~15;
- x_pu = x >> s->sps->log2_min_pu_size;
- y_pu = y >> s->sps->log2_min_pu_size;
+ ff_thread_await_progress(&ref->tf, y, 0);
+ x_pu = x >> s->ps.sps->log2_min_pu_size;
+ y_pu = y >> s->ps.sps->log2_min_pu_size;
temp_col = TAB_MVF(x_pu, y_pu);
availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
}
y = y0 + (nPbH >> 1);
x &= ~15;
y &= ~15;
- x_pu = x >> s->sps->log2_min_pu_size;
- y_pu = y >> s->sps->log2_min_pu_size;
+ ff_thread_await_progress(&ref->tf, y, 0);
+ x_pu = x >> s->ps.sps->log2_min_pu_size;
+ y_pu = y >> s->ps.sps->log2_min_pu_size;
temp_col = TAB_MVF(x_pu, y_pu);
availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
}
RefPicList *refPicList = s->ref->refPicList;
MvField *tab_mvf = s->ref->tab_mvf;
- const int min_pu_width = s->sps->min_pu_width;
+ const int min_pu_width = s->ps.sps->min_pu_width;
const int cand_bottom_left = lc->na.cand_bottom_left;
const int cand_left = lc->na.cand_left;
const int xA1 = x0 - 1;
const int yA1 = y0 + nPbH - 1;
- const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
- const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
+ const int xA1_pu = xA1 >> s->ps.sps->log2_min_pu_size;
+ const int yA1_pu = yA1 >> s->ps.sps->log2_min_pu_size;
const int xB1 = x0 + nPbW - 1;
const int yB1 = y0 - 1;
- const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;
- const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;
+ const int xB1_pu = xB1 >> s->ps.sps->log2_min_pu_size;
+ const int yB1_pu = yB1 >> s->ps.sps->log2_min_pu_size;
const int xB0 = x0 + nPbW;
const int yB0 = y0 - 1;
- const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;
- const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;
+ const int xB0_pu = xB0 >> s->ps.sps->log2_min_pu_size;
+ const int yB0_pu = yB0 >> s->ps.sps->log2_min_pu_size;
const int xA0 = x0 - 1;
const int yA0 = y0 + nPbH;
- const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;
- const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;
+ const int xA0_pu = xA0 >> s->ps.sps->log2_min_pu_size;
+ const int yA0_pu = yA0 >> s->ps.sps->log2_min_pu_size;
const int xB2 = x0 - 1;
const int yB2 = y0 - 1;
- const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;
- const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;
+ const int xB2_pu = xB2 >> s->ps.sps->log2_min_pu_size;
+ const int yB2_pu = yB2 >> s->ps.sps->log2_min_pu_size;
- const int nb_refs = (s->sh.slice_type == P_SLICE) ?
+ const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ?
s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
int check_MER = 1;
int check_MER_1 = 1;
// temporal motion vector candidate
if (s->sh.slice_temporal_mvp_enabled_flag &&
nb_merge_cand < s->sh.max_num_merge_cand) {
- Mv mv_l0_col, mv_l1_col;
+ Mv mv_l0_col = { 0 }, mv_l1_col = { 0 };
int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
0, &mv_l0_col, 0);
- int available_l1 = (s->sh.slice_type == B_SLICE) ?
+ int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ?
temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
0, &mv_l1_col, 1) : 0;
mergecandlist[nb_merge_cand].is_intra = 0;
mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;
mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;
- if (available_l0) {
- mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
- mergecandlist[nb_merge_cand].ref_idx[0] = 0;
- }
- if (available_l1) {
- mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
- mergecandlist[nb_merge_cand].ref_idx[1] = 0;
- }
+ AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);
+ mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
+ mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
+
if (merge_idx == nb_merge_cand)
return;
nb_merge_cand++;
nb_orig_merge_cand = nb_merge_cand;
// combined bi-predictive merge candidates (applies for B slices)
- if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
+ if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 &&
nb_orig_merge_cand < s->sh.max_num_merge_cand) {
int comb_idx;
if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&
(refPicList[0].list[l0_cand.ref_idx[0]] !=
refPicList[1].list[l1_cand.ref_idx[1]] ||
- l0_cand.mv[0].x != l1_cand.mv[1].x ||
- l0_cand.mv[0].y != l1_cand.mv[1].y)) {
+ AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {
mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
mergecandlist[nb_merge_cand].pred_flag[0] = 1;
mergecandlist[nb_merge_cand].pred_flag[1] = 1;
- mergecandlist[nb_merge_cand].mv[0].x = l0_cand.mv[0].x;
- mergecandlist[nb_merge_cand].mv[0].y = l0_cand.mv[0].y;
- mergecandlist[nb_merge_cand].mv[1].x = l1_cand.mv[1].x;
- mergecandlist[nb_merge_cand].mv[1].y = l1_cand.mv[1].y;
+ AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);
+ AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);
mergecandlist[nb_merge_cand].is_intra = 0;
if (merge_idx == nb_merge_cand)
return;
// append Zero motion vector candidates
while (nb_merge_cand < s->sh.max_num_merge_cand) {
mergecandlist[nb_merge_cand].pred_flag[0] = 1;
- mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;
- mergecandlist[nb_merge_cand].mv[0].x = 0;
- mergecandlist[nb_merge_cand].mv[0].y = 0;
- mergecandlist[nb_merge_cand].mv[1].x = 0;
- mergecandlist[nb_merge_cand].mv[1].y = 0;
+ mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == HEVC_SLICE_B;
+ AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);
+ AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);
mergecandlist[nb_merge_cand].is_intra = 0;
mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
{
int singleMCLFlag = 0;
int nCS = 1 << log2_cb_size;
- struct MvField mergecand_list[MRG_MAX_NUM_CANDS] = { { { { 0 } } } };
+ LOCAL_ALIGNED(4, MvField, mergecand_list, [MRG_MAX_NUM_CANDS]);
int nPbW2 = nPbW;
int nPbH2 = nPbH;
HEVCLocalContext *lc = &s->HEVClc;
- if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) {
+ if (s->ps.pps->log2_parallel_merge_level > 2 && nCS == 8) {
singleMCLFlag = 1;
x0 = lc->cu.x;
y0 = lc->cu.y;
Mv *mv, int ref_idx_curr, int ref_idx)
{
MvField *tab_mvf = s->ref->tab_mvf;
- int min_pu_width = s->sps->min_pu_width;
+ int min_pu_width = s->ps.sps->min_pu_width;
RefPicList *refPicList = s->ref->refPicList;
Mv *mv, int ref_idx_curr, int ref_idx)
{
MvField *tab_mvf = s->ref->tab_mvf;
- int min_pu_width = s->sps->min_pu_width;
+ int min_pu_width = s->ps.sps->min_pu_width;
RefPicList *refPicList = s->ref->refPicList;
int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
int availableFlagLXA0 = 0;
int availableFlagLXB0 = 0;
int numMVPCandLX = 0;
- int min_pu_width = s->sps->min_pu_width;
+ int min_pu_width = s->ps.sps->min_pu_width;
int xA0, yA0;
int xA0_pu, yA0_pu;
int ref_idx = 0;
int pred_flag_index_l0;
int pred_flag_index_l1;
- int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
- int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int x0b = x0 & ((1 << s->ps.sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->ps.sps->log2_ctb_size) - 1);
int cand_up = (lc->ctb_up_flag || y0b);
int cand_left = (lc->ctb_left_flag || x0b);
int cand_up_left =
(!x0b && !y0b) ? lc->ctb_up_left_flag : cand_left && cand_up;
int cand_up_right =
- (x0b + nPbW == (1 << s->sps->log2_ctb_size) ||
+ (x0b + nPbW == (1 << s->ps.sps->log2_ctb_size) ||
x0 + nPbW >= lc->end_of_tiles_x) ? lc->ctb_up_right_flag && !y0b
: cand_up;
int cand_bottom_left = (y0 + nPbH >= lc->end_of_tiles_y) ? 0 : cand_left;
// left bottom spatial candidate
xA0 = x0 - 1;
yA0 = y0 + nPbH;
- xA0_pu = xA0 >> s->sps->log2_min_pu_size;
- yA0_pu = yA0 >> s->sps->log2_min_pu_size;
+ xA0_pu = xA0 >> s->ps.sps->log2_min_pu_size;
+ yA0_pu = yA0 >> s->ps.sps->log2_min_pu_size;
is_available_a0 = PRED_BLOCK_AVAILABLE(A0) && AVAILABLE(cand_bottom_left, A0);
//left spatial merge candidate
xA1 = x0 - 1;
yA1 = y0 + nPbH - 1;
- xA1_pu = xA1 >> s->sps->log2_min_pu_size;
- yA1_pu = yA1 >> s->sps->log2_min_pu_size;
+ xA1_pu = xA1 >> s->ps.sps->log2_min_pu_size;
+ yA1_pu = yA1 >> s->ps.sps->log2_min_pu_size;
is_available_a1 = AVAILABLE(cand_left, A1);
if (is_available_a0 || is_available_a1)
// above right spatial merge candidate
xB0 = x0 + nPbW;
yB0 = y0 - 1;
- xB0_pu = xB0 >> s->sps->log2_min_pu_size;
- yB0_pu = yB0 >> s->sps->log2_min_pu_size;
+ xB0_pu = xB0 >> s->ps.sps->log2_min_pu_size;
+ yB0_pu = yB0 >> s->ps.sps->log2_min_pu_size;
is_available_b0 = PRED_BLOCK_AVAILABLE(B0) && AVAILABLE(cand_up_right, B0);
// above spatial merge candidate
xB1 = x0 + nPbW - 1;
yB1 = y0 - 1;
- xB1_pu = xB1 >> s->sps->log2_min_pu_size;
- yB1_pu = yB1 >> s->sps->log2_min_pu_size;
+ xB1_pu = xB1 >> s->ps.sps->log2_min_pu_size;
+ yB1_pu = yB1 >> s->ps.sps->log2_min_pu_size;
is_available_b1 = AVAILABLE(cand_up, B1);
// above left spatial merge candidate
xB2 = x0 - 1;
yB2 = y0 - 1;
- xB2_pu = xB2 >> s->sps->log2_min_pu_size;
- yB2_pu = yB2 >> s->sps->log2_min_pu_size;
+ xB2_pu = xB2 >> s->ps.sps->log2_min_pu_size;
+ yB2_pu = yB2 >> s->ps.sps->log2_min_pu_size;
is_available_b2 = AVAILABLE(cand_up_left, B2);
if (is_available_b2) {
mvpcand_list[numMVPCandLX++] = mxB;
//temporal motion vector prediction candidate
- if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag) {
+ if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
+ mvp_lx_flag == numMVPCandLX) {
Mv mv_col;
int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
nPbH, ref_idx,