📄 prediction.c
字号:
/* * prediction.c: Range image prediction with MC or ND * * Written by: Ullrich Hafner * Michael Unger * * This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> *//* * $Date: 2000/06/14 20:50:51 $ * $Author: hafner $ * $Revision: 5.1 $ * $State: Exp $ */#include "config.h"#if HAVE_STRING_H# include <string.h>#else /* not HAVE_STRING_H */# include <strings.h>#endif /* not HAVE_STRING_H */#include "types.h"#include "macros.h"#include "error.h"#include "cwfa.h"#include "ip.h"#include "control.h"#include "misc.h"#include "subdivide.h"#include "bintree.h"#include "domain-pool.h"#include "approx.h"#include "wfalib.h"#include "mwfa.h"#include "prediction.h"#include "decoder.h"/***************************************************************************** local variables *****************************************************************************/typedef struct state_data{ real_t final_distribution; byte_t level_of_state; byte_t domain_type; real_t *images_of_state; real_t *inner_products; real_t *ip_states_state [MAXLEVEL]; word_t tree [MAXLABELS]; mv_t mv_tree [MAXLABELS]; word_t y_state [MAXLABELS]; byte_t y_column [MAXLABELS]; byte_t prediction [MAXLABELS]; u_word_t x [MAXLABELS]; u_word_t y [MAXLABELS]; real_t weight [MAXLABELS][MAXEDGES + 1]; word_t int_weight [MAXLABELS][MAXEDGES + 1]; word_t into [MAXLABELS][MAXEDGES + 1];} state_data_t;/***************************************************************************** prototypes *****************************************************************************/static real_tnd_prediction (real_t max_costs, real_t price, unsigned band, int y_state, range_t *range, wfa_t *wfa, coding_t *c);static real_tmc_prediction (real_t max_costs, real_t price, unsigned band, int y_state, range_t *range, wfa_t *wfa, coding_t *c);static state_data_t *store_state_data (unsigned from, unsigned to, unsigned max_level, wfa_t *wfa, coding_t *c);static voidrestore_state_data (unsigned from, unsigned to, unsigned max_level, state_data_t *data, wfa_t *wfa, coding_t *c);/***************************************************************************** public code *****************************************************************************/ real_tpredict_range (real_t max_costs, real_t price, range_t *range, wfa_t *wfa, coding_t *c, unsigned band, int y_state, unsigned states, const tree_t *tree_model, const tree_t *p_tree_model, const void *domain_model, const void *d_domain_model, const void *coeff_model, const void *d_coeff_model){ unsigned state; /* counter */ void *rec_domain_model; /* domain model after recursion */ void *rec_d_domain_model; /* p domain model after recursion */ void *rec_coeff_model; /* coeff model after recursion */ void *rec_d_coeff_model; /* d coeff model after recursion */ tree_t rec_tree_model; /* tree_model after '' */ tree_t rec_p_tree_model; /* p_tree_model after '' */ unsigned rec_states; /* wfa->states after '' */ real_t *rec_pixels; /* c->pixels after '' */ state_data_t *rec_state_data; /* state_data struct after '' */ real_t costs; /* current approximation costs */ unsigned level; /* counter */ state_data_t *sd; /* pointer to state_data field */ /* * Store WFA data from state 'lc_states' to 'wfa->states' - 1 and * current state of probability models. */ rec_domain_model = c->domain_pool->model; rec_d_domain_model = c->d_domain_pool->model; rec_coeff_model = c->coeff->model; rec_d_coeff_model = c->d_coeff->model; rec_tree_model = c->tree; rec_p_tree_model = c->p_tree; rec_states = wfa->states; rec_pixels = c->pixels; rec_state_data = store_state_data (states, rec_states - 1, c->options.lc_max_level, wfa, c); /* * Restore probability models to the state before the recursive subdivision * has been started. */ wfa->states = states; c->tree = *tree_model; c->p_tree = *p_tree_model; c->domain_pool->model = c->domain_pool->model_duplicate (domain_model); c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model); c->coeff->model = c->coeff->model_duplicate (c->coeff, coeff_model); c->d_coeff->model = c->d_coeff->model_duplicate (c->d_coeff, d_coeff_model); if (c->mt->frame_type == I_FRAME) costs = nd_prediction (max_costs, price, band, y_state, range, wfa, c); else costs = mc_prediction (max_costs, price, band, y_state, range, wfa, c); c->pixels = rec_pixels; if (costs < MAXCOSTS) { /* * Free the memory used by the state_data struct */ for (state = states; state < rec_states; state++) { sd = &rec_state_data [state - states]; for (level = c->options.images_level + 1; level <= c->options.lc_max_level; level++) if (sd->ip_states_state [level] != NULL) Free (sd->ip_states_state [level]); if (sd->images_of_state != NULL) Free (sd->images_of_state); if (sd->inner_products != NULL) Free (sd->inner_products); } if (states < rec_states) Free (rec_state_data); c->domain_pool->model_free (rec_domain_model); c->d_domain_pool->model_free (rec_d_domain_model); c->coeff->model_free (rec_coeff_model); c->d_coeff->model_free (rec_d_coeff_model); costs = (range->tree_bits + range->matrix_bits + range->weights_bits + range->mv_tree_bits + range->mv_coord_bits + range->nd_tree_bits + range->nd_weights_bits) * price + range->err; } else { /* * Restore WFA to state before function was called */ c->domain_pool->model_free (c->domain_pool->model); c->d_domain_pool->model_free (c->d_domain_pool->model); c->coeff->model_free (c->coeff->model); c->d_coeff->model_free (c->d_coeff->model); c->domain_pool->model = rec_domain_model; c->d_domain_pool->model = rec_d_domain_model; c->coeff->model = rec_coeff_model; c->d_coeff->model = rec_d_coeff_model; c->tree = rec_tree_model; c->p_tree = rec_p_tree_model; range->prediction = NO; if (wfa->states != states) remove_states (states, wfa); restore_state_data (states, rec_states - 1, c->options.lc_max_level, rec_state_data, wfa, c); costs = MAXCOSTS; } return costs;} voidclear_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)/* * Clear norms arrays. * * No return value. */{ unsigned range_size = wi->half_pixel ? square (wi->search_range) : square (2 * wi->search_range); if (level > wi->p_min_level) { memset (mt->mc_forward_norms [level], 0, range_size * sizeof(real_t)); memset (mt->mc_backward_norms [level], 0, range_size * sizeof(real_t)); }}voidupdate_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)/* * Norms table of levels larger than the bottom level are computed * by summing up previously calculated displacement costs of lower levels. * * No return value. */{ unsigned range_size = wi->half_pixel ? square (wi->search_range) : square (2 * wi->search_range); if (level > wi->p_min_level) { unsigned index; /* index of motion vector */ for (index = 0; index < range_size; index++) mt->mc_forward_norms [level][index] += mt->mc_forward_norms [level - 1][index]; if (mt->frame_type == B_FRAME) for (index = 0; index < range_size; index++) mt->mc_backward_norms [level][index] += mt->mc_backward_norms [level - 1][index]; }}/***************************************************************************** private code *****************************************************************************/static real_tmc_prediction (real_t max_costs, real_t price, unsigned band, int y_state, range_t *range, wfa_t *wfa, coding_t *c){ real_t costs; /* current approximation costs */ range_t prange = *range; unsigned width = width_of_level (range->level); unsigned height = height_of_level (range->level); word_t *mcpe = Calloc (width * height, sizeof (word_t)); /* * If we are at the bottom level of the mc tree: * Fill in the norms table */ if (prange.level == wfa->wfainfo->p_min_level) fill_norms_table (prange.x, prange.y, prange.level, wfa->wfainfo, c->mt); /* * Predict 'range' with motion compensation according to frame type. * MCPE is returned in 'c->mcpe' */ if (c->mt->frame_type == P_FRAME) find_P_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt); else find_B_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt); costs = (prange.mv_tree_bits + prange.mv_coord_bits) * price; if (costs < max_costs) /* motion vector not too expensive */ { unsigned last_state; /* last WFA state before recursion */ real_t *ipi [MAXSTATES]; /* inner products pointers */ unsigned state; real_t mvt, mvc; c->pixels = Calloc (width * height, sizeof (real_t)); cut_to_bintree (c->pixels, mcpe, width, height, 0, 0, width, height); /* * Approximate MCPE recursively. */ last_state = wfa->states - 1; for (state = 0; state <= last_state; state++) if (need_image (state, wfa)) { ipi [state] = c->ip_images_state[state]; c->ip_images_state[state] = Calloc (size_of_tree (c->products_level), sizeof (real_t)); } mvc = prange.mv_coord_bits;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -