From: Marco Paniconi Date: Tue, 3 Apr 2018 22:50:19 +0000 (-0700) Subject: vp9-svc: Fix in choose_partitioning for different scaling. X-Git-Tag: v1.8.0~755^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9b6c5d5ad8b03e32c0e44959cbb74468dd81cbf;p=libvpx 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 --- diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index bf87a2663..164643558 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1255,13 +1255,17 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, 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);