1b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian/* 2b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * 4b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 5b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 6b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 7b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 8b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 9b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian */ 10b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 11b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This is an example demonstrating how to implement a multi-layer VP9 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// encoding scheme based on temporal scalability for video applications 13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// that benefit from a scalable bitstream. 14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <math.h> 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h> 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdlib.h> 18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <string.h> 19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define VPX_CODEC_DISABLE_COMPAT 1 21a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include "./vpx_config.h" 22a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include "vpx_ports/vpx_timer.h" 23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vp8cx.h" 24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vpx_encoder.h" 25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./tools_common.h" 27b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./video_writer.h" 28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 29b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const char *exec_name; 30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid usage_exit() { 32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exit(EXIT_FAILURE); 33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 34b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 35b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3}; 36b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 37b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// For rate control encoding stats. 38b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstruct RateControlMetrics { 39b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Number of input frames per layer. 40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int layer_input_frames[VPX_TS_MAX_LAYERS]; 41b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Total (cumulative) number of encoded frames per layer. 42b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int layer_tot_enc_frames[VPX_TS_MAX_LAYERS]; 43b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Number of encoded non-key frames per layer. 44b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int layer_enc_frames[VPX_TS_MAX_LAYERS]; 45b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Framerate per layer layer (cumulative). 46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian double layer_framerate[VPX_TS_MAX_LAYERS]; 47b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Target average frame size per layer (per-frame-bandwidth per layer). 48b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian double layer_pfb[VPX_TS_MAX_LAYERS]; 49b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Actual average frame size per layer. 50b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian double layer_avg_frame_size[VPX_TS_MAX_LAYERS]; 51b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Average rate mismatch per layer (|target - actual| / target). 52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; 53b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Actual encoding bitrate per layer (cumulative). 54b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian double layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; 55b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}; 56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Note: these rate control metrics assume only 1 key frame in the 58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// sequence (i.e., first frame only). So for temporal pattern# 7 59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// (which has key frame for every frame on base layer), the metrics 60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// computation will be off/wrong. 61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// TODO(marpan): Update these metrics to account for multiple key frames 62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// in the stream. 63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void set_rate_control_metrics(struct RateControlMetrics *rc, 64b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_enc_cfg_t *cfg) { 65b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int i = 0; 66b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Set the layer (cumulative) framerate and the target layer (non-cumulative) 67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // per-frame-bandwidth, for the rate control encoding stats below. 68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; 69b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; 70b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] / 71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_framerate[0]; 72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = 0; i < cfg->ts_number_layers; ++i) { 73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (i > 0) { 74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; 75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_pfb[i] = 1000.0 * 76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) / 77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); 78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_input_frames[i] = 0; 80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_enc_frames[i] = 0; 81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_tot_enc_frames[i] = 0; 82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_encoding_bitrate[i] = 0.0; 83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_avg_frame_size[i] = 0.0; 84b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_avg_rate_mismatch[i] = 0.0; 85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void printout_rate_control_summary(struct RateControlMetrics *rc, 89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_enc_cfg_t *cfg, 90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_cnt) { 91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int i = 0; 92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int tot_num_frames = 0; 93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Total number of processed frames: %d\n\n", frame_cnt -1); 94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Rate control layer stats for %d layer(s):\n\n", 95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers); 96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = 0; i < cfg->ts_number_layers; ++i) { 97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const int num_dropped = (i > 0) ? 98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : 99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); 100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian tot_num_frames += rc->layer_input_frames[i]; 101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * 102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_encoding_bitrate[i] / tot_num_frames; 103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / 104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_enc_frames[i]; 105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / 106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_enc_frames[i]; 107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("For layer#: %d \n", i); 108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i], 109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_encoding_bitrate[i]); 110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], 111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_avg_frame_size[i]); 112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); 113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Number of input frames, encoded (non-key) frames, " 114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], 115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc->layer_enc_frames[i], 116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 100.0 * num_dropped / rc->layer_input_frames[i]); 117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("\n"); 118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if ((frame_cnt - 1) != tot_num_frames) 120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Error: Number of input frames not equal to output! \n"); 121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Temporal scaling parameters: 124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// NOTE: The 3 prediction frames cannot be used interchangeably due to 125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// differences in the way they are handled throughout the code. The 126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frames should be allocated to layers in the order LAST, GF, ARF. 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Other combinations work, but may produce slightly inferior results. 128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void set_temporal_layer_pattern(int layering_mode, 129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_enc_cfg_t *cfg, 130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int *layer_flags, 131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int *flag_periodicity) { 132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian switch (layering_mode) { 133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 0: { 134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 1-layer. 135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[1] = {0}; 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 1; 137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 1; 138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 1; 139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 1; 140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Update L only. 142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | 143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 1: { 147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 2-layers, 2-frame period. 148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[2] = {0, 1}; 149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 2; 150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 2; 151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 2; 152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 2; 153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 1; 154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if 1 156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, Intra-layer prediction enabled. 157b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | 158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF; 159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | 160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF; 161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#else 162b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, Intra-layer prediction disabled. 163b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | 164b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF; 165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | 166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST; 167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif 168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 2: { 171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 2-layers, 3-frame period. 172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[3] = {0, 1, 1}; 173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 3; 174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 3; 175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 2; 176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 3; 177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 1; 178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, Intra-layer prediction enabled. 180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = 183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | 184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 3: { 188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers, 6-frame period. 189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[6] = {0, 2, 2, 1, 2, 2}; 190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 6; 191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 6; 192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 6; 194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 3; 195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled. 198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | 201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_LAST; 202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = 203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = 204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[4] = 205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; 206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 4: { 209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers, 4-frame period. 210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[4] = {0, 2, 1, 2}; 211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 4; 212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 4; 213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 4; 215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 2; 216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled. 219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | 222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = 224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | 225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 5: { 229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers, 4-frame period. 230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[4] = {0, 2, 1, 2}; 231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 4; 232b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 4; 233b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 234b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 4; 235b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 2; 236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled 239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // in layer 2. 240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | 243b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = 245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | 246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 6: { 250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers, 4-frame period. 251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[4] = {0, 2, 1, 2}; 252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 4; 253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 4; 254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 4; 256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 2; 257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled. 260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | 263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = 265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; 266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 268b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 7: { 269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // NOTE: Probably of academic interest only. 270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 5-layers, 16-frame period. 271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[16] = {0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4}; 272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 16; 273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 16; 274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 5; 275b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 16; 276b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 8; 277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 4; 278b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[3] = 2; 279b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[4] = 1; 280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF; 282b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = 283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = 284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[5] = 285b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[7] = 286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[9] = 287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[11] = 288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[13] = 289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[15] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | 290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 291b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = 292b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[6] = 293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[10] = 294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF; 295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[4] = 296b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[12] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF; 297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF; 298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 8: { 301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 2-layers, with sync point at first frame of layer 1. 302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[2] = {0, 1}; 303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 2; 304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 8; 305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 2; 306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 2; 307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 1; 308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF. 310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // ARF is used as predictor for all frames, and is only updated on 311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // key frame. Sync point every 8 frames. 312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0: predict from L and ARF, update L and G. 314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1: sync point: predict from L and ARF, and update G. 317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | 318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0, predict from L and ARF, update L. 320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | 321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1: predict from L, G and ARF, and update G. 323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | 324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ENTROPY; 325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0. 326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[4] = layer_flags[2]; 327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1. 328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[5] = layer_flags[3]; 329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0. 330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[6] = layer_flags[4]; 331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1. 332b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[7] = layer_flags[5]; 333b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 9: { 336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers: Sync points for layer 1 and 2 every 8 frames. 337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[4] = {0, 2, 1, 2}; 338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 4; 339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 8; 340b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 4; 342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 2; 343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF. 346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | 347b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | 349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; 350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | 351b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; 352b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = 353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; 354b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | 355b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[6] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | 357b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF; 358b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | 359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY; 360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 361b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 362b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 10: { 363b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers structure where ARF is used as predictor for all frames, 364b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // and is only updated on key frame. 365b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Sync points for layer 1 and 2 every 8 frames. 366b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[4] = {0, 2, 1, 2}; 368b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 4; 369b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 8; 370b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 371b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 4; 372b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 2; 373b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 374b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 375b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF. 376b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0: predict from L and ARF; update L and G. 377b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF | 378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_GF; 379b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 2: sync point: predict from L and ARF; update none. 380b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | 381b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | 382b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ENTROPY; 383b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1: sync point: predict from L and ARF; update G. 384b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | 385b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_LAST; 386b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 2: predict from L, G, ARF; update none. 387b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 388b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY; 389b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0: predict from L and ARF; update L. 390b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[4] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 391b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_GF; 392b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 2: predict from L, G, ARF; update none. 393b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[5] = layer_flags[3]; 394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1: predict from L, G, ARF; update G. 395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 2: predict from L, G, ARF; update none. 397b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[7] = layer_flags[3]; 398b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 399b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 400b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 11: 401b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian default: { 402b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 3-layers structure as in case 10, but no sync/refresh points for 403b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // layer 1 and 2. 404b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int ids[4] = {0, 2, 1, 2}; 405b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_periodicity = 4; 406b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *flag_periodicity = 8; 407b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_number_layers = 3; 408b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[0] = 4; 409b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[1] = 2; 410b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg->ts_rate_decimator[2] = 1; 411b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(cfg->ts_layer_id, ids, sizeof(ids)); 412b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // 0=L, 1=GF, 2=ARF. 413b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 0: predict from L and ARF; update L. 414b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 415b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_GF; 416b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[4] = layer_flags[0]; 417b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 1: predict from L, G, ARF; update G. 418b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 419b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[6] = layer_flags[2]; 420b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Layer 2: predict from L, G, ARF; update none. 421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[1] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 422b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY; 423b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[3] = layer_flags[1]; 424b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[5] = layer_flags[1]; 425b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[7] = layer_flags[1]; 426b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 427b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 428b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 429b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 430b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 431b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint main(int argc, char **argv) { 432b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS]; 433b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 434b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_enc_cfg_t cfg; 435b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_cnt = 0; 436b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_image_t raw; 437b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_err_t res; 438b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int width; 439b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int height; 4406ac915abcdb404a00d927fe6308a47fcf09d9519hkuang int speed; 441b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_avail; 442b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int got_data; 443b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int flags = 0; 444b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int i; 445b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int pts = 0; // PTS starts at 0. 446b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_duration = 1; // 1 timebase tick per frame. 447b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int layering_mode = 0; 448b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int layer_flags[VPX_TS_MAX_PERIODICITY] = {0}; 449b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int flag_periodicity = 1; 450b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int max_intra_size_pct; 451b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_svc_layer_id_t layer_id = {0, 0}; 452b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const VpxInterface *encoder = NULL; 453b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian FILE *infile = NULL; 454b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct RateControlMetrics rc; 455a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64_t cx_time = 0; 456b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 457b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exec_name = argv[0]; 458b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Check usage and arguments. 459b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (argc < 11) { 460b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " 4616ac915abcdb404a00d927fe6308a47fcf09d9519hkuang "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> " 462b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian "<Rate_0> ... <Rate_nlayers-1> \n", argv[0]); 463b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 464b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 465b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian encoder = get_vpx_encoder_by_name(argv[3]); 466b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!encoder) 467b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Unsupported codec."); 468b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 469b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Using %s\n", vpx_codec_iface_name(encoder->interface())); 470b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 471b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian width = strtol(argv[4], NULL, 0); 472b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian height = strtol(argv[5], NULL, 0); 473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (width < 16 || width % 2 || height < 16 || height % 2) { 474b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Invalid resolution: %d x %d", width, height); 475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 476b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4776ac915abcdb404a00d927fe6308a47fcf09d9519hkuang layering_mode = strtol(argv[10], NULL, 0); 478b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (layering_mode < 0 || layering_mode > 12) { 4796ac915abcdb404a00d927fe6308a47fcf09d9519hkuang die("Invalid layering mode (0..12) %s", argv[10]); 480b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 481b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (argc != 11 + mode_to_num_layers[layering_mode]) { 483b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Invalid number of arguments"); 484b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 485b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 486b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) { 487b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to allocate image", width, height); 488b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 489b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 490b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Populate encoder configuration. 491b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0); 492b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (res) { 493b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); 494b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return EXIT_FAILURE; 495b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 496b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 497b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Update the default configuration with our settings. 498b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_w = width; 499b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_h = height; 500b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 501b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Timebase format e.g. 30fps: numerator=1, demoninator = 30. 502b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_timebase.num = strtol(argv[6], NULL, 0); 503b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_timebase.den = strtol(argv[7], NULL, 0); 504b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 5056ac915abcdb404a00d927fe6308a47fcf09d9519hkuang speed = strtol(argv[8], NULL, 0); 5066ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (speed < 0) { 5076ac915abcdb404a00d927fe6308a47fcf09d9519hkuang die("Invalid speed setting: must be positive"); 5086ac915abcdb404a00d927fe6308a47fcf09d9519hkuang } 5096ac915abcdb404a00d927fe6308a47fcf09d9519hkuang 5106ac915abcdb404a00d927fe6308a47fcf09d9519hkuang for (i = 11; (int)i < 11 + mode_to_num_layers[layering_mode]; ++i) { 5116ac915abcdb404a00d927fe6308a47fcf09d9519hkuang cfg.ts_target_bitrate[i - 11] = strtol(argv[i], NULL, 0); 512b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 513b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 514b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Real time parameters. 5156ac915abcdb404a00d927fe6308a47fcf09d9519hkuang cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0); 516b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_end_usage = VPX_CBR; 517b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_resize_allowed = 0; 518b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_min_quantizer = 2; 519b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_max_quantizer = 56; 520b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_undershoot_pct = 50; 521b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_overshoot_pct = 50; 522b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_buf_initial_sz = 500; 523b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_buf_optimal_sz = 600; 524b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_buf_sz = 1000; 525b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 526b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Enable error resilient mode. 527b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_error_resilient = 1; 528b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_lag_in_frames = 0; 529b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.kf_mode = VPX_KF_DISABLED; 530b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 531b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Disable automatic keyframe placement. 532b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.kf_min_dist = cfg.kf_max_dist = 3000; 533b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 534b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian set_temporal_layer_pattern(layering_mode, 535b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian &cfg, 536b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags, 537b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian &flag_periodicity); 538b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 539b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian set_rate_control_metrics(&rc, &cfg); 540b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 541b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Target bandwidth for the whole stream. 542b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Set to ts_target_bitrate for highest layer (total bitrate). 543b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1]; 544b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 545b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Open input file. 546b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!(infile = fopen(argv[1], "rb"))) { 547b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for reading", argv[1]); 548b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 549b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 550b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Open an output file for each stream. 551b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = 0; i < cfg.ts_number_layers; ++i) { 552b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian char file_name[PATH_MAX]; 553b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoInfo info; 554b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.codec_fourcc = encoder->fourcc; 555b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.frame_width = cfg.g_w; 556b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.frame_height = cfg.g_h; 557b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.time_base.numerator = cfg.g_timebase.num; 558b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.time_base.denominator = cfg.g_timebase.den; 559b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 560b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i); 561b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info); 562b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!outfile[i]) 563b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for writing", file_name); 564b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 565b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // No spatial layers in this encoder. 566b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.ss_number_layers = 1; 567b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 568b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Initialize codec. 569b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0)) 570b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize encoder"); 571b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 5726ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (strncmp(encoder->name, "vp8", 3) == 0) { 5736ac915abcdb404a00d927fe6308a47fcf09d9519hkuang vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); 5746ac915abcdb404a00d927fe6308a47fcf09d9519hkuang vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 1); 5756ac915abcdb404a00d927fe6308a47fcf09d9519hkuang } else if (strncmp(encoder->name, "vp9", 3) == 0) { 5766ac915abcdb404a00d927fe6308a47fcf09d9519hkuang vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); 5776ac915abcdb404a00d927fe6308a47fcf09d9519hkuang vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); 5786ac915abcdb404a00d927fe6308a47fcf09d9519hkuang vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); 5796ac915abcdb404a00d927fe6308a47fcf09d9519hkuang vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 0); 5806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) { 5816ac915abcdb404a00d927fe6308a47fcf09d9519hkuang die_codec(&codec, "Failed to set SVC"); 582b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 583b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 584b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); 585b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); 586b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // This controls the maximum target size of the key frame. 587b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // For generating smaller key frames, use a smaller max_intra_size_pct 588b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // value, like 100 or 200. 589b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5) 590b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * ((double) cfg.g_timebase.den / cfg.g_timebase.num) / 10.0); 591a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // For low-quality key frame. 592a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian max_intra_size_pct = 200; 593b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, max_intra_size_pct); 594b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 595b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian frame_avail = 1; 596b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (frame_avail || got_data) { 597a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian struct vpx_usec_timer timer; 598b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 599b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_codec_cx_pkt_t *pkt; 600b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Update the temporal layer_id. No spatial layers in this test. 601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_id.spatial_layer_id = 0; 602b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_id.temporal_layer_id = 603b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity]; 604b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (strncmp(encoder->name, "vp9", 3) == 0) { 605b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id); 606b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 607b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian flags = layer_flags[frame_cnt % flag_periodicity]; 608b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian frame_avail = vpx_img_read(&raw, infile); 609b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (frame_avail) 610b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++rc.layer_input_frames[layer_id.temporal_layer_id]; 611a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian vpx_usec_timer_start(&timer); 612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts, 1, flags, 613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VPX_DL_REALTIME)) { 614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to encode frame"); 615b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 616a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian vpx_usec_timer_mark(&timer); 617a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian cx_time += vpx_usec_timer_elapsed(&timer); 618b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Reset KF flag. 619b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (layering_mode != 7) { 620b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian layer_flags[0] &= ~VPX_EFLAG_FORCE_KF; 621b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 622b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian got_data = 0; 623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while ( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) { 624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian got_data = 1; 625b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian switch (pkt->kind) { 626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case VPX_CODEC_CX_FRAME_PKT: 627b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity]; 628b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian i < cfg.ts_number_layers; ++i) { 629b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf, 630b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt->data.frame.sz, pts); 631b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++rc.layer_tot_enc_frames[i]; 632b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz; 633b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Keep count of rate control stats per layer (for non-key frames). 634b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] && 635b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian !(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) { 636b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz; 637b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc.layer_avg_rate_mismatch[i] += 638b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) / 639b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rc.layer_pfb[i]; 640b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++rc.layer_enc_frames[i]; 641b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 642b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 643b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 644b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian default: 645b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 646b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 647b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 648b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++frame_cnt; 649b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pts += frame_duration; 650b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 651b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fclose(infile); 652b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printout_rate_control_summary(&rc, &cfg, frame_cnt); 653a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian printf("\n"); 654a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", 655a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian frame_cnt, 656a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 1000 * (float)cx_time / (double)(frame_cnt * 1000000), 657a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 1000000 * (double)frame_cnt / (double)cx_time); 658b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 659b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_destroy(&codec)) 660b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec"); 661b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 662b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Try to rewrite the output file headers with the actual frame count. 663b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = 0; i < cfg.ts_number_layers; ++i) 664b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_video_writer_close(outfile[i]); 665b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 666b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return EXIT_SUCCESS; 667b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 668