Commit 0a103ae9 authored by Minghai Shang's avatar Minghai Shang Committed by Gerrit Code Review

Merge "[spatial svc]Implement lag in frames for spatial svc"

parents 35bd31cd 277338f7
...@@ -296,6 +296,7 @@ int main(int argc, const char **argv) { ...@@ -296,6 +296,7 @@ int main(int argc, const char **argv) {
int frame_duration = 1; /* 1 timebase tick per frame */ int frame_duration = 1; /* 1 timebase tick per frame */
FILE *infile = NULL; FILE *infile = NULL;
int end_of_stream = 0; int end_of_stream = 0;
int frame_size;
memset(&svc_ctx, 0, sizeof(svc_ctx)); memset(&svc_ctx, 0, sizeof(svc_ctx));
svc_ctx.log_print = 1; svc_ctx.log_print = 1;
...@@ -351,11 +352,10 @@ int main(int argc, const char **argv) { ...@@ -351,11 +352,10 @@ int main(int argc, const char **argv) {
die_codec(&codec, "Failed to encode frame"); die_codec(&codec, "Failed to encode frame");
} }
if (!(app_input.passes == 2 && app_input.pass == 1)) { if (!(app_input.passes == 2 && app_input.pass == 1)) {
if (vpx_svc_get_frame_size(&svc_ctx) > 0) { while ((frame_size = vpx_svc_get_frame_size(&svc_ctx)) > 0) {
vpx_video_writer_write_frame(writer, vpx_video_writer_write_frame(writer,
vpx_svc_get_buffer(&svc_ctx), vpx_svc_get_buffer(&svc_ctx),
vpx_svc_get_frame_size(&svc_ctx), frame_size, pts);
pts);
} }
} }
if (vpx_svc_get_rc_stats_buffer_size(&svc_ctx) > 0) { if (vpx_svc_get_rc_stats_buffer_size(&svc_ctx) > 0) {
......
...@@ -265,9 +265,17 @@ TEST_F(SvcTest, FirstFrameHasLayers) { ...@@ -265,9 +265,17 @@ TEST_F(SvcTest, FirstFrameHasLayers) {
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res); EXPECT_EQ(VPX_CODEC_OK, res);
if (vpx_svc_get_frame_size(&svc_) == 0) {
// Flush encoder
res = vpx_svc_encode(&svc_, &codec_, NULL, 0,
video.duration(), VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res);
}
int frame_size = vpx_svc_get_frame_size(&svc_);
EXPECT_GT(frame_size, 0);
const vpx_codec_err_t res_dec = decoder_->DecodeFrame( const vpx_codec_err_t res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
vpx_svc_get_frame_size(&svc_));
// this test fails with a decoder error // this test fails with a decoder error
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
...@@ -277,6 +285,9 @@ TEST_F(SvcTest, EncodeThreeFrames) { ...@@ -277,6 +285,9 @@ TEST_F(SvcTest, EncodeThreeFrames) {
svc_.spatial_layers = 2; svc_.spatial_layers = 2;
vpx_svc_set_scale_factors(&svc_, "4/16,16/16"); vpx_svc_set_scale_factors(&svc_, "4/16,16/16");
vpx_svc_set_quantizers(&svc_, "40,30", 0); vpx_svc_set_quantizers(&svc_, "40,30", 0);
int decoded_frames = 0;
vpx_codec_err_t res_dec;
int frame_size;
vpx_codec_err_t res = vpx_codec_err_t res =
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
...@@ -291,13 +302,14 @@ TEST_F(SvcTest, EncodeThreeFrames) { ...@@ -291,13 +302,14 @@ TEST_F(SvcTest, EncodeThreeFrames) {
// This frame is a keyframe. // This frame is a keyframe.
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(1, vpx_svc_is_keyframe(&svc_));
vpx_codec_err_t res_dec = decoder_->DecodeFrame( if ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
vpx_svc_get_frame_size(&svc_)); res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
// FRAME 1 // FRAME 1
video.Next(); video.Next();
...@@ -305,12 +317,14 @@ TEST_F(SvcTest, EncodeThreeFrames) { ...@@ -305,12 +317,14 @@ TEST_F(SvcTest, EncodeThreeFrames) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res); ASSERT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(0, vpx_svc_is_keyframe(&svc_));
if ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
res_dec = decoder_->DecodeFrame( res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
vpx_svc_get_frame_size(&svc_));
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
// FRAME 2 // FRAME 2
video.Next(); video.Next();
...@@ -318,12 +332,29 @@ TEST_F(SvcTest, EncodeThreeFrames) { ...@@ -318,12 +332,29 @@ TEST_F(SvcTest, EncodeThreeFrames) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res); ASSERT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(0, vpx_svc_is_keyframe(&svc_));
if ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
// Flush encoder
res = vpx_svc_encode(&svc_, &codec_, NULL, 0,
video.duration(), VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res);
while ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
res_dec = decoder_->DecodeFrame( res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
vpx_svc_get_frame_size(&svc_));
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
EXPECT_EQ(decoded_frames, 3);
} }
TEST_F(SvcTest, GetLayerResolution) { TEST_F(SvcTest, GetLayerResolution) {
...@@ -413,6 +444,9 @@ TEST_F(SvcTest, TwoPassEncode) { ...@@ -413,6 +444,9 @@ TEST_F(SvcTest, TwoPassEncode) {
vpx_codec_destroy(&codec_); vpx_codec_destroy(&codec_);
// Second pass encode // Second pass encode
int decoded_frames = 0;
vpx_codec_err_t res_dec;
int frame_size;
codec_enc_.g_pass = VPX_RC_LAST_PASS; codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.rc_twopass_stats_in.buf = &stats_buf[0]; codec_enc_.rc_twopass_stats_in.buf = &stats_buf[0];
codec_enc_.rc_twopass_stats_in.sz = stats_buf.size(); codec_enc_.rc_twopass_stats_in.sz = stats_buf.size();
...@@ -427,12 +461,14 @@ TEST_F(SvcTest, TwoPassEncode) { ...@@ -427,12 +461,14 @@ TEST_F(SvcTest, TwoPassEncode) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res); ASSERT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(1, vpx_svc_is_keyframe(&svc_));
vpx_codec_err_t res_dec = decoder_->DecodeFrame( if ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
vpx_svc_get_frame_size(&svc_)); res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
// FRAME 1 // FRAME 1
video.Next(); video.Next();
...@@ -440,12 +476,14 @@ TEST_F(SvcTest, TwoPassEncode) { ...@@ -440,12 +476,14 @@ TEST_F(SvcTest, TwoPassEncode) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res); ASSERT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(0, vpx_svc_is_keyframe(&svc_));
if ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
res_dec = decoder_->DecodeFrame( res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
vpx_svc_get_frame_size(&svc_));
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
// FRAME 2 // FRAME 2
video.Next(); video.Next();
...@@ -453,12 +491,29 @@ TEST_F(SvcTest, TwoPassEncode) { ...@@ -453,12 +491,29 @@ TEST_F(SvcTest, TwoPassEncode) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY); video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res); ASSERT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(0, vpx_svc_is_keyframe(&svc_));
if ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
// Flush encoder
res = vpx_svc_encode(&svc_, &codec_, NULL, 0,
video.duration(), VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res);
while ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
EXPECT_EQ((decoded_frames == 0), vpx_svc_is_keyframe(&svc_));
res_dec = decoder_->DecodeFrame( res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)), frame_size);
vpx_svc_get_frame_size(&svc_));
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
}
EXPECT_EQ(decoded_frames, 3);
} }
} // namespace } // namespace
...@@ -106,7 +106,7 @@ static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) { ...@@ -106,7 +106,7 @@ static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) {
} }
} }
static void set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) { void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) {
MACROBLOCK *const mb = &cpi->mb; MACROBLOCK *const mb = &cpi->mb;
cpi->common.allow_high_precision_mv = allow_high_precision_mv; cpi->common.allow_high_precision_mv = allow_high_precision_mv;
if (cpi->common.allow_high_precision_mv) { if (cpi->common.allow_high_precision_mv) {
...@@ -572,7 +572,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { ...@@ -572,7 +572,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
cm->reset_frame_context = 0; cm->reset_frame_context = 0;
vp9_reset_segment_features(&cm->seg); vp9_reset_segment_features(&cm->seg);
set_high_precision_mv(cpi, 0); vp9_set_high_precision_mv(cpi, 0);
{ {
int i; int i;
...@@ -2117,7 +2117,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, ...@@ -2117,7 +2117,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if (!frame_is_intra_only(cm)) { if (!frame_is_intra_only(cm)) {
cm->interp_filter = DEFAULT_INTERP_FILTER; cm->interp_filter = DEFAULT_INTERP_FILTER;
/* TODO: Decide this more intelligently */ /* TODO: Decide this more intelligently */
set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH); vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
} }
if (cpi->sf.recode_loop == DISALLOW_RECODE) { if (cpi->sf.recode_loop == DISALLOW_RECODE) {
...@@ -2298,12 +2298,22 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags, ...@@ -2298,12 +2298,22 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags,
int res = 0; int res = 0;
const int subsampling_x = sd->uv_width < sd->y_width; const int subsampling_x = sd->uv_width < sd->y_width;
const int subsampling_y = sd->uv_height < sd->y_height; const int subsampling_y = sd->uv_height < sd->y_height;
const int is_spatial_svc = cpi->use_svc &&
(cpi->svc.number_temporal_layers == 1);
check_initial_width(cpi, subsampling_x, subsampling_y); check_initial_width(cpi, subsampling_x, subsampling_y);
vpx_usec_timer_start(&timer); vpx_usec_timer_start(&timer);
if (vp9_lookahead_push(cpi->lookahead,
sd, time_stamp, end_time, frame_flags)) #ifdef CONFIG_SPATIAL_SVC
if (is_spatial_svc)
res = vp9_svc_lookahead_push(cpi, cpi->lookahead, sd, time_stamp, end_time,
frame_flags);
else
#endif
res = vp9_lookahead_push(cpi->lookahead,
sd, time_stamp, end_time, frame_flags);
if (res)
res = -1; res = -1;
vpx_usec_timer_mark(&timer); vpx_usec_timer_mark(&timer);
cpi->time_receive_data += vpx_usec_timer_elapsed(&timer); cpi->time_receive_data += vpx_usec_timer_elapsed(&timer);
...@@ -2419,11 +2429,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2419,11 +2429,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
YV12_BUFFER_CONFIG *force_src_buffer = NULL; YV12_BUFFER_CONFIG *force_src_buffer = NULL;
MV_REFERENCE_FRAME ref_frame; MV_REFERENCE_FRAME ref_frame;
int arf_src_index; int arf_src_index;
const int is_spatial_svc = cpi->use_svc &&
(cpi->svc.number_temporal_layers == 1);
if (!cpi) if (!cpi)
return -1; return -1;
if (cpi->svc.number_spatial_layers > 1 && cpi->pass == 2) { if (is_spatial_svc && cpi->pass == 2) {
vp9_svc_lookahead_peek(cpi, cpi->lookahead, 0, 1);
vp9_restore_layer_context(cpi); vp9_restore_layer_context(cpi);
} }
...@@ -2432,7 +2445,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2432,7 +2445,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
cpi->source = NULL; cpi->source = NULL;
cpi->last_source = NULL; cpi->last_source = NULL;
set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV); vp9_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
// Normal defaults // Normal defaults
cm->reset_frame_context = 0; cm->reset_frame_context = 0;
...@@ -2446,7 +2459,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2446,7 +2459,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (arf_src_index) { if (arf_src_index) {
assert(arf_src_index <= rc->frames_to_key); assert(arf_src_index <= rc->frames_to_key);
if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index))) { #ifdef CONFIG_SPATIAL_SVC
if (is_spatial_svc)
cpi->source = vp9_svc_lookahead_peek(cpi, cpi->lookahead,
arf_src_index, 1);
else
#endif
cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index);
if (cpi->source != NULL) {
cpi->alt_ref_source = cpi->source; cpi->alt_ref_source = cpi->source;
if (cpi->oxcf.arnr_max_frames > 0) { if (cpi->oxcf.arnr_max_frames > 0) {
...@@ -2472,12 +2492,24 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2472,12 +2492,24 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (!cpi->source) { if (!cpi->source) {
// Get last frame source. // Get last frame source.
if (cm->current_video_frame > 0) { if (cm->current_video_frame > 0) {
if ((cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL) #ifdef CONFIG_SPATIAL_SVC
if (is_spatial_svc)
cpi->last_source = vp9_svc_lookahead_peek(cpi, cpi->lookahead, -1, 0);
else
#endif
cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1);
if (cpi->last_source == NULL)
return -1; return -1;
} }
// Read in the source frame. // Read in the source frame.
if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) { #ifdef CONFIG_SPATIAL_SVC
if (is_spatial_svc)
cpi->source = vp9_svc_lookahead_pop(cpi, cpi->lookahead, flush);
else
#endif
cpi->source = vp9_lookahead_pop(cpi->lookahead, flush);
if (cpi->source != NULL) {
cm->show_frame = 1; cm->show_frame = 1;
cm->intra_only = 0; cm->intra_only = 0;
...@@ -2499,7 +2531,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2499,7 +2531,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
*time_stamp = cpi->source->ts_start; *time_stamp = cpi->source->ts_start;
*time_end = cpi->source->ts_end; *time_end = cpi->source->ts_end;
*frame_flags = cpi->source->flags; *frame_flags =
(cpi->source->flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
} else { } else {
*size = 0; *size = 0;
if (flush && cpi->pass == 1 && !cpi->twopass.first_pass_done) { if (flush && cpi->pass == 1 && !cpi->twopass.first_pass_done) {
...@@ -2830,3 +2864,42 @@ int vp9_get_y_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b) { ...@@ -2830,3 +2864,42 @@ int vp9_get_y_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b) {
int vp9_get_quantizer(VP9_COMP *cpi) { int vp9_get_quantizer(VP9_COMP *cpi) {
return cpi->common.base_qindex; return cpi->common.base_qindex;
} }
void vp9_apply_encoding_flags(VP9_COMP *cpi, vpx_enc_frame_flags_t flags) {
if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF)) {
int ref = 7;
if (flags & VP8_EFLAG_NO_REF_LAST)
ref ^= VP9_LAST_FLAG;
if (flags & VP8_EFLAG_NO_REF_GF)
ref ^= VP9_GOLD_FLAG;
if (flags & VP8_EFLAG_NO_REF_ARF)
ref ^= VP9_ALT_FLAG;
vp9_use_as_reference(cpi, ref);
}
if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF |
VP8_EFLAG_FORCE_ARF)) {
int upd = 7;
if (flags & VP8_EFLAG_NO_UPD_LAST)
upd ^= VP9_LAST_FLAG;
if (flags & VP8_EFLAG_NO_UPD_GF)
upd ^= VP9_GOLD_FLAG;
if (flags & VP8_EFLAG_NO_UPD_ARF)
upd ^= VP9_ALT_FLAG;
vp9_update_reference(cpi, upd);
}
if (flags & VP8_EFLAG_NO_UPD_ENTROPY) {
vp9_update_entropy(cpi, 0);
}
}
...@@ -517,10 +517,14 @@ void vp9_update_reference_frames(VP9_COMP *cpi); ...@@ -517,10 +517,14 @@ void vp9_update_reference_frames(VP9_COMP *cpi);
int64_t vp9_rescale(int64_t val, int64_t num, int denom); int64_t vp9_rescale(int64_t val, int64_t num, int denom);
void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv);
YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm, YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled); YV12_BUFFER_CONFIG *scaled);
void vp9_apply_encoding_flags(VP9_COMP *cpi, vpx_enc_frame_flags_t flags);
static INLINE void set_ref_ptrs(VP9_COMMON *cm, MACROBLOCKD *xd, static INLINE void set_ref_ptrs(VP9_COMMON *cm, MACROBLOCKD *xd,
MV_REFERENCE_FRAME ref0, MV_REFERENCE_FRAME ref0,
MV_REFERENCE_FRAME ref1) { MV_REFERENCE_FRAME ref1) {
......
...@@ -18,18 +18,6 @@ ...@@ -18,18 +18,6 @@
#include "vp9/encoder/vp9_extend.h" #include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_lookahead.h" #include "vp9/encoder/vp9_lookahead.h"
// The max of past frames we want to keep in the queue.
#define MAX_PRE_FRAMES 1
struct lookahead_ctx {
unsigned int max_sz; /* Absolute size of the queue */
unsigned int sz; /* Number of buffers currently in the queue */
unsigned int read_idx; /* Read index */
unsigned int write_idx; /* Write index */
struct lookahead_entry *buf; /* Buffer list */
};
/* Return the buffer at the given absolute index and increment the index */ /* Return the buffer at the given absolute index and increment the index */
static struct lookahead_entry *pop(struct lookahead_ctx *ctx, static struct lookahead_entry *pop(struct lookahead_ctx *ctx,
unsigned int *idx) { unsigned int *idx) {
......
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
#include "vpx_scale/yv12config.h" #include "vpx_scale/yv12config.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#ifdef CONFIG_SPATIAL_SVC
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -25,10 +30,22 @@ struct lookahead_entry { ...@@ -25,10 +30,22 @@ struct lookahead_entry {
int64_t ts_start; int64_t ts_start;
int64_t ts_end; int64_t ts_end;
unsigned int flags; unsigned int flags;
#ifdef CONFIG_SPATIAL_SVC
vpx_svc_parameters_t svc_params[VPX_SS_MAX_LAYERS];
#endif
}; };
// The max of past frames we want to keep in the queue.
#define MAX_PRE_FRAMES 1
struct lookahead_ctx; struct lookahead_ctx {
unsigned int max_sz; /* Absolute size of the queue */
unsigned int sz; /* Number of buffers currently in the queue */
unsigned int read_idx; /* Read index */
unsigned int write_idx; /* Write index */
struct lookahead_entry *buf; /* Buffer list */
};
/**\brief Initializes the lookahead stage /**\brief Initializes the lookahead stage
* *
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "vp9/encoder/vp9_encoder.h" #include "vp9/encoder/vp9_encoder.h"
#include "vp9/encoder/vp9_svc_layercontext.h" #include "vp9/encoder/vp9_svc_layercontext.h"
#include "vp9/encoder/vp9_extend.h"
void vp9_init_layer_context(VP9_COMP *const cpi) { void vp9_init_layer_context(VP9_COMP *const cpi) {
SVC *const svc = &cpi->svc; SVC *const svc = &cpi->svc;
...@@ -209,3 +210,101 @@ int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { ...@@ -209,3 +210,101 @@ int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
cpi->svc.spatial_layer_id > 0 && cpi->svc.spatial_layer_id > 0 &&
cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame; cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame;
} }
int vp9_svc_lookahead_push(const VP9_COMP *const cpi, struct lookahead_ctx *ctx,
YV12_BUFFER_CONFIG *src, int64_t ts_start,
int64_t ts_end, unsigned int flags) {