Projects
Essentials
kvazaar
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 8
View file
kvazaar.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Thu Jan 28 20:07:47 UTC 2016 - aloisio@gmx.com + +- Update to version 0.8.3 + +------------------------------------------------------------------- Sat Jan 16 19:25:59 UTC 2016 - aloisio@gmx.com - Update to version 0.8.2
View file
kvazaar.spec
Changed
@@ -18,7 +18,7 @@ %define libname libkvazaar %define libmver 3 Name: kvazaar -Version: 0.8.2 +Version: 0.8.3 Release: 0 Summary: HEVC encoder License: LGPL-2.1 @@ -85,7 +85,6 @@ %files -n %{libname}-devel %defattr(-,root,root) %{_includedir}/kvazaar.h -%{_includedir}/kvazaar_version.h %{_libdir}/%{libname}.so %{_libdir}/pkgconfig/kvazaar.pc
View file
kvazaar-0.8.2.tar.gz/src/config.c
Deleted
@@ -1,935 +0,0 @@ -/***************************************************************************** - * This file is part of Kvazaar HEVC encoder. - * - * Copyright (C) 2013-2015 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 Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * 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 Lesser 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/>. - ****************************************************************************/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -kvz_config *kvz_config_alloc(void) -{ - kvz_config *cfg = (kvz_config *)malloc(sizeof(kvz_config)); - if (!cfg) { - fprintf(stderr, "Failed to allocate a config object!\n"); - return cfg; - } - - FILL(*cfg, 0); - - return cfg; -} - -int kvz_config_init(kvz_config *cfg) -{ - cfg->width = 0; - cfg->height = 0; - cfg->framerate = 25; // deprecated and will be removed. - cfg->framerate_num = 0; - cfg->framerate_denom = 1; - cfg->qp = 32; - cfg->intra_period = 0; - cfg->vps_period = 0; - cfg->deblock_enable = 1; - cfg->deblock_beta = 0; - cfg->deblock_tc = 0; - cfg->sao_enable = 1; - cfg->rdoq_enable = 1; - cfg->signhide_enable = true; - cfg->smp_enable = false; - cfg->amp_enable = false; - cfg->rdo = 1; - cfg->mv_rdo = 0; - cfg->full_intra_search = 0; - cfg->trskip_enable = 1; - cfg->tr_depth_intra = 0; - cfg->ime_algorithm = 0; /* hexbs */ - cfg->fme_level = 1; - cfg->source_scan_type = 0; /* progressive */ - 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; - cfg->ref_frames = DEFAULT_REF_PIC_COUNT; - cfg->gop_len = 0; - cfg->bipred = 0; - cfg->target_bitrate = 0; - - cfg->tiles_width_count = 0; - cfg->tiles_height_count = 0; - cfg->tiles_width_split = NULL; - cfg->tiles_height_split = NULL; - - cfg->wpp = 0; - cfg->owf = -1; - cfg->slice_count = 1; - cfg->slice_addresses_in_ts = MALLOC(int32_t, 1); - cfg->slice_addresses_in_ts[0] = 0; - - cfg->threads = 0; - cfg->cpuid = 1; - - // Defaults for what sizes of PUs are tried. - cfg->pu_depth_inter.min = 0; // 0-3 - cfg->pu_depth_inter.max = 3; // 0-3 - cfg->pu_depth_intra.min = 1; // 0-4 - cfg->pu_depth_intra.max = 4; // 0-4 - - cfg->add_encoder_info = true; - - return 1; -} - -int kvz_config_destroy(kvz_config *cfg) -{ - if (cfg) { - FREE_POINTER(cfg->cqmfile); - FREE_POINTER(cfg->tiles_width_split); - FREE_POINTER(cfg->tiles_height_split); - FREE_POINTER(cfg->slice_addresses_in_ts); - } - free(cfg); - - return 1; -} - -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) -{ - int8_t i; - for (i = 0; names[i]; i++) { - if (!strcmp(arg, names[i])) { - *dst = i; - return 1; - } - } - - return 0; -} - -static int parse_tiles_specification(const char* const arg, int32_t * const ntiles, int32_t** const array) { - const char* current_arg = NULL; - int32_t current_value; - int32_t values[MAX_TILES_PER_DIM]; - - int i; - - //Free pointer in any case - if (*array) { - FREE_POINTER(*array); - } - - //If the arg starts with u, we want an uniform split - if (arg[0]=='u') { - *ntiles = atoi(arg+1)-1; - if (MAX_TILES_PER_DIM <= *ntiles || 0 > *ntiles) { - fprintf(stderr, "Invalid number of tiles (0 < %d <= %d = MAX_TILES_PER_DIM)!\n", *ntiles + 1, MAX_TILES_PER_DIM); - return 0; - } - //Done with parsing - return 1; - } - - //We have a comma-separated list of int for the split... - current_arg = arg; - *ntiles = 0; - do { - int ret = sscanf(current_arg, "%d", ¤t_value); - if (ret != 1) { - fprintf(stderr, "Could not parse integer \"%s\"!\n", current_arg); - return 0; - } - current_arg = strchr(current_arg, ','); - //Skip the , if we found one - if (current_arg) ++current_arg; - values[*ntiles] = current_value; - ++(*ntiles); - if (MAX_TILES_PER_DIM <= *ntiles) break; - } while (current_arg); - - if (MAX_TILES_PER_DIM <= *ntiles || 0 >= *ntiles) { - fprintf(stderr, "Invalid number of tiles (0 < %d <= %d = MAX_TILES_PER_DIM)!\n", *ntiles + 1, MAX_TILES_PER_DIM); - return 0; - } - - *array = MALLOC(int32_t, *ntiles); - if (!*array) { - fprintf(stderr, "Could not allocate array for tiles\n"); - return 0; - } - - //TODO: memcpy? - for (i = 0; i < *ntiles; ++i) { - (*array)[i] = values[i]; - } - - return 1; -} - -static int parse_slice_specification(const char* const arg, int32_t * const nslices, int32_t** const array) { - const char* current_arg = NULL; - int32_t current_value; - int32_t values[MAX_SLICES]; - - int i; - - //Free pointer in any case - if (*array) { - FREE_POINTER(*array); - } - - //If the arg starts with u, we want an uniform split - if (arg[0]=='u') { - *nslices = atoi(arg+1); - if (MAX_SLICES <= *nslices || 0 >= *nslices) { - fprintf(stderr, "Invalid number of tiles (0 < %d <= %d = MAX_SLICES)!\n", *nslices + 1, MAX_SLICES); - return 0; - } - //Done with parsing - return 1; - } - - //We have a comma-separated list of int for the split... - current_arg = arg; - //We always have a slice starting at 0 - values[0] = 0; - *nslices = 1; - do { - int ret = sscanf(current_arg, "%d", ¤t_value); - if (ret != 1) { - fprintf(stderr, "Could not parse integer \"%s\"!\n", current_arg); - return 0; - } - current_arg = strchr(current_arg, ','); - //Skip the , if we found one - if (current_arg) ++current_arg; - values[*nslices] = current_value; - ++(*nslices); - if (MAX_SLICES <= *nslices) break; - } while (current_arg); - - if (MAX_SLICES <= *nslices || 0 >= *nslices) { - fprintf(stderr, "Invalid number of slices (0 < %d <= %d = MAX_SLICES)!\n", *nslices, MAX_SLICES); - return 0; - } - - *array = MALLOC(int32_t, *nslices); - if (!*array) { - fprintf(stderr, "Could not allocate array for slices\n"); - return 0; - } - - //TODO: memcpy? - for (i = 0; i < *nslices; ++i) { - (*array)[i] = values[i]; - } - - return 1; -} - -int kvz_config_parse(kvz_config *cfg, const char *name, const char *value) -{ - static const char * const me_names[] = { "hexbs", "tz", "full", NULL }; - static const char * const source_scan_type_names[] = { "progressive", "tff", "bff", NULL }; - - 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 }; - - static const char * const preset_values[11][28] = { - { - "ultrafast", - "pu-depth-intra", "2-3", - "pu-depth-inter", "1-3", - "rd", "0", - "me", "hexbs", - "ref", "1", - "deblock", "0", - "signhide", "0", - "subme", "0", - "sao", "0", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "superfast", - "pu-depth-intra", "1-3", - "pu-depth-inter", "1-3", - "rd", "1", - "me", "hexbs", - "ref", "1", - "deblock", "0", - "signhide", "0", - "subme", "0", - "sao", "0", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "veryfast", - "pu-depth-intra", "1-3", - "pu-depth-inter", "0-3", - "rd", "1", - "me", "hexbs", - "ref", "2", - "deblock", "1", - "signhide", "0", - "subme", "0", - "sao", "0", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "faster", - "pu-depth-intra", "1-3", - "pu-depth-inter", "0-3", - "rd", "1", - "me", "hexbs", - "ref", "2", - "deblock", "1", - "signhide", "1", - "subme", "0", - "sao", "0", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "fast", - "pu-depth-intra", "1-3", - "pu-depth-inter", "0-3", - "rd", "1", - "me", "hexbs", - "ref", "2", - "deblock", "1", - "signhide", "1", - "subme", "1", - "sao", "0", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "medium", - "pu-depth-intra", "1-4", - "pu-depth-inter", "0-3", - "rd", "1", - "me", "hexbs", - "ref", "3", - "deblock", "1", - "signhide", "1", - "subme", "1", - "sao", "0", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "slow", - "pu-depth-intra", "1-4", - "pu-depth-inter", "0-3", - "rd", "2", - "me", "hexbs", - "ref", "3", - "deblock", "1", - "signhide", "1", - "subme", "1", - "sao", "1", - "rdoq", "0", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "slower", - "pu-depth-intra", "1-4", - "pu-depth-inter", "0-3", - "rd", "2", - "me", "tz", - "ref", "4", - "deblock", "1", - "signhide", "1", - "subme", "1", - "sao", "1", - "rdoq", "1", - "transform-skip", "0", - "full-intra-search", "0", - "mv-rdo", "0", - NULL - }, - { - "veryslow", - "pu-depth-intra", "1-4", - "pu-depth-inter", "0-3", - "rd", "2", - "me", "tz", - "ref", "4", - "deblock", "1", - "signhide", "1", - "subme", "1", - "sao", "1", - "rdoq", "1", - "transform-skip", "1", - "full-intra-search", "0", - "mv-rdo", "1", - NULL - }, - { - "placebo", - "pu-depth-intra", "0-4", - "pu-depth-inter", "0-3", - "rd", "3", - "me", "tz", - "ref", "6", - "deblock", "1", - "signhide", "1", - "subme", "1", - "sao", "1", - "rdoq", "1", - "transform-skip", "1", - "full-intra-search", "1", - "mv-rdo", "1", - NULL - }, - { NULL } - }; - - if (!name) - return 0; - - if (!value) - value = "true"; - - // Treat "--no-param" as --param 0 - if ((!strncmp(name, "no-", 3))) { - name += 3; - value = atobool(value) ? "false" : "true"; - } - -#define OPT(STR) (!strcmp(name, STR)) - if OPT("width") - cfg->width = atoi(value); - else if OPT("height") - cfg->height = atoi(value); - else if OPT("input-res") - if (!strcmp(value, "auto")) { - return 1; - } else { - return (sscanf(value, "%dx%d", &cfg->width, &cfg->height) == 2); - } - else if OPT("input-fps") { - int32_t fps_num, fps_denom; - if (sscanf(value, "%d/%d", &fps_num, &fps_denom) == 2) { - cfg->framerate_num = fps_num; - cfg->framerate_denom = fps_denom; - } else { - // Accept decimal notation, making sure not to round 0 to 1. - cfg->framerate_num = (int)(atof(value) * 1000 + 0.49); - cfg->framerate_denom = 1000; - } - } - else if OPT("qp") - cfg->qp = atoi(value); - else if OPT("period") - cfg->intra_period = atoi(value); - else if OPT("vps-period") - cfg->vps_period = atoi(value); - else if OPT("ref") - cfg->ref_frames = atoi(value); - else if 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 { - cfg->deblock_enable = atobool(value); - } - } - else if OPT("sao") - cfg->sao_enable = atobool(value); - else if OPT("rdoq") - cfg->rdoq_enable = atobool(value); - else if OPT("signhide") - cfg->signhide_enable = (bool)atobool(value); - else if OPT("smp") - cfg->smp_enable = (bool)atobool(value); - else if OPT("amp") - cfg->amp_enable = (bool)atobool(value); - else if OPT("rd") - cfg->rdo = atoi(value); - else if OPT("full-intra-search") - cfg->full_intra_search = atobool(value); - else if OPT("transform-skip") - cfg->trskip_enable = atobool(value); - else if OPT("tr-depth-intra") - cfg->tr_depth_intra = atoi(value); - else if OPT("me") { - int8_t ime_algorithm = 0; - if (!parse_enum(value, me_names, &ime_algorithm)) return 0; - cfg->ime_algorithm = ime_algorithm; - } - else if OPT("subme") - cfg->fme_level = atoi(value); - else if OPT("source-scan-type") - return parse_enum(value, source_scan_type_names, &cfg->source_scan_type); - else if OPT("sar") - return sscanf(value, "%d:%d", &cfg->vui.sar_width, &cfg->vui.sar_height) == 2; - else if OPT("overscan") - return parse_enum(value, overscan_names, &cfg->vui.overscan); - else if OPT("videoformat") - return parse_enum(value, videoformat_names, &cfg->vui.videoformat); - else if OPT("range") - return parse_enum(value, range_names, &cfg->vui.fullrange); - else if OPT("colorprim") - return parse_enum(value, colorprim_names, &cfg->vui.colorprim); - else if OPT("transfer") - return parse_enum(value, transfer_names, &cfg->vui.transfer); - else if OPT("colormatrix") - return parse_enum(value, colormatrix_names, &cfg->vui.colormatrix); - else if OPT("chromaloc") - cfg->vui.chroma_loc = atoi(value); - else if OPT("aud") - cfg->aud_enable = atobool(value); - else if OPT("cqmfile") - cfg->cqmfile = strdup(value); - else if OPT("tiles-width-split") - return parse_tiles_specification(value, &cfg->tiles_width_count, &cfg->tiles_width_split); - else if OPT("tiles-height-split") - return parse_tiles_specification(value, &cfg->tiles_height_count, &cfg->tiles_height_split); - else if OPT("wpp") - cfg->wpp = atobool(value); - else if OPT("owf") { - cfg->owf = atoi(value); - if (cfg->owf == 0 && !strcmp(value, "auto")) { - // -1 means automatic selection - cfg->owf = -1; - } - } - else if OPT("slice-addresses") - return parse_slice_specification(value, &cfg->slice_count, &cfg->slice_addresses_in_ts); - else if OPT("threads") - cfg->threads = atoi(value); - else if OPT("cpuid") - cfg->cpuid = atoi(value); - else if OPT("pu-depth-inter") - return sscanf(value, "%d-%d", &cfg->pu_depth_inter.min, &cfg->pu_depth_inter.max) == 2; - else if OPT("pu-depth-intra") - return sscanf(value, "%d-%d", &cfg->pu_depth_intra.min, &cfg->pu_depth_intra.max) == 2; - else if OPT("info") - cfg->add_encoder_info = atobool(value); - else if OPT("gop") { - if (!strncmp(value, "lp-", 3)) { // Handle GOPs starting with "lp-". - struct { - unsigned g; // length - unsigned d; // depth - unsigned r; // references - unsigned t; // temporal - } gop = { 0 }; - - if (sscanf(value, "lp-g%ud%ur%ut%u", &gop.g, &gop.d, &gop.r, &gop.t) != 4) { - fprintf(stderr, "Error in GOP syntax. Example: lp-g8d4r2t2\n"); - return 0; - } - - if (gop.g < 1 || gop.g > 32) { - fprintf(stderr, "gop.g must be between 1 and 32.\n"); - } - if (gop.d < 1 || gop.d > 8) { - fprintf(stderr, "gop.d must be between 1 and 8.\n"); - } - if (gop.r < 1 || gop.r > 15) { - fprintf(stderr, "gop.d must be between 1 and 15.\n"); - } - if (gop.t < 1 || gop.t > 15) { - fprintf(stderr, "gop.t must be between 1 and 32.\n"); - } - - // Initialize modulos for testing depth. - // The picture belong to the lowest depth in which (poc % modulo) == 0. - unsigned depth_modulos[8] = { 0 }; - for (int d = 0; d < gop.d; ++d) { - depth_modulos[gop.d - 1 - d] = 1 << d; - } - depth_modulos[0] = gop.g; - - cfg->gop_lowdelay = 1; - cfg->gop_len = gop.g; - for (int g = 1; g <= gop.g; ++g) { - kvz_gop_config *gop_pic = &cfg->gop[g - 1]; - - // Find gop depth for picture. - int gop_layer = 0; - while (gop_layer < gop.d && (g % depth_modulos[gop_layer])) { - ++gop_layer; - } - - gop_pic->poc_offset = g; - gop_pic->layer = gop_layer + 1; - gop_pic->qp_offset = gop_layer + 1; - gop_pic->ref_pos_count = 0; - gop_pic->ref_neg_count = gop.r; - gop_pic->is_ref = 0; - - // Set first ref to point to previous frame, and the rest to previous - // key-frames. - // If gop.t > 1, have (poc % gop.t) == 0 point gop.t frames away, - // instead of the previous frame. Set the frames in between to - // point to the nearest frame with a lower gop-depth. - if (gop.t > 1) { - if (gop_pic->poc_offset % gop.t == 0) { - gop_pic->ref_neg[0] = gop.t; - } else { - int r = gop_pic->poc_offset - 1; - while (r > 0) { - if (cfg->gop[r].layer < gop_pic->layer) break; - --r; - } - // Var r is now 0 or index of the pic with layer < depth. - if (cfg->gop[r].layer < gop_pic->layer) { - gop_pic->ref_neg[0] = gop_pic->poc_offset - cfg->gop[r].poc_offset; - cfg->gop[r].is_ref = 1; - } else { - // No ref was found, just refer to the previous key-frame. - gop_pic->ref_neg[0] = gop_pic->poc_offset % gop.g; - } - } - } else { - gop_pic->ref_neg[0] = 1; - if (gop_pic->poc_offset >= 2) { - cfg->gop[gop_pic->poc_offset - 2].is_ref = 1; - } - } - - int keyframe = gop_pic->poc_offset; - for (int i = 1; i < gop_pic->ref_neg_count; ++i) { - while (keyframe == gop_pic->ref_neg[i - 1]) { - keyframe += gop.g; - } - gop_pic->ref_neg[i] = keyframe; - } - - gop_pic->qp_factor = 0.4624; // from HM - } - - for (int g = 0; g < gop.g; ++g) { - kvz_gop_config *gop_pic = &cfg->gop[g]; - if (!gop_pic->is_ref) { - gop_pic->qp_factor = 0.68 * 1.31; // derived from HM - } - } - - // Key-frame is always a reference. - cfg->gop[gop.g - 1].is_ref = 1; - cfg->gop[gop.g - 1].qp_factor = 0.578; // from HM - } else if (atoi(value) == 8) { - cfg->gop_lowdelay = 0; - // GOP - cfg->gop_len = 8; - cfg->gop[0].poc_offset = 8; cfg->gop[0].qp_offset = 1; cfg->gop[0].layer = 1; cfg->gop[0].qp_factor = 0.442; cfg->gop[0].is_ref = 1; - cfg->gop[0].ref_pos_count = 0; - cfg->gop[0].ref_neg_count = 3; cfg->gop[0].ref_neg[0] = 8; cfg->gop[0].ref_neg[1] = 12; cfg->gop[0].ref_neg[2] = 16; - - cfg->gop[1].poc_offset = 4; cfg->gop[1].qp_offset = 2; cfg->gop[1].layer = 2; cfg->gop[1].qp_factor = 0.3536; cfg->gop[1].is_ref = 1; - cfg->gop[1].ref_neg_count = 2; cfg->gop[1].ref_neg[0] = 4; cfg->gop[1].ref_neg[1] = 8; - cfg->gop[1].ref_pos_count = 1; cfg->gop[1].ref_pos[0] = 4; - - cfg->gop[2].poc_offset = 2; cfg->gop[2].qp_offset = 3; cfg->gop[2].layer = 3; cfg->gop[2].qp_factor = 0.3536; cfg->gop[2].is_ref = 1; - cfg->gop[2].ref_neg_count = 2; cfg->gop[2].ref_neg[0] = 2; cfg->gop[2].ref_neg[1] = 6; - cfg->gop[2].ref_pos_count = 2; cfg->gop[2].ref_pos[0] = 2; cfg->gop[2].ref_pos[1] = 6; - - cfg->gop[3].poc_offset = 1; cfg->gop[3].qp_offset = 4; cfg->gop[3].layer = 4; cfg->gop[3].qp_factor = 0.68; cfg->gop[3].is_ref = 0; - cfg->gop[3].ref_neg_count = 1; cfg->gop[3].ref_neg[0] = 1; - cfg->gop[3].ref_pos_count = 3; cfg->gop[3].ref_pos[0] = 1; cfg->gop[3].ref_pos[1] = 3; cfg->gop[3].ref_pos[2] = 7; - - cfg->gop[4].poc_offset = 3; cfg->gop[4].qp_offset = 4; cfg->gop[4].layer = 4; cfg->gop[4].qp_factor = 0.68; cfg->gop[4].is_ref = 0; - cfg->gop[4].ref_neg_count = 2; cfg->gop[4].ref_neg[0] = 1; cfg->gop[4].ref_neg[1] = 3; - cfg->gop[4].ref_pos_count = 2; cfg->gop[4].ref_pos[0] = 1; cfg->gop[4].ref_pos[1] = 5; - - cfg->gop[5].poc_offset = 6; cfg->gop[5].qp_offset = 3; cfg->gop[5].layer = 3; cfg->gop[5].qp_factor = 0.3536; cfg->gop[5].is_ref = 1; - cfg->gop[5].ref_neg_count = 2; cfg->gop[5].ref_neg[0] = 2; cfg->gop[5].ref_neg[1] = 6; - cfg->gop[5].ref_pos_count = 1; cfg->gop[5].ref_pos[0] = 2; - - cfg->gop[6].poc_offset = 5; cfg->gop[6].qp_offset = 4; cfg->gop[6].layer = 4; cfg->gop[6].qp_factor = 0.68; cfg->gop[6].is_ref = 0; - cfg->gop[6].ref_neg_count = 2; cfg->gop[6].ref_neg[0] = 1; cfg->gop[6].ref_neg[1] = 5; - cfg->gop[6].ref_pos_count = 2; cfg->gop[6].ref_pos[0] = 1; cfg->gop[6].ref_pos[1] = 3; - - cfg->gop[7].poc_offset = 7; cfg->gop[7].qp_offset = 4; cfg->gop[7].layer = 4; cfg->gop[7].qp_factor = 0.68; cfg->gop[7].is_ref = 0; - cfg->gop[7].ref_neg_count = 3; cfg->gop[7].ref_neg[0] = 1; cfg->gop[7].ref_neg[1] = 3; cfg->gop[7].ref_neg[2] = 7; - cfg->gop[7].ref_pos_count = 1; cfg->gop[7].ref_pos[0] = 1; - } else if (atoi(value)) { - fprintf(stderr, "Input error: unsupported gop length, must be 0 or 8\n"); - return 0; - } - } - else if OPT("bipred") - cfg->bipred = atobool(value); - else if OPT("bitrate") - cfg->target_bitrate = atoi(value); - else if OPT("preset") { - int preset_line = 0; - - // Accept numbers from 0 to 9. - if ((atoi(value) == 0 && !strcmp(value, "0")) || (atoi(value) >= 1 && atoi(value) <= 9)) { - preset_line = atoi(value); - } else { - // Find the selected preset from the list - while (preset_values[preset_line][0] != NULL) { - if (!strcmp(value, preset_values[preset_line][0])) { - break; - } - preset_line++; - } - } - - if (preset_values[preset_line][0] != NULL) { - fprintf(stderr, "Using preset %s: ", value); - // Loop all the name and value pairs and push to the config parser - for (int preset_value = 1; preset_values[preset_line][preset_value] != NULL; preset_value += 2) { - fprintf(stderr, "--%s=%s ", preset_values[preset_line][preset_value], preset_values[preset_line][preset_value + 1]); - kvz_config_parse(cfg, preset_values[preset_line][preset_value], preset_values[preset_line][preset_value + 1]); - } - fprintf(stderr, "\n"); - } else { - fprintf(stderr, "Input error: unknown preset \"%s\"\n", value); - return 0; - } - } - else if OPT("mv-rdo") - cfg->mv_rdo = atobool(value); - else - return 0; -#undef OPT - - return 1; -} - -/** - * \brief Check that configuration is sensible. - * - * \param cfg config to check - * \return 1 if the config is ok, otherwise 1 - */ -int kvz_config_validate(const kvz_config *const cfg) -{ - int error = 0; - - if (cfg->width <= 0) { - fprintf(stderr, "Input error: width must be positive\n"); - error = 1; - } - - if (cfg->height <= 0) { - fprintf(stderr, "Input error: height must be positive\n"); - error = 1; - } - - if (cfg->width % 2 != 0) { - fprintf(stderr, "Input error: width must be a multiple of two\n"); - error = 1; - } - - if (cfg->height % 2 != 0) { - fprintf(stderr, "Input error: height must be a multiple of two\n"); - error = 1; - } - - if (cfg->framerate < 0.0) { - fprintf(stderr, "Input error: --input-fps must be positive\n"); - error = 1; - } - if (cfg->framerate_num < 0) { - fprintf(stderr, "Input error: --input-fps must >=0\n"); - error = 1; - } - if (cfg->framerate_denom <= 0) { - fprintf(stderr, "Input error: --input-fps denominator must be >0\n"); - error = 1; - } - - if (cfg->gop_len && - cfg->intra_period && - cfg->intra_period % cfg->gop_len != 0) { - fprintf(stderr, - "Input error: intra period (%d) not a multiple of gop length (%d)\n", - cfg->intra_period, - cfg->gop_len); - error = 1; - } - - if (cfg->ref_frames < 1 || cfg->ref_frames >= MAX_REF_PIC_COUNT) { - fprintf(stderr, "Input error: --ref out of range [1..%d]\n", MAX_REF_PIC_COUNT - 1); - error = 1; - } - - if (cfg->deblock_beta < -6 || cfg->deblock_beta > 6) { - fprintf(stderr, "Input error: deblock beta parameter out of range [-6..6]\n"); - error = 1; - } - if (cfg->deblock_tc < -6 || cfg->deblock_tc > 6) { - fprintf(stderr, "Input error: deblock tc parameter out of range [-6..6]\n"); - error = 1; - } - - if (cfg->rdo < 0 || cfg->rdo > 3) { - fprintf(stderr, "Input error: --rd parameter out of range [0..3]\n"); - error = 1; - } - - if (cfg->tr_depth_intra < 0 || cfg->tr_depth_intra > 4) { - // range is 0 .. CtbLog2SizeY - Log2MinTrafoSize - fprintf(stderr, "Input error: --tr-depth-intra is out of range [0..4]\n"); - error = 1; - } - - if (cfg->fme_level != 0 && cfg->fme_level != 1) { - fprintf(stderr, "Input error: invalid --subme parameter (must be 0 or 1)\n"); - error = 1; - } - - if (cfg->vui.chroma_loc < 0 || cfg->vui.chroma_loc > 5) { - fprintf(stderr, "Input error: --chromaloc parameter out of range [0..5]\n"); - error = 1; - } - - if (cfg->owf < -1) { - fprintf(stderr, "Input error: --owf must be nonnegative or -1\n"); - error = 1; - } - - if (cfg->target_bitrate < 0) { - fprintf(stderr, "Input error: --bitrate must be nonnegative\n"); - error = 1; - } - - if (!WITHIN(cfg->pu_depth_inter.min, PU_DEPTH_INTER_MIN, PU_DEPTH_INTER_MAX) || - !WITHIN(cfg->pu_depth_inter.max, PU_DEPTH_INTER_MIN, PU_DEPTH_INTER_MAX)) - { - fprintf(stderr, "Input error: illegal value for --pu-depth-inter (%d-%d)\n", - cfg->pu_depth_inter.min, cfg->pu_depth_inter.max); - error = 1; - } else if (cfg->pu_depth_inter.min > cfg->pu_depth_inter.max) { - fprintf(stderr, "Input error: Inter PU depth min (%d) > max (%d)\n", - cfg->pu_depth_inter.min, cfg->pu_depth_inter.max); - error = 1; - } - - if (!WITHIN(cfg->pu_depth_intra.min, PU_DEPTH_INTRA_MIN, PU_DEPTH_INTRA_MAX) || - !WITHIN(cfg->pu_depth_intra.max, PU_DEPTH_INTRA_MIN, PU_DEPTH_INTRA_MAX)) - { - fprintf(stderr, "Input error: illegal value for --pu-depth-intra (%d-%d)\n", - cfg->pu_depth_intra.min, cfg->pu_depth_intra.max); - error = 1; - } else if (cfg->pu_depth_intra.min > cfg->pu_depth_intra.max) { - fprintf(stderr, "Input error: Intra PU depth min (%d) > max (%d)\n", - cfg->pu_depth_intra.min, cfg->pu_depth_intra.max); - error = 1; - } - - // Tile separation should be at round position in terms of LCU, should be monotonic, and should not start by 0 - if (cfg->tiles_width_split) { - int i; - int32_t prev_tile_split = 0; - for (i=0; i < cfg->tiles_width_count; ++i) { - if (cfg->tiles_width_split[i] <= prev_tile_split) { - fprintf(stderr, "Input error: tile separations in width should be strictly monotonic (%d <= %d)\n", cfg->tiles_width_split[i], prev_tile_split); - error = 1; - break; - } - if ((cfg->tiles_width_split[i] % LCU_WIDTH) != 0) { - fprintf(stderr, "Input error: tile separation in width %d (at %d) is not at a multiple of LCU_WIDTH (%d)\n", i, cfg->tiles_width_split[i], LCU_WIDTH); - error = 1; - break; - } - prev_tile_split = cfg->tiles_width_split[i]; - } - if (cfg->tiles_width_split[cfg->tiles_width_count-1] >= cfg->width) { - fprintf(stderr, "Input error: last x tile separation in width (%d) should smaller than image width (%d)\n", cfg->tiles_width_split[cfg->tiles_width_count-1], cfg->width); - error = 1; - } - } - - if (cfg->tiles_height_split) { - int i; - int32_t prev_tile_split = 0; - for (i=0; i < cfg->tiles_height_count; ++i) { - if (cfg->tiles_height_split[i] <= prev_tile_split) { - fprintf(stderr, "Input error: tile separations in height should be strictly monotonic (%d <= %d)\n", cfg->tiles_height_split[i], prev_tile_split); - error = 1; - break; - } - if ((cfg->tiles_height_split[i] % LCU_WIDTH) != 0) { - fprintf(stderr, "Input error: tile separation in height %d (at %d) is not at a multiple of LCU_WIDTH (%d)\n", i, cfg->tiles_height_split[i], LCU_WIDTH); - error = 1; - break; - } - prev_tile_split = cfg->tiles_height_split[i]; - } - - if (cfg->tiles_height_split[cfg->tiles_height_count-1] >= cfg->height) { - fprintf(stderr, "Input error: last tile separation in height (%d) should smaller than image height (%d)\n", cfg->tiles_height_split[cfg->tiles_height_count-1], cfg->height); - error = 1; - } - } - - return !error; -}
View file
kvazaar-0.8.2.tar.gz/src/config.h
Deleted
@@ -1,39 +0,0 @@ -#ifndef CONFIG_H_ -#define CONFIG_H_ -/***************************************************************************** - * This file is part of Kvazaar HEVC encoder. - * - * Copyright (C) 2013-2015 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 Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * 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 Lesser 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/>. - ****************************************************************************/ - -/** - * \ingroup Control - * \file - * Runtime configuration through defaults and parsing of arguments. - */ - -#include "kvazaar.h" -#include "global.h" - -/* Function definitions */ -kvz_config *kvz_config_alloc(void); -int kvz_config_init(kvz_config *cfg); -int kvz_config_destroy(kvz_config *cfg); -int kvz_config_parse(kvz_config *cfg, const char *name, const char *value); -int kvz_config_validate(const kvz_config *cfg); - -#endif
View file
kvazaar-0.8.2.tar.gz/src/kvazaar_version.h
Deleted
@@ -1,32 +0,0 @@ -#ifndef KVAZAAR_VERSION_H_ -#define KVAZAAR_VERSION_H_ -/***************************************************************************** -* This file is part of Kvazaar HEVC encoder. -* -* Copyright (C) 2013-2015 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 Lesser General Public License as published by the -* Free Software Foundation; either version 2.1 of the License, or (at your -* option) any later version. -* -* 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 Lesser 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/>. -****************************************************************************/ - -/** - * \ingroup Control - * \file - * \brief Libkvazaar version numbers. - */ - -// KVZ_API_VERSION is incremented every time the public api changes. -#define KVZ_API_VERSION 10 - -#endif // KVAZAAR_VERSION_H_
View file
kvazaar-0.8.2.tar.gz/.gitignore -> kvazaar-0.8.3.tar.gz/.gitignore
Changed
@@ -24,27 +24,29 @@ /config.h.in* /config.status /configure -/kvazaar /libtool -/m4 +/m4/libtool.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 +/m4/lt~obsolete.m4 /stamp-h1 # Other files +*.a +*.d +*.dll +*.dylib *.exe -*.o +*.la *.lo -*.d +*.o *.log .kdev4 configure.scan src/kvazaar -src/libkvazaar.a -src/libkvazaar.la src/libkvazaar.so.* -src/kvazaar.dll -src/libkvazaar.dll.a -src/libkvazaar.*.dylib src/kvazaar.pc tests/kvazaar_tests tests/kvazaar_tests.trs
View file
kvazaar-0.8.2.tar.gz/.travis-script.sh -> kvazaar-0.8.3.tar.gz/.travis-script.sh
Changed
@@ -3,7 +3,7 @@ ./autogen.sh ./configure -make +make --jobs=2 V=1 if [ -n "$VALGRIND_TEST" ]; then libtool execute valgrind --leak-check=full --error-exitcode=1 -- \
View file
kvazaar-0.8.2.tar.gz/.travis.yml -> kvazaar-0.8.3.tar.gz/.travis.yml
Changed
@@ -5,7 +5,6 @@ - KVZ_DISABLE_AVX2=1 - TEST_DIM=264x130 - TEST_FRAMES=10 - - MAKEFLAGS="--jobs=2 --environment-overrides" sudo: false @@ -26,6 +25,9 @@ # These valgrind tests are slow, so they are performed with the minimum # number of small frames and fast settings. + # Tests for interlace + - env: VALGRIND_TEST="--source-scan-type=tff -p0 --preset=ultrafast --threads=2 --owf=1 --wpp" + # Tests for owf, wpp and tiles. There is lots of separate branches of # code related to owf=0 and owf!=0, which is why all permutations are # tried.
View file
kvazaar-0.8.2.tar.gz/README.md -> kvazaar-0.8.3.tar.gz/README.md
Changed
@@ -79,6 +79,7 @@ --preset <string> : Use preset. This will override previous options. ultrafast, superfast,veryfast, faster, fast, medium, slow, slower, veryslow, placebo + --no-psnr : Don't calculate PSNR for frames Video Usability Information: --sar <width:height> : Specify Sample Aspect Ratio
View file
kvazaar-0.8.2.tar.gz/autogen.sh -> kvazaar-0.8.3.tar.gz/autogen.sh
Changed
@@ -2,5 +2,4 @@ git submodule init git submodule update -mkdir -p m4 autoreconf -if
View file
kvazaar-0.8.2.tar.gz/build/kvazaar_lib/kvazaar_lib.vcxproj -> kvazaar-0.8.3.tar.gz/build/kvazaar_lib/kvazaar_lib.vcxproj
Changed
@@ -129,7 +129,7 @@ <ClCompile Include="..\..\src\kvazaar.c" /> <ClCompile Include="..\..\src\bitstream.c" /> <ClCompile Include="..\..\src\cabac.c" /> - <ClCompile Include="..\..\src\config.c" /> + <ClCompile Include="..\..\src\cfg.c" /> <ClCompile Include="..\..\src\context.c" /> <ClCompile Include="..\..\src\cu.c" /> <ClCompile Include="..\..\src\encoder.c" /> @@ -224,7 +224,7 @@ <ItemGroup> <ClInclude Include="..\..\src\bitstream.h" /> <ClInclude Include="..\..\src\cabac.h" /> - <ClInclude Include="..\..\src\config.h" /> + <ClInclude Include="..\..\src\cfg.h" /> <ClInclude Include="..\..\src\context.h" /> <ClInclude Include="..\..\src\encoder.h" /> <ClInclude Include="..\..\src\encoderstate.h" /> @@ -234,7 +234,6 @@ <ClInclude Include="..\..\src\inter.h" /> <ClInclude Include="..\..\src\intra.h" /> <ClInclude Include="..\..\src\kvazaar.h" /> - <ClInclude Include="..\..\src\kvazaar_version.h" /> <ClInclude Include="..\..\src\nal.h" /> <ClInclude Include="..\..\src\rate_control.h" /> <ClInclude Include="..\..\src\rdo.h" /> @@ -279,4 +278,4 @@ <ImportGroup Label="ExtensionTargets"> <Import Project="..\yasm\vsyasm.targets" /> </ImportGroup> -</Project> \ No newline at end of file +</Project>
View file
kvazaar-0.8.2.tar.gz/build/kvazaar_lib/kvazaar_lib.vcxproj.filters -> kvazaar-0.8.3.tar.gz/build/kvazaar_lib/kvazaar_lib.vcxproj.filters
Changed
@@ -144,7 +144,7 @@ <ClCompile Include="..\..\src\bitstream.c"> <Filter>CABAC</Filter> </ClCompile> - <ClCompile Include="..\..\src\config.c"> + <ClCompile Include="..\..\src\cfg.c"> <Filter>Control</Filter> </ClCompile> <ClCompile Include="..\..\src\filter.c"> @@ -218,7 +218,7 @@ <ClInclude Include="..\..\src\context.h"> <Filter>CABAC</Filter> </ClInclude> - <ClInclude Include="..\..\src\config.h"> + <ClInclude Include="..\..\src\cfg.h"> <Filter>Control</Filter> </ClInclude> <ClInclude Include="..\..\src\encoder.h"> @@ -251,9 +251,6 @@ <ClInclude Include="..\..\src\kvazaar_internal.h"> <Filter>Control</Filter> </ClInclude> - <ClInclude Include="..\..\src\kvazaar_version.h"> - <Filter>Control</Filter> - </ClInclude> <ClInclude Include="..\..\src\videoframe.h"> <Filter>Data structures</Filter> </ClInclude> @@ -397,4 +394,4 @@ <Filter>Optimization\strategies\x86_asm</Filter> </YASM> </ItemGroup> -</Project> \ No newline at end of file +</Project>
View file
kvazaar-0.8.2.tar.gz/build/kvazaar_tests/kvazaar_tests.vcxproj -> kvazaar-0.8.3.tar.gz/build/kvazaar_tests/kvazaar_tests.vcxproj
Changed
@@ -100,6 +100,7 @@ <ClCompile Include="..\..\tests\dct_tests.c" /> <ClCompile Include="..\..\tests\test_strategies.c" /> <ClCompile Include="..\..\tests\intra_sad_tests.c" /> + <ClCompile Include="..\..\tests\mv_cand_tests.c" /> <ClCompile Include="..\..\tests\sad_tests.c" /> <ClCompile Include="..\..\tests\satd_tests.c" /> <ClCompile Include="..\..\tests\speed_tests.c" /> @@ -113,4 +114,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project>
View file
kvazaar-0.8.2.tar.gz/build/kvazaar_tests/kvazaar_tests.vcxproj.filters -> kvazaar-0.8.3.tar.gz/build/kvazaar_tests/kvazaar_tests.vcxproj.filters
Changed
@@ -24,6 +24,9 @@ <ClCompile Include="..\..\tests\intra_sad_tests.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\tests\mv_cand_tests.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\..\tests\satd_tests.c"> <Filter>Source Files</Filter> </ClCompile> @@ -48,4 +51,4 @@ <Filter>Header Files</Filter> </ClInclude> </ItemGroup> -</Project> \ No newline at end of file +</Project>
View file
kvazaar-0.8.2.tar.gz/configure.ac -> kvazaar-0.8.3.tar.gz/configure.ac
Changed
@@ -14,14 +14,16 @@ # - Increment when ABI changes, meaning lib users need to be recompiled. # - ABI changes when anything existing gets modified, including sizes of structs. # minor: -# - Increment when only API changes. Because the function pointers are in a struct, that means basically never? +# - Increment when only API changes in a backwards compatible way without breaking ABI. +# - We count adding parameters to bottom of kvz_config as ABI compatible, because user +# shouldn't copy that struct or care about it's size. # - If not sure, increment major instead. # release: # - Increment when making new releases and major or minor was not changed since last release. # # Here is a somewhat sane guide to lib versioning: http://apr.apache.org/versioning.html ver_major=3 -ver_minor=0 +ver_minor=2 ver_release=0 # not used, but it prevents configure from adding a lot of defines to the CFLAGS @@ -34,13 +36,30 @@ AM_SILENT_RULES([yes]) AC_PROG_CC +AC_PROG_CC_C99 AM_PROG_AR +# Get fread that can read more than 2GB on 32 bit systems. +AC_SYS_LARGEFILE + LT_INIT([win32-dll]) +AX_CHECK_COMPILE_FLAG(-mavx2, [flag_avx2="true"]) +AX_CHECK_COMPILE_FLAG(-msse4.1, [flag_sse4_1="true"]) +AX_CHECK_COMPILE_FLAG(-msse2, [flag_sse2="true"]) + +AM_CONDITIONAL([HAVE_AVX2], [test x"$flag_avx2" = x"true"]) +AM_CONDITIONAL([HAVE_SSE4_1], [test x"$flag_sse4_1" = x"true"]) +AM_CONDITIONAL([HAVE_SSE2], [test x"$flag_sse2" = x"true"]) + +AX_PTHREAD +CFLAGS="-Wall -Wtype-limits -Wvla -I$srcdir/src -ftree-vectorize -fvisibility=hidden $PTHREAD_CFLAGS $CFLAGS" +CPPFLAGS="-DKVZ_DLL_EXPORTS $CPPFLAGS" -CFLAGS="-Wall -Wtype-limits -Wvla -I$srcdir/src -ftree-vectorize -fvisibility=hidden -std=gnu99 -DKVZ_DLL_EXPORTS $CFLAGS" -LIBS="-lm $LIBS" +AC_SEARCH_LIBS([log], [m c], [], [exit 1]) +AC_SEARCH_LIBS([pow], [m c], [], [exit 1]) +AC_SEARCH_LIBS([sqrt], [m c], [], [exit 1]) +LIBS="$PTHREAD_LIBS $LIBS" # --disable-werror @@ -57,8 +76,7 @@ AS_CASE([$host_cpu], [i?86], [BITS="32" ASFLAGS="$ASFLAGS -DARCH_X86_64=0" X86="true"], [x86_64], [BITS="64" ASFLAGS="$ASFLAGS -DARCH_X86_64=1 -m amd64" X86="true"], - [powerpc*], [PPC="true"], - [arm*], [ARM="true"] + [powerpc*], [PPC="true"] ) AS_CASE([$host_os], @@ -74,11 +92,14 @@ ASFLAGS="$ASFLAGS -fwin64 -DHAVE_ALIGNED_STACK=1" ] ) + ], + [linux*|*kfreebsd*], [ + ASFLAGS="$ASFLAGS -f elf$BITS" + LDFLAGS="$LDFLAGS -Wl,-z,noexecstack" + LIBS="$LIBS -lrt" ], [ ASFLAGS="$ASFLAGS -f elf$BITS" - CFLAGS="$CFLAGS -pthread" - LDFLAGS="$LDFLAGS -pthread -Wl,-z,noexecstack" - LIBS="$LIBS -lrt -lpthread" + LDFLAGS="$LDFLAGS -Wl,-z,noexecstack" ] ) @@ -105,10 +126,6 @@ AC_ARG_VAR([ASFLAGS], [ASFLAGS to use for assembler]) AC_SUBST([ASFLAGS]) -# use KVZ_API_VERSION for sonames -#KVZ_API_VERSION="$($AWK '/#define KVZ_API_VERSION/ { print $3 }' $srcdir/src/kvazaar_version.h)" - -# use library version for sonames (specified in src/Makefile) KVZ_API_VERSION="$ver_major:$ver_minor:$ver_release" AC_SUBST([KVZ_API_VERSION])
View file
kvazaar-0.8.3.tar.gz/m4
Added
+(directory)
View file
kvazaar-0.8.3.tar.gz/m4/ax_check_compile_flag.m4
Added
@@ -0,0 +1,74 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 4 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS
View file
kvazaar-0.8.3.tar.gz/m4/ax_pthread.m4
Added
@@ -0,0 +1,332 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> +# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 21 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +# Clang doesn't consider unrecognized options an error unless we specify +# -Werror. We throw in some extra Clang-specific options to ensure that +# this doesn't happen for GCC, which also accepts -Werror. + +AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) +save_CFLAGS="$CFLAGS" +ax_pthread_extra_flags="-Werror" +CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], + [AC_MSG_RESULT([yes])], + [ax_pthread_extra_flags= + AC_MSG_RESULT([no])]) +CFLAGS="$save_CFLAGS" + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT([$attr_name]) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + # TODO: What about Clang on Solaris? + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT([$flag]) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != xyes; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD
View file
kvazaar-0.8.2.tar.gz/src/Makefile.am -> kvazaar-0.8.3.tar.gz/src/Makefile.am
Changed
@@ -1,4 +1,3 @@ - bin_PROGRAMS = kvazaar lib_LTLIBRARIES = libkvazaar.la @@ -13,12 +12,16 @@ include_HEADERS = \ - kvazaar.h \ - kvazaar_version.h + kvazaar.h noinst_HEADERS = \ extras/x86inc.asm +noinst_LTLIBRARIES = \ + libaltivec.la \ + libavx2.la \ + libsse2.la \ + libsse41.la kvazaar_SOURCES = \ encmain.c \ @@ -36,8 +39,8 @@ cabac.h \ checkpoint.c \ checkpoint.h \ - config.c \ - config.h \ + cfg.c \ + cfg.h \ context.c \ context.h \ cu.c \ @@ -92,8 +95,6 @@ transform.h \ videoframe.c \ videoframe.h \ - strategies/altivec/picture-altivec.c \ - strategies/altivec/picture-altivec.h \ strategies/generic/dct-generic.c \ strategies/generic/dct-generic.h \ strategies/generic/intra-generic.c \ @@ -106,10 +107,6 @@ strategies/generic/picture-generic.h \ strategies/generic/quant-generic.c \ strategies/generic/quant-generic.h \ - strategies/sse2/picture-sse2.c \ - strategies/sse2/picture-sse2.h \ - strategies/sse41/picture-sse41.c \ - strategies/sse41/picture-sse41.h \ strategies/strategies-common.h \ strategies/strategies-dct.c \ strategies/strategies-dct.h \ @@ -128,7 +125,20 @@ strategyselector.c \ strategyselector.h -avx2_sources = \ +libkvazaar_la_LIBADD = \ + libaltivec.la \ + libavx2.la \ + libsse2.la \ + libsse41.la + +libkvazaar_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-number $(KVZ_API_VERSION) + + +libaltivec_la_SOURCES = \ + strategies/altivec/picture-altivec.c \ + strategies/altivec/picture-altivec.h + +libavx2_la_SOURCES = \ strategies/avx2/dct-avx2.c \ strategies/avx2/dct-avx2.h \ strategies/avx2/intra-avx2.c \ @@ -140,36 +150,45 @@ strategies/avx2/quant-avx2.c \ strategies/avx2/quant-avx2.h -libkvazaar_la_SOURCES += $(avx2_sources) -libkvazaar_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-number $(KVZ_API_VERSION) +libsse2_la_SOURCES = \ + strategies/sse2/picture-sse2.c \ + strategies/sse2/picture-sse2.h +libsse41_la_SOURCES = \ + strategies/sse41/picture-sse41.c \ + strategies/sse41/picture-sse41.h if HAVE_PPC - -strategies/altivec/picture-altivec.lo: CFLAGS += -maltivec - -else #HAVE_PPC +libaltivec_la_CFLAGS = -maltivec +endif if HAVE_X86 -strategies/sse2/picture-sse2.lo: CFLAGS += -msse2 -strategies/sse41/picture-sse41.lo: CFLAGS += -msse4.1 -$(avx2_sources): CFLAGS += -mavx2 + +if HAVE_AVX2 +libavx2_la_CFLAGS = -mavx2 +endif +if HAVE_SSE4_1 +libsse41_la_CFLAGS = -msse4.1 +endif +if HAVE_SSE2 +libsse2_la_CFLAGS = -msse2 +endif if ENABLE_ASM -libkvazaar_la_SOURCES += \ +noinst_LTLIBRARIES += libasm.la +libkvazaar_la_LIBADD += libasm.la +libasm_la_SOURCES = \ strategies/x86_asm/picture-x86-asm-sad.asm \ strategies/x86_asm/picture-x86-asm-sad.h \ strategies/x86_asm/picture-x86-asm-satd.asm \ strategies/x86_asm/picture-x86-asm-satd.h +libasm_la_CFLAGS = -DKVZ_COMPILE_ASM -strategies/x86_asm/picture-x86-asm.lo: CFLAGS += -DKVZ_COMPILE_ASM strategies/x86_asm/picture-x86-asm-sad.lo: strategies/x86_asm/picture-x86-asm-sad.asm strategies/x86_asm/picture-x86-asm-satd.lo: strategies/x86_asm/picture-x86-asm-satd.asm endif #ENABLE_ASM endif #HAVE_X86 -endif #HAVE_PPC - yasm_verbose = $(yasm_verbose_@AM_V@) yasm_verbose_ = $(yasm_verbose_@AM_DEFAULT_V@)
View file
kvazaar-0.8.2.tar.gz/src/bitstream.h -> kvazaar-0.8.3.tar.gz/src/bitstream.h
Changed
@@ -26,9 +26,10 @@ * Appending bits into an Annex-B coded bitstream. */ -#include "kvazaar.h" #include "global.h" +#include "kvazaar.h" + /** * A stream of bits. */
View file
kvazaar-0.8.3.tar.gz/src/cfg.c
Added
@@ -0,0 +1,938 @@ +/***************************************************************************** + * This file is part of Kvazaar HEVC encoder. + * + * Copyright (C) 2013-2015 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 Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * 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 Lesser 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/>. + ****************************************************************************/ + +#include "cfg.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +kvz_config *kvz_config_alloc(void) +{ + kvz_config *cfg = (kvz_config *)malloc(sizeof(kvz_config)); + if (!cfg) { + fprintf(stderr, "Failed to allocate a config object!\n"); + return cfg; + } + + FILL(*cfg, 0); + + return cfg; +} + +int kvz_config_init(kvz_config *cfg) +{ + cfg->width = 0; + cfg->height = 0; + cfg->framerate = 25; // deprecated and will be removed. + cfg->framerate_num = 0; + cfg->framerate_denom = 1; + cfg->qp = 32; + cfg->intra_period = 0; + cfg->vps_period = 0; + cfg->deblock_enable = 1; + cfg->deblock_beta = 0; + cfg->deblock_tc = 0; + cfg->sao_enable = 1; + cfg->rdoq_enable = 1; + cfg->signhide_enable = true; + cfg->smp_enable = false; + cfg->amp_enable = false; + cfg->rdo = 1; + cfg->mv_rdo = 0; + cfg->full_intra_search = 0; + cfg->trskip_enable = 1; + cfg->tr_depth_intra = 0; + cfg->ime_algorithm = 0; /* hexbs */ + cfg->fme_level = 1; + cfg->source_scan_type = 0; /* progressive */ + 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; + cfg->ref_frames = DEFAULT_REF_PIC_COUNT; + cfg->gop_len = 0; + cfg->bipred = 0; + cfg->target_bitrate = 0; + + cfg->tiles_width_count = 0; + cfg->tiles_height_count = 0; + cfg->tiles_width_split = NULL; + cfg->tiles_height_split = NULL; + + cfg->wpp = 0; + cfg->owf = -1; + cfg->slice_count = 1; + cfg->slice_addresses_in_ts = MALLOC(int32_t, 1); + cfg->slice_addresses_in_ts[0] = 0; + + cfg->threads = 0; + cfg->cpuid = 1; + + // Defaults for what sizes of PUs are tried. + cfg->pu_depth_inter.min = 0; // 0-3 + cfg->pu_depth_inter.max = 3; // 0-3 + cfg->pu_depth_intra.min = 1; // 0-4 + cfg->pu_depth_intra.max = 4; // 0-4 + + cfg->add_encoder_info = true; + cfg->calc_psnr = true; + + return 1; +} + +int kvz_config_destroy(kvz_config *cfg) +{ + if (cfg) { + FREE_POINTER(cfg->cqmfile); + FREE_POINTER(cfg->tiles_width_split); + FREE_POINTER(cfg->tiles_height_split); + FREE_POINTER(cfg->slice_addresses_in_ts); + } + free(cfg); + + return 1; +} + +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) +{ + int8_t i; + for (i = 0; names[i]; i++) { + if (!strcmp(arg, names[i])) { + *dst = i; + return 1; + } + } + + return 0; +} + +static int parse_tiles_specification(const char* const arg, int32_t * const ntiles, int32_t** const array) { + const char* current_arg = NULL; + int32_t current_value; + int32_t values[MAX_TILES_PER_DIM]; + + int i; + + //Free pointer in any case + if (*array) { + FREE_POINTER(*array); + } + + //If the arg starts with u, we want an uniform split + if (arg[0]=='u') { + *ntiles = atoi(arg+1)-1; + if (MAX_TILES_PER_DIM <= *ntiles || 0 > *ntiles) { + fprintf(stderr, "Invalid number of tiles (0 < %d <= %d = MAX_TILES_PER_DIM)!\n", *ntiles + 1, MAX_TILES_PER_DIM); + return 0; + } + //Done with parsing + return 1; + } + + //We have a comma-separated list of int for the split... + current_arg = arg; + *ntiles = 0; + do { + int ret = sscanf(current_arg, "%d", ¤t_value); + if (ret != 1) { + fprintf(stderr, "Could not parse integer \"%s\"!\n", current_arg); + return 0; + } + current_arg = strchr(current_arg, ','); + //Skip the , if we found one + if (current_arg) ++current_arg; + values[*ntiles] = current_value; + ++(*ntiles); + if (MAX_TILES_PER_DIM <= *ntiles) break; + } while (current_arg); + + if (MAX_TILES_PER_DIM <= *ntiles || 0 >= *ntiles) { + fprintf(stderr, "Invalid number of tiles (0 < %d <= %d = MAX_TILES_PER_DIM)!\n", *ntiles + 1, MAX_TILES_PER_DIM); + return 0; + } + + *array = MALLOC(int32_t, *ntiles); + if (!*array) { + fprintf(stderr, "Could not allocate array for tiles\n"); + return 0; + } + + //TODO: memcpy? + for (i = 0; i < *ntiles; ++i) { + (*array)[i] = values[i]; + } + + return 1; +} + +static int parse_slice_specification(const char* const arg, int32_t * const nslices, int32_t** const array) { + const char* current_arg = NULL; + int32_t current_value; + int32_t values[MAX_SLICES]; + + int i; + + //Free pointer in any case + if (*array) { + FREE_POINTER(*array); + } + + //If the arg starts with u, we want an uniform split + if (arg[0]=='u') { + *nslices = atoi(arg+1); + if (MAX_SLICES <= *nslices || 0 >= *nslices) { + fprintf(stderr, "Invalid number of tiles (0 < %d <= %d = MAX_SLICES)!\n", *nslices + 1, MAX_SLICES); + return 0; + } + //Done with parsing + return 1; + } + + //We have a comma-separated list of int for the split... + current_arg = arg; + //We always have a slice starting at 0 + values[0] = 0; + *nslices = 1; + do { + int ret = sscanf(current_arg, "%d", ¤t_value); + if (ret != 1) { + fprintf(stderr, "Could not parse integer \"%s\"!\n", current_arg); + return 0; + } + current_arg = strchr(current_arg, ','); + //Skip the , if we found one + if (current_arg) ++current_arg; + values[*nslices] = current_value; + ++(*nslices); + if (MAX_SLICES <= *nslices) break; + } while (current_arg); + + if (MAX_SLICES <= *nslices || 0 >= *nslices) { + fprintf(stderr, "Invalid number of slices (0 < %d <= %d = MAX_SLICES)!\n", *nslices, MAX_SLICES); + return 0; + } + + *array = MALLOC(int32_t, *nslices); + if (!*array) { + fprintf(stderr, "Could not allocate array for slices\n"); + return 0; + } + + //TODO: memcpy? + for (i = 0; i < *nslices; ++i) { + (*array)[i] = values[i]; + } + + return 1; +} + +int kvz_config_parse(kvz_config *cfg, const char *name, const char *value) +{ + static const char * const me_names[] = { "hexbs", "tz", "full", NULL }; + static const char * const source_scan_type_names[] = { "progressive", "tff", "bff", NULL }; + + 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 }; + + static const char * const preset_values[11][28] = { + { + "ultrafast", + "pu-depth-intra", "2-3", + "pu-depth-inter", "1-3", + "rd", "0", + "me", "hexbs", + "ref", "1", + "deblock", "0", + "signhide", "0", + "subme", "0", + "sao", "0", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "superfast", + "pu-depth-intra", "1-3", + "pu-depth-inter", "1-3", + "rd", "1", + "me", "hexbs", + "ref", "1", + "deblock", "0", + "signhide", "0", + "subme", "0", + "sao", "0", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "veryfast", + "pu-depth-intra", "1-3", + "pu-depth-inter", "0-3", + "rd", "1", + "me", "hexbs", + "ref", "2", + "deblock", "1", + "signhide", "0", + "subme", "0", + "sao", "0", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "faster", + "pu-depth-intra", "1-3", + "pu-depth-inter", "0-3", + "rd", "1", + "me", "hexbs", + "ref", "2", + "deblock", "1", + "signhide", "1", + "subme", "0", + "sao", "0", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "fast", + "pu-depth-intra", "1-3", + "pu-depth-inter", "0-3", + "rd", "1", + "me", "hexbs", + "ref", "2", + "deblock", "1", + "signhide", "1", + "subme", "1", + "sao", "0", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "medium", + "pu-depth-intra", "1-4", + "pu-depth-inter", "0-3", + "rd", "1", + "me", "hexbs", + "ref", "3", + "deblock", "1", + "signhide", "1", + "subme", "1", + "sao", "0", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "slow", + "pu-depth-intra", "1-4", + "pu-depth-inter", "0-3", + "rd", "2", + "me", "hexbs", + "ref", "3", + "deblock", "1", + "signhide", "1", + "subme", "1", + "sao", "1", + "rdoq", "0", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "slower", + "pu-depth-intra", "1-4", + "pu-depth-inter", "0-3", + "rd", "2", + "me", "tz", + "ref", "4", + "deblock", "1", + "signhide", "1", + "subme", "1", + "sao", "1", + "rdoq", "1", + "transform-skip", "0", + "full-intra-search", "0", + "mv-rdo", "0", + NULL + }, + { + "veryslow", + "pu-depth-intra", "1-4", + "pu-depth-inter", "0-3", + "rd", "2", + "me", "tz", + "ref", "4", + "deblock", "1", + "signhide", "1", + "subme", "1", + "sao", "1", + "rdoq", "1", + "transform-skip", "1", + "full-intra-search", "0", + "mv-rdo", "1", + NULL + }, + { + "placebo", + "pu-depth-intra", "0-4", + "pu-depth-inter", "0-3", + "rd", "3", + "me", "tz", + "ref", "6", + "deblock", "1", + "signhide", "1", + "subme", "1", + "sao", "1", + "rdoq", "1", + "transform-skip", "1", + "full-intra-search", "1", + "mv-rdo", "1", + NULL + }, + { NULL } + }; + + if (!name) + return 0; + + if (!value) + value = "true"; + + // Treat "--no-param" as --param 0 + if ((!strncmp(name, "no-", 3))) { + name += 3; + value = atobool(value) ? "false" : "true"; + } + +#define OPT(STR) (!strcmp(name, STR)) + if OPT("width") + cfg->width = atoi(value); + else if OPT("height") + cfg->height = atoi(value); + else if OPT("input-res") + if (!strcmp(value, "auto")) { + return 1; + } else { + return (sscanf(value, "%dx%d", &cfg->width, &cfg->height) == 2); + } + else if OPT("input-fps") { + int32_t fps_num, fps_denom; + if (sscanf(value, "%d/%d", &fps_num, &fps_denom) == 2) { + cfg->framerate_num = fps_num; + cfg->framerate_denom = fps_denom; + } else { + // Accept decimal notation, making sure not to round 0 to 1. + cfg->framerate_num = (int)(atof(value) * 1000 + 0.49); + cfg->framerate_denom = 1000; + } + } + else if OPT("qp") + cfg->qp = atoi(value); + else if OPT("period") + cfg->intra_period = atoi(value); + else if OPT("vps-period") + cfg->vps_period = atoi(value); + else if OPT("ref") + cfg->ref_frames = atoi(value); + else if 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 { + cfg->deblock_enable = atobool(value); + } + } + else if OPT("sao") + cfg->sao_enable = atobool(value); + else if OPT("rdoq") + cfg->rdoq_enable = atobool(value); + else if OPT("signhide") + cfg->signhide_enable = (bool)atobool(value); + else if OPT("smp") + cfg->smp_enable = (bool)atobool(value); + else if OPT("amp") + cfg->amp_enable = (bool)atobool(value); + else if OPT("rd") + cfg->rdo = atoi(value); + else if OPT("full-intra-search") + cfg->full_intra_search = atobool(value); + else if OPT("transform-skip") + cfg->trskip_enable = atobool(value); + else if OPT("tr-depth-intra") + cfg->tr_depth_intra = atoi(value); + else if OPT("me") { + int8_t ime_algorithm = 0; + if (!parse_enum(value, me_names, &ime_algorithm)) return 0; + cfg->ime_algorithm = ime_algorithm; + } + else if OPT("subme") + cfg->fme_level = atoi(value); + else if OPT("source-scan-type") + return parse_enum(value, source_scan_type_names, &cfg->source_scan_type); + else if OPT("sar") + return sscanf(value, "%d:%d", &cfg->vui.sar_width, &cfg->vui.sar_height) == 2; + else if OPT("overscan") + return parse_enum(value, overscan_names, &cfg->vui.overscan); + else if OPT("videoformat") + return parse_enum(value, videoformat_names, &cfg->vui.videoformat); + else if OPT("range") + return parse_enum(value, range_names, &cfg->vui.fullrange); + else if OPT("colorprim") + return parse_enum(value, colorprim_names, &cfg->vui.colorprim); + else if OPT("transfer") + return parse_enum(value, transfer_names, &cfg->vui.transfer); + else if OPT("colormatrix") + return parse_enum(value, colormatrix_names, &cfg->vui.colormatrix); + else if OPT("chromaloc") + cfg->vui.chroma_loc = atoi(value); + else if OPT("aud") + cfg->aud_enable = atobool(value); + else if OPT("cqmfile") + cfg->cqmfile = strdup(value); + else if OPT("tiles-width-split") + return parse_tiles_specification(value, &cfg->tiles_width_count, &cfg->tiles_width_split); + else if OPT("tiles-height-split") + return parse_tiles_specification(value, &cfg->tiles_height_count, &cfg->tiles_height_split); + else if OPT("wpp") + cfg->wpp = atobool(value); + else if OPT("owf") { + cfg->owf = atoi(value); + if (cfg->owf == 0 && !strcmp(value, "auto")) { + // -1 means automatic selection + cfg->owf = -1; + } + } + else if OPT("slice-addresses") + return parse_slice_specification(value, &cfg->slice_count, &cfg->slice_addresses_in_ts); + else if OPT("threads") + cfg->threads = atoi(value); + else if OPT("cpuid") + cfg->cpuid = atoi(value); + else if OPT("pu-depth-inter") + return sscanf(value, "%d-%d", &cfg->pu_depth_inter.min, &cfg->pu_depth_inter.max) == 2; + else if OPT("pu-depth-intra") + return sscanf(value, "%d-%d", &cfg->pu_depth_intra.min, &cfg->pu_depth_intra.max) == 2; + else if OPT("info") + cfg->add_encoder_info = atobool(value); + else if OPT("gop") { + if (!strncmp(value, "lp-", 3)) { // Handle GOPs starting with "lp-". + struct { + unsigned g; // length + unsigned d; // depth + unsigned r; // references + unsigned t; // temporal + } gop = { 0 }; + + if (sscanf(value, "lp-g%ud%ur%ut%u", &gop.g, &gop.d, &gop.r, &gop.t) != 4) { + fprintf(stderr, "Error in GOP syntax. Example: lp-g8d4r2t2\n"); + return 0; + } + + if (gop.g < 1 || gop.g > 32) { + fprintf(stderr, "gop.g must be between 1 and 32.\n"); + } + if (gop.d < 1 || gop.d > 8) { + fprintf(stderr, "gop.d must be between 1 and 8.\n"); + } + if (gop.r < 1 || gop.r > 15) { + fprintf(stderr, "gop.d must be between 1 and 15.\n"); + } + if (gop.t < 1 || gop.t > 15) { + fprintf(stderr, "gop.t must be between 1 and 32.\n"); + } + + // Initialize modulos for testing depth. + // The picture belong to the lowest depth in which (poc % modulo) == 0. + unsigned depth_modulos[8] = { 0 }; + for (int d = 0; d < gop.d; ++d) { + depth_modulos[gop.d - 1 - d] = 1 << d; + } + depth_modulos[0] = gop.g; + + cfg->gop_lowdelay = 1; + cfg->gop_len = gop.g; + for (int g = 1; g <= gop.g; ++g) { + kvz_gop_config *gop_pic = &cfg->gop[g - 1]; + + // Find gop depth for picture. + int gop_layer = 0; + while (gop_layer < gop.d && (g % depth_modulos[gop_layer])) { + ++gop_layer; + } + + gop_pic->poc_offset = g; + gop_pic->layer = gop_layer + 1; + gop_pic->qp_offset = gop_layer + 1; + gop_pic->ref_pos_count = 0; + gop_pic->ref_neg_count = gop.r; + gop_pic->is_ref = 0; + + // Set first ref to point to previous frame, and the rest to previous + // key-frames. + // If gop.t > 1, have (poc % gop.t) == 0 point gop.t frames away, + // instead of the previous frame. Set the frames in between to + // point to the nearest frame with a lower gop-depth. + if (gop.t > 1) { + if (gop_pic->poc_offset % gop.t == 0) { + gop_pic->ref_neg[0] = gop.t; + } else { + int r = gop_pic->poc_offset - 1; + while (r > 0) { + if (cfg->gop[r].layer < gop_pic->layer) break; + --r; + } + // Var r is now 0 or index of the pic with layer < depth. + if (cfg->gop[r].layer < gop_pic->layer) { + gop_pic->ref_neg[0] = gop_pic->poc_offset - cfg->gop[r].poc_offset; + cfg->gop[r].is_ref = 1; + } else { + // No ref was found, just refer to the previous key-frame. + gop_pic->ref_neg[0] = gop_pic->poc_offset % gop.g; + } + } + } else { + gop_pic->ref_neg[0] = 1; + if (gop_pic->poc_offset >= 2) { + cfg->gop[gop_pic->poc_offset - 2].is_ref = 1; + } + } + + int keyframe = gop_pic->poc_offset; + for (int i = 1; i < gop_pic->ref_neg_count; ++i) { + while (keyframe == gop_pic->ref_neg[i - 1]) { + keyframe += gop.g; + } + gop_pic->ref_neg[i] = keyframe; + } + + gop_pic->qp_factor = 0.4624; // from HM + } + + for (int g = 0; g < gop.g; ++g) { + kvz_gop_config *gop_pic = &cfg->gop[g]; + if (!gop_pic->is_ref) { + gop_pic->qp_factor = 0.68 * 1.31; // derived from HM + } + } + + // Key-frame is always a reference. + cfg->gop[gop.g - 1].is_ref = 1; + cfg->gop[gop.g - 1].qp_factor = 0.578; // from HM + } else if (atoi(value) == 8) { + cfg->gop_lowdelay = 0; + // GOP + cfg->gop_len = 8; + cfg->gop[0].poc_offset = 8; cfg->gop[0].qp_offset = 1; cfg->gop[0].layer = 1; cfg->gop[0].qp_factor = 0.442; cfg->gop[0].is_ref = 1; + cfg->gop[0].ref_pos_count = 0; + cfg->gop[0].ref_neg_count = 3; cfg->gop[0].ref_neg[0] = 8; cfg->gop[0].ref_neg[1] = 12; cfg->gop[0].ref_neg[2] = 16; + + cfg->gop[1].poc_offset = 4; cfg->gop[1].qp_offset = 2; cfg->gop[1].layer = 2; cfg->gop[1].qp_factor = 0.3536; cfg->gop[1].is_ref = 1; + cfg->gop[1].ref_neg_count = 2; cfg->gop[1].ref_neg[0] = 4; cfg->gop[1].ref_neg[1] = 8; + cfg->gop[1].ref_pos_count = 1; cfg->gop[1].ref_pos[0] = 4; + + cfg->gop[2].poc_offset = 2; cfg->gop[2].qp_offset = 3; cfg->gop[2].layer = 3; cfg->gop[2].qp_factor = 0.3536; cfg->gop[2].is_ref = 1; + cfg->gop[2].ref_neg_count = 2; cfg->gop[2].ref_neg[0] = 2; cfg->gop[2].ref_neg[1] = 6; + cfg->gop[2].ref_pos_count = 2; cfg->gop[2].ref_pos[0] = 2; cfg->gop[2].ref_pos[1] = 6; + + cfg->gop[3].poc_offset = 1; cfg->gop[3].qp_offset = 4; cfg->gop[3].layer = 4; cfg->gop[3].qp_factor = 0.68; cfg->gop[3].is_ref = 0; + cfg->gop[3].ref_neg_count = 1; cfg->gop[3].ref_neg[0] = 1; + cfg->gop[3].ref_pos_count = 3; cfg->gop[3].ref_pos[0] = 1; cfg->gop[3].ref_pos[1] = 3; cfg->gop[3].ref_pos[2] = 7; + + cfg->gop[4].poc_offset = 3; cfg->gop[4].qp_offset = 4; cfg->gop[4].layer = 4; cfg->gop[4].qp_factor = 0.68; cfg->gop[4].is_ref = 0; + cfg->gop[4].ref_neg_count = 2; cfg->gop[4].ref_neg[0] = 1; cfg->gop[4].ref_neg[1] = 3; + cfg->gop[4].ref_pos_count = 2; cfg->gop[4].ref_pos[0] = 1; cfg->gop[4].ref_pos[1] = 5; + + cfg->gop[5].poc_offset = 6; cfg->gop[5].qp_offset = 3; cfg->gop[5].layer = 3; cfg->gop[5].qp_factor = 0.3536; cfg->gop[5].is_ref = 1; + cfg->gop[5].ref_neg_count = 2; cfg->gop[5].ref_neg[0] = 2; cfg->gop[5].ref_neg[1] = 6; + cfg->gop[5].ref_pos_count = 1; cfg->gop[5].ref_pos[0] = 2; + + cfg->gop[6].poc_offset = 5; cfg->gop[6].qp_offset = 4; cfg->gop[6].layer = 4; cfg->gop[6].qp_factor = 0.68; cfg->gop[6].is_ref = 0; + cfg->gop[6].ref_neg_count = 2; cfg->gop[6].ref_neg[0] = 1; cfg->gop[6].ref_neg[1] = 5; + cfg->gop[6].ref_pos_count = 2; cfg->gop[6].ref_pos[0] = 1; cfg->gop[6].ref_pos[1] = 3; + + cfg->gop[7].poc_offset = 7; cfg->gop[7].qp_offset = 4; cfg->gop[7].layer = 4; cfg->gop[7].qp_factor = 0.68; cfg->gop[7].is_ref = 0; + cfg->gop[7].ref_neg_count = 3; cfg->gop[7].ref_neg[0] = 1; cfg->gop[7].ref_neg[1] = 3; cfg->gop[7].ref_neg[2] = 7; + cfg->gop[7].ref_pos_count = 1; cfg->gop[7].ref_pos[0] = 1; + } else if (atoi(value)) { + fprintf(stderr, "Input error: unsupported gop length, must be 0 or 8\n"); + return 0; + } + } + else if OPT("bipred") + cfg->bipred = atobool(value); + else if OPT("bitrate") + cfg->target_bitrate = atoi(value); + else if OPT("preset") { + int preset_line = 0; + + // Accept numbers from 0 to 9. + if ((atoi(value) == 0 && !strcmp(value, "0")) || (atoi(value) >= 1 && atoi(value) <= 9)) { + preset_line = atoi(value); + } else { + // Find the selected preset from the list + while (preset_values[preset_line][0] != NULL) { + if (!strcmp(value, preset_values[preset_line][0])) { + break; + } + preset_line++; + } + } + + if (preset_values[preset_line][0] != NULL) { + fprintf(stderr, "Using preset %s: ", value); + // Loop all the name and value pairs and push to the config parser + for (int preset_value = 1; preset_values[preset_line][preset_value] != NULL; preset_value += 2) { + fprintf(stderr, "--%s=%s ", preset_values[preset_line][preset_value], preset_values[preset_line][preset_value + 1]); + kvz_config_parse(cfg, preset_values[preset_line][preset_value], preset_values[preset_line][preset_value + 1]); + } + fprintf(stderr, "\n"); + } else { + fprintf(stderr, "Input error: unknown preset \"%s\"\n", value); + return 0; + } + } + else if OPT("mv-rdo") + cfg->mv_rdo = atobool(value); + else if OPT("psnr") + cfg->calc_psnr = (bool)atobool(value); + else + return 0; +#undef OPT + + return 1; +} + +/** + * \brief Check that configuration is sensible. + * + * \param cfg config to check + * \return 1 if the config is ok, otherwise 1 + */ +int kvz_config_validate(const kvz_config *const cfg) +{ + int error = 0; + + if (cfg->width <= 0) { + fprintf(stderr, "Input error: width must be positive\n"); + error = 1; + } + + if (cfg->height <= 0) { + fprintf(stderr, "Input error: height must be positive\n"); + error = 1; + } + + if (cfg->width % 2 != 0) { + fprintf(stderr, "Input error: width must be a multiple of two\n"); + error = 1; + } + + if (cfg->height % 2 != 0) { + fprintf(stderr, "Input error: height must be a multiple of two\n"); + error = 1; + } + + if (cfg->framerate < 0.0) { + fprintf(stderr, "Input error: --input-fps must be positive\n"); + error = 1; + } + if (cfg->framerate_num < 0) { + fprintf(stderr, "Input error: --input-fps must >=0\n"); + error = 1; + } + if (cfg->framerate_denom <= 0) { + fprintf(stderr, "Input error: --input-fps denominator must be >0\n"); + error = 1; + } + + if (cfg->gop_len && + cfg->intra_period && + cfg->intra_period % cfg->gop_len != 0) { + fprintf(stderr, + "Input error: intra period (%d) not a multiple of gop length (%d)\n", + cfg->intra_period, + cfg->gop_len); + error = 1; + } + + if (cfg->ref_frames < 1 || cfg->ref_frames >= MAX_REF_PIC_COUNT) { + fprintf(stderr, "Input error: --ref out of range [1..%d]\n", MAX_REF_PIC_COUNT - 1); + error = 1; + } + + if (cfg->deblock_beta < -6 || cfg->deblock_beta > 6) { + fprintf(stderr, "Input error: deblock beta parameter out of range [-6..6]\n"); + error = 1; + } + if (cfg->deblock_tc < -6 || cfg->deblock_tc > 6) { + fprintf(stderr, "Input error: deblock tc parameter out of range [-6..6]\n"); + error = 1; + } + + if (cfg->rdo < 0 || cfg->rdo > 3) { + fprintf(stderr, "Input error: --rd parameter out of range [0..3]\n"); + error = 1; + } + + if (cfg->tr_depth_intra < 0 || cfg->tr_depth_intra > 4) { + // range is 0 .. CtbLog2SizeY - Log2MinTrafoSize + fprintf(stderr, "Input error: --tr-depth-intra is out of range [0..4]\n"); + error = 1; + } + + if (cfg->fme_level != 0 && cfg->fme_level != 1) { + fprintf(stderr, "Input error: invalid --subme parameter (must be 0 or 1)\n"); + error = 1; + } + + if (cfg->vui.chroma_loc < 0 || cfg->vui.chroma_loc > 5) { + fprintf(stderr, "Input error: --chromaloc parameter out of range [0..5]\n"); + error = 1; + } + + if (cfg->owf < -1) { + fprintf(stderr, "Input error: --owf must be nonnegative or -1\n"); + error = 1; + } + + if (cfg->target_bitrate < 0) { + fprintf(stderr, "Input error: --bitrate must be nonnegative\n"); + error = 1; + } + + if (!WITHIN(cfg->pu_depth_inter.min, PU_DEPTH_INTER_MIN, PU_DEPTH_INTER_MAX) || + !WITHIN(cfg->pu_depth_inter.max, PU_DEPTH_INTER_MIN, PU_DEPTH_INTER_MAX)) + { + fprintf(stderr, "Input error: illegal value for --pu-depth-inter (%d-%d)\n", + cfg->pu_depth_inter.min, cfg->pu_depth_inter.max); + error = 1; + } else if (cfg->pu_depth_inter.min > cfg->pu_depth_inter.max) { + fprintf(stderr, "Input error: Inter PU depth min (%d) > max (%d)\n", + cfg->pu_depth_inter.min, cfg->pu_depth_inter.max); + error = 1; + } + + if (!WITHIN(cfg->pu_depth_intra.min, PU_DEPTH_INTRA_MIN, PU_DEPTH_INTRA_MAX) || + !WITHIN(cfg->pu_depth_intra.max, PU_DEPTH_INTRA_MIN, PU_DEPTH_INTRA_MAX)) + { + fprintf(stderr, "Input error: illegal value for --pu-depth-intra (%d-%d)\n", + cfg->pu_depth_intra.min, cfg->pu_depth_intra.max); + error = 1; + } else if (cfg->pu_depth_intra.min > cfg->pu_depth_intra.max) { + fprintf(stderr, "Input error: Intra PU depth min (%d) > max (%d)\n", + cfg->pu_depth_intra.min, cfg->pu_depth_intra.max); + error = 1; + } + + // Tile separation should be at round position in terms of LCU, should be monotonic, and should not start by 0 + if (cfg->tiles_width_split) { + int i; + int32_t prev_tile_split = 0; + for (i=0; i < cfg->tiles_width_count; ++i) { + if (cfg->tiles_width_split[i] <= prev_tile_split) { + fprintf(stderr, "Input error: tile separations in width should be strictly monotonic (%d <= %d)\n", cfg->tiles_width_split[i], prev_tile_split); + error = 1; + break; + } + if ((cfg->tiles_width_split[i] % LCU_WIDTH) != 0) { + fprintf(stderr, "Input error: tile separation in width %d (at %d) is not at a multiple of LCU_WIDTH (%d)\n", i, cfg->tiles_width_split[i], LCU_WIDTH); + error = 1; + break; + } + prev_tile_split = cfg->tiles_width_split[i]; + } + if (cfg->tiles_width_split[cfg->tiles_width_count-1] >= cfg->width) { + fprintf(stderr, "Input error: last x tile separation in width (%d) should smaller than image width (%d)\n", cfg->tiles_width_split[cfg->tiles_width_count-1], cfg->width); + error = 1; + } + } + + if (cfg->tiles_height_split) { + int i; + int32_t prev_tile_split = 0; + for (i=0; i < cfg->tiles_height_count; ++i) { + if (cfg->tiles_height_split[i] <= prev_tile_split) { + fprintf(stderr, "Input error: tile separations in height should be strictly monotonic (%d <= %d)\n", cfg->tiles_height_split[i], prev_tile_split); + error = 1; + break; + } + if ((cfg->tiles_height_split[i] % LCU_WIDTH) != 0) { + fprintf(stderr, "Input error: tile separation in height %d (at %d) is not at a multiple of LCU_WIDTH (%d)\n", i, cfg->tiles_height_split[i], LCU_WIDTH); + error = 1; + break; + } + prev_tile_split = cfg->tiles_height_split[i]; + } + + if (cfg->tiles_height_split[cfg->tiles_height_count-1] >= cfg->height) { + fprintf(stderr, "Input error: last tile separation in height (%d) should smaller than image height (%d)\n", cfg->tiles_height_split[cfg->tiles_height_count-1], cfg->height); + error = 1; + } + } + + return !error; +}
View file
kvazaar-0.8.3.tar.gz/src/cfg.h
Added
@@ -0,0 +1,40 @@ +#ifndef CONFIG_H_ +#define CONFIG_H_ +/***************************************************************************** + * This file is part of Kvazaar HEVC encoder. + * + * Copyright (C) 2013-2015 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 Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * 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 Lesser 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/>. + ****************************************************************************/ + +/** + * \ingroup Control + * \file + * Runtime configuration through defaults and parsing of arguments. + */ + +#include "global.h" + +#include "kvazaar.h" + +/* Function definitions */ +kvz_config *kvz_config_alloc(void); +int kvz_config_init(kvz_config *cfg); +int kvz_config_destroy(kvz_config *cfg); +int kvz_config_parse(kvz_config *cfg, const char *name, const char *value); +int kvz_config_validate(const kvz_config *cfg); + +#endif
View file
kvazaar-0.8.2.tar.gz/src/checkpoint.h -> kvazaar-0.8.3.tar.gz/src/checkpoint.h
Changed
@@ -29,6 +29,8 @@ #ifdef NDEBUG #error "CHECKPOINTS require assertions to be enabled!" #endif +#include "global.h" + #include <string.h> #include <stdio.h> #include <stdlib.h>
View file
kvazaar-0.8.2.tar.gz/src/cli.c -> kvazaar-0.8.3.tar.gz/src/cli.c
Changed
@@ -97,6 +97,8 @@ { "preset", required_argument, NULL, 0 }, { "mv-rdo", no_argument, NULL, 0 }, { "no-mv-rdo", no_argument, NULL, 0 }, + { "psnr", no_argument, NULL, 0 }, + { "no-psnr", no_argument, NULL, 0 }, {0, 0, 0, 0} }; @@ -337,6 +339,7 @@ " --preset <string> : Use preset\n" " ultrafast, superfast,veryfast, faster,\n" " fast, medium, slow, slower, veryslow, placebo\n" + " --no-psnr : Don't calculate PSNR for frames\n" "\n" " Video Usability Information:\n" " --sar <width:height> : Specify Sample Aspect Ratio\n"
View file
kvazaar-0.8.2.tar.gz/src/cli.h -> kvazaar-0.8.3.tar.gz/src/cli.h
Changed
@@ -25,8 +25,9 @@ * Command line interface */ -#include "kvazaar.h" #include "global.h" + +#include "kvazaar.h" #include "encoderstate.h" typedef struct cmdline_opts_t {
View file
kvazaar-0.8.2.tar.gz/src/context.c -> kvazaar-0.8.3.tar.gz/src/context.c
Changed
@@ -24,7 +24,6 @@ #include <stdlib.h> #include <string.h> -#include "config.h" #include "encoder.h"
View file
kvazaar-0.8.2.tar.gz/src/cu.h -> kvazaar-0.8.3.tar.gz/src/cu.h
Changed
@@ -27,8 +27,10 @@ */ #include "global.h" + #include "image.h" + //Cu stuff ////////////////////////////////////////////////////////////////////////// // CONSTANTS
View file
kvazaar-0.8.2.tar.gz/src/encmain.c -> kvazaar-0.8.3.tar.gz/src/encmain.c
Changed
@@ -31,6 +31,8 @@ #include <fcntl.h> /* _O_BINARY */ #endif +#include "global.h" + #include "kvazaar_internal.h" #include <math.h> @@ -120,6 +122,101 @@ } } +typedef struct { + FILE* input; + pthread_mutex_t* input_mutex; + pthread_mutex_t* main_thread_mutex; + + kvz_picture **img_in; + cmdline_opts_t *opts; + encoder_control_t *encoder; + uint8_t padding_x; + uint8_t padding_y; + const kvz_api * api; + int retval; +} input_handler_args; + +#define PTHREAD_LOCK(l) if (pthread_mutex_lock((l)) != 0) { fprintf(stderr, "pthread_mutex_lock(%s) failed!\n", #l); assert(0); return 0; } +#define PTHREAD_UNLOCK(l) if (pthread_mutex_unlock((l)) != 0) { fprintf(stderr, "pthread_mutex_unlock(%s) failed!\n", #l); assert(0); return 0; } + +#define RETVAL_RUNNING 0 +#define RETVAL_FAILURE 1 +#define RETVAL_EOF 2 + +/** +* \brief Handles input reading in a thread +* +* \param in_args pointer to argument struct +*/ +static void* input_read_thread(void* in_args) +{ + + // Reading a frame works as follows: + // - read full frame + // if progressive: set read frame as output + // if interlaced: + // - allocate two fields and fill them according to field order + // - deallocate the initial full frame + + input_handler_args* args = (input_handler_args*)in_args; + kvz_picture *frame_in = NULL; + int frames_read = 0; + + for (;;) { + // Each iteration of this loop puts either a single frame or a field into + // args->img_in for main thread to process. + + bool input_empty = !(args->opts->frames == 0 // number of frames to read is unknown + || frames_read < args->opts->frames); // not all frames have been read + if (feof(args->input) || input_empty) { + goto exit_eof; + } + + frame_in = args->api->picture_alloc(args->opts->config->width + args->padding_x, args->opts->config->height + args->padding_y); + + if (!frame_in) { + fprintf(stderr, "Failed to allocate image.\n"); + goto exit_failure; + } + + if (!yuv_io_read(args->input, args->opts->config->width, args->opts->config->height, frame_in)) { + // reading failed + if (feof(args->input)) { + goto exit_eof; + } else { + fprintf(stderr, "Failed to read a frame %d\n", frames_read); + goto exit_failure; + } + } + + if (args->encoder->cfg->source_scan_type != 0) { + // Set source scan type for frame, so that it will be turned into fields. + frame_in->interlacing = args->encoder->cfg->source_scan_type; + } + args->img_in[frames_read & 1] = frame_in; + frame_in = NULL; + + frames_read++; + + // Wait until main thread is ready to receive input and then release main thread + PTHREAD_LOCK(args->input_mutex); + PTHREAD_UNLOCK(args->main_thread_mutex); + } + +exit_eof: + args->retval = RETVAL_EOF; + args->img_in[frames_read & 1] = NULL; +exit_failure: + // Do some cleaning up + args->api->picture_free(frame_in); + if (!args->retval) { + args->retval = RETVAL_FAILURE; + } + pthread_exit(NULL); + return 0; +} + + /** * \brief Program main function. * \param argc Argument count from commandline @@ -200,8 +297,6 @@ fprintf(stderr, "Failed to seek %d frames.\n", opts->seek); goto exit_failure; } - encoder->vui.field_seq_flag = encoder->cfg->source_scan_type != 0; - encoder->vui.frame_field_info_present_flag = encoder->cfg->source_scan_type != 0; //Now, do the real stuff { @@ -214,44 +309,53 @@ uint32_t frames_done = 0; double psnr_sum[3] = { 0.0, 0.0, 0.0 }; - int8_t field_parity = 0; - kvz_picture *frame_in = NULL; uint8_t padding_x = get_padding(opts->config->width); uint8_t padding_y = get_padding(opts->config->height); + pthread_t input_thread; + + pthread_mutex_t input_mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t main_thread_mutex = PTHREAD_MUTEX_INITIALIZER; + + // Lock both mutexes at startup + PTHREAD_LOCK(&main_thread_mutex); + PTHREAD_LOCK(&input_mutex); + + // Give arguments via struct to the input thread + input_handler_args in_args; + kvz_picture *img_in[2] = { NULL }; + in_args.input = input; + in_args.img_in = img_in; + in_args.main_thread_mutex = &main_thread_mutex; + in_args.input_mutex = &input_mutex; + in_args.opts = opts; + in_args.encoder = encoder; + in_args.padding_x = padding_x; + in_args.padding_y = padding_y; + in_args.api = api; + in_args.retval = RETVAL_RUNNING; + + if (pthread_create(&input_thread, NULL, input_read_thread, (void*)&in_args) != 0) { + fprintf(stderr, "pthread_create failed!\n"); + assert(0); + return 0; + } + kvz_picture *cur_in_img; for (;;) { - kvz_picture *img_in = NULL; - - if (!feof(input) && (opts->frames == 0 || frames_read < opts->frames || field_parity == 1) ) { - // Try to read an input frame. - if(field_parity == 0) frame_in = api->picture_alloc(opts->config->width + padding_x, opts->config->height + padding_y); - if (!frame_in) { - fprintf(stderr, "Failed to allocate image.\n"); - goto exit_failure; - } - - if (field_parity == 0){ - if (yuv_io_read(input, opts->config->width, opts->config->height, frame_in)) { - frames_read += 1; - img_in = frame_in; - } else { - // EOF or some error - api->picture_free(frame_in); - img_in = NULL; - if (!feof(input)) { - fprintf(stderr, "Failed to read a frame %d\n", frames_read); - goto exit_failure; - } - } - } - - if (encoder->cfg->source_scan_type != 0){ - img_in = api->picture_alloc(encoder->in.width, encoder->in.height); - yuv_io_extract_field(frame_in, encoder->cfg->source_scan_type, field_parity, img_in); - if (field_parity == 1) api->picture_free(frame_in); - field_parity ^= 1; //0->1 or 1->0 - } + // Skip mutex locking when thread is no longer in run state + if (in_args.retval == RETVAL_RUNNING) { + // Wait for input to be read + // unlock the input thread to be able to continue to the next picture + PTHREAD_UNLOCK(&input_mutex); + PTHREAD_LOCK(&main_thread_mutex); + } + cur_in_img = img_in[frames_read & 1]; + img_in[frames_read & 1] = NULL; + frames_read++; + + if (in_args.retval == EXIT_FAILURE) { + goto exit_failure; } kvz_data_chunk* chunks_out = NULL; @@ -260,18 +364,18 @@ uint32_t len_out = 0; kvz_frame_info info_out; if (!api->encoder_encode(enc, - img_in, + cur_in_img, &chunks_out, &len_out, &img_rec, &img_src, &info_out)) { fprintf(stderr, "Failed to encode image.\n"); - api->picture_free(img_in); + api->picture_free(cur_in_img); goto exit_failure; } - if (chunks_out == NULL && img_in == NULL) { + if (chunks_out == NULL && cur_in_img == NULL) { // We are done since there is no more input and output left. break; } @@ -285,7 +389,7 @@ assert(written + chunk->len <= len_out); if (fwrite(chunk->data, sizeof(uint8_t), chunk->len, output) != chunk->len) { fprintf(stderr, "Failed to write data to file.\n"); - api->picture_free(img_in); + api->picture_free(cur_in_img); api->chunk_free(chunks_out); goto exit_failure; } @@ -298,7 +402,11 @@ // Compute and print stats. double frame_psnr[3] = { 0.0, 0.0, 0.0 }; - compute_psnr(img_src, img_rec, frame_psnr); + if (encoder->cfg->calc_psnr && encoder->cfg->source_scan_type == KVZ_INTERLACING_NONE) { + // Do not compute PSNR for interlaced frames, because img_rec does not contain + // the deinterlaced frame yet. + compute_psnr(img_src, img_rec, frame_psnr); + } if (recout) { // Since chunks_out was not NULL, img_rec should have been set. @@ -319,7 +427,7 @@ print_frame_info(&info_out, frame_psnr, len_out); } - api->picture_free(img_in); + api->picture_free(cur_in_img); api->chunk_free(chunks_out); api->picture_free(img_rec); api->picture_free(img_src); @@ -350,6 +458,7 @@ fprintf(stderr, " Encoding CPU usage: %.2f%%\n", encoding_time/wall_time*100.f); fprintf(stderr, " FPS: %.2f\n", ((double)frames_done)/wall_time); } + pthread_join(input_thread, NULL); } goto done;
View file
kvazaar-0.8.2.tar.gz/src/encoder.c -> kvazaar-0.8.3.tar.gz/src/encoder.c
Changed
@@ -26,7 +26,7 @@ #include <assert.h> #include "tables.h" -#include "config.h" +#include "cfg.h" #include "cabac.h" #include "image.h" #include "nal.h" @@ -125,6 +125,13 @@ encoder->owf = select_owf_auto(cfg); fprintf(stderr, "--owf=auto value set to %d.\n", encoder->owf); } + if (cfg->source_scan_type != KVZ_INTERLACING_NONE) { + // If using interlaced coding with OWF, the OWF has to be an even number + // to ensure that the pair of fields will be output for the same picture. + if (encoder->owf % 2 == 1) { + encoder->owf += 1; + } + } encoder->threadqueue = MALLOC(threadqueue_queue_t, 1); if (!encoder->threadqueue || @@ -149,8 +156,11 @@ // Rate-distortion optimization level encoder->rdo = 1; encoder->full_intra_search = 0; - // INTERLACING + + // Interlacing encoder->in.source_scan_type = (int8_t)cfg->source_scan_type; + encoder->vui.field_seq_flag = encoder->cfg->source_scan_type != 0; + encoder->vui.frame_field_info_present_flag = encoder->cfg->source_scan_type != 0; // Initialize the scaling list kvz_scalinglist_init(&encoder->scaling_list); @@ -437,6 +447,11 @@ encoder->vui.timing_info_present_flag = 1; encoder->vui.num_units_in_tick = cfg->framerate_denom; encoder->vui.time_scale = cfg->framerate_num; + if (cfg->source_scan_type != KVZ_INTERLACING_NONE) { + // when field_seq_flag=1, the time_scale and num_units_in_tick refer to + // field rate rather than frame rate. + encoder->vui.time_scale *= 2; + } } // AUD
View file
kvazaar-0.8.2.tar.gz/src/encoder.h -> kvazaar-0.8.3.tar.gz/src/encoder.h
Changed
@@ -31,7 +31,6 @@ #include "image.h" #include "bitstream.h" #include "cabac.h" -#include "config.h" #include "tables.h" #include "scalinglist.h" #include "threadqueue.h"
View file
kvazaar-0.8.2.tar.gz/src/encoder_state-bitstream.c -> kvazaar-0.8.3.tar.gz/src/encoder_state-bitstream.c
Changed
@@ -570,7 +570,7 @@ int8_t pic_struct = 0; //0: progressive picture, 1: top field, 2: bottom field, 3... int8_t source_scan_type = 1; //0: interlaced, 1: progressive - switch (state->encoder_control->in.source_scan_type){ + switch (state->tile->frame->source->interlacing){ case 0: //Progressive frame pic_struct = 0; source_scan_type = 1;
View file
kvazaar-0.8.2.tar.gz/src/encoderstate.c -> kvazaar-0.8.3.tar.gz/src/encoderstate.c
Changed
@@ -26,7 +26,6 @@ #include <assert.h> #include "tables.h" -#include "config.h" #include "cabac.h" #include "image.h" #include "nal.h"
View file
kvazaar-0.8.2.tar.gz/src/encoderstate.h -> kvazaar-0.8.3.tar.gz/src/encoderstate.h
Changed
@@ -33,7 +33,6 @@ #include "image.h" #include "bitstream.h" #include "cabac.h" -#include "config.h" #include "tables.h" #include "scalinglist.h" #include "threadqueue.h"
View file
kvazaar-0.8.2.tar.gz/src/filter.c -> kvazaar-0.8.3.tar.gz/src/filter.c
Changed
@@ -25,7 +25,6 @@ #include <stdlib.h> #include <string.h> -#include "config.h" #include "bitstream.h" #include "videoframe.h" #include "cabac.h"
View file
kvazaar-0.8.2.tar.gz/src/global.h -> kvazaar-0.8.3.tar.gz/src/global.h
Changed
@@ -29,6 +29,12 @@ * so that any file can refer to integer types with exact widths. */ +#ifdef HAVE_CONFIG_H +// Include config.h generated by automake. This needs to be before any other +// includes in every file, which is why it's in global. +#include "config.h" +#endif + #include <assert.h> #include <stdbool.h> #include <stdint.h> @@ -175,7 +181,7 @@ // NOTE: When making a release, check to see if incrementing libversion in // configure.ac is necessary. -#define KVZ_VERSION 0.8.2 +#define KVZ_VERSION 0.8.3 #define VERSION_STRING QUOTE_EXPAND(KVZ_VERSION) //#define VERBOSE 1
View file
kvazaar-0.8.2.tar.gz/src/image.c -> kvazaar-0.8.3.tar.gz/src/image.c
Changed
@@ -67,6 +67,8 @@ im->pts = 0; im->dts = 0; + im->interlacing = KVZ_INTERLACING_NONE; + return im; }
View file
kvazaar-0.8.2.tar.gz/src/image.h -> kvazaar-0.8.3.tar.gz/src/image.h
Changed
@@ -27,8 +27,10 @@ */ #include "global.h" + #include "kvazaar.h" + typedef struct { kvz_pixel y[LCU_LUMA_SIZE]; kvz_pixel u[LCU_CHROMA_SIZE];
View file
kvazaar-0.8.2.tar.gz/src/imagelist.h -> kvazaar-0.8.3.tar.gz/src/imagelist.h
Changed
@@ -26,6 +26,8 @@ * Container for a list of reference pictures. */ +#include "global.h" + #include "image.h" #include "cu.h"
View file
kvazaar-0.8.2.tar.gz/src/inter.c -> kvazaar-0.8.3.tar.gz/src/inter.c
Changed
@@ -24,7 +24,6 @@ #include <stdlib.h> #include <string.h> -#include "config.h" #include "filter.h" #include "strategies/strategies-ipol.h" #include "strategies/generic/ipol-generic.h"
View file
kvazaar-0.8.2.tar.gz/src/kvazaar.c -> kvazaar-0.8.3.tar.gz/src/kvazaar.c
Changed
@@ -22,7 +22,7 @@ #include <stdlib.h> -#include "config.h" +#include "cfg.h" #include "encoder.h" #include "strategyselector.h" #include "encoderstate.h" @@ -144,6 +144,49 @@ } +/** +* \brief Separate a single field from a frame. +* +* \param frame_in input frame to extract field from +* \param source_scan_type scan type of input material (0: progressive, 1:top field first, 2:bottom field first) +* \param field parity +* \param field_out +* +* \return 1 on success, 0 on failure +*/ +static int yuv_io_extract_field(const kvz_picture *frame_in, unsigned source_scan_type, unsigned field_parity, kvz_picture *field_out) +{ + if ((source_scan_type != 1) && (source_scan_type != 2)) return 0; + if ((field_parity != 0) && (field_parity != 1)) return 0; + + unsigned offset = 0; + if (source_scan_type == 1) offset = field_parity ? 1 : 0; + else if (source_scan_type == 2) offset = field_parity ? 0 : 1; + + //Luma + for (int i = 0; i < field_out->height; ++i){ + kvz_pixel *row_in = frame_in->y + MIN(frame_in->height - 1, 2 * i + offset) * frame_in->stride; + kvz_pixel *row_out = field_out->y + i * field_out->stride; + memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width); + } + + //Chroma + for (int i = 0; i < field_out->height / 2; ++i){ + kvz_pixel *row_in = frame_in->u + MIN(frame_in->height / 2 - 1, 2 * i + offset) * frame_in->stride / 2; + kvz_pixel *row_out = field_out->u + i * field_out->stride / 2; + memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width / 2); + } + + for (int i = 0; i < field_out->height / 2; ++i){ + kvz_pixel *row_in = frame_in->v + MIN(frame_in->height / 2 - 1, 2 * i + offset) * frame_in->stride / 2; + kvz_pixel *row_out = field_out->v + i * field_out->stride / 2; + memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width / 2); + } + + return 1; +} + + static int kvazaar_encode(kvz_encoder *enc, kvz_picture *pic_in, kvz_data_chunk **data_out, @@ -212,6 +255,90 @@ } +static int kvazaar_field_encoding_adapter(kvz_encoder *enc, + kvz_picture *pic_in, + kvz_data_chunk **data_out, + uint32_t *len_out, + kvz_picture **pic_out, + kvz_picture **src_out, + kvz_frame_info *info_out) +{ + if (enc->control->cfg->source_scan_type == KVZ_INTERLACING_NONE) { + // For progressive, simply call the normal encoding function. + return kvazaar_encode(enc, pic_in, data_out, len_out, pic_out, src_out, info_out); + } + + // For interlaced, make two fields out of the input frame and call encode on them separately. + encoder_state_t *state = &enc->states[enc->cur_state_num]; + kvz_picture *first_field = NULL, *second_field = NULL; + struct { + kvz_data_chunk* data_out; + uint32_t len_out; + } first = { 0 }, second = { 0 }; + + if (pic_in != NULL) { + first_field = kvz_image_alloc(state->encoder_control->in.width, state->encoder_control->in.height); + if (first_field == NULL) { + goto kvazaar_field_encoding_adapter_failure; + } + second_field = kvz_image_alloc(state->encoder_control->in.width, state->encoder_control->in.height); + if (second_field == NULL) { + goto kvazaar_field_encoding_adapter_failure; + } + + yuv_io_extract_field(pic_in, pic_in->interlacing, 0, first_field); + yuv_io_extract_field(pic_in, pic_in->interlacing, 1, second_field); + + first_field->pts = pic_in->pts; + first_field->dts = pic_in->dts; + first_field->interlacing = pic_in->interlacing; + + // Should the second field have higher pts and dts? It shouldn't affect anything. + second_field->pts = pic_in->pts; + second_field->dts = pic_in->dts; + second_field->interlacing = pic_in->interlacing; + } + + if (!kvazaar_encode(enc, first_field, &first.data_out, &first.len_out, pic_out, NULL, info_out)) { + goto kvazaar_field_encoding_adapter_failure; + } + if (!kvazaar_encode(enc, second_field, &second.data_out, &second.len_out, NULL, NULL, NULL)) { + goto kvazaar_field_encoding_adapter_failure; + } + + kvz_image_free(first_field); + kvz_image_free(second_field); + + // Concatenate bitstreams. + if (len_out != NULL) { + *len_out = first.len_out + second.len_out; + } + if (data_out != NULL) { + *data_out = first.data_out; + if (first.data_out != NULL) { + kvz_data_chunk *chunk = first.data_out; + while (chunk->next != NULL) { + chunk = chunk->next; + } + chunk->next = second.data_out; + } + } + + if (src_out != NULL) { + // TODO: deinterlace the fields to one picture. + } + + return 1; + +kvazaar_field_encoding_adapter_failure: + kvz_image_free(first_field); + kvz_image_free(second_field); + kvz_bitstream_free_chunks(first.data_out); + kvz_bitstream_free_chunks(second.data_out); + return 0; +} + + static const kvz_api kvz_8bit_api = { .config_alloc = kvz_config_alloc, .config_init = kvz_config_init, @@ -226,7 +353,7 @@ .encoder_open = kvazaar_open, .encoder_close = kvazaar_close, .encoder_headers = kvazaar_headers, - .encoder_encode = kvazaar_encode, + .encoder_encode = kvazaar_field_encoding_adapter, };
View file
kvazaar-0.8.2.tar.gz/src/kvazaar.h -> kvazaar-0.8.3.tar.gz/src/kvazaar.h
Changed
@@ -29,8 +29,6 @@ #include <stddef.h> #include <stdint.h> -#include "kvazaar_version.h" - #ifdef __cplusplus extern "C" { #endif @@ -93,6 +91,17 @@ }; /** + * \brief Interlacing methods. + * \since 3.2.0 + */ +enum kvz_interlacing +{ + KVZ_INTERLACING_NONE = 0, + KVZ_INTERLACING_TFF = 1, // top field first + KVZ_INTERLACING_BFF = 2, // bottom field first +}; + +/** * \brief GoP picture configuration. */ typedef struct kvz_gop_config { @@ -110,7 +119,9 @@ /** * \brief Struct which contains all configuration data * - * Function config_alloc in kvz_api must be used for allocation. + * Functions config_alloc, config_init and config_destroy must be used to + * maintain ABI compatibility. Do not copy this struct, as the size might + * change. */ typedef struct kvz_config { @@ -192,6 +203,7 @@ int32_t target_bitrate; int8_t mv_rdo; /*!< \brief MV RDO calculation in search (0: estimation, 1: RDO). */ + int8_t calc_psnr; /*!< \since 3.1.0 \brief Print PSNR in CLI. */ } kvz_config; /** @@ -217,6 +229,8 @@ int64_t pts; //!< \brief Presentation timestamp. Should be set for input frames. int64_t dts; //!< \brief Decompression timestamp. + + enum kvz_interlacing interlacing; //!< \since 3.2.0 \brief Field order for interlaced pictures. } kvz_picture; /**
View file
kvazaar-0.8.2.tar.gz/src/kvazaar_internal.h -> kvazaar-0.8.3.tar.gz/src/kvazaar_internal.h
Changed
@@ -26,6 +26,8 @@ * \brief Definitions for opaque structs in kvazaar.h */ +#include "global.h" + #include "kvazaar.h" #include "input_frame_buffer.h"
View file
kvazaar-0.8.2.tar.gz/src/nal.c -> kvazaar-0.8.3.tar.gz/src/nal.c
Changed
@@ -25,7 +25,6 @@ #include <string.h> #include <assert.h> -#include "config.h" #include "bitstream.h" #include "cabac.h" #include "encoder.h"
View file
kvazaar-0.8.2.tar.gz/src/rate_control.h -> kvazaar-0.8.3.tar.gz/src/rate_control.h
Changed
@@ -26,6 +26,8 @@ * \brief Functions related to rate control. */ +#include "global.h" + #include "encoderstate.h" double kvz_select_picture_lambda(encoder_state_t * const state);
View file
kvazaar-0.8.2.tar.gz/src/sao.h -> kvazaar-0.8.3.tar.gz/src/sao.h
Changed
@@ -26,6 +26,8 @@ * Sample Adaptive Offset filter. */ +#include "global.h" + #include "checkpoint.h" #include "global.h" #include "videoframe.h"
View file
kvazaar-0.8.2.tar.gz/src/strategies/avx2/intra-avx2.c -> kvazaar-0.8.3.tar.gz/src/strategies/avx2/intra-avx2.c
Changed
@@ -91,16 +91,12 @@ __m128i sample0 = _mm_cvtsi64_si128(*(uint64_t*)&(ref_main[x + delta_int])); __m128i sample1 = _mm_cvtsi64_si128(*(uint64_t*)&(ref_main[x + delta_int + 1])); __m128i pairs_lo = _mm_unpacklo_epi8(sample0, sample1); - __m128i pairs_hi = _mm_unpackhi_epi8(sample0, sample1); __m128i weight = _mm_set1_epi16( (delta_fract << 8) | (32 - delta_fract) ); __m128i v_temp_lo = _mm_maddubs_epi16(pairs_lo, weight); - __m128i v_temp_hi = _mm_maddubs_epi16(pairs_hi, weight); v_temp_lo = _mm_add_epi16(v_temp_lo, _mm_set1_epi16(16)); - v_temp_hi = _mm_add_epi16(v_temp_hi, _mm_set1_epi16(16)); v_temp_lo = _mm_srli_epi16(v_temp_lo, 5); - v_temp_hi = _mm_srli_epi16(v_temp_hi, 5); - sample0 = _mm_packus_epi16(v_temp_lo, v_temp_hi); + sample0 = _mm_packus_epi16(v_temp_lo, v_temp_lo); return sample0; } @@ -174,16 +170,12 @@ __m256i sample1 = _mm256_cvtepu8_epi16(_mm_loadu_si128((__m128i*)&(ref_main[x + delta_int + 1]))); sample1 = _mm256_packus_epi16(sample1, sample1); __m256i pairs_lo = _mm256_unpacklo_epi8(sample0, sample1); - __m256i pairs_hi = _mm256_unpackhi_epi8(sample0, sample1); __m256i weight = _mm256_set1_epi16( (delta_fract << 8) | (32 - delta_fract) ); __m256i v_temp_lo = _mm256_maddubs_epi16(pairs_lo, weight); - __m256i v_temp_hi = _mm256_maddubs_epi16(pairs_hi, weight); v_temp_lo = _mm256_add_epi16(v_temp_lo, _mm256_set1_epi16(16)); - v_temp_hi = _mm256_add_epi16(v_temp_hi, _mm256_set1_epi16(16)); v_temp_lo = _mm256_srli_epi16(v_temp_lo, 5); - v_temp_hi = _mm256_srli_epi16(v_temp_hi, 5); - sample0 = _mm256_packus_epi16(v_temp_lo, v_temp_hi); + sample0 = _mm256_packus_epi16(v_temp_lo, v_temp_lo); return sample0; }
View file
kvazaar-0.8.2.tar.gz/src/strategies/avx2/intra-avx2.h -> kvazaar-0.8.3.tar.gz/src/strategies/avx2/intra-avx2.h
Changed
@@ -26,7 +26,10 @@ * Optimizations for AVX2. */ +#include "global.h" + #include <stdint.h> + #include "encoderstate.h" int kvz_strategy_register_intra_avx2(void* opaque, uint8_t bitdepth);
View file
kvazaar-0.8.2.tar.gz/src/strategies/avx2/quant-avx2.h -> kvazaar-0.8.3.tar.gz/src/strategies/avx2/quant-avx2.h
Changed
@@ -26,6 +26,8 @@ * Optimizations for AVX2. */ +#include "global.h" + #include <stdint.h> int kvz_strategy_register_quant_avx2(void* opaque, uint8_t bitdepth);
View file
kvazaar-0.8.2.tar.gz/src/strategies/generic/intra-generic.h -> kvazaar-0.8.3.tar.gz/src/strategies/generic/intra-generic.h
Changed
@@ -26,7 +26,10 @@ * Generic C implementations of optimized functions. */ +#include "global.h" + #include <stdint.h> + #include "encoderstate.h" int kvz_strategy_register_intra_generic(void* opaque, uint8_t bitdepth);
View file
kvazaar-0.8.2.tar.gz/src/strategies/generic/ipol-generic.h -> kvazaar-0.8.3.tar.gz/src/strategies/generic/ipol-generic.h
Changed
@@ -26,6 +26,8 @@ * Generic C implementations of optimized functions. */ +#include "global.h" + #include "encoder.h" int kvz_strategy_register_ipol_generic(void* opaque, uint8_t bitdepth);
View file
kvazaar-0.8.2.tar.gz/src/strategies/generic/nal-generic.h -> kvazaar-0.8.3.tar.gz/src/strategies/generic/nal-generic.h
Changed
@@ -26,7 +26,7 @@ * Generic C implementations of optimized functions. */ -#include "global.h" +#include "global.h" int kvz_strategy_register_nal_generic(void* opaque, uint8_t bitdepth);
View file
kvazaar-0.8.2.tar.gz/src/strategies/generic/picture-generic.h -> kvazaar-0.8.3.tar.gz/src/strategies/generic/picture-generic.h
Changed
@@ -26,6 +26,8 @@ * Generic C implementations of optimized functions. */ +#include "global.h" + int kvz_strategy_register_picture_generic(void* opaque, uint8_t bitdepth); // Function to clip int16_t to pixel. (0-255 or 0-1023)
View file
kvazaar-0.8.2.tar.gz/src/strategies/generic/quant-generic.h -> kvazaar-0.8.3.tar.gz/src/strategies/generic/quant-generic.h
Changed
@@ -26,7 +26,10 @@ * Generic C implementations of optimized functions. */ +#include "global.h" + #include <stdint.h> + #include "encoderstate.h" #define QUANT_SHIFT 14
View file
kvazaar-0.8.2.tar.gz/src/strategies/sse2/picture-sse2.h -> kvazaar-0.8.3.tar.gz/src/strategies/sse2/picture-sse2.h
Changed
@@ -26,6 +26,8 @@ * Optimizations for SSE2. */ +#include "global.h" + int kvz_strategy_register_picture_sse2(void* opaque, unsigned char bitdepth); #endif //STRATEGIES_PICTURE_SSE2_H_
View file
kvazaar-0.8.2.tar.gz/src/strategies/sse41/picture-sse41.h -> kvazaar-0.8.3.tar.gz/src/strategies/sse41/picture-sse41.h
Changed
@@ -1,7 +1,5 @@ #ifndef STRATEGIES_PICTURE_SSE41_H_ #define STRATEGIES_PICTURE_SSE41_H_ - -#include "global.h" /***************************************************************************** * This file is part of Kvazaar HEVC encoder. * @@ -28,6 +26,8 @@ * Optimizations for SSE4.1. */ +#include "global.h" + int kvz_strategy_register_picture_sse41(void* opaque, uint8_t bitdepth); #endif //STRATEGIES_PICTURE_SSE41_H_
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-common.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-common.h
Changed
@@ -7,6 +7,8 @@ * Common tools strategies. */ +#include "global.h" + //Use with shuffle and permutation intrinsics. //Parameters are indices to packed elements. Each must be 0, 1, 2 or 3. #define KVZ_PERMUTE(a, b, c, d) ( (a << 0) | (b << 2) | (c << 4) | (d << 6) )
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-dct.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-dct.h
Changed
@@ -26,6 +26,8 @@ * Interface for transform functions. */ +#include "global.h" + #include <stdint.h> typedef unsigned (dct_func)(int8_t bitdepth, const int16_t *input, int16_t *output);
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-intra.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-intra.h
Changed
@@ -26,6 +26,8 @@ * Interface for intra prediction functions. */ +#include "global.h" + #include "encoderstate.h" typedef void (angular_pred_func)(
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-ipol.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-ipol.h
Changed
@@ -26,6 +26,8 @@ * Interface for subpixel interpolation functions. */ +#include "global.h" + #include <stdint.h> #include "encoder.h"
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-nal.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-nal.h
Changed
@@ -26,6 +26,8 @@ * Interface for hash functions. */ +#include "global.h" + #include "../nal.h" //Function pointer to kvz_array_checksum
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-picture.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-picture.h
Changed
@@ -26,6 +26,8 @@ * Interface for distortion metric functions. */ +#include "global.h" + #include "../image.h" typedef kvz_pixel (*pred_buffer)[32 * 32];
View file
kvazaar-0.8.2.tar.gz/src/strategies/strategies-quant.h -> kvazaar-0.8.3.tar.gz/src/strategies/strategies-quant.h
Changed
@@ -26,6 +26,8 @@ * Interface for quantization functions. */ +#include "global.h" + #include "encoderstate.h" // Declare function pointers.
View file
kvazaar-0.8.2.tar.gz/src/strategies/x86_asm/picture-x86-asm-sad.h -> kvazaar-0.8.3.tar.gz/src/strategies/x86_asm/picture-x86-asm-sad.h
Changed
@@ -26,6 +26,8 @@ * Optimizations for AVX, utilizing ASM implementations. */ +#include "global.h" + unsigned kvz_sad_4x4_avx(const kvz_pixel*, const kvz_pixel*); unsigned kvz_sad_8x8_avx(const kvz_pixel*, const kvz_pixel*); unsigned kvz_sad_16x16_avx(const kvz_pixel*, const kvz_pixel*);
View file
kvazaar-0.8.2.tar.gz/src/strategies/x86_asm/picture-x86-asm-satd.h -> kvazaar-0.8.3.tar.gz/src/strategies/x86_asm/picture-x86-asm-satd.h
Changed
@@ -26,6 +26,8 @@ * Optimizations for AVX, utilizing ASM implementations. */ +#include "global.h" + unsigned kvz_satd_4x4_avx(const kvz_pixel *org, const kvz_pixel *cur); unsigned kvz_satd_8x8_avx(const kvz_pixel *org, const kvz_pixel *cur); unsigned kvz_satd_16x16_avx(const kvz_pixel *org, const kvz_pixel *cur);
View file
kvazaar-0.8.2.tar.gz/src/strategies/x86_asm/picture-x86-asm.h -> kvazaar-0.8.3.tar.gz/src/strategies/x86_asm/picture-x86-asm.h
Changed
@@ -26,6 +26,8 @@ * Optimizations for AVX, utilizing ASM implementations. */ +#include "global.h" + int kvz_strategy_register_picture_x86_asm_avx(void* opaque, uint8_t bitdepth); #endif //STRATEGIES_PICTURE_X86_ASM_H_
View file
kvazaar-0.8.2.tar.gz/src/strategyselector.c -> kvazaar-0.8.3.tar.gz/src/strategyselector.c
Changed
@@ -258,10 +258,6 @@ static void set_hardware_flags(int32_t cpuid) { FILL(kvz_g_hardware_flags, 0); - - kvz_g_hardware_flags.arm = COMPILE_ARM; - kvz_g_hardware_flags.intel = COMPILE_INTEL; - kvz_g_hardware_flags.powerpc = COMPILE_POWERPC; #if COMPILE_INTEL if (cpuid) {
View file
kvazaar-0.8.2.tar.gz/src/strategyselector.h -> kvazaar-0.8.3.tar.gz/src/strategyselector.h
Changed
@@ -118,7 +118,6 @@ } strategy_to_select_t; typedef struct { - int intel; struct { int mmx; int sse; @@ -131,12 +130,10 @@ int avx2; } intel_flags; - int powerpc; struct { int altivec; } powerpc_flags; - int arm; struct { int neon; } arm_flags;
View file
kvazaar-0.8.2.tar.gz/src/threadqueue.h -> kvazaar-0.8.3.tar.gz/src/threadqueue.h
Changed
@@ -134,8 +134,8 @@ #define KVZ_PERF_SEARCHCU (1 << 5) #define KVZ_PERF_SEARCHPX (1 << 6) -#define IMPL_PERFORMANCE_MEASURE_START(mask) KVZ_CLOCK_T start, stop; if ((KVZ_DEBUG) & mask) { GET_TIME(&start); } -#define IMPL_PERFORMANCE_MEASURE_END(mask, threadqueue, str, ...) { if ((KVZ_DEBUG) & mask) { GET_TIME(&stop); {char job_description[256]; sprintf(job_description, (str), __VA_ARGS__); threadqueue_log((threadqueue), &start, &stop, job_description);}} } \ +#define IMPL_PERFORMANCE_MEASURE_START(mask) KVZ_CLOCK_T start, stop; if ((KVZ_DEBUG) & mask) { KVZ_GET_TIME(&start); } +#define IMPL_PERFORMANCE_MEASURE_END(mask, threadqueue, str, ...) { if ((KVZ_DEBUG) & mask) { KVZ_GET_TIME(&stop); {char job_description[256]; sprintf(job_description, (str), __VA_ARGS__); threadqueue_log((threadqueue), &start, &stop, job_description);}} } \ #ifdef _MSC_VER // Disable VS conditional expression warning from debug code.
View file
kvazaar-0.8.2.tar.gz/src/transform.c -> kvazaar-0.8.3.tar.gz/src/transform.c
Changed
@@ -25,7 +25,6 @@ #include <stdlib.h> #include <assert.h> -#include "config.h" #include "nal.h" #include "rdo.h" #include "strategies/strategies-dct.h"
View file
kvazaar-0.8.2.tar.gz/src/videoframe.h -> kvazaar-0.8.3.tar.gz/src/videoframe.h
Changed
@@ -27,6 +27,7 @@ */ #include "global.h" + #include "cu.h" #include "image.h"
View file
kvazaar-0.8.2.tar.gz/src/yuv_io.c -> kvazaar-0.8.3.tar.gz/src/yuv_io.c
Changed
@@ -203,44 +203,3 @@ return 1; } - -/** -* \brief Separate a single field from a frame. -* -* \param frame_in input frame to extract field from -* \param source_scan_type scan type of input material (0: progressive, 1:top field first, 2:bottom field first) -* \param field parity -* \param field_out -* -* \return 1 on success, 0 on failure -*/ -int yuv_io_extract_field(const kvz_picture *frame_in, unsigned source_scan_type, unsigned field_parity, kvz_picture *field_out) -{ - if ((source_scan_type != 1) && (source_scan_type != 2)) return 0; - if ((field_parity != 0) && (field_parity != 1)) return 0; - - unsigned offset = 0; - if (source_scan_type == 2) offset = frame_in->stride; - - //Luma - for (int i = 0; i < field_out->height; ++i){ - kvz_pixel *row_in = frame_in->y + CLIP(0, frame_in->height - 1, 2 * i) * frame_in->stride + offset; - kvz_pixel *row_out = field_out->y + i * field_out->stride + offset; - memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width); - } - - //Chroma - for (int i = 0; i < field_out->height / 2; ++i){ - kvz_pixel *row_in = frame_in->u + CLIP(0, frame_in->height / 2 - 1, 2 * i) * frame_in->stride / 2 + offset / 2; - kvz_pixel *row_out = field_out->u + i * field_out->stride / 2 + offset / 2; - memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width / 2); - } - - for (int i = 0; i < field_out->height / 2; ++i){ - kvz_pixel *row_in = frame_in->v + CLIP(0, frame_in->height / 2 - 1, 2 * i) * frame_in->stride / 2 + offset / 2; - kvz_pixel *row_out = field_out->v + i * field_out->stride / 2 + offset / 2; - memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width / 2); - } - - return 1; -} \ No newline at end of file
View file
kvazaar-0.8.2.tar.gz/src/yuv_io.h -> kvazaar-0.8.3.tar.gz/src/yuv_io.h
Changed
@@ -39,6 +39,4 @@ const kvz_picture *img, unsigned output_width, unsigned output_height); -int yuv_io_extract_field(const kvz_picture *frame_in, unsigned source_scan_type, unsigned field_parity, kvz_picture *field_out); - #endif // YUV_IO_H_
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.