Commit 38b6aed8 authored by Minghai Shang's avatar Minghai Shang Committed by Gerrit Code Review
Browse files

Merge "[spatial svc] Remove vpx_svc_parameters_t and the loop that sets it for each layer"

parents 45a577e8 209ee121
...@@ -305,12 +305,6 @@ int main(int argc, const char **argv) { ...@@ -305,12 +305,6 @@ int main(int argc, const char **argv) {
info.codec_fourcc = VP9_FOURCC; info.codec_fourcc = VP9_FOURCC;
info.time_base.numerator = enc_cfg.g_timebase.num; info.time_base.numerator = enc_cfg.g_timebase.num;
info.time_base.denominator = enc_cfg.g_timebase.den; info.time_base.denominator = enc_cfg.g_timebase.den;
if (vpx_svc_get_layer_resolution(&svc_ctx, svc_ctx.spatial_layers - 1,
(unsigned int *)&info.frame_width,
(unsigned int *)&info.frame_height) !=
VPX_CODEC_OK) {
die("Failed to get output resolution");
}
if (!(app_input.passes == 2 && app_input.pass == 1)) { if (!(app_input.passes == 2 && app_input.pass == 1)) {
// We don't save the bitstream for the 1st pass on two pass rate control // We don't save the bitstream for the 1st pass on two pass rate control
......
...@@ -515,37 +515,6 @@ TEST_F(SvcTest, OnePassEncodeThreeFrames) { ...@@ -515,37 +515,6 @@ TEST_F(SvcTest, OnePassEncodeThreeFrames) {
FreeBitstreamBuffers(&outputs[0], 3); FreeBitstreamBuffers(&outputs[0], 3);
} }
TEST_F(SvcTest, GetLayerResolution) {
svc_.spatial_layers = 2;
vpx_svc_set_options(&svc_, "scale-factors=4/16,8/16");
InitializeEncoder();
// ensure that requested layer is a valid layer
uint32_t layer_width, layer_height;
vpx_codec_err_t res = vpx_svc_get_layer_resolution(&svc_, svc_.spatial_layers,
&layer_width, &layer_height);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_get_layer_resolution(NULL, 0, &layer_width, &layer_height);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_get_layer_resolution(&svc_, 0, NULL, &layer_height);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, NULL);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, &layer_height);
EXPECT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(kWidth * 4 / 16, layer_width);
EXPECT_EQ(kHeight * 4 / 16, layer_height);
res = vpx_svc_get_layer_resolution(&svc_, 1, &layer_width, &layer_height);
EXPECT_EQ(VPX_CODEC_OK, res);
EXPECT_EQ(kWidth * 8 / 16, layer_width);
EXPECT_EQ(kHeight * 8 / 16, layer_height);
}
TEST_F(SvcTest, TwoPassEncode10Frames) { TEST_F(SvcTest, TwoPassEncode10Frames) {
// First pass encode // First pass encode
std::string stats_buf; std::string stats_buf;
......
...@@ -2448,15 +2448,7 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags, ...@@ -2448,15 +2448,7 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags,
vpx_usec_timer_start(&timer); vpx_usec_timer_start(&timer);
#if CONFIG_SPATIAL_SVC if (vp9_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, frame_flags))
if (is_two_pass_svc(cpi))
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);
...@@ -2585,11 +2577,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2585,11 +2577,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
MV_REFERENCE_FRAME ref_frame; MV_REFERENCE_FRAME ref_frame;
int arf_src_index; int arf_src_index;
if (is_two_pass_svc(cpi) && oxcf->pass == 2) { if (is_two_pass_svc(cpi)) {
#if CONFIG_SPATIAL_SVC #if CONFIG_SPATIAL_SVC
vp9_svc_lookahead_peek(cpi, cpi->lookahead, 0, 1); vp9_svc_start_frame(cpi);
#endif #endif
vp9_restore_layer_context(cpi); if (oxcf->pass == 2)
vp9_restore_layer_context(cpi);
} }
vpx_usec_timer_start(&cmptimer); vpx_usec_timer_start(&cmptimer);
...@@ -2608,13 +2601,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2608,13 +2601,7 @@ 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 CONFIG_SPATIAL_SVC if ((source = vp9_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
if (is_two_pass_svc(cpi))
source = vp9_svc_lookahead_peek(cpi, cpi->lookahead, arf_src_index, 0);
else
#endif
source = vp9_lookahead_peek(cpi->lookahead, arf_src_index);
if (source != NULL) {
cpi->alt_ref_source = source; cpi->alt_ref_source = source;
#if CONFIG_SPATIAL_SVC #if CONFIG_SPATIAL_SVC
...@@ -2652,13 +2639,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2652,13 +2639,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (!source) { if (!source) {
// Get last frame source. // Get last frame source.
if (cm->current_video_frame > 0) { if (cm->current_video_frame > 0) {
#if CONFIG_SPATIAL_SVC if ((last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL)
if (is_two_pass_svc(cpi))
last_source = vp9_svc_lookahead_peek(cpi, cpi->lookahead, -1, 0);
else
#endif
last_source = vp9_lookahead_peek(cpi->lookahead, -1);
if (last_source == NULL)
return -1; return -1;
} }
...@@ -2918,6 +2899,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2918,6 +2899,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
} }
#endif #endif
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; return 0;
} }
......
...@@ -30,10 +30,6 @@ struct lookahead_entry { ...@@ -30,10 +30,6 @@ 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;
#if 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. // The max of past frames we want to keep in the queue.
......
...@@ -233,51 +233,31 @@ int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { ...@@ -233,51 +233,31 @@ int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
} }
#if CONFIG_SPATIAL_SVC #if CONFIG_SPATIAL_SVC
int vp9_svc_lookahead_push(const VP9_COMP *const cpi, struct lookahead_ctx *ctx, static void get_layer_resolution(const int width_org, const int height_org,
YV12_BUFFER_CONFIG *src, int64_t ts_start, const int num, const int den,
int64_t ts_end, unsigned int flags) { int *width_out, int *height_out) {
struct lookahead_entry *buf; int w, h;
int i, index;
if (vp9_lookahead_push(ctx, src, ts_start, ts_end, flags)) if (width_out == NULL || height_out == NULL || den == 0)
return 1; return;
index = ctx->write_idx - 1; w = width_org * num / den;
if (index < 0) h = height_org * num / den;
index += ctx->max_sz;
buf = ctx->buf + index; // make height and width even to make chrome player happy
w += w % 2;
h += h % 2;
if (buf == NULL) *width_out = w;
return 1; *height_out = h;
// Store svc parameters for each layer
for (i = 0; i < cpi->svc.number_spatial_layers; ++i)
buf->svc_params[i] = cpi->svc.layer_context[i].svc_params_received;
return 0;
} }
static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) { int vp9_svc_start_frame(VP9_COMP *const cpi) {
int layer_id; int width = 0, height = 0;
vpx_svc_parameters_t *layer_param;
LAYER_CONTEXT *lc; LAYER_CONTEXT *lc;
int count = 1 << (cpi->svc.number_temporal_layers - 1); int count = 1 << (cpi->svc.number_temporal_layers - 1);
// Find the next layer to be encoded cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
for (layer_id = 0; layer_id < cpi->svc.number_spatial_layers; ++layer_id) {
if (buf->svc_params[layer_id].spatial_layer >=0)
break;
}
if (layer_id == cpi->svc.number_spatial_layers)
return 1;
layer_param = &buf->svc_params[layer_id];
cpi->svc.spatial_layer_id = layer_param->spatial_layer;
cpi->svc.temporal_layer_id = layer_param->temporal_layer;
cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
cpi->svc.temporal_layer_id = 0; cpi->svc.temporal_layer_id = 0;
...@@ -286,6 +266,8 @@ static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) { ...@@ -286,6 +266,8 @@ static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) {
count >>= 1; count >>= 1;
} }
cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
cpi->lst_fb_idx = cpi->svc.spatial_layer_id; cpi->lst_fb_idx = cpi->svc.spatial_layer_id;
if (cpi->svc.spatial_layer_id == 0) if (cpi->svc.spatial_layer_id == 0)
...@@ -325,13 +307,14 @@ static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) { ...@@ -325,13 +307,14 @@ static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) {
} }
} }
if (vp9_set_size_literal(cpi, layer_param->width, layer_param->height) != 0) get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
lc->scaling_factor_num, lc->scaling_factor_den,
&width, &height);
if (vp9_set_size_literal(cpi, width, height) != 0)
return VPX_CODEC_INVALID_PARAM; return VPX_CODEC_INVALID_PARAM;
cpi->oxcf.worst_allowed_q = cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q);
vp9_quantizer_to_qindex(layer_param->max_quantizer); cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
cpi->oxcf.best_allowed_q =
vp9_quantizer_to_qindex(layer_param->min_quantizer);
vp9_change_config(cpi, &cpi->oxcf); vp9_change_config(cpi, &cpi->oxcf);
...@@ -342,29 +325,15 @@ static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) { ...@@ -342,29 +325,15 @@ static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) {
return 0; return 0;
} }
struct lookahead_entry *vp9_svc_lookahead_peek(VP9_COMP *const cpi,
struct lookahead_ctx *ctx,
int index, int copy_params) {
struct lookahead_entry *buf = vp9_lookahead_peek(ctx, index);
if (buf != NULL && copy_params != 0) {
if (copy_svc_params(cpi, buf) != 0)
return NULL;
}
return buf;
}
struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi, struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi,
struct lookahead_ctx *ctx, struct lookahead_ctx *ctx,
int drain) { int drain) {
struct lookahead_entry *buf = NULL; struct lookahead_entry *buf = NULL;
if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
buf = vp9_svc_lookahead_peek(cpi, ctx, 0, 1); buf = vp9_lookahead_peek(ctx, 0);
if (buf != NULL) { if (buf != NULL) {
// Only remove the buffer when pop the highest layer. Simply set the // Only remove the buffer when pop the highest layer.
// spatial_layer to -1 for lower layers.
buf->svc_params[cpi->svc.spatial_layer_id].spatial_layer = -1;
if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
vp9_lookahead_pop(ctx, drain); vp9_lookahead_pop(ctx, drain);
} }
......
...@@ -24,13 +24,16 @@ typedef struct { ...@@ -24,13 +24,16 @@ typedef struct {
int target_bandwidth; int target_bandwidth;
double framerate; double framerate;
int avg_frame_size; int avg_frame_size;
int max_q;
int min_q;
int scaling_factor_num;
int scaling_factor_den;
TWO_PASS twopass; TWO_PASS twopass;
vpx_fixed_buf_t rc_twopass_stats_in; vpx_fixed_buf_t rc_twopass_stats_in;
unsigned int current_video_frame_in_layer; unsigned int current_video_frame_in_layer;
int is_key_frame; int is_key_frame;
int frames_from_key_frame; int frames_from_key_frame;
FRAME_TYPE last_frame_type; FRAME_TYPE last_frame_type;
vpx_svc_parameters_t svc_params_received;
struct lookahead_entry *alt_ref_source; struct lookahead_entry *alt_ref_source;
int alt_ref_idx; int alt_ref_idx;
int gold_ref_idx; int gold_ref_idx;
...@@ -45,6 +48,8 @@ typedef struct { ...@@ -45,6 +48,8 @@ typedef struct {
int number_spatial_layers; int number_spatial_layers;
int number_temporal_layers; int number_temporal_layers;
int spatial_layer_to_encode;
// Store scaled source frames to be used for temporal filter to generate // Store scaled source frames to be used for temporal filter to generate
// a alt ref frame. // a alt ref frame.
YV12_BUFFER_CONFIG scaled_frames[MAX_LAG_BUFFERS]; YV12_BUFFER_CONFIG scaled_frames[MAX_LAG_BUFFERS];
...@@ -88,22 +93,13 @@ void vp9_inc_frame_in_layer(struct VP9_COMP *const cpi); ...@@ -88,22 +93,13 @@ void vp9_inc_frame_in_layer(struct VP9_COMP *const cpi);
// Check if current layer is key frame in spatial upper layer // Check if current layer is key frame in spatial upper layer
int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi); int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi);
// Copy the source image, flags and svc parameters into a new framebuffer
// with the expected stride/border
int vp9_svc_lookahead_push(const struct VP9_COMP *const cpi,
struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
int64_t ts_start, int64_t ts_end,
unsigned int flags);
// Get the next source buffer to encode // Get the next source buffer to encode
struct lookahead_entry *vp9_svc_lookahead_pop(struct VP9_COMP *const cpi, struct lookahead_entry *vp9_svc_lookahead_pop(struct VP9_COMP *const cpi,
struct lookahead_ctx *ctx, struct lookahead_ctx *ctx,
int drain); int drain);
// Get a future source buffer to encode // Start a frame and initialize svc parameters
struct lookahead_entry *vp9_svc_lookahead_peek(struct VP9_COMP *const cpi, int vp9_svc_start_frame(struct VP9_COMP *const cpi);
struct lookahead_ctx *ctx,
int index, int copy_params);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
......
...@@ -1198,22 +1198,18 @@ static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, ...@@ -1198,22 +1198,18 @@ static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx,
static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
va_list args) { va_list args) {
VP9_COMP *const cpi = ctx->cpi; VP9_COMP *const cpi = ctx->cpi;
vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *); vpx_svc_extra_cfg_t *const params = va_arg(args, vpx_svc_extra_cfg_t *);
int i;
if (params == NULL || params->spatial_layer < 0 || for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
params->spatial_layer >= cpi->svc.number_spatial_layers) LAYER_CONTEXT *lc = &cpi->svc.layer_context[i];
return VPX_CODEC_INVALID_PARAM;
if (params->spatial_layer == 0) { lc->max_q = params->max_quantizers[i];
int i; lc->min_q = params->min_quantizers[i];
for (i = 0; i < cpi->svc.number_spatial_layers; ++i) { lc->scaling_factor_num = params->scaling_factor_num[i];
cpi->svc.layer_context[i].svc_params_received.spatial_layer = -1; lc->scaling_factor_den = params->scaling_factor_den[i];
}
} }
cpi->svc.layer_context[params->spatial_layer].svc_params_received =
*params;
return VPX_CODEC_OK; return VPX_CODEC_OK;
} }
......
...@@ -12,4 +12,3 @@ text vpx_svc_get_message ...@@ -12,4 +12,3 @@ text vpx_svc_get_message
text vpx_svc_init text vpx_svc_init
text vpx_svc_release text vpx_svc_release
text vpx_svc_set_options text vpx_svc_set_options
text vpx_svc_get_layer_resolution
...@@ -85,10 +85,7 @@ typedef struct SvcInternal { ...@@ -85,10 +85,7 @@ typedef struct SvcInternal {
char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options
// values extracted from option, quantizers // values extracted from option, quantizers
int scaling_factor_num[VPX_SS_MAX_LAYERS]; vpx_svc_extra_cfg_t svc_params;
int scaling_factor_den[VPX_SS_MAX_LAYERS];
int max_quantizers[VPX_SS_MAX_LAYERS];
int min_quantizers[VPX_SS_MAX_LAYERS];
int enable_auto_alt_ref[VPX_SS_MAX_LAYERS]; int enable_auto_alt_ref[VPX_SS_MAX_LAYERS];
int bitrates[VPX_SS_MAX_LAYERS]; int bitrates[VPX_SS_MAX_LAYERS];
...@@ -174,7 +171,8 @@ static vpx_codec_err_t extract_option(LAYER_OPTION_TYPE type, ...@@ -174,7 +171,8 @@ static vpx_codec_err_t extract_option(LAYER_OPTION_TYPE type,
if (*value0 < option_min_values[SCALE_FACTOR] || if (*value0 < option_min_values[SCALE_FACTOR] ||
*value1 < option_min_values[SCALE_FACTOR] || *value1 < option_min_values[SCALE_FACTOR] ||
*value0 > option_max_values[SCALE_FACTOR] || *value0 > option_max_values[SCALE_FACTOR] ||
*value1 > option_max_values[SCALE_FACTOR]) *value1 > option_max_values[SCALE_FACTOR] ||
*value0 > *value1) // num shouldn't be greater than den
return VPX_CODEC_INVALID_PARAM; return VPX_CODEC_INVALID_PARAM;
} else { } else {
*value0 = atoi(input); *value0 = atoi(input);
...@@ -259,16 +257,18 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { ...@@ -259,16 +257,18 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
svc_ctx->temporal_layers = atoi(option_value); svc_ctx->temporal_layers = atoi(option_value);
} else if (strcmp("scale-factors", option_name) == 0) { } else if (strcmp("scale-factors", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, SCALE_FACTOR, option_value, res = parse_layer_options_from_string(svc_ctx, SCALE_FACTOR, option_value,
si->scaling_factor_num, si->svc_params.scaling_factor_num,
si->scaling_factor_den); si->svc_params.scaling_factor_den);
if (res != VPX_CODEC_OK) break; if (res != VPX_CODEC_OK) break;
} else if (strcmp("max-quantizers", option_name) == 0) { } else if (strcmp("max-quantizers", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value,
si->max_quantizers, NULL); si->svc_params.max_quantizers,
NULL);
if (res != VPX_CODEC_OK) break; if (res != VPX_CODEC_OK) break;
} else if (strcmp("min-quantizers", option_name) == 0) { } else if (strcmp("min-quantizers", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value,
si->min_quantizers, NULL); si->svc_params.min_quantizers,
NULL);
if (res != VPX_CODEC_OK) break; if (res != VPX_CODEC_OK) break;
} else if (strcmp("auto-alt-refs", option_name) == 0) { } else if (strcmp("auto-alt-refs", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, AUTO_ALT_REF, option_value, res = parse_layer_options_from_string(svc_ctx, AUTO_ALT_REF, option_value,
...@@ -290,9 +290,10 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { ...@@ -290,9 +290,10 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
free(input_string); free(input_string);
for (i = 0; i < svc_ctx->spatial_layers; ++i) { for (i = 0; i < svc_ctx->spatial_layers; ++i) {
if (si->max_quantizers[i] > MAX_QUANTIZER || si->max_quantizers[i] < 0 || if (si->svc_params.max_quantizers[i] > MAX_QUANTIZER ||
si->min_quantizers[i] > si->max_quantizers[i] || si->svc_params.max_quantizers[i] < 0 ||
si->min_quantizers[i] < 0) si->svc_params.min_quantizers[i] > si->svc_params.max_quantizers[i] ||
si->svc_params.min_quantizers[i] < 0)
res = VPX_CODEC_INVALID_PARAM; res = VPX_CODEC_INVALID_PARAM;
} }
...@@ -340,9 +341,9 @@ void assign_layer_bitrates(const SvcContext *svc_ctx, ...@@ -340,9 +341,9 @@ void assign_layer_bitrates(const SvcContext *svc_ctx,
float alloc_ratio[VPX_SS_MAX_LAYERS] = {0}; float alloc_ratio[VPX_SS_MAX_LAYERS] = {0};
for (i = 0; i < svc_ctx->spatial_layers; ++i) { for (i = 0; i < svc_ctx->spatial_layers; ++i) {
if (si->scaling_factor_den[i] > 0) { if (si->svc_params.scaling_factor_den[i] > 0) {
alloc_ratio[i] = (float)(si->scaling_factor_num[i] * 1.0 / alloc_ratio[i] = (float)(si->svc_params.scaling_factor_num[i] * 1.0 /
si->scaling_factor_den[i]); si->svc_params.scaling_factor_den[i]);
alloc_ratio[i] *= alloc_ratio[i]; alloc_ratio[i] *= alloc_ratio[i];
total += alloc_ratio[i]; total += alloc_ratio[i];
...@@ -392,10 +393,10 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, ...@@ -392,10 +393,10 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
} }
for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) { for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) {
si->max_quantizers[i] = MAX_QUANTIZER; si->svc_params.max_quantizers[i] = MAX_QUANTIZER;
si->min_quantizers[i] = 0; si->svc_params.min_quantizers[i] = 0;
si->scaling_factor_num[i] = DEFAULT_SCALE_FACTORS_NUM[i]; si->svc_params.scaling_factor_num[i] = DEFAULT_SCALE_FACTORS_NUM[i];
si->scaling_factor_den[i] = DEFAULT_SCALE_FACTORS_DEN[i]; si->svc_params.scaling_factor_den[i] = DEFAULT_SCALE_FACTORS_DEN[i];
} }
// Parse aggregate command line options. Options must start with // Parse aggregate command line options. Options must start with
...@@ -444,62 +445,11 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, ...@@ -444,62 +445,11 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
} }
vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1); vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1);
vpx_codec_control(codec_ctx, VP9E_SET_SVC_PARAMETERS, &si->svc_params);
return VPX_CODEC_OK; return VPX_CODEC_OK;
} }
vpx_codec_err_t vpx_svc_get_layer_resolution(const SvcContext *svc_ctx,
int layer,
unsigned int *width,
unsigned int *height) {
int w, h, num, den;
const SvcInternal *const si = get_const_svc_internal(svc_ctx);
if (svc_ctx == NULL || si == NULL || width == NULL || height == NULL)
return VPX_CODEC_INVALID_PARAM;
if (layer < 0 || layer >= svc_ctx->spatial_layers)
return VPX_CODEC_INVALID_PARAM;