mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 02:24:07 +00:00
Merge branch 'refactor_encoder_state'
This commit is contained in:
commit
5890dd5350
|
@ -14,7 +14,8 @@
|
|||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>WIN32;WIN64;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;$(SolutionDir)..\src\extras;$(SolutionDir)..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4244;4204;4206</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4244;4204;4206;4028</DisableSpecificWarnings>
|
||||
<OpenMPSupport>true</OpenMPSupport>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
|
77
src/config.c
77
src/config.c
|
@ -86,6 +86,12 @@ int config_init(config *cfg)
|
|||
cfg->tiles_width_split = NULL;
|
||||
cfg->tiles_height_split = NULL;
|
||||
|
||||
cfg->wpp = 0;
|
||||
cfg->slice_count = 1;
|
||||
cfg->slice_addresses_in_ts = MALLOC(int32_t, 1);
|
||||
cfg->slice_addresses_in_ts[0] = 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -101,6 +107,7 @@ int config_destroy(config *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;
|
||||
|
@ -155,7 +162,7 @@ static int parse_enum(const char *arg, const char * const *names, int8_t *dst)
|
|||
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[256];
|
||||
int32_t values[MAX_TILES_PER_DIM];
|
||||
|
||||
int i;
|
||||
|
||||
|
@ -189,6 +196,7 @@ static int parse_tiles_specification(const char* const arg, int32_t * const ntil
|
|||
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) {
|
||||
|
@ -210,6 +218,67 @@ static int parse_tiles_specification(const char* const arg, int32_t * const ntil
|
|||
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;
|
||||
}
|
||||
|
||||
static int config_parse(config *cfg, const char *name, const char *value)
|
||||
{
|
||||
static const char * const overscan_names[] = { "undef", "show", "crop", NULL };
|
||||
|
@ -340,6 +409,10 @@ static int config_parse(config *cfg, const char *name, const char *value)
|
|||
error = !parse_tiles_specification(value, &cfg->tiles_width_count, &cfg->tiles_width_split);
|
||||
else if OPT("tiles-height-split")
|
||||
error = !parse_tiles_specification(value, &cfg->tiles_height_count, &cfg->tiles_height_split);
|
||||
else if OPT("wpp")
|
||||
cfg->wpp = atobool(value);
|
||||
else if OPT("slice-addresses")
|
||||
error = !parse_slice_specification(value, &cfg->slice_count, &cfg->slice_addresses_in_ts);
|
||||
else
|
||||
return 0;
|
||||
#undef OPT
|
||||
|
@ -388,6 +461,8 @@ int config_read(config *cfg,int argc, char *argv[])
|
|||
{ "seek", required_argument, NULL, 0 },
|
||||
{ "tiles-width-split", required_argument, NULL, 0 },
|
||||
{ "tiles-height-split", required_argument, NULL, 0 },
|
||||
{ "wpp", no_argument, NULL, 0 },
|
||||
{ "slice-addresses", required_argument, NULL, 0 },
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@ typedef struct
|
|||
int32_t tiles_height_count; /*!< \brief number of tiles separation in y direction */
|
||||
int32_t* tiles_width_split; /*!< \brief tiles split x coordinates (dimension: tiles_width_count) */
|
||||
int32_t* tiles_height_split; /*!< \brief tiles split y coordinates (dimension: tiles_height_count) */
|
||||
|
||||
int wpp;
|
||||
|
||||
int32_t slice_count;
|
||||
int32_t* slice_addresses_in_ts;
|
||||
} config;
|
||||
|
||||
/* Function definitions */
|
||||
|
|
|
@ -151,6 +151,16 @@ int main(int argc, char *argv[])
|
|||
" Can also be u followed by and a single int n,\n"
|
||||
" in which case it produces rows of uniform height.\n"
|
||||
"\n"
|
||||
" Wpp:\n"
|
||||
" --wpp: Enable wavefront parallel processing\n"
|
||||
"\n"
|
||||
" Slices:\n"
|
||||
" --slice-addresses <string>|u<int>: \n"
|
||||
" Specifies a comma separated list of LCU\n"
|
||||
" positions in tile scan order of tile separations.\n"
|
||||
" Can also be u followed by and a single int n,\n"
|
||||
" in which case it produces uniform slice length.\n"
|
||||
"\n"
|
||||
" Deprecated parameters: (might be removed at some point)\n"
|
||||
" Use --input-res:\n"
|
||||
" -w, --width : Width of input in pixels\n"
|
||||
|
@ -256,12 +266,13 @@ int main(int argc, char *argv[])
|
|||
encoder.in.width, encoder.in.height,
|
||||
encoder.in.real_width, encoder.in.real_height);
|
||||
|
||||
if (!encoder_state_init(&encoder_state, &encoder)) {
|
||||
encoder_state.encoder_control = &encoder;
|
||||
if (!encoder_state_init(&encoder_state, NULL)) {
|
||||
goto exit_failure;
|
||||
}
|
||||
|
||||
encoder_state.frame = 0;
|
||||
encoder_state.QP = (int8_t)encoder.cfg->qp;
|
||||
encoder_state.global->frame = 0;
|
||||
encoder_state.global->QP = (int8_t)encoder.cfg->qp;
|
||||
|
||||
// Only the code that handles conformance window coding needs to know
|
||||
// the real dimensions. As a quick fix for broken non-multiple of 8 videos,
|
||||
|
@ -272,14 +283,14 @@ int main(int argc, char *argv[])
|
|||
//cfg->height = encoder.in.height;
|
||||
|
||||
// Start coding cycle while data on input and not on the last frame
|
||||
while(!cfg->frames || encoder_state.frame < cfg->frames) {
|
||||
while(!cfg->frames || encoder_state.global->frame < cfg->frames) {
|
||||
int32_t diff;
|
||||
double temp_psnr[3];
|
||||
|
||||
// Skip '--seek' frames before input.
|
||||
// This block can be moved outside this while loop when there is a
|
||||
// mechanism to skip the while loop on error.
|
||||
if (encoder_state.frame == 0 && cfg->seek > 0) {
|
||||
if (encoder_state.global->frame == 0 && cfg->seek > 0) {
|
||||
int frame_bytes = cfg->width * cfg->height * 3 / 2;
|
||||
int error = 0;
|
||||
|
||||
|
@ -302,14 +313,14 @@ int main(int argc, char *argv[])
|
|||
// Read one frame from the input
|
||||
if (!read_one_frame(input, &encoder_state)) {
|
||||
if (!feof(input))
|
||||
fprintf(stderr, "Failed to read a frame %d\n", encoder_state.frame);
|
||||
fprintf(stderr, "Failed to read a frame %d\n", encoder_state.global->frame);
|
||||
break;
|
||||
}
|
||||
|
||||
// The actual coding happens here, after this function we have a coded frame
|
||||
encode_one_frame(&encoder_state);
|
||||
|
||||
cur_pic = encoder_state.cur_pic;
|
||||
cur_pic = encoder_state.tile->cur_pic;
|
||||
|
||||
if (cfg->debug != NULL) {
|
||||
// Write reconstructed frame out.
|
||||
|
@ -343,8 +354,8 @@ int main(int argc, char *argv[])
|
|||
temp_psnr[1] = image_psnr(cur_pic->u_data, cur_pic->u_recdata, cfg->width>>1, cfg->height>>1);
|
||||
temp_psnr[2] = image_psnr(cur_pic->v_data, cur_pic->v_recdata, cfg->width>>1, cfg->height>>1);
|
||||
|
||||
fprintf(stderr, "POC %4d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f\n", encoder_state.frame,
|
||||
"BPI"[cur_pic->slicetype%3], diff<<3,
|
||||
fprintf(stderr, "POC %4d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f\n", encoder_state.global->frame,
|
||||
"BPI"[encoder_state.global->slicetype%3], diff<<3,
|
||||
temp_psnr[0], temp_psnr[1], temp_psnr[2]);
|
||||
|
||||
// Increment total PSNR
|
||||
|
@ -361,8 +372,8 @@ int main(int argc, char *argv[])
|
|||
fgetpos(output,(fpos_t*)&curpos);
|
||||
|
||||
// Print statistics of the coding
|
||||
fprintf(stderr, " Processed %d frames, %10llu bits AVG PSNR: %2.4f %2.4f %2.4f\n", encoder_state.frame, (long long unsigned int) curpos<<3,
|
||||
psnr[0] / encoder_state.frame, psnr[1] / encoder_state.frame, psnr[2] / encoder_state.frame);
|
||||
fprintf(stderr, " Processed %d frames, %10llu bits AVG PSNR: %2.4f %2.4f %2.4f\n", encoder_state.global->frame, (long long unsigned int) curpos<<3,
|
||||
psnr[0] / encoder_state.global->frame, psnr[1] / encoder_state.global->frame, psnr[2] / encoder_state.global->frame);
|
||||
fprintf(stderr, " Total time: %.3f s.\n", ((float)(clock() - start_time)) / CLOCKS_PER_SEC);
|
||||
|
||||
fclose(input);
|
||||
|
|
1285
src/encoder.c
1285
src/encoder.c
File diff suppressed because it is too large
Load diff
|
@ -120,32 +120,91 @@ typedef struct
|
|||
|
||||
const int32_t *tiles_tile_id; /*!<spec: TileId (6.5.1); dimension: PicSizeInCtbsY */
|
||||
|
||||
//WPP
|
||||
int wpp;
|
||||
|
||||
//Slices
|
||||
int slice_count;
|
||||
const int* slice_addresses_in_ts;
|
||||
|
||||
} encoder_control;
|
||||
|
||||
typedef struct encoder_state {
|
||||
const encoder_control *encoder_control;
|
||||
typedef enum {
|
||||
ENCODER_STATE_TYPE_INVALID = 'i',
|
||||
ENCODER_STATE_TYPE_MAIN = 'M',
|
||||
ENCODER_STATE_TYPE_SLICE = 'S',
|
||||
ENCODER_STATE_TYPE_TILE = 'T',
|
||||
ENCODER_STATE_TYPE_WAVEFRONT_ROW = 'W',
|
||||
} encoder_state_type;
|
||||
|
||||
int32_t lcu_offset_x;
|
||||
int32_t lcu_offset_y;
|
||||
|
||||
picture *cur_pic;
|
||||
|
||||
typedef struct {
|
||||
double cur_lambda_cost;
|
||||
|
||||
int32_t frame;
|
||||
int32_t poc; /*!< \brief picture order count */
|
||||
|
||||
bitstream stream;
|
||||
int8_t QP; //!< \brief Quantization parameter
|
||||
|
||||
//Current picture available references
|
||||
picture_list *ref;
|
||||
int8_t ref_list;
|
||||
int8_t ref_idx_num[2];
|
||||
int8_t QP; // \brief Quantization parameter
|
||||
//int8_t ref_idx_num[2];
|
||||
|
||||
double cur_lambda_cost;
|
||||
int is_radl_frame;
|
||||
uint8_t pictype;
|
||||
uint8_t slicetype;
|
||||
|
||||
cabac_data cabac;
|
||||
} encoder_state_config_global;
|
||||
|
||||
typedef struct {
|
||||
//Current picture to encode
|
||||
picture *cur_pic;
|
||||
|
||||
int32_t id;
|
||||
|
||||
//Tile: offset in LCU for current encoder_state in global coordinates
|
||||
int32_t lcu_offset_x;
|
||||
int32_t lcu_offset_y;
|
||||
|
||||
//Position of the first element in tile scan in global coordinates
|
||||
int32_t lcu_offset_in_ts;
|
||||
} encoder_state_config_tile;
|
||||
|
||||
typedef struct {
|
||||
int32_t id;
|
||||
|
||||
//Global coordinates
|
||||
int32_t start_in_ts;
|
||||
int32_t end_in_ts;
|
||||
|
||||
//Global coordinates
|
||||
int32_t start_in_rs;
|
||||
int32_t end_in_rs;
|
||||
} encoder_state_config_slice;
|
||||
|
||||
typedef struct {
|
||||
//Row in image coordinates of the wavefront
|
||||
int32_t lcu_offset_y;
|
||||
} encoder_state_config_wfrow;
|
||||
|
||||
typedef struct encoder_state {
|
||||
const encoder_control *encoder_control;
|
||||
encoder_state_type type;
|
||||
|
||||
//List of children, the last item of this list is a pseudo-encoder with encoder_control = NULL
|
||||
//Use do { } while (encoder_state->children[++i].encoder_control)
|
||||
//Use for (i = 0; encoder_state->children[i].encoder_control; ++i) {
|
||||
struct encoder_state *children;
|
||||
struct encoder_state *parent;
|
||||
|
||||
encoder_state_config_global *global;
|
||||
encoder_state_config_tile *tile;
|
||||
encoder_state_config_slice *slice;
|
||||
encoder_state_config_wfrow *wfrow;
|
||||
|
||||
bitstream stream;
|
||||
cabac_data cabac;
|
||||
} encoder_state;
|
||||
|
||||
int encoder_control_init(encoder_control *encoder, const config *cfg);
|
||||
|
@ -153,8 +212,8 @@ int encoder_control_finalize(encoder_control *encoder);
|
|||
|
||||
void encoder_control_input_init(encoder_control *encoder, int32_t width, int32_t height);
|
||||
|
||||
int encoder_state_init(encoder_state *encoder_state, const encoder_control * encoder);
|
||||
int encoder_state_finalize(encoder_state *encoder_state);
|
||||
int encoder_state_init(encoder_state * child_state, encoder_state * parent_state);
|
||||
void encoder_state_finalize(encoder_state *encoder_state);
|
||||
void encoder_state_init_lambda(encoder_state *encoder_state);
|
||||
|
||||
void encode_one_frame(encoder_state *encoder_state);
|
||||
|
|
12
src/filter.c
12
src/filter.c
|
@ -167,7 +167,7 @@ void filter_deblock_edge_luma(encoder_state * const encoder_state,
|
|||
int32_t xpos, int32_t ypos,
|
||||
int8_t depth, int8_t dir)
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
const encoder_control * const encoder = encoder_state->encoder_control;
|
||||
|
||||
cu_info *cu_q = &cur_pic->cu_array[(xpos>>MIN_SIZE) + (ypos>>MIN_SIZE) * (cur_pic->width_in_lcu << MAX_DEPTH)];
|
||||
|
@ -194,7 +194,7 @@ void filter_deblock_edge_luma(encoder_state * const encoder_state,
|
|||
int16_t x_cu = xpos>>MIN_SIZE,y_cu = ypos>>MIN_SIZE;
|
||||
int8_t strength = 0;
|
||||
|
||||
int32_t qp = encoder_state->QP;
|
||||
int32_t qp = encoder_state->global->QP;
|
||||
int32_t bitdepth_scale = 1 << (encoder->bitdepth - 8);
|
||||
int32_t b_index = CLIP(0, 51, qp + (beta_offset_div2 << 1));
|
||||
int32_t beta = g_beta_table_8x8[b_index] * bitdepth_scale;
|
||||
|
@ -295,7 +295,7 @@ void filter_deblock_edge_chroma(encoder_state * const encoder_state,
|
|||
int8_t depth, int8_t dir)
|
||||
{
|
||||
const encoder_control * const encoder = encoder_state->encoder_control;
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
cu_info *cu_q = &cur_pic->cu_array[(x>>(MIN_SIZE-1)) + (y>>(MIN_SIZE-1)) * (cur_pic->width_in_lcu << MAX_DEPTH)];
|
||||
|
||||
// Chroma edges that do not lay on a 8x8 grid are not deblocked.
|
||||
|
@ -327,7 +327,7 @@ void filter_deblock_edge_chroma(encoder_state * const encoder_state,
|
|||
int16_t x_cu = x>>(MIN_SIZE-1),y_cu = y>>(MIN_SIZE-1);
|
||||
int8_t strength = 2;
|
||||
|
||||
int32_t QP = g_chroma_scale[encoder_state->QP];
|
||||
int32_t QP = g_chroma_scale[encoder_state->global->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 = g_tc_table_8x8[TC_index]*bitdepth_scale;
|
||||
|
@ -389,7 +389,7 @@ void filter_deblock_edge_chroma(encoder_state * const encoder_state,
|
|||
*/
|
||||
void filter_deblock_cu(encoder_state * const encoder_state, int32_t x, int32_t y, int8_t depth, int32_t edge)
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
cu_info *cur_cu = &cur_pic->cu_array[x + y*(cur_pic->width_in_lcu << MAX_DEPTH)];
|
||||
uint8_t split_flag = (cur_cu->depth > depth) ? 1 : 0;
|
||||
uint8_t border_x = (cur_pic->width < x*(LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth)) ? 1 : 0;
|
||||
|
@ -437,7 +437,7 @@ void filter_deblock_cu(encoder_state * const encoder_state, int32_t x, int32_t y
|
|||
*/
|
||||
void filter_deblock(encoder_state * const encoder_state)
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
int16_t x, y;
|
||||
|
||||
// TODO: Optimization: add thread for each LCU
|
||||
|
|
|
@ -128,6 +128,7 @@ typedef int16_t coefficient;
|
|||
#define SIZE_NONE 15
|
||||
|
||||
#define MAX_TILES_PER_DIM 16
|
||||
#define MAX_SLICES 16
|
||||
|
||||
/* Inlining functions */
|
||||
#ifdef _MSC_VER /* Visual studio */
|
||||
|
|
34
src/inter.c
34
src/inter.c
|
@ -83,12 +83,12 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
int32_t ref_width_c = ref->width>>1; //!< Reference picture width in chroma pixels
|
||||
|
||||
// negative overflow flag
|
||||
int8_t overflow_neg_x = (encoder_state->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) < 0)?1:0;
|
||||
int8_t overflow_neg_y = (encoder_state->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) < 0)?1:0;
|
||||
int8_t overflow_neg_x = (encoder_state->tile->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) < 0)?1:0;
|
||||
int8_t overflow_neg_y = (encoder_state->tile->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) < 0)?1:0;
|
||||
|
||||
// positive overflow flag
|
||||
int8_t overflow_pos_x = (encoder_state->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) + width > ref->width )?1:0;
|
||||
int8_t overflow_pos_y = (encoder_state->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) + width > ref->height)?1:0;
|
||||
int8_t overflow_pos_x = (encoder_state->tile->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) + width > ref->width )?1:0;
|
||||
int8_t overflow_pos_y = (encoder_state->tile->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) + width > ref->height)?1:0;
|
||||
|
||||
// Chroma half-pel
|
||||
#define HALFPEL_CHROMA_WIDTH ((LCU_WIDTH>>1) + 8)
|
||||
|
@ -114,7 +114,7 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
// Fill source blocks with data from reference, -4...width+4
|
||||
for (halfpel_y = 0, y = (ypos>>1) - 4; y < ((ypos + width)>>1) + 4; halfpel_y++, y++) {
|
||||
// calculate y-pixel offset
|
||||
coord_y = (y + encoder_state->lcu_offset_y * (LCU_WIDTH>>1)) + (mv[1]>>1);
|
||||
coord_y = (y + encoder_state->tile->lcu_offset_y * (LCU_WIDTH>>1)) + (mv[1]>>1);
|
||||
|
||||
// On y-overflow set coord_y accordingly
|
||||
overflow_neg_y_temp = (coord_y < 0) ? 1 : 0;
|
||||
|
@ -124,7 +124,7 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
coord_y *= ref_width_c;
|
||||
|
||||
for (halfpel_x = 0, x = (xpos>>1) - 4; x < ((xpos + width)>>1) + 4; halfpel_x++, x++) {
|
||||
coord_x = (x + encoder_state->lcu_offset_x * (LCU_WIDTH>>1)) + (mv[0]>>1);
|
||||
coord_x = (x + encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1)) + (mv[0]>>1);
|
||||
|
||||
// On x-overflow set coord_x accordingly
|
||||
overflow_neg_x_temp = (coord_x < 0) ? 1 : 0;
|
||||
|
@ -161,8 +161,8 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
int x_in_lcu = (x & ((LCU_WIDTH)-1));
|
||||
int y_in_lcu = (y & ((LCU_WIDTH)-1));
|
||||
|
||||
coord_x = (x + encoder_state->lcu_offset_x * LCU_WIDTH) + mv[0];
|
||||
coord_y = (y + encoder_state->lcu_offset_y * LCU_WIDTH) + mv[1];
|
||||
coord_x = (x + encoder_state->tile->lcu_offset_x * LCU_WIDTH) + mv[0];
|
||||
coord_y = (y + encoder_state->tile->lcu_offset_y * LCU_WIDTH) + mv[1];
|
||||
overflow_neg_x = (coord_x < 0)?1:0;
|
||||
overflow_neg_y = (coord_y < 0)?1:0;
|
||||
|
||||
|
@ -196,8 +196,8 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
int x_in_lcu = (x & ((LCU_WIDTH>>1)-1));
|
||||
int y_in_lcu = (y & ((LCU_WIDTH>>1)-1));
|
||||
|
||||
coord_x = (x + encoder_state->lcu_offset_x * (LCU_WIDTH >> 1)) + (mv[0]>>1);
|
||||
coord_y = (y + encoder_state->lcu_offset_y * (LCU_WIDTH >> 1)) + (mv[1]>>1);
|
||||
coord_x = (x + encoder_state->tile->lcu_offset_x * (LCU_WIDTH >> 1)) + (mv[0]>>1);
|
||||
coord_y = (y + encoder_state->tile->lcu_offset_y * (LCU_WIDTH >> 1)) + (mv[1]>>1);
|
||||
|
||||
overflow_neg_x = (coord_x < 0)?1:0;
|
||||
overflow_neg_y = (y + (mv[1]>>1) < 0)?1:0;
|
||||
|
@ -229,11 +229,11 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
// Copy Luma
|
||||
for (y = ypos; y < ypos + width; y++) {
|
||||
int y_in_lcu = (y & ((LCU_WIDTH)-1));
|
||||
coord_y = ((y + encoder_state->lcu_offset_y * LCU_WIDTH) + mv[1]) * ref->width; // pre-calculate
|
||||
coord_y = ((y + encoder_state->tile->lcu_offset_y * LCU_WIDTH) + mv[1]) * ref->width; // pre-calculate
|
||||
for (x = xpos; x < xpos + width; x++) {
|
||||
int x_in_lcu = (x & ((LCU_WIDTH)-1));
|
||||
|
||||
lcu->rec.y[y_in_lcu * LCU_WIDTH + x_in_lcu] = ref->y_recdata[coord_y + (x + encoder_state->lcu_offset_x * LCU_WIDTH) + mv[0]];
|
||||
lcu->rec.y[y_in_lcu * LCU_WIDTH + x_in_lcu] = ref->y_recdata[coord_y + (x + encoder_state->tile->lcu_offset_x * LCU_WIDTH) + mv[0]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,11 +242,11 @@ void inter_recon_lcu(const encoder_state * const encoder_state, const picture *
|
|||
// TODO: chroma fractional pixel interpolation
|
||||
for (y = ypos>>1; y < (ypos + width)>>1; y++) {
|
||||
int y_in_lcu = (y & ((LCU_WIDTH>>1)-1));
|
||||
coord_y = ((y + encoder_state->lcu_offset_y * (LCU_WIDTH>>1)) + (mv[1]>>1)) * ref_width_c; // pre-calculate
|
||||
coord_y = ((y + encoder_state->tile->lcu_offset_y * (LCU_WIDTH>>1)) + (mv[1]>>1)) * ref_width_c; // pre-calculate
|
||||
for (x = xpos>>1; x < (xpos + width)>>1; x++) {
|
||||
int x_in_lcu = (x & ((LCU_WIDTH>>1)-1));
|
||||
lcu->rec.u[y_in_lcu*dst_width_c + x_in_lcu] = ref->u_recdata[coord_y + (x + encoder_state->lcu_offset_x * (LCU_WIDTH>>1)) + (mv[0]>>1)];
|
||||
lcu->rec.v[y_in_lcu*dst_width_c + x_in_lcu] = ref->v_recdata[coord_y + (x + encoder_state->lcu_offset_x * (LCU_WIDTH>>1)) + (mv[0]>>1)];
|
||||
lcu->rec.u[y_in_lcu*dst_width_c + x_in_lcu] = ref->u_recdata[coord_y + (x + encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1)) + (mv[0]>>1)];
|
||||
lcu->rec.v[y_in_lcu*dst_width_c + x_in_lcu] = ref->v_recdata[coord_y + (x + encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1)) + (mv[0]>>1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,8 +332,8 @@ void inter_get_mv_cand(const encoder_state * const encoder_state, int32_t x, int
|
|||
inter_get_spatial_merge_candidates(x, y, depth, &b0, &b1, &b2, &a0, &a1, lcu);
|
||||
|
||||
#define CALCULATE_SCALE(cu,tb,td) ((tb * ((0x4000 + (abs(td)>>1))/td) + 32) >> 6)
|
||||
#define APPLY_MV_SCALING(cu, cand) {int td = encoder_state->poc - encoder_state->ref->pics[(cu)->inter.mv_ref]->poc;\
|
||||
int tb = encoder_state->poc - encoder_state->ref->pics[cur_cu->inter.mv_ref]->poc;\
|
||||
#define APPLY_MV_SCALING(cu, cand) {int td = encoder_state->global->poc - encoder_state->global->ref->pics[(cu)->inter.mv_ref]->poc;\
|
||||
int tb = encoder_state->global->poc - encoder_state->global->ref->pics[cur_cu->inter.mv_ref]->poc;\
|
||||
if (td != tb) { \
|
||||
int scale = CALCULATE_SCALE(cu,tb,td); \
|
||||
mv_cand[cand][0] = ((scale * (cu)->inter.mv[0] + 127 + (scale * (cu)->inter.mv[0] < 0)) >> 8 ); \
|
||||
|
|
|
@ -375,7 +375,7 @@ int16_t intra_prediction(encoder_state * const encoder_state, pixel *orig, int32
|
|||
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
||||
|
||||
sad = cost_func(pred, orig_block);
|
||||
sad += mode_cost * (int)(encoder_state->cur_lambda_cost + 0.5);
|
||||
sad += mode_cost * (int)(encoder_state->global->cur_lambda_cost + 0.5);
|
||||
// When rdo == 2, store best costs to an array and do full RDO later
|
||||
if(rdo == 2) {
|
||||
int rdo_mode = intra_rdo_cost_compare(rdo_costs, rdo_modes_to_check, sad);
|
||||
|
@ -419,7 +419,7 @@ int16_t intra_prediction(encoder_state * const encoder_state, pixel *orig, int32
|
|||
// Bitcost also calculated again for this mode
|
||||
rdo_bitcost = intra_pred_ratecost(rdo_modes[rdo_mode],intra_preds);
|
||||
// Add bitcost * lambda
|
||||
rdo_costs[rdo_mode] += rdo_bitcost * (int)(encoder_state->cur_lambda_cost + 0.5);
|
||||
rdo_costs[rdo_mode] += rdo_bitcost * (int)(encoder_state->global->cur_lambda_cost + 0.5);
|
||||
|
||||
if(rdo_costs[rdo_mode] < best_sad) {
|
||||
best_sad = rdo_costs[rdo_mode];
|
||||
|
|
|
@ -302,8 +302,6 @@ picture *picture_alloc(const int32_t width, const int32_t height,
|
|||
|
||||
pic->coeff_y = NULL; pic->coeff_u = NULL; pic->coeff_v = NULL;
|
||||
|
||||
pic->slice_sao_luma_flag = 1;
|
||||
pic->slice_sao_chroma_flag = 1;
|
||||
pic->sao_luma = MALLOC(sao_info, width_in_lcu * height_in_lcu);
|
||||
pic->sao_chroma = MALLOC(sao_info, width_in_lcu * height_in_lcu);
|
||||
|
||||
|
|
|
@ -126,10 +126,6 @@ typedef struct picture_struct
|
|||
uint8_t referenced; //!< \brief Whether this picture is referenced.
|
||||
int32_t refcount; //!< \brief Number of references in reflist to the picture
|
||||
cu_info* cu_array; //!< \brief Info for each CU at each depth.
|
||||
uint8_t type;
|
||||
uint8_t slicetype;
|
||||
uint8_t slice_sao_luma_flag;
|
||||
uint8_t slice_sao_chroma_flag;
|
||||
struct sao_info_struct *sao_luma; //!< \brief Array of sao parameters for every LCU.
|
||||
struct sao_info_struct *sao_chroma; //!< \brief Array of sao parameters for every LCU.
|
||||
int32_t poc; //!< \brief Picture order count
|
||||
|
|
32
src/rdo.c
32
src/rdo.c
|
@ -112,12 +112,12 @@ uint32_t rdo_cost_intra(encoder_state * const encoder_state, pixel *pred, pixel
|
|||
for (i = 0; i < width*width; i++) {
|
||||
coeffcost += abs((int)temp_coeff[i]);
|
||||
}
|
||||
cost += (1 + coeffcost + (coeffcost>>1))*((int)encoder_state->cur_lambda_cost+0.5);
|
||||
cost += (1 + coeffcost + (coeffcost>>1))*((int)encoder_state->global->cur_lambda_cost+0.5);
|
||||
// Full RDO
|
||||
} else if(encoder->rdo == 2) {
|
||||
coeffcost = get_coeff_cost(encoder_state, temp_coeff, width, 0, luma_scan_mode);
|
||||
|
||||
cost += coeffcost*((int)encoder_state->cur_lambda_cost+0.5);
|
||||
cost += coeffcost*((int)encoder_state->global->cur_lambda_cost+0.5);
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ uint32_t get_coded_level ( encoder_state * const encoder_state, double *coded_co
|
|||
cabac_ctx* 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 = encoder_state->cur_lambda_cost * CTX_ENTROPY_BITS(&base_sig_model[ctx_num_sig], 0);
|
||||
*coded_cost_sig = encoder_state->global->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 {
|
||||
|
@ -307,13 +307,13 @@ uint32_t get_coded_level ( encoder_state * const encoder_state, double *coded_co
|
|||
}
|
||||
|
||||
if( !last ) {
|
||||
cur_cost_sig = encoder_state->cur_lambda_cost * CTX_ENTROPY_BITS(&base_sig_model[ctx_num_sig], 1);
|
||||
cur_cost_sig = encoder_state->global->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 + encoder_state->cur_lambda_cost *
|
||||
double cur_cost = err * err * temp + encoder_state->global->cur_lambda_cost *
|
||||
get_ic_rate_cost( encoder_state, abs_level, ctx_num_one, ctx_num_abs,
|
||||
abs_go_rice, c1_idx, c2_idx, type);
|
||||
cur_cost += cur_cost_sig;
|
||||
|
@ -350,7 +350,7 @@ static double get_rate_last(const encoder_state * const encoder_state,
|
|||
if( ctx_y > 3 ) {
|
||||
uiCost += 32768.0 * ((ctx_y-2)>>1);
|
||||
}
|
||||
return encoder_state->cur_lambda_cost*uiCost;
|
||||
return encoder_state->global->cur_lambda_cost*uiCost;
|
||||
}
|
||||
|
||||
static void calc_last_bits(encoder_state * const encoder_state, int32_t width, int32_t height, int8_t type,
|
||||
|
@ -402,7 +402,7 @@ void rdoq(encoder_state * const encoder_state, coefficient *coef, coefficient *
|
|||
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 = get_scaled_qp(type, encoder_state->QP, 0);
|
||||
int32_t qp_scaled = get_scaled_qp(type, encoder_state->global->QP, 0);
|
||||
|
||||
{
|
||||
int32_t q_bits = QUANT_SHIFT + qp_scaled/6 + transform_shift;
|
||||
|
@ -591,7 +591,7 @@ void rdoq(encoder_state * const encoder_state, coefficient *coef, coefficient *
|
|||
if (sig_coeffgroup_flag[ cg_blkpos ] == 0) {
|
||||
uint32_t ctx_sig = context_get_sig_coeff_group(sig_coeffgroup_flag, cg_pos_x,
|
||||
cg_pos_y, width);
|
||||
cost_coeffgroup_sig[ cg_scanpos ] = encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
|
||||
cost_coeffgroup_sig[ cg_scanpos ] = encoder_state->global->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.
|
||||
|
@ -608,9 +608,9 @@ void rdoq(encoder_state * const encoder_state, coefficient *coef, coefficient *
|
|||
ctx_sig = 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] = encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],1);
|
||||
cost_coeffgroup_sig[cg_scanpos] = encoder_state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],1);
|
||||
base_cost += cost_coeffgroup_sig[cg_scanpos];
|
||||
cost_zero_cg += encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
|
||||
cost_zero_cg += encoder_state->global->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
|
||||
|
@ -624,7 +624,7 @@ void rdoq(encoder_state * const encoder_state, coefficient *coef, coefficient *
|
|||
sig_coeffgroup_flag[ cg_blkpos ] = 0;
|
||||
base_cost = cost_zero_cg;
|
||||
if (cg_scanpos < cg_last_scanpos) {
|
||||
cost_coeffgroup_sig[ cg_scanpos ] = encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&base_coeff_group_ctx[ctx_sig],0);
|
||||
cost_coeffgroup_sig[ cg_scanpos ] = encoder_state->global->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--) {
|
||||
|
@ -652,13 +652,13 @@ void rdoq(encoder_state * const encoder_state, coefficient *coef, coefficient *
|
|||
|
||||
|
||||
if( block_type != CU_INTRA && !type/* && pcCU->getTransformIdx( uiAbsPartIdx ) == 0*/ ) {
|
||||
best_cost = block_uncoded_cost + encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx_cu_qt_root_cbf_model),0);
|
||||
base_cost += encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx_cu_qt_root_cbf_model),1);
|
||||
best_cost = block_uncoded_cost + encoder_state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx_cu_qt_root_cbf_model),0);
|
||||
base_cost += encoder_state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&(cabac->ctx_cu_qt_root_cbf_model),1);
|
||||
} else {
|
||||
cabac_ctx* 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 + encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],0);
|
||||
base_cost += encoder_state->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],1);
|
||||
best_cost = block_uncoded_cost + encoder_state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],0);
|
||||
base_cost += encoder_state->global->cur_lambda_cost*CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],1);
|
||||
}
|
||||
|
||||
for (cg_scanpos = cg_last_scanpos; cg_scanpos >= 0; cg_scanpos--) {
|
||||
|
@ -712,7 +712,7 @@ void rdoq(encoder_state * const encoder_state, coefficient *coef, coefficient *
|
|||
if(*abs_sum >= 2) {
|
||||
int64_t rd_factor = (int64_t) (
|
||||
g_inv_quant_scales[qp_scaled%6] * g_inv_quant_scales[qp_scaled%6] * (1<<(2*(qp_scaled/6)))
|
||||
/ encoder_state->cur_lambda_cost / 16 / (1<<(2*(encoder->bitdepth-8)))
|
||||
/ encoder_state->global->cur_lambda_cost / 16 / (1<<(2*(encoder->bitdepth-8)))
|
||||
+ 0.5);
|
||||
int32_t lastCG = -1;
|
||||
int32_t absSum = 0;
|
||||
|
|
12
src/sao.c
12
src/sao.c
|
@ -669,7 +669,7 @@ static void sao_search_edge_sao(const encoder_state * const encoder_state,
|
|||
|
||||
{
|
||||
int mode_bits = sao_mode_bits_edge(edge_class, edge_offset, sao_top, sao_left);
|
||||
sum_ddistortion += (int)((double)mode_bits*(encoder_state->cur_lambda_cost+0.5));
|
||||
sum_ddistortion += (int)((double)mode_bits*(encoder_state->global->cur_lambda_cost+0.5));
|
||||
}
|
||||
// SAO is not applied for category 0.
|
||||
edge_offset[SAO_EO_CAT0] = 0;
|
||||
|
@ -711,7 +711,7 @@ static void sao_search_band_sao(const encoder_state * const encoder_state, const
|
|||
ddistortion = calc_sao_band_offsets(sao_bands, temp_offsets, &sao_out->band_position);
|
||||
|
||||
temp_rate = sao_mode_bits_band(sao_out->band_position, temp_offsets, sao_top, sao_left);
|
||||
ddistortion += (int)((double)temp_rate*(encoder_state->cur_lambda_cost+0.5));
|
||||
ddistortion += (int)((double)temp_rate*(encoder_state->global->cur_lambda_cost+0.5));
|
||||
|
||||
// Select band sao over edge sao when distortion is lower
|
||||
if (ddistortion < sao_out->ddistortion) {
|
||||
|
@ -745,7 +745,7 @@ static void sao_search_best_mode(const encoder_state * const encoder_state, cons
|
|||
|
||||
{
|
||||
int mode_bits = sao_mode_bits_edge(edge_sao.eo_class, edge_sao.offsets, sao_top, sao_left);
|
||||
int ddistortion = mode_bits * (int)(encoder_state->cur_lambda_cost + 0.5);
|
||||
int ddistortion = mode_bits * (int)(encoder_state->global->cur_lambda_cost + 0.5);
|
||||
unsigned buf_i;
|
||||
|
||||
for (buf_i = 0; buf_i < buf_cnt; ++buf_i) {
|
||||
|
@ -759,7 +759,7 @@ static void sao_search_best_mode(const encoder_state * const encoder_state, cons
|
|||
|
||||
{
|
||||
int mode_bits = sao_mode_bits_band(band_sao.band_position, &band_sao.offsets[1], sao_top, sao_left);
|
||||
int ddistortion = mode_bits * (int)(encoder_state->cur_lambda_cost + 0.5);
|
||||
int ddistortion = mode_bits * (int)(encoder_state->global->cur_lambda_cost + 0.5);
|
||||
unsigned buf_i;
|
||||
|
||||
for (buf_i = 0; buf_i < buf_cnt; ++buf_i) {
|
||||
|
@ -780,7 +780,7 @@ static void sao_search_best_mode(const encoder_state * const encoder_state, cons
|
|||
// Choose between SAO and doing nothing, taking into account the
|
||||
// rate-distortion cost of coding do nothing.
|
||||
{
|
||||
int cost_of_nothing = sao_mode_bits_none(sao_top, sao_left) * (int)(encoder_state->cur_lambda_cost + 0.5);
|
||||
int cost_of_nothing = sao_mode_bits_none(sao_top, sao_left) * (int)(encoder_state->global->cur_lambda_cost + 0.5);
|
||||
if (sao_out->ddistortion >= cost_of_nothing) {
|
||||
sao_out->type = SAO_TYPE_NONE;
|
||||
}
|
||||
|
@ -863,7 +863,7 @@ void sao_search_luma(const encoder_state * const encoder_state, const picture *p
|
|||
void sao_reconstruct_frame(encoder_state * const encoder_state)
|
||||
{
|
||||
vector2d lcu;
|
||||
picture * const cur_pic = encoder_state->cur_pic;
|
||||
picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
|
||||
// These are needed because SAO needs the pre-SAO pixels form left and
|
||||
// top LCUs. Single pixel wide buffers, like what search_lcu takes, would
|
||||
|
|
52
src/search.c
52
src/search.c
|
@ -159,7 +159,7 @@ static int calc_mvd_cost(const encoder_state * const encoder_state, int x, int y
|
|||
temp_bitcost += cur_mv_cand ? cand2_cost : cand1_cost;
|
||||
}
|
||||
*bitcost = temp_bitcost;
|
||||
return temp_bitcost*(int32_t)(encoder_state->cur_lambda_cost+0.5);
|
||||
return temp_bitcost*(int32_t)(encoder_state->global->cur_lambda_cost+0.5);
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,8 +201,8 @@ static unsigned hexagon_search(const encoder_state * const encoder_state, unsign
|
|||
for (i = 0; i < 7; ++i) {
|
||||
const vector2d *pattern = &large_hexbs[i];
|
||||
unsigned cost = calc_sad(pic, ref, orig->x, orig->y,
|
||||
(encoder_state->lcu_offset_x * LCU_WIDTH) + orig->x + mv.x + pattern->x,
|
||||
(encoder_state->lcu_offset_y * LCU_WIDTH) + orig->y + mv.y + pattern->y,
|
||||
(encoder_state->tile->lcu_offset_x * LCU_WIDTH) + orig->x + mv.x + pattern->x,
|
||||
(encoder_state->tile->lcu_offset_y * LCU_WIDTH) + orig->y + mv.y + pattern->y,
|
||||
block_width, block_width);
|
||||
cost += calc_mvd_cost(encoder_state, mv.x + pattern->x, mv.y + pattern->y, mv_cand,merge_cand,num_cand,ref_idx, &bitcost);
|
||||
|
||||
|
@ -216,8 +216,8 @@ static unsigned hexagon_search(const encoder_state * const encoder_state, unsign
|
|||
// Try the 0,0 vector.
|
||||
if (!(mv.x == 0 && mv.y == 0)) {
|
||||
unsigned cost = calc_sad(pic, ref, orig->x, orig->y,
|
||||
(encoder_state->lcu_offset_x * LCU_WIDTH) + orig->x,
|
||||
(encoder_state->lcu_offset_y * LCU_WIDTH) + orig->y,
|
||||
(encoder_state->tile->lcu_offset_x * LCU_WIDTH) + orig->x,
|
||||
(encoder_state->tile->lcu_offset_y * LCU_WIDTH) + orig->y,
|
||||
block_width, block_width);
|
||||
cost += calc_mvd_cost(encoder_state, 0, 0, mv_cand,merge_cand,num_cand,ref_idx, &bitcost);
|
||||
|
||||
|
@ -232,8 +232,8 @@ static unsigned hexagon_search(const encoder_state * const encoder_state, unsign
|
|||
for (i = 1; i < 7; ++i) {
|
||||
const vector2d *pattern = &large_hexbs[i];
|
||||
unsigned cost = calc_sad(pic, ref, orig->x, orig->y,
|
||||
(encoder_state->lcu_offset_x * LCU_WIDTH) + orig->x + pattern->x,
|
||||
(encoder_state->lcu_offset_y * LCU_WIDTH) + orig->y + pattern->y,
|
||||
(encoder_state->tile->lcu_offset_x * LCU_WIDTH) + orig->x + pattern->x,
|
||||
(encoder_state->tile->lcu_offset_y * LCU_WIDTH) + orig->y + pattern->y,
|
||||
block_width, block_width);
|
||||
cost += calc_mvd_cost(encoder_state, pattern->x, pattern->y, mv_cand,merge_cand,num_cand,ref_idx, &bitcost);
|
||||
|
||||
|
@ -267,8 +267,8 @@ static unsigned hexagon_search(const encoder_state * const encoder_state, unsign
|
|||
for (i = 0; i < 3; ++i) {
|
||||
const vector2d *offset = &large_hexbs[start + i];
|
||||
unsigned cost = calc_sad(pic, ref, orig->x, orig->y,
|
||||
(encoder_state->lcu_offset_x * LCU_WIDTH) + orig->x + mv.x + offset->x,
|
||||
(encoder_state->lcu_offset_y * LCU_WIDTH) + orig->y + mv.y + offset->y,
|
||||
(encoder_state->tile->lcu_offset_x * LCU_WIDTH) + orig->x + mv.x + offset->x,
|
||||
(encoder_state->tile->lcu_offset_y * LCU_WIDTH) + orig->y + mv.y + offset->y,
|
||||
block_width, block_width);
|
||||
cost += calc_mvd_cost(encoder_state, mv.x + offset->x, mv.y + offset->y, mv_cand,merge_cand,num_cand,ref_idx, &bitcost);
|
||||
|
||||
|
@ -290,8 +290,8 @@ static unsigned hexagon_search(const encoder_state * const encoder_state, unsign
|
|||
for (i = 1; i < 5; ++i) {
|
||||
const vector2d *offset = &small_hexbs[i];
|
||||
unsigned cost = calc_sad(pic, ref, orig->x, orig->y,
|
||||
(encoder_state->lcu_offset_x * LCU_WIDTH) + orig->x + mv.x + offset->x,
|
||||
(encoder_state->lcu_offset_y * LCU_WIDTH) + orig->y + mv.y + offset->y,
|
||||
(encoder_state->tile->lcu_offset_x * LCU_WIDTH) + orig->x + mv.x + offset->x,
|
||||
(encoder_state->tile->lcu_offset_y * LCU_WIDTH) + orig->y + mv.y + offset->y,
|
||||
block_width, block_width);
|
||||
cost += calc_mvd_cost(encoder_state, mv.x + offset->x, mv.y + offset->y, mv_cand,merge_cand,num_cand,ref_idx, &bitcost);
|
||||
|
||||
|
@ -374,7 +374,7 @@ static unsigned search_mv_full(unsigned depth,
|
|||
*/
|
||||
static int search_cu_inter(const encoder_state * const encoder_state, int x, int y, int depth, lcu_t *lcu)
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
uint32_t ref_idx = 0;
|
||||
int x_local = (x&0x3f), y_local = (y&0x3f);
|
||||
int x_cu = x>>3;
|
||||
|
@ -394,8 +394,8 @@ static int search_cu_inter(const encoder_state * const encoder_state, int x, int
|
|||
|
||||
cur_cu->inter.cost = UINT_MAX;
|
||||
|
||||
for (ref_idx = 0; ref_idx < encoder_state->ref->used_size; ref_idx++) {
|
||||
picture *ref_pic = encoder_state->ref->pics[ref_idx];
|
||||
for (ref_idx = 0; ref_idx < encoder_state->global->ref->used_size; ref_idx++) {
|
||||
picture *ref_pic = encoder_state->global->ref->pics[ref_idx];
|
||||
unsigned width_in_scu = NO_SCU_IN_LCU(ref_pic->width_in_lcu);
|
||||
cu_info *ref_cu = &ref_pic->cu_array[y_cu * width_in_scu + x_cu];
|
||||
uint32_t temp_bitcost = 0;
|
||||
|
@ -670,7 +670,7 @@ static int search_cu_intra(encoder_state * const encoder_state,
|
|||
const int x_px, const int y_px,
|
||||
const int depth, lcu_t *lcu)
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
const vector2d lcu_px = { x_px & 0x3f, y_px & 0x3f };
|
||||
const vector2d lcu_cu = { lcu_px.x >> 3, lcu_px.y >> 3 };
|
||||
const int8_t cu_width = (LCU_WIDTH >> (depth));
|
||||
|
@ -776,7 +776,7 @@ static int lcu_get_final_cost(const encoder_state * const encoder_state,
|
|||
}
|
||||
}
|
||||
// Coefficient costs
|
||||
cost += (coeff_cost + (coeff_cost>>1)) * (int32_t)(encoder_state->cur_lambda_cost+0.5);
|
||||
cost += (coeff_cost + (coeff_cost>>1)) * (int32_t)(encoder_state->global->cur_lambda_cost+0.5);
|
||||
|
||||
// Calculate actual bit costs for coding the coeffs
|
||||
// RDO
|
||||
|
@ -838,11 +838,11 @@ static int lcu_get_final_cost(const encoder_state * const encoder_state,
|
|||
coeff_cost += get_coeff_cost(encoder_state, coeff_temp_v, blockwidth, 2, chroma_scan_mode);
|
||||
}
|
||||
// Multiply bit count with lambda to get RD-cost
|
||||
cost += coeff_cost * (int32_t)(encoder_state->cur_lambda_cost+0.5);
|
||||
cost += coeff_cost * (int32_t)(encoder_state->global->cur_lambda_cost+0.5);
|
||||
}
|
||||
|
||||
// Bitcost
|
||||
cost += (cur_cu->type == CU_INTER ? cur_cu->inter.bitcost : cur_cu->intra[PU_INDEX(x_px >> 2, y_px >> 2)].bitcost)*(int32_t)(encoder_state->cur_lambda_cost+0.5);
|
||||
cost += (cur_cu->type == CU_INTER ? cur_cu->inter.bitcost : cur_cu->intra[PU_INDEX(x_px >> 2, y_px >> 2)].bitcost)*(int32_t)(encoder_state->global->cur_lambda_cost+0.5);
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
@ -859,7 +859,7 @@ static int lcu_get_final_cost(const encoder_state * const encoder_state,
|
|||
*/
|
||||
static int search_cu(encoder_state * const encoder_state, int x, int y, int depth, lcu_t work_tree[MAX_PU_DEPTH])
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
int cu_width = LCU_WIDTH >> depth;
|
||||
int cost = MAX_INT;
|
||||
cu_info *cur_cu;
|
||||
|
@ -883,7 +883,7 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept
|
|||
y + cu_width <= cur_pic->height)
|
||||
{
|
||||
|
||||
if (cur_pic->slicetype != SLICE_I &&
|
||||
if (encoder_state->global->slicetype != SLICE_I &&
|
||||
depth >= MIN_INTER_SEARCH_DEPTH &&
|
||||
depth <= MAX_INTER_SEARCH_DEPTH)
|
||||
{
|
||||
|
@ -911,7 +911,7 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept
|
|||
intra_recon_lcu(encoder_state, x, y, depth,&work_tree[depth], cur_pic->width, cur_pic->height);
|
||||
} else if (cur_cu->type == CU_INTER) {
|
||||
int cbf;
|
||||
inter_recon_lcu(encoder_state, encoder_state->ref->pics[cur_cu->inter.mv_ref], x, y, LCU_WIDTH>>depth, cur_cu->inter.mv, &work_tree[depth]);
|
||||
inter_recon_lcu(encoder_state, encoder_state->global->ref->pics[cur_cu->inter.mv_ref], x, y, LCU_WIDTH>>depth, cur_cu->inter.mv, &work_tree[depth]);
|
||||
encode_transform_tree(encoder_state, x, y, depth, &work_tree[depth]);
|
||||
|
||||
cbf = cbf_is_set(cur_cu->cbf.y, depth) || cbf_is_set(cur_cu->cbf.u, depth) || cbf_is_set(cur_cu->cbf.v, depth);
|
||||
|
@ -933,7 +933,7 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept
|
|||
// Recursively split all the way to max search depth.
|
||||
if (depth < MAX_INTRA_SEARCH_DEPTH || depth < MAX_INTER_SEARCH_DEPTH) {
|
||||
int half_cu = cu_width / 2;
|
||||
int split_cost = (int)(4.5 * encoder_state->cur_lambda_cost);
|
||||
int split_cost = (int)(4.5 * encoder_state->global->cur_lambda_cost);
|
||||
int cbf = cbf_is_set(cur_cu->cbf.y, depth) || cbf_is_set(cur_cu->cbf.u, depth) || cbf_is_set(cur_cu->cbf.v, depth);
|
||||
|
||||
// If skip mode was selected for the block, skip further search.
|
||||
|
@ -970,7 +970,7 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept
|
|||
*/
|
||||
static void init_lcu_t(const encoder_state * const encoder_state, const int x, const int y, lcu_t *lcu, const yuv_t *hor_buf, const yuv_t *ver_buf)
|
||||
{
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
|
||||
// Copy reference cu_info structs from neighbouring LCUs.
|
||||
{
|
||||
|
@ -1050,7 +1050,7 @@ static void init_lcu_t(const encoder_state * const encoder_state, const int x, c
|
|||
|
||||
// Copy LCU pixels.
|
||||
{
|
||||
const picture * const pic = encoder_state->cur_pic;
|
||||
const picture * const pic = encoder_state->tile->cur_pic;
|
||||
int pic_width = cur_pic->width;
|
||||
int x_max = MIN(x + LCU_WIDTH, pic_width) - x;
|
||||
int y_max = MIN(y + LCU_WIDTH, cur_pic->height) - y;
|
||||
|
@ -1080,7 +1080,7 @@ static void copy_lcu_to_cu_data(const encoder_state * const encoder_state, int x
|
|||
{
|
||||
const int x_cu = x_px >> MAX_DEPTH;
|
||||
const int y_cu = y_px >> MAX_DEPTH;
|
||||
const picture * const cur_pic = encoder_state->cur_pic;
|
||||
const picture * const cur_pic = encoder_state->tile->cur_pic;
|
||||
const int cu_array_width = cur_pic->width_in_lcu << MAX_DEPTH;
|
||||
cu_info *const cu_array = cur_pic->cu_array;
|
||||
|
||||
|
@ -1100,7 +1100,7 @@ static void copy_lcu_to_cu_data(const encoder_state * const encoder_state, int x
|
|||
|
||||
// Copy pixels to picture.
|
||||
{
|
||||
picture * const pic = encoder_state->cur_pic;
|
||||
picture * const pic = encoder_state->tile->cur_pic;
|
||||
const int pic_width = pic->width;
|
||||
const int x_max = MIN(x_px + LCU_WIDTH, pic_width) - x_px;
|
||||
const int y_max = MIN(y_px + LCU_WIDTH, pic->height) - y_px;
|
||||
|
|
|
@ -634,7 +634,7 @@ void quant(const encoder_state * const encoder_state, int16_t *coef, int16_t *q_
|
|||
int32_t delta_u[LCU_WIDTH*LCU_WIDTH>>2];
|
||||
#endif
|
||||
|
||||
int32_t qp_scaled = get_scaled_qp(type, encoder_state->QP, 0);
|
||||
int32_t qp_scaled = get_scaled_qp(type, encoder_state->global->QP, 0);
|
||||
|
||||
//New block for variable definitions
|
||||
{
|
||||
|
@ -646,7 +646,7 @@ void quant(const encoder_state * const encoder_state, int16_t *coef, int16_t *q_
|
|||
|
||||
int32_t transform_shift = MAX_TR_DYNAMIC_RANGE - encoder->bitdepth - log2_tr_size; //!< Represents scaling through forward transform
|
||||
int32_t q_bits = QUANT_SHIFT + qp_scaled/6 + transform_shift;
|
||||
int32_t add = ((encoder_state->cur_pic->slicetype == SLICE_I) ? 171 : 85) << (q_bits - 9);
|
||||
int32_t add = ((encoder_state->global->slicetype == SLICE_I) ? 171 : 85) << (q_bits - 9);
|
||||
|
||||
int32_t q_bits8 = q_bits - 8;
|
||||
for (n = 0; n < width * height; n++) {
|
||||
|
@ -762,7 +762,7 @@ void dequant(const encoder_state * const encoder_state, int16_t *q_coef, int16_t
|
|||
int32_t n;
|
||||
int32_t transform_shift = 15 - encoder->bitdepth - (g_convert_to_bit[ width ] + 2);
|
||||
|
||||
int32_t qp_scaled = get_scaled_qp(type, encoder_state->QP, 0);
|
||||
int32_t qp_scaled = get_scaled_qp(type, encoder_state->global->QP, 0);
|
||||
|
||||
shift = 20 - QUANT_SHIFT - transform_shift;
|
||||
|
||||
|
|
Loading…
Reference in a new issue