Commit abf58ecf authored by Marco's avatar Marco

Vidyo patch: Changes to the scalability code.

Changes to mode selection for 1 pass SVC mode:
use base layer motion vector, changes to intra-prediction.

Change-Id: I3e883aa04db521cfa026a0b12c9478ea35a344c9
parent a7e0b1ea
......@@ -30,6 +30,7 @@
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "../vpxstats.h"
#include "vp9/encoder/vp9_encoder.h"
#define OUTPUT_RC_STATS 1
static const arg_def_t skip_frames_arg =
......@@ -749,6 +750,7 @@ int main(int argc, const char **argv) {
cx_time += vpx_usec_timer_elapsed(&timer);
printf("%s", vpx_svc_get_message(&svc_ctx));
fflush(stdout);
if (res != VPX_CODEC_OK) {
die_codec(&codec, "Failed to encode frame");
}
......@@ -756,6 +758,7 @@ int main(int argc, const char **argv) {
while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
switch (cx_pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT: {
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
if (cx_pkt->data.frame.sz > 0) {
#if OUTPUT_RC_STATS
uint32_t sizes[8];
......@@ -851,6 +854,8 @@ int main(int argc, const char **argv) {
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
++frames_received;
break;
}
......
......@@ -41,7 +41,7 @@ enum denoiserState {
kDenoiserOnAdaptive
};
static int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3};
static int mode_to_num_layers[13] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3};
// For rate control encoding stats.
struct RateControlMetrics {
......@@ -432,7 +432,32 @@ static void set_temporal_layer_pattern(int layering_mode,
layer_flags[7] = layer_flags[3];
break;
}
case 11:
case 11: {
// 3-layers structure with one reference frame.
// This works same as temporal_layering_mode 3.
// This was added to compare with vp9_spatial_svc_encoder.
// 3-layers, 4-frame period.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 4;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[3] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
break;
}
case 12:
default: {
// 3-layers structure as in case 10, but no sync/refresh points for
// layer 1 and 2.
......@@ -530,7 +555,7 @@ int main(int argc, char **argv) {
}
layering_mode = strtol(argv[10], NULL, 0);
if (layering_mode < 0 || layering_mode > 12) {
if (layering_mode < 0 || layering_mode > 13) {
die("Invalid layering mode (0..12) %s", argv[10]);
}
......
......@@ -1754,7 +1754,9 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td,
}
}
if (cm->use_prev_frame_mvs) {
if (cm->use_prev_frame_mvs ||
(cpi->svc.use_base_mv && cpi->svc.number_spatial_layers > 1
&& cpi->svc.spatial_layer_id != cpi->svc.number_spatial_layers - 1)) {
MV_REF *const frame_mvs =
cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
int w, h;
......
......@@ -3318,6 +3318,11 @@ static void encode_without_recode_loop(VP9_COMP *cpi,
cpi->oxcf.content == VP9E_CONTENT_SCREEN)
vp9_avg_source_sad(cpi);
// TODO(wonkap/marpan): For 1 pass SVC, since only ZERMOV is allowed for
// upsampled reference frame (i.e, svc->force_zero_mode_spatial_ref = 0),
// we should be able to avoid this frame-level upsampling.
// Keeping it for now as there is an asan error in the multi-threaded SVC
// rate control test if this upsampling is removed.
if (frame_is_intra_only(cm) == 0) {
vp9_scale_references(cpi);
}
......
This diff is collapsed.
......@@ -33,6 +33,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
svc->first_spatial_layer_to_encode = 0;
svc->rc_drop_superframe = 0;
svc->force_zero_mode_spatial_ref = 0;
svc->use_base_mv = 0;
svc->current_superframe = 0;
for (i = 0; i < REF_FRAMES; ++i)
svc->ref_frame_index[i] = -1;
......@@ -416,7 +417,9 @@ static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
cpi->ref_frame_flags = VP9_LAST_FLAG;
} else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
// base layer is a key frame.
cpi->ref_frame_flags = VP9_GOLD_FLAG;
cpi->ref_frame_flags = VP9_LAST_FLAG;
cpi->ext_refresh_last_frame = 0;
cpi->ext_refresh_golden_frame = 1;
} else {
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
}
......@@ -431,7 +434,13 @@ static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
} else {
if (frame_num_within_temporal_struct == 1) {
// the first tl2 picture
if (!spatial_id) {
if (spatial_id == cpi->svc.number_spatial_layers - 1) { // top layer
cpi->ext_refresh_frame_flags_pending = 1;
if (!spatial_id)
cpi->ref_frame_flags = VP9_LAST_FLAG;
else
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
} else if (!spatial_id) {
cpi->ext_refresh_frame_flags_pending = 1;
cpi->ext_refresh_alt_ref_frame = 1;
cpi->ref_frame_flags = VP9_LAST_FLAG;
......@@ -439,32 +448,38 @@ static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
cpi->ext_refresh_frame_flags_pending = 1;
cpi->ext_refresh_alt_ref_frame = 1;
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
} else { // Top layer
cpi->ext_refresh_frame_flags_pending = 0;
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
}
} else {
// The second tl2 picture
if (!spatial_id) {
if (spatial_id == cpi->svc.number_spatial_layers - 1) { // top layer
cpi->ext_refresh_frame_flags_pending = 1;
if (!spatial_id)
cpi->ref_frame_flags = VP9_LAST_FLAG;
cpi->ext_refresh_last_frame = 1;
} else if (spatial_id < cpi->svc.number_spatial_layers - 1) {
else
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
} else if (!spatial_id) {
cpi->ext_refresh_frame_flags_pending = 1;
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
cpi->ext_refresh_last_frame = 1;
cpi->ref_frame_flags = VP9_LAST_FLAG;
cpi->ext_refresh_alt_ref_frame = 1;
} else { // top layer
cpi->ext_refresh_frame_flags_pending = 0;
cpi->ext_refresh_frame_flags_pending = 1;
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
cpi->ext_refresh_alt_ref_frame = 1;
}
}
}
if (temporal_id == 0) {
cpi->lst_fb_idx = spatial_id;
if (spatial_id)
if (spatial_id) {
if (cpi->svc.layer_context[temporal_id].is_key_frame) {
cpi->lst_fb_idx = spatial_id - 1;
cpi->gld_fb_idx = spatial_id;
} else {
cpi->gld_fb_idx = spatial_id - 1;
else
}
} else {
cpi->gld_fb_idx = 0;
}
cpi->alt_fb_idx = 0;
} else if (temporal_id == 1) {
cpi->lst_fb_idx = spatial_id;
......@@ -477,7 +492,7 @@ static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
} else {
cpi->lst_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
cpi->alt_fb_idx = 0;
cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
}
}
......@@ -499,7 +514,9 @@ static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) {
cpi->ref_frame_flags = VP9_LAST_FLAG;
} else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
// base layer is a key frame.
cpi->ref_frame_flags = VP9_GOLD_FLAG;
cpi->ref_frame_flags = VP9_LAST_FLAG;
cpi->ext_refresh_last_frame = 0;
cpi->ext_refresh_golden_frame = 1;
} else {
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
}
......@@ -515,10 +532,16 @@ static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) {
if (temporal_id == 0) {
cpi->lst_fb_idx = spatial_id;
if (spatial_id)
if (spatial_id) {
if (cpi->svc.layer_context[temporal_id].is_key_frame) {
cpi->lst_fb_idx = spatial_id - 1;
cpi->gld_fb_idx = spatial_id;
} else {
cpi->gld_fb_idx = spatial_id - 1;
else
}
} else {
cpi->gld_fb_idx = 0;
}
cpi->alt_fb_idx = 0;
} else if (temporal_id == 1) {
cpi->lst_fb_idx = spatial_id;
......@@ -540,20 +563,30 @@ static void set_flags_and_fb_idx_for_temporal_mode_noLayering(
if (!spatial_id) {
cpi->ref_frame_flags = VP9_LAST_FLAG;
} else if (cpi->svc.layer_context[0].is_key_frame) {
cpi->ref_frame_flags = VP9_GOLD_FLAG;
cpi->ref_frame_flags = VP9_LAST_FLAG;
cpi->ext_refresh_last_frame = 0;
cpi->ext_refresh_golden_frame = 1;
} else {
cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
}
cpi->lst_fb_idx = spatial_id;
if (spatial_id)
if (spatial_id) {
if (cpi->svc.layer_context[0].is_key_frame) {
cpi->lst_fb_idx = spatial_id - 1;
cpi->gld_fb_idx = spatial_id;
} else {
cpi->gld_fb_idx = spatial_id - 1;
else
}
} else {
cpi->gld_fb_idx = 0;
}
}
int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
int width = 0, height = 0;
LAYER_CONTEXT *lc = NULL;
if (cpi->svc.number_spatial_layers > 1)
cpi->svc.use_base_mv = 1;
cpi->svc.force_zero_mode_spatial_ref = 1;
if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) {
......
......@@ -86,6 +86,7 @@ typedef struct {
int ref_frame_index[REF_FRAMES];
int force_zero_mode_spatial_ref;
int current_superframe;
int use_base_mv;
} SVC;
struct VP9_COMP;
......
......@@ -322,8 +322,7 @@ void assign_layer_bitrates(const SvcContext *svc_ctx,
for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) {
if (si->svc_params.scaling_factor_den[sl] > 0) {
alloc_ratio[sl] = (float)(si->svc_params.scaling_factor_num[sl] *
1.0 / si->svc_params.scaling_factor_den[sl]);
alloc_ratio[sl] = (float)( (sl+1) );
total += alloc_ratio[sl];
}
}
......@@ -334,9 +333,9 @@ void assign_layer_bitrates(const SvcContext *svc_ctx,
alloc_ratio[sl] / total);
if (svc_ctx->temporal_layering_mode == 3) {
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers] =
spatial_layer_target >> 1;
(spatial_layer_target*6)/10; // 60%
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 1] =
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
(spatial_layer_target*8)/10; // 80%
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 2] =
spatial_layer_target;
} else if (svc_ctx->temporal_layering_mode == 2 ||
......@@ -398,11 +397,13 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
si->width = enc_cfg->g_w;
si->height = enc_cfg->g_h;
if (enc_cfg->kf_max_dist < 2) {
// wonkap: why is this necessary?
/*if (enc_cfg->kf_max_dist < 2) {
svc_log(svc_ctx, SVC_LOG_ERROR, "key frame distance too small: %d\n",
enc_cfg->kf_max_dist);
return VPX_CODEC_INVALID_PARAM;
}
}*/
si->kf_dist = enc_cfg->kf_max_dist;
if (svc_ctx->spatial_layers == 0)
......@@ -577,6 +578,27 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx,
}
#endif
#endif
case VPX_CODEC_PSNR_PKT:
{
#if VPX_ENCODER_ABI_VERSION > (5 + VPX_CODEC_ABI_VERSION)
int j;
svc_log(svc_ctx, SVC_LOG_DEBUG,
"frame: %d, layer: %d, PSNR(Total/Y/U/V): "
"%2.3f %2.3f %2.3f %2.3f \n",
si->psnr_pkt_received, 0,
cx_pkt->data.layer_psnr[0].psnr[0],
cx_pkt->data.layer_psnr[0].psnr[1],
cx_pkt->data.layer_psnr[0].psnr[2],
cx_pkt->data.layer_psnr[0].psnr[3]);
for (j = 0; j < COMPONENTS; ++j) {
si->psnr_sum[0][j] +=
cx_pkt->data.layer_psnr[0].psnr[j];
si->sse_sum[0][j] += cx_pkt->data.layer_psnr[0].sse[j];
}
#endif
}
++si->psnr_pkt_received;
break;
default: {
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment