[FFmpeg-devel] [PATCH] vp9: split segmentation map / mvpair references.

2015-03-08 Thread Ronald S. Bultje
This prevents a memcpy if segmentation.update_map == false.
---
 libavcodec/vp9.c | 72 ++--
 1 file changed, 34 insertions(+), 38 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index aff86d0..6f129f0 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -74,6 +74,7 @@ typedef struct VP9Frame {
 AVBufferRef *extradata;
 uint8_t *segmentation_map;
 struct VP9mvrefPair *mv;
+int uses_2pass;
 } VP9Frame;
 
 struct VP9Filter {
@@ -100,7 +101,7 @@ typedef struct VP9Context {
 VP56RangeCoder *c_b;
 unsigned c_b_size;
 VP9Block *b_base, *b;
-int pass, uses_2pass, last_uses_2pass;
+int pass;
 int row, row7, col, col7;
 uint8_t *dst[3];
 ptrdiff_t y_stride, uv_stride;
@@ -128,8 +129,9 @@ typedef struct VP9Context {
 uint8_t varcompref[2];
 ThreadFrame refs[8], next_refs[8];
 #define CUR_FRAME 0
-#define LAST_FRAME 1
-VP9Frame frames[2];
+#define REF_FRAME_MVPAIR 1
+#define REF_FRAME_SEGMAP 2
+VP9Frame frames[3];
 
 struct {
 uint8_t level;
@@ -277,13 +279,6 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame 
*f)
 f-segmentation_map = f-extradata-data;
 f-mv = (struct VP9mvrefPair *) (f-extradata-data + sz);
 
-// retain segmentation map if it doesn't update
-if (s-segmentation.enabled  !s-segmentation.update_map 
-!s-intraonly  !s-keyframe  !s-errorres 
-ctx-active_thread_type != FF_THREAD_FRAME) {
-memcpy(f-segmentation_map, s-frames[LAST_FRAME].segmentation_map, 
sz);
-}
-
 return 0;
 }
 
@@ -362,12 +357,12 @@ static int update_block_buffers(AVCodecContext *ctx)
 {
 VP9Context *s = ctx-priv_data;
 
-if (s-b_base  s-block_base  s-block_alloc_using_2pass == 
s-uses_2pass)
+if (s-b_base  s-block_base  s-block_alloc_using_2pass == 
s-frames[CUR_FRAME].uses_2pass)
 return 0;
 
 av_free(s-b_base);
 av_free(s-block_base);
-if (s-uses_2pass) {
+if (s-frames[CUR_FRAME].uses_2pass) {
 int sbs = s-sb_cols * s-sb_rows;
 
 s-b_base = av_malloc_array(s-cols * s-rows, sizeof(VP9Block));
@@ -390,7 +385,7 @@ static int update_block_buffers(AVCodecContext *ctx)
 s-uveob_base[0] = s-eob_base + 256;
 s-uveob_base[1] = s-uveob_base[0] + 64;
 }
-s-block_alloc_using_2pass = s-uses_2pass;
+s-block_alloc_using_2pass = s-frames[CUR_FRAME].uses_2pass;
 
 return 0;
 }
@@ -491,7 +486,6 @@ static int decode_frame_header(AVCodecContext *ctx,
 *ref = get_bits(s-gb, 3);
 return 0;
 }
-s-last_uses_2pass = s-uses_2pass;
 s-last_keyframe  = s-keyframe;
 s-keyframe   = !get_bits1(s-gb);
 last_invisible= s-invisible;
@@ -1082,10 +1076,10 @@ static void find_ref_mvs(VP9Context *s,
 
 // MV at this position in previous frame, using same reference frame
 if (s-use_last_frame_mvs) {
-struct VP9mvrefPair *mv = s-frames[LAST_FRAME].mv[row * s-sb_cols * 
8 + col];
+struct VP9mvrefPair *mv = s-frames[REF_FRAME_MVPAIR].mv[row * 
s-sb_cols * 8 + col];
 
-if (!s-last_uses_2pass)
-ff_thread_await_progress(s-frames[LAST_FRAME].tf, row  3, 0);
+if (!s-frames[REF_FRAME_MVPAIR].uses_2pass)
+ff_thread_await_progress(s-frames[REF_FRAME_MVPAIR].tf, row  
3, 0);
 if (mv-ref[0] == ref) {
 RETURN_MV(mv-mv[0]);
 } else if (mv-ref[1] == ref) {
@@ -1124,7 +1118,7 @@ static void find_ref_mvs(VP9Context *s,
 
 // MV at this position in previous frame, using different reference frame
 if (s-use_last_frame_mvs) {
-struct VP9mvrefPair *mv = s-frames[LAST_FRAME].mv[row * s-sb_cols * 
8 + col];
+struct VP9mvrefPair *mv = s-frames[REF_FRAME_MVPAIR].mv[row * 
s-sb_cols * 8 + col];
 
 // no need to await_progress, because we already did that above
 if (mv-ref[0] != ref  mv-ref[0] = 0) {
@@ -1348,21 +1342,14 @@ static void decode_mode(AVCodecContext *ctx)
 s-left_segpred_ctx[row7]]))) {
 if (!s-errorres) {
 int pred = 8, x;
-uint8_t *refsegmap = s-frames[LAST_FRAME].segmentation_map;
+uint8_t *refsegmap = s-frames[REF_FRAME_SEGMAP].segmentation_map;
 
-if (!s-last_uses_2pass)
-ff_thread_await_progress(s-frames[LAST_FRAME].tf, row  3, 
0);
+if (!s-frames[REF_FRAME_SEGMAP].uses_2pass)
+ff_thread_await_progress(s-frames[REF_FRAME_SEGMAP].tf, row 
 3, 0);
 for (y = 0; y  h4; y++) {
 int idx_base = (y + row) * 8 * s-sb_cols + col;
 for (x = 0; x  w4; x++)
 pred = FFMIN(pred, refsegmap[idx_base + x]);
-if (!s-segmentation.update_map  ctx-active_thread_type == 
FF_THREAD_FRAME) {
-// FIXME maybe retain reference to previous frame as
-// segmap reference instead of copying the whole map
- 

[FFmpeg-devel] [PATCH] vp9: split segmentation map / mvpair references.

2015-03-07 Thread Ronald S. Bultje
This prevents a memcpy if segmentation.update_map == false.
---
 libavcodec/vp9.c | 68 ++--
 1 file changed, 32 insertions(+), 36 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index aff86d0..6ac2935 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -74,6 +74,7 @@ typedef struct VP9Frame {
 AVBufferRef *extradata;
 uint8_t *segmentation_map;
 struct VP9mvrefPair *mv;
+int uses_2pass;
 } VP9Frame;
 
 struct VP9Filter {
@@ -100,7 +101,7 @@ typedef struct VP9Context {
 VP56RangeCoder *c_b;
 unsigned c_b_size;
 VP9Block *b_base, *b;
-int pass, uses_2pass, last_uses_2pass;
+int pass;
 int row, row7, col, col7;
 uint8_t *dst[3];
 ptrdiff_t y_stride, uv_stride;
@@ -128,8 +129,9 @@ typedef struct VP9Context {
 uint8_t varcompref[2];
 ThreadFrame refs[8], next_refs[8];
 #define CUR_FRAME 0
-#define LAST_FRAME 1
-VP9Frame frames[2];
+#define REF_FRAME_MVPAIR 1
+#define REF_FRAME_SEGMAP 2
+VP9Frame frames[3];
 
 struct {
 uint8_t level;
@@ -277,13 +279,6 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame 
*f)
 f-segmentation_map = f-extradata-data;
 f-mv = (struct VP9mvrefPair *) (f-extradata-data + sz);
 
-// retain segmentation map if it doesn't update
-if (s-segmentation.enabled  !s-segmentation.update_map 
-!s-intraonly  !s-keyframe  !s-errorres 
-ctx-active_thread_type != FF_THREAD_FRAME) {
-memcpy(f-segmentation_map, s-frames[LAST_FRAME].segmentation_map, 
sz);
-}
-
 return 0;
 }
 
@@ -362,12 +357,12 @@ static int update_block_buffers(AVCodecContext *ctx)
 {
 VP9Context *s = ctx-priv_data;
 
-if (s-b_base  s-block_base  s-block_alloc_using_2pass == 
s-uses_2pass)
+if (s-b_base  s-block_base  s-block_alloc_using_2pass == 
s-frames[CUR_FRAME].uses_2pass)
 return 0;
 
 av_free(s-b_base);
 av_free(s-block_base);
-if (s-uses_2pass) {
+if (s-frames[CUR_FRAME].uses_2pass) {
 int sbs = s-sb_cols * s-sb_rows;
 
 s-b_base = av_malloc_array(s-cols * s-rows, sizeof(VP9Block));
@@ -390,7 +385,7 @@ static int update_block_buffers(AVCodecContext *ctx)
 s-uveob_base[0] = s-eob_base + 256;
 s-uveob_base[1] = s-uveob_base[0] + 64;
 }
-s-block_alloc_using_2pass = s-uses_2pass;
+s-block_alloc_using_2pass = s-frames[CUR_FRAME].uses_2pass;
 
 return 0;
 }
@@ -491,7 +486,6 @@ static int decode_frame_header(AVCodecContext *ctx,
 *ref = get_bits(s-gb, 3);
 return 0;
 }
-s-last_uses_2pass = s-uses_2pass;
 s-last_keyframe  = s-keyframe;
 s-keyframe   = !get_bits1(s-gb);
 last_invisible= s-invisible;
@@ -1082,10 +1076,10 @@ static void find_ref_mvs(VP9Context *s,
 
 // MV at this position in previous frame, using same reference frame
 if (s-use_last_frame_mvs) {
-struct VP9mvrefPair *mv = s-frames[LAST_FRAME].mv[row * s-sb_cols * 
8 + col];
+struct VP9mvrefPair *mv = s-frames[REF_FRAME_MVPAIR].mv[row * 
s-sb_cols * 8 + col];
 
-if (!s-last_uses_2pass)
-ff_thread_await_progress(s-frames[LAST_FRAME].tf, row  3, 0);
+if (!s-frames[REF_FRAME_MVPAIR].uses_2pass)
+ff_thread_await_progress(s-frames[REF_FRAME_MVPAIR].tf, row  
3, 0);
 if (mv-ref[0] == ref) {
 RETURN_MV(mv-mv[0]);
 } else if (mv-ref[1] == ref) {
@@ -1124,7 +1118,7 @@ static void find_ref_mvs(VP9Context *s,
 
 // MV at this position in previous frame, using different reference frame
 if (s-use_last_frame_mvs) {
-struct VP9mvrefPair *mv = s-frames[LAST_FRAME].mv[row * s-sb_cols * 
8 + col];
+struct VP9mvrefPair *mv = s-frames[REF_FRAME_MVPAIR].mv[row * 
s-sb_cols * 8 + col];
 
 // no need to await_progress, because we already did that above
 if (mv-ref[0] != ref  mv-ref[0] = 0) {
@@ -1348,21 +1342,14 @@ static void decode_mode(AVCodecContext *ctx)
 s-left_segpred_ctx[row7]]))) {
 if (!s-errorres) {
 int pred = 8, x;
-uint8_t *refsegmap = s-frames[LAST_FRAME].segmentation_map;
+uint8_t *refsegmap = s-frames[REF_FRAME_SEGMAP].segmentation_map;
 
-if (!s-last_uses_2pass)
-ff_thread_await_progress(s-frames[LAST_FRAME].tf, row  3, 
0);
+if (!s-frames[REF_FRAME_SEGMAP].uses_2pass)
+ff_thread_await_progress(s-frames[REF_FRAME_SEGMAP].tf, row 
 3, 0);
 for (y = 0; y  h4; y++) {
 int idx_base = (y + row) * 8 * s-sb_cols + col;
 for (x = 0; x  w4; x++)
 pred = FFMIN(pred, refsegmap[idx_base + x]);
-if (!s-segmentation.update_map  ctx-active_thread_type == 
FF_THREAD_FRAME) {
-// FIXME maybe retain reference to previous frame as
-// segmap reference instead of copying the whole map
-