summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorMinghai Shang <minghai@google.com>2014-08-25 14:29:49 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2014-08-25 14:29:49 -0700
commit42ad07a138d0c0345c08101673f5ad473af48d99 (patch)
tree0d958004d9d1bc29b276a8d9960646dc27e8b97f /vp9
parent48d36e9cac21ce2b4c08621b6cab2a4163eddc03 (diff)
parentd4a407c051a1aa85214e7b96c1ad1e0ba41c6e9e (diff)
downloadlibvpx-42ad07a138d0c0345c08101673f5ad473af48d99.tar
libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.tar.gz
libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.tar.bz2
libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.zip
Merge "[spatial svc]Multiple frame context feature"
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_bitstream.c11
-rw-r--r--vp9/encoder/vp9_encoder.c25
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c1
-rw-r--r--vp9/encoder/vp9_svc_layercontext.h1
-rw-r--r--vp9/vp9_cx_iface.c2
5 files changed, 37 insertions, 3 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index bdb133882..8ca05c1c0 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1083,7 +1083,16 @@ static void write_uncompressed_header(VP9_COMP *cpi,
write_bitdepth_colorspace_sampling(cm, wb);
write_frame_size(cm, wb);
} else {
- if (!cm->show_frame)
+ // In spatial svc if it's not error_resilient_mode then we need to code all
+ // visible frames as invisible. But we need to keep the show_frame flag so
+ // that the publisher could know whether it is supposed to be visible.
+ // So we will code the show_frame flag as it is. Then code the intra_only
+ // bit here. This will make the bitstream incompatible. In the player we
+ // 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 ||
+ (is_spatial_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 5b710ff5b..4be604af7 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2123,6 +2123,19 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm->reset_frame_context = 2;
}
}
+ if (is_spatial_svc(cpi) && cm->error_resilient_mode == 0) {
+ cm->frame_context_idx = cpi->svc.spatial_layer_id;
+
+ // The probs will be updated based on the frame type of its previous
+ // frame if frame_parallel_decoding_mode is 0. The type may vary for
+ // the frame after a key frame in base layer since we may drop enhancement
+ // layers. So set frame_parallel_decoding_mode to 1 in this case.
+ if (cpi->svc.spatial_layer_id == 0 &&
+ cpi->svc.layer_context[0].last_frame_type == KEY_FRAME)
+ cm->frame_parallel_decoding_mode = 1;
+ else
+ cm->frame_parallel_decoding_mode = 0;
+ }
// Configure experimental use of segmentation for enhanced coding of
// static regions if indicated.
@@ -2298,8 +2311,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_spatial_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);
@@ -2310,6 +2327,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if (cpi->use_svc)
vp9_inc_frame_in_layer(&cpi->svc);
}
+
+ if (is_spatial_svc(cpi))
+ cpi->svc.layer_context[cpi->svc.spatial_layer_id].last_frame_type =
+ cm->frame_type;
}
static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index fb52d1ab7..9bd9792bd 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -36,6 +36,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
int i;
lc->current_video_frame_in_layer = 0;
lc->layer_size = 0;
+ lc->last_frame_type = FRAME_TYPES;
lrc->ni_av_qi = oxcf->worst_allowed_q;
lrc->total_actual_bits = 0;
lrc->total_target_vs_actual = 0;
diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h
index 0857e39cd..d475d5fcd 100644
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -28,6 +28,7 @@ typedef struct {
vpx_fixed_buf_t rc_twopass_stats_in;
unsigned int current_video_frame_in_layer;
int is_key_frame;
+ FRAME_TYPE last_frame_type;
vpx_svc_parameters_t svc_params_received;
struct lookahead_entry *alt_ref_source;
int alt_ref_idx;
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 83f8abb16..0130e9d9e 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -176,6 +176,8 @@ 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 > 3 && cfg->g_error_resilient == 0)
+ ERROR("Multiple frame contexts are not supported for more than 3 layers");
#endif
RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS);