mirror of
https://github.com/ittiam-systems/libhevc.git
synced 2026-10-09 10:22:19 +07:00
libhevc: Implement 10-bit 444 Chroma Intra-Prediction
This commit adds spatial intra-prediction support for 10-bit 444 chroma blocks during the decoder's prediction stage. Changes include: - Updated ihevc_hbd_chroma_intra_pred_filters.c to add 444 scaling (sub_sample = 2 vs sub_sample = 1). - Added support for 32x32 chroma block predictions (nt == 32), which is the maximum chroma transform unit size in the 444 profile. - Integrated the new filtering logic by updating the CTB intra-prediction loop in ihevcd_iquant_itrans_recon_ctb.c
This commit is contained in:
parent
a2ff0ddeff
commit
f90307a9d6
3 changed files with 194 additions and 23 deletions
|
|
@ -135,6 +135,12 @@ typedef void ihevc_intra_pred_chroma_ref_filtering_ft(UWORD8 *pu1_src,
|
|||
WORD32 mode,
|
||||
WORD32 intra_smoothing_flags);
|
||||
|
||||
typedef void ihevc_hbd_intra_pred_chroma_ref_filtering_ft(UWORD16* pu2_src,
|
||||
WORD32 nt,
|
||||
UWORD16* pu2_dst,
|
||||
WORD32 mode,
|
||||
WORD32 intra_smoothing_flags);
|
||||
|
||||
typedef void ihevc_hbd_intra_pred_chroma_planar_ft(
|
||||
UWORD16 *pu2_ref,
|
||||
WORD32 src_strd,
|
||||
|
|
@ -233,6 +239,7 @@ typedef void ihevc_hbd_intra_pred_chroma_ref_substitution_ft(UWORD16 *pu2_top_le
|
|||
WORD32 nbr_flags,
|
||||
UWORD16 *pu2_dst,
|
||||
WORD32 dst_strd,
|
||||
WORD32 chroma_format_idc,
|
||||
UWORD8 bit_depth);
|
||||
|
||||
/* C function declarations */
|
||||
|
|
@ -260,6 +267,7 @@ ihevc_hbd_intra_pred_chroma_mode_11_to_17_ft ihevc_hbd_intra_pred_chroma_mode_11
|
|||
ihevc_hbd_intra_pred_chroma_mode_19_to_25_ft ihevc_hbd_intra_pred_chroma_mode_19_to_25;
|
||||
ihevc_hbd_intra_pred_chroma_mode_27_to_33_ft ihevc_hbd_intra_pred_chroma_mode_27_to_33;
|
||||
ihevc_hbd_intra_pred_chroma_ref_substitution_ft ihevc_hbd_intra_pred_chroma_ref_substitution;
|
||||
ihevc_hbd_intra_pred_chroma_ref_filtering_ft ihevc_hbd_intra_pred_chroma_ref_filtering;
|
||||
|
||||
/* C function declarations */
|
||||
ihevc_intra_pred_chroma_planar_ft ihevc_intra_pred_chroma_planar;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
#include "ihevc_function_selector.h"
|
||||
#include "ihevc_platform_macros.h"
|
||||
#include "ihevc_intra_pred.h"
|
||||
#include "ihevc_defs.h"
|
||||
|
||||
#include "ihevc_chroma_intra_pred.h"
|
||||
#include "ihevc_common_tables.h"
|
||||
|
|
@ -87,6 +88,97 @@
|
|||
/* Function Definition */
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
*
|
||||
* @brief
|
||||
* Intra prediction interpolation filter for chroma ref_filtering (4:4:4)
|
||||
*
|
||||
*
|
||||
* @par Description:
|
||||
* Reference DC filtering for neighboring chroma samples dependent on TU size and
|
||||
* mode Refer to section 8.4.4.2.3 in the standard
|
||||
*
|
||||
* @param[in] pu2_src
|
||||
* UWORD16 pointer to the source
|
||||
*
|
||||
* @param[out] pu2_dst
|
||||
* UWORD16 pointer to the destination
|
||||
*
|
||||
* @param[in] nt
|
||||
* integer Transform Block size
|
||||
*
|
||||
* @param[in] mode
|
||||
* integer intraprediction mode
|
||||
*
|
||||
* @param[in] intra_smoothing_flag
|
||||
* integer containing intra_smoothing_disabled_flag and strong_smoothing_enable_flag
|
||||
*
|
||||
* @returns
|
||||
*
|
||||
* @remarks
|
||||
* None
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
void ihevc_hbd_intra_pred_chroma_ref_filtering(UWORD16* pu2_src,
|
||||
WORD32 nt,
|
||||
UWORD16* pu2_dst,
|
||||
WORD32 mode,
|
||||
WORD32 intra_smoothing_flag)
|
||||
{
|
||||
WORD32 filter_flag;
|
||||
WORD32 i; /* Generic indexing variable */
|
||||
WORD32 four_nt = 4 * nt;
|
||||
UWORD16 au2_flt[((4 * MAX_CU_SIZE) + 1) * 2];
|
||||
WORD32 intra_smoothing_disabled_flag = (intra_smoothing_flag >> 3) & 0x1;
|
||||
WORD32 strong_intra_smoothing_enable_flag = intra_smoothing_flag & 0x1;
|
||||
UNUSED(strong_intra_smoothing_enable_flag);
|
||||
|
||||
if (intra_smoothing_disabled_flag)
|
||||
{
|
||||
if (pu2_src == pu2_dst) return;
|
||||
for (i = 0; i < (2 * (four_nt + 1)); i += 2)
|
||||
{
|
||||
pu2_dst[i] = pu2_src[i];
|
||||
pu2_dst[i + 1] = pu2_src[i + 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
filter_flag = gau1_intra_pred_ref_filter[mode] & (1 << (CTZ(nt) - 2));
|
||||
if (0 == filter_flag)
|
||||
{
|
||||
if (pu2_src == pu2_dst) return;
|
||||
for (i = 0; i < (2 * (four_nt + 1)); i += 2)
|
||||
{
|
||||
pu2_dst[i] = pu2_src[i];
|
||||
pu2_dst[i + 1] = pu2_src[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Extremities Untouched*/
|
||||
au2_flt[0] = pu2_src[0];
|
||||
au2_flt[1] = pu2_src[1];
|
||||
au2_flt[four_nt * 2] = pu2_src[four_nt * 2];
|
||||
au2_flt[(four_nt * 2) + 1] = pu2_src[(four_nt * 2) + 1];
|
||||
|
||||
for (i = 2; i < four_nt * 2; i += 2)
|
||||
{
|
||||
au2_flt[i] = (pu2_src[i - 2] + 2 * pu2_src[i] + pu2_src[i + 2] + 2) >> 2;
|
||||
au2_flt[i + 1] = (pu2_src[i - 1] + 2 * pu2_src[i + 1] + pu2_src[i + 3] + 2) >> 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < (2 * (four_nt + 1)); i += 2)
|
||||
{
|
||||
pu2_dst[i] = au2_flt[i];
|
||||
pu2_dst[i + 1] = au2_flt[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
*
|
||||
|
|
@ -135,6 +227,7 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
WORD32 nbr_flags,
|
||||
UWORD16 * pu2_dst,
|
||||
WORD32 dst_strd,
|
||||
WORD32 chroma_format_idc,
|
||||
UWORD8 bit_depth)
|
||||
{
|
||||
UWORD16 pu2_ref_u, pu2_ref_v;
|
||||
|
|
@ -213,7 +306,7 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
pu2_dst[(4 * nt ) + 2 + i] = pu2_top[i]; // U-V interleaved Top-top right samples
|
||||
}
|
||||
}
|
||||
if(nt == 4)
|
||||
if (nt == 4 || (nt == 8 && chroma_format_idc == CHROMA_FMT_IDC_YUV444))
|
||||
{
|
||||
/* 1 bit extraction for all the neighboring blocks */
|
||||
tp_left = (nbr_flags & 0x10000) >> 16;
|
||||
|
|
@ -292,9 +385,10 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(nt == 8)
|
||||
else if (nt == 8 || (nt == 16 && chroma_format_idc == CHROMA_FMT_IDC_YUV444))
|
||||
{
|
||||
WORD32 nbr_flags_temp = 0;
|
||||
WORD32 sub_sample = chroma_format_idc == CHROMA_FMT_IDC_YUV444 ? 2 : 1;
|
||||
nbr_flags_temp = ((nbr_flags & 0xC)>>2) + ((nbr_flags & 0xC0) >> 4)
|
||||
+ ((nbr_flags & 0x300) >> 4)
|
||||
+ ((nbr_flags & 0x3000) >> 6)
|
||||
|
|
@ -303,18 +397,18 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
/* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/
|
||||
/* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
|
||||
{
|
||||
nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 4; /* for bottom left and left */
|
||||
if(nbr_id_from_bl == 32)
|
||||
nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * (4 * sub_sample); /* for bottom left and left */
|
||||
if (nbr_id_from_bl == (32 * sub_sample))
|
||||
{
|
||||
nbr_id_from_bl = 16;
|
||||
nbr_id_from_bl = (16 * sub_sample);
|
||||
}
|
||||
if(nbr_id_from_bl == 16)
|
||||
if (nbr_id_from_bl == (16 * sub_sample))
|
||||
{
|
||||
/* for top left : 1 pel per nbr bit */
|
||||
if(!((nbr_flags_temp >> 8) & 0x1))
|
||||
{
|
||||
nbr_id_from_bl++;
|
||||
nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 4; /* top and top right; 8 pels per nbr bit */
|
||||
nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * (4 * sub_sample); /* top and top right; 8 pels per nbr bit */
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -333,14 +427,14 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
}
|
||||
|
||||
/* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
|
||||
while(nbr_id_from_bl < ((T8C_4NT) + 1))
|
||||
while (nbr_id_from_bl < ((T8C_4NT * sub_sample) + 1))
|
||||
{
|
||||
/* To Obtain the next unavailable idx flag after reverse neighbor substitution */
|
||||
/* Divide by 8 to obtain the original index */
|
||||
frwd_nbr_flag = (nbr_id_from_bl >> 2);/*+ (nbr_id_from_bl & 0x1);*/
|
||||
frwd_nbr_flag = (nbr_id_from_bl >> (chroma_format_idc == CHROMA_FMT_IDC_YUV444 ? 3 : 2));/*+ (nbr_id_from_bl & 0x1);*/
|
||||
|
||||
/* The Top-left flag is at the last bit location of nbr_flags*/
|
||||
if(nbr_id_from_bl == (T8C_4NT / 2))
|
||||
if (nbr_id_from_bl == (T8C_4NT * sub_sample / 2))
|
||||
{
|
||||
get_bits = GET_BIT(nbr_flags_temp, 8);
|
||||
|
||||
|
|
@ -359,24 +453,25 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
/* 8 pel substitution (other than TL) */
|
||||
pu2_ref_u = pu2_dst[(2 * nbr_id_from_bl) - 2];
|
||||
pu2_ref_v = pu2_dst[(2 * nbr_id_from_bl) - 1];
|
||||
for(i = 0; i < 8; i+=2)
|
||||
for (i = 0; i < 8 * sub_sample; i += 2)
|
||||
{
|
||||
pu2_dst[(2 * nbr_id_from_bl) + i] = pu2_ref_u;
|
||||
pu2_dst[(2 * nbr_id_from_bl) + 1 + i] = pu2_ref_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
nbr_id_from_bl += (nbr_id_from_bl == (T8C_4NT / 2)) ? 1 : 4;
|
||||
nbr_id_from_bl += (nbr_id_from_bl == (T8C_4NT * sub_sample / 2)) ? 1 : 4 * sub_sample;
|
||||
}
|
||||
}
|
||||
else if(nt == 16)
|
||||
else if (nt == 16 || (nt == 32 && chroma_format_idc == CHROMA_FMT_IDC_YUV444))
|
||||
{
|
||||
WORD32 sub_sample = chroma_format_idc == CHROMA_FMT_IDC_YUV444 ? 2 : 1;
|
||||
/* compute trailing ones based on mbr_flag for substitution process of below left see section .*/
|
||||
/* as each bit in nbr flags corresponds to 4 pels for bot_left, left, top and topright but 1 pel for topleft */
|
||||
{
|
||||
nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 4; /* for bottom left and left */
|
||||
nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 4 * sub_sample; /* for bottom left and left */
|
||||
|
||||
if(nbr_id_from_bl == 32)
|
||||
if (nbr_id_from_bl == 32 * sub_sample)
|
||||
{
|
||||
/* for top left : 1 pel per nbr bit */
|
||||
if(!((nbr_flags >> 16) & 0x1))
|
||||
|
|
@ -384,7 +479,7 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
/* top left not available */
|
||||
nbr_id_from_bl++;
|
||||
/* top and top right; 4 pels per nbr bit */
|
||||
nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 4;
|
||||
nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 4 * sub_sample;
|
||||
}
|
||||
}
|
||||
/* Reverse Substitution Process*/
|
||||
|
|
@ -402,14 +497,14 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
}
|
||||
|
||||
/* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
|
||||
while(nbr_id_from_bl < ((T16C_4NT) + 1))
|
||||
while (nbr_id_from_bl < ((T16C_4NT * sub_sample) + 1))
|
||||
{
|
||||
/* To Obtain the next unavailable idx flag after reverse neighbor substitution */
|
||||
/* Devide by 4 to obtain the original index */
|
||||
frwd_nbr_flag = (nbr_id_from_bl >> 2);/*+ (nbr_id_from_bl & 0x1);*/
|
||||
/* Divide by 4 to obtain the original index */
|
||||
frwd_nbr_flag = (nbr_id_from_bl >> (chroma_format_idc == CHROMA_FMT_IDC_YUV444 ? 3 : 2));/*+ (nbr_id_from_bl & 0x1);*/
|
||||
|
||||
/* The Top-left flag is at the last bit location of nbr_flags*/
|
||||
if(nbr_id_from_bl == (T16C_4NT / 2))
|
||||
if (nbr_id_from_bl == (T16C_4NT * sub_sample / 2))
|
||||
{
|
||||
get_bits = GET_BIT(nbr_flags, 16);
|
||||
/* only pel substitution for TL */
|
||||
|
|
@ -427,14 +522,82 @@ void ihevc_hbd_intra_pred_chroma_ref_substitution(UWORD16 * pu2_top_left,
|
|||
/* 4 pel substitution (other than TL) */
|
||||
pu2_ref_u = pu2_dst[(2 * nbr_id_from_bl) - 2];
|
||||
pu2_ref_v = pu2_dst[(2 * nbr_id_from_bl) - 1];
|
||||
for(i = 0; i < 8; i+=2)
|
||||
for (i = 0; i < 4 * sub_sample; i++)
|
||||
{
|
||||
pu2_dst[(2 * nbr_id_from_bl) + 2 * i] = pu2_ref_u;
|
||||
pu2_dst[(2 * nbr_id_from_bl) + 1 + 2 * i] = pu2_ref_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
nbr_id_from_bl += (nbr_id_from_bl == (T16C_4NT * sub_sample / 2)) ? 1 : 4 * sub_sample;
|
||||
}
|
||||
}
|
||||
else if (nt == 32)
|
||||
{
|
||||
/* compute trailing ones based on mbr_flag for substitution process of below left see section .*/
|
||||
/* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
|
||||
{
|
||||
nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 8; /* for bottom left and left */
|
||||
|
||||
if (nbr_id_from_bl == 64)
|
||||
{
|
||||
/* for top left : 1 pel per nbr bit */
|
||||
if (!((nbr_flags >> 16) & 0x1))
|
||||
{
|
||||
/* top left not available */
|
||||
nbr_id_from_bl++;
|
||||
/* top and top right; 8 pels per nbr bit */
|
||||
nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 8;
|
||||
}
|
||||
}
|
||||
/* Reverse Substitution Process*/
|
||||
if (nbr_id_from_bl)
|
||||
{
|
||||
/* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
|
||||
pu2_ref_u = pu2_dst[2 * nbr_id_from_bl];
|
||||
pu2_ref_v = pu2_dst[2 * nbr_id_from_bl + 1];
|
||||
for (i = (2 * (nbr_id_from_bl - 1)); i >= 0; i -= 2)
|
||||
{
|
||||
pu2_dst[i] = pu2_ref_u;
|
||||
pu2_dst[i + 1] = pu2_ref_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
|
||||
while (nbr_id_from_bl < (128 + 1))
|
||||
{
|
||||
/* To Obtain the next unavailable idx flag after reverse neighbor substitution */
|
||||
/* Devide by 8 to obtain the original index */
|
||||
frwd_nbr_flag = (nbr_id_from_bl >> 3);
|
||||
|
||||
/* The Top-left flag is at the last bit location of nbr_flags*/
|
||||
if (nbr_id_from_bl == 64)
|
||||
{
|
||||
get_bits = GET_BIT(nbr_flags, 16);
|
||||
/* only pel substitution for TL */
|
||||
if (!get_bits)
|
||||
{
|
||||
pu2_dst[2 * nbr_id_from_bl] = pu2_dst[(2 * nbr_id_from_bl) - 2];
|
||||
pu2_dst[(2 * nbr_id_from_bl) + 1] = pu2_dst[(2 * nbr_id_from_bl) - 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
get_bits = GET_BIT(nbr_flags, frwd_nbr_flag);
|
||||
if (!get_bits)
|
||||
{
|
||||
/* 8 pel substitution (other than TL) */
|
||||
pu2_ref_u = pu2_dst[(2 * nbr_id_from_bl) - 2];
|
||||
pu2_ref_v = pu2_dst[(2 * nbr_id_from_bl) - 1];
|
||||
for (i = 0; i < 16; i += 2)
|
||||
{
|
||||
pu2_dst[(2 * nbr_id_from_bl) + i] = pu2_ref_u;
|
||||
pu2_dst[(2 * nbr_id_from_bl) + 1 + i] = pu2_ref_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
nbr_id_from_bl += (nbr_id_from_bl == (T16C_4NT / 2)) ? 1 : 4;
|
||||
nbr_id_from_bl += (nbr_id_from_bl == T16C_4NT) ? 1 : 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1746,7 +1746,7 @@ WORD32 ihevcd_iquant_itrans_recon_ctb(process_ctxt_t *ps_proc)
|
|||
{
|
||||
ps_codec->s_func_selector.ihevc_hbd_intra_pred_chroma_ref_substitution_fptr((UWORD16 *)pu1_top_left,
|
||||
(UWORD16 *)pu1_top, (UWORD16 *)pu1_left, ps_cb_tu->pred_strd, trans_size,
|
||||
chroma_nbr_flags, (UWORD16 *)pu1_ref_sub_out, 1,
|
||||
chroma_nbr_flags, (UWORD16 *)pu1_ref_sub_out, 1, ps_sps->i1_chroma_format_idc,
|
||||
(UWORD8) i4_bit_depth_chroma);
|
||||
|
||||
/* use the look up to get the function idx */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue