vp9 svc: add simulcast mode when inter-layer pred is off.

Force all upper spatial layers to be key frame if the base layer is key.
Mode only works for inter-layer pred=off and non-flexible mode.

Add flag to write out bitstream for each spatial layer in example
encoder.

Change-Id: I5db4543cf8697544ae49464f2157e692640d5256
This commit is contained in:
Jerome Jiang
2019-03-04 15:51:22 -08:00
parent d64e328624
commit 3529526e11
7 changed files with 133 additions and 9 deletions

View File

@@ -34,6 +34,8 @@
#define OUTPUT_RC_STATS 1
#define SIMULCAST_MODE 0
static const arg_def_t outputfile =
ARG_DEF("o", "output", 1, "Output filename");
static const arg_def_t skip_frames_arg =
@@ -749,7 +751,7 @@ static void set_frame_flags_bypass_mode_ex1(
}
}
#if CONFIG_VP9_DECODER
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
static void test_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
const int frames_out, int *mismatch_seen) {
vpx_image_t enc_img, dec_img;
@@ -834,12 +836,21 @@ static void svc_output_rc_stats(
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
unsigned int sl2;
uint64_t tot_size = 0;
#if SIMULCAST_MODE
for (sl2 = 0; sl2 < sl; ++sl2) {
if (cx_pkt->data.frame.spatial_layer_encoded[sl2]) tot_size += sizes[sl2];
}
vpx_video_writer_write_frame(outfile[sl],
(uint8_t *)(cx_pkt->data.frame.buf) + tot_size,
(size_t)(sizes[sl]), cx_pkt->data.frame.pts);
#else
for (sl2 = 0; sl2 <= sl; ++sl2) {
if (cx_pkt->data.frame.spatial_layer_encoded[sl2]) tot_size += sizes[sl2];
}
if (tot_size > 0)
vpx_video_writer_write_frame(outfile[sl], cx_pkt->data.frame.buf,
(size_t)(tot_size), cx_pkt->data.frame.pts);
#endif // SIMULCAST_MODE
}
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
@@ -924,7 +935,7 @@ int main(int argc, const char **argv) {
#if CONFIG_INTERNAL_STATS
FILE *f = fopen("opsnr.stt", "a");
#endif
#if CONFIG_VP9_DECODER
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
int mismatch_seen = 0;
vpx_codec_ctx_t decoder;
#endif
@@ -964,7 +975,7 @@ int main(int argc, const char **argv) {
if (vpx_svc_init(&svc_ctx, &encoder, vpx_codec_vp9_cx(), &enc_cfg) !=
VPX_CODEC_OK)
die("Failed to initialize encoder\n");
#if CONFIG_VP9_DECODER
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
if (vpx_codec_dec_init(
&decoder, get_vpx_decoder_by_name("vp9")->codec_interface(), NULL, 0))
die("Failed to initialize decoder\n");
@@ -1163,7 +1174,7 @@ int main(int argc, const char **argv) {
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;
#if CONFIG_VP9_DECODER
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
if (vpx_codec_decode(&decoder, cx_pkt->data.frame.buf,
(unsigned int)cx_pkt->data.frame.sz, NULL, 0))
die_codec(&decoder, "Failed to decode frame.");
@@ -1178,7 +1189,7 @@ int main(int argc, const char **argv) {
default: { break; }
}
#if CONFIG_VP9_DECODER
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
vpx_codec_control(&encoder, VP9E_GET_SVC_LAYER_ID, &layer_id);
// Don't look for mismatch on top spatial and top temporal layers as they
// are non reference frames.