Merge branch 'refactor'

This commit is contained in:
Arttu Ylä-Outinen 2016-08-10 20:05:31 +09:00
commit 25eb973c38
28 changed files with 1422 additions and 1344 deletions

View file

@ -139,6 +139,7 @@
<ClCompile Include="..\..\src\encoder_state-bitstream.c" />
<ClCompile Include="..\..\src\encoder_state-ctors_dtors.c" />
<ClCompile Include="..\..\src\encoder_state-geometry.c" />
<ClCompile Include="..\..\src\encode_coding_tree.c" />
<ClCompile Include="..\..\src\extras\getopt.c" />
<ClCompile Include="..\..\src\filter.c" />
<ClCompile Include="..\..\src\image.c" />
@ -217,6 +218,7 @@
<ClInclude Include="..\..\src\encoder_state-bitstream.h" />
<ClInclude Include="..\..\src\encoder_state-ctors_dtors.h" />
<ClInclude Include="..\..\src\encoder_state-geometry.h" />
<ClInclude Include="..\..\src\encode_coding_tree.h" />
<ClCompile Include="..\..\src\strategyselector.c" />
<ClCompile Include="..\..\src\tables.c" />
<ClCompile Include="..\..\src\threadqueue.c" />

View file

@ -207,6 +207,9 @@
<ClCompile Include="..\..\src\encoder_state-bitstream.c">
<Filter>Bitstream</Filter>
</ClCompile>
<ClCompile Include="..\..\src\encode_coding_tree.c">
<Filter>Bitstream</Filter>
</ClCompile>
<ClCompile Include="..\..\src\strategies\strategies-sao.c">
<Filter>Optimization\strategies</Filter>
</ClCompile>
@ -393,6 +396,9 @@
<ClInclude Include="..\..\src\encoder_state-bitstream.h">
<Filter>Bitstream</Filter>
</ClInclude>
<ClInclude Include="..\..\src\encode_coding_tree.h">
<Filter>Bitstream</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kvz_math.h" />
<ClInclude Include="..\..\src\strategies\strategies-sao.h">
<Filter>Optimization\strategies</Filter>

View file

@ -56,6 +56,8 @@ libkvazaar_la_SOURCES = \
encoder_state-ctors_dtors.h \
encoder_state-geometry.c \
encoder_state-geometry.h \
encode_coding_tree.c \
encode_coding_tree.h \
filter.c \
filter.h \
global.h \

View file

@ -19,7 +19,11 @@
****************************************************************************/
#include "cabac.h"
#include "encoder.h"
#include "encoderstate.h"
#include "extras/crypto.h"
#include "kvazaar.h"
const uint8_t kvz_g_auc_next_state_mps[128] =
{

1082
src/encode_coding_tree.c Normal file

File diff suppressed because it is too large Load diff

44
src/encode_coding_tree.h Normal file
View file

@ -0,0 +1,44 @@
#ifndef ENCODE_CODING_TREE_H_
#define ENCODE_CODING_TREE_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/>.
****************************************************************************/
/**
* \file
* Functions for writing the coding quadtree and related syntax.
*/
#include "encoderstate.h"
#include "global.h"
void kvz_encode_coding_tree(encoder_state_t *state,
uint16_t x_ctb,
uint16_t y_ctb,
uint8_t depth);
void kvz_encode_coeff_nxn(encoder_state_t *state,
coeff_t *coeff,
uint8_t width,
uint8_t type,
int8_t scan_mode,
int8_t tr_skip);
#endif // ENCODE_CODING_TREE_H_

View file

@ -46,8 +46,8 @@ static void encoder_state_write_bitstream_aud(encoder_state_t * const state)
bitstream_t * const stream = &state->stream;
kvz_nal_write(stream, KVZ_NAL_AUD_NUT, 0, 1);
uint8_t pic_type = state->global->slicetype == KVZ_SLICE_I ? 0
: state->global->slicetype == KVZ_SLICE_P ? 1
uint8_t pic_type = state->frame->slicetype == KVZ_SLICE_I ? 0
: state->frame->slicetype == KVZ_SLICE_P ? 1
: 2;
WRITE_U(stream, pic_type, 3, "pic_type");
@ -579,7 +579,7 @@ static void encoder_state_write_picture_timing_sei_message(encoder_state_t * con
if (state->encoder_control->vui.frame_field_info_present_flag){
int8_t odd_picture = state->global->frame % 2;
int8_t odd_picture = state->frame->num % 2;
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
@ -651,22 +651,22 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
int ref_negative = 0;
int ref_positive = 0;
if (encoder->cfg->gop_len) {
for (j = 0; j < state->global->ref->used_size; j++) {
if (state->global->ref->pocs[j] < state->global->poc) {
for (j = 0; j < state->frame->ref->used_size; j++) {
if (state->frame->ref->pocs[j] < state->frame->poc) {
ref_negative++;
} else {
ref_positive++;
}
}
} else ref_negative = state->global->ref->used_size;
} else ref_negative = state->frame->ref->used_size;
#ifdef KVZ_DEBUG
printf("=========== Slice ===========\n");
#endif
WRITE_U(stream, (state->slice->start_in_rs == 0), 1, "first_slice_segment_in_pic_flag");
if (state->global->pictype >= KVZ_NAL_BLA_W_LP
&& state->global->pictype <= KVZ_NAL_RSV_IRAP_VCL23) {
if (state->frame->pictype >= KVZ_NAL_BLA_W_LP
&& state->frame->pictype <= KVZ_NAL_RSV_IRAP_VCL23) {
WRITE_U(stream, 1, 1, "no_output_of_prior_pics_flag");
}
@ -677,7 +677,7 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
WRITE_UE(stream, state->slice->start_in_rs, "slice_segment_address");
}
WRITE_UE(stream, state->global->slicetype, "slice_type");
WRITE_UE(stream, state->frame->slicetype, "slice_type");
// if !entropy_slice_flag
@ -685,12 +685,12 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
//WRITE_U(stream, 1, 1, "pic_output_flag");
//end if
//if( IdrPicFlag ) <- nal_unit_type == 5
if (state->global->pictype != KVZ_NAL_IDR_W_RADL
&& state->global->pictype != KVZ_NAL_IDR_N_LP) {
if (state->frame->pictype != KVZ_NAL_IDR_W_RADL
&& state->frame->pictype != KVZ_NAL_IDR_N_LP) {
int last_poc = 0;
int poc_shift = 0;
WRITE_U(stream, state->global->poc&0x1f, 5, "pic_order_cnt_lsb");
WRITE_U(stream, state->frame->poc&0x1f, 5, "pic_order_cnt_lsb");
WRITE_U(stream, 0, 1, "short_term_ref_pic_set_sps_flag");
WRITE_UE(stream, ref_negative, "num_negative_pics");
WRITE_UE(stream, ref_positive, "num_positive_pics");
@ -700,9 +700,9 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
if (encoder->cfg->gop_len) {
int8_t found = 0;
do {
delta_poc = encoder->cfg->gop[state->global->gop_offset].ref_neg[j + poc_shift];
for (int i = 0; i < state->global->ref->used_size; i++) {
if (state->global->ref->pocs[i] == state->global->poc - delta_poc) {
delta_poc = encoder->cfg->gop[state->frame->gop_offset].ref_neg[j + poc_shift];
for (int i = 0; i < state->frame->ref->used_size; i++) {
if (state->frame->ref->pocs[i] == state->frame->poc - delta_poc) {
found = 1;
break;
}
@ -727,9 +727,9 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
if (encoder->cfg->gop_len) {
int8_t found = 0;
do {
delta_poc = encoder->cfg->gop[state->global->gop_offset].ref_pos[j + poc_shift];
for (int i = 0; i < state->global->ref->used_size; i++) {
if (state->global->ref->pocs[i] == state->global->poc + delta_poc) {
delta_poc = encoder->cfg->gop[state->frame->gop_offset].ref_pos[j + poc_shift];
for (int i = 0; i < state->frame->ref->used_size; i++) {
if (state->frame->ref->pocs[i] == state->frame->poc + delta_poc) {
found = 1;
break;
}
@ -756,10 +756,10 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
WRITE_U(stream, 1, 1, "slice_sao_chroma_flag");
}
if (state->global->slicetype != KVZ_SLICE_I) {
if (state->frame->slicetype != KVZ_SLICE_I) {
WRITE_U(stream, 1, 1, "num_ref_idx_active_override_flag");
WRITE_UE(stream, ref_negative != 0 ? ref_negative - 1: 0, "num_ref_idx_l0_active_minus1");
if (state->global->slicetype == KVZ_SLICE_B) {
if (state->frame->slicetype == KVZ_SLICE_B) {
WRITE_UE(stream, ref_positive != 0 ? ref_positive - 1 : 0, "num_ref_idx_l1_active_minus1");
WRITE_U(stream, 0, 1, "mvd_l1_zero_flag");
}
@ -767,7 +767,7 @@ void kvz_encoder_state_write_bitstream_slice_header(encoder_state_t * const stat
}
{
int slice_qp_delta = state->global->QP - encoder->cfg->qp;
int slice_qp_delta = state->frame->QP - encoder->cfg->qp;
WRITE_SE(stream, slice_qp_delta, "slice_qp_delta");
}
@ -872,15 +872,15 @@ static void encoder_state_write_bitstream_main(encoder_state_t * const state)
encoder_state_write_bitstream_aud(state);
}
if ((encoder->vps_period > 0 && state->global->frame % encoder->vps_period == 0)
|| (state->global->frame == 0 && encoder->vps_period >= 0))
if ((encoder->vps_period > 0 && state->frame->num % encoder->vps_period == 0)
|| (state->frame->num == 0 && encoder->vps_period >= 0))
{
first_nal_in_au = false;
kvz_encoder_state_write_parameter_sets(&state->stream, state);
}
// Send Kvazaar version information only in the first frame.
if (state->global->frame == 0 && encoder->cfg->add_encoder_info) {
if (state->frame->num == 0 && encoder->cfg->add_encoder_info) {
kvz_nal_write(stream, KVZ_NAL_PREFIX_SEI_NUT, 0, first_nal_in_au);
encoder_state_write_bitstream_prefix_sei_version(state);
@ -904,38 +904,38 @@ static void encoder_state_write_bitstream_main(encoder_state_t * const state)
}
{
uint8_t nal_type = (state->global->is_idr_frame ? KVZ_NAL_IDR_W_RADL : KVZ_NAL_TRAIL_R);
uint8_t nal_type = (state->frame->is_idr_frame ? KVZ_NAL_IDR_W_RADL : KVZ_NAL_TRAIL_R);
kvz_nal_write(stream, nal_type, 0, first_nal_in_au);
}
{
PERFORMANCE_MEASURE_START(KVZ_PERF_FRAME);
encoder_state_write_bitstream_children(state);
PERFORMANCE_MEASURE_END(KVZ_PERF_FRAME, encoder->threadqueue, "type=write_bitstream_append,frame=%d,encoder_type=%c", state->global->frame, state->type);
PERFORMANCE_MEASURE_END(KVZ_PERF_FRAME, encoder->threadqueue, "type=write_bitstream_append,frame=%d,encoder_type=%c", state->frame->num, state->type);
}
if (state->encoder_control->cfg->hash != KVZ_HASH_NONE) {
PERFORMANCE_MEASURE_START(KVZ_PERF_FRAME);
// Calculate checksum
add_checksum(state);
PERFORMANCE_MEASURE_END(KVZ_PERF_FRAME, encoder->threadqueue, "type=write_bitstream_checksum,frame=%d,encoder_type=%c", state->global->frame, state->type);
PERFORMANCE_MEASURE_END(KVZ_PERF_FRAME, encoder->threadqueue, "type=write_bitstream_checksum,frame=%d,encoder_type=%c", state->frame->num, state->type);
}
//Get bitstream length for stats
uint64_t newpos = kvz_bitstream_tell(stream);
state->stats_bitstream_length = (newpos >> 3) - (curpos >> 3);
if (state->global->frame > 0) {
state->global->total_bits_coded = state->previous_encoder_state->global->total_bits_coded;
if (state->frame->num > 0) {
state->frame->total_bits_coded = state->previous_encoder_state->frame->total_bits_coded;
}
state->global->total_bits_coded += newpos - curpos;
state->frame->total_bits_coded += newpos - curpos;
if (encoder->cfg->gop_len > 0 && state->global->gop_offset > 0) {
state->global->cur_gop_bits_coded = state->previous_encoder_state->global->cur_gop_bits_coded;
if (encoder->cfg->gop_len > 0 && state->frame->gop_offset > 0) {
state->frame->cur_gop_bits_coded = state->previous_encoder_state->frame->cur_gop_bits_coded;
} else {
state->global->cur_gop_bits_coded = 0;
state->frame->cur_gop_bits_coded = 0;
}
state->global->cur_gop_bits_coded += newpos - curpos;
state->frame->cur_gop_bits_coded += newpos - curpos;
}
void kvz_encoder_state_write_bitstream_leaf(encoder_state_t * const state)

View file

@ -29,30 +29,32 @@
#include "encoder.h"
#include "encoder_state-geometry.h"
#include "encoderstate.h"
#include "extras/crypto.h"
#include "image.h"
#include "imagelist.h"
#include "kvazaar.h"
#include "threadqueue.h"
#include "videoframe.h"
static int encoder_state_config_global_init(encoder_state_t * const state) {
state->global->ref = kvz_image_list_alloc(MAX_REF_PIC_COUNT);
if(!state->global->ref) {
static int encoder_state_config_frame_init(encoder_state_t * const state) {
state->frame->ref = kvz_image_list_alloc(MAX_REF_PIC_COUNT);
if(!state->frame->ref) {
fprintf(stderr, "Failed to allocate the picture list!\n");
return 0;
}
state->global->ref_list = REF_PIC_LIST_0;
state->global->frame = 0;
state->global->poc = 0;
state->global->total_bits_coded = 0;
state->global->cur_gop_bits_coded = 0;
state->global->rc_alpha = 3.2003;
state->global->rc_beta = -1.367;
state->frame->ref_list = REF_PIC_LIST_0;
state->frame->num = 0;
state->frame->poc = 0;
state->frame->total_bits_coded = 0;
state->frame->cur_gop_bits_coded = 0;
state->frame->rc_alpha = 3.2003;
state->frame->rc_beta = -1.367;
return 1;
}
static void encoder_state_config_global_finalize(encoder_state_t * const state) {
kvz_image_list_destroy(state->global->ref);
static void encoder_state_config_frame_finalize(encoder_state_t * const state) {
kvz_image_list_destroy(state->frame->ref);
}
static int encoder_state_config_tile_init(encoder_state_t * const state,
@ -245,7 +247,7 @@ static void encoder_state_dump_graphviz(const encoder_state_t * const state) {
printf(" \"%p\" [\n", state);
printf(" label = \"{encoder_state|");
printf("+ type=%c\\l", state->type);
if (!state->parent || state->global != state->parent->global) {
if (!state->parent || state->frame != state->parent->global) {
printf("|+ global\\l");
}
if (!state->parent || state->tile != state->parent->tile) {
@ -292,7 +294,7 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t
//
//If parent_state is not NULL, the following variable should either be set to NULL,
//in order to inherit from parent, or should point to a valid structure:
//child_state->global
//child_state->frame
//child_state->tile
//child_state->slice
//child_state->wfrow
@ -309,9 +311,9 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t
const encoder_control_t * const encoder = child_state->encoder_control;
child_state->type = ENCODER_STATE_TYPE_MAIN;
assert(child_state->encoder_control);
child_state->global = MALLOC(encoder_state_config_global_t, 1);
if (!child_state->global || !encoder_state_config_global_init(child_state)) {
fprintf(stderr, "Could not initialize encoder_state->global!\n");
child_state->frame = MALLOC(encoder_state_config_frame_t, 1);
if (!child_state->frame || !encoder_state_config_frame_init(child_state)) {
fprintf(stderr, "Could not initialize encoder_state->frame!\n");
return 0;
}
child_state->tile = MALLOC(encoder_state_config_tile_t, 1);
@ -331,7 +333,7 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t
}
} else {
child_state->encoder_control = parent_state->encoder_control;
if (!child_state->global) child_state->global = parent_state->global;
if (!child_state->frame) child_state->frame = parent_state->frame;
if (!child_state->tile) child_state->tile = parent_state->tile;
if (!child_state->slice) child_state->slice = parent_state->slice;
if (!child_state->wfrow) child_state->wfrow = parent_state->wfrow;
@ -419,9 +421,9 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t
//Create a slice
new_child = &child_state->children[child_count];
new_child->encoder_control = encoder;
new_child->type = ENCODER_STATE_TYPE_SLICE;
new_child->global = child_state->global;
new_child->tile = child_state->tile;
new_child->type = ENCODER_STATE_TYPE_SLICE;
new_child->frame = child_state->frame;
new_child->tile = child_state->tile;
new_child->wfrow = child_state->wfrow;
new_child->slice = MALLOC(encoder_state_config_slice_t, 1);
if (!new_child->slice || !encoder_state_config_slice_init(new_child, range_start, range_end_slice)) {
@ -445,9 +447,9 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t
new_child = &child_state->children[child_count];
new_child->encoder_control = encoder;
new_child->type = ENCODER_STATE_TYPE_TILE;
new_child->global = child_state->global;
new_child->tile = MALLOC(encoder_state_config_tile_t, 1);
new_child->type = ENCODER_STATE_TYPE_TILE;
new_child->frame = child_state->frame;
new_child->tile = MALLOC(encoder_state_config_tile_t, 1);
new_child->slice = child_state->slice;
new_child->wfrow = child_state->wfrow;
@ -529,9 +531,9 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t
encoder_state_t *new_child = &child_state->children[i];
new_child->encoder_control = encoder;
new_child->type = ENCODER_STATE_TYPE_WAVEFRONT_ROW;
new_child->global = child_state->global;
new_child->tile = child_state->tile;
new_child->type = ENCODER_STATE_TYPE_WAVEFRONT_ROW;
new_child->frame = child_state->frame;
new_child->tile = child_state->tile;
new_child->slice = child_state->slice;
new_child->wfrow = MALLOC(encoder_state_config_wfrow_t, 1);
@ -686,9 +688,9 @@ void kvz_encoder_state_finalize(encoder_state_t * const state) {
FREE_POINTER(state->tile);
}
if (!state->parent || (state->parent->global != state->global)) {
encoder_state_config_global_finalize(state);
FREE_POINTER(state->global);
if (!state->parent || (state->parent->frame != state->frame)) {
encoder_state_config_frame_finalize(state);
FREE_POINTER(state->frame);
}
kvz_bitstream_finalize(&state->stream);

File diff suppressed because it is too large Load diff

View file

@ -50,13 +50,13 @@ typedef enum {
typedef struct {
typedef struct encoder_state_config_frame_t {
double cur_lambda_cost; //!< \brief Lambda for SSE
double cur_lambda_cost_sqrt; //!< \brief Lambda for SAD and SATD
int32_t frame;
int32_t poc; /*!< \brief picture order count */
int8_t gop_offset; /*!< \brief offset in the gop structure */
int32_t num; /*!< \brief Frame number */
int32_t poc; /*!< \brief Picture order count */
int8_t gop_offset; /*!< \brief Offset in the gop structure */
int8_t QP; //!< \brief Quantization parameter
double QP_factor; //!< \brief Quantization factor
@ -88,9 +88,9 @@ typedef struct {
double rc_alpha;
double rc_beta;
} encoder_state_config_global_t;
} encoder_state_config_frame_t;
typedef struct {
typedef struct encoder_state_config_tile_t {
//Current sub-frame
videoframe_t *frame;
@ -121,7 +121,7 @@ typedef struct {
} encoder_state_config_tile_t;
typedef struct {
typedef struct encoder_state_config_slice_t {
int32_t id;
//Global coordinates
@ -133,7 +133,7 @@ typedef struct {
int32_t end_in_rs;
} encoder_state_config_slice_t;
typedef struct {
typedef struct encoder_state_config_wfrow_t {
//Row in tile coordinates of the wavefront
int32_t lcu_offset_y;
} encoder_state_config_wfrow_t;
@ -169,7 +169,7 @@ typedef struct encoder_state_t {
//Pointer to the encoder_state of the previous frame
struct encoder_state_t *previous_encoder_state;
encoder_state_config_global_t *global;
encoder_state_config_frame_t *frame;
encoder_state_config_tile_t *tile;
encoder_state_config_slice_t *slice;
encoder_state_config_wfrow_t *wfrow;
@ -206,20 +206,6 @@ void kvz_encode_one_frame(encoder_state_t * const state, kvz_picture* frame);
void kvz_encoder_prepare(encoder_state_t *state);
void kvz_encode_coding_tree(encoder_state_t *state, uint16_t x_ctb,
uint16_t y_ctb, uint8_t depth);
void kvz_encode_last_significant_xy(encoder_state_t *state,
uint8_t lastpos_x, uint8_t lastpos_y,
uint8_t width, uint8_t height,
uint8_t type, uint8_t scan);
void kvz_encode_coeff_nxn(encoder_state_t *state, coeff_t *coeff, uint8_t width,
uint8_t type, int8_t scan_mode, int8_t tr_skip);
void kvz_encode_transform_coeff(encoder_state_t *state, int32_t x_cu, int32_t y_cu,
int8_t depth, int8_t tr_depth, uint8_t parent_coeff_u, uint8_t parent_coeff_v);
void encode_block_residual(const encoder_control_t * const encoder,
uint16_t x_ctb, uint16_t y_ctb, uint8_t depth);
int kvz_encoder_state_match_children_of_previous_frame(encoder_state_t * const state);
coeff_scan_order_t kvz_get_scan_order(int8_t cu_type, int intra_mode, int depth);

View file

@ -291,7 +291,7 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
kvz_pixel *src = orig_src;
int8_t strength = 0;
int32_t qp = state->global->QP;
int32_t qp = state->frame->QP;
int32_t bitdepth_scale = 1 << (encoder->bitdepth - 8);
int32_t b_index = CLIP(0, 51, qp + (beta_offset_div2 << 1));
int32_t beta = kvz_g_beta_table_8x8[b_index] * bitdepth_scale;
@ -345,7 +345,7 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
}
// B-slice related checks
if(!strength && state->global->slicetype == KVZ_SLICE_B) {
if(!strength && state->frame->slicetype == KVZ_SLICE_B) {
// Zero all undefined motion vectors for easier usage
if(!(cu_q->inter.mv_dir & 1)) {
@ -490,7 +490,7 @@ static void filter_deblock_edge_chroma(encoder_state_t * const state,
};
int8_t strength = 2;
int32_t QP = kvz_g_chroma_scale[state->global->QP];
int32_t QP = kvz_g_chroma_scale[state->frame->QP];
int32_t bitdepth_scale = 1 << (encoder->bitdepth-8);
int32_t TC_index = CLIP(0, 51+2, (int32_t)(QP + 2*(strength-1) + (tc_offset_div2 << 1)));
int32_t Tc = kvz_g_tc_table_8x8[TC_index]*bitdepth_scale;

View file

@ -23,7 +23,6 @@
#include "encoder.h"
#include "encoderstate.h"
#include "image.h"
#include "videoframe.h"
void kvz_init_input_frame_buffer(input_frame_buffer_t *input_buffer)
@ -59,7 +58,7 @@ kvz_picture* kvz_encoder_feed_frame(input_frame_buffer_t *buf,
const int gop_buf_size = 3 * cfg->gop_len;
assert(state->global->frame >= 0);
assert(state->frame->num >= 0);
if (cfg->gop_len == 0 || cfg->gop_lowdelay) {
// No reordering of output pictures necessary.
@ -67,12 +66,12 @@ kvz_picture* kvz_encoder_feed_frame(input_frame_buffer_t *buf,
if (img_in == NULL) return NULL;
img_in->dts = img_in->pts;
state->global->gop_offset = 0;
state->frame->gop_offset = 0;
if (cfg->gop_lowdelay) {
state->global->gop_offset = (state->global->frame - 1) % cfg->gop_len;
if (state->global->gop_offset < 0) {
state->frame->gop_offset = (state->frame->num - 1) % cfg->gop_len;
if (state->frame->gop_offset < 0) {
// Set gop_offset of IDR as the highest quality picture.
state->global->gop_offset += cfg->gop_len;
state->frame->gop_offset += cfg->gop_len;
}
}
return kvz_image_copy_ref(img_in);
@ -173,7 +172,7 @@ kvz_picture* kvz_encoder_feed_frame(input_frame_buffer_t *buf,
assert(next_pic != NULL);
next_pic->dts = dts_out;
buf->pic_buffer[buf_idx] = NULL;
state->global->gop_offset = gop_offset;
state->frame->gop_offset = gop_offset;
buf->num_out++;
return next_pic;

View file

@ -25,9 +25,9 @@
#include "encoder.h"
#include "imagelist.h"
#include "strategies/generic/ipol-generic.h"
#include "strategies/generic/picture-generic.h"
#include "strategies/strategies-ipol.h"
#include "videoframe.h"
static void inter_recon_frac_luma(const encoder_state_t * const state,
@ -854,8 +854,8 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
int8_t reflist2nd = !reflist;
#define CALCULATE_SCALE(cu,tb,td) ((tb * ((0x4000 + (abs(td)>>1))/td) + 32) >> 6)
#define APPLY_MV_SCALING(cu, cand, list) {int td = state->global->poc - state->global->ref->pocs[(cu)->inter.mv_ref[list]];\
int tb = state->global->poc - state->global->ref->pocs[cur_cu->inter.mv_ref[reflist]];\
#define APPLY_MV_SCALING(cu, cand, list) {int td = state->frame->poc - state->frame->ref->pocs[(cu)->inter.mv_ref[list]];\
int tb = state->frame->poc - state->frame->ref->pocs[cur_cu->inter.mv_ref[reflist]];\
if (td != tb) { \
int scale = CALCULATE_SCALE(cu,tb,td); \
mv_cand[cand][0] = ((scale * (cu)->inter.mv[list][0] + 127 + (scale * (cu)->inter.mv[list][0] < 0)) >> 8 ); \
@ -1202,7 +1202,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
}
#endif
if (candidates < MRG_MAX_NUM_CANDS && state->global->slicetype == KVZ_SLICE_B) {
if (candidates < MRG_MAX_NUM_CANDS && state->frame->slicetype == KVZ_SLICE_B) {
#define NUM_PRIORITY_LIST 12;
static const uint8_t priorityList0[] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
static const uint8_t priorityList1[] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
@ -1235,14 +1235,14 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
}
}
int num_ref = state->global->ref->used_size;
int num_ref = state->frame->ref->used_size;
if (candidates < MRG_MAX_NUM_CANDS && state->global->slicetype == KVZ_SLICE_B) {
if (candidates < MRG_MAX_NUM_CANDS && state->frame->slicetype == KVZ_SLICE_B) {
int j;
int ref_negative = 0;
int ref_positive = 0;
for (j = 0; j < state->global->ref->used_size; j++) {
if (state->global->ref->pocs[j] < state->global->poc) {
for (j = 0; j < state->frame->ref->used_size; j++) {
if (state->frame->ref->pocs[j] < state->frame->poc) {
ref_negative++;
} else {
ref_positive++;
@ -1258,7 +1258,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
mv_cand[candidates].ref[0] = (zero_idx>=num_ref-1)?0:zero_idx;
mv_cand[candidates].ref[1] = mv_cand[candidates].ref[0];
mv_cand[candidates].dir = 1;
if (state->global->slicetype == KVZ_SLICE_B) {
if (state->frame->slicetype == KVZ_SLICE_B) {
mv_cand[candidates].mv[1][0] = 0;
mv_cand[candidates].mv[1][1] = 0;
mv_cand[candidates].dir = 3;

View file

@ -25,7 +25,6 @@
#include "image.h"
#include "kvz_math.h"
#include "strategies/strategies-intra.h"
#include "strategies/strategies-picture.h"
#include "tables.h"
#include "transform.h"
#include "videoframe.h"

View file

@ -100,7 +100,7 @@ static kvz_encoder * kvazaar_open(const kvz_config *cfg)
goto kvazaar_open_failure;
}
encoder->states[i].global->QP = (int8_t)cfg->qp;
encoder->states[i].frame->QP = (int8_t)cfg->qp;
}
for (int i = 0; i < encoder->num_encoder_states; ++i) {
@ -112,7 +112,7 @@ static kvz_encoder * kvazaar_open(const kvz_config *cfg)
kvz_encoder_state_match_children_of_previous_frame(&encoder->states[i]);
}
encoder->states[encoder->cur_state_num].global->frame = -1;
encoder->states[encoder->cur_state_num].frame->num = -1;
return encoder;
@ -124,10 +124,10 @@ kvazaar_open_failure:
static void set_frame_info(kvz_frame_info *const info, const encoder_state_t *const state)
{
info->poc = state->global->poc,
info->qp = state->global->QP;
info->nal_unit_type = state->global->pictype;
info->slice_type = state->global->slicetype;
info->poc = state->frame->poc,
info->qp = state->frame->QP;
info->nal_unit_type = state->frame->pictype;
info->slice_type = state->frame->slicetype;
kvz_encoder_get_ref_lists(state, info->ref_list_len, info->ref_list);
}
@ -217,12 +217,12 @@ static int kvazaar_encode(kvz_encoder *enc,
if (pic_in != NULL) {
// FIXME: The frame number printed here is wrong when GOP is enabled.
CHECKPOINT_MARK("read source frame: %d", state->global->frame + enc->control->cfg->seek);
CHECKPOINT_MARK("read source frame: %d", state->frame->num + enc->control->cfg->seek);
}
kvz_picture* frame = kvz_encoder_feed_frame(&enc->input_buffer, state, pic_in);
if (frame) {
assert(state->global->frame == enc->frames_started);
assert(state->frame->num == enc->frames_started);
// Start encoding.
kvz_encode_one_frame(state, frame);
enc->frames_started += 1;

View file

@ -42,19 +42,19 @@ static void update_rc_parameters(encoder_state_t * state)
const double bpp = state->stats_bitstream_length * 8 / pixels_per_picture;
const double log_bpp = log(bpp);
const double alpha_old = state->global->rc_alpha;
const double beta_old = state->global->rc_beta;
const double alpha_old = state->frame->rc_alpha;
const double beta_old = state->frame->rc_beta;
// lambda computed from real bpp
const double lambda_comp = CLIP(0.1, 10000, alpha_old * pow(bpp, beta_old));
// lambda used in encoding
const double lambda_real = state->global->cur_lambda_cost;
const double lambda_real = state->frame->cur_lambda_cost;
const double lambda_log_ratio = log(lambda_real) - log(lambda_comp);
const double alpha = alpha_old + 0.1 * lambda_log_ratio * alpha_old;
state->global->rc_alpha = CLIP(0.05, 20, alpha);
state->frame->rc_alpha = CLIP(0.05, 20, alpha);
const double beta = beta_old + 0.05 * lambda_log_ratio * CLIP(-5, 1, log_bpp);
state->global->rc_beta = CLIP(-3, -0.1, beta);
state->frame->rc_beta = CLIP(-3, -0.1, beta);
}
/**
@ -71,14 +71,14 @@ static void gop_allocate_bits(encoder_state_t * const state)
// At this point, total_bits_coded of the current state contains the
// number of bits written encoder->owf frames before the current frame.
uint64_t bits_coded = state->global->total_bits_coded;
int pictures_coded = MAX(0, state->global->frame - encoder->owf);
uint64_t bits_coded = state->frame->total_bits_coded;
int pictures_coded = MAX(0, state->frame->num - encoder->owf);
int gop_offset = (state->global->gop_offset - encoder->owf) % MAX(1, encoder->cfg->gop_len);
int gop_offset = (state->frame->gop_offset - encoder->owf) % MAX(1, encoder->cfg->gop_len);
// Only take fully coded GOPs into account.
if (encoder->cfg->gop_len > 0 && gop_offset != encoder->cfg->gop_len - 1) {
// Subtract number of bits in the partially coded GOP.
bits_coded -= state->global->cur_gop_bits_coded;
bits_coded -= state->frame->cur_gop_bits_coded;
// Subtract number of pictures in the partially coded GOP.
pictures_coded -= gop_offset + 1;
}
@ -86,7 +86,7 @@ static void gop_allocate_bits(encoder_state_t * const state)
double gop_target_bits =
(encoder->target_avg_bppic * (pictures_coded + SMOOTHING_WINDOW) - bits_coded)
* MAX(1, encoder->cfg->gop_len) / SMOOTHING_WINDOW;
state->global->cur_gop_target_bits = MAX(200, gop_target_bits);
state->frame->cur_gop_target_bits = MAX(200, gop_target_bits);
}
/**
@ -99,12 +99,12 @@ static double pic_allocate_bits(const encoder_state_t * const state)
const encoder_control_t * const encoder = state->encoder_control;
if (encoder->cfg->gop_len <= 0) {
return state->global->cur_gop_target_bits;
return state->frame->cur_gop_target_bits;
}
const double pic_weight = encoder->gop_layer_weights[
encoder->cfg->gop[state->global->gop_offset].layer - 1];
double pic_target_bits = state->global->cur_gop_target_bits * pic_weight;
encoder->cfg->gop[state->frame->gop_offset].layer - 1];
double pic_target_bits = state->frame->cur_gop_target_bits * pic_weight;
return MAX(100, pic_target_bits);
}
@ -122,20 +122,20 @@ double kvz_select_picture_lambda(encoder_state_t * const state)
assert(encoder->cfg->target_bitrate > 0);
if (state->global->frame > encoder->owf) {
if (state->frame->num > encoder->owf) {
// At least one frame has been written.
update_rc_parameters(state);
}
if (encoder->cfg->gop_len == 0 ||
state->global->gop_offset == 0 ||
state->global->frame == 0)
state->frame->gop_offset == 0 ||
state->frame->num == 0)
{
// A new GOP begins at this frame.
gop_allocate_bits(state);
} else {
state->global->cur_gop_target_bits =
state->previous_encoder_state->global->cur_gop_target_bits;
state->frame->cur_gop_target_bits =
state->previous_encoder_state->frame->cur_gop_target_bits;
}
// TODO: take the picture headers into account
@ -143,7 +143,7 @@ double kvz_select_picture_lambda(encoder_state_t * const state)
const double target_bits_per_pixel =
target_bits_current_picture / encoder->in.pixels_per_pic;
const double lambda =
state->global->rc_alpha * pow(target_bits_per_pixel, state->global->rc_beta);
state->frame->rc_alpha * pow(target_bits_per_pixel, state->frame->rc_beta);
return CLIP(0.1, 10000, lambda);
}
@ -167,9 +167,9 @@ double kvz_select_picture_lambda_from_qp(encoder_state_t const * const state)
const int intra_period = state->encoder_control->cfg->intra_period;
const int keyframe_period = gop_len > 0 ? gop_len : intra_period;
double lambda = pow(2.0, (state->global->QP - 12) / 3.0);
double lambda = pow(2.0, (state->frame->QP - 12) / 3.0);
if (state->global->slicetype == KVZ_SLICE_I) {
if (state->frame->slicetype == KVZ_SLICE_I) {
lambda *= 0.57;
// Reduce lambda for I-frames according to the number of references.
@ -179,14 +179,14 @@ double kvz_select_picture_lambda_from_qp(encoder_state_t const * const state)
lambda *= 1.0 - CLIP(0.0, 0.5, 0.05 * (keyframe_period - 1));
}
} else if (gop_len > 0) {
lambda *= state->global->QP_factor;
lambda *= state->frame->QP_factor;
} else {
lambda *= 0.4624;
}
// Increase lambda if not key-frame.
if (keyframe_period > 0 && state->global->poc % keyframe_period != 0) {
lambda *= CLIP(2.0, 4.0, (state->global->QP - 12) / 6.0);
if (keyframe_period > 0 && state->frame->poc % keyframe_period != 0) {
lambda *= CLIP(2.0, 4.0, (state->frame->QP - 12) / 6.0);
}
return lambda;

View file

@ -25,11 +25,11 @@
#include "cabac.h"
#include "context.h"
#include "encode_coding_tree.h"
#include "encoder.h"
#include "imagelist.h"
#include "inter.h"
#include "scalinglist.h"
#include "strategies/strategies-quant.h"
#include "tables.h"
#include "transform.h"
@ -259,7 +259,7 @@ uint32_t kvz_get_coded_level ( encoder_state_t * const state, double *coded_cost
cabac_ctx_t* base_sig_model = type?(cabac->ctx.cu_sig_model_chroma):(cabac->ctx.cu_sig_model_luma);
if( !last && max_abs_level < 3 ) {
*coded_cost_sig = state->global->cur_lambda_cost * CTX_ENTROPY_BITS(&base_sig_model[ctx_num_sig], 0);
*coded_cost_sig = state->frame->cur_lambda_cost * CTX_ENTROPY_BITS(&base_sig_model[ctx_num_sig], 0);
*coded_cost = *coded_cost0 + *coded_cost_sig;
if (max_abs_level == 0) return best_abs_level;
} else {
@ -267,13 +267,13 @@ uint32_t kvz_get_coded_level ( encoder_state_t * const state, double *coded_cost
}
if( !last ) {
cur_cost_sig = state->global->cur_lambda_cost * CTX_ENTROPY_BITS(&base_sig_model[ctx_num_sig], 1);
cur_cost_sig = state->frame->cur_lambda_cost * CTX_ENTROPY_BITS(&base_sig_model[ctx_num_sig], 1);
}
min_abs_level = ( max_abs_level > 1 ? max_abs_level - 1 : 1 );
for (abs_level = max_abs_level; abs_level >= min_abs_level ; abs_level-- ) {
double err = (double)(level_double - ( abs_level << q_bits ) );
double cur_cost = err * err * temp + state->global->cur_lambda_cost *
double cur_cost = err * err * temp + state->frame->cur_lambda_cost *
kvz_get_ic_rate( state, abs_level, ctx_num_one, ctx_num_abs,
abs_go_rice, c1_idx, c2_idx, type);
cur_cost += cur_cost_sig;
@ -310,7 +310,7 @@ static double get_rate_last(const encoder_state_t * const state,
if( ctx_y > 3 ) {
uiCost += 32768.0 * ((ctx_y-2)>>1);
}
return state->global->cur_lambda_cost*uiCost;
return state->frame->cur_lambda_cost*uiCost;
}
static void calc_last_bits(encoder_state_t * const state, int32_t width, int32_t height, int8_t type,
@ -360,7 +360,7 @@ void kvz_rdoq_sign_hiding(const encoder_state_t *const state,
int64_t rd_factor = (int64_t)(
kvz_g_inv_quant_scales[qp_scaled % 6] * kvz_g_inv_quant_scales[qp_scaled % 6] * (1 << (2 * (qp_scaled / 6)))
/ state->global->cur_lambda_cost / 16 / (1 << (2 * (encoder->bitdepth - 8)))
/ state->frame->cur_lambda_cost / 16 / (1 << (2 * (encoder->bitdepth - 8)))
+ 0.5);
int32_t lastCG = -1;
int32_t absSum = 0;
@ -469,7 +469,7 @@ void kvz_rdoq(encoder_state_t * const state, coeff_t *coef, coeff_t *dest_coeff
uint32_t max_num_coeff = width * height;
int32_t scalinglist_type= (block_type == CU_INTRA ? 0 : 3) + (int8_t)("\0\3\1\2"[type]);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->global->QP, (encoder->bitdepth-8)*6);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->frame->QP, (encoder->bitdepth-8)*6);
uint32_t abs_sum = 0;
@ -675,7 +675,7 @@ void kvz_rdoq(encoder_state_t * const state, coeff_t *coef, coeff_t *dest_coeff
if (sig_coeffgroup_flag[ cg_blkpos ] == 0) {
uint32_t ctx_sig = kvz_context_get_sig_coeff_group(sig_coeffgroup_flag, cg_pos_x,
cg_pos_y, width);
cost_coeffgroup_sig[ cg_scanpos ] = state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
cost_coeffgroup_sig[ cg_scanpos ] = state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
base_cost += cost_coeffgroup_sig[ cg_scanpos ] - rd_stats.sig_cost;
} else {
if (cg_scanpos < cg_last_scanpos) {//skip the last coefficient group, which will be handled together with last position below.
@ -692,9 +692,9 @@ void kvz_rdoq(encoder_state_t * const state, coeff_t *coef, coeff_t *dest_coeff
ctx_sig = kvz_context_get_sig_coeff_group(sig_coeffgroup_flag, cg_pos_x,
cg_pos_y, width);
if (cg_scanpos < cg_last_scanpos) {
cost_coeffgroup_sig[cg_scanpos] = state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],1);
cost_coeffgroup_sig[cg_scanpos] = state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],1);
base_cost += cost_coeffgroup_sig[cg_scanpos];
cost_zero_cg += state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
cost_zero_cg += state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
}
// try to convert the current coeff group from non-zero to all-zero
@ -708,7 +708,7 @@ void kvz_rdoq(encoder_state_t * const state, coeff_t *coef, coeff_t *dest_coeff
sig_coeffgroup_flag[ cg_blkpos ] = 0;
base_cost = cost_zero_cg;
if (cg_scanpos < cg_last_scanpos) {
cost_coeffgroup_sig[ cg_scanpos ] = state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
cost_coeffgroup_sig[ cg_scanpos ] = state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
}
// reset coeffs to 0 in this block
for (scanpos_in_cg = cg_size-1; scanpos_in_cg >= 0; scanpos_in_cg--) {
@ -736,13 +736,13 @@ void kvz_rdoq(encoder_state_t * const state, coeff_t *coef, coeff_t *dest_coeff
if( block_type != CU_INTRA && !type/* && pcCU->getTransformIdx( uiAbsPartIdx ) == 0*/ ) {
best_cost = block_uncoded_cost + state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx.cu_qt_root_cbf_model),0);
base_cost += state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx.cu_qt_root_cbf_model),1);
best_cost = block_uncoded_cost + state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx.cu_qt_root_cbf_model),0);
base_cost += state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx.cu_qt_root_cbf_model),1);
} else {
cabac_ctx_t* base_cbf_model = type?(cabac->ctx.qt_cbf_model_chroma):(cabac->ctx.qt_cbf_model_luma);
ctx_cbf = ( type ? tr_depth : !tr_depth);
best_cost = block_uncoded_cost + state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],0);
base_cost += state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],1);
best_cost = block_uncoded_cost + state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],0);
base_cost += state->frame->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],1);
}
for (cg_scanpos = cg_last_scanpos; cg_scanpos >= 0; cg_scanpos--) {
@ -926,8 +926,8 @@ int kvz_calc_mvd_cost_cabac(encoder_state_t * const state, int x, int y, int mv_
uint32_t ref_list_idx;
uint32_t j;
int ref_list[2] = { 0, 0 };
for (j = 0; j < state->global->ref->used_size; j++) {
if (state->global->ref->pocs[j] < state->global->poc) {
for (j = 0; j < state->frame->ref->used_size; j++) {
if (state->frame->ref->pocs[j] < state->frame->poc) {
ref_list[0]++;
} else {
ref_list[1]++;
@ -965,7 +965,7 @@ int kvz_calc_mvd_cost_cabac(encoder_state_t * const state, int x, int y, int mv_
}
// ToDo: Bidir vector support
if (!(state->global->ref_list == REF_PIC_LIST_1 && /*cur_cu->inter.mv_dir == 3*/ 0)) {
if (!(state->frame->ref_list == REF_PIC_LIST_1 && /*cur_cu->inter.mv_dir == 3*/ 0)) {
const int32_t mvd_hor = mvd.x;
const int32_t mvd_ver = mvd.y;
const int8_t hor_abs_gr0 = mvd_hor != 0;
@ -1015,5 +1015,5 @@ int kvz_calc_mvd_cost_cabac(encoder_state_t * const state, int x, int y, int mv_
*bitcost = (23 - state_cabac_copy.bits_left) + (state_cabac_copy.num_buffered_bytes << 3);
// Store bitcost before restoring cabac
return *bitcost * (int32_t)(state->global->cur_lambda_cost_sqrt + 0.5);
return *bitcost * (int32_t)(state->frame->cur_lambda_cost_sqrt + 0.5);
}

View file

@ -30,9 +30,7 @@
#include "cu.h"
#include "encoderstate.h"
#include "global.h" // IWYU pragma: keep
#include "inter.h"
#include "search_inter.h"
#include "kvazaar.h"
extern const uint32_t kvz_g_go_rice_range[5];

View file

@ -25,8 +25,8 @@
#include <string.h>
#include "cabac.h"
#include "image.h"
#include "rdo.h"
#include "strategies/strategies-picture.h"
#include "strategies/strategies-sao.h"
@ -501,7 +501,7 @@ static void sao_search_edge_sao(const encoder_state_t * const state,
{
float mode_bits = sao_mode_bits_edge(state, edge_class, edge_offset, sao_top, sao_left, buf_cnt);
sum_ddistortion += (int)((double)mode_bits*state->global->cur_lambda_cost+0.5);
sum_ddistortion += (int)((double)mode_bits*state->frame->cur_lambda_cost+0.5);
}
// SAO is not applied for category 0.
edge_offset[SAO_EO_CAT0] = 0;
@ -545,7 +545,7 @@ static void sao_search_band_sao(const encoder_state_t * const state, const kvz_p
}
temp_rate = sao_mode_bits_band(state, sao_out->band_position, temp_offsets, sao_top, sao_left, buf_cnt);
ddistortion += (int)((double)temp_rate*state->global->cur_lambda_cost + 0.5);
ddistortion += (int)((double)temp_rate*state->frame->cur_lambda_cost + 0.5);
// Select band sao over edge sao when distortion is lower
if (ddistortion < sao_out->ddistortion) {
@ -589,7 +589,7 @@ static void sao_search_best_mode(const encoder_state_t * const state, const kvz_
{
float mode_bits = sao_mode_bits_edge(state, edge_sao.eo_class, edge_sao.offsets, sao_top, sao_left, buf_cnt);
int ddistortion = (int)(mode_bits * state->global->cur_lambda_cost + 0.5);
int ddistortion = (int)(mode_bits * state->frame->cur_lambda_cost + 0.5);
unsigned buf_i;
for (buf_i = 0; buf_i < buf_cnt; ++buf_i) {
@ -603,7 +603,7 @@ static void sao_search_best_mode(const encoder_state_t * const state, const kvz_
{
float mode_bits = sao_mode_bits_band(state, band_sao.band_position, band_sao.offsets, sao_top, sao_left, buf_cnt);
int ddistortion = (int)(mode_bits * state->global->cur_lambda_cost + 0.5);
int ddistortion = (int)(mode_bits * state->frame->cur_lambda_cost + 0.5);
unsigned buf_i;
for (buf_i = 0; buf_i < buf_cnt; ++buf_i) {
@ -626,7 +626,7 @@ static void sao_search_best_mode(const encoder_state_t * const state, const kvz_
// Choose between SAO and doing nothing, taking into account the
// rate-distortion cost of coding do nothing.
{
int cost_of_nothing = (int)(sao_mode_bits_none(state, sao_top, sao_left) * state->global->cur_lambda_cost + 0.5);
int cost_of_nothing = (int)(sao_mode_bits_none(state, sao_top, sao_left) * state->frame->cur_lambda_cost + 0.5);
if (sao_out->ddistortion >= cost_of_nothing) {
sao_out->type = SAO_TYPE_NONE;
merge_cost[0] = cost_of_nothing;
@ -643,7 +643,7 @@ static void sao_search_best_mode(const encoder_state_t * const state, const kvz_
if (merge_cand) {
unsigned buf_i;
float mode_bits = sao_mode_bits_merge(state, i + 1);
int ddistortion = (int)(mode_bits * state->global->cur_lambda_cost + 0.5);
int ddistortion = (int)(mode_bits * state->frame->cur_lambda_cost + 0.5);
switch (merge_cand->type) {
case SAO_TYPE_EDGE:

View file

@ -32,7 +32,6 @@
#include "rdo.h"
#include "search_inter.h"
#include "search_intra.h"
#include "strategies/strategies-picture.h"
#include "threadqueue.h"
#include "transform.h"
#include "videoframe.h"
@ -315,7 +314,7 @@ double kvz_cu_rd_cost_luma(const encoder_state_t *const state,
sum += kvz_cu_rd_cost_luma(state, x_px, y_px + offset, depth + 1, pred_cu, lcu);
sum += kvz_cu_rd_cost_luma(state, x_px + offset, y_px + offset, depth + 1, pred_cu, lcu);
return sum + tr_tree_bits * state->global->cur_lambda_cost;
return sum + tr_tree_bits * state->frame->cur_lambda_cost;
}
// Add transform_tree cbf_luma bit cost.
@ -347,7 +346,7 @@ double kvz_cu_rd_cost_luma(const encoder_state_t *const state,
}
double bits = tr_tree_bits + coeff_bits;
return (double)ssd * LUMA_MULT + bits * state->global->cur_lambda_cost;
return (double)ssd * LUMA_MULT + bits * state->frame->cur_lambda_cost;
}
@ -392,7 +391,7 @@ double kvz_cu_rd_cost_chroma(const encoder_state_t *const state,
sum += kvz_cu_rd_cost_chroma(state, x_px, y_px + offset, depth + 1, pred_cu, lcu);
sum += kvz_cu_rd_cost_chroma(state, x_px + offset, y_px + offset, depth + 1, pred_cu, lcu);
return sum + tr_tree_bits * state->global->cur_lambda_cost;
return sum + tr_tree_bits * state->frame->cur_lambda_cost;
}
// Chroma SSD
@ -422,7 +421,7 @@ double kvz_cu_rd_cost_chroma(const encoder_state_t *const state,
}
double bits = tr_tree_bits + coeff_bits;
return (double)ssd * CHROMA_MULT + bits * state->global->cur_lambda_cost;
return (double)ssd * CHROMA_MULT + bits * state->frame->cur_lambda_cost;
}
@ -508,7 +507,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
{
bool can_use_inter =
state->global->slicetype != KVZ_SLICE_I
state->frame->slicetype != KVZ_SLICE_I
&& WITHIN(depth, ctrl->pu_depth_inter.min, ctrl->pu_depth_inter.max);
if (can_use_inter) {
@ -620,8 +619,8 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
if (cur_pu->inter.mv_dir == 3) {
const kvz_picture *const refs[2] = {
state->global->ref->images[cur_pu->inter.mv_ref[0]],
state->global->ref->images[cur_pu->inter.mv_ref[1]],
state->frame->ref->images[cur_pu->inter.mv_ref[0]],
state->frame->ref->images[cur_pu->inter.mv_ref[1]],
};
kvz_inter_recon_lcu_bipred(state,
refs[0], refs[1],
@ -632,7 +631,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
} else {
const int mv_idx = cur_pu->inter.mv_dir - 1;
const kvz_picture *const ref =
state->global->ref->images[cur_pu->inter.mv_ref[mv_idx]];
state->frame->ref->images[cur_pu->inter.mv_ref[mv_idx]];
kvz_inter_recon_lcu(state,
ref,
pu_x, pu_y,
@ -671,11 +670,11 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
mode_bits = inter_bitcost;
}
cost += mode_bits * state->global->cur_lambda_cost;
cost += mode_bits * state->frame->cur_lambda_cost;
}
// Recursively split all the way to max search depth.
if (depth < ctrl->pu_depth_intra.max || (depth < ctrl->pu_depth_inter.max && state->global->slicetype != KVZ_SLICE_I)) {
if (depth < ctrl->pu_depth_intra.max || (depth < ctrl->pu_depth_inter.max && state->frame->slicetype != KVZ_SLICE_I)) {
int half_cu = cu_width / 2;
double split_cost = 0.0;
int cbf = cbf_is_set_any(cur_cu->cbf, depth);
@ -684,15 +683,15 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
// Add cost of cu_split_flag.
uint8_t split_model = get_ctx_cu_split_model(lcu, x, y, depth);
const cabac_ctx_t *ctx = &(state->cabac.ctx.split_flag_model[split_model]);
cost += CTX_ENTROPY_FBITS(ctx, 0) * state->global->cur_lambda_cost;
split_cost += CTX_ENTROPY_FBITS(ctx, 1) * state->global->cur_lambda_cost;
cost += CTX_ENTROPY_FBITS(ctx, 0) * state->frame->cur_lambda_cost;
split_cost += CTX_ENTROPY_FBITS(ctx, 1) * state->frame->cur_lambda_cost;
}
if (cur_cu->type == CU_INTRA && depth == MAX_DEPTH) {
// Add cost of intra part_size.
const cabac_ctx_t *ctx = &(state->cabac.ctx.part_size_model[0]);
cost += CTX_ENTROPY_FBITS(ctx, 1) * state->global->cur_lambda_cost; // 2Nx2N
split_cost += CTX_ENTROPY_FBITS(ctx, 0) * state->global->cur_lambda_cost; // NxN
cost += CTX_ENTROPY_FBITS(ctx, 1) * state->frame->cur_lambda_cost; // 2Nx2N
split_cost += CTX_ENTROPY_FBITS(ctx, 0) * state->frame->cur_lambda_cost; // NxN
}
// If skip mode was selected for the block, skip further search.
@ -736,11 +735,11 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
// Add the cost of coding no-split.
uint8_t split_model = get_ctx_cu_split_model(lcu, x, y, depth);
const cabac_ctx_t *ctx = &(state->cabac.ctx.split_flag_model[split_model]);
cost += CTX_ENTROPY_FBITS(ctx, 0) * state->global->cur_lambda_cost;
cost += CTX_ENTROPY_FBITS(ctx, 0) * state->frame->cur_lambda_cost;
// Add the cost of coding intra mode only once.
double mode_bits = calc_mode_bits(state, &work_tree[depth], cur_cu, x, y);
cost += mode_bits * state->global->cur_lambda_cost;
cost += mode_bits * state->frame->cur_lambda_cost;
}
}
@ -762,7 +761,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
work_tree_copy_down(x, y, depth, work_tree);
}
PERFORMANCE_MEASURE_END(KVZ_PERF_SEARCHCU, state->encoder_control->threadqueue, "type=search_cu,frame=%d,tile=%d,slice=%d,px_x=%d-%d,px_y=%d-%d,depth=%d,split=%d,cur_cu_is_intra=%d", state->global->frame, state->tile->id, state->slice->id,
PERFORMANCE_MEASURE_END(KVZ_PERF_SEARCHCU, state->encoder_control->threadqueue, "type=search_cu,frame=%d,tile=%d,slice=%d,px_x=%d-%d,px_y=%d-%d,depth=%d,split=%d,cur_cu_is_intra=%d", state->frame->num, state->tile->id, state->slice->id,
(state->tile->lcu_offset_x * LCU_WIDTH) + x,
(state->tile->lcu_offset_x * LCU_WIDTH) + x + (LCU_WIDTH >> depth),
(state->tile->lcu_offset_y * LCU_WIDTH) + y,

View file

@ -22,7 +22,6 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "cabac.h"
#include "encoder.h"
@ -252,7 +251,7 @@ static int calc_mvd_cost(encoder_state_t * const state, int x, int y, int mv_shi
temp_bitcost += cur_mv_cand ? cand2_cost : cand1_cost;
}
*bitcost = temp_bitcost;
return temp_bitcost*(int32_t)(state->global->cur_lambda_cost_sqrt+0.5);
return temp_bitcost*(int32_t)(state->frame->cur_lambda_cost_sqrt+0.5);
}
@ -1231,14 +1230,14 @@ static void search_pu_inter_ref(encoder_state_t * const state,
const int x_cu = x >> 3;
const int y_cu = y >> 3;
const videoframe_t * const frame = state->tile->frame;
kvz_picture *ref_image = state->global->ref->images[ref_idx];
kvz_picture *ref_image = state->frame->ref->images[ref_idx];
uint32_t temp_bitcost = 0;
uint32_t temp_cost = 0;
vector2d_t orig;
int32_t merged = 0;
uint8_t cu_mv_cand = 0;
int8_t merge_idx = 0;
int8_t ref_list = state->global->refmap[ref_idx].list-1;
int8_t ref_list = state->frame->refmap[ref_idx].list-1;
int8_t temp_ref_idx = cur_cu->inter.mv_ref[ref_list];
orig.x = x_cu * CU_MIN_SIZE_PIXELS;
orig.y = y_cu * CU_MIN_SIZE_PIXELS;
@ -1259,7 +1258,7 @@ static void search_pu_inter_ref(encoder_state_t * const state,
};
const int mid_x = tile_top_left_corner.x + x + (width >> 1);
const int mid_y = tile_top_left_corner.y + y + (height >> 1);
const cu_array_t* ref_array = state->global->ref->cu_arrays[ref_idx];
const cu_array_t* ref_array = state->frame->ref->cu_arrays[ref_idx];
const cu_info_t* ref_cu = kvz_cu_array_at_const(ref_array, mid_x, mid_y);
if (ref_cu->type == CU_INTER) {
if (ref_cu->inter.mv_dir & 1) {
@ -1379,7 +1378,7 @@ static void search_pu_inter_ref(encoder_state_t * const state,
if (temp_cost < *inter_cost) {
// Map reference index to L0/L1 pictures
cur_cu->inter.mv_dir = ref_list+1;
uint8_t mv_ref_coded = state->global->refmap[ref_idx].idx;
uint8_t mv_ref_coded = state->frame->refmap[ref_idx].idx;
cur_cu->merged = merged;
cur_cu->merge_idx = merge_idx;
@ -1459,7 +1458,7 @@ static void search_pu_inter(encoder_state_t * const state,
CU_SET_MV_CAND(cur_cu, 1, 0);
uint32_t ref_idx;
for (ref_idx = 0; ref_idx < state->global->ref->used_size; ref_idx++) {
for (ref_idx = 0; ref_idx < state->frame->ref->used_size; ref_idx++) {
search_pu_inter_ref(state,
x, y,
width, height,
@ -1473,7 +1472,7 @@ static void search_pu_inter(encoder_state_t * const state,
}
// Search bi-pred positions
bool can_use_bipred = state->global->slicetype == KVZ_SLICE_B
bool can_use_bipred = state->frame->slicetype == KVZ_SLICE_B
&& state->encoder_control->cfg->bipred
&& width + height >= 16; // 4x8 and 8x4 PBs are restricted to unipred
@ -1508,7 +1507,7 @@ static void search_pu_inter(encoder_state_t * const state,
kvz_pixel tmp_block[64 * 64];
kvz_pixel tmp_pic[64 * 64];
// Force L0 and L1 references
if (state->global->refmap[merge_cand[i].ref[0]].list == 2 || state->global->refmap[merge_cand[j].ref[1]].list == 1) continue;
if (state->frame->refmap[merge_cand[i].ref[0]].list == 2 || state->frame->refmap[merge_cand[j].ref[1]].list == 1) continue;
mv[0][0] = merge_cand[i].mv[0][0];
mv[0][1] = merge_cand[i].mv[0][1];
@ -1526,8 +1525,8 @@ static void search_pu_inter(encoder_state_t * const state,
}
kvz_inter_recon_lcu_bipred(state,
state->global->ref->images[merge_cand[i].ref[0]],
state->global->ref->images[merge_cand[j].ref[1]],
state->frame->ref->images[merge_cand[i].ref[0]],
state->frame->ref->images[merge_cand[j].ref[1]],
x, y,
width,
height,
@ -1552,8 +1551,8 @@ static void search_pu_inter(encoder_state_t * const state,
cur_cu->inter.mv_dir = 3;
uint8_t mv_ref_coded[2] = {
state->global->refmap[merge_cand[i].ref[0]].idx,
state->global->refmap[merge_cand[j].ref[1]].idx
state->frame->refmap[merge_cand[i].ref[0]].idx,
state->frame->refmap[merge_cand[j].ref[1]].idx
};
cur_cu->inter.mv_ref[0] = merge_cand[i].ref[0];

View file

@ -30,6 +30,7 @@
#include "encoderstate.h"
#include "global.h" // IWYU pragma: keep
#include "inter.h"
#include "kvazaar.h"
#define FILTER_SIZE 8
#define HALF_FILTER (FILTER_SIZE>>1)

View file

@ -114,7 +114,7 @@ static double get_cost(encoder_state_t * const state,
ctx = &state->cabac.ctx.transform_skip_model_chroma;
trskip_bits += 2.0 * (CTX_ENTROPY_FBITS(ctx, 1) - CTX_ENTROPY_FBITS(ctx, 0));
double sad_cost = TRSKIP_RATIO * sad_func(pred, orig_block) + state->global->cur_lambda_cost_sqrt * trskip_bits;
double sad_cost = TRSKIP_RATIO * sad_func(pred, orig_block) + state->frame->cur_lambda_cost_sqrt * trskip_bits;
if (sad_cost < satd_cost) {
return sad_cost;
}
@ -158,7 +158,7 @@ static void get_cost_dual(encoder_state_t * const state,
double sad_costs[PARALLEL_BLKS] = { 0 };
sad_twin_func(preds, orig_block, PARALLEL_BLKS, unsigned_sad_costs);
for (int i = 0; i < PARALLEL_BLKS; ++i) {
sad_costs[i] = TRSKIP_RATIO * (double)unsigned_sad_costs[i] + state->global->cur_lambda_cost_sqrt * trskip_bits;
sad_costs[i] = TRSKIP_RATIO * (double)unsigned_sad_costs[i] + state->frame->cur_lambda_cost_sqrt * trskip_bits;
if (sad_costs[i] < (double)satd_costs[i]) {
costs_out[i] = sad_costs[i];
}
@ -248,7 +248,7 @@ static double search_intra_trdepth(encoder_state_t * const state,
// max_depth.
// - Min transform size hasn't been reached (MAX_PU_DEPTH).
if (depth < max_depth && depth < MAX_PU_DEPTH) {
split_cost = 3 * state->global->cur_lambda_cost;
split_cost = 3 * state->frame->cur_lambda_cost;
split_cost += search_intra_trdepth(state, x_px, y_px, depth + 1, max_depth, intra_mode, nosplit_cost, pred_cu, lcu);
if (split_cost < nosplit_cost) {
@ -290,7 +290,7 @@ static double search_intra_trdepth(encoder_state_t * const state,
}
double bits = tr_split_bit + cbf_bits;
split_cost += bits * state->global->cur_lambda_cost;
split_cost += bits * state->frame->cur_lambda_cost;
} else {
assert(width <= TR_MAX_WIDTH);
}
@ -516,7 +516,7 @@ static int8_t search_intra_rough(encoder_state_t * const state,
// Add prediction mode coding cost as the last thing. We don't want this
// affecting the halving search.
int lambda_cost = (int)(state->global->cur_lambda_cost_sqrt + 0.5);
int lambda_cost = (int)(state->frame->cur_lambda_cost_sqrt + 0.5);
for (int mode_i = 0; mode_i < modes_selected; ++mode_i) {
costs[mode_i] += lambda_cost * kvz_luma_mode_bits(state, modes[mode_i], intra_preds);
}
@ -587,7 +587,7 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
for(int rdo_mode = 0; rdo_mode < modes_to_check; rdo_mode ++) {
int rdo_bitcost = kvz_luma_mode_bits(state, modes[rdo_mode], intra_preds);
costs[rdo_mode] = rdo_bitcost * (int)(state->global->cur_lambda_cost + 0.5);
costs[rdo_mode] = rdo_bitcost * (int)(state->frame->cur_lambda_cost + 0.5);
// Perform transform split search and save mode RD cost for the best one.
cu_info_t pred_cu;
@ -688,7 +688,7 @@ int8_t kvz_search_intra_chroma_rdo(encoder_state_t * const state,
chroma.cost = kvz_cu_rd_cost_chroma(state, lcu_px.x, lcu_px.y, depth, tr_cu, lcu);
double mode_bits = kvz_chroma_mode_bits(state, chroma.mode, intra_mode);
chroma.cost += mode_bits * state->global->cur_lambda_cost;
chroma.cost += mode_bits * state->frame->cur_lambda_cost;
if (chroma.cost < best_chroma.cost) {
best_chroma = chroma;

View file

@ -53,13 +53,13 @@ void kvz_quant_flat_avx2(const encoder_state_t * const state, coeff_t *coef, coe
const uint32_t log2_block_size = kvz_g_convert_to_bit[width] + 2;
const uint32_t * const scan = kvz_g_sig_last_scan[scan_idx][log2_block_size - 1];
int32_t qp_scaled = kvz_get_scaled_qp(type, state->global->QP, (encoder->bitdepth - 8) * 6);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->frame->QP, (encoder->bitdepth - 8) * 6);
const uint32_t log2_tr_size = kvz_g_convert_to_bit[width] + 2;
const int32_t scalinglist_type = (block_type == CU_INTRA ? 0 : 3) + (int8_t)("\0\3\1\2"[type]);
const int32_t *quant_coeff = encoder->scaling_list.quant_coeff[log2_tr_size - 2][scalinglist_type][qp_scaled % 6];
const int32_t transform_shift = MAX_TR_DYNAMIC_RANGE - encoder->bitdepth - log2_tr_size; //!< Represents scaling through forward transform
const int32_t q_bits = QUANT_SHIFT + qp_scaled / 6 + transform_shift;
const int32_t add = ((state->global->slicetype == KVZ_SLICE_I) ? 171 : 85) << (q_bits - 9);
const int32_t add = ((state->frame->slicetype == KVZ_SLICE_I) ? 171 : 85) << (q_bits - 9);
const int32_t q_bits8 = q_bits - 8;
assert(quant_coeff[0] <= (1 << 15) - 1 && quant_coeff[0] >= -(1 << 15)); //Assuming flat values to fit int16_t
@ -458,7 +458,7 @@ void kvz_dequant_avx2(const encoder_state_t * const state, coeff_t *q_coef, coef
int32_t n;
int32_t transform_shift = 15 - encoder->bitdepth - (kvz_g_convert_to_bit[ width ] + 2);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->global->QP, (encoder->bitdepth-8)*6);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->frame->QP, (encoder->bitdepth-8)*6);
shift = 20 - QUANT_SHIFT - transform_shift;

View file

@ -21,7 +21,6 @@
#include "strategies/generic/picture-generic.h"
#include <stdlib.h>
#include <string.h>
#include "strategies/strategies-picture.h"
#include "strategyselector.h"

View file

@ -41,13 +41,13 @@ void kvz_quant_generic(const encoder_state_t * const state, coeff_t *coef, coeff
const uint32_t log2_block_size = kvz_g_convert_to_bit[width] + 2;
const uint32_t * const scan = kvz_g_sig_last_scan[scan_idx][log2_block_size - 1];
int32_t qp_scaled = kvz_get_scaled_qp(type, state->global->QP, (encoder->bitdepth - 8) * 6);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->frame->QP, (encoder->bitdepth - 8) * 6);
const uint32_t log2_tr_size = kvz_g_convert_to_bit[width] + 2;
const int32_t scalinglist_type = (block_type == CU_INTRA ? 0 : 3) + (int8_t)("\0\3\1\2"[type]);
const int32_t *quant_coeff = encoder->scaling_list.quant_coeff[log2_tr_size - 2][scalinglist_type][qp_scaled % 6];
const int32_t transform_shift = MAX_TR_DYNAMIC_RANGE - encoder->bitdepth - log2_tr_size; //!< Represents scaling through forward transform
const int32_t q_bits = QUANT_SHIFT + qp_scaled / 6 + transform_shift;
const int32_t add = ((state->global->slicetype == KVZ_SLICE_I) ? 171 : 85) << (q_bits - 9);
const int32_t add = ((state->frame->slicetype == KVZ_SLICE_I) ? 171 : 85) << (q_bits - 9);
const int32_t q_bits8 = q_bits - 8;
uint32_t ac_sum = 0;
@ -286,7 +286,7 @@ void kvz_dequant_generic(const encoder_state_t * const state, coeff_t *q_coef, c
int32_t n;
int32_t transform_shift = 15 - encoder->bitdepth - (kvz_g_convert_to_bit[ width ] + 2);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->global->QP, (encoder->bitdepth-8)*6);
int32_t qp_scaled = kvz_get_scaled_qp(type, state->frame->QP, (encoder->bitdepth-8)*6);
shift = 20 - QUANT_SHIFT - transform_shift;

View file

@ -24,7 +24,6 @@
#include "kvazaar.h"
#include "rdo.h"
#include "strategies/strategies-dct.h"
#include "strategies/strategies-picture.h"
#include "strategies/strategies-quant.h"
#include "tables.h"
@ -200,7 +199,7 @@ int kvz_quantize_residual_trskip(
int has_coeffs;
} skip, noskip, *best;
const int bit_cost = (int)(state->global->cur_lambda_cost+0.5);
const int bit_cost = (int)(state->frame->cur_lambda_cost+0.5);
noskip.has_coeffs = kvz_quantize_residual(
state, cur_cu, width, color, scan_order,