diff options
author | Paul Wilkins <paulwilkins@google.com> | 2014-10-16 10:44:47 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2014-10-16 10:44:47 -0700 |
commit | c601cc538980d154a72cd11b18c8fe806ebc9d25 (patch) | |
tree | 9060146e474ec29481037fe0600837bc6dcf55f4 | |
parent | d39b12a4db9b38cefe7c249acef87f17113eff78 (diff) | |
parent | 468032961d2ce9f0c85a2498a51024aaf92965ca (diff) | |
download | libvpx-c601cc538980d154a72cd11b18c8fe806ebc9d25.tar libvpx-c601cc538980d154a72cd11b18c8fe806ebc9d25.tar.gz libvpx-c601cc538980d154a72cd11b18c8fe806ebc9d25.tar.bz2 libvpx-c601cc538980d154a72cd11b18c8fe806ebc9d25.zip |
Merge "Revert "[spatial svc]Another workaround to avoid using prev_mi""
-rw-r--r-- | test/svc_test.cc | 127 | ||||
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 9 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 58 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.c | 63 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.h | 10 | ||||
-rw-r--r-- | vp9/encoder/vp9_temporal_filter.c | 3 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 6 | ||||
-rw-r--r-- | vpx/src/svc_encodeframe.c | 2 |
9 files changed, 137 insertions, 144 deletions
diff --git a/test/svc_test.cc b/test/svc_test.cc index 67e83e395..fdde702d2 100644 --- a/test/svc_test.cc +++ b/test/svc_test.cc @@ -225,9 +225,10 @@ class SvcTest : public ::testing::Test { EXPECT_EQ(received_frames, n); } - void DropEnhancementLayers(struct vpx_fixed_buf *const inputs, - const int num_super_frames, - const int remained_spatial_layers) { + void DropLayersAndMakeItVP9Comaptible(struct vpx_fixed_buf *const inputs, + const int num_super_frames, + const int remained_spatial_layers, + const bool is_multiple_frame_contexts) { ASSERT_TRUE(inputs != NULL); ASSERT_GT(num_super_frames, 0); ASSERT_GT(remained_spatial_layers, 0); @@ -249,6 +250,45 @@ class SvcTest : public ::testing::Test { if (frame_count == 0) { // There's no super frame but only a single frame. ASSERT_EQ(1, remained_spatial_layers); + if (is_multiple_frame_contexts) { + // Make a new super frame. + uint8_t marker = 0xc1; + unsigned int mask; + int mag; + + // Choose the magnitude. + for (mag = 0, mask = 0xff; mag < 4; ++mag) { + if (inputs[i].sz < mask) + break; + mask <<= 8; + mask |= 0xff; + } + marker |= mag << 3; + int index_sz = 2 + (mag + 1) * 2; + + inputs[i].buf = realloc(inputs[i].buf, inputs[i].sz + index_sz + 16); + ASSERT_TRUE(inputs[i].buf != NULL); + uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf); + frame_data[0] &= ~2; // Set the show_frame flag to 0. + frame_data += inputs[i].sz; + // Add an one byte frame with show_existing_frame. + *frame_data++ = 0x88; + + // Write the super frame index. + *frame_data++ = marker; + + frame_sizes[0] = inputs[i].sz; + frame_sizes[1] = 1; + for (int j = 0; j < 2; ++j) { + unsigned int this_sz = frame_sizes[j]; + for (int k = 0; k <= mag; k++) { + *frame_data++ = this_sz & 0xff; + this_sz >>= 8; + } + } + *frame_data++ = marker; + inputs[i].sz += index_sz + 1; + } } else { // Found a super frame. uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf); @@ -264,13 +304,16 @@ class SvcTest : public ::testing::Test { } ASSERT_LT(frame, frame_count) << "Couldn't find a visible frame. " << "remained_spatial_layers: " << remained_spatial_layers - << " super_frame: " << i; - if (frame == frame_count - 1) + << " super_frame: " << i + << " is_multiple_frame_context: " << is_multiple_frame_contexts; + if (frame == frame_count - 1 && !is_multiple_frame_contexts) continue; frame_data += frame_sizes[frame]; // We need to add one more frame for multiple frame contexts. + if (is_multiple_frame_contexts) + ++frame; uint8_t marker = static_cast<const uint8_t*>(inputs[i].buf)[inputs[i].sz - 1]; const uint32_t mag = ((marker >> 3) & 0x3) + 1; @@ -280,14 +323,35 @@ class SvcTest : public ::testing::Test { marker |= frame; // Copy existing frame sizes. - memmove(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1, - new_index_sz - 2); + memmove(frame_data + (is_multiple_frame_contexts ? 2 : 1), + frame_start + inputs[i].sz - index_sz + 1, new_index_sz - 2); + if (is_multiple_frame_contexts) { + // Add a one byte frame with flag show_existing_frame. + *frame_data++ = 0x88 | (remained_spatial_layers - 1); + } // New marker. frame_data[0] = marker; frame_data += (mag * (frame + 1) + 1); + if (is_multiple_frame_contexts) { + // Write the frame size for the one byte frame. + frame_data -= mag; + *frame_data++ = 1; + for (uint32_t j = 1; j < mag; ++j) { + *frame_data++ = 0; + } + } + *frame_data++ = marker; inputs[i].sz = frame_data - frame_start; + + if (is_multiple_frame_contexts) { + // Change the show frame flag to 0 for all frames. + for (int j = 0; j < frame; ++j) { + frame_start[0] &= ~2; + frame_start += frame_sizes[j]; + } + } } } } @@ -491,7 +555,7 @@ TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) { vpx_fixed_buf outputs[10]; memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); - DropEnhancementLayers(&outputs[0], 10, 1); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, false); DecodeNFrames(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10); } @@ -509,13 +573,13 @@ TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) { Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]); DecodeNFrames(&outputs[0], 10); - DropEnhancementLayers(&outputs[0], 10, 4); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 4, false); DecodeNFrames(&outputs[0], 10); - DropEnhancementLayers(&outputs[0], 10, 3); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 3, false); DecodeNFrames(&outputs[0], 10); - DropEnhancementLayers(&outputs[0], 10, 2); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, false); DecodeNFrames(&outputs[0], 10); - DropEnhancementLayers(&outputs[0], 10, 1); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, false); DecodeNFrames(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10); @@ -552,9 +616,9 @@ TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) { memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]); DecodeNFrames(&outputs[0], 20); - DropEnhancementLayers(&outputs[0], 20, 2); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 20, 2, false); DecodeNFrames(&outputs[0], 20); - DropEnhancementLayers(&outputs[0], 20, 1); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 20, 1, false); DecodeNFrames(&outputs[0], 20); FreeBitstreamBuffers(&outputs[0], 20); @@ -585,6 +649,7 @@ TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) { vpx_fixed_buf outputs[10]; memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, true); DecodeNFrames(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10); } @@ -602,7 +667,7 @@ TEST_F(SvcTest, vpx_fixed_buf outputs[10]; memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); - DropEnhancementLayers(&outputs[0], 10, 1); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true); DecodeNFrames(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10); } @@ -621,6 +686,7 @@ TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) { vpx_fixed_buf outputs[10]; memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, true); DecodeNFrames(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10); } @@ -641,13 +707,32 @@ TEST_F(SvcTest, memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]); - DecodeNFrames(&outputs[0], 10); - DropEnhancementLayers(&outputs[0], 10, 2); - DecodeNFrames(&outputs[0], 10); - DropEnhancementLayers(&outputs[0], 10, 1); - DecodeNFrames(&outputs[0], 10); + vpx_fixed_buf outputs_new[10]; + for (int i = 0; i < 10; ++i) { + outputs_new[i].buf = malloc(outputs[i].sz + 16); + ASSERT_TRUE(outputs_new[i].buf != NULL); + memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz); + outputs_new[i].sz = outputs[i].sz; + } + DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 3, true); + DecodeNFrames(&outputs_new[0], 10); + + for (int i = 0; i < 10; ++i) { + memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz); + outputs_new[i].sz = outputs[i].sz; + } + DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 2, true); + DecodeNFrames(&outputs_new[0], 10); + + for (int i = 0; i < 10; ++i) { + memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz); + outputs_new[i].sz = outputs[i].sz; + } + DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 1, true); + DecodeNFrames(&outputs_new[0], 10); FreeBitstreamBuffers(&outputs[0], 10); + FreeBitstreamBuffers(&outputs_new[0], 10); } TEST_F(SvcTest, TwoPassEncode2TemporalLayers) { @@ -684,6 +769,7 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) { vpx_fixed_buf outputs[10]; memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true); DecodeNFrames(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10); } @@ -728,6 +814,7 @@ TEST_F(SvcTest, vpx_fixed_buf outputs[10]; memset(&outputs[0], 0, sizeof(outputs)); Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); + DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true); vpx_fixed_buf base_layer[5]; for (int i = 0; i < 5; ++i) diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 3954fe6a7..694cac76f 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1013,11 +1013,7 @@ static void write_frame_size_with_refs(VP9_COMP *cpi, ((cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) || (cpi->svc.number_spatial_layers > 1 && - cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame) || - (is_two_pass_svc(cpi) && - cpi->svc.encode_empty_frame_state == ENCODING && - cpi->svc.layer_context[0].frames_from_key_frame < - cpi->svc.number_temporal_layers + 1))) { + cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame))) { found = 0; } vp9_wb_write_bit(wb, found); @@ -1109,7 +1105,8 @@ static void write_uncompressed_header(VP9_COMP *cpi, // will change to show_frame flag to 0, then add an one byte frame with // show_existing_frame flag which tells the decoder which frame we want to // show. - if (!cm->show_frame) + if (!cm->show_frame || + (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0)) vp9_wb_write_bit(wb, cm->intra_only); if (!cm->error_resilient_mode) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 0928c0bb7..dea93062b 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -225,9 +225,6 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { } vpx_memset(&cpi->svc.scaled_frames[0], 0, MAX_LAG_BUFFERS * sizeof(cpi->svc.scaled_frames[0])); - - vp9_free_frame_buffer(&cpi->svc.empty_frame.img); - vpx_memset(&cpi->svc.empty_frame, 0, sizeof(cpi->svc.empty_frame)); } static void save_coding_context(VP9_COMP *cpi) { @@ -2638,10 +2635,7 @@ void set_frame_size(VP9_COMP *cpi) { // For two pass encodes analyse the first pass stats and determine // the bit allocation and other parameters for this frame / group of frames. - if ((oxcf->pass == 2) && - (!cpi->use_svc || - (is_two_pass_svc(cpi) && - cpi->svc.encode_empty_frame_state != ENCODING))) { + if ((oxcf->pass == 2) && (!cpi->use_svc || is_two_pass_svc(cpi))) { vp9_rc_get_second_pass_params(cpi); } @@ -3140,9 +3134,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } } if (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0) { - // Use the last frame context for the empty frame. cm->frame_context_idx = - (cpi->svc.encode_empty_frame_state == ENCODING) ? FRAME_CONTEXTS - 1 : cpi->svc.spatial_layer_id * cpi->svc.number_temporal_layers + cpi->svc.temporal_layer_id; @@ -3277,9 +3269,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cpi->ref_frame_flags = get_ref_frame_flags(cpi); cm->last_frame_type = cm->frame_type; - - if (!(is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING)) - vp9_rc_postencode_update(cpi, *size); + vp9_rc_postencode_update(cpi, *size); #if 0 output_frame_level_debug_stats(cpi); @@ -3303,8 +3293,12 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->last_height = cm->height; // reset to normal state now that we are done. - if (!cm->show_existing_frame) - cm->last_show_frame = cm->show_frame; + if (!cm->show_existing_frame) { + if (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0) + cm->last_show_frame = 0; + else + cm->last_show_frame = cm->show_frame; + } if (cm->show_frame) { vp9_swap_mi_and_prev_mi(cm); @@ -3341,9 +3335,7 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags) { cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; encode_frame_to_data_rate(cpi, size, dest, frame_flags); - - if (!(is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING)) - vp9_twopass_postencode_update(cpi); + vp9_twopass_postencode_update(cpi); } static void check_initial_width(VP9_COMP *cpi, @@ -3521,9 +3513,6 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, if (is_two_pass_svc(cpi)) { #if CONFIG_SPATIAL_SVC vp9_svc_start_frame(cpi); - // Use a small empty frame instead of a real frame - if (cpi->svc.encode_empty_frame_state == ENCODING) - source = &cpi->svc.empty_frame; #endif if (oxcf->pass == 2) vp9_restore_layer_context(cpi); @@ -3542,11 +3531,6 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, // Should we encode an arf frame. arf_src_index = get_arf_src_index(cpi); - - // Skip alt frame if we encode the empty frame - if (is_two_pass_svc(cpi) && source != NULL) - arf_src_index = 0; - if (arf_src_index) { assert(arf_src_index <= rc->frames_to_key); @@ -3834,18 +3818,10 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, #endif - if (is_two_pass_svc(cpi)) { - if (cpi->svc.encode_empty_frame_state == ENCODING) - cpi->svc.encode_empty_frame_state = ENCODED; - - if (cm->show_frame) { - ++cpi->svc.spatial_layer_to_encode; - if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers) - cpi->svc.spatial_layer_to_encode = 0; - - // May need the empty frame after an visible frame. - cpi->svc.encode_empty_frame_state = NEED_TO_ENCODE; - } + if (is_two_pass_svc(cpi) && cm->show_frame) { + ++cpi->svc.spatial_layer_to_encode; + if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers) + cpi->svc.spatial_layer_to_encode = 0; } return 0; } @@ -3936,6 +3912,10 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width, if (width) { cm->width = width; + if (cm->width * 5 < cpi->initial_width) { + cm->width = cpi->initial_width / 5 + 1; + printf("Warning: Desired width too small, changed to %d\n", cm->width); + } if (cm->width > cpi->initial_width) { cm->width = cpi->initial_width; printf("Warning: Desired width too large, changed to %d\n", cm->width); @@ -3944,6 +3924,10 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width, if (height) { cm->height = height; + if (cm->height * 5 < cpi->initial_height) { + cm->height = cpi->initial_height / 5 + 1; + printf("Warning: Desired height too small, changed to %d\n", cm->height); + } if (cm->height > cpi->initial_height) { cm->height = cpi->initial_height; printf("Warning: Desired height too large, changed to %d\n", cm->height); diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 760ec320c..9e204d7e9 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -2406,9 +2406,6 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG); lc->frames_from_key_frame = 0; - // Reset the empty frame resolution since we have a key frame. - cpi->svc.empty_frame_width = cm->width; - cpi->svc.empty_frame_height = cm->height; } } else { cm->frame_type = INTER_FRAME; diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 1573557d4..eed681c96 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -14,8 +14,6 @@ #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; @@ -30,25 +28,6 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { 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) { @@ -331,47 +310,6 @@ int vp9_svc_start_frame(VP9_COMP *const cpi) { 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; @@ -379,6 +317,7 @@ int vp9_svc_start_frame(VP9_COMP *const cpi) { 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; diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index e9645ce9f..47a5456b6 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -50,16 +50,6 @@ typedef struct { int spatial_layer_to_encode; - // Workaround for multiple frame contexts - enum { - ENCODED = 0, - ENCODING, - NEED_TO_ENCODE - }encode_empty_frame_state; - struct lookahead_entry empty_frame; - int empty_frame_width; - int empty_frame_height; - // Store scaled source frames to be used for temporal filter to generate // a alt ref frame. YV12_BUFFER_CONFIG scaled_frames[MAX_LAG_BUFFERS]; diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index 5599227ce..9ae81e761 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -719,9 +719,6 @@ void vp9_temporal_filter(VP9_COMP *cpi, int distance) { ++frame_used; } } - cm->mi = cm->mip + cm->mi_stride + 1; - cpi->mb.e_mbd.mi = cm->mi; - cpi->mb.e_mbd.mi[0].src_mi = &cpi->mb.e_mbd.mi[0]; } else { // ARF is produced at the native frame size and resized when coded. #if CONFIG_VP9_HIGHBITDEPTH diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index d0ca5242c..041ba27da 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -188,9 +188,11 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, } if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers) ERROR("Not enough ref buffers for svc alt ref frames"); - if (cfg->ss_number_layers * cfg->ts_number_layers > 3 && + if ((cfg->ss_number_layers > 3 || + cfg->ss_number_layers * cfg->ts_number_layers > 4) && cfg->g_error_resilient == 0) - ERROR("Multiple frame context are not supported for more than 3 layers"); + ERROR("Multiple frame context are not supported for more than 3 spatial " + "layers or more than 4 spatial x temporal layers"); } #endif diff --git a/vpx/src/svc_encodeframe.c b/vpx/src/svc_encodeframe.c index fa3409c69..773087ddc 100644 --- a/vpx/src/svc_encodeframe.c +++ b/vpx/src/svc_encodeframe.c @@ -350,7 +350,7 @@ void assign_layer_bitrates(const SvcContext *svc_ctx, } } - for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) { + for (i = 0; i < svc_ctx->spatial_layers; ++i) { if (total > 0) { enc_cfg->ss_target_bitrate[i] = (unsigned int) (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total); |