summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/vp8_cx_iface.c1
-rw-r--r--vp9/common/vp9_onyx.h6
-rw-r--r--vp9/common/vp9_onyxc_int.h1
-rw-r--r--vp9/decoder/vp9_decodemv.c6
-rw-r--r--vp9/decoder/vp9_decodframe.c14
-rw-r--r--vp9/encoder/vp9_bitstream.c9
-rw-r--r--vp9/encoder/vp9_onyx_if.c18
-rw-r--r--vp9/encoder/vp9_rdopt.c3
-rw-r--r--vp9/vp9_cx_iface.c4
-rw-r--r--vpx/vpx_encoder.h6
-rw-r--r--vpxenc.c17
11 files changed, 69 insertions, 16 deletions
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index b985cb1b7..0b58b0eaa 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -1238,6 +1238,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
{1, 30}, /* g_timebase */
0, /* g_error_resilient */
+ 0, /* g_frame_parallel_decoding */
VPX_RC_ONE_PASS, /* g_pass */
diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h
index 46ae2f0f4..d757c398e 100644
--- a/vp9/common/vp9_onyx.h
+++ b/vp9/common/vp9_onyx.h
@@ -165,6 +165,12 @@ extern "C"
*/
unsigned int error_resilient_mode;
+ /* Bitfield defining the parallel decoding mode where the
+ * decoding in successive frames may be conducted in parallel
+ * just by decoding the frame headers.
+ */
+ unsigned int frame_parallel_decoding_mode;
+
int arnr_max_frames;
int arnr_strength;
int arnr_type;
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 4e2fa3799..cbabfa3da 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -277,6 +277,7 @@ typedef struct VP9Common {
#endif
int error_resilient_mode;
+ int frame_parallel_decoding_mode;
} VP9_COMMON;
static int get_free_fb(VP9_COMMON *cm) {
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 31ae257dc..76fb817df 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -791,7 +791,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
if (mbmi->mode != ZEROMV) {
vp9_find_best_ref_mvs(xd,
- pbi->common.error_resilient_mode ?
+ pbi->common.error_resilient_mode ||
+ pbi->common.frame_parallel_decoding_mode ?
0 : xd->pre.y_buffer,
recon_y_stride,
mbmi->ref_mvs[ref_frame],
@@ -851,7 +852,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
if (mbmi->mode != ZEROMV) {
vp9_find_best_ref_mvs(xd,
- pbi->common.error_resilient_mode ?
+ pbi->common.error_resilient_mode ||
+ pbi->common.frame_parallel_decoding_mode ?
0 : xd->second_pre.y_buffer,
recon_y_stride,
mbmi->ref_mvs[mbmi->second_ref_frame],
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 10bcbf953..936251a6a 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1624,7 +1624,13 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
}
- pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
+ if (!pc->error_resilient_mode) {
+ pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
+ pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc);
+ } else {
+ pc->refresh_entropy_probs = 0;
+ pc->frame_parallel_decoding_mode = 1;
+ }
pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
vpx_memcpy(&pc->fc, &pc->frame_contexts[pc->frame_context_idx],
sizeof(pc->fc));
@@ -1771,10 +1777,12 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
"A stream must start with a complete key frame");
}
- if (!pc->error_resilient_mode)
+ if (!pc->error_resilient_mode &&
+ !pc->frame_parallel_decoding_mode)
vp9_adapt_coef_probs(pc);
if (pc->frame_type != KEY_FRAME) {
- if (!pc->error_resilient_mode) {
+ if (!pc->error_resilient_mode &&
+ !pc->frame_parallel_decoding_mode) {
vp9_adapt_mode_probs(pc);
vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
vp9_adapt_mode_context(&pbi->common);
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 34d27d1be..23a5b93c5 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1833,7 +1833,11 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
#endif
}
- vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
+ if (!pc->error_resilient_mode) {
+ vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
+ vp9_write_bit(&header_bc, pc->frame_parallel_decoding_mode);
+ }
+
vp9_write_literal(&header_bc, pc->frame_context_idx,
NUM_FRAME_CONTEXTS_LG2);
@@ -2023,9 +2027,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
* final packing pass */
// if (!cpi->dummy_packing) vp9_zero(cpi->NMVcount);
write_modes(cpi, &residual_bc);
-
- if (!cpi->common.error_resilient_mode)
- vp9_adapt_mode_context(&cpi->common);
}
vp9_stop_encode(&residual_bc);
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index a14165752..d1c48e14c 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -2824,6 +2824,12 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
cm->error_resilient_mode = (cpi->oxcf.error_resilient_mode != 0);
+ cm->frame_parallel_decoding_mode =
+ (cpi->oxcf.frame_parallel_decoding_mode != 0);
+ if (cm->error_resilient_mode) {
+ cm->frame_parallel_decoding_mode = 1;
+ cm->refresh_entropy_probs = 0;
+ }
}
// Test code for new segment features
@@ -3449,7 +3455,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_copy(cpi->common.fc.hybrid_coef_counts_16x16,
cpi->hybrid_coef_counts_16x16);
vp9_copy(cpi->common.fc.coef_counts_32x32, cpi->coef_counts_32x32);
- if (!cpi->common.error_resilient_mode)
+ if (!cpi->common.error_resilient_mode &&
+ !cpi->common.frame_parallel_decoding_mode)
vp9_adapt_coef_probs(&cpi->common);
if (cpi->common.frame_type != KEY_FRAME) {
vp9_copy(cpi->common.fc.sb_ymode_counts, cpi->sb_ymode_count);
@@ -3462,12 +3469,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
#if CONFIG_COMP_INTERINTRA_PRED
vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
#endif
- if (!cpi->common.error_resilient_mode)
- vp9_adapt_mode_probs(&cpi->common);
-
cpi->common.fc.NMVcount = cpi->NMVcount;
- if (!cpi->common.error_resilient_mode)
+ if (!cpi->common.error_resilient_mode &&
+ !cpi->common.frame_parallel_decoding_mode) {
+ vp9_adapt_mode_probs(&cpi->common);
+ vp9_adapt_mode_context(&cpi->common);
vp9_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv);
+ }
}
#if CONFIG_COMP_INTERINTRA_PRED
if (cm->frame_type != KEY_FRAME)
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 8710475bd..2f52f0297 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3179,7 +3179,8 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
// Candidate refinement carried out at encoder and decoder
vp9_find_best_ref_mvs(xd,
- cpi->common.error_resilient_mode ?
+ cpi->common.error_resilient_mode ||
+ cpi->common.frame_parallel_decoding_mode ?
0 : y_buffer[frame_type],
yv12->y_stride,
mbmi->ref_mvs[frame_type],
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 0c82d067c..75df0e037 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -314,6 +314,7 @@ static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
#endif
oxcf->error_resilient_mode = cfg.g_error_resilient;
+ oxcf->frame_parallel_decoding_mode = cfg.g_frame_parallel_decoding;
/*
printf("Current VP9 Settings: \n");
printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
@@ -342,6 +343,8 @@ static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
printf("Version: %d\n", oxcf->Version);
printf("encode_breakout: %d\n", oxcf->encode_breakout);
printf("error resilient: %d\n", oxcf->error_resilient_mode);
+ printf("frame parallel detokenization: %d\n",
+ oxcf->frame_parallel_decoding_mode);
*/
return VPX_CODEC_OK;
}
@@ -1034,6 +1037,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = {
{1, 30}, /* g_timebase */
0, /* g_error_resilient */
+ 0, /* g_frame_parallel_decoding */
VPX_RC_ONE_PASS, /* g_pass */
diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h
index ffdbc0644..2ec09bdd4 100644
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -334,6 +334,12 @@ extern "C" {
*/
vpx_codec_er_flags_t g_error_resilient;
+ /*!\brief Enable frame parallel decoding mode
+ * This value should be 1 to encode in a way that enables frame parallel
+ * decoding. Otherwise make it 0.
+ */
+ unsigned int g_frame_parallel_decoding;
+
/*!\brief Multi-pass Encoding Mode
*
diff --git a/vpxenc.c b/vpxenc.c
index d53d9db57..e6f935174 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -993,12 +993,20 @@ static const arg_def_t timebase = ARG_DEF(NULL, "timebase", 1,
"Output timestamp precision (fractional seconds)");
static const arg_def_t error_resilient = ARG_DEF(NULL, "error-resilient", 1,
"Enable error resiliency features");
+#if CONFIG_VP9_ENCODER
+static const arg_def_t frame_parallel_decoding = ARG_DEF(
+ NULL, "frame-parallel", 1, "Enable frame parallel decodability features");
+#endif
static const arg_def_t lag_in_frames = ARG_DEF(NULL, "lag-in-frames", 1,
"Max number of frames to lag");
static const arg_def_t *global_args[] = {
&use_yv12, &use_i420, &usage, &threads, &profile,
- &width, &height, &stereo_mode, &timebase, &framerate, &error_resilient,
+ &width, &height, &stereo_mode, &timebase, &framerate,
+ &error_resilient,
+#if CONFIG_VP9_ENCODER
+ &frame_parallel_decoding,
+#endif
&lag_in_frames, NULL
};
@@ -1882,6 +1890,10 @@ static int parse_stream_params(struct global_config *global,
validate_positive_rational(arg.name, &config->cfg.g_timebase);
} else if (arg_match(&arg, &error_resilient, argi))
config->cfg.g_error_resilient = arg_parse_uint(&arg);
+#if CONFIG_VP9_ENCODER
+ else if (arg_match(&arg, &frame_parallel_decoding, argi))
+ config->cfg.g_frame_parallel_decoding = arg_parse_uint(&arg);
+#endif
else if (arg_match(&arg, &lag_in_frames, argi))
config->cfg.g_lag_in_frames = arg_parse_uint(&arg);
else if (arg_match(&arg, &dropframe_thresh, argi))
@@ -2062,6 +2074,9 @@ static void show_stream_config(struct stream_state *stream,
SHOW(g_timebase.num);
SHOW(g_timebase.den);
SHOW(g_error_resilient);
+#if CONFIG_VP9_ENCODER
+ SHOW(g_frame_parallel_decoding);
+#endif
SHOW(g_pass);
SHOW(g_lag_in_frames);
SHOW(rc_dropframe_thresh);