Square prediction units are the most common.
About 0.7% faster on 4k videos.
---
 libavcodec/hevc.c             | 64 +++++++++++++++++++++++++++++++++----------
 libavcodec/hevcdsp.c          |  6 ++++
 libavcodec/hevcdsp.h          |  2 ++
 libavcodec/hevcdsp_template.c | 16 +++++++++++
 4 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 1634185..7d15ed3 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -27,6 +27,7 @@
 #include "libavutil/common.h"
 #include "libavutil/display.h"
 #include "libavutil/internal.h"
+#include "libavutil/intmath.h"
 #include "libavutil/md5.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
@@ -1652,9 +1653,27 @@ static void hevc_await_progress(HEVCContext *s, 
HEVCFrame *ref,
     ff_thread_await_progress(&ref->tf, y, 0);
 }
 
-static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
-                                int nPbW, int nPbH,
-                                int log2_cb_size, int partIdx)
+av_always_inline
+static void put_unweighted_pred(HEVCContext *s,
+                                uint8_t *dst, ptrdiff_t dststride,
+                                int16_t *src, ptrdiff_t srcstride,
+                                int width, int height, int square)
+{
+    if (!square) {
+        s->hevcdsp.put_unweighted_pred(dst, dststride,
+                                       src, srcstride, width, height);
+    } else {
+        const int square = av_log2_16bit(width) - 2;
+        s->hevcdsp.put_unweighted_pred_square[square](dst, dststride,
+                                                      src, srcstride);
+    }
+}
+
+av_always_inline
+static void hls_prediction_unit_internal(HEVCContext *s, int x0, int y0,
+                                         int nPbW, int nPbH,
+                                         int log2_cb_size, int partIdx,
+                                         int square)
 {
 #define POS(c_idx, x, y)                                                       
       \
     &s->frame->data[c_idx][((y) >> s->sps->vshift[c_idx]) * 
s->frame->linesize[c_idx] + \
@@ -1796,7 +1815,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, 
int y0,
                                      dst0, s->frame->linesize[0], tmp,
                                      tmpstride, nPbW, nPbH);
         } else {
-            s->hevcdsp.put_unweighted_pred(dst0, s->frame->linesize[0], tmp, 
tmpstride, nPbW, nPbH);
+            put_unweighted_pred(s, dst0, s->frame->linesize[0], tmp, 
tmpstride, nPbW, nPbH, square);
         }
         chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame,
                   &current_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
@@ -1814,8 +1833,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, 
int y0,
                                      dst2, s->frame->linesize[2], tmp2, 
tmpstride,
                                      nPbW / 2, nPbH / 2);
         } else {
-            s->hevcdsp.put_unweighted_pred(dst1, s->frame->linesize[1], tmp, 
tmpstride, nPbW/2, nPbH/2);
-            s->hevcdsp.put_unweighted_pred(dst2, s->frame->linesize[2], tmp2, 
tmpstride, nPbW/2, nPbH/2);
+            put_unweighted_pred(s, dst1, s->frame->linesize[1], tmp, 
tmpstride, nPbW / 2, nPbH / 2, square);
+            put_unweighted_pred(s, dst2, s->frame->linesize[2], tmp2, 
tmpstride, nPbW / 2, nPbH / 2, square);
         }
     } else if (!current_mv.pred_flag[0] && current_mv.pred_flag[1]) {
         DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
@@ -1835,7 +1854,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, 
int y0,
                                       dst0, s->frame->linesize[0], tmp, 
tmpstride,
                                       nPbW, nPbH);
         } else {
-            s->hevcdsp.put_unweighted_pred(dst0, s->frame->linesize[0], tmp, 
tmpstride, nPbW, nPbH);
+            put_unweighted_pred(s, dst0, s->frame->linesize[0], tmp, 
tmpstride, nPbW, nPbH, square);
         }
 
         chroma_mc(s, tmp, tmp2, tmpstride, ref1->frame,
@@ -1852,8 +1871,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, 
int y0,
                                      
s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1],
                                      dst2, s->frame->linesize[2], tmp2, 
tmpstride, nPbW/2, nPbH/2);
         } else {
-            s->hevcdsp.put_unweighted_pred(dst1, s->frame->linesize[1], tmp, 
tmpstride, nPbW/2, nPbH/2);
-            s->hevcdsp.put_unweighted_pred(dst2, s->frame->linesize[2], tmp2, 
tmpstride, nPbW/2, nPbH/2);
+            put_unweighted_pred(s, dst1, s->frame->linesize[1], tmp, 
tmpstride, nPbW / 2, nPbH / 2, square);
+            put_unweighted_pred(s, dst2, s->frame->linesize[2], tmp2, 
tmpstride, nPbW / 2, nPbH / 2, square);
         }
     } else if (current_mv.pred_flag[0] && current_mv.pred_flag[1]) {
         DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
@@ -1913,6 +1932,21 @@ static void hls_prediction_unit(HEVCContext *s, int x0, 
int y0,
     }
 }
 
+
+static void hls_prediction_unit_square(HEVCContext *s, int x0, int y0,
+                                       int cb_size, int log2_cb_size,
+                                       int partIdx)
+{
+    hls_prediction_unit_internal(s, x0, y0, cb_size, cb_size, log2_cb_size, 
partIdx, 1);
+}
+
+static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
+                                int nPbW, int nPbH,
+                                int log2_cb_size, int partIdx)
+{
+    hls_prediction_unit_internal(s, x0, y0, nPbW, nPbH, log2_cb_size, partIdx, 
0);
+}
+
 /**
  * 8.4.1
  */
@@ -2121,7 +2155,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int 
y0, int log2_cb_size)
     }
 
     if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
-        hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
+        hls_prediction_unit_square(s, x0, y0, cb_size, log2_cb_size, 0);
         intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
 
         if (!s->sh.disable_deblocking_filter_flag)
@@ -2159,7 +2193,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int 
y0, int log2_cb_size)
             intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
             switch (lc->cu.part_mode) {
             case PART_2Nx2N:
-                hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 
0);
+                hls_prediction_unit_square(s, x0, y0, cb_size, log2_cb_size, 
0);
                 break;
             case PART_2NxN:
                 hls_prediction_unit(s, x0, y0,               cb_size, cb_size 
/ 2, log2_cb_size, 0);
@@ -2186,10 +2220,10 @@ static int hls_coding_unit(HEVCContext *s, int x0, int 
y0, int log2_cb_size)
                 hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size     / 
4, cb_size, log2_cb_size, 1);
                 break;
             case PART_NxN:
-                hls_prediction_unit(s, x0,               y0,               
cb_size / 2, cb_size / 2, log2_cb_size, 0);
-                hls_prediction_unit(s, x0 + cb_size / 2, y0,               
cb_size / 2, cb_size / 2, log2_cb_size, 1);
-                hls_prediction_unit(s, x0,               y0 + cb_size / 2, 
cb_size / 2, cb_size / 2, log2_cb_size, 2);
-                hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, 
cb_size / 2, cb_size / 2, log2_cb_size, 3);
+                hls_prediction_unit_square(s, x0,               y0,            
   cb_size / 2, log2_cb_size, 0);
+                hls_prediction_unit_square(s, x0 + cb_size / 2, y0,            
   cb_size / 2, log2_cb_size, 1);
+                hls_prediction_unit_square(s, x0,               y0 + cb_size / 
2, cb_size / 2, log2_cb_size, 2);
+                hls_prediction_unit_square(s, x0 + cb_size / 2, y0 + cb_size / 
2, cb_size / 2, log2_cb_size, 3);
                 break;
             }
         }
diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c
index 969c11c..883503b 100644
--- a/libavcodec/hevcdsp.c
+++ b/libavcodec/hevcdsp.c
@@ -166,6 +166,12 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int 
bit_depth)
     hevcdsp->put_hevc_epel[1][1] = FUNC(put_hevc_epel_hv, depth);           \
                                                                             \
     hevcdsp->put_unweighted_pred   = FUNC(put_unweighted_pred, depth);      \
+    hevcdsp->put_unweighted_pred_square[0] = FUNC(put_unweighted_pred_4, 
depth);  \
+    hevcdsp->put_unweighted_pred_square[1] = FUNC(put_unweighted_pred_8, 
depth);  \
+    hevcdsp->put_unweighted_pred_square[2] = FUNC(put_unweighted_pred_16, 
depth); \
+    hevcdsp->put_unweighted_pred_square[3] = FUNC(put_unweighted_pred_32, 
depth); \
+    hevcdsp->put_unweighted_pred_square[4] = FUNC(put_unweighted_pred_64, 
depth); \
+                                                                               
          \
     hevcdsp->put_weighted_pred_avg = FUNC(put_weighted_pred_avg, depth);    \
                                                                             \
     hevcdsp->weighted_pred         = FUNC(weighted_pred, depth);            \
diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h
index 1665ad6..139f48d 100644
--- a/libavcodec/hevcdsp.h
+++ b/libavcodec/hevcdsp.h
@@ -68,6 +68,8 @@ typedef struct HEVCDSPContext {
 
     void (*put_unweighted_pred)(uint8_t *dst, ptrdiff_t dststride, int16_t 
*src,
                                 ptrdiff_t srcstride, int width, int height);
+    void (*put_unweighted_pred_square[5])(uint8_t *dst, ptrdiff_t dststride, 
int16_t *src,
+                                          ptrdiff_t srcstride);
     void (*put_weighted_pred_avg)(uint8_t *dst, ptrdiff_t dststride,
                                   int16_t *src1, int16_t *src2,
                                   ptrdiff_t srcstride, int width, int height);
diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c
index 72e50b5..429ec20 100644
--- a/libavcodec/hevcdsp_template.c
+++ b/libavcodec/hevcdsp_template.c
@@ -1031,6 +1031,7 @@ static void FUNC(put_hevc_epel_hv)(int16_t *dst, 
ptrdiff_t dststride,
     }
 }
 
+av_always_inline
 static void FUNC(put_unweighted_pred)(uint8_t *_dst, ptrdiff_t _dststride,
                                       int16_t *src, ptrdiff_t srcstride,
                                       int width, int height)
@@ -1053,6 +1054,21 @@ static void FUNC(put_unweighted_pred)(uint8_t *_dst, 
ptrdiff_t _dststride,
     }
 }
 
+#define UNWEIGHTED_PRED_SQUARE(size)                                         \
+static void FUNC(put_unweighted_pred_ ## size) (uint8_t * _dst,              \
+                                                ptrdiff_t _dststride,        \
+                                                int16_t * src,               \
+                                                ptrdiff_t srcstride)         \
+{                                                                            \
+    FUNC(put_unweighted_pred)(_dst, _dststride, src, srcstride, size, size); \
+}
+
+UNWEIGHTED_PRED_SQUARE(4)
+UNWEIGHTED_PRED_SQUARE(8)
+UNWEIGHTED_PRED_SQUARE(16)
+UNWEIGHTED_PRED_SQUARE(32)
+UNWEIGHTED_PRED_SQUARE(64)
+
 static void FUNC(put_weighted_pred_avg)(uint8_t *_dst, ptrdiff_t _dststride,
                                         int16_t *src1, int16_t *src2,
                                         ptrdiff_t srcstride,
-- 
1.9.0

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to