/******************************************************************************
*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
/*!
******************************************************************************
* \file hme_utils.h
*
* \brief
* Prototypes for various utilities used by coarse/refinement/subpel fxns
*
* \date
* 18/09/2012
*
* \author
* Ittiam
*
******************************************************************************
*/
#ifndef _HME_UTILS_H_
#define _HME_UTILS_H_
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/**
********************************************************************************
* @fn hme_init_histogram(
*
* @brief Top level entry point for Coarse ME. Runs across blocks and does the
* needful by calling other low level routines.
*
* @param[in,out] ps_hist : the histogram structure
*
* @param[in] i4_max_mv_x : Maximum mv allowed in x direction (fpel units)
*
* @param[in] i4_max_mv_y : Maximum mv allowed in y direction (fpel units)
*
* @return None
********************************************************************************
*/
void hme_init_histogram(mv_hist_t *ps_hist, S32 i4_max_mv_x, S32 i4_max_mv_y);
/**
********************************************************************************
* @fn hme_update_histogram(
*
* @brief Updates the histogram given an mv entry
*
* @param[in,out] ps_hist : the histogram structure
*
* @param[in] i4_mv_x : x component of the mv (fpel units)
*
* @param[in] i4_mv_y : y component of the mv (fpel units)
*
* @return None
********************************************************************************
*/
void hme_update_histogram(mv_hist_t *ps_hist, S32 i4_mv_x, S32 i4_mv_y);
/**
********************************************************************************
* @fn hme_get_global_mv(
*
* @brief returns the global mv of a previous picture. Accounts for the fact
* that the delta poc of the previous picture may have been different
* from delta poc of current picture. Delta poc is POC difference
* between a picture and its reference.
*
* @param[out] ps_mv: mv_t structure where the motion vector is returned
*
* @param[in] i4_delta_poc: the delta poc for the current pic w.r.t. reference
*
* @return None
********************************************************************************
*/
void hme_get_global_mv(layer_ctxt_t *ps_prev_layer, hme_mv_t *ps_mv, S32 i4_delta_poc);
/**
********************************************************************************
* @fn hme_calculate_global_mv(
*
* @brief Calculates global mv for a given histogram
*
* @param[in] ps_hist : the histogram structure
*
* @param[in] ps_mv : used to return the global mv
*
* @param[in] e_lobe_type : refer to GMV_MVTYPE_T
*
* @return None
********************************************************************************
*/
void hme_calculate_global_mv(mv_hist_t *ps_hist, hme_mv_t *ps_mv, GMV_MVTYPE_T e_lobe_type);
/**
********************************************************************************
* @fn hme_collate_fpel_results(search_results_t *ps_search_results,
* S32 i1_ref_idx, S32 i1_idx_to_merge)
*
* @brief After full pel search and result seeding in every search iteration
* results, this function called to collapse a given search iteration
* results into another.
*
* @param[in,out] ps_search_results : Search results data structure
* @param[in] i1_ref_idx: id of the search iteration where the results
will be collapsed
* @param[in] i1_idx_to_merge : id of the search iteration from which the
* results are picked up.
*
* @return None
********************************************************************************
*/
void hme_collate_fpel_results(
search_results_t *ps_search_results, S08 i1_ref_idx, S08 i1_idx_to_merge);
/**
********************************************************************************
* @fn hme_map_mvs_to_grid(mv_grid_t **pps_mv_grid,
search_results_t *ps_search_results, S32 i4_num_ref)
*
* @brief For a given CU whose results are in ps_search_results, the 17x17
* mv grid is updated for future use within the CTB
*
* @param[in] ps_search_results : Search results data structure
*
* @param[out] pps_mv_grid: The mv grid (as many as num ref)
*
* @param[in] i4_num_ref: nuber of search iterations to update
*
* @param[in] mv_res_shift: Shift for resolution of mv (fpel/qpel)
*
* @return None
********************************************************************************
*/
void hme_map_mvs_to_grid(
mv_grid_t **pps_mv_grid,
search_results_t *ps_search_results,
U08 *pu1_pred_dir_searched,
S32 i4_num_pred_dir);
/**
********************************************************************************
* @fn hme_create_valid_part_ids(S32 i4_part_mask, S32 *pi4_valid_part_ids)
*
* @brief Expands the part mask to a list of valid part ids terminated by -1
*
* @param[in] i4_part_mask : bit mask of active partitino ids
*
* @param[out] pi4_valid_part_ids : array, each entry has one valid part id
* Terminated by -1 to signal end.
*
* @return number of partitions
********************************************************************************
*/
S32 hme_create_valid_part_ids(S32 i4_part_mask, S32 *pi4_valid_part_ids);
/**
********************************************************************************
* @fn get_num_blks_in_ctb(S32 i4_ctb_x,
S32 i4_ctb_y,
S32 i4_pic_wd,
S32 i4_pic_ht,
S32 i4_blk_size)
*
* @brief returns the number of blks in the ctb (64x64 ctb)
*
* @param[in] i4_ctb_x : pixel x offset of the top left corner of ctb in pic
*
* @param[in] i4_ctb_y : pixel y offset of the top left corner of ctb in pic
*
* @param[in] i4_ctb_x : width of the picture in pixels
*
* @param[in] i4_pic_ht : height of hte picture in pixels
*
* @param[in] i4_blk_size : Size of the blk in pixels
*
* @return number of blks in the ctb
********************************************************************************
*/
S32 get_num_blks_in_ctb(S32 i4_ctb_x, S32 i4_ctb_y, S32 i4_pic_wd, S32 i4_pic_ht, S32 i4_blk_size);
/**
********************************************************************************
* @fn hevc_avg_2d(U08 *pu1_src1,
* U08 *pu1_src2,
* S32 i4_src1_stride,
* S32 i4_src2_stride,
* S32 i4_blk_wd,
* S32 i4_blk_ht,
* U08 *pu1_dst,
* S32 i4_dst_stride)
*
*
* @brief point wise average of two buffers into a third buffer
*
* @param[in] pu1_src1 : first source buffer
*
* @param[in] pu1_src2 : 2nd source buffer
*
* @param[in] i4_src1_stride : stride of source 1 buffer
*
* @param[in] i4_src2_stride : stride of source 2 buffer
*
* @param[in] i4_blk_wd : block width
*
* @param[in] i4_blk_ht : block height
*
* @param[out] pu1_dst : destination buffer
*
* @param[in] i4_dst_stride : stride of the destination buffer
*
* @return void
********************************************************************************
*/
void hevc_avg_2d(
U08 *pu1_src1,
U08 *pu1_src2,
S32 i4_src1_stride,
S32 i4_src2_stride,
S32 i4_blk_wd,
S32 i4_blk_ht,
U08 *pu1_dst,
S32 i4_dst_stride);
/**
********************************************************************************
* @fn hme_pick_back_search_node(search_results_t *ps_search_results,
* search_node_t *ps_search_node_fwd,
* S32 i4_part_idx,
* layer_ctxt_t *ps_curr_layer)
*
*
* @brief returns the search node corresponding to a ref idx in same or
* opp direction. Preference is given to opp direction, but if that
* does not yield results, same direction is attempted.
*
* @param[in] ps_search_results: search results overall
*
* @param[in] ps_search_node_fwd: search node corresponding to "fwd" direction
*
* @param[in] i4_part_idx : partition id
*
* @param[in] ps_curr_layer : layer context for current layer.
*
* @return search node corresponding to hte "other direction"
********************************************************************************
*/
search_node_t *hme_pick_back_search_node(
search_results_t *ps_search_results,
search_node_t *ps_search_node_fwd,
S32 i4_part_idx,
layer_ctxt_t *ps_curr_layer);
/**
********************************************************************************
* @fn hme_study_input_segmentation(U08 *pu1_inp,
* S32 i4_inp_stride,
* S32 limit_active_partitions)
*
*
* @brief Examines input 16x16 for possible edges and orientations of those,
* and returns a bit mask of partitions that should be searched for
*
* @param[in] pu1_inp : input buffer
*
* @param[in] i4_inp_stride: input stride
*
* @param[in] limit_active_partitions : 1: Edge algo done and partitions are
* limited, 0 : Brute force, all partitions considered
*
* @return part mask (bit mask of active partitions to search)
********************************************************************************
*/
S32 hme_study_input_segmentation(U08 *pu1_inp, S32 i4_inp_stride, S32 limit_active_partitions);
/**
********************************************************************************
* @fn hme_init_search_results(search_results_t *ps_search_results,
* S32 i4_num_ref,
* S32 i4_num_best_results,
* S32 i4_num_results_per_part,
* BLK_SIZE_T e_blk_size,
* S32 i4_x_off,
* S32 i4_y_off)
*
* @brief Initializes the search results structure with some key attributes
*
* @param[out] ps_search_results : search results structure to initialise
*
* @param[in] i4_num_Ref: corresponds to the number of ref ids searched
*
* @param[in] i4_num_best_results: Number of best results for the CU to
* be maintained in the result structure
*
* @param[in] i4_num_results_per_part: Per active partition the number of best
* results to be maintained
*
* @param[in] e_blk_size: blk size of the CU for which this structure used
*
* @param[in] i4_x_off: x offset of the top left of CU from CTB top left
*
* @param[in] i4_y_off: y offset of the top left of CU from CTB top left
*
* @return void
********************************************************************************
*/
void hme_init_search_results(
search_results_t *ps_search_results,
S32 i4_num_ref,
S32 i4_num_best_results,
S32 i4_num_results_per_part,
BLK_SIZE_T e_blk_size,
S32 i4_x_off,
S32 i4_y_off,
U08 *pu1_is_past);
/**
********************************************************************************
* @fn hme_reset_search_results((search_results_t *ps_search_results,
* S32 i4_part_mask)
*
*
* @brief Resets the best results to maximum values, so as to allow search
* for the new CU's partitions. The existing results may be from an
* older CU using same structure.
*
* @param[in] ps_search_results: search results structure
*
* @param[in] i4_part_mask : bit mask of active partitions
*
* @param[in] mv_res : Resolution of the mv predictors (fpel/qpel)
*
* @return void
********************************************************************************
*/
void hme_reset_search_results(search_results_t *ps_search_results, S32 i4_part_mask, S32 mv_res);
/**
********************************************************************************
* @fn hme_clamp_grid_by_mvrange(search_node_t *ps_search_node,
* S32 i4_step,
* range_prms_t *ps_mvrange)
*
* @brief Given a central pt within mv range, and a grid of points surrounding
* this pt, this function returns a grid mask of pts within search rng
*
* @param[in] ps_search_node: the centre pt of the grid
*
* @param[in] i4_step: step size of grid
*
* @param[in] ps_mvrange: structure containing the current mv range
*
* @return bitmask of the pts in grid within search range
********************************************************************************
*/
S32 hme_clamp_grid_by_mvrange(search_node_t *ps_search_node, S32 i4_step, range_prms_t *ps_mvrange);
/**
********************************************************************************
* @fn layer_ctxt_t *hme_get_past_layer_ctxt(me_ctxt_t *ps_ctxt,
S32 i4_layer_id)
*
* @brief returns the layer ctxt of the layer with given id from the temporally
* previous frame
*
* @param[in] ps_ctxt : ME context
*
* @param[in] i4_layer_id : id of layer required
*
* @return layer ctxt of given layer id in temporally previous frame
********************************************************************************
*/
layer_ctxt_t *hme_get_past_layer_ctxt(
me_ctxt_t *ps_ctxt, me_frm_ctxt_t *ps_frm_ctxt, S32 i4_layer_id, S32 i4_num_me_frm_pllel);
layer_ctxt_t *hme_coarse_get_past_layer_ctxt(coarse_me_ctxt_t *ps_ctxt, S32 i4_layer_id);
/**
********************************************************************************
* @fn void hme_init_mv_bank(layer_ctxt_t *ps_layer_ctxt,
BLK_SIZE_T e_blk_size,
S32 i4_num_ref,
S32 i4_num_results_per_part)
*
* @brief Given a blk size to be used for this layer, this function initialize
* the mv bank to make it ready to store and return results.
*
* @param[in, out] ps_layer_ctxt: pointer to layer ctxt
*
* @param[in] e_blk_size : resolution at which mvs are stored
*
* @param[in] i4_num_ref: number of reference frames corresponding to which
* results are stored.
*
* @param[in] e_blk_size : resolution at which mvs are stored
*
* @param[in] i4_num_results_per_part : Number of results to be stored per
* ref idx. So these many best results stored
*
* @return void
********************************************************************************
*/
void hme_init_mv_bank(
layer_ctxt_t *ps_layer_ctxt,
BLK_SIZE_T e_blk_size,
S32 i4_num_ref,
S32 i4_num_results_per_part,
U08 u1_enc);
/**
********************************************************************************
* @fn void hme_derive_search_range(range_prms_t *ps_range,
* range_prms_t *ps_pic_limit,
* range_prms_t *ps_mv_limit,
* S32 i4_x,
* S32 i4_y,
* S32 blk_wd,
* S32 blk_ht)
*
* @brief given picture limits and blk dimensions and mv search limits, obtains
* teh valid search range such that the blk stays within pic boundaries,
* where picture boundaries include padded portions of picture
*
* @param[out] ps_range: updated with actual search range
*
* @param[in] ps_pic_limit : picture boundaries
*
* @param[in] ps_mv_limit: Search range limits for the mvs
*
* @param[in] i4_x : x coordinate of the blk
*
* @param[in] i4_y : y coordinate of the blk
*
* @param[in] blk_wd : blk width
*
* @param[in] blk_ht : blk height
*
* @return void
********************************************************************************
*/
void hme_derive_search_range(
range_prms_t *ps_range,
range_prms_t *ps_pic_limit,
range_prms_t *ps_mv_limit,
S32 i4_x,
S32 i4_y,
S32 blk_wd,
S32 blk_ht);
/**
********************************************************************************
* @fn void hme_get_spatial_candt(layer_ctxt_t *ps_curr_layer,
* BLK_SIZE_T e_search_blk_size,
* S32 blk_x,
* S32 blk_y,
* S08 i1_ref_idx,
* search_node_t *ps_top_neighbours,
* search_node_t *ps_left_neighbours,
* S32 i4_result_id);
*
* @brief Obtains top, top left, top right and left adn bottom left candts
*
* @param[in] ps_curr_layer: layer ctxt, has the mv bank structure pointer
*
* @param[in] e_search_blk_size : search blk size of current layer
*
* @param[in] i4_blk_x : x coordinate of the block in mv bank
*
* @param[in] i4_blk_y : y coordinate of the block in mv bank
*
* @param[in] i1_ref_idx : Corresponds to ref idx from which to pick up mv
* results, useful if multiple ref idx candts maintained separately.
*
* @param[out] ps_top_neighbours : T, TL, TR candts are output here
*
* @param[out] ps_left_neighbours : L BL candts outptu here
*
* @param[in] i4_result_id : If multiple results stored per ref idx, this
* pts to the id of the result
*
* @return void
********************************************************************************
*/
void hme_get_spatial_candt(
layer_ctxt_t *ps_curr_layer,
BLK_SIZE_T e_search_blk_size,
S32 blk_x,
S32 blk_y,
S08 i1_ref_idx,
search_node_t *ps_top_neighbours,
search_node_t *ps_left_neighbours,
S32 i4_result_id,
S32 i4_tr_avail,
S32 i4_bl_avail,
S32 encode);
void hme_get_spatial_candt_in_l1_me(
layer_ctxt_t *ps_curr_layer,
BLK_SIZE_T e_search_blk_size,
S32 i4_blk_x,
S32 i4_blk_y,
S08 i1_ref_idx,
U08 u1_pred_dir,
search_node_t *ps_top_neighbours,
search_node_t *ps_left_neighbours,
S32 i4_result_id,
S32 tr_avail,
S32 bl_avail,
S32 i4_num_act_ref_l0,
S32 i4_num_act_ref_l1);
/**
********************************************************************************
* @fn void hme_fill_ctb_neighbour_mvs(layer_ctxt_t *ps_curr_layer,
* S32 i4_blk_x,
* S32 i4_blk_y,
* mvgrid_t *ps_mv_grid ,
* S32 i1_ref_id)
*
* @brief The 18x18 MV grid for a ctb, is filled in first row and 1st col
* this corresponds to neighbours (TL, T, TR, L, BL)
*
* @param[in] ps_curr_layer: layer ctxt, has the mv bank structure pointer
*
* @param[in] blk_x : x coordinate of the block in mv bank
*
* @param[in] blk_y : y coordinate of the block in mv bank
*
* @param[in] ps_mv_grid : Grid (18x18 mvs at 4x4 level)
*
* @param[in] u1_pred_lx : Corresponds to pred dir from which to pick up mv
* results
*
* @return void
********************************************************************************
*/
void hme_fill_ctb_neighbour_mvs(
layer_ctxt_t *ps_curr_layer,
S32 blk_x,
S32 blk_y,
mv_grid_t *ps_mv_grid,
U08 u1_pred_dir_ctr,
U08 u1_default_ref_id,
S32 i4_num_act_ref_l0);
/**
********************************************************************************
* @fn void *hme_get_wkg_mem(buf_mgr_t *ps_buf_mgr, S32 i4_size)
*
* @brief Allocates a block of size = i4_size from working memory and returns
*
* @param[in,out] ps_buf_mgr: Buffer manager for wkg memory
*
* @param[in] i4_size : size required
*
* @return void pointer to allocated memory, NULL if failure
********************************************************************************
*/
void *hme_get_wkg_mem(buf_mgr_t *ps_buf_mgr, S32 i4_size);
void hme_reset_wkg_mem(buf_mgr_t *ps_buf_mgr);
void hme_init_wkg_mem(buf_mgr_t *ps_buf_mgr, U08 *pu1_mem, S32 size);
void hme_reset_ctb_mem_mgr(ctb_mem_mgr_t *ps_ctb_mem_mgr);
void hme_init_ctb_mem_mgr(ctb_mem_mgr_t *ps_ctb_mem_mgr, U08 *pu1_mem, S32 size);
void hme_fill_mvbank_intra(layer_ctxt_t *ps_layer_ctxt);
void hme_scale_mv_grid(mv_grid_t *ps_mv_grid);
void hme_downscale_mv_grid(mv_grid_t *ps_mv_grid);
void hme_create_parent_ctb(
ctb_node_t *ps_ctb_node_parent,
ctb_node_t *ps_ctb_child_tl,
ctb_node_t *ps_ctb_child_tr,
ctb_node_t *ps_ctb_child_bl,
ctb_node_t *ps_ctb_child_br,
CU_SIZE_T e_cu_size_parent,
buf_mgr_t *ps_buf_mgr);
void hme_create_merged_ctbs(
search_results_t *ps_results_merged,
ctb_mem_mgr_t *ps_ctb_mem_mgr,
buf_mgr_t *ps_buf_mgr,
ctb_node_t **pps_ctb_list_unified,
S32 num_candts);
void hme_init_mv_grid(mv_grid_t *ps_mv_grid);
typedef void (*pf_get_wt_inp)(
layer_ctxt_t *ps_curr_layer,
wgt_pred_ctxt_t *ps_wt_inp_prms,
S32 dst_stride,
S32 pos_x,
S32 pos_y,
S32 size,
S32 num_ref,
U08 u1_is_wt_pred_on);
/**
********************************************************************************
* @fn void hme_pad_left(U08 *pu1_dst, S32 stride, S32 pad_wd, S32 pad_ht)
*
* @brief Pads horizontally to left side. Each pixel replicated across a line
*
* @param[in] pu1_dst : destination pointer. Points to the pixel to be repeated
*
* @param[in] stride : stride of destination buffer
*
* @param[in] pad_wd : Amt of horizontal padding to be done
*
* @param[in] pad_ht : Number of lines for which horizontal padding to be done
*
* @return void
********************************************************************************
*/
void hme_pad_left(U08 *pu1_dst, S32 stride, S32 pad_wd, S32 pad_ht);
/**
********************************************************************************
* @fn void hme_pad_right(U08 *pu1_dst, S32 stride, S32 pad_wd, S32 pad_ht)
*
* @brief Pads horizontally to rt side. Each pixel replicated across a line
*
* @param[in] pu1_dst : destination pointer. Points to the pixel to be repeated
*
* @param[in] stride : stride of destination buffer
*
* @param[in] pad_wd : Amt of horizontal padding to be done
*
* @param[in] pad_ht : Number of lines for which horizontal padding to be done
*
* @return void
********************************************************************************
*/
void hme_pad_right(U08 *pu1_dst, S32 stride, S32 pad_wd, S32 pad_ht);
/**
********************************************************************************
* @fn void hme_pad_top(U08 *pu1_dst, S32 stride, S32 pad_ht, S32 pad_wd)
*
* @brief Pads vertically on the top. Repeats the top line for top padding
*
* @param[in] pu1_dst : destination pointer. Points to the line to be repeated
*
* @param[in] stride : stride of destination buffer
*
* @param[in] pad_ht : Amt of vertical padding to be done
*
* @param[in] pad_wd : Number of columns for which vertical padding to be done
*
* @return void
********************************************************************************
*/
void hme_pad_top(U08 *pu1_dst, S32 stride, S32 pad_ht, S32 pad_wd);
/**
********************************************************************************
* @fn void hme_pad_bot(U08 *pu1_dst, S32 stride, S32 pad_ht, S32 pad_wd)
*
* @brief Pads vertically on the bot. Repeats the top line for top padding
*
* @param[in] pu1_dst : destination pointer. Points to the line to be repeated
*
* @param[in] stride : stride of destination buffer
*
* @param[in] pad_ht : Amt of vertical padding to be done
*
* @param[in] pad_wd : Number of columns for which vertical padding to be done
*
* @return void
********************************************************************************
*/
void hme_pad_bot(U08 *pu1_dst, S32 stride, S32 pad_ht, S32 pad_wd);
/**
**************************************************************************************************
* @fn hme_populate_pus(search_results_t *ps_search_results, inter_cu_results_t *ps_cu_results)
*
* @brief Population the pu_results structure with the results after the subpel refinement
*
* This is called post subpel refinmenent for 16x16s, 8x8s and
* for post merge evaluation for 32x32,64x64 CUs
*
* @param[in,out] ps_search_results : Search results data structure
* - ps_cu_results : cu_results data structure
* ps_pu_result : Pointer to the memory for storing PU's
*
****************************************************************************************************
*/
void hme_populate_pus(
me_ctxt_t *ps_thrd_ctxt,
me_frm_ctxt_t *ps_ctxt,
hme_subpel_prms_t *ps_subpel_prms,
search_results_t *ps_search_results,
inter_cu_results_t *ps_cu_results,
inter_pu_results_t *ps_pu_results,
pu_result_t *ps_pu_result,
inter_ctb_prms_t *ps_inter_ctb_prms,
wgt_pred_ctxt_t *ps_wt_prms,
layer_ctxt_t *ps_curr_layer,
U08 *pu1_pred_dir_searched,
WORD32 i4_num_active_ref);
void hme_populate_pus_8x8_cu(
me_ctxt_t *ps_thrd_ctxt,
me_frm_ctxt_t *ps_ctxt,
hme_subpel_prms_t *ps_subpel_prms,
search_results_t *ps_search_results,
inter_cu_results_t *ps_cu_results,
inter_pu_results_t *ps_pu_results,
pu_result_t *ps_pu_result,
inter_ctb_prms_t *ps_inter_ctb_prms,
U08 *pu1_pred_dir_searched,
WORD32 i4_num_active_ref,
U08 u1_blk_8x8_mask);
S32 hme_recompute_lambda_from_min_8x8_act_in_ctb(
me_frm_ctxt_t *ps_ctxt, ipe_l0_ctb_analyse_for_me_t *ps_cur_ipe_ctb);
/**
********************************************************************************
* @fn hme_update_dynamic_search_params
*
* @brief Update the Dynamic search params based on the current MVs
*
* @param[in,out] ps_dyn_range_prms [inout] : Dyn. Range Param str.
* i2_mvy [in] : current MV y comp.
*
* @return None
********************************************************************************
*/
void hme_update_dynamic_search_params(dyn_range_prms_t *ps_dyn_range_prms, WORD16 i2_mvy);
S32 hme_create_child_nodes_cu_tree(
cur_ctb_cu_tree_t *ps_cu_tree_root,
cur_ctb_cu_tree_t *ps_cu_tree_cur_node,
S32 nodes_already_created);
void hme_add_new_node_to_a_sorted_array(
search_node_t *ps_result_node,
search_node_t **pps_sorted_array,
U08 *pu1_shifts,
U32 u4_num_results_updated,
U08 u1_shift);
S32 hme_find_pos_of_implicitly_stored_ref_id(
S08 *pi1_ref_idx, S08 i1_ref_idx, S32 i4_result_id, S32 i4_num_results);
S32 hme_populate_search_candidates(fpel_srch_cand_init_data_t *ps_ctxt);
void hme_init_pred_buf_info(
hme_pred_buf_info_t (*ps_info)[MAX_NUM_INTER_PARTS],
hme_pred_buf_mngr_t *ps_buf_mngr,
U08 u1_pu1_wd,
U08 u1_pu1_ht,
PART_TYPE_T e_part_type);
void hme_debrief_bipred_eval(
part_type_results_t *ps_part_type_result,
hme_pred_buf_info_t (*ps_pred_buf_info)[MAX_NUM_INTER_PARTS],
hme_pred_buf_mngr_t *ps_pred_buf_mngr,
U08 *pu1_allocated_pred_buf_array_indixes,
ihevce_cmn_opt_func_t *ps_cmn_utils_optimised_function_list);
U08 hme_decide_search_candidate_priority_in_l1_and_l2_me(
SEARCH_CANDIDATE_TYPE_T e_cand_type, ME_QUALITY_PRESETS_T e_quality_preset);
U08 hme_decide_search_candidate_priority_in_l0_me(SEARCH_CANDIDATE_TYPE_T e_cand_type, U08 u1_index);
void hme_search_cand_data_init(
S32 *pi4_id_Z,
S32 *pi4_id_coloc,
S32 *pi4_num_coloc_cands,
U08 *pu1_search_candidate_list_index,
S32 i4_num_act_ref_l0,
S32 i4_num_act_ref_l1,
U08 u1_is_bidir_enabled,
U08 u1_4x4_blk_in_l1me);
void hme_compute_variance_for_all_parts(
U08 *pu1_data,
S32 i4_data_stride,
S32 *pi4_valid_part_array,
U32 *pu4_variance,
S32 i4_num_valid_parts,
U08 u1_cu_size);
void hme_compute_sigmaX_and_sigmaXSquared(
U08 *pu1_data,
S32 i4_buf_stride,
void *pv_sigmaX,
void *pv_sigmaXSquared,
U08 u1_base_blk_wd,
U08 u1_base_blk_ht,
U08 u1_blk_wd,
U08 u1_blk_ht,
U08 u1_is_sigma_pointer_size_32_bit,
U08 u1_array_stride);
void hme_compute_final_sigma_of_pu_from_base_blocks(
U32 *pu4_SigmaX,
U32 *pu4_SigmaXSquared,
ULWORD64 *pu8_final_sigmaX,
ULWORD64 *pu8_final_sigmaX_Squared,
U08 u1_cu_size,
U08 u1_base_block_size,
S32 i4_part_id,
U08 u1_base_blk_array_stride);
void hme_compute_stim_injected_distortion_for_all_parts(
U08 *pu1_pred,
S32 i4_pred_stride,
S32 *pi4_valid_part_array,
ULWORD64 *pu8_src_sigmaX,
ULWORD64 *pu8_src_sigmaXSquared,
S32 *pi4_sad_array,
S32 i4_alpha_stim_multiplier,
S32 i4_inv_wt,
S32 i4_inv_wt_shift_val,
S32 i4_num_valid_parts,
S32 i4_wpred_log_wdc,
U08 u1_cu_size);
void sigma_for_cusize_16_and_baseblock_size_16(
U08 *pu1_data, S32 i4_data_stride, U32 *pu4_sigmaX, U32 *pu4_sigmaXSquared);
void sigma_for_cusize_16_and_baseblock_size_8(
U08 *pu1_data, S32 i4_data_stride, U32 *pu4_sigmaX, U32 *pu4_sigmaXSquared, U08 diff_cu_size);
void sigma_for_cusize_16_and_baseblock_size_4(
U08 *pu1_data, S32 i4_data_stride, U32 *pu4_sigmaX, U32 *pu4_sigmaXSquared);
void sigma_for_cusize_32_and_baseblock_size_32(
U08 *pu1_data, S32 i4_data_stride, U32 *pu4_sigmaX, U32 *pu4_sigmaXSquared);
void sigma_for_cusize_64_and_baseblock_size_64(
U08 *pu1_data, S32 i4_data_stride, U32 *pu4_sigmaX, U32 *pu4_sigmaXSquared);
void hme_choose_best_noise_preserver_amongst_fpel_and_subpel_winners(
fullpel_refine_ctxt_t *ps_fullpel_winner_data,
search_node_t **pps_part_results,
layer_ctxt_t *ps_curr_layer,
wgt_pred_ctxt_t *ps_wt_inp_prms,
U32 *pu4_src_variance,
S32 i4_cu_x_off_in_ctb,
S32 i4_cu_y_off_in_ctb,
S32 i4_ctb_x_off,
S32 i4_ctb_y_off,
S32 i4_inp_stride,
S32 i4_alpha_stim_multiplier,
U08 u1_subpel_uses_satd);
#if TEMPORAL_NOISE_DETECT
WORD32 ihevce_16x16block_temporal_noise_detect(
WORD32 had_block_size,
WORD32 ctb_width,
WORD32 ctb_height,
ihevce_ctb_noise_params *ps_ctb_noise_params,
fpel_srch_cand_init_data_t *s_proj_srch_cand_init_data,
hme_search_prms_t *s_search_prms_blk,
me_frm_ctxt_t *ps_ctxt,
WORD32 num_pred_dir,
WORD32 i4_num_act_ref_l0,
WORD32 i4_num_act_ref_l1,
WORD32 i4_cu_x_off,
WORD32 i4_cu_y_off,
wgt_pred_ctxt_t *ps_wt_inp_prms,
WORD32 input_stride,
WORD32 index_8x8_block,
WORD32 num_horz_blocks,
WORD32 num_8x8_in_ctb_row,
WORD32 i4_index_variance);
#endif
/**
********************************************************************************
* @fn hme_decide_part_types(search_results_t *ps_search_results)
*
* @brief Does uni/bi evaluation accross various partition types,
* decides best inter partition types for the CU, compares
* intra cost and decides the best K results for the CU
*
* This is called post subpel refinmenent for 16x16s, 8x8s and
* for post merge evaluation for 32x32,64x64 CUs
*
* @param[in,out] ps_search_results : Search results data structure
* - In : 2 lists of upto 2mvs & refids, active partition mask
* - Out: Best results for final rdo evaluation of the cu
*
* @param[in] ps_subpel_prms : Sub pel params data structure
*
* @par Description
* --------------------------------------------------------------------------------
* Flow:
* for each category (SMP,AMP,2Nx2N based on part mask)
* {
* for each part_type
* {
* for each part
* pick best candidate from each list
* combine uni part type
* update best results for part type
* }
* pick the best part type for given category (for SMP & AMP)
* }
* ||
* ||
* \/
* for upto 3 best part types
* {
* for each part
* {
* compute fixed size had for all uni and remember coeffs
* compute bisatd
* uni vs bi and gives upto two results
* also gives the pt level pred buffer
* }
* }
* ||
* ||
* \/
* select X candidates for tu recursion as per the Note below
* tu_rec_on_part_type (reuse transform coeffs)
* ||
* ||
* \/
* insert intra nodes at appropriate result id
* ||
* ||
* \/
* populate y best resuls for rdo based on preset
*
* Note :
* number of TU rec for P pics : 2 2nx2n + 1 smp + 1 amp for ms or 9 for hq
* number of TU rec for B pics : 1 2nx2n + 1 smp + 1 amp for ms or 2 uni 2nx2n + 1 smp + 1 amp for ms or 9 for hq
* --------------------------------------------------------------------------------
*
* @return None
********************************************************************************
*/
void hme_decide_part_types(
inter_cu_results_t *ps_cu_results,
inter_pu_results_t *ps_pu_results,
inter_ctb_prms_t *ps_inter_ctb_prms,
me_frm_ctxt_t *ps_ctxt,
ihevce_cmn_opt_func_t *ps_cmn_utils_optimised_function_list,
ihevce_me_optimised_function_list_t *ps_me_optimised_function_list);
void hme_compute_pred_and_evaluate_bi(
inter_cu_results_t *ps_cu_results,
inter_pu_results_t *ps_pu_results,
inter_ctb_prms_t *ps_inter_ctb_prms,
part_type_results_t *ps_part_type_result,
ULWORD64 *pu8_winning_pred_sigmaXSquare,
ULWORD64 *pu8_winning_pred_sigmaX,
ihevce_cmn_opt_func_t *ps_cmn_utils_optimised_function_list,
ihevce_me_optimised_function_list_t *ps_me_optimised_function_list);
/**
********************************************************************************
* @fn hme_insert_intra_nodes_post_bipred
*
* @brief Compares intra costs (populated by IPE) with the best inter costs
* (populated after evaluating bi-pred) and updates the best results
* if intra cost is better
*
* @param[in,out] ps_cu_results [inout] : Best results structure of CU
* ps_cur_ipe_ctb [in] : intra results for the current CTB
* i4_frm_qstep [in] : current frame quantizer(qscale)*
*
* @return None
********************************************************************************
*/
void hme_insert_intra_nodes_post_bipred(
inter_cu_results_t *ps_cu_results,
ipe_l0_ctb_analyse_for_me_t *ps_cur_ipe_ctb,
WORD32 i4_frm_qstep);
void hme_set_mv_limit_using_dvsr_data(
me_frm_ctxt_t *ps_ctxt,
layer_ctxt_t *ps_curr_layer,
range_prms_t *ps_mv_limit,
S16 *pi2_prev_enc_frm_max_mv_y,
U08 u1_num_act_ref_pics);
S32 hme_part_mask_populator(
U08 *pu1_inp,
S32 i4_inp_stride,
U08 u1_limit_active_partitions,
U08 u1_is_bPic,
U08 u1_is_refPic,
U08 u1_blk_8x8_mask,
ME_QUALITY_PRESETS_T e_me_quality_preset);
#endif /* #ifndef _HME_UTILS_H_ */