| Index: source/libvpx/vp9/encoder/vp9_svc_layercontext.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_svc_layercontext.c (revision 292608)
|
| +++ source/libvpx/vp9/encoder/vp9_svc_layercontext.c (working copy)
|
| @@ -14,6 +14,8 @@
|
| #include "vp9/encoder/vp9_svc_layercontext.h"
|
| #include "vp9/encoder/vp9_extend.h"
|
|
|
| +#define SMALL_FRAME_FB_IDX 7
|
| +
|
| void vp9_init_layer_context(VP9_COMP *const cpi) {
|
| SVC *const svc = &cpi->svc;
|
| const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| @@ -28,6 +30,25 @@
|
| layer_end = svc->number_temporal_layers;
|
| } else {
|
| layer_end = svc->number_spatial_layers;
|
| +
|
| + if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
|
| + if (vp9_realloc_frame_buffer(&cpi->svc.empty_frame.img,
|
| + cpi->common.width, cpi->common.height,
|
| + cpi->common.subsampling_x,
|
| + cpi->common.subsampling_y,
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + cpi->common.use_highbitdepth,
|
| +#endif
|
| + VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
|
| + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
|
| + "Failed to allocate empty frame for multiple frame "
|
| + "contexts");
|
| +
|
| + vpx_memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80,
|
| + cpi->svc.empty_frame.img.buffer_alloc_sz);
|
| + cpi->svc.empty_frame_width = cpi->common.width;
|
| + cpi->svc.empty_frame_height = cpi->common.height;
|
| + }
|
| }
|
|
|
| for (layer = 0; layer < layer_end; ++layer) {
|
| @@ -310,6 +331,47 @@
|
| get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
|
| lc->scaling_factor_num, lc->scaling_factor_den,
|
| &width, &height);
|
| +
|
| + // Workaround for multiple frame contexts. In some frames we can't use prev_mi
|
| + // since its previous frame could be changed during decoding time. The idea is
|
| + // we put a empty invisible frame in front of them, then we will not use
|
| + // prev_mi when encoding these frames.
|
| + if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2 &&
|
| + cpi->svc.encode_empty_frame_state == NEED_TO_ENCODE) {
|
| + if ((cpi->svc.number_temporal_layers > 1 &&
|
| + cpi->svc.temporal_layer_id < cpi->svc.number_temporal_layers - 1) ||
|
| + (cpi->svc.number_spatial_layers > 1 &&
|
| + cpi->svc.spatial_layer_id == 0)) {
|
| + struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead, 0);
|
| +
|
| + if (buf != NULL) {
|
| + cpi->svc.empty_frame.ts_start = buf->ts_start;
|
| + cpi->svc.empty_frame.ts_end = buf->ts_end;
|
| + cpi->svc.encode_empty_frame_state = ENCODING;
|
| + cpi->common.show_frame = 0;
|
| + cpi->ref_frame_flags = 0;
|
| + cpi->common.frame_type = INTER_FRAME;
|
| + cpi->lst_fb_idx =
|
| + cpi->gld_fb_idx = cpi->alt_fb_idx = SMALL_FRAME_FB_IDX;
|
| +
|
| + // Gradually make the empty frame smaller to save bits. Make it half of
|
| + // its previous size because of the scaling factor restriction.
|
| + cpi->svc.empty_frame_width >>= 1;
|
| + cpi->svc.empty_frame_width = (cpi->svc.empty_frame_width + 1) & ~1;
|
| + if (cpi->svc.empty_frame_width < 16)
|
| + cpi->svc.empty_frame_width = 16;
|
| +
|
| + cpi->svc.empty_frame_height >>= 1;
|
| + cpi->svc.empty_frame_height = (cpi->svc.empty_frame_height + 1) & ~1;
|
| + if (cpi->svc.empty_frame_height < 16)
|
| + cpi->svc.empty_frame_height = 16;
|
| +
|
| + width = cpi->svc.empty_frame_width;
|
| + height = cpi->svc.empty_frame_height;
|
| + }
|
| + }
|
| + }
|
| +
|
| if (vp9_set_size_literal(cpi, width, height) != 0)
|
| return VPX_CODEC_INVALID_PARAM;
|
|
|
| @@ -317,7 +379,6 @@
|
| cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
|
|
|
| vp9_change_config(cpi, &cpi->oxcf);
|
| -
|
| vp9_set_high_precision_mv(cpi, 1);
|
|
|
| cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source;
|
|
|