aboutsummaryrefslogtreecommitdiff
path: root/Src/h264dec/ldecod/src/quant.c
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/h264dec/ldecod/src/quant.c
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/h264dec/ldecod/src/quant.c')
-rw-r--r--Src/h264dec/ldecod/src/quant.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/Src/h264dec/ldecod/src/quant.c b/Src/h264dec/ldecod/src/quant.c
new file mode 100644
index 00000000..2f01c34a
--- /dev/null
+++ b/Src/h264dec/ldecod/src/quant.c
@@ -0,0 +1,338 @@
+
+/*!
+***********************************************************************
+* \file
+* quant.c
+*
+* \brief
+* Quantization functions
+*
+* \author
+* Main contributors (see contributors.h for copyright, address and affiliation details)
+*
+***********************************************************************
+*/
+
+#include "contributors.h"
+
+#include "global.h"
+#include "memalloc.h"
+#include "block.h"
+#include "image.h"
+#include "mb_access.h"
+#include "transform.h"
+#include "quant.h"
+
+int quant_intra_default[16] = {
+ 6,13,20,28,
+ 13,20,28,32,
+ 20,28,32,37,
+ 28,32,37,42
+};
+
+int quant_inter_default[16] = {
+ 10,14,20,24,
+ 14,20,24,27,
+ 20,24,27,30,
+ 24,27,30,34
+};
+
+int quant8_intra_default[64] = {
+ 6,10,13,16,18,23,25,27,
+ 10,11,16,18,23,25,27,29,
+ 13,16,18,23,25,27,29,31,
+ 16,18,23,25,27,29,31,33,
+ 18,23,25,27,29,31,33,36,
+ 23,25,27,29,31,33,36,38,
+ 25,27,29,31,33,36,38,40,
+ 27,29,31,33,36,38,40,42
+};
+
+int quant8_inter_default[64] = {
+ 9,13,15,17,19,21,22,24,
+ 13,13,17,19,21,22,24,25,
+ 15,17,19,21,22,24,25,27,
+ 17,19,21,22,24,25,27,28,
+ 19,21,22,24,25,27,28,30,
+ 21,22,24,25,27,28,30,32,
+ 22,24,25,27,28,30,32,33,
+ 24,25,27,28,30,32,33,35
+};
+
+int quant_org[16] = { //to be use if no q matrix is chosen
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16
+};
+
+int quant8_org[64] = { //to be use if no q matrix is chosen
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16
+};
+
+static void CalculateQuant8x8Param(Slice *currslice);
+
+/*!
+***********************************************************************
+* \brief
+* Initiate quantization process arrays
+***********************************************************************
+*/
+void init_qp_process(VideoParameters *p_Vid)
+{
+ int bitdepth_qp_scale = imax(p_Vid->bitdepth_luma_qp_scale,p_Vid->bitdepth_chroma_qp_scale);
+ int i;
+
+ // We should allocate memory outside of this process since maybe we will have a change of SPS
+ // and we may need to recreate these. Currently should only support same bitdepth
+ if (p_Vid->qp_per_matrix == NULL)
+ if ((p_Vid->qp_per_matrix = (int*)malloc((MAX_QP + 1 + bitdepth_qp_scale)*sizeof(int))) == NULL)
+ no_mem_exit("init_qp_process: p_Vid->qp_per_matrix");
+
+ if (p_Vid->qp_rem_matrix == NULL)
+ if ((p_Vid->qp_rem_matrix = (int*)malloc((MAX_QP + 1 + bitdepth_qp_scale)*sizeof(int))) == NULL)
+ no_mem_exit("init_qp_process: p_Vid->qp_rem_matrix");
+
+ for (i = 0; i < MAX_QP + bitdepth_qp_scale + 1; i++)
+ {
+ p_Vid->qp_per_matrix[i] = i / 6;
+ p_Vid->qp_rem_matrix[i] = i % 6;
+ }
+}
+
+void free_qp_matrices(VideoParameters *p_Vid)
+{
+ if (p_Vid->qp_per_matrix != NULL)
+ {
+ free (p_Vid->qp_per_matrix);
+ p_Vid->qp_per_matrix = NULL;
+ }
+
+ if (p_Vid->qp_rem_matrix != NULL)
+ {
+ free (p_Vid->qp_rem_matrix);
+ p_Vid->qp_rem_matrix = NULL;
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* For mapping the q-matrix to the active id and calculate quantisation values
+*
+* \param currSlice
+* Slice pointer
+* \param pps
+* Picture parameter set
+* \param sps
+* Sequence parameter set
+*
+************************************************************************
+*/
+void assign_quant_params(Slice *currSlice)
+{
+ seq_parameter_set_rbsp_t* sps = currSlice->active_sps;
+ pic_parameter_set_rbsp_t* pps = currSlice->active_pps;
+ int i;
+ int n_ScalingList;
+
+ if(!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag)
+ {
+ for(i=0; i<12; i++)
+ currSlice->qmatrix[i] = (i < 6) ? quant_org : quant8_org;
+ }
+ else
+ {
+ n_ScalingList = (sps->chroma_format_idc != YUV444) ? 8 : 12;
+ if(sps->seq_scaling_matrix_present_flag) // check sps first
+ {
+ for(i=0; i<n_ScalingList; i++)
+ {
+ if(i<6)
+ {
+ if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A
+ {
+ if(i==0)
+ currSlice->qmatrix[i] = quant_intra_default;
+ else if(i==3)
+ currSlice->qmatrix[i] = quant_inter_default;
+ else
+ currSlice->qmatrix[i] = currSlice->qmatrix[i-1];
+ }
+ else
+ {
+ if(sps->UseDefaultScalingMatrix4x4Flag[i])
+ currSlice->qmatrix[i] = (i<3) ? quant_intra_default : quant_inter_default;
+ else
+ currSlice->qmatrix[i] = sps->ScalingList4x4[i];
+ }
+ }
+ else
+ {
+ if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A
+ {
+ if(i==6)
+ currSlice->qmatrix[i] = quant8_intra_default;
+ else if(i==7)
+ currSlice->qmatrix[i] = quant8_inter_default;
+ else
+ currSlice->qmatrix[i] = currSlice->qmatrix[i-2];
+ }
+ else
+ {
+ if(sps->UseDefaultScalingMatrix8x8Flag[i-6])
+ currSlice->qmatrix[i] = (i==6 || i==8 || i==10) ? quant8_intra_default:quant8_inter_default;
+ else
+ currSlice->qmatrix[i] = sps->ScalingList8x8[i-6];
+ }
+ }
+ }
+ }
+
+ if(pps->pic_scaling_matrix_present_flag) // then check pps
+ {
+ for(i=0; i<n_ScalingList; i++)
+ {
+ if(i<6)
+ {
+ if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B
+ {
+ if (i==0)
+ {
+ if(!sps->seq_scaling_matrix_present_flag)
+ currSlice->qmatrix[i] = quant_intra_default;
+ }
+ else if (i==3)
+ {
+ if(!sps->seq_scaling_matrix_present_flag)
+ currSlice->qmatrix[i] = quant_inter_default;
+ }
+ else
+ currSlice->qmatrix[i] = currSlice->qmatrix[i-1];
+ }
+ else
+ {
+ if(pps->UseDefaultScalingMatrix4x4Flag[i])
+ currSlice->qmatrix[i] = (i<3) ? quant_intra_default:quant_inter_default;
+ else
+ currSlice->qmatrix[i] = pps->ScalingList4x4[i];
+ }
+ }
+ else
+ {
+ if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B
+ {
+ if (i==6)
+ {
+ if(!sps->seq_scaling_matrix_present_flag)
+ currSlice->qmatrix[i] = quant8_intra_default;
+ }
+ else if(i==7)
+ {
+ if(!sps->seq_scaling_matrix_present_flag)
+ currSlice->qmatrix[i] = quant8_inter_default;
+ }
+ else
+ currSlice->qmatrix[i] = currSlice->qmatrix[i-2];
+ }
+ else
+ {
+ if(pps->UseDefaultScalingMatrix8x8Flag[i-6])
+ currSlice->qmatrix[i] = (i==6 || i==8 || i==10) ? quant8_intra_default:quant8_inter_default;
+ else
+ currSlice->qmatrix[i] = pps->ScalingList8x8[i-6];
+ }
+ }
+ }
+ }
+ }
+
+ CalculateQuant4x4Param(currSlice);
+ if(pps->transform_8x8_mode_flag)
+ CalculateQuant8x8Param(currSlice);
+}
+
+/*!
+************************************************************************
+* \brief
+* For calculating the quantisation values at frame level
+*
+************************************************************************
+*/
+void CalculateQuant4x4Param(Slice *currSlice)
+{
+ int i, j, k, temp;
+
+ for(k=0; k<6; k++)
+ {
+ for(i=0; i<4; i++)
+ {
+ for(j=0; j<4; j++)
+ {
+ temp = (i<<2)+j;
+ currSlice->InvLevelScale4x4_Intra[0][k][i][j] = dequant_coef[k][i][j] * currSlice->qmatrix[0][temp];
+ currSlice->InvLevelScale4x4_Intra[1][k][i][j] = dequant_coef[k][i][j] * currSlice->qmatrix[1][temp];
+ currSlice->InvLevelScale4x4_Intra[2][k][i][j] = dequant_coef[k][i][j] * currSlice->qmatrix[2][temp];
+
+ currSlice->InvLevelScale4x4_Inter[0][k][i][j] = dequant_coef[k][i][j] * currSlice->qmatrix[3][temp];
+ currSlice->InvLevelScale4x4_Inter[1][k][i][j] = dequant_coef[k][i][j] * currSlice->qmatrix[4][temp];
+ currSlice->InvLevelScale4x4_Inter[2][k][i][j] = dequant_coef[k][i][j] * currSlice->qmatrix[5][temp];
+ }
+ }
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Calculate the quantisation and inverse quantisation parameters
+*
+************************************************************************
+*/
+static void CalculateQuant8x8Param(Slice *currSlice)
+{
+ VideoParameters *p_Vid = currSlice->p_Vid;
+ int i, j, k, temp;
+
+ for(k=0; k<6; k++)
+ {
+ int x = 0;
+ for(i=0; i<8; i++)
+ {
+ for(j=0; j<8; j++)
+ {
+ temp = (i<<3)+j;
+ currSlice->InvLevelScale8x8_Intra[0][k][x] = dequant_coef8[k][x] * currSlice->qmatrix[6][temp];
+ currSlice->InvLevelScale8x8_Inter[0][k][x] = dequant_coef8[k][x] * currSlice->qmatrix[7][temp];
+ x++;
+ }
+ }
+ }
+
+ if( p_Vid->active_sps->chroma_format_idc == YUV444 ) // 4:4:4
+ {
+ for(k=0; k<6; k++)
+ {
+ int x=0;
+ for(i=0; i<8; i++)
+ {
+ for(j=0; j<8; j++)
+ {
+ temp = (i<<3)+j;
+ currSlice->InvLevelScale8x8_Intra[1][k][x] = dequant_coef8[k][x] * currSlice->qmatrix[8][temp];
+ currSlice->InvLevelScale8x8_Inter[1][k][x] = dequant_coef8[k][x] * currSlice->qmatrix[9][temp];
+ currSlice->InvLevelScale8x8_Intra[2][k][x] = dequant_coef8[k][x] * currSlice->qmatrix[10][temp];
+ currSlice->InvLevelScale8x8_Inter[2][k][x] = dequant_coef8[k][x] * currSlice->qmatrix[11][temp];
+ x++;
+ }
+ }
+ }
+ }
+}