unplugged-system/external/libavc/decoder/svc/isvcd_residual_resamp.c

2649 lines
114 KiB
C
Raw Permalink Normal View History

/******************************************************************************
*
* Copyright (C) 2022 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
* isvcd_residual_resamp.c
*
* @brief
* Contains routines that resample for SVC resampling
*
* @author
* Kishore
*
* @par List of Functions:
* - isvcd_residual_chroma_dyadic_alt()
* - isvcd_residual_chroma_dyadic()
* - isvcd_residual_luma_dyadic()
* - isvcd_ref_layer_ptr_incr()
* - isvcd_residual_reflayer_const_non_boundary_mb()
* - isvcd_residual_reflayer_const_boundary_mb()
* - isvcd_residual_reflayer_const()
* - isvcd_interpolate_residual()
* - isvcd_residual_samp_mb()
* - isvcd_residual_samp_mb_dyadic()
* - isvcd_residual_samp_populate_list()
* - isvcd_residual_samp_res_init()
*
* @remarks
* None
*
*******************************************************************************
*/
#include <assert.h>
#include <string.h>
#include "ih264_typedefs.h"
#include "ih264_macros.h"
#include "ih264_platform_macros.h"
#include "ih264d_bitstrm.h"
#include "ih264d_defs.h"
#include "ih264d_debug.h"
#include "isvcd_structs.h"
#include "ih264d_defs.h"
#include "ih264d_parse_cavlc.h"
#include "ih264d_mb_utils.h"
#include "ih264d_deblocking.h"
#include "ih264d_dpb_manager.h"
#include "ih264d_mvpred.h"
#include "ih264d_inter_pred.h"
#include "ih264d_process_pslice.h"
#include "ih264d_error_handler.h"
#include "ih264d_cabac.h"
#include "ih264d_debug.h"
#include "ih264d_tables.h"
#include "ih264d_parse_slice.h"
#include "ih264d_utils.h"
#include "ih264d_parse_islice.h"
#include "ih264d_process_bslice.h"
#include "ih264d_process_intra_mb.h"
#include "ih264_debug.h"
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_chroma_dyadic_alt */
/* */
/* Description : this fucntion does the upsampling of chroma residuals for*/
/* Dyadic cases and specific chroma phase cases */
/* */
/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
/* pu1_inp_data : input 8 bit data pointer */
/* i4_inp_data_stride : input buffer stride */
/* pi2_out_res : output 16 bit buffer pointer */
/* i4_out_res_stride : Output buffer stride */
/* pu1_inp_bitmap : input packed sign bit data pointer */
/* i4_inp_bitmap_stride : sign bit buffer stride */
/* i4_start_bit_pos : bit position in the byte of packed */
/* sign values */
/* Globals : none */
/* Processing : it does the upsampling with intial phase values */
/* */
/* Outputs : Upsampled residuals for chroma */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 09 2021 vijayakumar creation */
/* */
/*****************************************************************************/
void isvcd_residual_chroma_dyadic_alt(void *pv_residual_samp_ctxt, UWORD16 u2_mb_x, UWORD16 u2_mb_y,
mem_element_t *ps_ref_mb_mode, WORD16 *pi2_inp_data,
WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
WORD32 i4_out_res_stride, WORD32 i4_cr_flag)
{
residual_sampling_ctxt_t *ps_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
/* ----------------- Processing ------------------------------- */
{
ref_pixel_map_t *ps_pos_phase;
residual_samp_map_ctxt_t *ps_chroma_map;
ref_mb_map_t *ps_x_off_len_chroma;
ref_mb_map_t *ps_y_off_len_chroma;
WORD32 i4_i;
WORD16 *pi2_ref_data_byte;
WORD32 *pi4_ref_array;
WORD32 i4_phase1, i4_phase2;
WORD32 i4_offset_x, i4_offset_y;
WORD32 i4_chrm_horz_int_mode, i4_chrm_vert_int_mode;
WORD32 i4_horz_intp_ctr = SUB_BLOCK_HEIGHT;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
/* get the actual offset for the buffers */
i4_offset_x = ps_x_off_len_chroma[u2_mb_x].i2_offset;
i4_offset_y = ps_y_off_len_chroma[u2_mb_y].i2_offset;
{
UWORD8 u1_mask;
WORD32 i4_mb_x, i4_mb_y;
WORD32 i4_chrm_nnz;
WORD32 i4_num_element_stride;
inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms, *ps_inter_lyr_mb_prms_curr;
u1_mask = (SVCD_TRUE == i4_cr_flag) ? 0xF0 : 0x0F;
/* Top Left */
i4_mb_x = i4_offset_x >> 3;
i4_mb_y = i4_offset_y >> 3;
/* get the location of the byte which has the current mb mode */
ps_inter_lyr_mb_prms = ps_ref_mb_mode->pv_buffer;
i4_num_element_stride = ps_ref_mb_mode->i4_num_element_stride;
ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
i4_chrm_nnz = ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
/* Top Right */
i4_mb_x = (i4_offset_x + 4) >> 3;
ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
/* Bottom Left */
i4_mb_x = i4_offset_x >> 3;
i4_mb_y = (i4_offset_y + 4) >> 3;
ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
/* Bottom Right */
i4_mb_x = (i4_offset_x + 4) >> 3;
ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
if(0 == i4_chrm_nnz)
{
return;
}
}
i4_chrm_horz_int_mode = ps_lyr_ctxt->i4_chrm_horz_int_mode;
i4_chrm_vert_int_mode = ps_lyr_ctxt->i4_chrm_vert_int_mode;
if(0 == i4_chrm_horz_int_mode)
{
if(i4_offset_x >= 0)
{
pi2_inp_data++;
}
}
if(0 == i4_chrm_vert_int_mode)
{
if(i4_offset_y >= 0)
{
pi2_inp_data += i4_inp_data_stride;
}
}
else
{
/* extra additional row of interpolation required for this case */
i4_horz_intp_ctr++;
}
/* ----------- Horizontal Interpolation ---------------- */
pi2_ref_data_byte = pi2_inp_data;
ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_pos_phase;
pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
i4_phase1 = ps_pos_phase[0].i2_phase;
i4_phase2 = (i4_phase1 + 8) & 0x0F;
/* interchange the phase values for corner case */
if(1 == i4_chrm_horz_int_mode)
{
WORD32 i4_temp;
i4_temp = i4_phase1;
i4_phase1 = i4_phase2;
i4_phase2 = i4_temp;
}
for(i4_i = 0; i4_i < i4_horz_intp_ctr; i4_i++)
{
WORD16 i2_coeff1, i2_coeff2;
i2_coeff1 = (WORD16) (pi2_ref_data_byte[0]);
if(0 == i4_chrm_horz_int_mode)
{
/* populate the first inter sample */
*pi4_ref_array++ = i2_coeff1 << 4;
}
/* unroll count 1 */
i2_coeff2 = (WORD16) (pi2_ref_data_byte[2]);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
*pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
/* unroll count 2 */
i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
*pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
/* unroll count 3 */
i2_coeff2 = (WORD16) (pi2_ref_data_byte[6]);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
*pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
/* populate the last inter sample */
*pi4_ref_array++ = i2_coeff2 << 4;
if(1 == i4_chrm_horz_int_mode)
{
i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
/* populate the last inter sample */
*pi4_ref_array++ = i2_coeff1 << 4;
}
/* vertical loop updates */
pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
}
/* ----------- Vertical Interpolation ---------------- */
pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_pos_phase;
i4_phase1 = ps_pos_phase[0].i2_phase;
i4_phase2 = (i4_phase1 + 8) & 0x0F;
/* interchange the phase values for corner case */
if(0 != i4_chrm_vert_int_mode)
{
WORD32 i4_temp;
i4_temp = i4_phase1;
i4_phase1 = i4_phase2;
i4_phase2 = i4_temp;
}
for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
{
WORD16 *pi2_out;
WORD32 *pi4_ref_array_temp;
WORD32 i4_horz_samp_1, i4_horz_samp_2;
pi2_out = pi2_out_res;
pi4_ref_array_temp = pi4_ref_array;
/* populate the first inter sample */
i4_horz_samp_1 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
if(1 != i4_chrm_vert_int_mode)
{
*pi2_out = (i4_horz_samp_1 + 8) >> 4;
pi2_out += i4_out_res_stride;
}
if(2 == i4_chrm_vert_int_mode)
{
i4_horz_samp_1 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
*pi2_out = (i4_horz_samp_1 + 8) >> 4;
pi2_out += i4_out_res_stride;
}
/* unroll count 1 */
i4_horz_samp_2 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
/* populate 2 samples based on current coeffs */
*pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 2 */
*pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 3 */
i4_horz_samp_1 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
/* populate 2 samples based on current coeffs */
*pi2_out = ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 4 */
*pi2_out = ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 5 */
i4_horz_samp_2 = *pi4_ref_array_temp;
/* populate 2 samples based on current coeffs */
*pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 6 */
*pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
if(2 != i4_chrm_vert_int_mode)
{
/* populate the last inter sample */
*pi2_out = (i4_horz_samp_2 + 8) >> 4;
if(1 == i4_chrm_vert_int_mode)
{
pi2_out += i4_out_res_stride;
pi4_ref_array_temp += BLOCK_WIDTH;
i4_horz_samp_1 = *pi4_ref_array_temp;
/* populate the last inter sample */
*pi2_out = (i4_horz_samp_1 + 8) >> 4;
}
}
/* horizontal loop updates */
pi4_ref_array++;
pi2_out_res += 2;
}
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_chroma_dyadic */
/* */
/* Description : this fucntion does the upsampling of chroma residuals for*/
/* Dyadic cases */
/* */
/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
/* pu1_inp_data : input 8 bit data pointer */
/* i4_inp_data_stride : input buffer stride */
/* pi2_out_res : output 16 bit buffer pointer */
/* i4_out_res_stride : Output buffer stride */
/* pu1_inp_bitmap : input packed sign bit data pointer */
/* i4_inp_bitmap_stride : sign bit buffer stride */
/* i4_start_bit_pos : bit position in the byte of packed */
/* sign values */
/* Globals : none */
/* Processing : it does the upsampling with intial phase values */
/* */
/* Outputs : Upsampled residuals for chroma */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 09 2021 vijayakumar creation */
/* */
/*****************************************************************************/
void isvcd_residual_chroma_dyadic(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
WORD32 i4_out_res_stride)
{
residual_sampling_ctxt_t *ps_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
/* ----------------- Processing ------------------------------- */
{
WORD32 i4_i;
WORD16 *pi2_ref_data_byte;
WORD32 *pi4_ref_array;
ref_pixel_map_t *ps_pos_phase;
WORD32 i4_phase1, i4_phase2;
pi2_ref_data_byte = pi2_inp_data;
ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_pos_phase;
/* ----------- Horizontal Interpolation ---------------- */
pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
i4_phase1 = ps_pos_phase[0].i2_phase;
i4_phase2 = (i4_phase1 + 8) & 0x0F;
for(i4_i = 0; i4_i < SUB_BLOCK_HEIGHT; i4_i++)
{
WORD16 i2_coeff1, i2_coeff2;
i2_coeff1 = (WORD16) (pi2_ref_data_byte[0]);
/* populate the first inter sample */
*pi4_ref_array++ = i2_coeff1 << 4;
/* unroll count 1 */
i2_coeff2 = (WORD16) (pi2_ref_data_byte[2]);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
/* unroll count 2 */
*pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
/* unroll count 3 */
i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
/* unroll count 4 */
*pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
/* unroll count 5 */
i2_coeff2 = (WORD16) (pi2_ref_data_byte[6]);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
/* unroll count 6 */
*pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
/* populate the last inter sample */
*pi4_ref_array++ = i2_coeff2 << 4;
/* vertical loop uopdates */
pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
}
/* ----------- Vertical Interpolation ---------------- */
pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_pos_phase;
i4_phase1 = ps_pos_phase[0].i2_phase;
i4_phase2 = (i4_phase1 + 8) & 0x0F;
for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
{
WORD16 *pi2_out;
WORD32 *pi4_ref_array_temp;
WORD32 i4_horz_samp_1, i4_horz_samp_2;
pi2_out = pi2_out_res;
pi4_ref_array_temp = pi4_ref_array;
/* populate the first inter sample */
i4_horz_samp_1 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
*pi2_out = (i4_horz_samp_1 + 8) >> 4;
pi2_out += i4_out_res_stride;
/* unroll count 1 */
i4_horz_samp_2 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
/* populate 2 samples based on current coeffs */
*pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 2 */
*pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 3 */
i4_horz_samp_1 = *pi4_ref_array_temp;
pi4_ref_array_temp += BLOCK_WIDTH;
/* populate 2 samples based on current coeffs */
*pi2_out = ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 4 */
*pi2_out = ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 5 */
i4_horz_samp_2 = *pi4_ref_array_temp;
/* populate 2 samples based on current coeffs */
*pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* unroll count 6 */
*pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
pi2_out += i4_out_res_stride;
/* populate the last inter sample */
*pi2_out = (i4_horz_samp_2 + 8) >> 4;
/* horizontal loop updates */
pi4_ref_array++;
pi2_out_res += 2;
}
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_luma_dyadic */
/* */
/* Description : this fucntion does the upsampling of luma residuals for */
/* Dyadic cases */
/* */
/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
/* pu1_inp_data : input 8 bit data pointer */
/* i4_inp_data_stride : input buffer stride */
/* pi2_out_res : output 16 bit buffer pointer */
/* i4_out_res_stride : Output buffer stride */
/* pu1_inp_bitmap : input packed sign bit data pointer */
/* i4_inp_bitmap_stride : sign bit buffer stride */
/* ps_ref_mb_mode : reference mb mode pointer of base layer */
/* ps_coord : mb co-ordinate pointer */
/* Globals : none */
/* Processing : it does the upsampling with fixed phase values and */
/* reference layer transform size */
/* Outputs : Upsampled residuals for luma */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 09 2021 vijayakumar creation */
/* */
/*****************************************************************************/
void isvcd_residual_luma_dyadic(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
WORD32 i4_out_res_stride, mem_element_t *ps_ref_mb_mode,
UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_ref_nnz,
WORD32 i4_ref_tx_size)
{
WORD16 *pi2_refarray_buffer;
WORD32 i4_blk_ctr;
residual_sampling_ctxt_t *ps_ctxt;
UNUSED(ps_ref_mb_mode);
UNUSED(u2_mb_x);
UNUSED(u2_mb_y);
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
pi2_refarray_buffer = ps_ctxt->pi2_refarray_buffer;
/* based on transform size the counter and interpolation width and */
/* height are intialised as follows */
if((i4_ref_tx_size) && (0 != i4_ref_nnz))
{
WORD16 *pi2_ref_data_byte;
WORD32 *pi4_ref_array;
WORD32 i4_i, i4_j;
pi2_ref_data_byte = pi2_inp_data;
/* ----------- Horizontal Interpolation ---------------- */
pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
for(i4_i = 0; i4_i < BLOCK_HEIGHT; i4_i++)
{
WORD16 i2_coeff1, i2_coeff2;
i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
/* populate the first inter sample */
*pi4_ref_array++ = i2_coeff1 << 2;
for(i4_j = 0; i4_j < 14; i4_j += 2)
{
i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
*pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
/* store the coeff 2 to coeff 1 */
/* (used in next iteration) */
i2_coeff1 = i2_coeff2;
}
/* populate the last inter sample */
*pi4_ref_array++ = i2_coeff1 << 2;
/* vertical loop uopdates */
pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
}
/* ----------- Vertical Interpolation ---------------- */
pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
for(i4_i = 0; i4_i < MB_WIDTH; i4_i++)
{
WORD32 *pi4_ref_array_temp;
WORD16 *pi2_out;
WORD32 i4_horz_samp_1, i4_horz_samp_2;
pi4_ref_array_temp = pi4_ref_array;
pi2_out = pi2_out_res;
i4_horz_samp_1 = *pi4_ref_array_temp;
/* populate the first inter sample */
*pi2_out = (i4_horz_samp_1 + 2) >> 2;
pi2_out += i4_out_res_stride;
for(i4_j = 0; i4_j < 14; i4_j += 2)
{
pi4_ref_array_temp += MB_WIDTH;
i4_horz_samp_2 = *pi4_ref_array_temp;
/* populate 2 samples based on current coeffs */
*pi2_out = ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
pi2_out += i4_out_res_stride;
*pi2_out = ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
pi2_out += i4_out_res_stride;
/* store the coeff 2 to coeff 1 */
/* (used in next iteration) */
i4_horz_samp_1 = i4_horz_samp_2;
}
/* populate the first inter sample */
*pi2_out = (i4_horz_samp_1 + 2) >> 2;
/* horizontal loop updates */
pi4_ref_array++;
pi2_out_res++;
}
}
else
{
/* ----------------------------------------------------------------- */
/* LOOP over number of blocks */
/* ----------------------------------------------------------------- */
for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
{
WORD16 *pi2_ref_data_byte;
WORD32 *pi4_ref_array;
WORD32 i4_i;
/* if reference layer is not coded then no processing */
if(0 != (i4_ref_nnz & 0x1))
{
pi2_ref_data_byte = pi2_inp_data;
/* ----------- Horizontal Interpolation ---------------- */
pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
for(i4_i = 0; i4_i < SUB_BLOCK_HEIGHT; i4_i++)
{
WORD16 i2_coeff1, i2_coeff2;
i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
/* populate the first inter sample */
*pi4_ref_array++ = i2_coeff1 << 2;
i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
*pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
*pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
/* populate 2 samples based on current coeffs */
*pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
*pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
/* populate the last inter sample */
*pi4_ref_array++ = i2_coeff2 << 2;
/* vertical loop uopdates */
pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
}
/* ----------- Vertical Interpolation ---------------- */
pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
{
WORD32 *pi4_ref_array_temp;
WORD16 *pi2_out;
WORD32 i4_horz_samp_1, i4_horz_samp_2;
pi4_ref_array_temp = pi4_ref_array;
pi2_out = pi2_out_res;
i4_horz_samp_1 = *pi4_ref_array_temp;
/* populate the first inter sample */
*pi2_out = (i4_horz_samp_1 + 2) >> 2;
pi2_out += i4_out_res_stride;
/* unroll loop count 1 */
pi4_ref_array_temp += BLOCK_WIDTH;
i4_horz_samp_2 = *pi4_ref_array_temp;
/* populate 2 samples based on current coeffs */
*pi2_out =
((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
pi2_out += i4_out_res_stride;
*pi2_out =
((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
pi2_out += i4_out_res_stride;
/* unroll loop count 2 */
pi4_ref_array_temp += BLOCK_WIDTH;
i4_horz_samp_1 = *pi4_ref_array_temp;
/* populate 2 samples based on current coeffs */
*pi2_out =
((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
pi2_out += i4_out_res_stride;
*pi2_out =
((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
pi2_out += i4_out_res_stride;
/* unroll loop count 3 */
pi4_ref_array_temp += BLOCK_WIDTH;
i4_horz_samp_2 = *pi4_ref_array_temp;
/* populate 2 samples based on current coeffs */
*pi2_out =
((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
pi2_out += i4_out_res_stride;
*pi2_out =
((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
pi2_out += i4_out_res_stride;
/* populate the last inter sample */
*pi2_out = (i4_horz_samp_2 + 2) >> 2;
/* horizontal loop updates */
pi4_ref_array++;
pi2_out_res++;
}
}
else
{
pi2_out_res += BLOCK_WIDTH;
}
/* Block level loop updates */
if(1 == i4_blk_ctr)
{
pi2_inp_data -= SUB_BLOCK_WIDTH;
pi2_inp_data += (i4_inp_data_stride * SUB_BLOCK_HEIGHT);
pi2_out_res -= MB_WIDTH;
pi2_out_res += (i4_out_res_stride * BLOCK_HEIGHT);
i4_ref_nnz >>= 2;
}
else
{
pi2_inp_data += SUB_BLOCK_WIDTH;
}
i4_ref_nnz >>= 1;
} /* end of loop over all the blocks */
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_ref_layer_ptr_incr */
/* */
/* Description : this function returns the pointer increments for */
/* the operand2 of the bilinear interpolation */
/* Inputs : pi1_ref_mb_modes : reference mb modes */
/* i4_ref_mode_stride : mb mode buffer stride */
/* i4_element_size : size of reference mb mode */
/* i4_x_offset : ref offset x */
/* i4_y_offset : ref offset y */
/* i4_refary_wd : reference array width */
/* i4_refary_ht : reference array height */
/* pu1_ref_x_ptr_incr : ptr increment buffer for x */
/* pu1_ref_y_ptr_incr : ptr increment buffer for y */
/* i4_chroma_flag : chroma processing flag */
/* Globals : none */
/* Processing : it calculates the increment as per the transform size */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 18 08 2021 Kishore creation */
/* */
/*****************************************************************************/
WORD32 isvcd_ref_layer_ptr_incr(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
WORD32 i4_element_size, WORD32 i4_x_offset, WORD32 i4_y_offset,
WORD32 i4_refary_wd, WORD32 i4_refary_ht,
UWORD8 *pu1_ref_x_ptr_incr, UWORD8 *pu1_ref_y_ptr_incr,
WORD32 i4_chroma_flag)
{
WORD32 i4_x, i4_y;
WORD32 i4_x_idx, i4_y_idx;
WORD32 i4_prev_x, i4_prev_y;
WORD32 i4_const_val;
WORD32 i4_pos_x, i4_pos_y;
WORD32 i4_trans_size;
WORD32 i4_act_ary_wd, i4_act_ary_ht;
WORD32 i4_and_const;
UWORD8 *pu1_incr_x, *pu1_incr_y;
WORD32 i4_mb_sft;
WORD32 i4_mb_x, i4_mb_y;
WORD8 *pi1_ref_mb_modes_incr;
WORD8 *pi1_ref_mb_modes_incr_temp;
inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
WORD32 i4_mb_x_strt, i4_mb_y_strt;
WORD32 i4_mb_quard1_part_x, i4_mb_quard1_part_y;
WORD32 i4_x_ref, i4_y_ref;
WORD32 i4_tx_size, i4_tx_size_q0, i4_tx_size_q1, i4_tx_size_q2, i4_tx_size_q3;
WORD8 i1_mb_mode_q0, i1_mb_mode_q1, i1_mb_mode_q2, i1_mb_mode_q3;
WORD32 i4_mb_wd;
WORD32 i4_mb_ht;
i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
/* Memset to 1 the increment buffers */
memset(pu1_ref_x_ptr_incr, 1, (i4_refary_wd * i4_refary_ht));
memset(pu1_ref_y_ptr_incr, 1, (i4_refary_wd * i4_refary_ht));
/* Initialise actual width and height */
i4_act_ary_wd = i4_refary_wd;
i4_act_ary_ht = i4_refary_ht;
/* Initialize x and y */
i4_x = 0;
i4_y = 0;
i4_prev_y = 0;
i4_mb_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
/* Loop over all MBs in the reference array */
if(0 == i4_chroma_flag)
{
i4_x_ref = i4_x_offset + 0;
i4_y_ref = i4_y_offset + 0;
i4_mb_x_strt = i4_x_ref % i4_mb_wd;
i4_mb_y_strt = i4_y_ref % i4_mb_ht;
i4_mb_quard1_part_x = i4_mb_wd - i4_mb_x_strt;
i4_mb_quard1_part_y = i4_mb_ht - i4_mb_y_strt;
if(!(i4_mb_quard1_part_x >= 0))
{
return NOT_OK;
}
if(!(i4_mb_quard1_part_y >= 0))
{
return NOT_OK;
}
/* Take care of negative offsets */
if(i4_x_ref > 0)
{
i4_mb_x = (i4_x_ref >> i4_mb_sft);
}
else
{
i4_mb_x = 0;
}
if(i4_y_ref > 0)
{
i4_mb_y = (i4_y_ref >> i4_mb_sft);
}
else
{
i4_mb_y = 0;
}
/* get the location of the byte which has the current mb mode */
pi1_ref_mb_modes_incr = pi1_ref_mb_modes + (i4_mb_y * i4_ref_mode_stride * i4_element_size);
pi1_ref_mb_modes_incr += (i4_mb_x * i4_element_size);
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr;
i1_mb_mode_q0 = ps_inter_lyr_mb_prms->i1_mb_mode;
i4_tx_size_q0 =
(i1_mb_mode_q0 <= SVC_INTER_MB)
? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1 : ps_inter_lyr_mb_prms->i1_tx_size)
: 1;
pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr;
if(i4_mb_quard1_part_x > 0)
{
pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr + i4_element_size;
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
i1_mb_mode_q1 = ps_inter_lyr_mb_prms->i1_mb_mode;
i4_tx_size_q1 =
(i1_mb_mode_q1 <= SVC_INTER_MB)
? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1
: ps_inter_lyr_mb_prms->i1_tx_size)
: 1;
}
if(i4_mb_quard1_part_y > 0)
{
pi1_ref_mb_modes_incr_temp =
pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size);
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
i1_mb_mode_q2 = ps_inter_lyr_mb_prms->i1_mb_mode;
i4_tx_size_q2 =
(i1_mb_mode_q2 <= SVC_INTER_MB)
? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1
: ps_inter_lyr_mb_prms->i1_tx_size)
: 1;
}
if((i4_mb_quard1_part_x > 0) && (i4_mb_quard1_part_y > 0))
{
pi1_ref_mb_modes_incr_temp =
pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size) + i4_element_size;
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
i1_mb_mode_q3 = ps_inter_lyr_mb_prms->i1_mb_mode;
i4_tx_size_q3 =
(i1_mb_mode_q3 <= SVC_INTER_MB)
? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1
: ps_inter_lyr_mb_prms->i1_tx_size)
: 1;
}
do
{
WORD32 i4_idx;
WORD32 i4_wd, i4_ht;
WORD32 i4_max_pos_x, i4_max_pos_y;
i4_prev_x = i4_x;
i4_x_ref = i4_x_offset + i4_x;
i4_y_ref = i4_y_offset + i4_y;
i4_tx_size = i4_tx_size_q0;
if(i4_x >= i4_mb_quard1_part_x)
{
if(i4_y < i4_mb_quard1_part_y)
{
i4_tx_size = i4_tx_size_q1;
}
else if(i4_y >= i4_mb_quard1_part_y)
{
i4_tx_size = i4_tx_size_q3;
}
}
else if(i4_x < i4_mb_quard1_part_x)
{
if(i4_y >= i4_mb_quard1_part_y)
{
i4_tx_size = i4_tx_size_q2;
}
}
/* Get the transform size as 4 or 8 */
i4_trans_size = ((i4_tx_size + 1) << 2);
i4_const_val = i4_trans_size - 1;
i4_and_const = i4_const_val;
/* Fill horizontal tx block edges of current reference mb with 0 */
pu1_incr_x = pu1_ref_x_ptr_incr + i4_x;
pu1_incr_x += (i4_y * i4_refary_wd);
i4_ht = (16 - (i4_y_ref & 0xF));
i4_ht = MIN((i4_act_ary_ht - i4_y), i4_ht);
i4_x_idx = i4_x;
i4_pos_x = i4_x_ref & 0xF;
i4_max_pos_x = 16;
i4_x += (16 - i4_pos_x);
/* Get the transform block edge pos */
i4_idx = (i4_const_val - (i4_pos_x & i4_and_const));
i4_x_idx += i4_idx;
while((i4_pos_x < i4_max_pos_x) && (i4_x_idx < i4_act_ary_wd))
{
WORD32 i4_i;
UWORD8 *pu1_incr;
pu1_incr = pu1_incr_x + i4_idx;
for(i4_i = 0; i4_i < i4_ht; i4_i++)
{
/* Fill the block edge with 0s */
*pu1_incr = 0;
pu1_incr += i4_refary_wd;
}
/* Updates */
i4_pos_x += i4_trans_size;
pu1_incr_x += i4_trans_size;
i4_x_idx += MIN(i4_trans_size, (i4_act_ary_wd - i4_x_idx));
}
/* Fill vertical tx block edges of current reference mb with 0 */
pu1_incr_y = pu1_ref_y_ptr_incr + i4_prev_x;
pu1_incr_y += (i4_y * i4_refary_wd);
i4_wd = (16 - (i4_x_ref & 0xF));
i4_wd = MIN((i4_act_ary_wd - i4_prev_x), i4_wd);
i4_y_idx = i4_y;
i4_pos_y = i4_y_ref & 0xF;
i4_max_pos_y = 16;
i4_y += (16 - i4_pos_y);
/* Get the transform block edge pos */
i4_idx = (i4_const_val - (i4_pos_y & i4_and_const));
i4_y_idx += i4_idx;
while((i4_pos_y < i4_max_pos_y) && (i4_y_idx < i4_act_ary_ht))
{
WORD32 i4_i;
UWORD8 *pu1_incr;
pu1_incr = pu1_incr_y + i4_idx * i4_refary_wd;
for(i4_i = 0; i4_i < i4_wd; i4_i++)
{
/* Fill the block edge with 0s */
*pu1_incr = 0;
pu1_incr++;
}
/* Updates */
i4_pos_y += i4_trans_size;
pu1_incr_y += i4_trans_size * i4_refary_wd;
i4_y_idx += MIN(i4_trans_size, (i4_act_ary_ht - i4_y_idx));
}
/* Loop updates */
if(i4_x < i4_act_ary_wd)
{
i4_y = i4_prev_y;
}
else if(i4_y < i4_act_ary_ht)
{
i4_prev_y = i4_y;
i4_x = 0;
}
} while((i4_y < i4_act_ary_ht) || (i4_x < i4_act_ary_wd));
} /* End of if 0 == i4_chroma_flag */
else
{
/* Set the transform size as 4 */
i4_trans_size = 4;
i4_const_val = 3;
do
{
WORD32 i4_x_ref, i4_y_ref;
WORD32 i4_idx;
WORD32 i4_wd, i4_ht;
WORD32 i4_max_pos_x, i4_max_pos_y;
i4_prev_x = i4_x;
i4_x_ref = i4_x_offset + i4_x;
i4_y_ref = i4_y_offset + i4_y;
/* Fill horizontal tx block edges of current reference mb with 0 */
pu1_incr_x = pu1_ref_x_ptr_incr + i4_x;
pu1_incr_x += (i4_y * i4_refary_wd);
i4_ht = (8 - (i4_y_ref & 0x7));
i4_ht = MIN((i4_act_ary_ht - i4_y), i4_ht);
i4_x_idx = i4_x;
i4_pos_x = i4_x_ref & 0x7;
i4_max_pos_x = 8;
i4_x += (8 - i4_pos_x);
/* Get the transform block edge pos */
i4_idx = (i4_const_val - (i4_pos_x & 0x3));
i4_x_idx += i4_idx;
while((i4_pos_x < i4_max_pos_x) && (i4_x_idx < i4_act_ary_wd))
{
WORD32 i4_i;
UWORD8 *pu1_incr;
pu1_incr = pu1_incr_x + i4_idx;
for(i4_i = 0; i4_i < i4_ht; i4_i++)
{
/* Fill the block edge with 0s */
*pu1_incr = 0;
pu1_incr += i4_refary_wd;
}
/* Updates */
i4_pos_x += i4_trans_size;
pu1_incr_x += i4_trans_size;
i4_x_idx += MIN(i4_trans_size, (i4_act_ary_wd - i4_x_idx));
}
/* Fill vertical tx block edges of current reference mb with 0 */
pu1_incr_y = pu1_ref_y_ptr_incr + i4_prev_x;
pu1_incr_y += (i4_y * i4_refary_wd);
i4_wd = (8 - (i4_x_ref & 0x7));
i4_wd = MIN((i4_act_ary_wd - i4_prev_x), i4_wd);
i4_y_idx = i4_y;
i4_pos_y = i4_y_ref & 0x7;
i4_max_pos_y = 8;
i4_y += (8 - i4_pos_y);
/* Get the transform block edge pos */
i4_idx = (i4_const_val - (i4_pos_y & 0x3));
i4_y_idx += i4_idx;
while((i4_pos_y < i4_max_pos_y) && (i4_y_idx < i4_act_ary_ht))
{
WORD32 i4_i;
UWORD8 *pu1_incr;
pu1_incr = pu1_incr_y + i4_idx * i4_refary_wd;
for(i4_i = 0; i4_i < i4_wd; i4_i++)
{
/* Fill the block edge with 0s */
*pu1_incr = 0;
pu1_incr++;
}
/* Updates */
i4_pos_y += i4_trans_size;
pu1_incr_y += i4_trans_size * i4_refary_wd;
i4_y_idx += MIN(i4_trans_size, (i4_act_ary_ht - i4_y_idx));
}
/* Loop updates */
if(i4_x < i4_act_ary_wd)
{
i4_y = i4_prev_y;
}
else if(i4_y < i4_act_ary_ht)
{
i4_prev_y = i4_y;
i4_x = 0;
}
} while((i4_y < i4_act_ary_ht) || (i4_x < i4_act_ary_wd));
} /* End of chroma */
return OK;
} /* End of "isvcd_ref_layer_ptr_incr" */
void isvcd_residual_reflayer_const_non_boundary_mb(
WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride, WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
WORD32 i4_refarray_ht, WORD32 i4_ref_mb_type_q0, WORD32 i4_ref_mb_type_q1,
WORD32 i4_ref_mb_type_q2, WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag)
{
WORD32 i4_x_ref, i4_y_ref;
WORD32 i4_x, i4_y;
WORD32 i4_ref_mb_type;
WORD16 *pi2_ref_data_byte;
WORD16 *pi2_ref_array_temp;
for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
{
for(i4_x = 0; i4_x < i4_refarray_wd; i4_x++)
{
i4_y_ref = i4_y;
i4_x_ref = i4_x;
i4_ref_mb_type = i4_ref_mb_type_q0;
if(i4_x >= i4_mb_quard1_part_x)
{
if(i4_y < i4_mb_quard1_part_y)
{
i4_ref_mb_type = i4_ref_mb_type_q1;
}
else if(i4_y >= i4_mb_quard1_part_y)
{
i4_ref_mb_type = i4_ref_mb_type_q3;
}
}
else if(i4_x < i4_mb_quard1_part_x)
{
if(i4_y >= i4_mb_quard1_part_y)
{
i4_ref_mb_type = i4_ref_mb_type_q2;
}
}
/****************************************************************/
/* Reference layer Residual Buffer is maintained as 8-bit data */
/* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
/* and sign of the data sample is extracted depending upon bit */
/* postition. */
/****************************************************************/
/* update the buffer pointers to appropriate locations */
pi2_ref_array_temp = pi2_ref_array + i4_x;
pi2_ref_array_temp += i4_y * i4_refarray_wd;
/* extract the residual value and fill the buffer */
if(SVC_INTER_MB == i4_ref_mb_type)
{
/* derive the reference data pointers */
pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
/* store the residual value */
*pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
}
else
{
/* if non inter MB then store the 0 */
*pi2_ref_array_temp = 0;
}
}
}
}
void isvcd_residual_reflayer_const_boundary_mb(WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride,
WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
WORD32 i4_refarray_ht, WORD32 i4_ref_wd,
WORD32 i4_ref_ht, WORD32 i4_x_offset,
WORD32 i4_y_offset, WORD32 i4_ref_mb_type_q0,
WORD32 i4_ref_mb_type_q1, WORD32 i4_ref_mb_type_q2,
WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag)
{
WORD32 i4_x_ref, i4_y_ref;
WORD32 i4_x, i4_y;
WORD16 *pi2_ref_data_byte;
WORD16 *pi2_ref_array_temp;
/*Quard 0*/
for(i4_y = 0; i4_y < i4_mb_quard1_part_y; i4_y++)
{
for(i4_x = 0; i4_x < i4_mb_quard1_part_x; i4_x++)
{
i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
/****************************************************************/
/* Reference layer Residual Buffer is maintained as 8-bit data */
/* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
/* and sign of the data sample is extracted depending upon bit */
/* postition. */
/****************************************************************/
/* update the buffer pointers to appropriate locations */
pi2_ref_array_temp = pi2_ref_array + i4_x;
pi2_ref_array_temp += i4_y * i4_refarray_wd;
/* extract the residual value and fill the buffer */
if(SVC_INTER_MB == i4_ref_mb_type_q0)
{
/* input pointer will be pointing to (xoffset,yoffset) */
/* So subtract the correction to reference location */
if(0 <= i4_x_offset)
{
/* if only inside frame dimension */
i4_x_ref = i4_x_ref - i4_x_offset;
}
if(0 <= i4_y_offset)
{
/* if only inside frame dimension */
i4_y_ref = i4_y_ref - i4_y_offset;
}
/* derive the reference data pointers */
pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
/* store the residual value */
*pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
}
else
{
/* if non inter MB then store the 0 */
*pi2_ref_array_temp = 0;
}
}
}
/*Quard 1*/
for(i4_y = 0; i4_y < i4_mb_quard1_part_y; i4_y++)
{
for(i4_x = i4_mb_quard1_part_x; i4_x < i4_refarray_wd; i4_x++)
{
i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
/****************************************************************/
/* Reference layer Residual Buffer is maintained as 8-bit data */
/* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
/* and sign of the data sample is extracted depending upon bit */
/* postition. */
/****************************************************************/
/* update the buffer pointers to appropriate locations */
pi2_ref_array_temp = pi2_ref_array + i4_x;
pi2_ref_array_temp += i4_y * i4_refarray_wd;
/* extract the residual value and fill the buffer */
if(SVC_INTER_MB == i4_ref_mb_type_q1)
{
/* input pointer will be pointing to (xoffset,yoffset) */
/* So subtract the correction to reference location */
if(0 <= i4_x_offset)
{
/* if only inside frame dimension */
i4_x_ref = i4_x_ref - i4_x_offset;
}
if(0 <= i4_y_offset)
{
/* if only inside frame dimension */
i4_y_ref = i4_y_ref - i4_y_offset;
}
/* derive the reference data pointers */
pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
/* store the residual value */
*pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
}
else
{
/* if non inter MB then store the 0 */
*pi2_ref_array_temp = 0;
}
}
}
/*Quard 2*/
for(i4_y = i4_mb_quard1_part_y; i4_y < i4_refarray_ht; i4_y++)
{
for(i4_x = 0; i4_x < i4_mb_quard1_part_x; i4_x++)
{
i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
/****************************************************************/
/* Reference layer Residual Buffer is maintained as 8-bit data */
/* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
/* and sign of the data sample is extracted depending upon bit */
/* postition. */
/****************************************************************/
/* update the buffer pointers to appropriate locations */
pi2_ref_array_temp = pi2_ref_array + i4_x;
pi2_ref_array_temp += i4_y * i4_refarray_wd;
/* extract the residual value and fill the buffer */
if(SVC_INTER_MB == i4_ref_mb_type_q2)
{
/* input pointer will be pointing to (xoffset,yoffset) */
/* So subtract the correction to reference location */
if(0 <= i4_x_offset)
{
/* if only inside frame dimension */
i4_x_ref = i4_x_ref - i4_x_offset;
}
if(0 <= i4_y_offset)
{
/* if only inside frame dimension */
i4_y_ref = i4_y_ref - i4_y_offset;
}
/* derive the reference data pointers */
pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
/* store the residual value */
*pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
}
else
{
/* if non inter MB then store the 0 */
*pi2_ref_array_temp = 0;
}
}
}
/*Quard 3*/
for(i4_y = i4_mb_quard1_part_y; i4_y < i4_refarray_ht; i4_y++)
{
for(i4_x = i4_mb_quard1_part_x; i4_x < i4_refarray_wd; i4_x++)
{
i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
/****************************************************************/
/* Reference layer Residual Buffer is maintained as 8-bit data */
/* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
/* and sign of the data sample is extracted depending upon bit */
/* postition. */
/****************************************************************/
/* update the buffer pointers to appropriate locations */
pi2_ref_array_temp = pi2_ref_array + i4_x;
pi2_ref_array_temp += i4_y * i4_refarray_wd;
/* extract the residual value and fill the buffer */
if(SVC_INTER_MB == i4_ref_mb_type_q3)
{
/* input pointer will be pointing to (xoffset,yoffset) */
/* So subtract the correction to reference location */
if(0 <= i4_x_offset)
{
/* if only inside frame dimension */
i4_x_ref = i4_x_ref - i4_x_offset;
}
if(0 <= i4_y_offset)
{
/* if only inside frame dimension */
i4_y_ref = i4_y_ref - i4_y_offset;
}
/* derive the reference data pointers */
pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
/* store the residual value */
*pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
}
else
{
/* if non inter MB then store the 0 */
*pi2_ref_array_temp = 0;
}
}
}
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_reflayer_const */
/* */
/* Description : This function constructs the reference array buffer */
/* used for residual resampling of a component in an MB */
/* */
/* Inputs : pv_residual_samp_ctxt: intra sampling context */
/* pu1_inp : input (reference layer data) */
/* i4_inp_stride : input buffer stride */
/* pu1_inp_bitmap : input (reference layer sign bits) */
/* i4_inp_stride : input buffer stride */
/* ps_ref_mb_mode : ref layer mb mode buffer desc */
/* pi4_refarr_wd : pointer to store the reference array WD */
/* pi4_refarr_ht : pointer to store the reference array HT */
/* pi4_x_offset : pointer to store the reference X offset */
/* pi4_y_offset : pointer to store the reference Y offset */
/* ps_coord : mb co-ordinate structure */
/* i4_chroma_flag : chroma processing flag */
/* Globals : none */
/* Processing : it fills the reference layer data if they are falling in */
/* INTRA MB region. If all the pixels are not filled it */
/* calls the border extension algorithm to fill them */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 07 2021 vijayakumar creation */
/* */
/*****************************************************************************/
WORD32 isvcd_residual_reflayer_const(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
WORD32 i4_inp_data_stride, mem_element_t *ps_ref_mb_mode,
WORD32 *pi4_refarr_wd, mb_coord_t *ps_coord,
WORD32 i4_chroma_flag)
{
residual_sampling_ctxt_t *ps_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
WORD8 *pi1_ref_mb_modes;
WORD32 i4_ref_mode_stride;
WORD32 i4_element_size;
WORD32 i4_ref_wd;
WORD32 i4_ref_ht;
WORD32 i4_x_offset;
WORD32 i4_y_offset;
WORD32 i4_refarray_wd;
WORD32 i4_refarray_ht;
WORD8 i1_edge_mb;
WORD16 *pi2_ref_array;
WORD32 i4_mb_sft;
WORD32 i4_mb_x, i4_mb_y;
WORD32 i4_mb_x_strt, i4_mb_y_strt;
WORD32 i4_mb_quard1_part_x, i4_mb_quard1_part_y;
WORD8 *pi1_ref_mb_modes_incr;
WORD8 *pi1_ref_mb_modes_incr_temp;
inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
WORD32 i4_mb_wd;
WORD32 i4_mb_ht;
WORD32 i4_x_ref, i4_y_ref;
WORD32 i4_ref_mb_type_q0, i4_ref_mb_type_q1, i4_ref_mb_type_q2, i4_ref_mb_type_q3;
WORD8 i1_mb_mode_q0, i1_mb_mode_q1, i1_mb_mode_q2, i1_mb_mode_q3;
WORD32 ret;
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
pi2_ref_array = ps_ctxt->pi2_refarray_buffer;
pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode->pv_buffer;
i4_ref_mode_stride = ps_ref_mb_mode->i4_num_element_stride;
i4_element_size = ps_ref_mb_mode->i4_element_size;
if(NULL == pi1_ref_mb_modes)
{
return NOT_OK;
}
i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
/* ----------------------------------------------------------------- */
/* Deriving the parameters required for further processing */
/* ----------------------------------------------------------------- */
{
ref_mb_map_t *ps_x_off_len;
ref_mb_map_t *ps_y_off_len;
WORD32 i4_mbaddr_x;
WORD32 i4_mbaddr_y;
WORD32 i4_base_width;
WORD32 i4_base_height;
residual_samp_map_ctxt_t *ps_map_ctxt;
if(1 == i4_chroma_flag)
ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
else
ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
i4_mbaddr_y = ps_coord->u2_mb_y;
i4_mbaddr_x = ps_coord->u2_mb_x;
i4_base_width = ps_lyr_ctxt->i4_ref_width;
i4_base_height = ps_lyr_ctxt->i4_ref_height;
i4_ref_wd = i4_base_width >> i4_chroma_flag;
i4_ref_ht = i4_base_height >> i4_chroma_flag;
/* --------------------------------------------------------------------- */
/* Extracting information from the mapping context */
/* --------------------------------------------------------------------- */
ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
i4_x_offset = ps_x_off_len[i4_mbaddr_x].i2_offset;
i4_y_offset = ps_y_off_len[i4_mbaddr_y].i2_offset;
i4_refarray_wd = ps_x_off_len[i4_mbaddr_x].i2_length;
i4_refarray_ht = ps_y_off_len[i4_mbaddr_y].i2_length;
}
/* Call the module to fill the increments based on transform blocks */
ret = isvcd_ref_layer_ptr_incr(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
i4_x_offset, i4_y_offset, i4_refarray_wd, i4_refarray_ht,
ps_ctxt->pu1_ref_x_ptr_incr, ps_ctxt->pu1_ref_y_ptr_incr,
i4_chroma_flag);
if(ret != OK)
{
return ret;
}
i4_mb_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
/* --------------------------------------------------------------------- */
/* MB Level Resampling for the MB - Pointers sent for MB in both layers */
/* This has been written according to the dyadic case */
/* --------------------------------------------------------------------- */
i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, 0 + i4_y_offset));
i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, 0 + i4_x_offset));
i4_mb_x_strt = i4_x_ref % i4_mb_wd;
i4_mb_y_strt = i4_y_ref % i4_mb_ht;
i4_mb_quard1_part_x = i4_mb_wd - i4_mb_x_strt;
i4_mb_quard1_part_y = i4_mb_ht - i4_mb_y_strt;
if(!(i4_mb_quard1_part_x >= 0))
{
return NOT_OK;
}
if(!(i4_mb_quard1_part_y >= 0))
{
return NOT_OK;
}
i4_mb_x = (i4_x_ref >> i4_mb_sft);
i4_mb_y = (i4_y_ref >> i4_mb_sft);
/* get the location of the byte which has the current mb mode */
pi1_ref_mb_modes_incr = pi1_ref_mb_modes + (i4_mb_y * i4_ref_mode_stride * i4_element_size);
pi1_ref_mb_modes_incr += (i4_mb_x * i4_element_size);
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr;
i1_mb_mode_q0 = ps_inter_lyr_mb_prms->i1_mb_mode;
i1_mb_mode_q1 = i1_mb_mode_q0;
i1_mb_mode_q2 = i1_mb_mode_q0;
i1_mb_mode_q3 = i1_mb_mode_q0;
pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr;
if(i4_mb_quard1_part_x > 0)
{
pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr + i4_element_size;
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
i1_mb_mode_q1 = ps_inter_lyr_mb_prms->i1_mb_mode;
}
if(i4_mb_quard1_part_y > 0)
{
pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size);
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
i1_mb_mode_q2 = ps_inter_lyr_mb_prms->i1_mb_mode;
}
if((i4_mb_quard1_part_x > 0) && (i4_mb_quard1_part_y > 0))
{
pi1_ref_mb_modes_incr_temp =
pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size) + i4_element_size;
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
i1_mb_mode_q3 = ps_inter_lyr_mb_prms->i1_mb_mode;
}
i4_ref_mb_type_q0 = (i1_mb_mode_q0 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
i4_ref_mb_type_q1 = (i1_mb_mode_q1 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
i4_ref_mb_type_q2 = (i1_mb_mode_q2 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
i4_ref_mb_type_q3 = (i1_mb_mode_q3 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
i1_edge_mb = (ps_coord->u2_mb_x == 0 || ps_coord->u2_mb_y == 0 ||
(ps_coord->u2_mb_x == ((ps_lyr_ctxt->i4_curr_width >> MB_WIDTH_SHIFT) - 1)) ||
(ps_coord->u2_mb_y == ((ps_lyr_ctxt->i4_curr_height >> MB_HEIGHT_SHIFT) - 1)));
if(i1_edge_mb)
{
ps_ctxt->pf_residual_reflayer_const_boundary_mb(
pi2_inp_data, i4_inp_data_stride, pi2_ref_array, i4_refarray_wd, i4_refarray_ht,
i4_ref_wd, i4_ref_ht, i4_x_offset, i4_y_offset, i4_ref_mb_type_q0, i4_ref_mb_type_q1,
i4_ref_mb_type_q2, i4_ref_mb_type_q3, i4_mb_quard1_part_x, i4_mb_quard1_part_y,
i4_chroma_flag);
}
else
{
ps_ctxt->pf_residual_reflayer_const_non_boundary_mb(
pi2_inp_data, i4_inp_data_stride, pi2_ref_array, i4_refarray_wd, i4_refarray_ht,
i4_ref_mb_type_q0, i4_ref_mb_type_q1, i4_ref_mb_type_q2, i4_ref_mb_type_q3,
i4_mb_quard1_part_x, i4_mb_quard1_part_y, i4_chroma_flag);
}
/* store the values into the place holders */
*pi4_refarr_wd = i4_refarray_wd;
return OK;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_interpolate_residual */
/* */
/* Description : This function takes the refernce array buffer and perform*/
/* interpolation of a component to find the residual */
/* resampled value */
/* Inputs : pv_residual_samp_ctxt : residual sampling context */
/* pi2_out : output buffer pointer */
/* i4_out_stride : output buffer stride */
/* i4_refarray_wd : reference array width */
/* i4_x_offset : offset in reference layer in horz direction*/
/* ps_coord : current mb co-ordinate */
/* i4_chroma_flag : chroma processing flag */
/* Globals : none */
/* Processing : it does the interpolation in vertical direction followed */
/* by horizontal direction */
/* Outputs : resampled pixels */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 07 2021 vijayakumar creation */
/* */
/*****************************************************************************/
void isvcd_interpolate_residual(void *pv_residual_samp_ctxt, WORD16 *pi2_out, WORD32 i4_out_stride,
WORD32 i4_refarray_wd, UWORD16 u2_mb_x, UWORD16 u2_mb_y,
WORD32 i4_chroma_flag)
{
residual_sampling_ctxt_t *ps_ctxt;
residual_samp_map_ctxt_t *ps_map_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
ref_pixel_map_t *ps_x_pos_phase;
ref_pixel_map_t *ps_y_pos_phase;
WORD32 i4_x, i4_y;
WORD32 i4_frm_mb_x, i4_frm_mb_y;
WORD32 i4_temp_array_ht;
WORD32 i4_mb_wd;
WORD32 i4_mb_ht;
WORD16 *pi2_ref_array;
UWORD8 *pu1_ref_x_ptr_incr, *pu1_ref_y_ptr_incr;
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
pi2_ref_array = ps_ctxt->pi2_refarray_buffer;
pu1_ref_x_ptr_incr = ps_ctxt->pu1_ref_x_ptr_incr;
pu1_ref_y_ptr_incr = ps_ctxt->pu1_ref_y_ptr_incr;
/* --------------------------------------------------------------------- */
/* Extracting information from the mapping context */
/* --------------------------------------------------------------------- */
if(1 == i4_chroma_flag)
ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
else
ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
i4_temp_array_ht = i4_mb_ht;
i4_frm_mb_y = u2_mb_y * i4_mb_ht;
i4_frm_mb_x = u2_mb_x * i4_mb_wd;
/* --------------------------------------------------------------------- */
/* Loop for interpolation */
/* --------------------------------------------------------------------- */
for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
{
for(i4_x = 0; i4_x < (i4_mb_wd); i4_x++)
{
WORD32 i4_i;
WORD32 i4_y_ref;
WORD32 i4_y_phase;
WORD32 i4_x_ref;
WORD32 i4_x_phase;
WORD32 i4_x_ref_round;
WORD16 *pi2_out_curr;
WORD32 ai4_temp_pred[2] = {0};
UWORD8 *pu1_ref_y_ptr_incr_temp;
WORD32 *pi4_temp_pred;
UWORD8 u1_incr_y;
WORD16 i2_res;
/* derive the current output pointer */
pi2_out_curr = pi2_out + (i4_x << i4_chroma_flag) + (i4_y * i4_out_stride);
/* -------------------------------------------------------------- */
/* Finding the offset */
/* -------------------------------------------------------------- */
i4_y_ref = ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos;
i4_y_phase = ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
i4_x_ref = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
i4_x_phase = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
/* horizontal processing*/
for(i4_i = 0; i4_i < 2; i4_i++)
{
UWORD8 *pu1_ref_x_ptr_incr_temp;
UWORD8 u1_incr;
WORD16 *pi2_ref_array_1, *pi2_ref_array_2;
/* derive appropriate pointers */
pu1_ref_x_ptr_incr_temp = pu1_ref_x_ptr_incr + i4_x_ref;
pu1_ref_x_ptr_incr_temp += ((i4_y_ref + i4_i) * i4_refarray_wd);
u1_incr = *pu1_ref_x_ptr_incr_temp;
pi2_ref_array_1 = pi2_ref_array + i4_x_ref;
pi2_ref_array_1 += ((i4_y_ref + i4_i) * i4_refarray_wd);
if(!u1_incr)
{
pi2_ref_array_1 += (i4_x_phase >> 3);
}
pi2_ref_array_2 = pi2_ref_array_1 + u1_incr;
ai4_temp_pred[i4_i] =
(16 - i4_x_phase) * (*pi2_ref_array_1) + i4_x_phase * (*pi2_ref_array_2);
}
/* vertical processing */
i4_x_ref_round = (i4_x_ref + (i4_x_phase >> 3));
pu1_ref_y_ptr_incr_temp =
pu1_ref_y_ptr_incr + i4_x_ref_round + (i4_y_ref * i4_refarray_wd);
u1_incr_y = *pu1_ref_y_ptr_incr_temp;
pi4_temp_pred = &ai4_temp_pred[0];
if(!u1_incr_y)
{
pi4_temp_pred += (i4_y_phase >> 3);
}
i2_res = (((16 - i4_y_phase) * pi4_temp_pred[0] +
i4_y_phase * pi4_temp_pred[u1_incr_y] + 128) >>
8);
/* store back the final residual */
*pi2_out_curr = i2_res;
} /* end of loop over width */
} /* end of loop over height */
return;
} /* End of Interpolation Function */
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_samp_mb */
/* */
/* Description : MB level function whcih perform the residual resampling */
/* of data of an MB (luma and chroma insclusive) */
/* */
/* Inputs : pv_residual_samp_ctxt : residual sampling context */
/* ps_ref_luma : reference layer luma data buffer desc */
/* ps_ref_chroma : reference layer chroma data buffer desc */
/* ps_ref_luma_bitmap : ref layer luma bit map buffer desc */
/* ps_ref_chroma_bitmap : ref layer chroma bit map buff des */
/* ps_ref_mb_mode : ref layer mb mode map buff desc */
/* ps_out_luma : current layer out luma buffer desc */
/* ps_out_chroma : current layer out chroma buffer desc */
/* ps_mb_coord : current mb coorinate */
/* Globals : none */
/* Processing : it calls the reference layer construction followed by */
/* interplaotion function for luma and cb and cr */
/* Outputs : inter resampled data of current MB */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 26 06 2021 vijayakumar creation */
/* */
/*****************************************************************************/
WORD32 isvcd_residual_samp_mb(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
UWORD16 u2_mb_x, UWORD16 u2_mb_y)
{
/* --------------------------------------------------------------------- */
/* I/O buffer params */
/* --------------------------------------------------------------------- */
residual_sampling_ctxt_t *ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
WORD16 *pi2_inp;
WORD16 *pi2_out;
WORD32 i4_inp_stride;
WORD32 i4_out_stride;
WORD32 i4_refarray_wd;
mb_coord_t s_mb_coord = {0};
WORD32 ret;
s_mb_coord.u2_mb_x = u2_mb_x;
s_mb_coord.u2_mb_y = u2_mb_y;
/* --------------------------------------------------------------------- */
/* LUMA PROCESSING */
/* --------------------------------------------------------------------- */
pi2_inp = (WORD16 *) ps_ref_luma->pv_buffer;
pi2_out = (WORD16 *) ps_out_luma->pv_buffer;
i4_inp_stride = ps_ref_luma->i4_num_element_stride;
i4_out_stride = ps_out_luma->i4_num_element_stride;
/* ------- Constructing refSampleArray ----------------------- */
ret = isvcd_residual_reflayer_const(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
ps_ref_mb_mode, &i4_refarray_wd, &s_mb_coord, 0);
if(ret != OK) return ret;
/* ---- Interpolation process for Residual prediction ------ */
ps_ctxt->pf_interpolate_residual(pv_residual_samp_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
s_mb_coord.u2_mb_x, s_mb_coord.u2_mb_y, 0);
/* --------------------------------------------------------------------- */
/* CHROMA PROCESSING */
/* --------------------------------------------------------------------- */
/* CB */
pi2_inp = (WORD16 *) ps_ref_chroma->pv_buffer;
pi2_out = (WORD16 *) ps_out_chroma->pv_buffer;
i4_inp_stride = ps_ref_chroma->i4_num_element_stride;
i4_out_stride = ps_out_chroma->i4_num_element_stride;
/* ------- Constructing refSampleArray ----------------------- */
ret = isvcd_residual_reflayer_const(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
ps_ref_mb_mode, &i4_refarray_wd, &s_mb_coord, 1);
if(ret != OK) return ret;
/* ---- Interpolation process for Residual prediction ------ */
ps_ctxt->pf_interpolate_residual(pv_residual_samp_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
s_mb_coord.u2_mb_x, s_mb_coord.u2_mb_y, 1);
/* CR */
pi2_inp += 1;
pi2_out += 1;
/* ------- Constructing refSampleArray ----------------------- */
ret = isvcd_residual_reflayer_const(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
ps_ref_mb_mode, &i4_refarray_wd, &s_mb_coord, 1);
if(ret != OK) return ret;
/* ---- Interpolation process for Residual prediction --------- */
ps_ctxt->pf_interpolate_residual(pv_residual_samp_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
s_mb_coord.u2_mb_x, s_mb_coord.u2_mb_y, 1);
return OK;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_samp_mb_dyadic */
/* */
/* Description : MB level function whcih perform the residual resampling */
/* of data of an MB (luma and chroma insclusive) */
/* for Dyadic cases */
/* Inputs : pv_residual_samp_ctxt : residual sampling context */
/* ps_ref_luma : reference layer luma data buffer desc */
/* ps_ref_chroma : reference layer chroma data buffer desc */
/* ps_ref_luma_bitmap : ref layer luma bit map buffer desc */
/* ps_ref_chroma_bitmap : ref layer chroma bit map buff des */
/* ps_ref_mb_mode : ref layer mb mode map buff desc */
/* ps_out_luma : current layer out luma buffer desc */
/* ps_out_chroma : current layer out chroma buffer desc */
/* ps_mb_coord : current mb coorinate */
/* Globals : none */
/* Processing : it calls the reference layer construction followed by */
/* interplaotion function for luma and cb and cr */
/* Outputs : inter resampled data of current MB */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 26 06 2021 vijayakumar creation */
/* */
/*****************************************************************************/
WORD32 isvcd_residual_samp_mb_dyadic(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
UWORD16 u2_mb_x, UWORD16 u2_mb_y)
{
residual_sampling_ctxt_t *ps_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
/* --------------------------------------------------------------------- */
/* I/O buffer params */
/* --------------------------------------------------------------------- */
WORD16 *pi2_inp;
WORD16 *pi2_out;
WORD32 i4_inp_stride;
WORD32 i4_out_stride;
WORD32 i4_luma_nnz;
WORD32 i4_chroma_nnz;
WORD32 i4_tx_size;
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
/* --------------------------------------------------------------------- */
/* LUMA PROCESSING */
/* --------------------------------------------------------------------- */
pi2_inp = (WORD16 *) ps_ref_luma->pv_buffer;
pi2_out = (WORD16 *) ps_out_luma->pv_buffer;
i4_inp_stride = ps_ref_luma->i4_num_element_stride;
i4_out_stride = ps_out_luma->i4_num_element_stride;
{
WORD32 i4_offset_x, i4_offset_y;
residual_samp_map_ctxt_t *ps_luma_map;
ref_mb_map_t *ps_x_off_len_luma;
ref_mb_map_t *ps_y_off_len_luma;
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_x_off_len_luma = ps_luma_map->ps_x_offset_length;
ps_y_off_len_luma = ps_luma_map->ps_y_offset_length;
/* get the actual offset for the buffers */
i4_offset_x = ps_x_off_len_luma[u2_mb_x].i2_offset;
i4_offset_y = ps_y_off_len_luma[u2_mb_y].i2_offset;
{
inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
WORD32 i4_mb_x, i4_mb_y;
UWORD16 u2_luma_mask = 0x0033;
UWORD8 u1_chrm_mask = 0x11;
WORD32 i4_luma_rt_sft_amt = 0;
WORD32 i4_chrm_rt_sft_amt = 0;
i4_mb_x = ((i4_offset_x + 1) >> MB_WIDTH_SHIFT);
i4_mb_y = ((i4_offset_y + 1) >> MB_HEIGHT_SHIFT);
/* get the location of the byte which has the current mb mode */
ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_ref_mb_mode->pv_buffer;
ps_inter_lyr_mb_prms += i4_mb_x;
ps_inter_lyr_mb_prms += i4_mb_y * ps_ref_mb_mode->i4_num_element_stride;
/* get the approp block in base layer in horz direction */
if(0 != ((i4_offset_x + 1) & 15))
{
u2_luma_mask <<= 2;
i4_luma_rt_sft_amt += 2;
u1_chrm_mask <<= 1;
i4_chrm_rt_sft_amt += 1;
}
/* get the approp block in base layer in vert direction */
if(0 != ((i4_offset_y + 1) & 15))
{
u2_luma_mask <<= 8;
i4_luma_rt_sft_amt += 8;
u1_chrm_mask <<= 2;
i4_chrm_rt_sft_amt += 2;
}
/* extract the nnz and store it */
i4_luma_nnz = (ps_inter_lyr_mb_prms->u2_luma_nnz & u2_luma_mask) >> i4_luma_rt_sft_amt;
i4_chroma_nnz =
(ps_inter_lyr_mb_prms->u1_chroma_nnz & u1_chrm_mask) >> i4_chrm_rt_sft_amt;
i4_tx_size =
(ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1 : ps_inter_lyr_mb_prms->i1_tx_size;
}
/* since in dyadic case the window width and height will be 10x10 */
/* and the window start offsets will be always 1 column left and */
/* 1 row above the block boundary. so the pointer and the required */
/* positions are appropriately modified */
if(i4_offset_x >= 0)
{
pi2_inp++;
}
if(i4_offset_y >= 0)
{
pi2_inp += i4_inp_stride;
}
ps_ctxt->pf_residual_luma_dyadic(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride, pi2_out,
i4_out_stride, ps_ref_mb_mode, u2_mb_x, u2_mb_y,
i4_luma_nnz, i4_tx_size);
}
/* --------------------------------------------------------------------- */
/* CHROMA PROCESSING */
/* --------------------------------------------------------------------- */
/* CB */
pi2_inp = (WORD16 *) ps_ref_chroma->pv_buffer;
pi2_out = (WORD16 *) ps_out_chroma->pv_buffer;
i4_inp_stride = ps_ref_chroma->i4_num_element_stride;
i4_out_stride = ps_out_chroma->i4_num_element_stride;
/* choose the appropriate chroma processing routine */
if(SVCD_FALSE == ps_lyr_ctxt->i4_chrm_alt_proc)
{
WORD32 i4_offset_x, i4_offset_y;
residual_samp_map_ctxt_t *ps_chroma_map;
ref_mb_map_t *ps_x_off_len_chroma;
ref_mb_map_t *ps_y_off_len_chroma;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
/* get the actual offset for the buffers */
i4_offset_x = ps_x_off_len_chroma[u2_mb_x].i2_offset;
i4_offset_y = ps_y_off_len_chroma[u2_mb_y].i2_offset;
/* since in dyadic case the window width and height will be 6x6 */
/* and the window start offsets will be always 1 column left and */
/* 1 row above the block boundary. so the pointer and the required */
/* positions are appropriately modified */
if(i4_offset_x >= 0)
{
pi2_inp += 2;
}
if(i4_offset_y >= 0)
{
pi2_inp += i4_inp_stride;
}
if(0 != (i4_chroma_nnz & 0x01))
{
ps_ctxt->pf_residual_chroma_dyadic(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
pi2_out, i4_out_stride);
}
}
else
{
ps_ctxt->pf_residual_chroma_dyadic_alt(pv_residual_samp_ctxt, u2_mb_x, u2_mb_y,
ps_ref_mb_mode, pi2_inp, i4_inp_stride, pi2_out,
i4_out_stride, SVCD_FALSE);
}
/* CR */
pi2_inp += 1;
pi2_out += 1;
if(SVCD_FALSE == ps_lyr_ctxt->i4_chrm_alt_proc)
{
if(0 != (i4_chroma_nnz & 0x10))
{
ps_ctxt->pf_residual_chroma_dyadic(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
pi2_out, i4_out_stride);
}
}
else
{
ps_ctxt->pf_residual_chroma_dyadic_alt(pv_residual_samp_ctxt, u2_mb_x, u2_mb_y,
ps_ref_mb_mode, pi2_inp, i4_inp_stride, pi2_out,
i4_out_stride, SVCD_TRUE);
}
return OK;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_samp_populate_list */
/* */
/* Description : This is a seq or frame level init function which fills */
/* all offsets, projected locations arrays based on */
/* the two resolutions and cropping parameters */
/* Inputs : refer to doxygen comments below */
/* Globals : none */
/* Processing : it projects the locations and computes the values */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 07 2021 vijayakumar creation */
/* */
/*****************************************************************************/
void isvcd_residual_samp_populate_list(residual_samp_map_ctxt_t *ps_map_ctxt,
dec_seq_params_t *ps_sps,
dec_svc_seq_params_t *ps_subset_sps,
res_prms_t *ps_curr_res_prms, res_prms_t *ps_ref_res_prms,
WORD32 i4_chroma_flag)
{
/* --------------------------------------------------------------------- */
/* Local variables required for finding the mapping between the layers */
/* --------------------------------------------------------------------- */
UWORD32 u4_shift_x;
UWORD32 u4_shift_y;
UWORD32 u4_scale_x;
UWORD32 u4_scale_y;
WORD32 i4_offset_x;
WORD32 i4_offset_y;
WORD32 i4_add_x;
WORD32 i4_add_y;
WORD32 i4_delta_x;
WORD32 i4_delta_y;
WORD32 i4_refphase_x;
WORD32 i4_refphase_y;
WORD32 i4_phase_x;
WORD32 i4_phase_y;
WORD32 i4_sub_wd;
WORD32 i4_sub_ht;
WORD32 i4_mb_wd;
WORD32 i4_mb_ht;
/* --------------------------------------------------------------------- */
/* Local Pointer Declaration for arrays in Mapping context */
/* --------------------------------------------------------------------- */
ref_mb_map_t *ps_x_off_len;
ref_mb_map_t *ps_y_off_len;
UWORD32 i4_ref_wd;
UWORD32 i4_ref_ht;
UWORD32 i4_scaled_wd;
UWORD32 i4_scaled_ht;
WORD32 i4_curr_lyr_width;
WORD32 i4_curr_lyr_height;
/* --------------------------------------------------------------------- */
/* Local Flag Declaration */
/* --------------------------------------------------------------------- */
WORD32 i4_ref_layer_field_pic_flag;
WORD32 i4_field_pic_flag;
WORD32 i4_frame_mbs_only_flag;
WORD32 i4_ref_layer_frame_Mbs_only_flag;
WORD32 i4_field_Mb_flag;
WORD32 i4_bot_field_flag;
/* --------------------------------------------------------------------- */
/* Cropping Parameters Declaration */
/* --------------------------------------------------------------------- */
WORD32 i4_scaled_ref_layer_left_offset;
WORD32 i4_scaled_ref_layer_top_offset;
/* --------------------------------------------------------------------- */
/* Hardcoding flag information (assuming no field support) */
/* --------------------------------------------------------------------- */
i4_ref_layer_field_pic_flag = SVCD_FALSE;
i4_field_pic_flag = SVCD_FALSE;
i4_frame_mbs_only_flag = SVCD_TRUE;
i4_field_Mb_flag = SVCD_FALSE;
i4_bot_field_flag = SVCD_FALSE;
i4_ref_layer_frame_Mbs_only_flag = SVCD_TRUE;
/* --------------------------------------------------------------------- */
/* Pointer and Paramater are intialized - Chroma and Luma */
/* --------------------------------------------------------------------- */
{
WORD32 i4_base_width;
WORD32 i4_base_height;
WORD32 i4_ref_layer_chroma_phase_x_plus1_flag;
WORD32 i4_ref_layer_chroma_phase_y_plus1;
WORD32 i4_chroma_phase_x_plus1_flag;
WORD32 i4_chroma_phase_y_plus1;
/* ------------------------------------------------------------- */
/* HARD CODED FOR 420 */
/* ------------------------------------------------------------- */
WORD32 i4_sub_wd_chroma = 2;
WORD32 i4_sub_ht_chroma = 2;
i4_base_width = ps_ref_res_prms->i4_res_width;
i4_base_height = ps_ref_res_prms->i4_res_height;
i4_ref_layer_chroma_phase_x_plus1_flag =
ps_curr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
i4_ref_layer_chroma_phase_y_plus1 = ps_curr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
i4_chroma_phase_x_plus1_flag =
ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag;
i4_chroma_phase_y_plus1 =
ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1;
i4_scaled_ref_layer_left_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_left;
i4_scaled_ref_layer_top_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_top;
/* ----------------------------------------------------------------- */
/* Computing Effective Frame Dimensions */
/* ------------------------------------------------------------------*/
i4_ref_wd = (i4_base_width >> i4_chroma_flag);
i4_ref_ht = (i4_base_height >> i4_chroma_flag) * (1 + i4_ref_layer_field_pic_flag);
i4_scaled_wd = ps_curr_res_prms->u2_scaled_ref_width;
i4_scaled_ht = ps_curr_res_prms->u2_scaled_ref_height;
i4_scaled_wd = (i4_scaled_wd >> i4_chroma_flag);
i4_scaled_ht = (i4_scaled_ht >> i4_chroma_flag) * (1 + i4_field_pic_flag);
if(1 == i4_chroma_flag)
{
i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1_flag - 1;
i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
i4_phase_x = i4_chroma_phase_x_plus1_flag - 1;
i4_phase_y = i4_chroma_phase_y_plus1 - 1;
i4_sub_wd = i4_sub_wd_chroma;
i4_sub_ht = i4_sub_ht_chroma;
i4_mb_wd = MB_WIDTH >> 1;
i4_mb_ht = MB_HEIGHT >> 1;
}
else
{
i4_refphase_x = 0;
i4_refphase_y = 0;
i4_phase_x = 0;
i4_phase_y = 0;
i4_sub_wd = 1;
i4_sub_ht = 1;
i4_mb_wd = MB_WIDTH;
i4_mb_ht = MB_HEIGHT;
}
}
/* --------------------------------------------------------------------- */
/* Derive shift x and y based on level idd */
/* --------------------------------------------------------------------- */
if(ps_sps->u1_level_idc <= 30)
{
u4_shift_x = 16;
u4_shift_y = 16;
}
else
{
u4_shift_x = 31 - isvcd_get_ceil_log2(i4_ref_wd);
u4_shift_y = 31 - isvcd_get_ceil_log2(i4_ref_ht);
}
/* --------------------------------------------------------------------- */
/* The following condition is not true in our case for time being */
/* --------------------------------------------------------------------- */
if((SVCD_FALSE == i4_frame_mbs_only_flag) || (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
{
i4_phase_y = i4_phase_y + 4 * i4_bot_field_flag;
if(1 == i4_ref_layer_frame_Mbs_only_flag)
i4_refphase_y = (2 * i4_refphase_y) + 2;
else
i4_refphase_y = i4_refphase_y + (4 * i4_bot_field_flag);
}
/* --------------------------------------------------------------------- */
/* Dx and Dy Computation - Ratio of the base and enhance layer width */
/* --------------------------------------------------------------------- */
u4_scale_x = ((i4_ref_wd << u4_shift_x) + (i4_scaled_wd >> 1)) / (i4_scaled_wd);
u4_scale_y = ((i4_ref_ht << u4_shift_y) + (i4_scaled_ht >> 1)) / (i4_scaled_ht);
i4_offset_x = i4_scaled_ref_layer_left_offset / i4_sub_wd;
i4_add_x = (((i4_ref_wd * (2 + i4_phase_x)) << (u4_shift_x - 2)) + (i4_scaled_wd >> 1)) /
i4_scaled_wd +
(1 << (u4_shift_x - 5));
i4_delta_x = 4 * (2 + i4_refphase_x);
if((SVCD_TRUE == i4_frame_mbs_only_flag) && (SVCD_TRUE == i4_ref_layer_frame_Mbs_only_flag))
{
i4_offset_y = i4_scaled_ref_layer_top_offset / i4_sub_ht;
i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (u4_shift_y - 2)) + (i4_scaled_ht >> 1)) /
i4_scaled_ht +
(1 << (u4_shift_y - 5));
i4_delta_y = 4 * (2 + i4_refphase_y);
}
else
{
i4_offset_y = i4_scaled_ref_layer_top_offset / (2 * i4_sub_ht);
i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (u4_shift_y - 3)) + (i4_scaled_ht >> 1)) /
i4_scaled_ht +
(1 << (u4_shift_y - 5));
i4_delta_y = 2 * (2 + i4_refphase_y);
}
/* --------------------------------------------------------------------- */
/* Intializing Local Pointers - Chroma and Luma */
/* --------------------------------------------------------------------- */
ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
i4_curr_lyr_width = ps_curr_res_prms->i4_res_width >> i4_chroma_flag;
i4_curr_lyr_height = ps_curr_res_prms->i4_res_height >> i4_chroma_flag;
{
WORD32 i4_i, i4_j;
/* ----------------------------------------------------------------- */
/* Computation of offsetX refArrayW Xmin and Xmax Lists */
/* ----------------------------------------------------------------- */
for(i4_i = 0; i4_i < i4_curr_lyr_width; i4_i = i4_i + i4_mb_wd)
{
WORD32 i4_x_refmin16;
WORD32 i4_x_refmax16;
WORD32 i4_x_offset;
i4_x_refmin16 = (WORD64) (((WORD64) ((i4_i - i4_offset_x) * u4_scale_x) + i4_add_x) >>
((WORD32) (u4_shift_x - 4))) -
i4_delta_x;
i4_x_refmax16 =
(WORD64) (((WORD64) (i4_i + i4_mb_wd - 1 - i4_offset_x) * u4_scale_x + i4_add_x) >>
((WORD32) (u4_shift_x - 4))) -
i4_delta_x;
/* AC205 */
i4_x_offset = i4_x_refmin16 >> 4;
ps_x_off_len->i2_offset = i4_x_offset;
ps_x_off_len->i2_length = (i4_x_refmax16 >> 4) - i4_x_offset + 2;
/* increment the pointer */
ps_x_off_len++;
} /* end of loop over current layer width */
/* ----------------------------------------------------------------- */
/* Computation of offsetY refArrayH Ymin and Ymax Lists */
/* ----------------------------------------------------------------- */
for(i4_j = 0; i4_j < i4_curr_lyr_height; i4_j = i4_j + i4_mb_ht)
{
WORD32 i4_y_refmin16;
WORD32 i4_y_refmax16;
WORD32 i4_y_offset;
i4_y_refmin16 = (WORD64) (((WORD64) (i4_j - i4_offset_y) * u4_scale_y + i4_add_y) >>
((WORD32) (u4_shift_y - 4))) -
i4_delta_y;
i4_y_refmax16 =
(WORD64) (((WORD64) (i4_j + i4_mb_ht - 1 - i4_offset_y) * u4_scale_y + i4_add_y) >>
((WORD32) (u4_shift_y - 4))) -
i4_delta_y;
/* AC205 */
i4_y_offset = i4_y_refmin16 >> 4;
ps_y_off_len->i2_offset = i4_y_offset;
ps_y_off_len->i2_length = (i4_y_refmax16 >> 4) - i4_y_offset + 2;
/* increment the pointer */
ps_y_off_len++;
} /* end of loop over current layer height */
}
/* --------------------------------------------------------------------- */
/* Computation of Xref and Xphase List as per standard */
/* --------------------------------------------------------------------- */
ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
{
WORD32 i4_xc;
WORD32 i4_offset_x_index;
ref_pixel_map_t *ps_x_pos_phase;
ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
for(i4_xc = 0; i4_xc < i4_curr_lyr_width; i4_xc++)
{
WORD32 i4_x_offset;
WORD32 i4_x_ref16;
i4_offset_x_index = i4_xc / i4_mb_wd;
i4_x_offset = ps_x_off_len[i4_offset_x_index].i2_offset;
i4_x_ref16 = (WORD64) (((WORD64) (i4_xc - i4_offset_x) * u4_scale_x + i4_add_x) >>
((WORD32) (u4_shift_x - 4))) -
i4_delta_x;
/* store the values */
ps_x_pos_phase->i2_ref_pos = (i4_x_ref16 >> 4) - i4_x_offset;
ps_x_pos_phase->i2_phase = (i4_x_ref16 - (16 * i4_x_offset)) & 15;
/* increment the pointer */
ps_x_pos_phase++;
} /* end of loop over scaled width */
}
/* --------------------------------------------------------------------- */
/* Computation of Yref and Yphase List as per standard */
/* --------------------------------------------------------------------- */
{
WORD32 i4_yc;
WORD32 i4_offset_y_index;
ref_pixel_map_t *ps_y_pos_phase;
ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
for(i4_yc = 0; i4_yc < i4_curr_lyr_height; i4_yc++)
{
WORD32 i4_y_offset;
WORD32 i4_y_ref16;
i4_offset_y_index = i4_yc / i4_mb_ht;
i4_y_offset = ps_y_off_len[i4_offset_y_index].i2_offset;
if((SVCD_FALSE == i4_frame_mbs_only_flag) ||
(SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
{
i4_yc = i4_yc >> (1 - i4_field_Mb_flag);
}
i4_y_ref16 = (WORD64) ((((WORD64) (i4_yc - i4_offset_y) * u4_scale_y + i4_add_y) >>
((WORD32) (u4_shift_y - 4))) -
i4_delta_y);
ps_y_pos_phase->i2_ref_pos = (i4_y_ref16 >> 4) - i4_y_offset;
ps_y_pos_phase->i2_phase = (i4_y_ref16 - (16 * i4_y_offset)) & 15;
/* increment the pointer */
ps_y_pos_phase++;
} /* end of loop over scaled height */
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_samp_res_init */
/* */
/* Description : this function calculates the scale factors and initialise*/
/* the context structure */
/* */
/* Inputs : pv_residual_samp_ctxt: handle to private structure */
/* ps_curr_lyr_res_prms: pointer to current resolution */
/* params */
/* Globals : none */
/* Processing : it stores the layer dimensions */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 26 06 2021 vijayakumar creation */
/* */
/*****************************************************************************/
WORD32 isvcd_residual_samp_res_init(void *pv_svc_dec)
{
residual_sampling_ctxt_t *ps_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
dec_seq_params_t *ps_sps;
dec_svc_seq_params_t *ps_subset_sps;
svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
void *pv_residual_samp_ctxt = ps_svc_lyr_dec->pv_residual_sample_ctxt;
res_prms_t *ps_curr_lyr_res_prms = &ps_svc_lyr_dec->s_res_prms;
ref_mb_map_t **pps_luma_map_horz = &ps_svc_lyr_dec->ps_ressam_luma_map_horz;
ref_mb_map_t **pps_chroma_map_horz = &ps_svc_lyr_dec->ps_ressam_chroma_map_horz;
ref_mb_map_t **pps_luma_map_vert = &ps_svc_lyr_dec->ps_ressam_luma_map_vert;
ref_mb_map_t **pps_chroma_map_vert = &ps_svc_lyr_dec->ps_ressam_chroma_map_vert;
if((NULL == pv_residual_samp_ctxt) || (NULL == ps_curr_lyr_res_prms) ||
(NULL == pps_luma_map_horz) || (NULL == pps_chroma_map_horz) ||
(NULL == pps_luma_map_vert) || (NULL == pps_chroma_map_vert))
{
return NOT_OK;
}
ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
/* if called for base resolution store deafult values */
if(SVCD_TRUE == ps_svc_lyr_dec->u1_base_res_flag)
{
*pps_luma_map_horz = NULL;
*pps_chroma_map_horz = NULL;
*pps_luma_map_vert = NULL;
*pps_chroma_map_vert = NULL;
ps_ctxt->i4_res_lyr_id = -1;
ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
return OK;
}
/* derive the current sps */
ps_sps = ps_dec->ps_cur_sps;
ps_subset_sps = ps_svc_lyr_dec->ps_cur_subset_sps;
/* store the res id appropriately */
ps_ctxt->i4_res_lyr_id = ps_svc_lyr_dec->u1_layer_id - 1;
/* get the current layer ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_svc_lyr_dec->u1_layer_id - 1];
/* get the width and heights */
ps_lyr_ctxt->i4_curr_width = ps_curr_lyr_res_prms->i4_res_width;
ps_lyr_ctxt->i4_curr_height = ps_curr_lyr_res_prms->i4_res_height;
ps_lyr_ctxt->i4_ref_width = ps_ctxt->i4_ref_width;
ps_lyr_ctxt->i4_ref_height = ps_ctxt->i4_ref_height;
/* store the strcuture pointer containing projected locations */
*pps_luma_map_horz = ps_lyr_ctxt->s_luma_map_ctxt.ps_x_offset_length;
*pps_chroma_map_horz = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_offset_length;
*pps_luma_map_vert = ps_lyr_ctxt->s_luma_map_ctxt.ps_y_offset_length;
*pps_chroma_map_vert = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_offset_length;
/* check for recomputation of mapping required */
if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_remap_req_flag)
{
res_prms_t s_ref_res_prms = {0};
/* store the reference layer resolution width and height */
s_ref_res_prms.i4_res_width = ps_ctxt->i4_ref_width;
s_ref_res_prms.i4_res_height = ps_ctxt->i4_ref_height;
/* call the frame level projections calculation function */
isvcd_residual_samp_populate_list(&ps_lyr_ctxt->s_luma_map_ctxt, ps_sps, ps_subset_sps,
ps_curr_lyr_res_prms, &s_ref_res_prms, 0);
isvcd_residual_samp_populate_list(&ps_lyr_ctxt->s_chroma_map_ctxt, ps_sps, ps_subset_sps,
ps_curr_lyr_res_prms, &s_ref_res_prms, 1);
/* default values for flags */
ps_lyr_ctxt->pf_residual_samp_mb = &isvcd_residual_samp_mb;
ps_lyr_ctxt->i4_chrm_horz_int_mode = 0;
ps_lyr_ctxt->i4_chrm_vert_int_mode = 0;
ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_FALSE;
/* Store the Dyadic flag */
ps_lyr_ctxt->i4_dyadic_flag = ps_curr_lyr_res_prms->u1_dyadic_flag;
/* set the appropriate chroma processing routine based on */
/* phase values */
if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_dyadic_flag)
{
WORD32 i4_ref_layer_chroma_phase_x_plus1_flag;
WORD32 i4_ref_layer_chroma_phase_y_plus1;
WORD32 i4_chroma_phase_x_plus1_flag;
WORD32 i4_chroma_phase_y_plus1;
ps_lyr_ctxt->pf_residual_samp_mb = &isvcd_residual_samp_mb_dyadic;
i4_ref_layer_chroma_phase_x_plus1_flag =
ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
i4_ref_layer_chroma_phase_y_plus1 =
ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
i4_chroma_phase_x_plus1_flag =
ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag;
i4_chroma_phase_y_plus1 =
ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1;
if((0 == i4_ref_layer_chroma_phase_x_plus1_flag) && (1 == i4_chroma_phase_x_plus1_flag))
{
ps_lyr_ctxt->i4_chrm_horz_int_mode = 1;
ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
}
if((0 == i4_ref_layer_chroma_phase_y_plus1) && (1 == i4_chroma_phase_y_plus1))
{
ps_lyr_ctxt->i4_chrm_vert_int_mode = 1;
ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
}
if((0 == i4_ref_layer_chroma_phase_y_plus1) && (2 == i4_chroma_phase_y_plus1))
{
ps_lyr_ctxt->i4_chrm_vert_int_mode = 1;
ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
}
if((2 == i4_ref_layer_chroma_phase_y_plus1) && (0 == i4_chroma_phase_y_plus1))
{
ps_lyr_ctxt->i4_chrm_vert_int_mode = 2;
ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
}
}
}
else
{
/* should take false value */
if(SVCD_FALSE != ps_curr_lyr_res_prms->u1_remap_req_flag)
{
return NOT_OK;
}
}
/* store the current layer width and height to context */
ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
/* assert on max ranges of width and shift values */
if((ps_lyr_ctxt->i4_curr_width > H264_MAX_FRAME_WIDTH) ||
(ps_lyr_ctxt->i4_ref_width > H264_MAX_FRAME_WIDTH) ||
(ps_lyr_ctxt->i4_curr_height > H264_MAX_FRAME_HEIGHT) ||
(ps_lyr_ctxt->i4_ref_height > H264_MAX_FRAME_HEIGHT))
{
return NOT_OK;
}
return OK;
}