ref: c9b6c5d5ad8b03e32c0e44959cbb74468dd81cbf
parent: ee37046f1b07a4df47a6943b4750b1ad6115db0e
author: Marco Paniconi <marpan@google.com>
date: Tue Apr 3 11:50:19 EDT 2018
vp9-svc: Fix in choose_partitioning for different scaling. In the SVC encoder LAST ref frame should be the last temporal reference at the same resolution. This is the case for the default/fixed patterns, but may not be the case for arbitrary pattern in flexible mode. Add check that the LAST reference frame has same resolution as the current frame. If the reference scale for LAST is different from current treat the current frame as key frame just for the purpose of superblock partitioning. This avoids potential segfault in vp9_int_pro_motion_estimation() for different scaled reference. Change-Id: I4276ff616de46cd4e12c73316f85ae313f170242
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1255,13 +1255,17 @@
int segment_id;
int sb_offset = (cm->mi_stride >> 3) * (mi_row >> 3) + (mi_col >> 3);
- // For SVC: check if LAST frame is NULL and if so treat this frame as a key
- // frame, for the purpose of the superblock partitioning. This can happen
- // (LAST is NULL) in some cases where enhancement spatial layers are enabled
- // dyanmically in the stream and the only reference is the spatial
+ // For SVC: check if LAST frame is NULL or if the resolution of LAST is
+ // different than the current frame resolution, and if so, treat this frame
+ // as a key frame, for the purpose of the superblock partitioning.
+ // LAST == NULL can happen in some cases where enhancement spatial layers are
+ // enabled dyanmically in the stream and the only reference is the spatial
// reference (GOLDEN).
if (cpi->use_svc) {
- if (get_ref_frame_buffer(cpi, LAST_FRAME) == NULL) is_key_frame = 1;
+ const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, LAST_FRAME);
+ if (ref == NULL || ref->y_crop_height != cm->height ||
+ ref->y_crop_width != cm->width)
+ is_key_frame = 1;
}
set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);