From cf6090dc6252f2b276aa4133e3d73a89f4c6046c Mon Sep 17 00:00:00 2001 From: Christophe Gisquet Date: Fri, 8 Aug 2014 18:21:02 +0000 Subject: [PATCH] hevc: use intreadwrite When dealing with MVs, both components may be processed at a time. Signed-off-by: Anton Khirnov --- libavcodec/hevc.c | 3 +-- libavcodec/hevc.h | 2 +- libavcodec/hevc_mvs.c | 26 +++++++++++--------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 4794e4b0f3..ef41ddfe7b 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -1714,8 +1714,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, } if (s->sh.mvd_l1_zero_flag == 1 && inter_pred_idc == PRED_BI) { - lc->pu.mvd.x = 0; - lc->pu.mvd.y = 0; + AV_ZERO32(&lc->pu.mvd); } else { hls_mvd_coding(s, x0, y0, 1); } diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 03980b729c..93c5125665 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -621,7 +621,7 @@ typedef struct Mv { } Mv; typedef struct MvField { - Mv mv[2]; + DECLARE_ALIGNED(4, Mv, mv)[2]; int8_t ref_idx[2]; int8_t pred_flag[2]; uint8_t is_intra; diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c index 8d86b59b17..89b514f24e 100644 --- a/libavcodec/hevc_mvs.c +++ b/libavcodec/hevc_mvs.c @@ -118,20 +118,21 @@ static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP) 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; } @@ -508,16 +509,13 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, 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; @@ -530,10 +528,8 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, 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; + 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; @@ -554,7 +550,7 @@ void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, { 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;