Commit 3e579a60 authored by Sarah Parker's avatar Sarah Parker

Remove global motion from compressed header

This requires making a temporary copy of the functions in
binary_codes_writer/reader to take in the aom_write_bit_buffer type.

Change-Id: Idb60b29cff69b45224535c6e6a4079a34a2c6871
parent 49c335f4
......@@ -53,6 +53,15 @@ uint16_t aom_read_primitive_quniform_(aom_reader *r,
return v < m ? v : (v << 1) - m + aom_read_bit(r, ACCT_STR_NAME);
}
static uint16_t aom_rb_read_primitive_quniform(struct aom_read_bit_buffer *rb,
uint16_t n) {
if (n <= 1) return 0;
const int l = get_msb(n - 1) + 1;
const int m = (1 << l) - n;
const int v = aom_rb_read_literal(rb, l - 1);
return v < m ? v : (v << 1) - m + aom_rb_read_bit(rb);
}
uint16_t aom_read_primitive_refbilevel_(aom_reader *r, uint16_t n, uint16_t p,
uint16_t ref ACCT_STR_PARAM) {
if (n <= 1) return 0;
......@@ -101,15 +110,42 @@ uint16_t aom_read_primitive_subexpfin_(aom_reader *r, uint16_t n,
return v;
}
// Decode finite subexponential code that for a symbol v in [0, n-1] with
// parameter k
// based on a reference ref also in [0, n-1].
static uint16_t aom_rb_read_primitive_subexpfin(struct aom_read_bit_buffer *rb,
uint16_t n, uint16_t k) {
int i = 0;
int mk = 0;
uint16_t v;
while (1) {
int b = (i ? k + i - 1 : k);
int a = (1 << b);
if (n <= mk + 3 * a) {
v = aom_rb_read_primitive_quniform(rb, n - mk) + mk;
break;
} else {
if (aom_rb_read_bit(rb)) {
i = i + 1;
mk += a;
} else {
v = aom_rb_read_literal(rb, b) + mk;
break;
}
}
}
return v;
}
uint16_t aom_read_primitive_refsubexpfin_(aom_reader *r, uint16_t n, uint16_t k,
uint16_t ref ACCT_STR_PARAM) {
return inv_recenter_finite_nonneg(
n, ref, aom_read_primitive_subexpfin(r, n, k, ACCT_STR_NAME));
}
static uint16_t aom_rb_read_primitive_refsubexpfin(
struct aom_read_bit_buffer *rb, uint16_t n, uint16_t k, uint16_t ref) {
return inv_recenter_finite_nonneg(n, ref,
aom_rb_read_primitive_subexpfin(rb, n, k));
}
// Decode finite subexponential code that for a symbol v in [-(n-1), n-1] with
// parameter k based on a reference ref also in [-(n-1), n-1].
int16_t aom_read_signed_primitive_refsubexpfin_(aom_reader *r, uint16_t n,
......@@ -120,3 +156,10 @@ int16_t aom_read_signed_primitive_refsubexpfin_(aom_reader *r, uint16_t n,
return aom_read_primitive_refsubexpfin(r, scaled_n, k, ref, ACCT_STR_NAME) -
n + 1;
}
int16_t aom_rb_read_signed_primitive_refsubexpfin(
struct aom_read_bit_buffer *rb, uint16_t n, uint16_t k, int16_t ref) {
ref += n - 1;
const uint16_t scaled_n = (n << 1) - 1;
return aom_rb_read_primitive_refsubexpfin(rb, scaled_n, k, ref) - n + 1;
}
......@@ -17,9 +17,11 @@ extern "C" {
#endif
#include <assert.h>
#include "./aom_config.h"
#include "aom/aom_integer.h"
#include "aom_dsp/bitreader.h"
#include "aom_dsp/bitreader_buffer.h"
#define aom_read_primitive_symmetric(r, n, ACCT_STR_NAME) \
aom_read_primitive_symmetric_(r, n ACCT_STR_ARG(ACCT_STR_NAME))
......@@ -47,6 +49,9 @@ uint16_t aom_read_primitive_refsubexpfin_(aom_reader *r, uint16_t n, uint16_t k,
int16_t aom_read_signed_primitive_refsubexpfin_(aom_reader *r, uint16_t n,
uint16_t k,
int16_t ref ACCT_STR_PARAM);
int16_t aom_rb_read_signed_primitive_refsubexpfin(
struct aom_read_bit_buffer *rb, uint16_t n, uint16_t k, int16_t ref);
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -10,6 +10,7 @@
*/
#include "aom_dsp/bitwriter.h"
#include "aom_dsp/binary_codes_writer.h"
#include "av1/common/common.h"
......@@ -68,6 +69,19 @@ void aom_write_primitive_quniform(aom_writer *w, uint16_t n, uint16_t v) {
}
}
static void aom_wb_write_primitive_quniform(struct aom_write_bit_buffer *wb,
uint16_t n, uint16_t v) {
if (n <= 1) return;
const int l = get_msb(n - 1) + 1;
const int m = (1 << l) - n;
if (v < m) {
aom_wb_write_literal(wb, v, l - 1);
} else {
aom_wb_write_literal(wb, m + ((v - m) >> 1), l - 1);
aom_wb_write_bit(wb, (v - m) & 1);
}
}
int aom_count_primitive_quniform(uint16_t n, uint16_t v) {
if (n <= 1) return 0;
const int l = get_msb(n - 1) + 1;
......@@ -155,6 +169,31 @@ void aom_write_primitive_subexpfin(aom_writer *w, uint16_t n, uint16_t k,
}
}
static void aom_wb_write_primitive_subexpfin(struct aom_write_bit_buffer *wb,
uint16_t n, uint16_t k,
uint16_t v) {
int i = 0;
int mk = 0;
while (1) {
int b = (i ? k + i - 1 : k);
int a = (1 << b);
if (n <= mk + 3 * a) {
aom_wb_write_primitive_quniform(wb, n - mk, v - mk);
break;
} else {
int t = (v >= mk + a);
aom_wb_write_bit(wb, t);
if (t) {
i = i + 1;
mk += a;
} else {
aom_wb_write_literal(wb, v - mk, b);
break;
}
}
}
}
int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v) {
int count = 0;
int i = 0;
......@@ -184,19 +223,34 @@ int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v) {
// based on a reference ref also in [0, n-1].
// Recenters symbol around r first and then uses a finite subexponential code.
void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
int16_t ref, int16_t v) {
uint16_t ref, uint16_t v) {
aom_write_primitive_subexpfin(w, n, k, recenter_finite_nonneg(n, ref, v));
}
static void aom_wb_write_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
uint16_t n, uint16_t k,
uint16_t ref, uint16_t v) {
aom_wb_write_primitive_subexpfin(wb, n, k, recenter_finite_nonneg(n, ref, v));
}
void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
uint16_t k, uint16_t ref,
uint16_t v) {
uint16_t k, int16_t ref,
int16_t v) {
ref += n - 1;
v += n - 1;
const uint16_t scaled_n = (n << 1) - 1;
aom_write_primitive_refsubexpfin(w, scaled_n, k, ref, v);
}
void aom_wb_write_signed_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
uint16_t n, uint16_t k,
int16_t ref, int16_t v) {
ref += n - 1;
v += n - 1;
const uint16_t scaled_n = (n << 1) - 1;
aom_wb_write_primitive_refsubexpfin(wb, scaled_n, k, ref, v);
}
int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
uint16_t v) {
return aom_count_primitive_subexpfin(n, k, recenter_finite_nonneg(n, ref, v));
......
......@@ -20,6 +20,7 @@ extern "C" {
#include "./aom_config.h"
#include "aom/aom_integer.h"
#include "aom_dsp/bitwriter.h"
#include "aom_dsp/bitwriter_buffer.h"
// Codes a symbol v in [-2^mag_bits, 2^mag_bits]
// mag_bits is number of bits for magnitude. The alphabet is of size
......@@ -53,6 +54,10 @@ void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
uint16_t k, int16_t ref,
int16_t v);
void aom_wb_write_signed_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
uint16_t n, uint16_t k,
int16_t ref, int16_t v);
// Functions that counts bits for the above primitives
int aom_count_primitive_symmetric(int16_t v, unsigned int mag_bits);
int aom_count_primitive_quniform(uint16_t n, uint16_t v);
......
......@@ -4366,6 +4366,140 @@ static void check_valid_ref_frames(AV1_COMMON *cm) {
}
#endif // CONFIG_VAR_REFS
#if CONFIG_GLOBAL_MOTION
static int read_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
struct aom_read_bit_buffer *rb,
int allow_hp) {
TransformationType type = aom_rb_read_bit(rb);
if (type != IDENTITY) {
#if GLOBAL_TRANS_TYPES > 4
type += aom_rb_read_literal(rb, GLOBAL_TYPE_BITS);
#else
if (aom_rb_read_bit(rb))
type = ROTZOOM;
else
type = aom_rb_read_bit(rb) ? TRANSLATION : AFFINE;
#endif // GLOBAL_TRANS_TYPES > 4
}
int trans_bits;
int trans_dec_factor;
int trans_prec_diff;
set_default_warp_params(params);
params->wmtype = type;
switch (type) {
case HOMOGRAPHY:
case HORTRAPEZOID:
case VERTRAPEZOID:
if (type != HORTRAPEZOID)
params->wmmat[6] =
aom_rb_read_signed_primitive_refsubexpfin(
rb, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF)) *
GM_ROW3HOMO_DECODE_FACTOR;
if (type != VERTRAPEZOID)
params->wmmat[7] =
aom_rb_read_signed_primitive_refsubexpfin(
rb, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF)) *
GM_ROW3HOMO_DECODE_FACTOR;
case AFFINE:
case ROTZOOM:
params->wmmat[2] = aom_rb_read_signed_primitive_refsubexpfin(
rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS)) *
GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS);
if (type != VERTRAPEZOID)
params->wmmat[3] = aom_rb_read_signed_primitive_refsubexpfin(
rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF)) *
GM_ALPHA_DECODE_FACTOR;
if (type >= AFFINE) {
if (type != HORTRAPEZOID)
params->wmmat[4] = aom_rb_read_signed_primitive_refsubexpfin(
rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF)) *
GM_ALPHA_DECODE_FACTOR;
params->wmmat[5] = aom_rb_read_signed_primitive_refsubexpfin(
rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS)) *
GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS);
} else {
params->wmmat[4] = -params->wmmat[3];
params->wmmat[5] = params->wmmat[2];
}
// fallthrough intended
case TRANSLATION:
trans_bits = (type == TRANSLATION) ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
: GM_ABS_TRANS_BITS;
trans_dec_factor = (type == TRANSLATION)
? GM_TRANS_ONLY_DECODE_FACTOR * (1 << !allow_hp)
: GM_TRANS_DECODE_FACTOR;
trans_prec_diff = (type == TRANSLATION)
? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
: GM_TRANS_PREC_DIFF;
params->wmmat[0] = aom_rb_read_signed_primitive_refsubexpfin(
rb, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[0] >> trans_prec_diff)) *
trans_dec_factor;
params->wmmat[1] = aom_rb_read_signed_primitive_refsubexpfin(
rb, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[1] >> trans_prec_diff)) *
trans_dec_factor;
case IDENTITY: break;
default: assert(0);
}
if (params->wmtype <= AFFINE) {
int good_shear_params = get_shear_params(params);
if (!good_shear_params) return 0;
}
return 1;
}
static void read_global_motion(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
int frame;
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
int good_params = read_global_motion_params(
&cm->global_motion[frame], &cm->prev_frame->global_motion[frame], rb,
cm->allow_high_precision_mv);
if (!good_params)
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Invalid shear parameters for global motion.");
// TODO(sarahparker, debargha): The logic in the commented out code below
// does not work currently and causes mismatches when resize is on. Fix it
// before turning the optimization back on.
/*
YV12_BUFFER_CONFIG *ref_buf = get_ref_frame(cm, frame);
if (cm->width == ref_buf->y_crop_width &&
cm->height == ref_buf->y_crop_height) {
read_global_motion_params(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame], rb,
cm->allow_high_precision_mv);
} else {
set_default_warp_params(&cm->global_motion[frame]);
}
*/
/*
printf("Dec Ref %d [%d/%d]: %d %d %d %d\n",
frame, cm->current_video_frame, cm->show_frame,
cm->global_motion[frame].wmmat[0],
cm->global_motion[frame].wmmat[1],
cm->global_motion[frame].wmmat[2],
cm->global_motion[frame].wmmat[3]);
*/
}
memcpy(cm->cur_frame->global_motion, cm->global_motion,
TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
}
#endif // CONFIG_GLOBAL_MOTION
static size_t read_uncompressed_header(AV1Decoder *pbi,
struct aom_read_bit_buffer *rb) {
AV1_COMMON *const cm = &pbi->common;
......@@ -4821,6 +4955,10 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
cm->reduced_tx_set_used = aom_rb_read_bit(rb);
#endif // CONFIG_EXT_TX
#if CONFIG_GLOBAL_MOTION
read_global_motion(cm, rb);
#endif
read_tile_info(pbi, rb);
sz = aom_rb_read_literal(rb, 16);
......@@ -4843,145 +4981,6 @@ static void read_supertx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
}
#endif // CONFIG_SUPERTX
#if CONFIG_GLOBAL_MOTION
static int read_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
aom_reader *r, int allow_hp) {
TransformationType type = aom_read_bit(r, ACCT_STR);
if (type != IDENTITY) {
#if GLOBAL_TRANS_TYPES > 4
type += aom_read_literal(r, GLOBAL_TYPE_BITS, ACCT_STR);
#else
if (aom_read_bit(r, ACCT_STR))
type = ROTZOOM;
else
type = aom_read_bit(r, ACCT_STR) ? TRANSLATION : AFFINE;
#endif // GLOBAL_TRANS_TYPES > 4
}
int trans_bits;
int trans_dec_factor;
int trans_prec_diff;
set_default_warp_params(params);
params->wmtype = type;
switch (type) {
case HOMOGRAPHY:
case HORTRAPEZOID:
case VERTRAPEZOID:
if (type != HORTRAPEZOID)
params->wmmat[6] =
aom_read_signed_primitive_refsubexpfin(
r, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF), ACCT_STR) *
GM_ROW3HOMO_DECODE_FACTOR;
if (type != VERTRAPEZOID)
params->wmmat[7] =
aom_read_signed_primitive_refsubexpfin(
r, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF), ACCT_STR) *
GM_ROW3HOMO_DECODE_FACTOR;
case AFFINE:
case ROTZOOM:
params->wmmat[2] = aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
ACCT_STR) *
GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS);
if (type != VERTRAPEZOID)
params->wmmat[3] =
aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF), ACCT_STR) *
GM_ALPHA_DECODE_FACTOR;
if (type >= AFFINE) {
if (type != HORTRAPEZOID)
params->wmmat[4] =
aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF), ACCT_STR) *
GM_ALPHA_DECODE_FACTOR;
params->wmmat[5] = aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
ACCT_STR) *
GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS);
} else {
params->wmmat[4] = -params->wmmat[3];
params->wmmat[5] = params->wmmat[2];
}
// fallthrough intended
case TRANSLATION:
trans_bits = (type == TRANSLATION) ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
: GM_ABS_TRANS_BITS;
trans_dec_factor = (type == TRANSLATION)
? GM_TRANS_ONLY_DECODE_FACTOR * (1 << !allow_hp)
: GM_TRANS_DECODE_FACTOR;
trans_prec_diff = (type == TRANSLATION)
? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
: GM_TRANS_PREC_DIFF;
params->wmmat[0] =
aom_read_signed_primitive_refsubexpfin(
r, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[0] >> trans_prec_diff), ACCT_STR) *
trans_dec_factor;
params->wmmat[1] =
aom_read_signed_primitive_refsubexpfin(
r, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[1] >> trans_prec_diff), ACCT_STR) *
trans_dec_factor;
case IDENTITY: break;
default: assert(0);
}
if (params->wmtype <= AFFINE) {
int good_shear_params = get_shear_params(params);
if (!good_shear_params) return 0;
}
return 1;
}
static void read_global_motion(AV1_COMMON *cm, aom_reader *r) {
int frame;
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
int good_params = read_global_motion_params(
&cm->global_motion[frame], &cm->prev_frame->global_motion[frame], r,
cm->allow_high_precision_mv);
if (!good_params)
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Invalid shear parameters for global motion.");
// TODO(sarahparker, debargha): The logic in the commented out code below
// does not work currently and causes mismatches when resize is on. Fix it
// before turning the optimization back on.
/*
YV12_BUFFER_CONFIG *ref_buf = get_ref_frame(cm, frame);
if (cm->width == ref_buf->y_crop_width &&
cm->height == ref_buf->y_crop_height) {
read_global_motion_params(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame], r,
cm->allow_high_precision_mv);
} else {
set_default_warp_params(&cm->global_motion[frame]);
}
*/
/*
printf("Dec Ref %d [%d/%d]: %d %d %d %d\n",
frame, cm->current_video_frame, cm->show_frame,
cm->global_motion[frame].wmmat[0],
cm->global_motion[frame].wmmat[1],
cm->global_motion[frame].wmmat[2],
cm->global_motion[frame].wmmat[3]);
*/
}
memcpy(cm->cur_frame->global_motion, cm->global_motion,
TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
}
#endif // CONFIG_GLOBAL_MOTION
static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
size_t partition_size) {
AV1_COMMON *const cm = &pbi->common;
......@@ -5087,9 +5086,6 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
#endif
#if CONFIG_SUPERTX
if (!xd->lossless[0]) read_supertx_probs(fc, &r);
#endif
#if CONFIG_GLOBAL_MOTION
read_global_motion(cm, &r);
#endif
}
......@@ -5278,6 +5274,15 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
bitstream_queue_set_frame_read(cm->current_video_frame * 2 + cm->show_frame);
#endif
#if CONFIG_GLOBAL_MOTION
int i;
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
set_default_warp_params(&cm->global_motion[i]);
set_default_warp_params(&cm->cur_frame->global_motion[i]);
}
xd->global_motion = cm->global_motion;
#endif // CONFIG_GLOBAL_MOTION
first_partition_size = read_uncompressed_header(
pbi, init_read_bit_buffer(pbi, &rb, data, data_end, clear_data));
......@@ -5307,14 +5312,6 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
xd->cur_buf->y_crop_width, xd->cur_buf->y_crop_height);
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_INTRABC
#if CONFIG_GLOBAL_MOTION
int i;
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
set_default_warp_params(&cm->global_motion[i]);
set_default_warp_params(&cm->cur_frame->global_motion[i]);
}
xd->global_motion = cm->global_motion;
#endif // CONFIG_GLOBAL_MOTION
if (!first_partition_size) {
// showing a frame directly
......
......@@ -4196,6 +4196,120 @@ static void write_compound_tools(const AV1_COMMON *cm,
}
#endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
static void write_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
struct aom_write_bit_buffer *wb,
int allow_hp) {
TransformationType type = params->wmtype;
int trans_bits;
int trans_prec_diff;
aom_wb_write_bit(wb, type != IDENTITY);
if (type != IDENTITY) {
#if GLOBAL_TRANS_TYPES > 4
aom_wb_write_literal(wb, type - 1, GLOBAL_TYPE_BITS);
#else
aom_wb_write_bit(wb, type == ROTZOOM);
if (type != ROTZOOM) aom_wb_write_bit(wb, type == TRANSLATION);
#endif // GLOBAL_TRANS_TYPES > 4
}
switch (type) {
case HOMOGRAPHY:
case HORTRAPEZOID:
case VERTRAPEZOID:
if (type != HORTRAPEZOID)
aom_wb_write_signed_primitive_refsubexpfin(
wb, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
(params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF));
if (type != VERTRAPEZOID)
aom_wb_write_signed_primitive_refsubexpfin(
wb, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
(params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF));
// fallthrough intended
case AFFINE:
case ROTZOOM:
aom_wb_write_signed_primitive_refsubexpfin(
wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
(params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
if (type != VERTRAPEZOID)
aom_wb_write_signed_primitive_refsubexpfin(
wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF),
(params->wmmat[3] >> GM_ALPHA_PREC_DIFF));
if (type >= AFFINE) {
if (type != HORTRAPEZOID)
aom_wb_write_signed_primitive_refsubexpfin(
wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF),
(params->wmmat[4] >> GM_ALPHA_PREC_DIFF));
aom_wb_write_signed_primitive_refsubexpfin(
wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
(params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS));
}
// fallthrough intended
case TRANSLATION:
trans_bits = (type == TRANSLATION) ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
: GM_ABS_TRANS_BITS;
trans_prec_diff = (type == TRANSLATION)
? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
: GM_TRANS_PREC_DIFF;
aom_wb_write_signed_primitive_refsubexpfin(
wb, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[0] >> trans_prec_diff),
(params->wmmat[0] >> trans_prec_diff));
aom_wb_write_signed_primitive_refsubexpfin(
wb, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[1] >> trans_prec_diff),
(params->wmmat[1] >> trans_prec_diff));
break;
case IDENTITY: break;
default: assert(0);