1d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org/* 2d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Copyright (c) 2013 The WebM project authors. All Rights Reserved. 3d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * 4d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Use of this source code is governed by a BSD-style license 5d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * that can be found in the LICENSE file in the root of the source 6d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * tree. An additional intellectual property rights grant can be found 7d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * in the file PATENTS. All contributing project authors may 8d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * be found in the AUTHORS file in the root of the source tree. 9d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org */ 10d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 11d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org/** 12d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * @file 13d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * VP9 SVC encoding support via libvpx 14d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org */ 15d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <assert.h> 17411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include <math.h> 1887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include <limits.h> 19d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdarg.h> 20d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdio.h> 21d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdlib.h> 22d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <string.h> 23d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define VPX_DISABLE_CTRL_TYPECHECKS 1 24ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org#include "./vpx_config.h" 25d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vpx/svc_context.h" 26d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vpx/vp8cx.h" 27d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vpx/vpx_encoder.h" 28e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org#include "vpx_mem/vpx_mem.h" 29ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org#include "vp9/common/vp9_onyxc_int.h" 30d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 31411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#ifdef __MINGW32__ 32d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define strtok_r strtok_s 33411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#ifndef MINGW_HAS_SECURE_API 34d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h 35d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org_CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context); 36411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#endif /* MINGW_HAS_SECURE_API */ 37411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#endif /* __MINGW32__ */ 38d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 39d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#ifdef _MSC_VER 40d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define strdup _strdup 41d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define strtok_r strtok_s 42d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#endif 43d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 44d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define SVC_REFERENCE_FRAMES 8 45d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define SUPERFRAME_SLOTS (8) 46d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define SUPERFRAME_BUFFER_SIZE (SUPERFRAME_SLOTS * sizeof(uint32_t) + 2) 4787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#define OPTION_BUFFER_SIZE 1024 48411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#define COMPONENTS 4 // psnr & sse statistics maintained for total, y, u, v 49d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 5087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#define MAX_QUANTIZER 63 5187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 5287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic const int DEFAULT_SCALE_FACTORS_NUM[VPX_SS_MAX_LAYERS] = { 5387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 4, 5, 7, 11, 16 5487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}; 5587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 5687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic const int DEFAULT_SCALE_FACTORS_DEN[VPX_SS_MAX_LAYERS] = { 5787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 16, 16, 16, 16, 16 5887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}; 5987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 6087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgtypedef enum { 6187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org QUANTIZER = 0, 6287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org BITRATE, 6387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org SCALE_FACTOR, 6487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org AUTO_ALT_REF, 6587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ALL_OPTION_TYPES 6687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org} LAYER_OPTION_TYPE; 6787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 6887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic const int option_max_values[ALL_OPTION_TYPES] = { 6987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 63, INT_MAX, INT_MAX, 1 7087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}; 7187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 7287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic const int option_min_values[ALL_OPTION_TYPES] = { 7387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 0, 0, 1, 0 7487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}; 75d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 76e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org// One encoded frame 77e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.orgtypedef struct FrameData { 78e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org void *buf; // compressed data buffer 79e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org size_t size; // length of compressed data 80e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vpx_codec_frame_flags_t flags; /**< flags for this frame */ 81e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org struct FrameData *next; 82e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org} FrameData; 83e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 84d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgtypedef struct SvcInternal { 85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options 86d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // values extracted from option, quantizers 8887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vpx_svc_extra_cfg_t svc_params; 89ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org int enable_auto_alt_ref[VPX_SS_MAX_LAYERS]; 9087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int bitrates[VPX_SS_MAX_LAYERS]; 91d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 92d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // accumulated statistics 93411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org double psnr_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; // total/Y/U/V 94411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org uint64_t sse_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; 95411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org uint32_t bytes_sum[VPX_SS_MAX_LAYERS]; 96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // codec encoding values 98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int width; // width of highest layer 99d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int height; // height of highest layer 100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int kf_dist; // distance between keyframes 101d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // state variables 10387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int psnr_pkt_received; 104d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int layer; 105d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org int use_multiple_frame_contexts; 106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 107d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char message_buffer[2048]; 108d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_ctx_t *codec_ctx; 109d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} SvcInternal; 110d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 111d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic SvcInternal *get_svc_internal(SvcContext *svc_ctx) { 112d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL) return NULL; 113d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx->internal == NULL) { 11476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org SvcInternal *const si = (SvcInternal *)malloc(sizeof(*si)); 115d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (si != NULL) { 116d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org memset(si, 0, sizeof(*si)); 117d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 118d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_ctx->internal = si; 119d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 12076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org return (SvcInternal *)svc_ctx->internal; 121d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 122d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 123d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic const SvcInternal *get_const_svc_internal(const SvcContext *svc_ctx) { 124d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL) return NULL; 12576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org return (const SvcInternal *)svc_ctx->internal; 126d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 127d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 128d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic void svc_log_reset(SvcContext *svc_ctx) { 129d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *const si = (SvcInternal *)svc_ctx->internal; 130d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->message_buffer[0] = '\0'; 131d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 132d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 1337765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.orgstatic int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level, 1347765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org const char *fmt, ...) { 135d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char buf[512]; 136d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int retval = 0; 137d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org va_list ap; 138d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *const si = get_svc_internal(svc_ctx); 139d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 140d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (level > svc_ctx->log_level) { 141d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return retval; 142d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 143d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 144d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org va_start(ap, fmt); 145d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org retval = vsnprintf(buf, sizeof(buf), fmt, ap); 146d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org va_end(ap); 147d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 148d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx->log_print) { 149d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org printf("%s", buf); 150d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else { 151d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org strncat(si->message_buffer, buf, 152d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org sizeof(si->message_buffer) - strlen(si->message_buffer) - 1); 153d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 154d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 155d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (level == SVC_LOG_ERROR) { 156d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->codec_ctx->err_detail = si->message_buffer; 157d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 158d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return retval; 159d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 160d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 16187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic vpx_codec_err_t extract_option(LAYER_OPTION_TYPE type, 16287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org char *input, 16387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int *value0, 16487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int *value1) { 16587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (type == SCALE_FACTOR) { 16687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value0 = strtol(input, &input, 10); 16787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (*input++ != '/') 16887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 16987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value1 = strtol(input, &input, 10); 17087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 17187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (*value0 < option_min_values[SCALE_FACTOR] || 17287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value1 < option_min_values[SCALE_FACTOR] || 17387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value0 > option_max_values[SCALE_FACTOR] || 17487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value1 > option_max_values[SCALE_FACTOR] || 17587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value0 > *value1) // num shouldn't be greater than den 17687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 177d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else { 17887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value0 = atoi(input); 17987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (*value0 < option_min_values[type] || 18087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *value0 > option_max_values[type]) 18187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 182d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 18387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org return VPX_CODEC_OK; 184d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 185d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 18687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic vpx_codec_err_t parse_layer_options_from_string(SvcContext *svc_ctx, 18787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org LAYER_OPTION_TYPE type, 18887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const char *input, 18987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int *option0, 19087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int *option1) { 19187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int i; 19287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vpx_codec_err_t res = VPX_CODEC_OK; 193ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org char *input_string; 194ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org char *token; 195ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org const char *delim = ","; 196ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org char *save_ptr; 197ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 19887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (input == NULL || option0 == NULL || 19987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org (option1 == NULL && type == SCALE_FACTOR)) 200ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 201ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 20287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org input_string = strdup(input); 203ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org token = strtok_r(input_string, delim, &save_ptr); 204ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 205ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (token != NULL) { 20687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = extract_option(type, token, option0 + i, option1 + i); 20787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (res != VPX_CODEC_OK) 208ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org break; 209ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org token = strtok_r(NULL, delim, &save_ptr); 210ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } else { 21187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org break; 212d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 213d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 21487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (res == VPX_CODEC_OK && i != svc_ctx->spatial_layers) { 215d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, 21687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "svc: layer params type: %d %d values required, " 21787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "but only %d specified\n", type, svc_ctx->spatial_layers, i); 218d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org res = VPX_CODEC_INVALID_PARAM; 219d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 220d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org free(input_string); 221d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return res; 222d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 223d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 224d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org/** 225d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Parse SVC encoding options 226d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Format: encoding-mode=<svc_mode>,layers=<layer_count> 227d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * scale-factors=<n1>/<d1>,<n2>/<d2>,... 228d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * quantizers=<q1>,<q2>,... 229d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * svc_mode = [i|ip|alt_ip|gf] 230d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org */ 231d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { 232d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char *input_string; 233d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char *option_name; 234d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char *option_value; 235d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char *input_ptr; 236d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org SvcInternal *const si = get_svc_internal(svc_ctx); 23776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_codec_err_t res = VPX_CODEC_OK; 23887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int i, alt_ref_enabled = 0; 239d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 240d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (options == NULL) return VPX_CODEC_OK; 241d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_string = strdup(options); 242d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 243d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // parse option name 244d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org option_name = strtok_r(input_string, "=", &input_ptr); 245d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org while (option_name != NULL) { 246d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // parse option value 247d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org option_value = strtok_r(NULL, " ", &input_ptr); 248d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (option_value == NULL) { 249d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, "option missing value: %s\n", 250d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org option_name); 251d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org res = VPX_CODEC_INVALID_PARAM; 252d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org break; 253d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 254d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (strcmp("spatial-layers", option_name) == 0) { 255d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_ctx->spatial_layers = atoi(option_value); 256d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org } else if (strcmp("temporal-layers", option_name) == 0) { 257d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->temporal_layers = atoi(option_value); 258d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else if (strcmp("scale-factors", option_name) == 0) { 25987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = parse_layer_options_from_string(svc_ctx, SCALE_FACTOR, option_value, 26087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.scaling_factor_num, 26187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.scaling_factor_den); 262d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (res != VPX_CODEC_OK) break; 26387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else if (strcmp("max-quantizers", option_name) == 0) { 26487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, 26587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.max_quantizers, 26687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org NULL); 26787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (res != VPX_CODEC_OK) break; 26887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else if (strcmp("min-quantizers", option_name) == 0) { 26987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, 27087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.min_quantizers, 27187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org NULL); 272d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (res != VPX_CODEC_OK) break; 273ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } else if (strcmp("auto-alt-refs", option_name) == 0) { 27487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = parse_layer_options_from_string(svc_ctx, AUTO_ALT_REF, option_value, 27587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->enable_auto_alt_ref, NULL); 27687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (res != VPX_CODEC_OK) break; 27787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else if (strcmp("bitrates", option_name) == 0) { 27887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = parse_layer_options_from_string(svc_ctx, BITRATE, option_value, 27987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->bitrates, NULL); 280ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (res != VPX_CODEC_OK) break; 281d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org } else if (strcmp("multi-frame-contexts", option_name) == 0) { 282d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org si->use_multiple_frame_contexts = atoi(option_value); 283d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else { 284d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name); 285d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org res = VPX_CODEC_INVALID_PARAM; 286d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org break; 287d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 288d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org option_name = strtok_r(NULL, "=", &input_ptr); 289d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 290d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org free(input_string); 291d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 29287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 29387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (si->svc_params.max_quantizers[i] > MAX_QUANTIZER || 29487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.max_quantizers[i] < 0 || 29587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.min_quantizers[i] > si->svc_params.max_quantizers[i] || 29687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.min_quantizers[i] < 0) 29787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = VPX_CODEC_INVALID_PARAM; 29887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 29987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 300d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (si->use_multiple_frame_contexts && 301d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org (svc_ctx->spatial_layers > 3 || 302d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->spatial_layers * svc_ctx->temporal_layers > 4)) 303d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org res = VPX_CODEC_INVALID_PARAM; 304d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 30587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) 30687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org alt_ref_enabled += si->enable_auto_alt_ref[i]; 30787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (alt_ref_enabled > REF_FRAMES - svc_ctx->spatial_layers) { 30887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, 30987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "svc: auto alt ref: Maxinum %d(REF_FRAMES - layers) layers could" 31087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "enabled auto alt reference frame, but % layers are enabled\n", 31187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org REF_FRAMES - svc_ctx->spatial_layers, alt_ref_enabled); 31287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org res = VPX_CODEC_INVALID_PARAM; 31387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 31487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 315d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return res; 316d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 317d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 318d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) { 319d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *const si = get_svc_internal(svc_ctx); 320d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL || options == NULL || si == NULL) { 321d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 322d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 323d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org strncpy(si->options, options, sizeof(si->options)); 324d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->options[sizeof(si->options) - 1] = '\0'; 325d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_OK; 326d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 327d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 32887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid assign_layer_bitrates(const SvcContext *svc_ctx, 32987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vpx_codec_enc_cfg_t *const enc_cfg) { 33087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int i; 33187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const SvcInternal *const si = get_const_svc_internal(svc_ctx); 332d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 33387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (si->bitrates[0] != 0) { 33487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org enc_cfg->rc_target_bitrate = 0; 33587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 33687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org enc_cfg->ss_target_bitrate[i] = (unsigned int)si->bitrates[i]; 33787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org enc_cfg->rc_target_bitrate += si->bitrates[i]; 33887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 33987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else { 34087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org float total = 0; 34187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org float alloc_ratio[VPX_SS_MAX_LAYERS] = {0}; 34287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 34387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 34487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (si->svc_params.scaling_factor_den[i] > 0) { 34587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org alloc_ratio[i] = (float)(si->svc_params.scaling_factor_num[i] * 1.0 / 34687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.scaling_factor_den[i]); 34787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 34887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org alloc_ratio[i] *= alloc_ratio[i]; 34987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org total += alloc_ratio[i]; 35087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 35187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 35287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 35387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 35487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (total > 0) { 35587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org enc_cfg->ss_target_bitrate[i] = (unsigned int) 35687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total); 35787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 35887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 359d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 360d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 361d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 362d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, 363d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_iface_t *iface, 364d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_enc_cfg_t *enc_cfg) { 365d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_err_t res; 366ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org int i; 367d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *const si = get_svc_internal(svc_ctx); 368d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL || codec_ctx == NULL || iface == NULL || 369d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org enc_cfg == NULL) { 370d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 371d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 372d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (si == NULL) return VPX_CODEC_MEM_ERROR; 373d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 374d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->codec_ctx = codec_ctx; 375d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 376d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->width = enc_cfg->g_w; 377d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->height = enc_cfg->g_h; 378d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 379d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (enc_cfg->kf_max_dist < 2) { 380d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, "key frame distance too small: %d\n", 381d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org enc_cfg->kf_max_dist); 382d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 383d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 384d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si->kf_dist = enc_cfg->kf_max_dist; 385d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 386d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx->spatial_layers == 0) 387d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS; 388d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx->spatial_layers < 1 || 389d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) { 390d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n", 391d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_ctx->spatial_layers); 392d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 393d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 394d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 39587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) { 39687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.max_quantizers[i] = MAX_QUANTIZER; 39787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.min_quantizers[i] = 0; 39887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.scaling_factor_num[i] = DEFAULT_SCALE_FACTORS_NUM[i]; 39987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->svc_params.scaling_factor_den[i] = DEFAULT_SCALE_FACTORS_DEN[i]; 40087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 401d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 40293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Parse aggregate command line options. Options must start with 40393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // "layers=xx" then followed by other options 404d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org res = parse_options(svc_ctx, si->options); 405d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (res != VPX_CODEC_OK) return res; 406d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 407d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc_ctx->spatial_layers < 1) 408d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->spatial_layers = 1; 409d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) 410d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->spatial_layers = VPX_SS_MAX_LAYERS; 411d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 412d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc_ctx->temporal_layers < 1) 413d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->temporal_layers = 1; 414d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc_ctx->temporal_layers > VPX_TS_MAX_LAYERS) 415d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->temporal_layers = VPX_TS_MAX_LAYERS; 416d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 41787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org assign_layer_bitrates(svc_ctx, enc_cfg); 418411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 41941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if CONFIG_SPATIAL_SVC 42087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) 421ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org enc_cfg->ss_enable_auto_alt_ref[i] = si->enable_auto_alt_ref[i]; 42241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 423ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 424d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc_ctx->temporal_layers > 1) { 425d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org int i; 426d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org for (i = 0; i < svc_ctx->temporal_layers; ++i) { 427d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org enc_cfg->ts_target_bitrate[i] = enc_cfg->rc_target_bitrate / 428d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org svc_ctx->temporal_layers; 429d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org enc_cfg->ts_rate_decimator[i] = 1 << (svc_ctx->temporal_layers - 1 - i); 430d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org } 431d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org } 432d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 433d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // modify encoder configuration 43487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org enc_cfg->ss_number_layers = svc_ctx->spatial_layers; 435d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org enc_cfg->ts_number_layers = svc_ctx->temporal_layers; 436d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 437d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0) 438d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org enc_cfg->g_error_resilient = 1; 439d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 440d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // Initialize codec 441d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR); 442d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (res != VPX_CODEC_OK) { 443d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_ERROR, "svc_enc_init error\n"); 444d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return res; 445d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 446d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 447d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1); 44887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vpx_codec_control(codec_ctx, VP9E_SET_SVC_PARAMETERS, &si->svc_params); 449d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 450d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_OK; 451d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 452d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 453d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org/** 454d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Encode a frame into multiple layers 455d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Create a superframe containing the individual layers 456d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org */ 457d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, 458d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org struct vpx_image *rawimg, vpx_codec_pts_t pts, 459d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int64_t duration, int deadline) { 460d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_err_t res; 461d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org vpx_codec_iter_t iter; 462d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org const vpx_codec_cx_pkt_t *cx_pkt; 463d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *const si = get_svc_internal(svc_ctx); 46493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (svc_ctx == NULL || codec_ctx == NULL || si == NULL) { 465d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 466d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 467d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 468d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log_reset(svc_ctx); 469d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 470e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 0, 471e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org deadline); 472e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org if (res != VPX_CODEC_OK) { 473e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org return res; 474e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org } 475e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org // save compressed data 476e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org iter = NULL; 477e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) { 478e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org switch (cx_pkt->kind) { 47987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_SPATIAL_SVC 48087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org case VPX_CODEC_SPATIAL_SVC_LAYER_PSNR: { 481e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org int i; 48287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 48387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int j; 48487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_DEBUG, 48587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): " 48687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "%2.3f %2.3f %2.3f %2.3f \n", 48787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->psnr_pkt_received, i, 48887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].psnr[0], 48987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].psnr[1], 49087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].psnr[2], 49187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].psnr[3]); 49287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_DEBUG, 49387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "SVC frame: %d, layer: %d, SSE(Total/Y/U/V): " 49487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org "%2.3f %2.3f %2.3f %2.3f \n", 49587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->psnr_pkt_received, i, 49687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].sse[0], 49787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].sse[1], 49887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].sse[2], 49987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].sse[3]); 50087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 50187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (j = 0; j < COMPONENTS; ++j) { 50287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->psnr_sum[i][j] += 50387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cx_pkt->data.layer_psnr[i].psnr[j]; 50487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->sse_sum[i][j] += cx_pkt->data.layer_psnr[i].sse[j]; 505411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org } 506d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 50787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ++si->psnr_pkt_received; 508e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org break; 509d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 510ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org case VPX_CODEC_SPATIAL_SVC_LAYER_SIZES: { 511ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org int i; 51287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) 513ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org si->bytes_sum[i] += cx_pkt->data.layer_sizes[i]; 514ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org break; 515ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 51641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 517e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org default: { 518e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org break; 51993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 520d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 521d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 522e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 523d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return VPX_CODEC_OK; 524d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 525d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 526d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgconst char *vpx_svc_get_message(const SvcContext *svc_ctx) { 527d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org const SvcInternal *const si = get_const_svc_internal(svc_ctx); 528d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL || si == NULL) return NULL; 529d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return si->message_buffer; 530d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 531d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 532411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgstatic double calc_psnr(double d) { 533411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org if (d == 0) return 100; 534411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org return -10.0 * log(d) / log(10.0); 535411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org} 536411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 537d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// dump accumulated statistics and reset accumulated values 538d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgconst char *vpx_svc_dump_statistics(SvcContext *svc_ctx) { 53987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int number_of_frames; 540411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org int i, j; 541d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org uint32_t bytes_total = 0; 542411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org double scale[COMPONENTS]; 543411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org double psnr[COMPONENTS]; 544411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org double mse[COMPONENTS]; 545411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org double y_scale; 546411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 547d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *const si = get_svc_internal(svc_ctx); 548d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL || si == NULL) return NULL; 549d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 550d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log_reset(svc_ctx); 551d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 55287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org number_of_frames = si->psnr_pkt_received; 55387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (number_of_frames <= 0) return vpx_svc_get_message(svc_ctx); 554d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 555d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_INFO, "\n"); 55687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org for (i = 0; i < svc_ctx->spatial_layers; ++i) { 557d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 558411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org svc_log(svc_ctx, SVC_LOG_INFO, 559411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org "Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n", 560411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org i, (double)si->psnr_sum[i][0] / number_of_frames, 561411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org (double)si->psnr_sum[i][1] / number_of_frames, 562411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org (double)si->psnr_sum[i][2] / number_of_frames, 563411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org (double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]); 564411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org // the following psnr calculation is deduced from ffmpeg.c#print_report 565411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames; 566411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org scale[1] = y_scale; 567411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org scale[2] = scale[3] = y_scale / 4; // U or V 568411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org scale[0] = y_scale * 1.5; // total 569411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 570411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org for (j = 0; j < COMPONENTS; j++) { 571411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org psnr[j] = calc_psnr(si->sse_sum[i][j] / scale[j]); 572411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org mse[j] = si->sse_sum[i][j] * 255.0 * 255.0 / scale[j]; 573411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org } 574411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org svc_log(svc_ctx, SVC_LOG_INFO, 575411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org "Layer %d Overall PSNR=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, psnr[0], 576411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org psnr[1], psnr[2], psnr[3]); 577411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org svc_log(svc_ctx, SVC_LOG_INFO, 578411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org "Layer %d Overall MSE=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, mse[0], 579411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org mse[1], mse[2], mse[3]); 580411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 581411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org bytes_total += si->bytes_sum[i]; 582411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org // clear sums for next time 583411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org si->bytes_sum[i] = 0; 584411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org for (j = 0; j < COMPONENTS; ++j) { 585411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org si->psnr_sum[i][j] = 0; 586411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org si->sse_sum[i][j] = 0; 587411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org } 588d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 589d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 590d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // only display statistics once 59187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org si->psnr_pkt_received = 0; 592d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 593d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total); 594d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return vpx_svc_get_message(svc_ctx); 595d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 596d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 597d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid vpx_svc_release(SvcContext *svc_ctx) { 598d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org SvcInternal *si; 599d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (svc_ctx == NULL) return; 600d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // do not use get_svc_internal as it will unnecessarily allocate an 601d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // SvcInternal if it was not already allocated 602d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org si = (SvcInternal *)svc_ctx->internal; 603d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (si != NULL) { 604d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org free(si); 605d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org svc_ctx->internal = NULL; 606d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 607d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 60893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 609