summaryrefslogtreecommitdiffstats
path: root/libvpx/vp9/decoder
diff options
context:
space:
mode:
authorhkuang <hkuang@google.com>2013-07-25 11:11:39 -0700
committerhkuang <hkuang@google.com>2013-07-25 12:03:12 -0700
commit91037db265ecdd914a26e056cf69207b4f50924e (patch)
treec78c618cf6d0ffb187e2734d524bca19698b3c0d /libvpx/vp9/decoder
parentba164dffc5a6795bce97fae02b51ccf3330e15e4 (diff)
downloadandroid_external_libvpx-91037db265ecdd914a26e056cf69207b4f50924e.tar.gz
android_external_libvpx-91037db265ecdd914a26e056cf69207b4f50924e.tar.bz2
android_external_libvpx-91037db265ecdd914a26e056cf69207b4f50924e.zip
Roll latest libvpx into Android.
Make the VP9 decoding 2X faster than the old one. Checkout is from master branch(hash:242157c756314827ad9244952c7253e8900b9626). Change-Id: Ibe67b3ee19f82b87df2416826b63a67f7f79b63a
Diffstat (limited to 'libvpx/vp9/decoder')
-rw-r--r--libvpx/vp9/decoder/arm/neon/vp9_add_constant_residual_neon.asm230
-rw-r--r--libvpx/vp9/decoder/vp9_dboolhuff.c23
-rw-r--r--libvpx/vp9/decoder/vp9_dboolhuff.h23
-rw-r--r--libvpx/vp9/decoder/vp9_decodemv.c943
-rw-r--r--libvpx/vp9/decoder/vp9_decodemv.h9
-rw-r--r--libvpx/vp9/decoder/vp9_decodframe.c781
-rw-r--r--libvpx/vp9/decoder/vp9_decodframe.h1
-rw-r--r--libvpx/vp9/decoder/vp9_detokenize.c78
-rw-r--r--libvpx/vp9/decoder/vp9_dsubexp.c106
-rw-r--r--libvpx/vp9/decoder/vp9_dsubexp.h (renamed from libvpx/vp9/decoder/vp9_asm_dec_offsets.c)13
-rw-r--r--libvpx/vp9/decoder/vp9_idct_blk.c2
-rw-r--r--libvpx/vp9/decoder/vp9_onyxd_if.c15
-rw-r--r--libvpx/vp9/decoder/vp9_onyxd_int.h31
-rw-r--r--libvpx/vp9/decoder/vp9_read_bit_buffer.h6
14 files changed, 1111 insertions, 1150 deletions
diff --git a/libvpx/vp9/decoder/arm/neon/vp9_add_constant_residual_neon.asm b/libvpx/vp9/decoder/arm/neon/vp9_add_constant_residual_neon.asm
new file mode 100644
index 0000000..174e747
--- /dev/null
+++ b/libvpx/vp9/decoder/arm/neon/vp9_add_constant_residual_neon.asm
@@ -0,0 +1,230 @@
+;
+; Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+;
+; Use of this source code is governed by a BSD-style license
+; that can be found in the LICENSE file in the root of the source
+; tree. An additional intellectual property rights grant can be found
+; in the file PATENTS. All contributing project authors may
+; be found in the AUTHORS file in the root of the source tree.
+;
+
+ EXPORT |vp9_add_constant_residual_8x8_neon|
+ EXPORT |vp9_add_constant_residual_16x16_neon|
+ EXPORT |vp9_add_constant_residual_32x32_neon|
+ ARM
+
+ AREA ||.text||, CODE, READONLY, ALIGN=2
+
+ MACRO
+ LD_16x8 $src, $stride
+ vld1.8 {q8}, [$src], $stride
+ vld1.8 {q9}, [$src], $stride
+ vld1.8 {q10}, [$src], $stride
+ vld1.8 {q11}, [$src], $stride
+ vld1.8 {q12}, [$src], $stride
+ vld1.8 {q13}, [$src], $stride
+ vld1.8 {q14}, [$src], $stride
+ vld1.8 {q15}, [$src], $stride
+ MEND
+
+ MACRO
+ ADD_DIFF_16x8 $diff
+ vqadd.u8 q8, q8, $diff
+ vqadd.u8 q9, q9, $diff
+ vqadd.u8 q10, q10, $diff
+ vqadd.u8 q11, q11, $diff
+ vqadd.u8 q12, q12, $diff
+ vqadd.u8 q13, q13, $diff
+ vqadd.u8 q14, q14, $diff
+ vqadd.u8 q15, q15, $diff
+ MEND
+
+ MACRO
+ SUB_DIFF_16x8 $diff
+ vqsub.u8 q8, q8, $diff
+ vqsub.u8 q9, q9, $diff
+ vqsub.u8 q10, q10, $diff
+ vqsub.u8 q11, q11, $diff
+ vqsub.u8 q12, q12, $diff
+ vqsub.u8 q13, q13, $diff
+ vqsub.u8 q14, q14, $diff
+ vqsub.u8 q15, q15, $diff
+ MEND
+
+ MACRO
+ ST_16x8 $dst, $stride
+ vst1.8 {q8}, [$dst], $stride
+ vst1.8 {q9}, [$dst], $stride
+ vst1.8 {q10}, [$dst], $stride
+ vst1.8 {q11}, [$dst], $stride
+ vst1.8 {q12}, [$dst], $stride
+ vst1.8 {q13}, [$dst], $stride
+ vst1.8 {q14}, [$dst], $stride
+ vst1.8 {q15}, [$dst], $stride
+ MEND
+
+; void add_constant_residual(const int16_t diff, uint8_t *dest, int stride,
+; int width, int height) {
+; int r, c;
+;
+; for (r = 0; r < height; r++) {
+; for (c = 0; c < width; c++)
+; dest[c] = clip_pixel(diff + dest[c]);
+;
+; dest += stride;
+; }
+;}
+;void vp9_add_constant_residual_8x8_c(const int16_t diff, uint8_t *dest,
+; int stride) {
+; add_constant_residual(diff, dest, stride, 8, 8);
+;}
+; r0 : const int16_t diff
+; r1 : const uint8_t *dest
+; r2 : int stride
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+|vp9_add_constant_residual_8x8_neon| PROC
+ mov r3, r1 ; r3: save dest to r3
+ vld1.8 {d0}, [r1], r2
+ vld1.8 {d1}, [r1], r2
+ vld1.8 {d2}, [r1], r2
+ vld1.8 {d3}, [r1], r2
+ vld1.8 {d4}, [r1], r2
+ vld1.8 {d5}, [r1], r2
+ vld1.8 {d6}, [r1], r2
+ vld1.8 {d7}, [r1], r2
+ cmp r0, #0
+ bge DIFF_POSITIVE_8x8
+
+DIFF_NEGATIVE_8x8 ; diff < 0
+ neg r0, r0
+ usat r0, #8, r0
+ vdup.u8 q8, r0
+
+ vqsub.u8 q0, q0, q8
+ vqsub.u8 q1, q1, q8
+ vqsub.u8 q2, q2, q8
+ vqsub.u8 q3, q3, q8
+ b DIFF_SAVE_8x8
+
+DIFF_POSITIVE_8x8 ; diff >= 0
+ usat r0, #8, r0
+ vdup.u8 q8, r0
+
+ vqadd.u8 q0, q0, q8
+ vqadd.u8 q1, q1, q8
+ vqadd.u8 q2, q2, q8
+ vqadd.u8 q3, q3, q8
+
+DIFF_SAVE_8x8
+ vst1.8 {d0}, [r3], r2
+ vst1.8 {d1}, [r3], r2
+ vst1.8 {d2}, [r3], r2
+ vst1.8 {d3}, [r3], r2
+ vst1.8 {d4}, [r3], r2
+ vst1.8 {d5}, [r3], r2
+ vst1.8 {d6}, [r3], r2
+ vst1.8 {d7}, [r3], r2
+
+ bx lr
+ ENDP
+
+;void vp9_add_constant_residual_16x16_c(const int16_t diff, uint8_t *dest,
+; int stride) {
+; add_constant_residual(diff, dest, stride, 16, 16);
+;}
+; r0 : const int16_t diff
+; r1 : const uint8_t *dest
+; r2 : int stride
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+|vp9_add_constant_residual_16x16_neon| PROC
+ mov r3, r1
+ LD_16x8 r1, r2
+ cmp r0, #0
+ bge DIFF_POSITIVE_16x16
+
+|DIFF_NEGATIVE_16x16|
+ neg r0, r0
+ usat r0, #8, r0
+ vdup.u8 q0, r0
+
+ SUB_DIFF_16x8 q0
+ ST_16x8 r3, r2
+ LD_16x8 r1, r2
+ SUB_DIFF_16x8 q0
+ b DIFF_SAVE_16x16
+
+|DIFF_POSITIVE_16x16|
+ usat r0, #8, r0
+ vdup.u8 q0, r0
+
+ ADD_DIFF_16x8 q0
+ ST_16x8 r3, r2
+ LD_16x8 r1, r2
+ ADD_DIFF_16x8 q0
+
+|DIFF_SAVE_16x16|
+ ST_16x8 r3, r2
+ bx lr
+ ENDP
+
+;void vp9_add_constant_residual_32x32_c(const int16_t diff, uint8_t *dest,
+; int stride) {
+; add_constant_residual(diff, dest, stride, 32, 32);
+;}
+; r0 : const int16_t diff
+; r1 : const uint8_t *dest
+; r2 : int stride
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+|vp9_add_constant_residual_32x32_neon| PROC
+ push {r4,lr}
+ pld [r1]
+ mov r3, r1
+ add r4, r1, #16 ; r4 dest + 16 for second loop
+ cmp r0, #0
+ bge DIFF_POSITIVE_32x32
+
+|DIFF_NEGATIVE_32x32|
+ neg r0, r0
+ usat r0, #8, r0
+ vdup.u8 q0, r0
+ mov r0, #4
+
+|DIFF_NEGATIVE_32x32_LOOP|
+ sub r0, #1
+ LD_16x8 r1, r2
+ SUB_DIFF_16x8 q0
+ ST_16x8 r3, r2
+
+ LD_16x8 r1, r2
+ SUB_DIFF_16x8 q0
+ ST_16x8 r3, r2
+ cmp r0, #2
+ moveq r1, r4
+ moveq r3, r4
+ cmp r0, #0
+ bne DIFF_NEGATIVE_32x32_LOOP
+ pop {r4,pc}
+
+|DIFF_POSITIVE_32x32|
+ usat r0, #8, r0
+ vdup.u8 q0, r0
+ mov r0, #4
+
+|DIFF_POSITIVE_32x32_LOOP|
+ sub r0, #1
+ LD_16x8 r1, r2
+ ADD_DIFF_16x8 q0
+ ST_16x8 r3, r2
+
+ LD_16x8 r1, r2
+ ADD_DIFF_16x8 q0
+ ST_16x8 r3, r2
+ cmp r0, #2
+ moveq r1, r4
+ moveq r3, r4
+ cmp r0, #0
+ bne DIFF_POSITIVE_32x32_LOOP
+ pop {r4,pc}
+ ENDP
+
+ END
diff --git a/libvpx/vp9/decoder/vp9_dboolhuff.c b/libvpx/vp9/decoder/vp9_dboolhuff.c
index df77d65..31b1ae2 100644
--- a/libvpx/vp9/decoder/vp9_dboolhuff.c
+++ b/libvpx/vp9/decoder/vp9_dboolhuff.c
@@ -13,6 +13,12 @@
#include "vp9/decoder/vp9_dboolhuff.h"
+// This is meant to be a large, positive constant that can still be efficiently
+// loaded as an immediate (on platforms like ARM, for example).
+// Even relatively modest values like 100 would work fine.
+#define VP9_LOTS_OF_BITS 0x40000000
+
+
int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size) {
int marker_bit;
@@ -67,3 +73,20 @@ const uint8_t *vp9_reader_find_end(vp9_reader *r) {
return r->buffer;
}
+int vp9_reader_has_error(vp9_reader *r) {
+ // Check if we have reached the end of the buffer.
+ //
+ // Variable 'count' stores the number of bits in the 'value' buffer, minus
+ // 8. The top byte is part of the algorithm, and the remainder is buffered
+ // to be shifted into it. So if count == 8, the top 16 bits of 'value' are
+ // occupied, 8 for the algorithm and 8 in the buffer.
+ //
+ // When reading a byte from the user's buffer, count is filled with 8 and
+ // one byte is filled into the value buffer. When we reach the end of the
+ // data, count is additionally filled with VP9_LOTS_OF_BITS. So when
+ // count == VP9_LOTS_OF_BITS - 1, the user's data has been exhausted.
+ //
+ // 1 if we have tried to decode bits after the end of stream was encountered.
+ // 0 No error.
+ return r->count > VP9_BD_VALUE_SIZE && r->count < VP9_LOTS_OF_BITS;
+}
diff --git a/libvpx/vp9/decoder/vp9_dboolhuff.h b/libvpx/vp9/decoder/vp9_dboolhuff.h
index b50aa35..c46dd73 100644
--- a/libvpx/vp9/decoder/vp9_dboolhuff.h
+++ b/libvpx/vp9/decoder/vp9_dboolhuff.h
@@ -22,11 +22,6 @@ typedef size_t VP9_BD_VALUE;
#define VP9_BD_VALUE_SIZE ((int)sizeof(VP9_BD_VALUE)*CHAR_BIT)
-// This is meant to be a large, positive constant that can still be efficiently
-// loaded as an immediate (on platforms like ARM, for example).
-// Even relatively modest values like 100 would work fine.
-#define VP9_LOTS_OF_BITS 0x40000000
-
typedef struct {
const uint8_t *buffer_end;
const uint8_t *buffer;
@@ -93,22 +88,6 @@ static int vp9_read_literal(vp9_reader *br, int bits) {
return z;
}
-static int vp9_reader_has_error(vp9_reader *r) {
- // Check if we have reached the end of the buffer.
- //
- // Variable 'count' stores the number of bits in the 'value' buffer, minus
- // 8. The top byte is part of the algorithm, and the remainder is buffered
- // to be shifted into it. So if count == 8, the top 16 bits of 'value' are
- // occupied, 8 for the algorithm and 8 in the buffer.
- //
- // When reading a byte from the user's buffer, count is filled with 8 and
- // one byte is filled into the value buffer. When we reach the end of the
- // data, count is additionally filled with VP9_LOTS_OF_BITS. So when
- // count == VP9_LOTS_OF_BITS - 1, the user's data has been exhausted.
- //
- // 1 if we have tried to decode bits after the end of stream was encountered.
- // 0 No error.
- return r->count > VP9_BD_VALUE_SIZE && r->count < VP9_LOTS_OF_BITS;
-}
+int vp9_reader_has_error(vp9_reader *r);
#endif // VP9_DECODER_VP9_DBOOLHUFF_H_
diff --git a/libvpx/vp9/decoder/vp9_decodemv.c b/libvpx/vp9/decoder/vp9_decodemv.c
index b3d41be..6f0044a 100644
--- a/libvpx/vp9/decoder/vp9_decodemv.c
+++ b/libvpx/vp9/decoder/vp9_decodemv.c
@@ -8,151 +8,188 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <assert.h>
-#include "vp9/decoder/vp9_treereader.h"
-#include "vp9/common/vp9_entropymv.h"
+#include "vp9/common/vp9_common.h"
+#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_entropymode.h"
-#include "vp9/common/vp9_reconinter.h"
-#include "vp9/decoder/vp9_onyxd_int.h"
+#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_findnearmv.h"
-#include "vp9/common/vp9_common.h"
-#include "vp9/common/vp9_seg_common.h"
+#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_pred_common.h"
-#include "vp9/common/vp9_entropy.h"
+#include "vp9/common/vp9_reconinter.h"
+#include "vp9/common/vp9_seg_common.h"
+
#include "vp9/decoder/vp9_decodemv.h"
#include "vp9/decoder/vp9_decodframe.h"
-#include "vp9/common/vp9_mvref_common.h"
-#if CONFIG_DEBUG
-#include <assert.h>
-#endif
+#include "vp9/decoder/vp9_onyxd_int.h"
+#include "vp9/decoder/vp9_dsubexp.h"
+#include "vp9/decoder/vp9_treereader.h"
+
+static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
+ return (MB_PREDICTION_MODE)treed_read(r, vp9_intra_mode_tree, p);
+}
-// #define DEBUG_DEC_MV
-#ifdef DEBUG_DEC_MV
-int dec_mvcount = 0;
-#endif
+static MB_PREDICTION_MODE read_inter_mode(vp9_reader *r, const vp9_prob *p) {
+ return (MB_PREDICTION_MODE)treed_read(r, vp9_inter_mode_tree, p);
+}
-// #define DEC_DEBUG
-#ifdef DEC_DEBUG
-extern int dec_debug;
-#endif
+static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
+ return treed_read(r, vp9_segment_tree, seg->tree_probs);
+}
-static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
- MB_PREDICTION_MODE m = treed_read(r, vp9_intra_mode_tree, p);
- return m;
+static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
+ BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
+ const uint8_t context = vp9_get_pred_context_tx_size(xd);
+ const vp9_prob *tx_probs = get_tx_probs(bsize, context, &cm->fc.tx_probs);
+ TX_SIZE tx_size = vp9_read(r, tx_probs[0]);
+ if (tx_size != TX_4X4 && bsize >= BLOCK_SIZE_MB16X16) {
+ tx_size += vp9_read(r, tx_probs[1]);
+ if (tx_size != TX_8X8 && bsize >= BLOCK_SIZE_SB32X32)
+ tx_size += vp9_read(r, tx_probs[2]);
+ }
+
+ update_tx_counts(bsize, context, tx_size, &cm->counts.tx);
+ return tx_size;
}
-static int read_mb_segid(vp9_reader *r, MACROBLOCKD *xd) {
- return treed_read(r, vp9_segment_tree, xd->mb_segment_tree_probs);
+static TX_SIZE read_tx_size(VP9D_COMP *pbi, TX_MODE tx_mode,
+ BLOCK_SIZE_TYPE bsize, int select_cond,
+ vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+
+ if (tx_mode == TX_MODE_SELECT && bsize >= BLOCK_SIZE_SB8X8 && select_cond)
+ return read_selected_tx_size(cm, xd, bsize, r);
+ else if (tx_mode >= ALLOW_32X32 && bsize >= BLOCK_SIZE_SB32X32)
+ return TX_32X32;
+ else if (tx_mode >= ALLOW_16X16 && bsize >= BLOCK_SIZE_MB16X16)
+ return TX_16X16;
+ else if (tx_mode >= ALLOW_8X8 && bsize >= BLOCK_SIZE_SB8X8)
+ return TX_8X8;
+ else
+ return TX_4X4;
}
-static void set_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi,
+static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize,
int mi_row, int mi_col, int segment_id) {
- const int mi_index = mi_row * cm->mi_cols + mi_col;
- const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
- const int bw = 1 << mi_width_log2(sb_type);
- const int bh = 1 << mi_height_log2(sb_type);
- const int ymis = MIN(cm->mi_rows - mi_row, bh);
+ const int mi_offset = mi_row * cm->mi_cols + mi_col;
+ const int bw = 1 << mi_width_log2(bsize);
+ const int bh = 1 << mi_height_log2(bsize);
const int xmis = MIN(cm->mi_cols - mi_col, bw);
+ const int ymis = MIN(cm->mi_rows - mi_row, bh);
int x, y;
- for (y = 0; y < ymis; y++) {
- for (x = 0; x < xmis; x++) {
- const int index = mi_index + (y * cm->mi_cols + x);
- cm->last_frame_seg_map[index] = segment_id;
- }
- }
-}
+ assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
-static TX_SIZE select_txfm_size(VP9_COMMON *cm, MACROBLOCKD *xd,
- vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
- const int context = vp9_get_pred_context(cm, xd, PRED_TX_SIZE);
- const vp9_prob *tx_probs = vp9_get_pred_probs(cm, xd, PRED_TX_SIZE);
- TX_SIZE txfm_size = vp9_read(r, tx_probs[0]);
- if (txfm_size != TX_4X4 && bsize >= BLOCK_SIZE_MB16X16) {
- txfm_size += vp9_read(r, tx_probs[1]);
- if (txfm_size != TX_8X8 && bsize >= BLOCK_SIZE_SB32X32)
- txfm_size += vp9_read(r, tx_probs[2]);
- }
- if (bsize >= BLOCK_SIZE_SB32X32) {
- cm->fc.tx_count_32x32p[context][txfm_size]++;
- } else if (bsize >= BLOCK_SIZE_MB16X16) {
- cm->fc.tx_count_16x16p[context][txfm_size]++;
- } else {
- cm->fc.tx_count_8x8p[context][txfm_size]++;
- }
- return txfm_size;
+ for (y = 0; y < ymis; y++)
+ for (x = 0; x < xmis; x++)
+ cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}
+static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
+ vp9_reader *r) {
+ MACROBLOCKD *const xd = &pbi->mb;
+ struct segmentation *const seg = &xd->seg;
+ const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
+ int segment_id;
+
+ if (!seg->enabled)
+ return 0; // Default for disabled segmentation
+
+ if (!seg->update_map)
+ return 0;
-static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
- int mi_row, int mi_col,
- vp9_reader *r) {
+ segment_id = read_segment_id(r, seg);
+ set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id);
+ return segment_id;
+}
+
+static int read_inter_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
+ vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
- const int mis = cm->mode_info_stride;
+ struct segmentation *const seg = &xd->seg;
+ const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
+ int pred_segment_id, segment_id;
- // Read segmentation map if it is being updated explicitly this frame
- m->mbmi.segment_id = 0;
- if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
- m->mbmi.segment_id = read_mb_segid(r, xd);
- set_segment_id(cm, &m->mbmi, mi_row, mi_col, m->mbmi.segment_id);
- }
+ if (!seg->enabled)
+ return 0; // Default for disabled segmentation
- m->mbmi.mb_skip_coeff = vp9_segfeature_active(xd, m->mbmi.segment_id,
- SEG_LVL_SKIP);
- if (!m->mbmi.mb_skip_coeff) {
- m->mbmi.mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
- cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
- [m->mbmi.mb_skip_coeff]++;
+ pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
+ bsize, mi_row, mi_col);
+ if (!seg->update_map)
+ return pred_segment_id;
+
+ if (seg->temporal_update) {
+ const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(xd);
+ const int pred_flag = vp9_read(r, pred_prob);
+ vp9_set_pred_flag_seg_id(cm, bsize, mi_row, mi_col, pred_flag);
+ segment_id = pred_flag ? pred_segment_id
+ : read_segment_id(r, seg);
+ } else {
+ segment_id = read_segment_id(r, seg);
}
+ set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
+ return segment_id;
+}
- if (cm->txfm_mode == TX_MODE_SELECT &&
- m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
- m->mbmi.txfm_size = select_txfm_size(cm, xd, r, m->mbmi.sb_type);
- } else if (cm->txfm_mode >= ALLOW_32X32 &&
- m->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
- m->mbmi.txfm_size = TX_32X32;
- } else if (cm->txfm_mode >= ALLOW_16X16 &&
- m->mbmi.sb_type >= BLOCK_SIZE_MB16X16) {
- m->mbmi.txfm_size = TX_16X16;
- } else if (cm->txfm_mode >= ALLOW_8X8 &&
- m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
- m->mbmi.txfm_size = TX_8X8;
- } else {
- m->mbmi.txfm_size = TX_4X4;
+static uint8_t read_skip_coeff(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+ int skip_coeff = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP);
+ if (!skip_coeff) {
+ const int ctx = vp9_get_pred_context_mbskip(xd);
+ skip_coeff = vp9_read(r, vp9_get_pred_prob_mbskip(cm, xd));
+ cm->counts.mbskip[ctx][skip_coeff]++;
}
+ return skip_coeff;
+}
- // luma mode
- m->mbmi.ref_frame[0] = INTRA_FRAME;
- if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
+static void read_intra_mode_info(VP9D_COMP *pbi, MODE_INFO *m,
+ int mi_row, int mi_col, vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+ MB_MODE_INFO *const mbmi = &m->mbmi;
+ const BLOCK_SIZE_TYPE bsize = mbmi->sb_type;
+ const int mis = cm->mode_info_stride;
+
+ mbmi->segment_id = read_intra_segment_id(pbi, mi_row, mi_col, r);
+ mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
+ mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, bsize, 1, r);
+ mbmi->ref_frame[0] = INTRA_FRAME;
+
+ if (bsize >= BLOCK_SIZE_SB8X8) {
const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
const MB_PREDICTION_MODE L = xd->left_available ?
left_block_mode(m, 0) : DC_PRED;
- m->mbmi.mode = read_intra_mode(r, cm->kf_y_mode_prob[A][L]);
+ mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
} else {
+ // Only 4x4, 4x8, 8x4 blocks
+ const int bw = 1 << b_width_log2(bsize);
+ const int bh = 1 << b_height_log2(bsize);
int idx, idy;
- int bw = 1 << b_width_log2(m->mbmi.sb_type);
- int bh = 1 << b_height_log2(m->mbmi.sb_type);
for (idy = 0; idy < 2; idy += bh) {
for (idx = 0; idx < 2; idx += bw) {
- int ib = idy * 2 + idx;
- int k;
+ const int ib = idy * 2 + idx;
const MB_PREDICTION_MODE A = above_block_mode(m, ib, mis);
const MB_PREDICTION_MODE L = (xd->left_available || idx) ?
left_block_mode(m, ib) : DC_PRED;
- m->bmi[ib].as_mode.first =
- read_intra_mode(r, cm->kf_y_mode_prob[A][L]);
- for (k = 1; k < bh; ++k)
- m->bmi[ib + k * 2].as_mode.first = m->bmi[ib].as_mode.first;
- for (k = 1; k < bw; ++k)
- m->bmi[ib + k].as_mode.first = m->bmi[ib].as_mode.first;
+ const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
+ vp9_kf_y_mode_prob[A][L]);
+ m->bmi[ib].as_mode = b_mode;
+ if (bh == 2)
+ m->bmi[ib + 2].as_mode = b_mode;
+ if (bw == 2)
+ m->bmi[ib + 1].as_mode = b_mode;
}
}
- m->mbmi.mode = m->bmi[3].as_mode.first;
+
+ mbmi->mode = m->bmi[3].as_mode;
}
- m->mbmi.uv_mode = read_intra_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]);
+ mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
}
static int read_mv_component(vp9_reader *r,
@@ -161,9 +198,10 @@ static int read_mv_component(vp9_reader *r,
int mag, d, fr, hp;
const int sign = vp9_read(r, mvcomp->sign);
const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
+ const int class0 = mv_class == MV_CLASS_0;
// Integer part
- if (mv_class == MV_CLASS_0) {
+ if (class0) {
d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
} else {
int i;
@@ -176,66 +214,77 @@ static int read_mv_component(vp9_reader *r,
// Fractional part
fr = treed_read(r, vp9_mv_fp_tree,
- mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp);
+ class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
// High precision part (if hp is not used, the default value of the hp is 1)
- hp = usehp ? vp9_read(r,
- mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp)
+ hp = usehp ? vp9_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp)
: 1;
- // result
+ // Result
mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
return sign ? -mag : mag;
}
-static void update_nmv(vp9_reader *r, vp9_prob *const p,
- const vp9_prob upd_p) {
- if (vp9_read(r, upd_p)) {
-#ifdef LOW_PRECISION_MV_UPDATE
+static INLINE void read_mv(vp9_reader *r, MV *mv, const MV *ref,
+ const nmv_context *ctx,
+ nmv_context_counts *counts, int usehp) {
+ const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
+ MV diff = {0, 0};
+
+ usehp = usehp && vp9_use_mv_hp(ref);
+ if (mv_joint_vertical(j))
+ diff.row = read_mv_component(r, &ctx->comps[0], usehp);
+
+ if (mv_joint_horizontal(j))
+ diff.col = read_mv_component(r, &ctx->comps[1], usehp);
+
+ vp9_inc_mv(&diff, counts);
+
+ mv->row = ref->row + diff.row;
+ mv->col = ref->col + diff.col;
+}
+
+static void update_mv(vp9_reader *r, vp9_prob *p, vp9_prob upd_p) {
+ if (vp9_read(r, upd_p))
*p = (vp9_read_literal(r, 7) << 1) | 1;
-#else
- *p = (vp9_read_literal(r, 8));
-#endif
- }
}
-static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx,
- int usehp) {
+static void read_mv_probs(vp9_reader *r, nmv_context *mvc, int usehp) {
int i, j, k;
-#ifdef MV_GROUP_UPDATE
- if (!vp9_read_bit(r))
- return;
-#endif
for (j = 0; j < MV_JOINTS - 1; ++j)
- update_nmv(r, &mvctx->joints[j], VP9_NMV_UPDATE_PROB);
+ update_mv(r, &mvc->joints[j], VP9_NMV_UPDATE_PROB);
for (i = 0; i < 2; ++i) {
- update_nmv(r, &mvctx->comps[i].sign, VP9_NMV_UPDATE_PROB);
+ nmv_component *const comp = &mvc->comps[i];
+
+ update_mv(r, &comp->sign, VP9_NMV_UPDATE_PROB);
for (j = 0; j < MV_CLASSES - 1; ++j)
- update_nmv(r, &mvctx->comps[i].classes[j], VP9_NMV_UPDATE_PROB);
+ update_mv(r, &comp->classes[j], VP9_NMV_UPDATE_PROB);
for (j = 0; j < CLASS0_SIZE - 1; ++j)
- update_nmv(r, &mvctx->comps[i].class0[j], VP9_NMV_UPDATE_PROB);
+ update_mv(r, &comp->class0[j], VP9_NMV_UPDATE_PROB);
for (j = 0; j < MV_OFFSET_BITS; ++j)
- update_nmv(r, &mvctx->comps[i].bits[j], VP9_NMV_UPDATE_PROB);
+ update_mv(r, &comp->bits[j], VP9_NMV_UPDATE_PROB);
}
for (i = 0; i < 2; ++i) {
+ nmv_component *const comp = &mvc->comps[i];
+
for (j = 0; j < CLASS0_SIZE; ++j)
for (k = 0; k < 3; ++k)
- update_nmv(r, &mvctx->comps[i].class0_fp[j][k], VP9_NMV_UPDATE_PROB);
+ update_mv(r, &comp->class0_fp[j][k], VP9_NMV_UPDATE_PROB);
for (j = 0; j < 3; ++j)
- update_nmv(r, &mvctx->comps[i].fp[j], VP9_NMV_UPDATE_PROB);
+ update_mv(r, &comp->fp[j], VP9_NMV_UPDATE_PROB);
}
if (usehp) {
for (i = 0; i < 2; ++i) {
- update_nmv(r, &mvctx->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
- update_nmv(r, &mvctx->comps[i].hp, VP9_NMV_UPDATE_PROB);
+ update_mv(r, &mvc->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
+ update_mv(r, &mvc->comps[i].hp, VP9_NMV_UPDATE_PROB);
}
}
}
@@ -245,205 +294,71 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
- const int seg_ref_active = vp9_segfeature_active(xd, segment_id,
- SEG_LVL_REF_FRAME);
+ FRAME_CONTEXT *const fc = &cm->fc;
+ FRAME_COUNTS *const counts = &cm->counts;
- // Segment reference frame features not available.
- if (!seg_ref_active) {
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
+ ref_frame[0] = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME);
+ ref_frame[1] = NONE;
+ } else {
+ const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
int is_comp;
- int comp_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER);
if (cm->comp_pred_mode == HYBRID_PREDICTION) {
- is_comp = vp9_read(r, cm->fc.comp_inter_prob[comp_ctx]);
- cm->fc.comp_inter_count[comp_ctx][is_comp]++;
+ is_comp = vp9_read(r, fc->comp_inter_prob[comp_ctx]);
+ counts->comp_inter[comp_ctx][is_comp]++;
} else {
is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
}
// FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
if (is_comp) {
- int b, fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
- int ref_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_REF_P);
-
- ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
- b = vp9_read(r, cm->fc.comp_ref_prob[ref_ctx]);
- cm->fc.comp_ref_count[ref_ctx][b]++;
+ const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
+ const int ref_ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
+ const int b = vp9_read(r, fc->comp_ref_prob[ref_ctx]);
+ counts->comp_ref[ref_ctx][b]++;
+ ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
} else {
- int ref1_ctx = vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P1);
+ const int ref1_ctx = vp9_get_pred_context_single_ref_p1(xd);
ref_frame[1] = NONE;
- if (vp9_read(r, cm->fc.single_ref_prob[ref1_ctx][0])) {
- int ref2_ctx = vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P2);
- int b2 = vp9_read(r, cm->fc.single_ref_prob[ref2_ctx][1]);
- ref_frame[0] = b2 ? ALTREF_FRAME : GOLDEN_FRAME;
- cm->fc.single_ref_count[ref1_ctx][0][1]++;
- cm->fc.single_ref_count[ref2_ctx][1][b2]++;
+ if (vp9_read(r, fc->single_ref_prob[ref1_ctx][0])) {
+ const int ref2_ctx = vp9_get_pred_context_single_ref_p2(xd);
+ const int b = vp9_read(r, fc->single_ref_prob[ref2_ctx][1]);
+ ref_frame[0] = b ? ALTREF_FRAME : GOLDEN_FRAME;
+ counts->single_ref[ref1_ctx][0][1]++;
+ counts->single_ref[ref2_ctx][1][b]++;
} else {
ref_frame[0] = LAST_FRAME;
- cm->fc.single_ref_count[ref1_ctx][0][0]++;
+ counts->single_ref[ref1_ctx][0][0]++;
}
}
- } else {
- ref_frame[0] = vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME);
- ref_frame[1] = NONE;
}
}
-static MB_PREDICTION_MODE read_sb_mv_ref(vp9_reader *r, const vp9_prob *p) {
- return (MB_PREDICTION_MODE) treed_read(r, vp9_sb_mv_ref_tree, p);
-}
-
-#ifdef VPX_MODE_COUNT
-unsigned int vp9_mv_cont_count[5][4] = {
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
-};
-#endif
-
-static void read_switchable_interp_probs(VP9_COMMON* const cm, vp9_reader *r) {
+static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
int i, j;
- for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j)
- for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB)) {
- cm->fc.switchable_interp_prob[j][i] =
- // vp9_read_prob(r);
- vp9_read_prob_diff_update(r, cm->fc.switchable_interp_prob[j][i]);
- }
- }
+ for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j)
+ for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
}
-static void read_inter_mode_probs(VP9_COMMON *const cm, vp9_reader *r) {
+static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
int i, j;
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
- for (j = 0; j < VP9_INTER_MODES - 1; ++j) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB)) {
- // cm->fc.inter_mode_probs[i][j] = vp9_read_prob(r);
- cm->fc.inter_mode_probs[i][j] =
- vp9_read_prob_diff_update(r, cm->fc.inter_mode_probs[i][j]);
- }
- }
+ for (j = 0; j < VP9_INTER_MODES - 1; ++j)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
}
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
COMPPREDMODE_TYPE mode = vp9_read_bit(r);
if (mode)
- mode += vp9_read_bit(r);
+ mode += vp9_read_bit(r);
return mode;
}
-static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
- VP9_COMMON *const cm = &pbi->common;
-
- if ((cm->frame_type != KEY_FRAME) && (!cm->intra_only)) {
- nmv_context *const nmvc = &pbi->common.fc.nmvc;
- MACROBLOCKD *const xd = &pbi->mb;
- int i, j;
-
- read_inter_mode_probs(cm, r);
-
- if (cm->mcomp_filter_type == SWITCHABLE)
- read_switchable_interp_probs(cm, r);
-
- for (i = 0; i < INTRA_INTER_CONTEXTS; i++) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- cm->fc.intra_inter_prob[i] =
- vp9_read_prob_diff_update(r, cm->fc.intra_inter_prob[i]);
- }
-
- if (cm->allow_comp_inter_inter) {
- cm->comp_pred_mode = read_comp_pred_mode(r);
- if (cm->comp_pred_mode == HYBRID_PREDICTION)
- for (i = 0; i < COMP_INTER_CONTEXTS; i++)
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- cm->fc.comp_inter_prob[i] =
- vp9_read_prob_diff_update(r, cm->fc.comp_inter_prob[i]);
- } else {
- cm->comp_pred_mode = SINGLE_PREDICTION_ONLY;
- }
-
- if (cm->comp_pred_mode != COMP_PREDICTION_ONLY)
- for (i = 0; i < REF_CONTEXTS; i++) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- cm->fc.single_ref_prob[i][0] =
- vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][0]);
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- cm->fc.single_ref_prob[i][1] =
- vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][1]);
- }
-
- if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
- for (i = 0; i < REF_CONTEXTS; i++)
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- cm->fc.comp_ref_prob[i] =
- vp9_read_prob_diff_update(r, cm->fc.comp_ref_prob[i]);
-
- // VP9_INTRA_MODES
- for (j = 0; j < BLOCK_SIZE_GROUPS; j++) {
- for (i = 0; i < VP9_INTRA_MODES - 1; ++i) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB)) {
- cm->fc.y_mode_prob[j][i] =
- vp9_read_prob_diff_update(r, cm->fc.y_mode_prob[j][i]);
- }
- }
- }
- for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j) {
- for (i = 0; i < PARTITION_TYPES - 1; ++i) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB)) {
- cm->fc.partition_prob[INTER_FRAME][j][i] =
- vp9_read_prob_diff_update(r,
- cm->fc.partition_prob[INTER_FRAME][j][i]);
- }
- }
- }
-
- read_nmvprobs(r, nmvc, xd->allow_high_precision_mv);
- }
-}
-
-// This function either reads the segment id for the current macroblock from
-// the bitstream or if the value is temporally predicted asserts the predicted
-// value
-static int read_mb_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
- vp9_reader *r) {
- VP9_COMMON *const cm = &pbi->common;
- MACROBLOCKD *const xd = &pbi->mb;
- MODE_INFO *const mi = xd->mode_info_context;
- MB_MODE_INFO *const mbmi = &mi->mbmi;
-
- if (!xd->segmentation_enabled)
- return 0; // Default for disabled segmentation
-
- if (xd->update_mb_segmentation_map) {
- int segment_id;
-
- if (cm->temporal_update) {
- // Temporal coding of the segment id for this mb is enabled.
- // Get the context based probability for reading the
- // prediction status flag
- const vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_SEG_ID);
- const int pred_flag = vp9_read(r, pred_prob);
- vp9_set_pred_flag(xd, PRED_SEG_ID, pred_flag);
-
- // If the value is flagged as correctly predicted
- // then use the predicted value, otherwise decode it explicitly
- segment_id = pred_flag ? vp9_get_pred_mi_segid(cm, mbmi->sb_type,
- mi_row, mi_col)
- : read_mb_segid(r, xd);
- } else {
- segment_id = read_mb_segid(r, xd); // Normal unpredicted coding mode
- }
-
- set_segment_id(cm, mbmi, mi_row, mi_col, segment_id); // Side effect
- return segment_id;
- } else {
- return vp9_get_pred_mi_segid(cm, mbmi->sb_type, mi_row, mi_col);
- }
-}
-
-
static INLINE void assign_and_clamp_mv(int_mv *dst, const int_mv *src,
int mb_to_left_edge,
int mb_to_right_edge,
@@ -454,242 +369,188 @@ static INLINE void assign_and_clamp_mv(int_mv *dst, const int_mv *src,
mb_to_bottom_edge);
}
-static INLINE void decode_mv(vp9_reader *r, MV *mv, const MV *ref,
- const nmv_context *ctx,
- nmv_context_counts *counts,
- int usehp) {
- const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
- MV diff = {0, 0};
-
- usehp = usehp && vp9_use_nmv_hp(ref);
- if (mv_joint_vertical(j))
- diff.row = read_mv_component(r, &ctx->comps[0], usehp);
+static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
+ VP9D_COMP *pbi, vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+ const vp9_prob *probs = vp9_get_pred_probs_switchable_interp(cm, xd);
+ const int index = treed_read(r, vp9_switchable_interp_tree, probs);
+ const int ctx = vp9_get_pred_context_switchable_interp(xd);
+ ++cm->counts.switchable_interp[ctx][index];
+ return vp9_switchable_interp[index];
+}
- if (mv_joint_horizontal(j))
- diff.col = read_mv_component(r, &ctx->comps[1], usehp);
+static void read_intra_block_modes(VP9D_COMP *pbi, MODE_INFO *mi,
+ vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
+ const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
+ const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
- vp9_increment_nmv(&diff, ref, counts, usehp);
+ if (bsize >= BLOCK_SIZE_SB8X8) {
+ const int size_group = MIN(3, MIN(bwl, bhl));
+ mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[size_group]);
+ cm->counts.y_mode[size_group][mbmi->mode]++;
+ } else {
+ // Only 4x4, 4x8, 8x4 blocks
+ const int bw = 1 << bwl, bh = 1 << bhl;
+ int idx, idy;
+
+ for (idy = 0; idy < 2; idy += bh) {
+ for (idx = 0; idx < 2; idx += bw) {
+ const int ib = idy * 2 + idx;
+ const int b_mode = read_intra_mode(r, cm->fc.y_mode_prob[0]);
+ mi->bmi[ib].as_mode = b_mode;
+ cm->counts.y_mode[0][b_mode]++;
+
+ if (bh == 2)
+ mi->bmi[ib + 2].as_mode = b_mode;
+ if (bw == 2)
+ mi->bmi[ib + 1].as_mode = b_mode;
+ }
+ }
+ mbmi->mode = mi->bmi[3].as_mode;
+ }
- mv->row = diff.row + ref->row;
- mv->col = diff.col + ref->col;
+ mbmi->uv_mode = read_intra_mode(r, cm->fc.uv_mode_prob[mbmi->mode]);
+ cm->counts.uv_mode[mbmi->mode][mbmi->uv_mode]++;
}
-static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
- VP9D_COMP *pbi, vp9_reader *r) {
- const int index = treed_read(r, vp9_switchable_interp_tree,
- vp9_get_pred_probs(&pbi->common, &pbi->mb,
- PRED_SWITCHABLE_INTERP));
- ++pbi->common.fc.switchable_interp_count
- [vp9_get_pred_context(
- &pbi->common, &pbi->mb, PRED_SWITCHABLE_INTERP)][index];
- return vp9_switchable_interp[index];
+static MV_REFERENCE_FRAME read_reference_frame(VP9D_COMP *pbi, int segment_id,
+ vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+
+ MV_REFERENCE_FRAME ref;
+ if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
+ const int ctx = vp9_get_pred_context_intra_inter(xd);
+ ref = (MV_REFERENCE_FRAME)
+ vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
+ cm->counts.intra_inter[ctx][ref != INTRA_FRAME]++;
+ } else {
+ ref = (MV_REFERENCE_FRAME) vp9_get_segdata(&xd->seg, segment_id,
+ SEG_LVL_REF_FRAME) != INTRA_FRAME;
+ }
+ return ref;
}
-static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
- int mi_row, int mi_col,
- vp9_reader *r) {
+static void read_inter_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
+ int mi_row, int mi_col, vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
- nmv_context *const nmvc = &cm->fc.nmvc;
MACROBLOCKD *const xd = &pbi->mb;
+ nmv_context *const nmvc = &cm->fc.nmvc;
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
int_mv *const mv0 = &mbmi->mv[0];
int_mv *const mv1 = &mbmi->mv[1];
- BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
- int bw = 1 << b_width_log2(bsize);
- int bh = 1 << b_height_log2(bsize);
+ const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
+ const int bw = 1 << b_width_log2(bsize);
+ const int bh = 1 << b_height_log2(bsize);
- int mb_to_left_edge, mb_to_right_edge, mb_to_top_edge, mb_to_bottom_edge;
- int j, idx, idy;
+ int idx, idy;
+ mbmi->segment_id = read_inter_segment_id(pbi, mi_row, mi_col, r);
+ mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
+ mbmi->ref_frame[0] = read_reference_frame(pbi, mbmi->segment_id, r);
mbmi->ref_frame[1] = NONE;
+ mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, bsize,
+ (!mbmi->mb_skip_coeff || mbmi->ref_frame[0] == INTRA_FRAME), r);
- // Make sure the MACROBLOCKD mode info pointer is pointed at the
- // correct entry for the current macroblock.
- xd->mode_info_context = mi;
-
- // Distance of Mb to the various image edges.
- // These specified to 8th pel as they are always compared to MV values
- // that are in 1/8th pel units
- set_mi_row_col(cm, xd, mi_row, 1 << mi_height_log2(bsize),
- mi_col, 1 << mi_width_log2(bsize));
-
- mb_to_top_edge = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
- mb_to_bottom_edge = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
- mb_to_left_edge = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
- mb_to_right_edge = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
-
- // Read the macroblock segment id.
- mbmi->segment_id = read_mb_segment_id(pbi, mi_row, mi_col, r);
-
- mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id,
- SEG_LVL_SKIP);
- if (!mbmi->mb_skip_coeff) {
- mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
- cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
- [mbmi->mb_skip_coeff]++;
- }
-
- // Read the reference frame
- if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_REF_FRAME)) {
- mbmi->ref_frame[0] =
- vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_INTRA_INTER));
- cm->fc.intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)]
- [mbmi->ref_frame[0] != INTRA_FRAME]++;
- } else {
- mbmi->ref_frame[0] =
- vp9_get_segdata(xd, mbmi->segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME;
- }
-
- if (cm->txfm_mode == TX_MODE_SELECT &&
- (mbmi->mb_skip_coeff == 0 || mbmi->ref_frame[0] == INTRA_FRAME) &&
- bsize >= BLOCK_SIZE_SB8X8) {
- mbmi->txfm_size = select_txfm_size(cm, xd, r, bsize);
- } else if (bsize >= BLOCK_SIZE_SB32X32 &&
- cm->txfm_mode >= ALLOW_32X32) {
- mbmi->txfm_size = TX_32X32;
- } else if (cm->txfm_mode >= ALLOW_16X16 &&
- bsize >= BLOCK_SIZE_MB16X16) {
- mbmi->txfm_size = TX_16X16;
- } else if (cm->txfm_mode >= ALLOW_8X8 && (bsize >= BLOCK_SIZE_SB8X8)) {
- mbmi->txfm_size = TX_8X8;
- } else {
- mbmi->txfm_size = TX_4X4;
- }
-
- // If reference frame is an Inter frame
if (mbmi->ref_frame[0] != INTRA_FRAME) {
int_mv nearest, nearby, best_mv;
int_mv nearest_second, nearby_second, best_mv_second;
vp9_prob *mv_ref_p;
+ MV_REFERENCE_FRAME ref0, ref1;
read_ref_frame(pbi, r, mbmi->segment_id, mbmi->ref_frame);
+ ref0 = mbmi->ref_frame[0];
+ ref1 = mbmi->ref_frame[1];
- {
-#ifdef DEC_DEBUG
- if (dec_debug)
- printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
- xd->mode_info_context->mbmi.mv[0].as_mv.col);
-#endif
- vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
- mbmi->ref_frame[0], mbmi->ref_mvs[mbmi->ref_frame[0]],
- cm->ref_frame_sign_bias);
-
- mv_ref_p = cm->fc.inter_mode_probs[
- mbmi->mb_mode_context[mbmi->ref_frame[0]]];
-
- // If the segment level skip mode enabled
- if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) {
- mbmi->mode = ZEROMV;
- } else if (bsize >= BLOCK_SIZE_SB8X8) {
- mbmi->mode = read_sb_mv_ref(r, mv_ref_p);
- vp9_accum_mv_refs(cm, mbmi->mode,
- mbmi->mb_mode_context[mbmi->ref_frame[0]]);
- }
+ vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
+ ref0, mbmi->ref_mvs[ref0], cm->ref_frame_sign_bias);
- if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
- vp9_find_best_ref_mvs(xd,
- mbmi->ref_mvs[mbmi->ref_frame[0]],
- &nearest, &nearby);
+ mv_ref_p = cm->fc.inter_mode_probs[mbmi->mb_mode_context[ref0]];
- best_mv.as_int = mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_int;
- }
+ if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
+ mbmi->mode = ZEROMV;
+ } else if (bsize >= BLOCK_SIZE_SB8X8) {
+ mbmi->mode = read_inter_mode(r, mv_ref_p);
+ vp9_accum_mv_refs(cm, mbmi->mode, mbmi->mb_mode_context[ref0]);
+ }
+ mbmi->uv_mode = DC_PRED;
-#ifdef DEC_DEBUG
- if (dec_debug)
- printf("[D %d %d] %d %d %d %d\n", ref_frame,
- mbmi->mb_mode_context[ref_frame],
- mv_ref_p[0], mv_ref_p[1], mv_ref_p[2], mv_ref_p[3]);
-#endif
+ // nearest, nearby
+ if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
+ vp9_find_best_ref_mvs(xd, mbmi->ref_mvs[ref0], &nearest, &nearby);
+ best_mv.as_int = mbmi->ref_mvs[ref0][0].as_int;
}
mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
? read_switchable_filter_type(pbi, r)
: cm->mcomp_filter_type;
- if (mbmi->ref_frame[1] > INTRA_FRAME) {
+ if (ref1 > INTRA_FRAME) {
vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
- mbmi->ref_frame[1],
- mbmi->ref_mvs[mbmi->ref_frame[1]],
- cm->ref_frame_sign_bias);
+ ref1, mbmi->ref_mvs[ref1], cm->ref_frame_sign_bias);
if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
- vp9_find_best_ref_mvs(xd,
- mbmi->ref_mvs[mbmi->ref_frame[1]],
- &nearest_second,
- &nearby_second);
- best_mv_second.as_int = mbmi->ref_mvs[mbmi->ref_frame[1]][0].as_int;
+ vp9_find_best_ref_mvs(xd, mbmi->ref_mvs[ref1],
+ &nearest_second, &nearby_second);
+ best_mv_second.as_int = mbmi->ref_mvs[ref1][0].as_int;
}
}
- mbmi->uv_mode = DC_PRED;
+
if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
for (idy = 0; idy < 2; idy += bh) {
for (idx = 0; idx < 2; idx += bw) {
int_mv blockmv, secondmv;
- int blockmode;
- int i;
- j = idy * 2 + idx;
+ const int j = idy * 2 + idx;
+ const int blockmode = read_inter_mode(r, mv_ref_p);
- blockmode = read_sb_mv_ref(r, mv_ref_p);
- vp9_accum_mv_refs(cm, blockmode,
- mbmi->mb_mode_context[mbmi->ref_frame[0]]);
+ vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref0]);
if (blockmode == NEARESTMV || blockmode == NEARMV) {
- MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0);
- if (rf2 > 0) {
+ if (ref1 > 0)
vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest_second,
&nearby_second, j, 1);
- }
}
switch (blockmode) {
case NEWMV:
- decode_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
- &cm->fc.NMVcount, xd->allow_high_precision_mv);
+ read_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
+ &cm->counts.mv, xd->allow_high_precision_mv);
- if (mbmi->ref_frame[1] > 0)
- decode_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
- &cm->fc.NMVcount, xd->allow_high_precision_mv);
-
-#ifdef VPX_MODE_COUNT
- vp9_mv_cont_count[mv_contz][3]++;
-#endif
+ if (ref1 > 0)
+ read_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
+ &cm->counts.mv, xd->allow_high_precision_mv);
break;
case NEARESTMV:
blockmv.as_int = nearest.as_int;
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
secondmv.as_int = nearest_second.as_int;
-#ifdef VPX_MODE_COUNT
- vp9_mv_cont_count[mv_contz][0]++;
-#endif
break;
case NEARMV:
blockmv.as_int = nearby.as_int;
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
secondmv.as_int = nearby_second.as_int;
-#ifdef VPX_MODE_COUNT
- vp9_mv_cont_count[mv_contz][1]++;
-#endif
break;
case ZEROMV:
blockmv.as_int = 0;
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
secondmv.as_int = 0;
-#ifdef VPX_MODE_COUNT
- vp9_mv_cont_count[mv_contz][2]++;
-#endif
break;
default:
- break;
+ assert(!"Invalid inter mode value");
}
mi->bmi[j].as_mv[0].as_int = blockmv.as_int;
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
mi->bmi[j].as_mv[1].as_int = secondmv.as_int;
- for (i = 1; i < bh; ++i)
- vpx_memcpy(&mi->bmi[j + i * 2], &mi->bmi[j], sizeof(mi->bmi[j]));
- for (i = 1; i < bw; ++i)
- vpx_memcpy(&mi->bmi[j + i], &mi->bmi[j], sizeof(mi->bmi[j]));
+ if (bh == 2)
+ mi->bmi[j + 2] = mi->bmi[j];
+ if (bw == 2)
+ mi->bmi[j + 1] = mi->bmi[j];
mi->mbmi.mode = blockmode;
}
}
@@ -697,6 +558,11 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mv0->as_int = mi->bmi[3].as_mv[0].as_int;
mv1->as_int = mi->bmi[3].as_mv[1].as_int;
} else {
+ const int mb_to_top_edge = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
+ const int mb_to_bottom_edge = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
+ const int mb_to_left_edge = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
+ const int mb_to_right_edge = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
+
switch (mbmi->mode) {
case NEARMV:
// Clip "next_nearest" so that it does not extend to far out of image
@@ -704,7 +570,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_right_edge,
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
assign_and_clamp_mv(mv1, &nearby_second, mb_to_left_edge,
mb_to_right_edge,
mb_to_top_edge,
@@ -717,7 +583,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_right_edge,
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
assign_and_clamp_mv(mv1, &nearest_second, mb_to_left_edge,
mb_to_right_edge,
mb_to_top_edge,
@@ -726,98 +592,109 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
case ZEROMV:
mv0->as_int = 0;
- if (mbmi->ref_frame[1] > 0)
+ if (ref1 > 0)
mv1->as_int = 0;
break;
case NEWMV:
- decode_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
- xd->allow_high_precision_mv);
- if (mbmi->ref_frame[1] > 0)
- decode_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
- &cm->fc.NMVcount, xd->allow_high_precision_mv);
+ read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->counts.mv,
+ xd->allow_high_precision_mv);
+ if (ref1 > 0)
+ read_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
+ &cm->counts.mv, xd->allow_high_precision_mv);
break;
default:
-#if CONFIG_DEBUG
- assert(0);
-#endif
- break;
+ assert(!"Invalid inter mode value");
}
}
} else {
- // required for left and above block mv
- mv0->as_int = 0;
-
- if (bsize >= BLOCK_SIZE_SB8X8) {
- const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
- const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
- const int bsl = MIN(bwl, bhl);
- mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[MIN(3, bsl)]);
- cm->fc.y_mode_counts[MIN(3, bsl)][mbmi->mode]++;
- } else {
- int idx, idy;
- for (idy = 0; idy < 2; idy += bh) {
- for (idx = 0; idx < 2; idx += bw) {
- int ib = idy * 2 + idx, k;
- int m = read_intra_mode(r, cm->fc.y_mode_prob[0]);
- mi->bmi[ib].as_mode.first = m;
- cm->fc.y_mode_counts[0][m]++;
- for (k = 1; k < bh; ++k)
- mi->bmi[ib + k * 2].as_mode.first = m;
- for (k = 1; k < bw; ++k)
- mi->bmi[ib + k].as_mode.first = m;
- }
- }
- mbmi->mode = mi->bmi[3].as_mode.first;
+ mv0->as_int = 0; // required for left and above block mv
+ read_intra_block_modes(pbi, mi, r);
+ }
+}
+
+static void read_comp_pred(VP9_COMMON *cm, vp9_reader *r) {
+ int i;
+
+ cm->comp_pred_mode = cm->allow_comp_inter_inter ? read_comp_pred_mode(r)
+ : SINGLE_PREDICTION_ONLY;
+
+ if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ for (i = 0; i < COMP_INTER_CONTEXTS; i++)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.comp_inter_prob[i]);
+
+ if (cm->comp_pred_mode != COMP_PREDICTION_ONLY)
+ for (i = 0; i < REF_CONTEXTS; i++) {
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][0]);
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][1]);
}
- mbmi->uv_mode = read_intra_mode(r, cm->fc.uv_mode_prob[mbmi->mode]);
- cm->fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
- }
+ if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
+ for (i = 0; i < REF_CONTEXTS; i++)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.comp_ref_prob[i]);
}
-void vp9_decode_mode_mvs_init(VP9D_COMP* const pbi, vp9_reader *r) {
- VP9_COMMON *cm = &pbi->common;
+void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r) {
+ VP9_COMMON *const cm = &pbi->common;
int k;
// TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
// vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
- for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB)) {
- cm->fc.mbskip_probs[k] =
- vp9_read_prob_diff_update(r, cm->fc.mbskip_probs[k]);
- }
- // cm->fc.mbskip_probs[k] = vp9_read_prob(r);
- }
+ for (k = 0; k < MBSKIP_CONTEXTS; ++k)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.mbskip_probs[k]);
+
+ if (cm->frame_type != KEY_FRAME && !cm->intra_only) {
+ nmv_context *const nmvc = &pbi->common.fc.nmvc;
+ MACROBLOCKD *const xd = &pbi->mb;
+ int i, j;
+
+ read_inter_mode_probs(&cm->fc, r);
- mb_mode_mv_init(pbi, r);
+ if (cm->mcomp_filter_type == SWITCHABLE)
+ read_switchable_interp_probs(&cm->fc, r);
+
+ for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.intra_inter_prob[i]);
+
+ read_comp_pred(cm, r);
+
+ for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
+ for (i = 0; i < VP9_INTRA_MODES - 1; ++i)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.y_mode_prob[j][i]);
+
+ for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j)
+ for (i = 0; i < PARTITION_TYPES - 1; ++i)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &cm->fc.partition_prob[INTER_FRAME][j][i]);
+
+ read_mv_probs(r, nmvc, xd->allow_high_precision_mv);
+ }
}
-void vp9_decode_mb_mode_mv(VP9D_COMP* const pbi,
- MACROBLOCKD* const xd,
- int mi_row,
- int mi_col,
- vp9_reader *r) {
+void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
MODE_INFO *mi = xd->mode_info_context;
- MB_MODE_INFO *const mbmi = &mi->mbmi;
+ const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
+ const int bw = 1 << mi_width_log2(bsize);
+ const int bh = 1 << mi_height_log2(bsize);
+ const int y_mis = MIN(bh, cm->mi_rows - mi_row);
+ const int x_mis = MIN(bw, cm->mi_cols - mi_col);
+ int x, y;
- if ((cm->frame_type == KEY_FRAME) || cm->intra_only) {
- kfread_modes(pbi, mi, mi_row, mi_col, r);
- } else {
- read_mb_modes_mv(pbi, mi, &mi->mbmi, mi_row, mi_col, r);
- }
+ if (cm->frame_type == KEY_FRAME || cm->intra_only)
+ read_intra_mode_info(pbi, mi, mi_row, mi_col, r);
+ else
+ read_inter_mode_info(pbi, mi, mi_row, mi_col, r);
- if (1) {
- const int bw = 1 << mi_width_log2(mbmi->sb_type);
- const int bh = 1 << mi_height_log2(mbmi->sb_type);
- const int y_mis = MIN(bh, cm->mi_rows - mi_row);
- const int x_mis = MIN(bw, cm->mi_cols - mi_col);
- const int mis = cm->mode_info_stride;
- int x, y;
-
- for (y = 0; y < y_mis; y++)
- for (x = !y; x < x_mis; x++)
- mi[y * mis + x] = *mi;
- }
+ for (y = 0; y < y_mis; y++)
+ for (x = !y; x < x_mis; x++)
+ mi[y * cm->mode_info_stride + x] = *mi;
}
diff --git a/libvpx/vp9/decoder/vp9_decodemv.h b/libvpx/vp9/decoder/vp9_decodemv.h
index bf5e83c..4073d9e 100644
--- a/libvpx/vp9/decoder/vp9_decodemv.h
+++ b/libvpx/vp9/decoder/vp9_decodemv.h
@@ -13,11 +13,8 @@
#include "vp9/decoder/vp9_onyxd_int.h"
-void vp9_decode_mb_mode_mv(VP9D_COMP* const pbi,
- MACROBLOCKD* const xd,
- int mb_row,
- int mb_col,
- vp9_reader *r);
-void vp9_decode_mode_mvs_init(VP9D_COMP* const pbi, vp9_reader *r);
+void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r);
+
+void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r);
#endif // VP9_DECODER_VP9_DECODEMV_H_
diff --git a/libvpx/vp9/decoder/vp9_decodframe.c b/libvpx/vp9/decoder/vp9_decodframe.c
index 49b181d..ffec8ea 100644
--- a/libvpx/vp9/decoder/vp9_decodframe.c
+++ b/libvpx/vp9/decoder/vp9_decodframe.c
@@ -14,15 +14,15 @@
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
-#include "vp9/common/vp9_extend.h"
-#include "vp9/common/vp9_modecont.h"
+#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_common.h"
-#include "vp9/common/vp9_reconintra.h"
-#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_entropy.h"
-#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_entropymode.h"
+#include "vp9/common/vp9_extend.h"
+#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
+#include "vp9/common/vp9_reconintra.h"
+#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_tile_common.h"
@@ -30,169 +30,58 @@
#include "vp9/decoder/vp9_decodframe.h"
#include "vp9/decoder/vp9_detokenize.h"
#include "vp9/decoder/vp9_decodemv.h"
+#include "vp9/decoder/vp9_dsubexp.h"
#include "vp9/decoder/vp9_onyxd_int.h"
#include "vp9/decoder/vp9_read_bit_buffer.h"
-
-// #define DEC_DEBUG
-#ifdef DEC_DEBUG
-int dec_debug = 0;
-#endif
-
static int read_be32(const uint8_t *p) {
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
// len == 0 is not allowed
-static int read_is_valid(const uint8_t *start, size_t len,
- const uint8_t *end) {
+static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
return start + len > start && start + len <= end;
}
-static void setup_txfm_mode(VP9_COMMON *pc, int lossless, vp9_reader *r) {
- if (lossless) {
- pc->txfm_mode = ONLY_4X4;
- } else {
- pc->txfm_mode = vp9_read_literal(r, 2);
- if (pc->txfm_mode == ALLOW_32X32)
- pc->txfm_mode += vp9_read_bit(r);
- if (pc->txfm_mode == TX_MODE_SELECT) {
- int i, j;
- for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
- for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- pc->fc.tx_probs_8x8p[i][j] =
- vp9_read_prob_diff_update(r, pc->fc.tx_probs_8x8p[i][j]);
- }
- }
- for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
- for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- pc->fc.tx_probs_16x16p[i][j] =
- vp9_read_prob_diff_update(r, pc->fc.tx_probs_16x16p[i][j]);
- }
- }
- for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
- for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j) {
- if (vp9_read(r, VP9_MODE_UPDATE_PROB))
- pc->fc.tx_probs_32x32p[i][j] =
- vp9_read_prob_diff_update(r, pc->fc.tx_probs_32x32p[i][j]);
- }
- }
- }
- }
-}
-
-static int get_unsigned_bits(unsigned int num_values) {
- int cat = 0;
- if (num_values <= 1)
- return 0;
- num_values--;
- while (num_values > 0) {
- cat++;
- num_values >>= 1;
- }
- return cat;
-}
-
-static int inv_recenter_nonneg(int v, int m) {
- if (v > 2 * m)
- return v;
-
- return v % 2 ? m - (v + 1) / 2 : m + v / 2;
-}
-
-static int decode_uniform(vp9_reader *r, int n) {
- int v;
- const int l = get_unsigned_bits(n);
- const int m = (1 << l) - n;
- if (!l)
- return 0;
-
- v = vp9_read_literal(r, l - 1);
- return v < m ? v : (v << 1) - m + vp9_read_bit(r);
-}
-
-static int decode_term_subexp(vp9_reader *r, int k, int num_syms) {
- int i = 0, mk = 0, word;
- while (1) {
- const int b = i ? k + i - 1 : k;
- const int a = 1 << b;
- if (num_syms <= mk + 3 * a) {
- word = decode_uniform(r, num_syms - mk) + mk;
- break;
- } else {
- if (vp9_read_bit(r)) {
- i++;
- mk += a;
- } else {
- word = vp9_read_literal(r, b) + mk;
- break;
- }
- }
- }
- return word;
-}
-
static int decode_unsigned_max(struct vp9_read_bit_buffer *rb, int max) {
const int data = vp9_rb_read_literal(rb, get_unsigned_bits(max));
return data > max ? max : data;
}
-static int merge_index(int v, int n, int modulus) {
- int max1 = (n - 1 - modulus / 2) / modulus + 1;
- if (v < max1) {
- v = v * modulus + modulus / 2;
- } else {
- int w;
- v -= max1;
- w = v;
- v += (v + modulus - modulus / 2) / modulus;
- while (v % modulus == modulus / 2 ||
- w != v - (v + modulus - modulus / 2) / modulus) v++;
- }
- return v;
-}
-
-static int inv_remap_prob(int v, int m) {
- const int n = 255;
-
- v = merge_index(v, n - 1, MODULUS_PARAM);
- m--;
- if ((m << 1) <= n) {
- return 1 + inv_recenter_nonneg(v + 1, m);
- } else {
- return n - inv_recenter_nonneg(v + 1, n - 1 - m);
- }
+static TX_MODE read_tx_mode(vp9_reader *r) {
+ TX_MODE tx_mode = vp9_read_literal(r, 2);
+ if (tx_mode == ALLOW_32X32)
+ tx_mode += vp9_read_bit(r);
+ return tx_mode;
}
-vp9_prob vp9_read_prob_diff_update(vp9_reader *r, int oldp) {
- int delp = decode_term_subexp(r, SUBEXP_PARAM, 255);
- return (vp9_prob)inv_remap_prob(delp, oldp);
-}
+static void read_tx_probs(struct tx_probs *tx_probs, vp9_reader *r) {
+ int i, j;
-void vp9_init_dequantizer(VP9_COMMON *pc) {
- int q;
+ for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
+ for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]);
- for (q = 0; q < QINDEX_RANGE; q++) {
- // DC value
- pc->y_dequant[q][0] = vp9_dc_quant(q, pc->y_dc_delta_q);
- pc->uv_dequant[q][0] = vp9_dc_quant(q, pc->uv_dc_delta_q);
+ for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
+ for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]);
- // AC values
- pc->y_dequant[q][1] = vp9_ac_quant(q, 0);
- pc->uv_dequant[q][1] = vp9_ac_quant(q, pc->uv_ac_delta_q);
- }
+ for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
+ for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j)
+ if (vp9_read(r, VP9_MODE_UPDATE_PROB))
+ vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]);
}
-static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) {
+static void init_dequantizer(VP9_COMMON *cm, MACROBLOCKD *xd) {
int i;
const int segment_id = xd->mode_info_context->mbmi.segment_id;
- xd->q_index = vp9_get_qindex(xd, segment_id, pc->base_qindex);
+ xd->q_index = vp9_get_qindex(xd, segment_id, cm->base_qindex);
- xd->plane[0].dequant = pc->y_dequant[xd->q_index];
+ xd->plane[0].dequant = cm->y_dequant[xd->q_index];
for (i = 1; i < MAX_MB_PLANE; i++)
- xd->plane[i].dequant = pc->uv_dequant[xd->q_index];
+ xd->plane[i].dequant = cm->uv_dequant[xd->q_index];
}
static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
@@ -201,32 +90,32 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
struct macroblockd_plane *pd = &xd->plane[plane];
int16_t* const qcoeff = BLOCK_OFFSET(pd->qcoeff, block, 16);
const int stride = pd->dst.stride;
+ const int eob = pd->eobs[block];
const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
block, ss_txfrm_size);
uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane,
raster_block,
pd->dst.buf, stride);
- TX_TYPE tx_type;
-
switch (ss_txfrm_size / 2) {
- case TX_4X4:
- tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT;
+ case TX_4X4: {
+ const TX_TYPE tx_type = get_tx_type_4x4(pd->plane_type, xd, raster_block);
if (tx_type == DCT_DCT)
- xd->itxm_add(qcoeff, dst, stride, pd->eobs[block]);
+ xd->itxm_add(qcoeff, dst, stride, eob);
else
- vp9_iht_add_c(tx_type, qcoeff, dst, stride, pd->eobs[block]);
+ vp9_iht_add_c(tx_type, qcoeff, dst, stride, eob);
break;
+ }
case TX_8X8:
- tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT;
- vp9_iht_add_8x8_c(tx_type, qcoeff, dst, stride, pd->eobs[block]);
+ vp9_iht_add_8x8_c(get_tx_type_8x8(pd->plane_type, xd), qcoeff, dst,
+ stride, eob);
break;
case TX_16X16:
- tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT;
- vp9_iht_add_16x16_c(tx_type, qcoeff, dst, stride, pd->eobs[block]);
+ vp9_iht_add_16x16_c(get_tx_type_16x16(pd->plane_type, xd), qcoeff, dst,
+ stride, eob);
break;
case TX_32X32:
- vp9_idct_add_32x32(qcoeff, dst, stride, pd->eobs[block]);
+ vp9_idct_add_32x32(qcoeff, dst, stride, eob);
break;
}
}
@@ -235,6 +124,7 @@ static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
MACROBLOCKD* const xd = arg;
struct macroblockd_plane *pd = &xd->plane[plane];
+ MODE_INFO *const mi = xd->mode_info_context;
const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
block, ss_txfrm_size);
@@ -245,13 +135,12 @@ static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
int b_mode;
int plane_b_size;
const int tx_ib = raster_block >> tx_size;
- const int mode = plane == 0 ? xd->mode_info_context->mbmi.mode
- : xd->mode_info_context->mbmi.uv_mode;
+ const int mode = plane == 0 ? mi->mbmi.mode
+ : mi->mbmi.uv_mode;
-
- if (plane == 0 && xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
+ if (plane == 0 && mi->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
assert(bsize == BLOCK_SIZE_SB8X8);
- b_mode = xd->mode_info_context->bmi[raster_block].as_mode.first;
+ b_mode = mi->bmi[raster_block].as_mode;
} else {
b_mode = mode;
}
@@ -261,97 +150,28 @@ static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
plane_b_size = b_width_log2(bsize) - pd->subsampling_x;
vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, b_mode,
+ dst, pd->dst.stride,
dst, pd->dst.stride);
// Early exit if there are no coefficients
- if (xd->mode_info_context->mbmi.mb_skip_coeff)
+ if (mi->mbmi.mb_skip_coeff)
return;
decode_block(plane, block, bsize, ss_txfrm_size, arg);
}
-static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd,
- int mi_row, int mi_col,
- vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
- MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
-
- assert(mbmi->ref_frame[0] != INTRA_FRAME);
-
- if ((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only))
- vp9_setup_interp_filters(xd, mbmi->interp_filter, &pbi->common);
-
- // prediction
- vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
-
- if (mbmi->mb_skip_coeff) {
- vp9_reset_sb_tokens_context(xd, bsize);
- } else {
- if (xd->segmentation_enabled)
- mb_init_dequantizer(&pbi->common, xd);
-
- if (!vp9_reader_has_error(r))
- vp9_decode_tokens(pbi, r, bsize);
-
- foreach_transformed_block(xd, bsize, decode_block, xd);
- }
-}
+static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
+ MACROBLOCKD *const xd = &pbi->mb;
-static void decode_sb_intra(VP9D_COMP *pbi, MACROBLOCKD *xd,
- int mi_row, int mi_col,
- vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
- MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
- if (mbmi->mb_skip_coeff) {
+ if (xd->mode_info_context->mbmi.mb_skip_coeff) {
vp9_reset_sb_tokens_context(xd, bsize);
+ return -1;
} else {
- if (xd->segmentation_enabled)
- mb_init_dequantizer(&pbi->common, xd);
-
- if (!vp9_reader_has_error(r))
- vp9_decode_tokens(pbi, r, bsize);
- }
+ if (xd->seg.enabled)
+ init_dequantizer(&pbi->common, xd);
- foreach_transformed_block(xd, bsize, decode_block_intra, xd);
-}
-
-
-static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col,
- vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
- const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize);
- const int bw = 1 << bwl, bh = 1 << bhl;
- int n, eobtotal;
- VP9_COMMON *const pc = &pbi->common;
- MODE_INFO *const mi = xd->mode_info_context;
- MB_MODE_INFO *const mbmi = &mi->mbmi;
- const int mis = pc->mode_info_stride;
-
- assert(mbmi->sb_type == bsize);
- assert(mbmi->ref_frame[0] != INTRA_FRAME);
-
- if (pbi->common.frame_type != KEY_FRAME)
- vp9_setup_interp_filters(xd, mbmi->interp_filter, pc);
-
- // generate prediction
- vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
-
- if (mbmi->mb_skip_coeff) {
- vp9_reset_sb_tokens_context(xd, bsize);
- } else {
- // re-initialize macroblock dequantizer before detokenization
- if (xd->segmentation_enabled)
- mb_init_dequantizer(pc, xd);
-
- // dequantization and idct
- eobtotal = vp9_decode_tokens(pbi, r, bsize);
- if (eobtotal == 0) { // skip loopfilter
- for (n = 0; n < bw * bh; n++) {
- const int x_idx = n & (bw - 1), y_idx = n >> bwl;
-
- if (mi_col + x_idx < pc->mi_cols && mi_row + y_idx < pc->mi_rows)
- mi[y_idx * mis + x_idx].mbmi.mb_skip_coeff = 1;
- }
- } else {
- foreach_transformed_block(xd, bsize, decode_block, xd);
- }
+ // TODO(dkovalev) if (!vp9_reader_has_error(r))
+ return vp9_decode_tokens(pbi, r, bsize);
}
}
@@ -377,8 +197,8 @@ static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize,
pd->left_context = cm->left_context[i] +
(((mi_row * 2) & 15) >> pd->subsampling_y);
}
- xd->above_seg_context = cm->above_seg_context + mi_col;
- xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
+
+ set_partition_seg_context(cm, xd, mi_row, mi_col);
// Distance of Mb to the various image edges. These are specified to 8th pel
// as they are always compared to values that are in 1/8th pel units
@@ -387,53 +207,65 @@ static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize,
setup_dst_planes(xd, &cm->yv12_fb[cm->new_fb_idx], mi_row, mi_col);
}
-static void set_refs(VP9D_COMP *pbi, int mi_row, int mi_col) {
+static void set_ref(VP9D_COMP *pbi, int i, int mi_row, int mi_col) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+ const int ref = mbmi->ref_frame[i] - 1;
- if (mbmi->ref_frame[0] > INTRA_FRAME) {
- // Select the appropriate reference frame for this MB
- const int fb_idx = cm->active_ref_idx[mbmi->ref_frame[0] - 1];
- const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx];
- xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1];
- xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1];
- setup_pre_planes(xd, cfg, NULL, mi_row, mi_col,
- xd->scale_factor, xd->scale_factor_uv);
- xd->corrupted |= cfg->corrupted;
-
- if (mbmi->ref_frame[1] > INTRA_FRAME) {
- // Select the appropriate reference frame for this MB
- const int second_fb_idx = cm->active_ref_idx[mbmi->ref_frame[1] - 1];
- const YV12_BUFFER_CONFIG *second_cfg = &cm->yv12_fb[second_fb_idx];
- xd->scale_factor[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1];
- xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1];
- setup_pre_planes(xd, NULL, second_cfg, mi_row, mi_col,
- xd->scale_factor, xd->scale_factor_uv);
- xd->corrupted |= second_cfg->corrupted;
- }
- }
+ const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->active_ref_idx[ref]];
+ xd->scale_factor[i] = cm->active_ref_scale[ref];
+ setup_pre_planes(xd, i, cfg, mi_row, mi_col, &xd->scale_factor[i]);
+ xd->corrupted |= cfg->corrupted;
}
static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
+ VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
+ const int less8x8 = bsize < BLOCK_SIZE_SB8X8;
+ MB_MODE_INFO *mbmi;
- if (bsize < BLOCK_SIZE_SB8X8)
+ if (less8x8)
if (xd->ab_index > 0)
return;
+
set_offsets(pbi, bsize, mi_row, mi_col);
- vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r);
- set_refs(pbi, mi_row, mi_col);
+ vp9_read_mode_info(pbi, mi_row, mi_col, r);
- if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
- decode_sb_intra(pbi, xd, mi_row, mi_col, r, (bsize < BLOCK_SIZE_SB8X8) ?
- BLOCK_SIZE_SB8X8 : bsize);
- else if (bsize < BLOCK_SIZE_SB8X8)
- decode_atom(pbi, xd, mi_row, mi_col, r, BLOCK_SIZE_SB8X8);
- else
- decode_sb(pbi, xd, mi_row, mi_col, r, bsize);
+ if (less8x8)
+ bsize = BLOCK_SIZE_SB8X8;
+ // Has to be called after set_offsets
+ mbmi = &xd->mode_info_context->mbmi;
+
+ if (mbmi->ref_frame[0] == INTRA_FRAME) {
+ // Intra reconstruction
+ decode_tokens(pbi, bsize, r);
+ foreach_transformed_block(xd, bsize, decode_block_intra, xd);
+ } else {
+ // Inter reconstruction
+ int eobtotal;
+
+ set_ref(pbi, 0, mi_row, mi_col);
+ if (mbmi->ref_frame[1] > INTRA_FRAME)
+ set_ref(pbi, 1, mi_row, mi_col);
+
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
+ vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
+ eobtotal = decode_tokens(pbi, bsize, r);
+ if (less8x8) {
+ if (eobtotal >= 0)
+ foreach_transformed_block(xd, bsize, decode_block, xd);
+ } else {
+ assert(mbmi->sb_type == bsize);
+ if (eobtotal == 0)
+ // skip loopfilter
+ vp9_set_pred_flag_mbskip(cm, bsize, mi_row, mi_col, 1);
+ else if (eobtotal > 0)
+ foreach_transformed_block(xd, bsize, decode_block, xd);
+ }
+ }
xd->corrupted |= vp9_reader_has_error(r);
}
@@ -448,16 +280,13 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col,
if (mi_row >= pc->mi_rows || mi_col >= pc->mi_cols)
return;
- if (bsize < BLOCK_SIZE_SB8X8)
+ if (bsize < BLOCK_SIZE_SB8X8) {
if (xd->ab_index != 0)
return;
-
- if (bsize >= BLOCK_SIZE_SB8X8) {
+ } else {
int pl;
- int idx = check_bsize_coverage(pc, xd, mi_row, mi_col, bsize);
- // read the partition information
- xd->left_seg_context = pc->left_seg_context + (mi_row & MI_MASK);
- xd->above_seg_context = pc->above_seg_context + mi_col;
+ const int idx = check_bsize_coverage(pc, xd, mi_row, mi_col, bsize);
+ set_partition_seg_context(pc, xd, mi_row, mi_col);
pl = partition_plane_context(xd, bsize);
if (idx == 0)
@@ -469,7 +298,7 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col,
else
partition = PARTITION_SPLIT;
- pc->fc.partition_counts[pl][partition]++;
+ pc->counts.partition[pl][partition]++;
}
subsize = get_subsize(bsize, partition);
@@ -499,8 +328,9 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col,
}
break;
default:
- assert(0);
+ assert(!"Invalid partition type");
}
+
// update partition context
if (bsize >= BLOCK_SIZE_SB8X8 &&
(bsize == BLOCK_SIZE_SB8X8 || partition != PARTITION_SPLIT)) {
@@ -527,142 +357,118 @@ static void setup_token_decoder(VP9D_COMP *pbi,
"Failed to allocate bool decoder %d", 1);
}
-static void read_coef_probs_common(FRAME_CONTEXT *fc, TX_SIZE tx_size,
+static void read_coef_probs_common(vp9_coeff_probs_model *coef_probs,
vp9_reader *r) {
- vp9_coeff_probs_model *coef_probs = fc->coef_probs[tx_size];
-
- if (vp9_read_bit(r)) {
- int i, j, k, l, m;
- for (i = 0; i < BLOCK_TYPES; i++) {
- for (j = 0; j < REF_TYPES; j++) {
- for (k = 0; k < COEF_BANDS; k++) {
- for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
- if (l >= 3 && k == 0)
- continue;
-
- for (m = 0; m < UNCONSTRAINED_NODES; m++) {
- vp9_prob *const p = coef_probs[i][j][k][l] + m;
-
- if (vp9_read(r, VP9_COEF_UPDATE_PROB))
- *p = vp9_read_prob_diff_update(r, *p);
- }
- }
- }
- }
- }
- }
-}
+ int i, j, k, l, m;
-static void read_coef_probs(VP9D_COMP *pbi, vp9_reader *r) {
- const TXFM_MODE txfm_mode = pbi->common.txfm_mode;
- FRAME_CONTEXT *const fc = &pbi->common.fc;
+ if (vp9_read_bit(r))
+ for (i = 0; i < BLOCK_TYPES; i++)
+ for (j = 0; j < REF_TYPES; j++)
+ for (k = 0; k < COEF_BANDS; k++)
+ for (l = 0; l < PREV_COEF_CONTEXTS; l++)
+ if (k > 0 || l < 3)
+ for (m = 0; m < UNCONSTRAINED_NODES; m++)
+ if (vp9_read(r, VP9_COEF_UPDATE_PROB))
+ vp9_diff_update_prob(r, &coef_probs[i][j][k][l][m]);
+}
- read_coef_probs_common(fc, TX_4X4, r);
+static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode,
+ vp9_reader *r) {
+ read_coef_probs_common(fc->coef_probs[TX_4X4], r);
- if (txfm_mode > ONLY_4X4)
- read_coef_probs_common(fc, TX_8X8, r);
+ if (tx_mode > ONLY_4X4)
+ read_coef_probs_common(fc->coef_probs[TX_8X8], r);
- if (txfm_mode > ALLOW_8X8)
- read_coef_probs_common(fc, TX_16X16, r);
+ if (tx_mode > ALLOW_8X8)
+ read_coef_probs_common(fc->coef_probs[TX_16X16], r);
- if (txfm_mode > ALLOW_16X16)
- read_coef_probs_common(fc, TX_32X32, r);
+ if (tx_mode > ALLOW_16X16)
+ read_coef_probs_common(fc->coef_probs[TX_32X32], r);
}
-static void setup_segmentation(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
+static void setup_segmentation(struct segmentation *seg,
+ struct vp9_read_bit_buffer *rb) {
int i, j;
- VP9_COMMON *const cm = &pbi->common;
- MACROBLOCKD *const xd = &pbi->mb;
-
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ seg->update_map = 0;
+ seg->update_data = 0;
- xd->segmentation_enabled = vp9_rb_read_bit(rb);
- if (!xd->segmentation_enabled)
+ seg->enabled = vp9_rb_read_bit(rb);
+ if (!seg->enabled)
return;
// Segmentation map update
- xd->update_mb_segmentation_map = vp9_rb_read_bit(rb);
- if (xd->update_mb_segmentation_map) {
- for (i = 0; i < MB_SEG_TREE_PROBS; i++)
- xd->mb_segment_tree_probs[i] = vp9_rb_read_bit(rb) ?
- vp9_rb_read_literal(rb, 8) : MAX_PROB;
-
- cm->temporal_update = vp9_rb_read_bit(rb);
- if (cm->temporal_update) {
+ seg->update_map = vp9_rb_read_bit(rb);
+ if (seg->update_map) {
+ for (i = 0; i < SEG_TREE_PROBS; i++)
+ seg->tree_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8)
+ : MAX_PROB;
+
+ seg->temporal_update = vp9_rb_read_bit(rb);
+ if (seg->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++)
- cm->segment_pred_probs[i] = vp9_rb_read_bit(rb) ?
- vp9_rb_read_literal(rb, 8) : MAX_PROB;
+ seg->pred_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8)
+ : MAX_PROB;
} else {
for (i = 0; i < PREDICTION_PROBS; i++)
- cm->segment_pred_probs[i] = MAX_PROB;
+ seg->pred_probs[i] = MAX_PROB;
}
}
// Segmentation data update
- xd->update_mb_segmentation_data = vp9_rb_read_bit(rb);
- if (xd->update_mb_segmentation_data) {
- xd->mb_segment_abs_delta = vp9_rb_read_bit(rb);
+ seg->update_data = vp9_rb_read_bit(rb);
+ if (seg->update_data) {
+ seg->abs_delta = vp9_rb_read_bit(rb);
- vp9_clearall_segfeatures(xd);
+ vp9_clearall_segfeatures(seg);
- for (i = 0; i < MAX_MB_SEGMENTS; i++) {
+ for (i = 0; i < MAX_SEGMENTS; i++) {
for (j = 0; j < SEG_LVL_MAX; j++) {
int data = 0;
const int feature_enabled = vp9_rb_read_bit(rb);
if (feature_enabled) {
- vp9_enable_segfeature(xd, i, j);
+ vp9_enable_segfeature(seg, i, j);
data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j));
if (vp9_is_segfeature_signed(j))
data = vp9_rb_read_bit(rb) ? -data : data;
}
- vp9_set_segdata(xd, i, j, data);
+ vp9_set_segdata(seg, i, j, data);
}
}
}
}
-static void setup_loopfilter(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
- VP9_COMMON *const cm = &pbi->common;
- MACROBLOCKD *const xd = &pbi->mb;
+static void setup_loopfilter(struct loopfilter *lf,
+ struct vp9_read_bit_buffer *rb) {
- cm->filter_level = vp9_rb_read_literal(rb, 6);
- cm->sharpness_level = vp9_rb_read_literal(rb, 3);
+ lf->filter_level = vp9_rb_read_literal(rb, 6);
+ lf->sharpness_level = vp9_rb_read_literal(rb, 3);
// Read in loop filter deltas applied at the MB level based on mode or ref
// frame.
- xd->mode_ref_lf_delta_update = 0;
+ lf->mode_ref_delta_update = 0;
- xd->mode_ref_lf_delta_enabled = vp9_rb_read_bit(rb);
- if (xd->mode_ref_lf_delta_enabled) {
- xd->mode_ref_lf_delta_update = vp9_rb_read_bit(rb);
- if (xd->mode_ref_lf_delta_update) {
+ lf->mode_ref_delta_enabled = vp9_rb_read_bit(rb);
+ if (lf->mode_ref_delta_enabled) {
+ lf->mode_ref_delta_update = vp9_rb_read_bit(rb);
+ if (lf->mode_ref_delta_update) {
int i;
- for (i = 0; i < MAX_REF_LF_DELTAS; i++) {
- if (vp9_rb_read_bit(rb)) {
- const int value = vp9_rb_read_literal(rb, 6);
- xd->ref_lf_deltas[i] = vp9_rb_read_bit(rb) ? -value : value;
- }
- }
+ for (i = 0; i < MAX_REF_LF_DELTAS; i++)
+ if (vp9_rb_read_bit(rb))
+ lf->ref_deltas[i] = vp9_rb_read_signed_literal(rb, 6);
- for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
- if (vp9_rb_read_bit(rb)) {
- const int value = vp9_rb_read_literal(rb, 6);
- xd->mode_lf_deltas[i] = vp9_rb_read_bit(rb) ? -value : value;
- }
- }
+ for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
+ if (vp9_rb_read_bit(rb))
+ lf->mode_deltas[i] = vp9_rb_read_signed_literal(rb, 6);
}
}
}
static int read_delta_q(struct vp9_read_bit_buffer *rb, int *delta_q) {
const int old = *delta_q;
- if (vp9_rb_read_bit(rb)) {
- const int value = vp9_rb_read_literal(rb, 4);
- *delta_q = vp9_rb_read_bit(rb) ? -value : value;
- }
+ if (vp9_rb_read_bit(rb))
+ *delta_q = vp9_rb_read_signed_literal(rb, 4);
return old != *delta_q;
}
@@ -682,11 +488,9 @@ static void setup_quantization(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
cm->y_dc_delta_q == 0 &&
cm->uv_dc_delta_q == 0 &&
cm->uv_ac_delta_q == 0;
- if (xd->lossless) {
- xd->itxm_add = vp9_idct_add_lossless_c;
- } else {
- xd->itxm_add = vp9_idct_add;
- }
+
+ xd->itxm_add = xd->lossless ? vp9_idct_add_lossless_c
+ : vp9_idct_add;
}
static INTERPOLATIONFILTERTYPE read_interp_filter_type(
@@ -778,108 +582,90 @@ static void setup_frame_size_with_refs(VP9D_COMP *pbi,
apply_frame_size(pbi, width, height);
}
-static void update_frame_context(FRAME_CONTEXT *fc) {
- vp9_copy(fc->pre_coef_probs, fc->coef_probs);
- vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob);
- vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob);
- vp9_copy(fc->pre_partition_prob, fc->partition_prob[1]);
- vp9_copy(fc->pre_intra_inter_prob, fc->intra_inter_prob);
- vp9_copy(fc->pre_comp_inter_prob, fc->comp_inter_prob);
- vp9_copy(fc->pre_single_ref_prob, fc->single_ref_prob);
- vp9_copy(fc->pre_comp_ref_prob, fc->comp_ref_prob);
- fc->pre_nmvc = fc->nmvc;
- vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob);
- vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs);
- vp9_copy(fc->pre_tx_probs_8x8p, fc->tx_probs_8x8p);
- vp9_copy(fc->pre_tx_probs_16x16p, fc->tx_probs_16x16p);
- vp9_copy(fc->pre_tx_probs_32x32p, fc->tx_probs_32x32p);
- vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs);
-
- vp9_zero(fc->coef_counts);
- vp9_zero(fc->eob_branch_counts);
- vp9_zero(fc->y_mode_counts);
- vp9_zero(fc->uv_mode_counts);
- vp9_zero(fc->NMVcount);
- vp9_zero(fc->inter_mode_counts);
- vp9_zero(fc->partition_counts);
- vp9_zero(fc->switchable_interp_count);
- vp9_zero(fc->intra_inter_count);
- vp9_zero(fc->comp_inter_count);
- vp9_zero(fc->single_ref_count);
- vp9_zero(fc->comp_ref_count);
- vp9_zero(fc->tx_count_8x8p);
- vp9_zero(fc->tx_count_16x16p);
- vp9_zero(fc->tx_count_32x32p);
- vp9_zero(fc->mbskip_count);
-}
-
static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) {
VP9_COMMON *const pc = &pbi->common;
int mi_row, mi_col;
- for (mi_row = pc->cur_tile_mi_row_start;
- mi_row < pc->cur_tile_mi_row_end; mi_row += 64 / MI_SIZE) {
+ if (pbi->do_loopfilter_inline) {
+ vp9_loop_filter_frame_init(pc, &pbi->mb, pbi->mb.lf.filter_level);
+ }
+
+ for (mi_row = pc->cur_tile_mi_row_start; mi_row < pc->cur_tile_mi_row_end;
+ mi_row += MI_BLOCK_SIZE) {
// For a SB there are 2 left contexts, each pertaining to a MB row within
vpx_memset(&pc->left_context, 0, sizeof(pc->left_context));
vpx_memset(pc->left_seg_context, 0, sizeof(pc->left_seg_context));
- for (mi_col = pc->cur_tile_mi_col_start;
- mi_col < pc->cur_tile_mi_col_end; mi_col += 64 / MI_SIZE)
+ for (mi_col = pc->cur_tile_mi_col_start; mi_col < pc->cur_tile_mi_col_end;
+ mi_col += MI_BLOCK_SIZE) {
decode_modes_sb(pbi, mi_row, mi_col, r, BLOCK_SIZE_SB64X64);
+ }
+
+ if (pbi->do_loopfilter_inline) {
+ YV12_BUFFER_CONFIG *const fb =
+ &pbi->common.yv12_fb[pbi->common.new_fb_idx];
+ // delay the loopfilter by 1 macroblock row.
+ const int lf_start = mi_row - MI_BLOCK_SIZE;
+ if (lf_start < 0) continue;
+ vp9_loop_filter_rows(fb, pc, &pbi->mb, lf_start, mi_row, 0);
+ }
+ }
+
+ if (pbi->do_loopfilter_inline) {
+ YV12_BUFFER_CONFIG *const fb = &pbi->common.yv12_fb[pbi->common.new_fb_idx];
+ vp9_loop_filter_rows(fb, pc, &pbi->mb,
+ mi_row - MI_BLOCK_SIZE, pc->mi_rows, 0);
}
}
static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
- int delta_log2_tiles;
+ int min_log2_tile_cols, max_log2_tile_cols, max_ones;
+ vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
- vp9_get_tile_n_bits(cm, &cm->log2_tile_columns, &delta_log2_tiles);
- while (delta_log2_tiles--) {
- if (vp9_rb_read_bit(rb)) {
- cm->log2_tile_columns++;
- } else {
- break;
- }
- }
+ // columns
+ max_ones = max_log2_tile_cols - min_log2_tile_cols;
+ cm->log2_tile_cols = min_log2_tile_cols;
+ while (max_ones-- && vp9_rb_read_bit(rb))
+ cm->log2_tile_cols++;
+ // rows
cm->log2_tile_rows = vp9_rb_read_bit(rb);
if (cm->log2_tile_rows)
cm->log2_tile_rows += vp9_rb_read_bit(rb);
-
- cm->tile_columns = 1 << cm->log2_tile_columns;
- cm->tile_rows = 1 << cm->log2_tile_rows;
}
-static void decode_tiles(VP9D_COMP *pbi,
- const uint8_t *data, size_t first_partition_size,
- vp9_reader *residual_bc) {
+static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) {
+ vp9_reader residual_bc;
+
VP9_COMMON *const pc = &pbi->common;
- const uint8_t *data_ptr = data + first_partition_size;
- const uint8_t* const data_end = pbi->source + pbi->source_sz;
+ const uint8_t *const data_end = pbi->source + pbi->source_sz;
+ const int aligned_mi_cols = mi_cols_aligned_to_sb(pc->mi_cols);
+ const int tile_cols = 1 << pc->log2_tile_cols;
+ const int tile_rows = 1 << pc->log2_tile_rows;
int tile_row, tile_col;
// Note: this memset assumes above_context[0], [1] and [2]
// are allocated as part of the same buffer.
- vpx_memset(pc->above_context[0], 0, sizeof(ENTROPY_CONTEXT) * 2 *
- MAX_MB_PLANE * mi_cols_aligned_to_sb(pc));
+ vpx_memset(pc->above_context[0], 0,
+ sizeof(ENTROPY_CONTEXT) * 2 * MAX_MB_PLANE * aligned_mi_cols);
- vpx_memset(pc->above_seg_context, 0, sizeof(PARTITION_CONTEXT) *
- mi_cols_aligned_to_sb(pc));
+ vpx_memset(pc->above_seg_context, 0,
+ sizeof(PARTITION_CONTEXT) * aligned_mi_cols);
if (pbi->oxcf.inv_tile_order) {
- const int n_cols = pc->tile_columns;
const uint8_t *data_ptr2[4][1 << 6];
vp9_reader bc_bak = {0};
// pre-initialize the offsets, we're going to read in inverse order
- data_ptr2[0][0] = data_ptr;
- for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+ data_ptr2[0][0] = data;
+ for (tile_row = 0; tile_row < tile_rows; tile_row++) {
if (tile_row) {
- const int size = read_be32(data_ptr2[tile_row - 1][n_cols - 1]);
- data_ptr2[tile_row - 1][n_cols - 1] += 4;
- data_ptr2[tile_row][0] = data_ptr2[tile_row - 1][n_cols - 1] + size;
+ const int size = read_be32(data_ptr2[tile_row - 1][tile_cols - 1]);
+ data_ptr2[tile_row - 1][tile_cols - 1] += 4;
+ data_ptr2[tile_row][0] = data_ptr2[tile_row - 1][tile_cols - 1] + size;
}
- for (tile_col = 1; tile_col < n_cols; tile_col++) {
+ for (tile_col = 1; tile_col < tile_cols; tile_col++) {
const int size = read_be32(data_ptr2[tile_row][tile_col - 1]);
data_ptr2[tile_row][tile_col - 1] += 4;
data_ptr2[tile_row][tile_col] =
@@ -887,48 +673,49 @@ static void decode_tiles(VP9D_COMP *pbi,
}
}
- for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+ for (tile_row = 0; tile_row < tile_rows; tile_row++) {
vp9_get_tile_row_offsets(pc, tile_row);
- for (tile_col = n_cols - 1; tile_col >= 0; tile_col--) {
+ for (tile_col = tile_cols - 1; tile_col >= 0; tile_col--) {
vp9_get_tile_col_offsets(pc, tile_col);
setup_token_decoder(pbi, data_ptr2[tile_row][tile_col],
data_end - data_ptr2[tile_row][tile_col],
- residual_bc);
- decode_tile(pbi, residual_bc);
- if (tile_row == pc->tile_rows - 1 && tile_col == n_cols - 1)
- bc_bak = *residual_bc;
+ &residual_bc);
+ decode_tile(pbi, &residual_bc);
+ if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1)
+ bc_bak = residual_bc;
}
}
- *residual_bc = bc_bak;
+ residual_bc = bc_bak;
} else {
int has_more;
- for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+ for (tile_row = 0; tile_row < tile_rows; tile_row++) {
vp9_get_tile_row_offsets(pc, tile_row);
- for (tile_col = 0; tile_col < pc->tile_columns; tile_col++) {
+ for (tile_col = 0; tile_col < tile_cols; tile_col++) {
size_t size;
vp9_get_tile_col_offsets(pc, tile_col);
- has_more = tile_col < pc->tile_columns - 1 ||
- tile_row < pc->tile_rows - 1;
+ has_more = tile_col < tile_cols - 1 || tile_row < tile_rows - 1;
if (has_more) {
- if (!read_is_valid(data_ptr, 4, data_end))
+ if (!read_is_valid(data, 4, data_end))
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt tile length");
- size = read_be32(data_ptr);
- data_ptr += 4;
+ size = read_be32(data);
+ data += 4;
} else {
- size = data_end - data_ptr;
+ size = data_end - data;
}
- setup_token_decoder(pbi, data_ptr, size, residual_bc);
- decode_tile(pbi, residual_bc);
- data_ptr += size;
+ setup_token_decoder(pbi, data, size, &residual_bc);
+ decode_tile(pbi, &residual_bc);
+ data += size;
}
}
}
+
+ return vp9_reader_find_end(&residual_bc);
}
static void check_sync_code(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
@@ -949,10 +736,9 @@ static void setup_inter_inter(VP9_COMMON *cm) {
int i;
cm->allow_comp_inter_inter = 0;
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
- cm->allow_comp_inter_inter |= i > 0 &&
+ for (i = 1; i < ALLOWED_REFS_PER_FRAME; ++i)
+ cm->allow_comp_inter_inter |=
cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1];
- }
if (cm->allow_comp_inter_inter) {
// which one is always-on in comp inter-inter?
@@ -999,7 +785,7 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
int frame_to_show = cm->ref_frame_map[vp9_rb_read_literal(rb, 3)];
ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->new_fb_idx, frame_to_show);
pbi->refresh_frame_flags = 0;
- cm->filter_level = 0;
+ xd->lf.filter_level = 0;
return 0;
}
@@ -1053,7 +839,7 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
- const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LG2);
+ const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LOG2);
cm->active_ref_idx[i] = cm->ref_frame_map[ref];
cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
}
@@ -1078,23 +864,54 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
cm->frame_parallel_decoding_mode = 1;
}
- cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
+ cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LOG2);
if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode || cm->intra_only)
vp9_setup_past_independence(cm, xd);
- setup_loopfilter(pbi, rb);
+ setup_loopfilter(&xd->lf, rb);
setup_quantization(pbi, rb);
- setup_segmentation(pbi, rb);
+ setup_segmentation(&xd->seg, rb);
setup_tile_info(cm, rb);
return vp9_rb_read_literal(rb, 16);
}
+static int read_compressed_header(VP9D_COMP *pbi, const uint8_t *data,
+ size_t partition_size) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+ vp9_reader r;
+
+ if (vp9_reader_init(&r, data, partition_size))
+ vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+ "Failed to allocate bool decoder 0");
+
+ cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r);
+ if (cm->tx_mode == TX_MODE_SELECT)
+ read_tx_probs(&cm->fc.tx_probs, &r);
+ read_coef_probs(&cm->fc, cm->tx_mode, &r);
+
+ vp9_prepare_read_mode_info(pbi, &r);
+
+ return vp9_reader_has_error(&r);
+}
+
+void vp9_init_dequantizer(VP9_COMMON *cm) {
+ int q;
+
+ for (q = 0; q < QINDEX_RANGE; q++) {
+ cm->y_dequant[q][0] = vp9_dc_quant(q, cm->y_dc_delta_q);
+ cm->y_dequant[q][1] = vp9_ac_quant(q, 0);
+
+ cm->uv_dequant[q][0] = vp9_dc_quant(q, cm->uv_dc_delta_q);
+ cm->uv_dequant[q][1] = vp9_ac_quant(q, cm->uv_ac_delta_q);
+ }
+}
+
int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
int i;
- vp9_reader header_bc, residual_bc;
VP9_COMMON *const pc = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
@@ -1115,6 +932,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
data += vp9_rb_bytes_read(&rb);
xd->corrupted = 0;
new_fb->corrupted = 0;
+ pbi->do_loopfilter_inline =
+ (pc->log2_tile_rows | pc->log2_tile_cols) == 0 && pbi->mb.lf.filter_level;
if (!pbi->decoded_key_frame && !keyframe)
return -1;
@@ -1125,37 +944,29 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
xd->mode_info_context = pc->mi;
xd->prev_mode_info_context = pc->prev_mi;
- xd->frame_type = pc->frame_type;
xd->mode_info_stride = pc->mode_info_stride;
- if (vp9_reader_init(&header_bc, data, first_partition_size))
- vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
- "Failed to allocate bool decoder 0");
-
- mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup
+ init_dequantizer(pc, &pbi->mb);
if (!keyframe)
vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
pc->fc = pc->frame_contexts[pc->frame_context_idx];
- update_frame_context(&pc->fc);
-
- setup_txfm_mode(pc, xd->lossless, &header_bc);
-
- read_coef_probs(pbi, &header_bc);
+ vp9_zero(pc->counts);
// Initialize xd pointers. Any reference should do for xd->pre, so use 0.
- setup_pre_planes(xd, &pc->yv12_fb[pc->active_ref_idx[0]], NULL,
- 0, 0, NULL, NULL);
+ setup_pre_planes(xd, 0, &pc->yv12_fb[pc->active_ref_idx[0]], 0, 0, NULL);
setup_dst_planes(xd, new_fb, 0, 0);
+ new_fb->corrupted |= read_compressed_header(pbi, data, first_partition_size);
+
// Create the segmentation map structure and set to 0
if (!pc->last_frame_seg_map)
- CHECK_MEM_ERROR(pc->last_frame_seg_map,
+ CHECK_MEM_ERROR(pc, pc->last_frame_seg_map,
vpx_calloc((pc->mi_rows * pc->mi_cols), 1));
- vp9_setup_block_dptrs(xd, pc->subsampling_x, pc->subsampling_y);
+ setup_block_dptrs(xd, pc->subsampling_x, pc->subsampling_y);
// clear out the coeff buffer
for (i = 0; i < MAX_MB_PLANE; ++i)
@@ -1163,14 +974,12 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
set_prev_mi(pc);
- vp9_decode_mode_mvs_init(pbi, &header_bc);
-
- decode_tiles(pbi, data, first_partition_size, &residual_bc);
+ *p_data_end = decode_tiles(pbi, data + first_partition_size);
pc->last_width = pc->width;
pc->last_height = pc->height;
- new_fb->corrupted = vp9_reader_has_error(&header_bc) | xd->corrupted;
+ new_fb->corrupted |= xd->corrupted;
if (!pbi->decoded_key_frame) {
if (keyframe && !new_fb->corrupted)
@@ -1180,20 +989,18 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
"A stream must start with a complete key frame");
}
- // Adaptation
if (!pc->error_resilient_mode && !pc->frame_parallel_decoding_mode) {
vp9_adapt_coef_probs(pc);
- if ((!keyframe) && (!pc->intra_only)) {
+ if (!keyframe && !pc->intra_only) {
vp9_adapt_mode_probs(pc);
vp9_adapt_mode_context(pc);
- vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
+ vp9_adapt_mv_probs(pc, xd->allow_high_precision_mv);
}
}
if (pc->refresh_frame_context)
pc->frame_contexts[pc->frame_context_idx] = pc->fc;
- *p_data_end = vp9_reader_find_end(&residual_bc);
return 0;
}
diff --git a/libvpx/vp9/decoder/vp9_decodframe.h b/libvpx/vp9/decoder/vp9_decodframe.h
index 66e951d..00b6d67 100644
--- a/libvpx/vp9/decoder/vp9_decodframe.h
+++ b/libvpx/vp9/decoder/vp9_decodframe.h
@@ -17,6 +17,5 @@ struct VP9Decompressor;
void vp9_init_dequantizer(struct VP9Common *pc);
int vp9_decode_frame(struct VP9Decompressor *cpi, const uint8_t **p_data_end);
-vp9_prob vp9_read_prob_diff_update(vp9_reader *r, int oldp);
#endif // VP9_DECODER_VP9_DECODFRAME_H_
diff --git a/libvpx/vp9/decoder/vp9_detokenize.c b/libvpx/vp9/decoder/vp9_detokenize.c
index 3bbb212..01c1db0 100644
--- a/libvpx/vp9/decoder/vp9_detokenize.c
+++ b/libvpx/vp9/decoder/vp9_detokenize.c
@@ -18,14 +18,8 @@
#include "vp9/decoder/vp9_detokenize.h"
#include "vp9/decoder/vp9_onyxd_int.h"
-#if CONFIG_BALANCED_COEFTREE
-#define ZERO_CONTEXT_NODE 0
-#define EOB_CONTEXT_NODE 1
-#else
#define EOB_CONTEXT_NODE 0
#define ZERO_CONTEXT_NODE 1
-#endif
-
#define ONE_CONTEXT_NODE 2
#define LOW_VAL_CONTEXT_NODE 3
#define TWO_CONTEXT_NODE 4
@@ -91,13 +85,15 @@ DECLARE_ALIGNED(16, extern const uint8_t,
val += 1 << bits_count; \
} while (0);
-static int decode_coefs(FRAME_CONTEXT *fc, const MACROBLOCKD *xd,
+static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd,
vp9_reader *r, int block_idx,
PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
TX_SIZE txfm_size, const int16_t *dq,
ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) {
+ FRAME_CONTEXT *const fc = &cm->fc;
+ FRAME_COUNTS *const counts = &cm->counts;
ENTROPY_CONTEXT above_ec, left_ec;
- int pt, c = 0, pad, default_eob;
+ int pt, c = 0;
int band;
vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES];
vp9_prob coef_probs_full[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
@@ -113,53 +109,31 @@ static int decode_coefs(FRAME_CONTEXT *fc, const MACROBLOCKD *xd,
vp9_prob *prob;
vp9_coeff_count_model *coef_counts;
const int ref = xd->mode_info_context->mbmi.ref_frame[0] != INTRA_FRAME;
- TX_TYPE tx_type = DCT_DCT;
- const int *scan, *nb;
+ const int16_t *scan, *nb;
uint8_t token_cache[1024];
const uint8_t * band_translate;
-#if CONFIG_BALANCED_COEFTREE
- int skip_eob_node = 0;
-#endif
-
coef_probs = fc->coef_probs[txfm_size][type][ref];
- coef_counts = fc->coef_counts[txfm_size];
+ coef_counts = counts->coef[txfm_size];
switch (txfm_size) {
default:
case TX_4X4: {
- tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
- get_tx_type_4x4(xd, block_idx) : DCT_DCT;
- scan = get_scan_4x4(tx_type);
+ scan = get_scan_4x4(get_tx_type_4x4(type, xd, block_idx));
above_ec = A[0] != 0;
left_ec = L[0] != 0;
- default_eob = 16;
band_translate = vp9_coefband_trans_4x4;
break;
}
case TX_8X8: {
- const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
- const int sz = 1 + b_width_log2(sb_type);
- const int x = block_idx & ((1 << sz) - 1);
- const int y = block_idx - x;
- tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
- get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
- scan = get_scan_8x8(tx_type);
+ scan = get_scan_8x8(get_tx_type_8x8(type, xd));
above_ec = (A[0] + A[1]) != 0;
left_ec = (L[0] + L[1]) != 0;
- default_eob = 64;
band_translate = vp9_coefband_trans_8x8plus;
break;
}
case TX_16X16: {
- const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
- const int sz = 2 + b_width_log2(sb_type);
- const int x = block_idx & ((1 << sz) - 1);
- const int y = block_idx - x;
- tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
- get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
- scan = get_scan_16x16(tx_type);
+ scan = get_scan_16x16(get_tx_type_16x16(type, xd));
above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
- default_eob = 256;
band_translate = vp9_coefband_trans_8x8plus;
break;
}
@@ -167,13 +141,12 @@ static int decode_coefs(FRAME_CONTEXT *fc, const MACROBLOCKD *xd,
scan = vp9_default_scan_32x32;
above_ec = (A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7]) != 0;
left_ec = (L[0] + L[1] + L[2] + L[3] + L[4] + L[5] + L[6] + L[7]) != 0;
- default_eob = 1024;
band_translate = vp9_coefband_trans_8x8plus;
break;
}
pt = combine_entropy_contexts(above_ec, left_ec);
- nb = vp9_get_coef_neighbors_handle(scan, &pad);
+ nb = vp9_get_coef_neighbors_handle(scan);
while (1) {
int val;
@@ -181,43 +154,26 @@ static int decode_coefs(FRAME_CONTEXT *fc, const MACROBLOCKD *xd,
if (c >= seg_eob)
break;
if (c)
- pt = vp9_get_coef_context(scan, nb, pad, token_cache,
- c, default_eob);
+ pt = get_coef_context(nb, token_cache, c);
band = get_coef_band(band_translate, c);
prob = coef_probs[band][pt];
-#if !CONFIG_BALANCED_COEFTREE
- fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
+ counts->eob_branch[txfm_size][type][ref][band][pt]++;
if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
break;
SKIP_START:
-#endif
if (c >= seg_eob)
break;
if (c)
- pt = vp9_get_coef_context(scan, nb, pad, token_cache,
- c, default_eob);
+ pt = get_coef_context(nb, token_cache, c);
band = get_coef_band(band_translate, c);
prob = coef_probs[band][pt];
if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
INCREMENT_COUNT(ZERO_TOKEN);
++c;
-#if CONFIG_BALANCED_COEFTREE
- skip_eob_node = 1;
- continue;
-#else
goto SKIP_START;
-#endif
- }
-#if CONFIG_BALANCED_COEFTREE
- if (!skip_eob_node) {
- fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
- if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
- break;
}
- skip_eob_node = 0;
-#endif
// ONE_CONTEXT_NODE_0_
if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
@@ -293,8 +249,8 @@ SKIP_START:
return c;
}
-static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
- return vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
+static int get_eob(struct segmentation *seg, int segment_id, int eob_max) {
+ return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
}
struct decode_block_args {
@@ -315,7 +271,7 @@ static void decode_block(int plane, int block,
struct macroblockd_plane* pd = &xd->plane[plane];
const int segment_id = xd->mode_info_context->mbmi.segment_id;
const TX_SIZE ss_tx_size = ss_txfrm_size / 2;
- const int seg_eob = get_eob(xd, segment_id, 16 << ss_txfrm_size);
+ const int seg_eob = get_eob(&xd->seg, segment_id, 16 << ss_txfrm_size);
const int off = block >> ss_txfrm_size;
const int mod = bw - ss_tx_size - pd->subsampling_x;
const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size;
@@ -323,7 +279,7 @@ static void decode_block(int plane, int block,
ENTROPY_CONTEXT *A = pd->above_context + aoff;
ENTROPY_CONTEXT *L = pd->left_context + loff;
- const int eob = decode_coefs(&arg->pbi->common.fc, xd, arg->r, block,
+ const int eob = decode_coefs(&arg->pbi->common, xd, arg->r, block,
pd->plane_type, seg_eob,
BLOCK_OFFSET(pd->qcoeff, block, 16),
ss_tx_size, pd->dequant, A, L);
diff --git a/libvpx/vp9/decoder/vp9_dsubexp.c b/libvpx/vp9/decoder/vp9_dsubexp.c
new file mode 100644
index 0000000..8cc64f7
--- /dev/null
+++ b/libvpx/vp9/decoder/vp9_dsubexp.c
@@ -0,0 +1,106 @@
+/*
+ Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "vp9/common/vp9_entropy.h"
+
+#include "vp9/decoder/vp9_dsubexp.h"
+
+static int inv_recenter_nonneg(int v, int m) {
+ if (v > 2 * m)
+ return v;
+
+ return v % 2 ? m - (v + 1) / 2 : m + v / 2;
+}
+
+static int decode_uniform(vp9_reader *r, int n) {
+ int v;
+ const int l = get_unsigned_bits(n);
+ const int m = (1 << l) - n;
+ if (!l)
+ return 0;
+
+ v = vp9_read_literal(r, l - 1);
+ return v < m ? v : (v << 1) - m + vp9_read_bit(r);
+}
+
+
+static int merge_index(int v, int n, int modulus) {
+ int max1 = (n - 1 - modulus / 2) / modulus + 1;
+ if (v < max1) {
+ v = v * modulus + modulus / 2;
+ } else {
+ int w;
+ v -= max1;
+ w = v;
+ v += (v + modulus - modulus / 2) / modulus;
+ while (v % modulus == modulus / 2 ||
+ w != v - (v + modulus - modulus / 2) / modulus) v++;
+ }
+ return v;
+}
+
+static int inv_remap_prob(int v, int m) {
+ static int inv_map_table[MAX_PROB - 1] = {
+ // generated by:
+ // inv_map_table[j] = merge_index(j, MAX_PROB - 1, MODULUS_PARAM);
+ 6, 19, 32, 45, 58, 71, 84, 97, 110, 123, 136, 149, 162, 175, 188,
+ 201, 214, 227, 240, 253, 0, 1, 2, 3, 4, 5, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+ 108, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 137, 138, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 154, 155, 156,
+ 157, 158, 159, 160, 161, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
+ 173, 174, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 189,
+ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 202, 203, 204, 205,
+ 206, 207, 208, 209, 210, 211, 212, 213, 215, 216, 217, 218, 219, 220, 221,
+ 222, 223, 224, 225, 226, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
+ 238, 239, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
+
+ };
+ // v = merge_index(v, MAX_PROBS - 1, MODULUS_PARAM);
+ v = inv_map_table[v];
+ m--;
+ if ((m << 1) <= MAX_PROB) {
+ return 1 + inv_recenter_nonneg(v + 1, m);
+ } else {
+ return MAX_PROB - inv_recenter_nonneg(v + 1, MAX_PROB - 1 - m);
+ }
+}
+
+static int decode_term_subexp(vp9_reader *r, int k, int num_syms) {
+ int i = 0, mk = 0, word;
+ while (1) {
+ const int b = i ? k + i - 1 : k;
+ const int a = 1 << b;
+ if (num_syms <= mk + 3 * a) {
+ word = decode_uniform(r, num_syms - mk) + mk;
+ break;
+ } else {
+ if (vp9_read_bit(r)) {
+ i++;
+ mk += a;
+ } else {
+ word = vp9_read_literal(r, b) + mk;
+ break;
+ }
+ }
+ }
+ return word;
+}
+
+void vp9_diff_update_prob(vp9_reader *r, vp9_prob* p) {
+ int delp = decode_term_subexp(r, SUBEXP_PARAM, 255);
+ *p = (vp9_prob)inv_remap_prob(delp, *p);
+}
diff --git a/libvpx/vp9/decoder/vp9_asm_dec_offsets.c b/libvpx/vp9/decoder/vp9_dsubexp.h
index e4b9c97..aeb9399 100644
--- a/libvpx/vp9/decoder/vp9_asm_dec_offsets.c
+++ b/libvpx/vp9/decoder/vp9_dsubexp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@@ -9,12 +9,11 @@
*/
-#include "vpx_ports/asm_offsets.h"
-#include "vp9/decoder/vp9_onyxd_int.h"
+#ifndef VP9_DECODER_VP9_DSUBEXP_H_
+#define VP9_DECODER_VP9_DSUBEXP_H_
-BEGIN
+#include "vp9/decoder/vp9_dboolhuff.h"
-END
+void vp9_diff_update_prob(vp9_reader *r, vp9_prob* p);
-/* add asserts for any offset that is not supported by assembly code */
-/* add asserts for any size that is not supported by assembly code */
+#endif // VP9_DECODER_VP9_DSUBEXP_H_
diff --git a/libvpx/vp9/decoder/vp9_idct_blk.c b/libvpx/vp9/decoder/vp9_idct_blk.c
index c52963c..0217919 100644
--- a/libvpx/vp9/decoder/vp9_idct_blk.c
+++ b/libvpx/vp9/decoder/vp9_idct_blk.c
@@ -66,7 +66,7 @@ void vp9_idct_add_c(int16_t *input, uint8_t *dest, int stride, int eob) {
vp9_short_idct4x4_add(input, dest, stride);
vpx_memset(input, 0, 32);
} else {
- vp9_dc_only_idct_add(input[0], dest, dest, stride, stride);
+ vp9_short_idct4x4_1_add(input, dest, stride);
((int *)input)[0] = 0;
}
}
diff --git a/libvpx/vp9/decoder/vp9_onyxd_if.c b/libvpx/vp9/decoder/vp9_onyxd_if.c
index 3cef88b..cb72920 100644
--- a/libvpx/vp9/decoder/vp9_onyxd_if.c
+++ b/libvpx/vp9/decoder/vp9_onyxd_if.c
@@ -136,7 +136,7 @@ VP9D_PTR vp9_create_decompressor(VP9D_CONFIG *oxcf) {
// vp9_init_dequantizer() for every frame.
vp9_init_dequantizer(&pbi->common);
- vp9_loop_filter_init(&pbi->common);
+ vp9_loop_filter_init(&pbi->common, &pbi->mb.lf);
pbi->common.error.setjmp = 0;
pbi->decoded_key_frame = 0;
@@ -154,7 +154,6 @@ void vp9_remove_decompressor(VP9D_PTR ptr) {
vpx_free(pbi->common.last_frame_seg_map);
vp9_remove_common(&pbi->common);
- vpx_free(pbi->mbc);
vpx_free(pbi);
}
@@ -347,9 +346,9 @@ int vp9_receive_compressed_data(VP9D_PTR ptr,
cm->current_video_frame + 1000);
#endif
- if (cm->filter_level) {
+ if (!pbi->do_loopfilter_inline) {
/* Apply the loop filter if appropriate. */
- vp9_loop_filter_frame(cm, &pbi->mb, cm->filter_level, 0);
+ vp9_loop_filter_frame(cm, &pbi->mb, pbi->mb.lf.filter_level, 0);
}
#if WRITE_RECON_BUFFER == 2
@@ -361,8 +360,9 @@ int vp9_receive_compressed_data(VP9D_PTR ptr,
cm->current_video_frame + 3000);
#endif
- vp9_extend_frame_borders(cm->frame_to_show,
- cm->subsampling_x, cm->subsampling_y);
+ vp9_extend_frame_inner_borders(cm->frame_to_show,
+ cm->subsampling_x,
+ cm->subsampling_y);
}
#if WRITE_RECON_BUFFER == 1
@@ -412,9 +412,8 @@ int vp9_get_raw_frame(VP9D_PTR ptr, YV12_BUFFER_CONFIG *sd,
*time_stamp = pbi->last_time_stamp;
*time_end_stamp = 0;
- sd->clrtype = pbi->common.clr_type;
#if CONFIG_POSTPROC
- ret = vp9_post_proc_frame(&pbi->common, sd, flags);
+ ret = vp9_post_proc_frame(&pbi->common, &pbi->mb.lf, sd, flags);
#else
if (pbi->common.frame_to_show) {
diff --git a/libvpx/vp9/decoder/vp9_onyxd_int.h b/libvpx/vp9/decoder/vp9_onyxd_int.h
index 8698570..4760066 100644
--- a/libvpx/vp9/decoder/vp9_onyxd_int.h
+++ b/libvpx/vp9/decoder/vp9_onyxd_int.h
@@ -10,13 +10,14 @@
#ifndef VP9_DECODER_VP9_ONYXD_INT_H_
#define VP9_DECODER_VP9_ONYXD_INT_H_
+
#include "./vpx_config.h"
-#include "vp9/decoder/vp9_onyxd.h"
-#include "vp9/decoder/vp9_treereader.h"
+
#include "vp9/common/vp9_onyxc_int.h"
-#include "vp9/decoder/vp9_idct_blk.h"
-// #define DEC_DEBUG
+#include "vp9/decoder/vp9_idct_blk.h"
+#include "vp9/decoder/vp9_onyxd.h"
+#include "vp9/decoder/vp9_treereader.h"
typedef struct VP9Decompressor {
DECLARE_ALIGNED(16, MACROBLOCKD, mb);
@@ -28,35 +29,17 @@ typedef struct VP9Decompressor {
const uint8_t *source;
uint32_t source_sz;
- vp9_reader *mbc;
int64_t last_time_stamp;
int ready_for_new_data;
int refresh_frame_flags;
- vp9_prob prob_skip_false;
int decoded_key_frame;
int initial_width;
int initial_height;
-} VP9D_COMP;
-
-#if CONFIG_DEBUG
-#define CHECK_MEM_ERROR(lval,expr) do {\
- lval = (expr); \
- if(!lval) \
- vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,\
- "Failed to allocate "#lval" at %s:%d", \
- __FILE__,__LINE__);\
- } while(0)
-#else
-#define CHECK_MEM_ERROR(lval,expr) do {\
- lval = (expr); \
- if(!lval) \
- vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,\
- "Failed to allocate "#lval);\
- } while(0)
-#endif
+ int do_loopfilter_inline; // apply loopfilter to available rows immediately
+} VP9D_COMP;
#endif // VP9_DECODER_VP9_TREEREADER_H_
diff --git a/libvpx/vp9/decoder/vp9_read_bit_buffer.h b/libvpx/vp9/decoder/vp9_read_bit_buffer.h
index f243cb4..c7fa3aa 100644
--- a/libvpx/vp9/decoder/vp9_read_bit_buffer.h
+++ b/libvpx/vp9/decoder/vp9_read_bit_buffer.h
@@ -51,4 +51,10 @@ static int vp9_rb_read_literal(struct vp9_read_bit_buffer *rb, int bits) {
return value;
}
+static int vp9_rb_read_signed_literal(struct vp9_read_bit_buffer *rb,
+ int bits) {
+ const int value = vp9_rb_read_literal(rb, bits);
+ return vp9_rb_read_bit(rb) ? -value : value;
+}
+
#endif // VP9_READ_BIT_BUFFER_