Commit d2bcbb56 authored by Fergus Simpson's avatar Fergus Simpson

frame_superres: Post encode/decode upscaling

This patch implements the post-encode and post-decode upscaling for the
frame superresolution experiment to work.

Upscaling happens after cdef and before loop restoration.

For now, this patch forces on random-superres.

The patch also cleans up some broken rate control hooks from VP9
days, to be brought back later when the resize and superres tools
are stable.

Change-Id: If0a8f69224dfaa0f4ae7703bd429ea2af953c7a6
parent 8e689e4b
...@@ -302,6 +302,8 @@ typedef struct AV1Common { ...@@ -302,6 +302,8 @@ typedef struct AV1Common {
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
// The numerator of the superres scale; the denominator is fixed. // The numerator of the superres scale; the denominator is fixed.
uint8_t superres_scale_numerator; uint8_t superres_scale_numerator;
int superres_upscaled_width;
int superres_upscaled_height;
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
RestorationInfo rst_info[MAX_MB_PLANE]; RestorationInfo rst_info[MAX_MB_PLANE];
......
...@@ -816,11 +816,11 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride, ...@@ -816,11 +816,11 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride,
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
#if CONFIG_HIGHBITDEPTH #if CONFIG_HIGHBITDEPTH
static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src, void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst, int bd) { YV12_BUFFER_CONFIG *dst, int bd) {
#else #else
static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src, void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst) { YV12_BUFFER_CONFIG *dst) {
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
// TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t // TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t
int i; int i;
...@@ -855,8 +855,8 @@ static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src, ...@@ -855,8 +855,8 @@ static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm, YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled) { YV12_BUFFER_CONFIG *scaled) {
if (cm->mi_cols * MI_SIZE != unscaled->y_width || if (cm->width != unscaled->y_crop_width ||
cm->mi_rows * MI_SIZE != unscaled->y_height) { cm->height != unscaled->y_crop_height) {
// For 2x2 scaling down. // For 2x2 scaling down.
aom_scale_frame(unscaled, scaled, unscaled->y_buffer, 9, 2, 1, 2, 1, 0); aom_scale_frame(unscaled, scaled, unscaled->y_buffer, 9, 2, 1, 2, 1, 0);
aom_extend_frame_borders(scaled); aom_extend_frame_borders(scaled);
...@@ -869,14 +869,107 @@ YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm, ...@@ -869,14 +869,107 @@ YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm, YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled) { YV12_BUFFER_CONFIG *scaled) {
if (cm->width != unscaled->y_width || cm->height != unscaled->y_height) { if (cm->width != unscaled->y_crop_width ||
cm->height != unscaled->y_crop_height) {
#if CONFIG_HIGHBITDEPTH #if CONFIG_HIGHBITDEPTH
resize_and_extend_frame(unscaled, scaled, (int)cm->bit_depth); av1_resize_and_extend_frame(unscaled, scaled, (int)cm->bit_depth);
#else #else
resize_and_extend_frame(unscaled, scaled); av1_resize_and_extend_frame(unscaled, scaled);
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
return scaled; return scaled;
} else { } else {
return unscaled; return unscaled;
} }
} }
#if CONFIG_FRAME_SUPERRES
void av1_calculate_superres_size(const AV1_COMMON *cm, int *width,
int *height) {
*width = *width * cm->superres_scale_numerator / SUPERRES_SCALE_DENOMINATOR;
*height = *height * cm->superres_scale_numerator / SUPERRES_SCALE_DENOMINATOR;
}
// TODO(afergs): Look for in-place upscaling
// TODO(afergs): aom_ vs av1_ functions? Which can I use?
// Upscale decoded image.
void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool) {
if (av1_superres_unscaled(cm)) return;
YV12_BUFFER_CONFIG copy_buffer;
memset(&copy_buffer, 0, sizeof(copy_buffer));
YV12_BUFFER_CONFIG *const frame_to_show = get_frame_new_buffer(cm);
if (aom_alloc_frame_buffer(&copy_buffer, cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#ifdef CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif // CONFIG_HIGHBITDEPTH
AOM_BORDER_IN_PIXELS, cm->byte_alignment))
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate copy buffer for superres upscaling");
// Copy function assumes the frames are the same size, doesn't copy bit_depth.
aom_yv12_copy_frame(frame_to_show, &copy_buffer);
copy_buffer.bit_depth = frame_to_show->bit_depth;
assert(copy_buffer.y_crop_width == cm->width);
assert(copy_buffer.y_crop_height == cm->height);
// Realloc the current frame buffer at a higher resolution in place.
if (pool != NULL) {
// Use callbacks if on the decoder.
aom_codec_frame_buffer_t *fb =
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer;
aom_release_frame_buffer_cb_fn_t release_fb_cb = pool->release_fb_cb;
aom_get_frame_buffer_cb_fn_t cb = pool->get_fb_cb;
void *cb_priv = pool->cb_priv;
// Realloc with callback does not release the frame buffer - release first.
if (release_fb_cb(cb_priv, fb))
aom_internal_error(
&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to free current frame buffer before superres upscaling");
if (aom_realloc_frame_buffer(
frame_to_show, cm->superres_upscaled_width,
cm->superres_upscaled_height, cm->subsampling_x, cm->subsampling_y,
#ifdef CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif // CONFIG_HIGHBITDEPTH
AOM_BORDER_IN_PIXELS, cm->byte_alignment, fb, cb, cb_priv))
aom_internal_error(
&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate current frame buffer for superres upscaling");
} else {
// Don't use callbacks on the encoder.
if (aom_alloc_frame_buffer(frame_to_show, cm->superres_upscaled_width,
cm->superres_upscaled_height, cm->subsampling_x,
cm->subsampling_y,
#ifdef CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif // CONFIG_HIGHBITDEPTH
AOM_BORDER_IN_PIXELS, cm->byte_alignment))
aom_internal_error(
&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to reallocate current frame buffer for superres upscaling");
}
// TODO(afergs): verify frame_to_show is correct after realloc
// encoder:
// decoder:
frame_to_show->bit_depth = copy_buffer.bit_depth;
assert(frame_to_show->y_crop_width == cm->superres_upscaled_width);
assert(frame_to_show->y_crop_height == cm->superres_upscaled_height);
// Scale up and back into frame_to_show.
assert(frame_to_show->y_crop_width != cm->width);
assert(frame_to_show->y_crop_height != cm->height);
#if CONFIG_HIGHBITDEPTH
av1_resize_and_extend_frame(&copy_buffer, frame_to_show, (int)cm->bit_depth);
#else
av1_resize_and_extend_frame(&copy_buffer, frame_to_show);
#endif // CONFIG_HIGHBITDEPTH
// Free the copy buffer
aom_free_frame_buffer(&copy_buffer);
}
#endif // CONFIG_FRAME_SUPERRES
...@@ -63,6 +63,14 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride, ...@@ -63,6 +63,14 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride,
int owidth, int bd); int owidth, int bd);
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
#if CONFIG_HIGHBITDEPTH
void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst, int bd);
#else
void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst);
#endif // CONFIG_HIGHBITDEPTH
YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm, YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled); YV12_BUFFER_CONFIG *scaled);
...@@ -71,6 +79,21 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm, ...@@ -71,6 +79,21 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled); YV12_BUFFER_CONFIG *scaled);
#if CONFIG_FRAME_SUPERRES
// This is the size after superress scaling, which could be 1:1.
// Superres scaling happens after regular downscaling.
// TODO(afergs): Limit overall reduction to 1/2 of the original size
void av1_calculate_superres_size(const AV1_COMMON *cm, int *width, int *height);
void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool);
// Returns 1 if a superres upscaled frame is unscaled and 0 otherwise.
static INLINE int av1_superres_unscaled(const AV1_COMMON *cm) {
return (cm->superres_scale_numerator == SUPERRES_SCALE_DENOMINATOR);
}
#endif // CONFIG_FRAME_SUPERRES
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
......
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
#include "av1/common/quant_common.h" #include "av1/common/quant_common.h"
#include "av1/common/reconinter.h" #include "av1/common/reconinter.h"
#include "av1/common/reconintra.h" #include "av1/common/reconintra.h"
#if CONFIG_FRAME_SUPERRES
#include "av1/common/resize.h"
#endif // CONFIG_FRAME_SUPERRES
#include "av1/common/seg_common.h" #include "av1/common/seg_common.h"
#include "av1/common/thread_common.h" #include "av1/common/thread_common.h"
#include "av1/common/tile_common.h" #include "av1/common/tile_common.h"
...@@ -2203,6 +2206,7 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd, ...@@ -2203,6 +2206,7 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
partition, partition,
#endif #endif
bsize); bsize);
#if !(CONFIG_MOTION_VAR && CONFIG_NCOBMC) #if !(CONFIG_MOTION_VAR && CONFIG_NCOBMC)
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (!supertx_enabled) if (!supertx_enabled)
...@@ -3020,31 +3024,30 @@ static InterpFilter read_frame_interp_filter(struct aom_read_bit_buffer *rb) { ...@@ -3020,31 +3024,30 @@ static InterpFilter read_frame_interp_filter(struct aom_read_bit_buffer *rb) {
} }
static void setup_render_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { static void setup_render_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
#if CONFIG_FRAME_SUPERRES
cm->render_width = cm->superres_upscaled_width;
cm->render_height = cm->superres_upscaled_height;
#else
cm->render_width = cm->width; cm->render_width = cm->width;
cm->render_height = cm->height; cm->render_height = cm->height;
#endif // CONFIG_FRAME_SUPERRES
if (aom_rb_read_bit(rb)) if (aom_rb_read_bit(rb))
av1_read_frame_size(rb, &cm->render_width, &cm->render_height); av1_read_frame_size(rb, &cm->render_width, &cm->render_height);
} }
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
// TODO(afergs): make "struct aom_read_bit_buffer *const rb"? // TODO(afergs): make "struct aom_read_bit_buffer *const rb"?
static void setup_superres_size(AV1_COMMON *const cm, static void setup_superres(AV1_COMMON *const cm, struct aom_read_bit_buffer *rb,
struct aom_read_bit_buffer *rb, int *width, int *width, int *height) {
int *height) { cm->superres_upscaled_width = *width;
// TODO(afergs): Save input resolution - it's the upscaled resolution cm->superres_upscaled_height = *height;
if (aom_rb_read_bit(rb)) { if (aom_rb_read_bit(rb)) {
cm->superres_scale_numerator = cm->superres_scale_numerator =
(uint8_t)aom_rb_read_literal(rb, SUPERRES_SCALE_BITS); (uint8_t)aom_rb_read_literal(rb, SUPERRES_SCALE_BITS);
cm->superres_scale_numerator += SUPERRES_SCALE_NUMERATOR_MIN; cm->superres_scale_numerator += SUPERRES_SCALE_NUMERATOR_MIN;
// Don't edit cm->width or cm->height directly, or the buffers won't get // Don't edit cm->width or cm->height directly, or the buffers won't get
// resized correctly // resized correctly
// TODO(afergs): Should the render resolution not be modified? It's the same av1_calculate_superres_size(cm, width, height);
// by default (ie. when it isn't sent)...
// resize_context_buffers() will change cm->width to equal cm->render_width,
// then they'll be the same again
*width = *width * cm->superres_scale_numerator / SUPERRES_SCALE_DENOMINATOR;
*height =
*width * cm->superres_scale_numerator / SUPERRES_SCALE_DENOMINATOR;
} else { } else {
// 1:1 scaling - ie. no scaling, scale not provided // 1:1 scaling - ie. no scaling, scale not provided
cm->superres_scale_numerator = SUPERRES_SCALE_DENOMINATOR; cm->superres_scale_numerator = SUPERRES_SCALE_DENOMINATOR;
...@@ -3097,10 +3100,10 @@ static void setup_frame_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { ...@@ -3097,10 +3100,10 @@ static void setup_frame_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
int width, height; int width, height;
BufferPool *const pool = cm->buffer_pool; BufferPool *const pool = cm->buffer_pool;
av1_read_frame_size(rb, &width, &height); av1_read_frame_size(rb, &width, &height);
setup_render_size(cm, rb);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
setup_superres_size(cm, rb, &width, &height); setup_superres(cm, rb, &width, &height);
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
setup_render_size(cm, rb);
resize_context_buffers(cm, width, height); resize_context_buffers(cm, width, height);
lock_buffer_pool(pool); lock_buffer_pool(pool);
...@@ -3149,6 +3152,9 @@ static void setup_frame_size_with_refs(AV1_COMMON *cm, ...@@ -3149,6 +3152,9 @@ static void setup_frame_size_with_refs(AV1_COMMON *cm,
height = buf->y_crop_height; height = buf->y_crop_height;
cm->render_width = buf->render_width; cm->render_width = buf->render_width;
cm->render_height = buf->render_height; cm->render_height = buf->render_height;
#if CONFIG_FRAME_SUPERRES
setup_superres(cm, rb, &width, &height);
#endif // CONFIG_FRAME_SUPERRES
found = 1; found = 1;
break; break;
} }
...@@ -3156,10 +3162,10 @@ static void setup_frame_size_with_refs(AV1_COMMON *cm, ...@@ -3156,10 +3162,10 @@ static void setup_frame_size_with_refs(AV1_COMMON *cm,
if (!found) { if (!found) {
av1_read_frame_size(rb, &width, &height); av1_read_frame_size(rb, &width, &height);
setup_render_size(cm, rb);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
setup_superres_size(cm, rb, &width, &height); setup_superres(cm, rb, &width, &height);
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
setup_render_size(cm, rb);
} }
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
...@@ -5186,6 +5192,19 @@ static void make_update_tile_list_dec(AV1Decoder *pbi, int tile_rows, ...@@ -5186,6 +5192,19 @@ static void make_update_tile_list_dec(AV1Decoder *pbi, int tile_rows,
} }
#endif #endif
#if CONFIG_FRAME_SUPERRES
void superres_post_decode(AV1Decoder *pbi) {
AV1_COMMON *const cm = &pbi->common;
BufferPool *const pool = cm->buffer_pool;
if (av1_superres_unscaled(cm)) return;
lock_buffer_pool(pool);
av1_superres_upscale(cm, pool);
unlock_buffer_pool(pool);
}
#endif // CONFIG_FRAME_SUPERRES
void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data, void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
const uint8_t *data_end, const uint8_t **p_data_end) { const uint8_t *data_end, const uint8_t **p_data_end) {
AV1_COMMON *const cm = &pbi->common; AV1_COMMON *const cm = &pbi->common;
...@@ -5281,14 +5300,23 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data, ...@@ -5281,14 +5300,23 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
#if CONFIG_TEMPMV_SIGNALING #if CONFIG_TEMPMV_SIGNALING
if (cm->use_prev_frame_mvs) { if (cm->use_prev_frame_mvs) {
assert(!cm->error_resilient_mode && cm->prev_frame && assert(!cm->error_resilient_mode && cm->prev_frame &&
cm->width == last_fb_ref_buf->buf->y_width && #if CONFIG_FRAME_SUPERRES
cm->height == last_fb_ref_buf->buf->y_height && cm->width == cm->last_width && cm->height == cm->last_height &&
#else
cm->width == last_fb_ref_buf->buf->y_crop_width &&
cm->height == last_fb_ref_buf->buf->y_crop_height &&
#endif // CONFIG_FRAME_SUPERRES
!cm->prev_frame->intra_only); !cm->prev_frame->intra_only);
} }
#else #else
cm->use_prev_frame_mvs = !cm->error_resilient_mode && cm->prev_frame && cm->use_prev_frame_mvs = !cm->error_resilient_mode && cm->prev_frame &&
#if CONFIG_FRAME_SUPERRES
cm->width == cm->last_width &&
cm->height == cm->last_height &&
#else
cm->width == cm->prev_frame->buf.y_crop_width && cm->width == cm->prev_frame->buf.y_crop_width &&
cm->height == cm->prev_frame->buf.y_crop_height && cm->height == cm->prev_frame->buf.y_crop_height &&
#endif // CONFIG_FRAME_SUPERRES
!cm->last_intra_only && cm->last_show_frame && !cm->last_intra_only && cm->last_show_frame &&
(cm->last_frame_type != KEY_FRAME); (cm->last_frame_type != KEY_FRAME);
#endif // CONFIG_TEMPMV_SIGNALING #endif // CONFIG_TEMPMV_SIGNALING
...@@ -5361,6 +5389,10 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data, ...@@ -5361,6 +5389,10 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
} }
#endif // CONFIG_CDEF #endif // CONFIG_CDEF
#if CONFIG_FRAME_SUPERRES
superres_post_decode(pbi);
#endif // CONFIG_FRAME_SUPERRES
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE || if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[1].frame_restoration_type != RESTORE_NONE || cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
......
...@@ -444,7 +444,10 @@ int av1_receive_compressed_data(AV1Decoder *pbi, size_t size, ...@@ -444,7 +444,10 @@ int av1_receive_compressed_data(AV1Decoder *pbi, size_t size,
// border. // border.
if (pbi->dec_tile_row == -1 && pbi->dec_tile_col == -1) if (pbi->dec_tile_row == -1 && pbi->dec_tile_col == -1)
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
aom_extend_frame_inner_borders(cm->frame_to_show); // TODO(debargha): Fix encoder side mv range, so that we can use the
// inner border extension. As of now use the larger extension.
// aom_extend_frame_inner_borders(cm->frame_to_show);
aom_extend_frame_borders(cm->frame_to_show);
aom_clear_system_state(); aom_clear_system_state();
......
...@@ -352,10 +352,7 @@ void av1_cyclic_refresh_check_golden_update(AV1_COMP *const cpi) { ...@@ -352,10 +352,7 @@ void av1_cyclic_refresh_check_golden_update(AV1_COMP *const cpi) {
// For video conference clips, if the background has high motion in current // For video conference clips, if the background has high motion in current
// frame because of the camera movement, set this frame as the golden frame. // frame because of the camera movement, set this frame as the golden frame.
// Use 70% and 5% as the thresholds for golden frame refreshing. // Use 70% and 5% as the thresholds for golden frame refreshing.
// Also, force this frame as a golden update frame if this frame will change if (cnt1 * 10 > (70 * rows * cols) && cnt2 * 20 < cnt1) {
// the resolution (av1_resize_pending != 0).
if (av1_resize_pending(cpi) ||
(cnt1 * 10 > (70 * rows * cols) && cnt2 * 20 < cnt1)) {
av1_cyclic_refresh_set_golden_update(cpi); av1_cyclic_refresh_set_golden_update(cpi);
rc->frames_till_gf_update_due = rc->baseline_gf_interval; rc->frames_till_gf_update_due = rc->baseline_gf_interval;
......
...@@ -4172,8 +4172,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -4172,8 +4172,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
static void write_render_size(const AV1_COMMON *cm, static void write_render_size(const AV1_COMMON *cm,
struct aom_write_bit_buffer *wb) { struct aom_write_bit_buffer *wb) {
const int scaling_active = const int scaling_active = !av1_resize_unscaled(cm);
cm->width != cm->render_width || cm->height != cm->render_height;
aom_wb_write_bit(wb, scaling_active); aom_wb_write_bit(wb, scaling_active);
if (scaling_active) { if (scaling_active) {
aom_wb_write_literal(wb, cm->render_width - 1, 16); aom_wb_write_literal(wb, cm->render_width - 1, 16);
...@@ -4189,7 +4188,6 @@ static void write_superres_scale(const AV1_COMMON *const cm, ...@@ -4189,7 +4188,6 @@ static void write_superres_scale(const AV1_COMMON *const cm,
aom_wb_write_bit(wb, 0); // no scaling aom_wb_write_bit(wb, 0); // no scaling
} else { } else {
aom_wb_write_bit(wb, 1); // scaling, write scale factor aom_wb_write_bit(wb, 1); // scaling, write scale factor
// TODO(afergs): write factor to the compressed header instead
aom_wb_write_literal( aom_wb_write_literal(
wb, cm->superres_scale_numerator - SUPERRES_SCALE_NUMERATOR_MIN, wb, cm->superres_scale_numerator - SUPERRES_SCALE_NUMERATOR_MIN,
SUPERRES_SCALE_BITS); SUPERRES_SCALE_BITS);
...@@ -4199,13 +4197,15 @@ static void write_superres_scale(const AV1_COMMON *const cm, ...@@ -4199,13 +4197,15 @@ static void write_superres_scale(const AV1_COMMON *const cm,
static void write_frame_size(const AV1_COMMON *cm, static void write_frame_size(const AV1_COMMON *cm,
struct aom_write_bit_buffer *wb) { struct aom_write_bit_buffer *wb) {
aom_wb_write_literal(wb, cm->width - 1, 16);
aom_wb_write_literal(wb, cm->height - 1, 16);
write_render_size(cm, wb);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
aom_wb_write_literal(wb, cm->superres_upscaled_width - 1, 16);
aom_wb_write_literal(wb, cm->superres_upscaled_height - 1, 16);
write_superres_scale(cm, wb); write_superres_scale(cm, wb);
#else
aom_wb_write_literal(wb, cm->width - 1, 16);
aom_wb_write_literal(wb, cm->height - 1, 16);
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
write_render_size(cm, wb);
} }
static void write_frame_size_with_refs(AV1_COMP *cpi, static void write_frame_size_with_refs(AV1_COMP *cpi,
...@@ -4218,20 +4218,26 @@ static void write_frame_size_with_refs(AV1_COMP *cpi, ...@@ -4218,20 +4218,26 @@ static void write_frame_size_with_refs(AV1_COMP *cpi,
YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame); YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame);
if (cfg != NULL) { if (cfg != NULL) {
#if CONFIG_FRAME_SUPERRES
found = cm->superres_upscaled_width == cfg->y_crop_width &&
cm->superres_upscaled_height == cfg->y_crop_height;
#else
found = found =
cm->width == cfg->y_crop_width && cm->height == cfg->y_crop_height; cm->width == cfg->y_crop_width && cm->height == cfg->y_crop_height;
#endif
found &= cm->render_width == cfg->render_width && found &= cm->render_width == cfg->render_width &&
cm->render_height == cfg->render_height; cm->render_height == cfg->render_height;
} }
aom_wb_write_bit(wb, found); aom_wb_write_bit(wb, found);
if (found) { if (found) {
#if CONFIG_FRAME_SUPERRES
write_superres_scale(cm, wb);
#endif // CONFIG_FRAME_SUPERRES
break; break;
} }
} }
if (!found) { if (!found) write_frame_size(cm, wb);
write_frame_size(cm, wb);
}
} }
static void write_sync_code(struct aom_write_bit_buffer *wb) { static void write_sync_code(struct aom_write_bit_buffer *wb) {
...@@ -4370,11 +4376,6 @@ static void write_uncompressed_header(AV1_COMP *cpi, ...@@ -4370,11 +4376,6 @@ static void write_uncompressed_header(AV1_COMP *cpi,
} }
#endif #endif
#if CONFIG_FRAME_SUPERRES
// TODO(afergs): Remove - this is just to stop superres from breaking
cm->superres_scale_numerator = SUPERRES_SCALE_DENOMINATOR;
#endif // CONFIG_FRAME_SUPERRES
if (cm->frame_type == KEY_FRAME) { if (cm->frame_type == KEY_FRAME) {
write_sync_code(wb); write_sync_code(wb);
write_bitdepth_colorspace_sampling(cm, wb); write_bitdepth_colorspace_sampling(cm, wb);
......
...@@ -4860,17 +4860,31 @@ static void encode_frame_internal(AV1_COMP *cpi) { ...@@ -4860,17 +4860,31 @@ static void encode_frame_internal(AV1_COMP *cpi) {
#if CONFIG_TEMPMV_SIGNALING #if CONFIG_TEMPMV_SIGNALING
if (cm->prev_frame) { if (cm->prev_frame) {
cm->use_prev_frame_mvs &= !cm->error_resilient_mode && cm->use_prev_frame_mvs &= !cm->error_resilient_mode &&
cm->width == cm->prev_frame->buf.y_width && #if CONFIG_FRAME_SUPERRES
cm->height == cm->prev_frame->buf.y_height && cm->width == cm->last_width &&
cm->height == cm->last_height &&
#else
cm->width == cm->prev_frame->buf.y_crop_width &&
cm->height == cm->prev_frame->buf.y_crop_height &&
#endif // CONFIG_FRAME_SUPERRES
!cm->intra_only && !cm->prev_frame->intra_only; !cm->intra_only && !cm->prev_frame->intra_only;
} else { } else {
cm->use_prev_frame_mvs = 0; cm->use_prev_frame_mvs = 0;
} }
#else #else
cm->use_prev_frame_mvs = !cm->error_resilient_mode && cm->prev_frame && if (cm->prev_frame) {
cm->width == cm->prev_frame->buf.y_crop_width && cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
cm->height == cm->prev_frame->buf.y_crop_height && #if CONFIG_FRAME_SUPERRES
!cm->intra_only && cm->last_show_frame; cm->width == cm->last_width &&
cm->height == cm->last_height &&
#else
cm->width == cm->prev_frame->buf.y_crop_width &&
cm->height == cm->prev_frame->buf.y_crop_height &&
#endif // CONFIG_FRAME_SUPERRES
!cm->intra_only && cm->last_show_frame;
} else {
cm->use_prev_frame_mvs = 0;
}
#endif // CONFIG_TEMPMV_SIGNALING #endif // CONFIG_TEMPMV_SIGNALING
// Special case: set prev_mi to NULL when the previous mode info // Special case: set prev_mi to NULL when the previous mode info
......
This diff is collapsed.
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "av1/common/entropymode.h" #include "av1/common/entropymode.h"
#include "av1/common/thread_common.h" #include "av1/common/thread_common.h"
#include "av1/common/onyxc_int.h" #include "av1/common/onyxc_int.h"
#include "av1/common/resize.h"
#include "av1/encoder/aq_cyclicrefresh.h" #include "av1/encoder/aq_cyclicrefresh.h"
#if CONFIG_ANS #if CONFIG_ANS
#include "aom_dsp/ans.h" #include "aom_dsp/ans.h"
...@@ -372,7 +373,7 @@ typedef struct AV1_COMP { ...@@ -372,7 +373,7 @@ typedef struct AV1_COMP {
YV12_BUFFER_CONFIG *source; YV12_BUFFER_CONFIG *source;
YV12_BUFFER_CONFIG *last_source; // NULL for first frame and alt_ref frames YV12_BUFFER_CONFIG *last_source; // NULL for first frame and alt_ref frames
YV12_BUFFER_CONFIG *un_scaled_source; YV12_BUFFER_CONFIG *unscaled_source;
YV12_BUFFER_CONFIG scaled_source; YV12_BUFFER_CONFIG scaled_source;
YV12_BUFFER_CONFIG *unscaled_last_source; YV12_BUFFER_CONFIG *unscaled_last_source;
YV12_BUFFER_CONFIG scaled_last_source; YV12_BUFFER_CONFIG scaled_last_source;
...@@ -601,18 +602,10 @@ typedef struct AV1_COMP { ...@@ -601,18 +602,10 @@ typedef struct AV1_COMP {
TileBufferEnc tile_buffers[MAX_TILE_ROWS][MAX_TILE_COLS]; TileBufferEnc tile_buffers[MAX_TILE_ROWS][MAX_TILE_COLS];
int resize_state; int resize_state;
int resize_scale_num;
int resize_scale_den;
int resize_next_scale_num;
int resize_next_scale_den;
int resize_avg_qp; int resize_avg_qp;
int resize_buffer_underflow; int resize_buffer_underflow;
int resize_count; int resize_count;
#if CONFIG_FRAME_SUPERRES
int superres_pending;
#endif // CONFIG_FRAME_SUPERRES
// VARIANCE_AQ segment map refresh // VARIANCE_AQ segment map refresh
int vaq_refresh; int vaq_refresh;
...@@ -831,23 +824,22 @@ static INLINE void uref_cnt_fb(EncRefCntBuffer *ubufs, int *uidx, ...@@ -831,23 +824,22 @@ static I