mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 18:34:06 +00:00
a860bbc7f9
The coefficients in a matrix are stored in up-right diagonal order. The following indicates the default matrices specified in the spec. INTRA4X4_LUMA 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 INTRA4X4_CHROMAU 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 INTRA4X4_CHROMAV 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 INTER4X4_LUMA 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 INTER4X4_CHROMAU 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 INTER4X4_CHROMAV 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 INTRA8X8_LUMA 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTRA8X8_CHROMAU 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTRA8X8_CHROMAV 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTER8X8_LUMA 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTER8X8_CHROMAU 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTER8X8_CHROMAV 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTRA16X16_LUMA 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTRA16X16_CHROMAU 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTRA16X16_CHROMAV 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTER16X16_LUMA 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTER16X16_CHROMAU 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTER16X16_CHROMAV 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTRA32X32_LUMA 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25, 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36, 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65, 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115 INTER32X32_LUMA 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25, 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33, 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54, 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91 INTRA16X16_LUMA_DC 16 INTRA16X16_CHROMAU_DC 16 INTRA16X16_CHROMAV_DC 16 INTER16X16_LUMA_DC 16 INTER16X16_CHROMAU_DC 16 INTER16X16_CHROMAV_DC 16 INTRA32X32_LUMA_DC 16 INTER32X32_LUMA_DC 16
321 lines
9.6 KiB
C
321 lines
9.6 KiB
C
/*****************************************************************************
|
|
* This file is part of Kvazaar HEVC encoder.
|
|
*
|
|
* Copyright (C) 2013-2014 Tampere University of Technology and others (see
|
|
* COPYING file).
|
|
*
|
|
* Kvazaar is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as published
|
|
* by the Free Software Foundation.
|
|
*
|
|
* Kvazaar is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
|
****************************************************************************/
|
|
|
|
/*
|
|
* \file
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "extras/getopt.h"
|
|
|
|
/**
|
|
* \brief Allocate memory for config object
|
|
* \return pointer to allocated memory
|
|
*/
|
|
config *config_alloc()
|
|
{
|
|
config *cfg = (config *)malloc(sizeof(config));
|
|
if (!cfg) {
|
|
fprintf(stderr, "Failed to allocate a config object!\n");
|
|
return cfg;
|
|
}
|
|
|
|
memset(cfg, 0, sizeof(config));
|
|
return cfg;
|
|
}
|
|
|
|
/**
|
|
* \brief Initialize config structure
|
|
* \param cfg config object
|
|
* \return 1 on success, 0 on failure
|
|
*/
|
|
int config_init(config *cfg)
|
|
{
|
|
cfg->input = NULL;
|
|
cfg->output = NULL;
|
|
cfg->debug = NULL;
|
|
cfg->frames = 0;
|
|
cfg->width = 320;
|
|
cfg->height = 240;
|
|
cfg->qp = 32;
|
|
cfg->intra_period = 0;
|
|
cfg->deblock_enable = 1;
|
|
cfg->deblock_beta = 0;
|
|
cfg->deblock_tc = 0;
|
|
cfg->sao_enable = 1;
|
|
cfg->vui.sar_width = 0;
|
|
cfg->vui.sar_height = 0;
|
|
cfg->vui.overscan = 0; /* undef */
|
|
cfg->vui.videoformat = 5; /* undef */
|
|
cfg->vui.fullrange = 0; /* limited range */
|
|
cfg->vui.colorprim = 2; /* undef */
|
|
cfg->vui.transfer = 2; /* undef */
|
|
cfg->vui.colormatrix = 2; /* undef */
|
|
cfg->vui.chroma_loc = 0; /* left center */
|
|
cfg->aud_enable = 0;
|
|
cfg->cqmfile = NULL;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* \brief Free memory allocated to the config
|
|
* \param cfg config object
|
|
* \return 1 on success, 0 on failure
|
|
*/
|
|
int config_destroy(config *cfg)
|
|
{
|
|
FREE_POINTER(cfg->input);
|
|
FREE_POINTER(cfg->output);
|
|
FREE_POINTER(cfg->cqmfile);
|
|
free(cfg);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* \brief Allocates memory space for a string, and copies it
|
|
* \param char * string to copy
|
|
* \return a pointer to the copied string on success, null on failure
|
|
*/
|
|
char *copy_string(const char *string)
|
|
{
|
|
// Allocate +1 for \0
|
|
char *allocated_string = (char *)malloc(strlen(string) + 1);
|
|
if (!allocated_string) {
|
|
fprintf(stderr, "Failed to allocate a string!\n");
|
|
return allocated_string;
|
|
}
|
|
|
|
// Copy the string to the new buffer
|
|
memcpy(allocated_string, string, strlen(string) + 1);
|
|
|
|
return allocated_string;
|
|
}
|
|
|
|
static int atobool(const char *str)
|
|
{
|
|
if (!strcmp(str, "1") ||
|
|
!strcmp(str, "true") ||
|
|
!strcmp(str, "yes"))
|
|
return 1;
|
|
if (!strcmp(str, "0") ||
|
|
!strcmp(str, "false") ||
|
|
!strcmp(str, "no"))
|
|
return 0;
|
|
return 0;
|
|
}
|
|
|
|
static int parse_enum(const char *arg, const char * const *names, int8_t *dst)
|
|
{
|
|
int i;
|
|
for (i = 0; names[i]; i++)
|
|
if (!strcmp(arg, names[i])) {
|
|
*dst = i;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int config_parse(config *cfg, const char *name, const char *value)
|
|
{
|
|
static const char * const overscan_names[] = { "undef", "show", "crop", NULL };
|
|
static const char * const videoformat_names[] = { "component", "pal", "ntsc", "secam", "mac", "undef", NULL };
|
|
static const char * const range_names[] = { "tv", "pc", NULL };
|
|
static const char * const colorprim_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m",
|
|
"smpte240m", "film", "bt2020", NULL };
|
|
static const char * const transfer_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m",
|
|
"smpte240m", "linear", "log100", "log316", "iec61966-2-4",
|
|
"bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", NULL };
|
|
static const char * const colormatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m",
|
|
"smpte240m", "YCgCo", "bt2020nc", "bt2020c", NULL };
|
|
|
|
int i;
|
|
int error = 0;
|
|
|
|
if (!name)
|
|
return 0;
|
|
if (!value)
|
|
value = "true";
|
|
|
|
if ((!strncmp(name, "no-", 3) && (i = 3))) {
|
|
name += i;
|
|
value = atobool(value) ? "false" : "true";
|
|
}
|
|
|
|
#define OPT(STR) else if (!strcmp(name, STR))
|
|
if (0);
|
|
OPT("input")
|
|
cfg->input = copy_string(value);
|
|
OPT("output")
|
|
cfg->output = copy_string(value);
|
|
OPT("debug")
|
|
cfg->debug = copy_string(value);
|
|
OPT("width")
|
|
cfg->width = atoi(value);
|
|
OPT("height")
|
|
cfg->height = atoi(value);
|
|
OPT("frames")
|
|
cfg->frames = atoi(value);
|
|
OPT("qp")
|
|
cfg->qp = atoi(value);
|
|
OPT("period")
|
|
cfg->intra_period = atoi(value);
|
|
OPT("deblock") {
|
|
int beta, tc;
|
|
if (2 == sscanf(value, "%d:%d", &beta, &tc)) {
|
|
cfg->deblock_enable = 1;
|
|
cfg->deblock_beta = beta;
|
|
cfg->deblock_tc = tc;
|
|
} else if (sscanf(value, "%d", &beta)) {
|
|
cfg->deblock_enable = 1;
|
|
cfg->deblock_beta = beta;
|
|
cfg->deblock_tc = cfg->deblock_beta;
|
|
} else
|
|
cfg->deblock_enable = atobool(value);
|
|
|
|
if (cfg->deblock_beta < -6 || cfg->deblock_beta > 6) {
|
|
fprintf(stderr, "--deblock beta parameter out of range [-6..6], set to 0\n");
|
|
cfg->deblock_beta = 0;
|
|
}
|
|
if (cfg->deblock_tc < -6 || cfg->deblock_tc > 6) {
|
|
fprintf(stderr, "--deblock tc parameter out of range [-6..6], set to 0\n");
|
|
cfg->deblock_tc = 0;
|
|
}
|
|
}
|
|
OPT("sao")
|
|
cfg->sao_enable = atobool(value);
|
|
OPT("sar") {
|
|
int sar_width, sar_height;
|
|
if (2 == sscanf(value, "%d:%d", &sar_width, &sar_height)) {
|
|
cfg->vui.sar_width = sar_width;
|
|
cfg->vui.sar_height = sar_height;
|
|
} else
|
|
error = 1;
|
|
}
|
|
OPT("overscan")
|
|
error = !parse_enum(value, overscan_names, &cfg->vui.overscan);
|
|
OPT("videoformat")
|
|
error = !parse_enum(value, videoformat_names, &cfg->vui.videoformat);
|
|
OPT("range")
|
|
error = !parse_enum(value, range_names, &cfg->vui.fullrange);
|
|
OPT("colorprim")
|
|
error = !parse_enum(value, colorprim_names, &cfg->vui.colorprim);
|
|
OPT("transfer")
|
|
error = !parse_enum(value, transfer_names, &cfg->vui.transfer);
|
|
OPT("colormatrix")
|
|
error = !parse_enum(value, colormatrix_names, &cfg->vui.colormatrix);
|
|
OPT("chromaloc") {
|
|
cfg->vui.chroma_loc = atoi(value);
|
|
if (cfg->vui.chroma_loc < 0 || cfg->vui.chroma_loc > 5) {
|
|
fprintf(stderr, "--chromaloc parameter out of range [0..5], set to 0\n");
|
|
cfg->vui.chroma_loc = 0;
|
|
}
|
|
}
|
|
OPT("aud")
|
|
cfg->aud_enable = atobool(value);
|
|
OPT("cqmfile")
|
|
cfg->cqmfile = copy_string(value);
|
|
else
|
|
return 0;
|
|
#undef OPT
|
|
|
|
return error ? 0 : 1;
|
|
}
|
|
|
|
/**
|
|
* \brief Read configuration options from argv to the config struct
|
|
* \param cfg config object
|
|
* \param argc argument count
|
|
* \param argv argument list
|
|
* \return 1 on success, 0 on failure
|
|
*/
|
|
int config_read(config *cfg,int argc, char *argv[])
|
|
{
|
|
uint32_t pos = 0;
|
|
int arg = 1;
|
|
char option = 0;
|
|
|
|
static char short_options[] = "i:o:d:w:h:n:q:p:";
|
|
static struct option long_options[] =
|
|
{
|
|
{ "input", required_argument, NULL, 'i' },
|
|
{ "output", required_argument, NULL, 'o' },
|
|
{ "debug", required_argument, NULL, 'd' },
|
|
{ "width", required_argument, NULL, 'w' },
|
|
{ "height", required_argument, NULL, 'h' },
|
|
{ "frames", required_argument, NULL, 'n' },
|
|
{ "qp", required_argument, NULL, 'q' },
|
|
{ "period", required_argument, NULL, 'p' },
|
|
{ "no-deblock", no_argument, NULL, 0 },
|
|
{ "deblock", required_argument, NULL, 0 },
|
|
{ "no-sao", no_argument, NULL, 0 },
|
|
{ "sar", required_argument, NULL, 0 },
|
|
{ "overscan", required_argument, NULL, 0 },
|
|
{ "videoformat", required_argument, NULL, 0 },
|
|
{ "range", required_argument, NULL, 0 },
|
|
{ "colorprim", required_argument, NULL, 0 },
|
|
{ "transfer", required_argument, NULL, 0 },
|
|
{ "colormatrix", required_argument, NULL, 0 },
|
|
{ "chromaloc", required_argument, NULL, 0 },
|
|
{ "aud", no_argument, NULL, 0 },
|
|
{ "cqmfile", required_argument, NULL, 0 },
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
// Parse command line options
|
|
for (optind = 0;;) {
|
|
int long_options_index = -1;
|
|
|
|
int c = getopt_long(argc, argv, short_options, long_options, &long_options_index);
|
|
if (c == -1)
|
|
break;
|
|
|
|
if (long_options_index < 0) {
|
|
int i;
|
|
for (i = 0; long_options[i].name; i++)
|
|
if (long_options[i].val == c) {
|
|
long_options_index = i;
|
|
break;
|
|
}
|
|
if (long_options_index < 0) {
|
|
// getopt_long already printed an error message
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!config_parse(cfg, long_options[long_options_index].name, optarg)) {
|
|
const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind-2];
|
|
fprintf(stderr, "invalid argument: %s = %s\r\n", name, optarg );
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check that the required files were defined
|
|
if(cfg->input == NULL || cfg->output == NULL) return 0;
|
|
|
|
return 1;
|
|
}
|