diff --git a/aom_dsp/binary_codes_reader.c b/aom_dsp/binary_codes_reader.c index bf304dadaa8af67ebddb168805243c7eee602f80..4f38afbc55fabbcf4bf11bdc65306270f0af22b2 100644 --- a/aom_dsp/binary_codes_reader.c +++ b/aom_dsp/binary_codes_reader.c @@ -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; +} diff --git a/aom_dsp/binary_codes_reader.h b/aom_dsp/binary_codes_reader.h index 1540cf46b3280f273c18908f964fe81cdb768740..8885142c99c48bd69878891ad4c8a4bc379cb314 100644 --- a/aom_dsp/binary_codes_reader.h +++ b/aom_dsp/binary_codes_reader.h @@ -17,9 +17,11 @@ extern "C" { #endif #include + #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 diff --git a/aom_dsp/binary_codes_writer.c b/aom_dsp/binary_codes_writer.c index 91e807b299fd8b3df63d7311c21fe913144233dc..e092b627820e5c1c21444e46945fbf9c05d42151 100644 --- a/aom_dsp/binary_codes_writer.c +++ b/aom_dsp/binary_codes_writer.c @@ -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)); diff --git a/aom_dsp/binary_codes_writer.h b/aom_dsp/binary_codes_writer.h index ab5ccbf15ce259ef2483481690d478722d2d2fc2..18ad5078f63ed0f8d5a834881bcb90738045c073 100644 --- a/aom_dsp/binary_codes_writer.h +++ b/aom_dsp/binary_codes_writer.h @@ -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); diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index dbdc126b2df3303d542b3bf422d0209c9d853e6c..8efb3c447ac73cc69daf6a836105eaf38ec6dd0b 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -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 diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 30882fc4a9db27e7f876e974ef3bb1e5b749da45..2c8b0b9b6136acb50a53bb3effef9eba38c533ed 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -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); + } +} + +static void write_global_motion(AV1_COMP *cpi, + struct aom_write_bit_buffer *wb) { + AV1_COMMON *const cm = &cpi->common; + int frame; + for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) { + write_global_motion_params(&cm->global_motion[frame], + &cm->prev_frame->global_motion[frame], wb, + cm->allow_high_precision_mv); + // 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_buffer(cpi, frame); + if (cpi->source->y_crop_width == ref_buf->y_crop_width && + cpi->source->y_crop_height == ref_buf->y_crop_height) { + write_global_motion_params(&cm->global_motion[frame], + &cm->prev_frame->global_motion[frame], wb, + cm->allow_high_precision_mv); + } else { + assert(cm->global_motion[frame].wmtype == IDENTITY && + "Invalid warp type for frames of different resolutions"); + } + */ + /* + printf("Frame %d/%d: Enc Ref %d: %d %d %d %d\n", + cm->current_video_frame, cm->show_frame, 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]); + */ + } +} +#endif + static void write_uncompressed_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb) { AV1_COMMON *const cm = &cpi->common; @@ -4474,119 +4588,12 @@ static void write_uncompressed_header(AV1_COMP *cpi, aom_wb_write_bit(wb, cm->reduced_tx_set_used); #endif // CONFIG_EXT_TX - write_tile_info(cm, wb); -} - #if CONFIG_GLOBAL_MOTION -static void write_global_motion_params(WarpedMotionParams *params, - WarpedMotionParams *ref_params, - aom_writer *w, int allow_hp) { - TransformationType type = params->wmtype; - int trans_bits; - int trans_prec_diff; - aom_write_bit(w, type != IDENTITY); - if (type != IDENTITY) { -#if GLOBAL_TRANS_TYPES > 4 - aom_write_literal(w, type - 1, GLOBAL_TYPE_BITS); -#else - aom_write_bit(w, type == ROTZOOM); - if (type != ROTZOOM) aom_write_bit(w, type == TRANSLATION); -#endif // GLOBAL_TRANS_TYPES > 4 - } - - switch (type) { - case HOMOGRAPHY: - case HORTRAPEZOID: - case VERTRAPEZOID: - if (type != HORTRAPEZOID) - aom_write_signed_primitive_refsubexpfin( - w, 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_write_signed_primitive_refsubexpfin( - w, 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_write_signed_primitive_refsubexpfin( - w, 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_write_signed_primitive_refsubexpfin( - w, 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_write_signed_primitive_refsubexpfin( - w, GM_ALPHA_MAX + 1, SUBEXPFIN_K, - (ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF), - (params->wmmat[4] >> GM_ALPHA_PREC_DIFF)); - aom_write_signed_primitive_refsubexpfin( - w, 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_write_signed_primitive_refsubexpfin( - w, (1 << trans_bits) + 1, SUBEXPFIN_K, - (ref_params->wmmat[0] >> trans_prec_diff), - (params->wmmat[0] >> trans_prec_diff)); - aom_write_signed_primitive_refsubexpfin( - w, (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); - } -} + write_global_motion(cpi, wb); +#endif // CONFIG_GLOBAL_MOTION -static void write_global_motion(AV1_COMP *cpi, aom_writer *w) { - AV1_COMMON *const cm = &cpi->common; - int frame; - for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) { - write_global_motion_params(&cm->global_motion[frame], - &cm->prev_frame->global_motion[frame], w, - cm->allow_high_precision_mv); - // 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_buffer(cpi, frame); - if (cpi->source->y_crop_width == ref_buf->y_crop_width && - cpi->source->y_crop_height == ref_buf->y_crop_height) { - write_global_motion_params(&cm->global_motion[frame], - &cm->prev_frame->global_motion[frame], w, - cm->allow_high_precision_mv); - } else { - assert(cm->global_motion[frame].wmtype == IDENTITY && - "Invalid warp type for frames of different resolutions"); - } - */ - /* - printf("Frame %d/%d: Enc Ref %d (used %d): %d %d %d %d\n", - cm->current_video_frame, cm->show_frame, frame, - cpi->global_motion_used[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]); - */ - } + write_tile_info(cm, wb); } -#endif static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { AV1_COMMON *const cm = &cpi->common; @@ -4750,9 +4757,6 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { #if CONFIG_SUPERTX if (!xd->lossless[0]) update_supertx_probs(cm, probwt, header_bc); #endif // CONFIG_SUPERTX -#if CONFIG_GLOBAL_MOTION - write_global_motion(cpi, header_bc); -#endif // CONFIG_GLOBAL_MOTION } aom_stop_encode(header_bc); assert(header_bc->pos <= 0xffff);