Merge "[spatial svc] Remove encoding modes since we only need one mode at this time."
This commit is contained in:
Коммит
83269ff8ff
|
@ -28,16 +28,6 @@
|
|||
#include "vpx/vpx_encoder.h"
|
||||
#include "./vpxstats.h"
|
||||
|
||||
static const struct arg_enum_list encoding_mode_enum[] = {
|
||||
{"i", INTER_LAYER_PREDICTION_I},
|
||||
{"alt-ip", ALT_INTER_LAYER_PREDICTION_IP},
|
||||
{"ip", INTER_LAYER_PREDICTION_IP},
|
||||
{"gf", USE_GOLDEN_FRAME},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static const arg_def_t encoding_mode_arg = ARG_DEF_ENUM(
|
||||
"m", "encoding-mode", 1, "Encoding mode algorithm", encoding_mode_enum);
|
||||
static const arg_def_t skip_frames_arg =
|
||||
ARG_DEF("s", "skip-frames", 1, "input frames to skip");
|
||||
static const arg_def_t frames_arg =
|
||||
|
@ -74,15 +64,13 @@ static const arg_def_t max_bitrate_arg =
|
|||
ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
|
||||
|
||||
static const arg_def_t *svc_args[] = {
|
||||
&encoding_mode_arg, &frames_arg, &width_arg, &height_arg,
|
||||
&frames_arg, &width_arg, &height_arg,
|
||||
&timebase_arg, &bitrate_arg, &skip_frames_arg, &layers_arg,
|
||||
&kf_dist_arg, &scale_factors_arg, &quantizers_arg, &passes_arg,
|
||||
&pass_arg, &fpf_name_arg, &min_q_arg, &max_q_arg,
|
||||
&min_bitrate_arg, &max_bitrate_arg, NULL
|
||||
};
|
||||
|
||||
static const SVC_ENCODING_MODE default_encoding_mode =
|
||||
INTER_LAYER_PREDICTION_IP;
|
||||
static const uint32_t default_frames_to_skip = 0;
|
||||
static const uint32_t default_frames_to_code = 60 * 60;
|
||||
static const uint32_t default_width = 1920;
|
||||
|
@ -131,7 +119,6 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
// initialize SvcContext with parameters that will be passed to vpx_svc_init
|
||||
svc_ctx->log_level = SVC_LOG_DEBUG;
|
||||
svc_ctx->spatial_layers = default_spatial_layers;
|
||||
svc_ctx->encoding_mode = default_encoding_mode;
|
||||
|
||||
// start with default encoder configuration
|
||||
res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
|
||||
|
@ -157,9 +144,7 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
|
||||
arg.argv_step = 1;
|
||||
|
||||
if (arg_match(&arg, &encoding_mode_arg, argi)) {
|
||||
svc_ctx->encoding_mode = arg_parse_enum_or_int(&arg);
|
||||
} else if (arg_match(&arg, &frames_arg, argi)) {
|
||||
if (arg_match(&arg, &frames_arg, argi)) {
|
||||
app_input->frames_to_code = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &width_arg, argi)) {
|
||||
enc_cfg->g_w = arg_parse_uint(&arg);
|
||||
|
@ -264,12 +249,12 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
|
||||
printf(
|
||||
"Codec %s\nframes: %d, skip: %d\n"
|
||||
"mode: %d, layers: %d\n"
|
||||
"layers: %d\n"
|
||||
"width %d, height: %d,\n"
|
||||
"num: %d, den: %d, bitrate: %d,\n"
|
||||
"gop size: %d\n",
|
||||
vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
|
||||
app_input->frames_to_skip, svc_ctx->encoding_mode,
|
||||
app_input->frames_to_skip,
|
||||
svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h,
|
||||
enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
|
||||
enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
|
||||
|
|
|
@ -41,7 +41,6 @@ class SvcTest : public ::testing::Test {
|
|||
virtual ~SvcTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
svc_.encoding_mode = INTER_LAYER_PREDICTION_IP;
|
||||
svc_.log_level = SVC_LOG_DEBUG;
|
||||
svc_.log_print = 0;
|
||||
|
||||
|
@ -131,22 +130,13 @@ TEST_F(SvcTest, SetLayersOption) {
|
|||
EXPECT_EQ(3, svc_.spatial_layers);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetEncodingMode) {
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "encoding-mode=alt-ip");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
codec_initialized_ = true;
|
||||
EXPECT_EQ(ALT_INTER_LAYER_PREDICTION_IP, svc_.encoding_mode);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetMultipleOptions) {
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "layers=2 encoding-mode=ip");
|
||||
vpx_codec_err_t res =
|
||||
vpx_svc_set_options(&svc_, "layers=2 scale-factors=1/3,2/3");
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
codec_initialized_ = true;
|
||||
EXPECT_EQ(2, svc_.spatial_layers);
|
||||
EXPECT_EQ(INTER_LAYER_PREDICTION_IP, svc_.encoding_mode);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetScaleFactorsOption) {
|
||||
|
|
|
@ -194,23 +194,6 @@ static int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level,
|
|||
return retval;
|
||||
}
|
||||
|
||||
static vpx_codec_err_t set_option_encoding_mode(SvcContext *svc_ctx,
|
||||
const char *value_str) {
|
||||
if (strcmp(value_str, "i") == 0) {
|
||||
svc_ctx->encoding_mode = INTER_LAYER_PREDICTION_I;
|
||||
} else if (strcmp(value_str, "alt-ip") == 0) {
|
||||
svc_ctx->encoding_mode = ALT_INTER_LAYER_PREDICTION_IP;
|
||||
} else if (strcmp(value_str, "ip") == 0) {
|
||||
svc_ctx->encoding_mode = INTER_LAYER_PREDICTION_IP;
|
||||
} else if (strcmp(value_str, "gf") == 0) {
|
||||
svc_ctx->encoding_mode = USE_GOLDEN_FRAME;
|
||||
} else {
|
||||
svc_log(svc_ctx, SVC_LOG_ERROR, "invalid encoding mode: %s", value_str);
|
||||
return VPX_CODEC_INVALID_PARAM;
|
||||
}
|
||||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
static vpx_codec_err_t parse_quantizer_values(SvcContext *svc_ctx,
|
||||
const char *quantizer_values) {
|
||||
char *input_string;
|
||||
|
@ -344,10 +327,7 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
|
|||
res = VPX_CODEC_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
if (strcmp("encoding-mode", option_name) == 0) {
|
||||
res = set_option_encoding_mode(svc_ctx, option_value);
|
||||
if (res != VPX_CODEC_OK) break;
|
||||
} else if (strcmp("layers", option_name) == 0) {
|
||||
if (strcmp("layers", option_name) == 0) {
|
||||
svc_ctx->spatial_layers = atoi(option_value);
|
||||
} else if (strcmp("scale-factors", option_name) == 0) {
|
||||
res = parse_scale_factors(svc_ctx, option_value);
|
||||
|
@ -591,62 +571,14 @@ static void calculate_enc_frame_flags(SvcContext *svc_ctx) {
|
|||
return;
|
||||
}
|
||||
|
||||
switch (svc_ctx->encoding_mode) {
|
||||
case ALT_INTER_LAYER_PREDICTION_IP:
|
||||
if (si->layer == 0) {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
} else if (is_keyframe) {
|
||||
if (si->layer == si->layers - 1) {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST | UPDATE_GF);
|
||||
}
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_LAST | USE_ARF | UPDATE_LAST);
|
||||
}
|
||||
break;
|
||||
case INTER_LAYER_PREDICTION_I:
|
||||
if (si->layer == 0) {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
} else if (is_keyframe) {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
}
|
||||
break;
|
||||
case INTER_LAYER_PREDICTION_IP:
|
||||
if (si->layer == 0) {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
} else if (is_keyframe) {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_LAST | USE_ARF | UPDATE_LAST);
|
||||
}
|
||||
break;
|
||||
case USE_GOLDEN_FRAME:
|
||||
if (2 * si->layers - SVC_REFERENCE_FRAMES <= si->layer) {
|
||||
if (si->layer == 0) {
|
||||
flags = map_vp8_flags(USE_LAST | USE_GF | UPDATE_LAST);
|
||||
} else if (is_keyframe) {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST | UPDATE_GF);
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_LAST | USE_ARF | USE_GF | UPDATE_LAST);
|
||||
}
|
||||
} else {
|
||||
if (si->layer == 0) {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
} else if (is_keyframe) {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
svc_log(svc_ctx, SVC_LOG_ERROR, "unexpected encoding mode: %d\n",
|
||||
svc_ctx->encoding_mode);
|
||||
break;
|
||||
if (si->layer == 0) {
|
||||
flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
|
||||
} else if (is_keyframe) {
|
||||
flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
|
||||
} else {
|
||||
flags = map_vp8_flags(USE_LAST | USE_ARF | UPDATE_LAST);
|
||||
}
|
||||
|
||||
si->enc_frame_flags = flags;
|
||||
}
|
||||
|
||||
|
@ -692,13 +624,6 @@ static void set_svc_parameters(SvcContext *svc_ctx,
|
|||
svc_params.flags = si->enc_frame_flags;
|
||||
|
||||
layer = si->layer;
|
||||
if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
|
||||
si->frame_within_gop == 0) {
|
||||
// layers 1 & 3 don't exist in this mode, use the higher one
|
||||
if (layer == 0 || layer == 2) {
|
||||
layer += 1;
|
||||
}
|
||||
}
|
||||
if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(svc_ctx, layer,
|
||||
&svc_params.width,
|
||||
&svc_params.height)) {
|
||||
|
@ -720,21 +645,8 @@ static void set_svc_parameters(SvcContext *svc_ctx,
|
|||
svc_params.lst_fb_idx = si->layer;
|
||||
|
||||
// Use buffer i-1 for layer i Alt (Inter-layer prediction)
|
||||
if (si->layer != 0) {
|
||||
const int use_higher_layer =
|
||||
svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
|
||||
si->frame_within_gop == 0;
|
||||
svc_params.alt_fb_idx = use_higher_layer ? si->layer - 2 : si->layer - 1;
|
||||
}
|
||||
|
||||
if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP) {
|
||||
svc_params.gld_fb_idx = si->layer + 1;
|
||||
} else {
|
||||
if (si->layer < 2 * si->layers - SVC_REFERENCE_FRAMES)
|
||||
svc_params.gld_fb_idx = svc_params.lst_fb_idx;
|
||||
else
|
||||
svc_params.gld_fb_idx = 2 * si->layers - 1 - si->layer;
|
||||
}
|
||||
svc_params.alt_fb_idx = (si->layer > 0) ? si->layer - 1 : 0;
|
||||
svc_params.gld_fb_idx = svc_params.lst_fb_idx;
|
||||
|
||||
svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, layer: %d, %dx%d, q: %d\n",
|
||||
si->encode_frame_count, si->layer, svc_params.width,
|
||||
|
@ -793,11 +705,6 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
if (rawimg != NULL) {
|
||||
// encode each layer
|
||||
for (si->layer = 0; si->layer < si->layers; ++si->layer) {
|
||||
if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
|
||||
si->is_keyframe && (si->layer == 1 || si->layer == 3)) {
|
||||
svc_log(svc_ctx, SVC_LOG_DEBUG, "Skip encoding layer %d\n", si->layer);
|
||||
continue;
|
||||
}
|
||||
calculate_enc_frame_flags(svc_ctx);
|
||||
set_svc_parameters(svc_ctx, codec_ctx);
|
||||
}
|
||||
|
@ -936,7 +843,7 @@ static double calc_psnr(double d) {
|
|||
|
||||
// dump accumulated statistics and reset accumulated values
|
||||
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
|
||||
int number_of_frames, number_of_keyframes, encode_frame_count;
|
||||
int number_of_frames, encode_frame_count;
|
||||
int i, j;
|
||||
uint32_t bytes_total = 0;
|
||||
double scale[COMPONENTS];
|
||||
|
@ -953,14 +860,9 @@ const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
|
|||
if (si->encode_frame_count <= 0) return vpx_svc_get_message(svc_ctx);
|
||||
|
||||
svc_log(svc_ctx, SVC_LOG_INFO, "\n");
|
||||
number_of_keyframes = encode_frame_count / si->kf_dist + 1;
|
||||
for (i = 0; i < si->layers; ++i) {
|
||||
number_of_frames = encode_frame_count;
|
||||
|
||||
if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
|
||||
(i == 1 || i == 3)) {
|
||||
number_of_frames -= number_of_keyframes;
|
||||
}
|
||||
svc_log(svc_ctx, SVC_LOG_INFO,
|
||||
"Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n",
|
||||
i, (double)si->psnr_sum[i][0] / number_of_frames,
|
||||
|
|
|
@ -23,13 +23,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum SVC_ENCODING_MODE {
|
||||
INTER_LAYER_PREDICTION_I,
|
||||
ALT_INTER_LAYER_PREDICTION_IP,
|
||||
INTER_LAYER_PREDICTION_IP,
|
||||
USE_GOLDEN_FRAME
|
||||
} SVC_ENCODING_MODE;
|
||||
|
||||
typedef enum SVC_LOG_LEVEL {
|
||||
SVC_LOG_ERROR,
|
||||
SVC_LOG_INFO,
|
||||
|
@ -39,7 +32,6 @@ typedef enum SVC_LOG_LEVEL {
|
|||
typedef struct {
|
||||
// public interface to svc_command options
|
||||
int spatial_layers; // number of layers
|
||||
SVC_ENCODING_MODE encoding_mode; // svc encoding strategy
|
||||
SVC_LOG_LEVEL log_level; // amount of information to display
|
||||
int log_print; // when set, printf log messages instead of returning the
|
||||
// message with svc_get_message
|
||||
|
|
Загрузка…
Ссылка в новой задаче