q_offsets.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:22k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file q_offsets.c
  4.  *
  5.  * brief
  6.  *    read Quantization Offset matrix parameters from input file: q_OffsetMatrix.cfg
  7.  *
  8.  *************************************************************************************
  9.  */
  10. #include "global.h"
  11. #include "memalloc.h"
  12. #include "q_matrix.h"
  13. #include "q_offsets.h"
  14. extern char *GetConfigFileContent (char *Filename, int error_type);
  15. #define MAX_ITEMS_TO_PARSE  2000
  16. int offset4x4_check[6] = { 0, 0, 0, 0, 0, 0 };
  17. int offset8x8_check[6] = { 0, 0, 0, 0, 0, 0 };
  18. static const char OffsetType4x4[15][24] = {
  19.   "INTRA4X4_LUMA_INTRA",
  20.   "INTRA4X4_CHROMAU_INTRA",
  21.   "INTRA4X4_CHROMAV_INTRA",
  22.   "INTRA4X4_LUMA_INTERP",
  23.   "INTRA4X4_CHROMAU_INTERP",
  24.   "INTRA4X4_CHROMAV_INTERP",
  25.   "INTRA4X4_LUMA_INTERB",
  26.   "INTRA4X4_CHROMAU_INTERB",
  27.   "INTRA4X4_CHROMAV_INTERB",
  28.   "INTER4X4_LUMA_INTERP",
  29.   "INTER4X4_CHROMAU_INTERP",
  30.   "INTER4X4_CHROMAV_INTERP",
  31.   "INTER4X4_LUMA_INTERB",
  32.   "INTER4X4_CHROMAU_INTERB",
  33.   "INTER4X4_CHROMAV_INTERB"
  34. };
  35. static const char OffsetType8x8[15][24] = {
  36.   "INTRA8X8_LUMA_INTRA",
  37.   "INTRA8X8_LUMA_INTERP",
  38.   "INTRA8X8_LUMA_INTERB",
  39.   "INTER8X8_LUMA_INTERP",
  40.   "INTER8X8_LUMA_INTERB",
  41.   "INTRA8X8_CHROMAU_INTRA",
  42.   "INTRA8X8_CHROMAU_INTERP",
  43.   "INTRA8X8_CHROMAU_INTERB",
  44.   "INTER8X8_CHROMAU_INTERP",
  45.   "INTER8X8_CHROMAU_INTERB",
  46.   "INTRA8X8_CHROMAV_INTRA",
  47.   "INTRA8X8_CHROMAV_INTERP",
  48.   "INTRA8X8_CHROMAV_INTERB",
  49.   "INTER8X8_CHROMAV_INTERP",
  50.   "INTER8X8_CHROMAV_INTERB"
  51. };
  52. int *****LevelOffset4x4Comp;
  53. int *****LevelOffset8x8Comp;
  54. // global pointers for level offset matrices
  55. int ****ptLevelOffset4x4;
  56. int ****ptLevelOffset8x8;
  57. int AdaptRndWeight;
  58. int AdaptRndCrWeight;
  59. short **OffsetList4x4input;
  60. short **OffsetList8x8input;
  61. short ***OffsetList4x4;
  62. short ***OffsetList8x8;
  63. void InitOffsetParam ();
  64. const int OffsetBits = 11;
  65. static const short Offset_intra_default_intra[16] = {
  66.   682, 682, 682, 682,
  67.   682, 682, 682, 682,
  68.   682, 682, 682, 682,
  69.   682, 682, 682, 682
  70. };
  71. static const short Offset_intra_default_chroma[16] = {
  72.   682, 682, 682, 682,
  73.   682, 682, 682, 682,
  74.   682, 682, 682, 682,
  75.   682, 682, 682, 682
  76. };
  77. static const short Offset_intra_default_inter[16] = {
  78.   342, 342, 342, 342,
  79.   342, 342, 342, 342,
  80.   342, 342, 342, 342,
  81.   342, 342, 342, 342,
  82. };
  83. static const short Offset_inter_default[16] = {
  84.   342, 342, 342, 342,
  85.   342, 342, 342, 342,
  86.   342, 342, 342, 342,
  87.   342, 342, 342, 342,
  88. };
  89. static const short Offset8_intra_default_intra[64] = {
  90.   682, 682, 682, 682, 682, 682, 682, 682,
  91.   682, 682, 682, 682, 682, 682, 682, 682,
  92.   682, 682, 682, 682, 682, 682, 682, 682,
  93.   682, 682, 682, 682, 682, 682, 682, 682,
  94.   682, 682, 682, 682, 682, 682, 682, 682,
  95.   682, 682, 682, 682, 682, 682, 682, 682,
  96.   682, 682, 682, 682, 682, 682, 682, 682,
  97.   682, 682, 682, 682, 682, 682, 682, 682
  98. };
  99. static const short Offset8_intra_default_chroma[64] = {
  100.   682, 682, 682, 682, 682, 682, 682, 682,
  101.   682, 682, 682, 682, 682, 682, 682, 682,
  102.   682, 682, 682, 682, 682, 682, 682, 682,
  103.   682, 682, 682, 682, 682, 682, 682, 682,
  104.   682, 682, 682, 682, 682, 682, 682, 682,
  105.   682, 682, 682, 682, 682, 682, 682, 682,
  106.   682, 682, 682, 682, 682, 682, 682, 682,
  107.   682, 682, 682, 682, 682, 682, 682, 682
  108. };
  109. static const short Offset8_intra_default_inter[64] = {
  110.   342, 342, 342, 342, 342, 342, 342, 342,
  111.   342, 342, 342, 342, 342, 342, 342, 342,
  112.   342, 342, 342, 342, 342, 342, 342, 342,
  113.   342, 342, 342, 342, 342, 342, 342, 342,
  114.   342, 342, 342, 342, 342, 342, 342, 342,
  115.   342, 342, 342, 342, 342, 342, 342, 342,
  116.   342, 342, 342, 342, 342, 342, 342, 342,
  117.   342, 342, 342, 342, 342, 342, 342, 342
  118. };
  119. static const short Offset8_inter_default[64] = {
  120.   342, 342, 342, 342, 342, 342, 342, 342,
  121.   342, 342, 342, 342, 342, 342, 342, 342,
  122.   342, 342, 342, 342, 342, 342, 342, 342,
  123.   342, 342, 342, 342, 342, 342, 342, 342,
  124.   342, 342, 342, 342, 342, 342, 342, 342,
  125.   342, 342, 342, 342, 342, 342, 342, 342,
  126.   342, 342, 342, 342, 342, 342, 342, 342,
  127.   342, 342, 342, 342, 342, 342, 342, 342
  128. };
  129. /*!
  130.  ***********************************************************************
  131.  * brief
  132.  *    Allocate Q matrix arrays
  133.  ***********************************************************************
  134.  */
  135. void allocate_QOffsets ()
  136. {
  137.   int max_bitdepth = imax(params->output.bit_depth[0], params->output.bit_depth[1]);
  138.   int max_qp = (3 + 6*(max_bitdepth));
  139.   get_mem5Dint(&LevelOffset4x4Comp, 3, 2, max_qp + 1, 4, 4);
  140.   get_mem5Dint(&LevelOffset8x8Comp, 3, 2, max_qp + 1, 8, 8);
  141.   if (params->AdaptRoundingFixed)
  142.   {
  143.     get_mem3Dshort(&OffsetList4x4, 1, 25, 16);
  144.     get_mem3Dshort(&OffsetList8x8, 1, 15, 64);    
  145.   }
  146.   else
  147.   {
  148.     get_mem3Dshort(&OffsetList4x4, max_qp + 1, 25, 16);
  149.     get_mem3Dshort(&OffsetList8x8, max_qp + 1, 15, 64);    
  150.   }
  151.   get_mem2Dshort(&OffsetList4x4input, 25, 16);
  152.   get_mem2Dshort(&OffsetList8x8input, 15, 64);
  153. }
  154. /*!
  155.  ***********************************************************************
  156.  * brief
  157.  *    Free Q matrix arrays
  158.  ***********************************************************************
  159.  */
  160. void free_QOffsets ()
  161. {
  162.   free_mem5Dint(LevelOffset4x4Comp);
  163.   free_mem5Dint(LevelOffset8x8Comp);
  164.   if (params->AdaptRoundingFixed)
  165.   {
  166.     free_mem3Dshort(OffsetList8x8);
  167.     free_mem3Dshort(OffsetList4x4);    
  168.   }
  169.   else
  170.   {
  171.     free_mem3Dshort(OffsetList8x8);
  172.     free_mem3Dshort(OffsetList4x4);    
  173.   }
  174.   free_mem2Dshort(OffsetList8x8input);
  175.   free_mem2Dshort(OffsetList4x4input);
  176. }
  177. /*!
  178.  ***********************************************************************
  179.  * brief
  180.  *    Check the parameter name.
  181.  * param s
  182.  *    parameter name string
  183.  * param type
  184.  *    4x4 or 8x8 offset matrix type
  185.  * return
  186.  *    the index number if the string is a valid parameter name,         n
  187.  *    -1 for error
  188.  ***********************************************************************
  189.  */
  190. int CheckOffsetParameterName (char *s, int *type)
  191. {
  192.   int i = 0;
  193.   *type = 0;
  194.   while ((OffsetType4x4[i] != NULL) && (i < 15))
  195.   {
  196.     if (0 == strcmp (OffsetType4x4[i], s))
  197.       return i;
  198.     else
  199.       i++;
  200.   }
  201.   i = 0;
  202.   *type = 1;
  203.   while ((OffsetType8x8[i] != NULL) && (i < 15))
  204.   {
  205.     if (0 == strcmp (OffsetType8x8[i], s))
  206.       return i;
  207.     else
  208.       i++;
  209.   }
  210.   return -1;
  211. }
  212. /*!
  213.  ***********************************************************************
  214.  * brief
  215.  *    Parse the Q Offset Matrix values read from cfg file.
  216.  * param buf
  217.  *    buffer to be parsed
  218.  * param bufsize
  219.  *    buffer size of buffer
  220.  ***********************************************************************
  221.  */
  222. void ParseQOffsetMatrix (char *buf, int bufsize)
  223. {
  224.   char *items[MAX_ITEMS_TO_PARSE];
  225.   int MapIdx;
  226.   int item = 0;
  227.   int InString = 0, InItem = 0;
  228.   char *p = buf;
  229.   char *bufend = &buf[bufsize];
  230.   int IntContent;
  231.   int i, j, range, type, cnt;
  232.   short *OffsetList;
  233.   while (p < bufend)
  234.   {
  235.     switch (*p)
  236.     {
  237.       case 13:
  238.         p++;
  239.         break;
  240.       case '#':                 // Found comment
  241.         *p = '';              // Replace '#' with '' in case of comment immediately following integer or string
  242.         while (*p != 'n' && p < bufend)  // Skip till EOL or EOF, whichever comes first
  243.           p++;
  244.         InString = 0;
  245.         InItem = 0;
  246.         break;
  247.       case 'n':
  248.         InItem = 0;
  249.         InString = 0;
  250.       *p++ = '';
  251.         break;
  252.       case ' ':
  253.       case 't':              // Skip whitespace, leave state unchanged
  254.         if (InString)
  255.           p++;
  256.         else
  257.         {                     // Terminate non-strings once whitespace is found
  258.           *p++ = '';
  259.           InItem = 0;
  260.         }
  261.         break;
  262.       case '"':               // Begin/End of String
  263.         *p++ = '';
  264.         if (!InString)
  265.         {
  266.           items[item++] = p;
  267.           InItem = ~InItem;
  268.         }
  269.         else
  270.           InItem = 0;
  271.         InString = ~InString; // Toggle
  272.         break;
  273.       case ',':
  274.         p++;
  275.         InItem = 0;
  276.         break;
  277.       default:
  278.         if (!InItem)
  279.         {
  280.           items[item++] = p;
  281.           InItem = ~InItem;
  282.         }
  283.         p++;
  284.     }
  285.   }
  286.   item--;
  287.   for (i = 0; i < item; i += cnt)
  288.   {
  289.     cnt = 0;
  290.     if (0 > (MapIdx = CheckOffsetParameterName (items[i + cnt], &type)))
  291.     {
  292.       snprintf (errortext, ET_SIZE,
  293.         " Parsing error in config file: Parameter Name '%s' not recognized.",
  294.         items[i + cnt]);
  295.       error (errortext, 300);
  296.     }
  297.     cnt++;
  298.     if (strcmp ("=", items[i + cnt]))
  299.     {
  300.       snprintf (errortext, ET_SIZE,
  301.         " Parsing error in config file: '=' expected as the second token in each item.");
  302.       error (errortext, 300);
  303.     }
  304.     cnt++;
  305.     if (!type) //4x4 Matrix
  306.     {
  307.       range = 16;
  308.       OffsetList = OffsetList4x4input[MapIdx];
  309.       offset4x4_check[MapIdx] = 1; //to indicate matrix found in cfg file
  310.     }
  311.     else //8x8 matrix
  312.     {
  313.       range = 64;
  314.       OffsetList = OffsetList8x8input[MapIdx];
  315.       offset8x8_check[MapIdx] = 1; //to indicate matrix found in cfg file
  316.     }
  317.     for (j = 0; j < range; j++)
  318.     {
  319.       if (1 != sscanf (items[i + cnt + j], "%d", &IntContent))
  320.       {
  321.         snprintf (errortext, ET_SIZE,
  322.           " Parsing error: Expected numerical value for Parameter of %s, found '%s'.",
  323.           items[i], items[i + cnt + j]);
  324.         error (errortext, 300);
  325.       }
  326.       OffsetList[j] = (short) IntContent; //save value in matrix
  327.     }
  328.     cnt += j;
  329.     printf (".");
  330.   }
  331. }
  332. /*!
  333.  ***********************************************************************
  334.  * brief
  335.  *    Initialise Q offset matrix values.
  336.  ***********************************************************************
  337.  */
  338. void Init_QOffsetMatrix ()
  339. {
  340.   char *content;
  341.   allocate_QOffsets ();
  342.   if (params->OffsetMatrixPresentFlag)
  343.   {
  344.     printf ("Parsing Quantization Offset Matrix file %s ",
  345.       params->QOffsetMatrixFile);
  346.     content = GetConfigFileContent (params->QOffsetMatrixFile, 0);
  347.     if (content != '')
  348.       ParseQOffsetMatrix (content, strlen (content));
  349.     else
  350.     {
  351.       printf
  352.         ("nError: %snProceeding with default values for all matrices.",
  353.         errortext);
  354.       params->OffsetMatrixPresentFlag = 0;
  355.     }
  356.     printf ("n");
  357.     free (content);
  358.   }
  359.   //! Now set up all offset params. This process could be reused if we wish to re-init offsets
  360.   InitOffsetParam ();
  361. }
  362. /*!
  363.  ************************************************************************
  364.  * brief
  365.  *    Intit quantization offset params
  366.  *
  367.  * par Input:
  368.  *    none
  369.  *
  370.  * par Output:
  371.  *    none
  372.  ************************************************************************
  373.  */
  374. void InitOffsetParam ()
  375. {
  376.   int i, k;
  377.   int max_qp_luma = (4 + 6*(params->output.bit_depth[0]));
  378.   int max_qp_cr   = (4 + 6*(params->output.bit_depth[1]));
  379.   for (i = 0; i < (params->AdaptRoundingFixed ? 1 : imax(max_qp_luma, max_qp_cr)); i++)
  380.   {
  381.     if (params->OffsetMatrixPresentFlag)
  382.     {
  383.       memcpy(&(OffsetList4x4[i][0][0]),&(OffsetList4x4input[0][0]), 400 * sizeof(short)); // 25 * 16
  384.       memcpy(&(OffsetList8x8[i][0][0]),&(OffsetList8x8input[0][0]), 960 * sizeof(short)); // 15 * 64
  385.     }
  386.     else
  387.     {
  388.       // 0 (INTRA4X4_LUMA_INTRA)
  389.       memcpy(&(OffsetList4x4[i][0][0]),&(Offset_intra_default_intra[0]), 16 * sizeof(short));
  390.       for (k = 1; k < 3; k++) // 1,2 (INTRA4X4_CHROMA_INTRA)
  391.         memcpy(&(OffsetList4x4[i][k][0]),&(Offset_intra_default_chroma[0]),  16 * sizeof(short));
  392.       for (k = 3; k < 9; k++) // 3,4,5,6,7,8 (INTRA4X4_LUMA/CHROMA_INTERP/INTERB)
  393.         memcpy(&(OffsetList4x4[i][k][0]),&(Offset_intra_default_inter[0]),  16 * sizeof(short));
  394.       for (k = 9; k < 25; k++) // 9,10,11,12,13,14 (INTER4X4)
  395.         memcpy(&(OffsetList4x4[i][k][0]),&(Offset_inter_default[0]),  16 * sizeof(short));
  396.       // 0 (INTRA8X8_LUMA_INTRA)
  397.       memcpy(&(OffsetList8x8[i][0][0]),&(Offset8_intra_default_intra[0]), 64 * sizeof(short));
  398.       for (k = 1; k < 3; k++)  // 1,2 (INTRA8X8_LUMA_INTERP/INTERB)
  399.         memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]),  64 * sizeof(short));
  400.       for (k = 3; k < 5; k++)  // 3,4 (INTER8X8_LUMA_INTERP/INTERB)
  401.         memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]),  64 * sizeof(short));
  402.       // 5 (INTRA8X8_CHROMAU_INTRA)
  403.       memcpy(&(OffsetList8x8[i][5][0]),&(Offset8_intra_default_chroma[0]), 64 * sizeof(short));
  404.       for (k = 6; k < 8; k++)  // 6,7 (INTRA8X8_CHROMAU_INTERP/INTERB)
  405.         memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]),  64 * sizeof(short));
  406.       for (k = 8; k < 10; k++)  // 8,9 (INTER8X8_CHROMAU_INTERP/INTERB)
  407.         memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]),  64 * sizeof(short));
  408.       // 10 (INTRA8X8_CHROMAV_INTRA)
  409.       memcpy(&(OffsetList8x8[i][10][0]),&(Offset8_intra_default_chroma[0]), 64 * sizeof(short));
  410.       for (k = 11; k < 13; k++)  // 11,12 (INTRA8X8_CHROMAV_INTERP/INTERB)
  411.         memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]),  64 * sizeof(short));
  412.       for (k = 13; k < 15; k++)  // 8,9 (INTER8X8_CHROMAV_INTERP/INTERB)
  413.         memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]),  64 * sizeof(short));
  414.     }
  415.   }  
  416. }
  417. /*!
  418.  ************************************************************************
  419.  * brief
  420.  *    Calculation of the quantization offset params at the frame level
  421.  *
  422.  * par Input:
  423.  *    none
  424.  *
  425.  * par Output:
  426.  *    none
  427.  ************************************************************************
  428.  */
  429. void CalculateOffsetParam ()
  430. {
  431.   int i, j, k, temp;  
  432.   int qp_per, qp;
  433.   short **OffsetList;
  434.   static int **LevelOffsetCmp0Intra, **LevelOffsetCmp1Intra, **LevelOffsetCmp2Intra;
  435.   static int **LevelOffsetCmp0Inter, **LevelOffsetCmp1Inter, **LevelOffsetCmp2Inter;
  436.   int img_type = (img->type == SI_SLICE ? I_SLICE : (img->type == SP_SLICE ? P_SLICE : img->type));
  437.   int max_qp_scale = imax(img->bitdepth_luma_qp_scale, img->bitdepth_chroma_qp_scale);
  438.   int max_qp = 51 + max_qp_scale;
  439.   AdaptRndWeight = params->AdaptRndWFactor[img->nal_reference_idc != 0][img_type];
  440.   AdaptRndCrWeight = params->AdaptRndCrWFactor[img->nal_reference_idc != 0][img_type];
  441.   if (img_type == I_SLICE )
  442.   {
  443.     for (qp = 0; qp < max_qp + 1; qp++)
  444.     {
  445.       k = qp_per_matrix [qp];
  446.       qp_per = Q_BITS + k - OffsetBits;
  447.       OffsetList = OffsetList4x4[params->AdaptRoundingFixed ? 0 : qp];
  448.       LevelOffsetCmp0Intra = LevelOffset4x4Comp[0][1][qp];
  449.       LevelOffsetCmp1Intra = LevelOffset4x4Comp[1][1][qp];
  450.       LevelOffsetCmp2Intra = LevelOffset4x4Comp[2][1][qp];
  451.       temp = 0;
  452.       for (j = 0; j < 4; j++)
  453.       {
  454.         for (i = 0; i < 4; i++, temp++)
  455.         {
  456.           LevelOffsetCmp0Intra[j][i] = (int) OffsetList[0][temp] << qp_per;
  457.           LevelOffsetCmp1Intra[j][i] = (int) OffsetList[1][temp] << qp_per;
  458.           LevelOffsetCmp2Intra[j][i] = (int) OffsetList[2][temp] << qp_per;
  459.         }
  460.       }
  461.     }
  462.   }
  463.   else if (img_type == B_SLICE)
  464.   {
  465.     for (qp = 0; qp < max_qp + 1; qp++)
  466.     {
  467.       k = qp_per_matrix [qp];
  468.       qp_per = Q_BITS + k - OffsetBits;
  469.       OffsetList = OffsetList4x4[params->AdaptRoundingFixed ? 0 : qp];
  470.       LevelOffsetCmp0Intra = LevelOffset4x4Comp[0][1][qp];
  471.       LevelOffsetCmp1Intra = LevelOffset4x4Comp[1][1][qp];
  472.       LevelOffsetCmp2Intra = LevelOffset4x4Comp[2][1][qp];
  473.       LevelOffsetCmp0Inter = LevelOffset4x4Comp[0][0][qp];
  474.       LevelOffsetCmp1Inter = LevelOffset4x4Comp[1][0][qp];
  475.       LevelOffsetCmp2Inter = LevelOffset4x4Comp[2][0][qp];
  476.       for (temp = 0, j = 0; j < 4; j++)
  477.       {
  478.         for (i = 0; i < 4; i++, temp++)
  479.         {          
  480.           // intra
  481.           LevelOffsetCmp0Intra[j][i] = (int) OffsetList[6][temp] << qp_per;
  482.           LevelOffsetCmp1Intra[j][i] = (int) OffsetList[7][temp] << qp_per;
  483.           LevelOffsetCmp2Intra[j][i] = (int) OffsetList[8][temp] << qp_per;
  484.         }
  485.       }
  486.       for (temp = 0, j = 0; j < 4; j++)
  487.       {
  488.         for (i = 0; i < 4; i++, temp++)
  489.         {          
  490.           // inter
  491.           LevelOffsetCmp0Inter[j][i] = (int) OffsetList[12][temp] << qp_per;
  492.           LevelOffsetCmp1Inter[j][i] = (int) OffsetList[13][temp] << qp_per;
  493.           LevelOffsetCmp2Inter[j][i] = (int) OffsetList[14][temp] << qp_per;
  494.         }
  495.       }
  496.     }
  497.   }
  498.   else
  499.   {
  500.     for (qp = 0; qp < max_qp + 1; qp++)
  501.     {
  502.       k = qp_per_matrix [qp];
  503.       qp_per = Q_BITS + k - OffsetBits;
  504.       OffsetList = OffsetList4x4[params->AdaptRoundingFixed ? 0 : qp];
  505.       LevelOffsetCmp0Intra = LevelOffset4x4Comp[0][1][qp];
  506.       LevelOffsetCmp1Intra = LevelOffset4x4Comp[1][1][qp];
  507.       LevelOffsetCmp2Intra = LevelOffset4x4Comp[2][1][qp];
  508.       LevelOffsetCmp0Inter = LevelOffset4x4Comp[0][0][qp];
  509.       LevelOffsetCmp1Inter = LevelOffset4x4Comp[1][0][qp];
  510.       LevelOffsetCmp2Inter = LevelOffset4x4Comp[2][0][qp];
  511.       temp = 0;
  512.       for (j = 0; j < 4; j++)
  513.       {
  514.         for (i = 0; i < 4; i++, temp++)
  515.         {
  516.           // intra
  517.           LevelOffsetCmp0Intra[j][i] = (int) OffsetList[3][temp] << qp_per;
  518.           LevelOffsetCmp1Intra[j][i] = (int) OffsetList[4][temp] << qp_per;
  519.           LevelOffsetCmp2Intra[j][i] = (int) OffsetList[5][temp] << qp_per;
  520.           // inter
  521.           LevelOffsetCmp0Inter[j][i] = (int) OffsetList[9 ][temp] << qp_per;
  522.           LevelOffsetCmp1Inter[j][i] = (int) OffsetList[10][temp] << qp_per;
  523.           LevelOffsetCmp2Inter[j][i] = (int) OffsetList[11][temp] << qp_per;
  524.         }
  525.       }      
  526.     }
  527.   }
  528.   // setting for 4x4 luma quantization offset
  529.   if( IS_INDEPENDENT(params) )
  530.   {
  531.     if( img->colour_plane_id == 0 )
  532.     {
  533.       ptLevelOffset4x4 = LevelOffset4x4Comp[0];
  534.     }
  535.     else if( img->colour_plane_id == 1 )
  536.     {
  537.       ptLevelOffset4x4   = LevelOffset4x4Comp[1];
  538.     }
  539.     else if( img->colour_plane_id == 2 )
  540.     {
  541.       ptLevelOffset4x4   = LevelOffset4x4Comp[2];
  542.     }
  543.   }
  544.   else
  545.   {
  546.     ptLevelOffset4x4 = LevelOffset4x4Comp[0];
  547.   }
  548. }
  549. /*!
  550.  ************************************************************************
  551.  * brief
  552.  *    Calculate the quantisation offset parameters
  553.  *
  554.  ************************************************************************
  555. */
  556. void CalculateOffset8Param ()
  557. {
  558.   int i, j, k, temp;
  559.   int q_bits, qp;
  560.   int max_qp_scale = imax(img->bitdepth_luma_qp_scale, img->bitdepth_chroma_qp_scale);
  561.   int max_qp = 51 + max_qp_scale;
  562.   if (img->type == I_SLICE || img->type == SI_SLICE )
  563.   {
  564.     for (qp = 0; qp < max_qp + 1; qp++)
  565.     {
  566.       q_bits = Q_BITS_8 + qp_per_matrix[qp] - OffsetBits;
  567.       k = params->AdaptRoundingFixed ? 0 : qp;
  568.       for (j = 0; j < 8; j++)
  569.       {
  570.         temp = (j << 3);
  571.         for (i = 0; i < 8; i++)
  572.         {          
  573.           // INTRA8X8
  574.           LevelOffset8x8Comp[0][1][qp][j][i] = (int) OffsetList8x8[k][0][temp] << q_bits;
  575.           // INTRA8X8 CHROMAU
  576.           LevelOffset8x8Comp[1][1][qp][j][i] = (int) OffsetList8x8[k][5][temp] << q_bits;
  577.           // INTRA8X8 CHROMAV
  578.           LevelOffset8x8Comp[2][1][qp][j][i] = (int) OffsetList8x8[k][10][temp++] << q_bits;
  579.         }
  580.       }
  581.     }
  582.   }
  583.   else if ((img->type == P_SLICE) || (img->type == SP_SLICE))
  584.   {
  585.     for (qp = 0; qp < max_qp + 1; qp++)
  586.     {
  587.       q_bits = Q_BITS_8 + qp_per_matrix[qp] - OffsetBits;
  588.       k = params->AdaptRoundingFixed ? 0 : qp;
  589.       for (j = 0; j < 8; j++)
  590.       {
  591.         temp = (j << 3);
  592.         for (i = 0; i < 8; i++)
  593.         {
  594.           // INTRA8X8
  595.           LevelOffset8x8Comp[0][1][qp][j][i] = (int) OffsetList8x8[k][1][temp] << q_bits;
  596.           // INTER8X8
  597.           LevelOffset8x8Comp[0][0][qp][j][i] = (int) OffsetList8x8[k][3][temp] << q_bits;
  598.           // INTRA8X8 CHROMAU
  599.           LevelOffset8x8Comp[1][1][qp][j][i] = (int) OffsetList8x8[k][6][temp] << q_bits;
  600.           // INTER8X8 CHROMAU
  601.           LevelOffset8x8Comp[1][0][qp][j][i] = (int) OffsetList8x8[k][8][temp] << q_bits;
  602.           // INTRA8X8 CHROMAV
  603.           LevelOffset8x8Comp[2][1][qp][j][i] = (int) OffsetList8x8[k][11][temp] << q_bits;
  604.           // INTER8X8 CHROMAV
  605.           LevelOffset8x8Comp[2][0][qp][j][i] = (int) OffsetList8x8[k][13][temp++] << q_bits;
  606.         }
  607.       }
  608.     }
  609.   }
  610.   else
  611.   {
  612.     for (qp = 0; qp < max_qp + 1; qp++)
  613.     {
  614.       q_bits = Q_BITS_8 + qp_per_matrix[qp] - OffsetBits;
  615.       k = params->AdaptRoundingFixed ? 0 : qp;
  616.       for (j = 0; j < 8; j++)
  617.       {
  618.         temp = (j << 3);
  619.         for (i = 0; i < 8; i++)
  620.         {
  621.           // INTRA8X8
  622.           LevelOffset8x8Comp[0][1][qp][j][i] = (int) OffsetList8x8[k][2][temp] << q_bits;
  623.           // INTER8X8
  624.           LevelOffset8x8Comp[0][0][qp][j][i] = (int) OffsetList8x8[k][4][temp] << q_bits;
  625.           // INTRA8X8 CHROMAU
  626.           LevelOffset8x8Comp[1][1][qp][j][i] = (int) OffsetList8x8[k][7][temp] << q_bits;
  627.           // INTER8X8 CHROMAU
  628.           LevelOffset8x8Comp[1][0][qp][j][i] = (int) OffsetList8x8[k][9][temp] << q_bits;
  629.           // INTRA8X8 CHROMAV
  630.           LevelOffset8x8Comp[2][1][qp][j][i] = (int) OffsetList8x8[k][12][temp] << q_bits;
  631.           // INTER8X8 CHROMAV
  632.           LevelOffset8x8Comp[2][0][qp][j][i] = (int) OffsetList8x8[k][14][temp++] << q_bits;
  633.         }
  634.       }
  635.     }
  636.   }
  637.   // setting for 8x8 luma quantization offset
  638.   if( IS_INDEPENDENT(params) )
  639.   {
  640.     if( img->colour_plane_id == 0 )
  641.     {
  642.       ptLevelOffset8x8 = LevelOffset8x8Comp[0];
  643.     }
  644.     else if( img->colour_plane_id == 1 )
  645.     {
  646.       ptLevelOffset8x8 = LevelOffset8x8Comp[1];
  647.     }
  648.     else if( img->colour_plane_id == 2 )
  649.     {
  650.       ptLevelOffset8x8 = LevelOffset8x8Comp[2];
  651.     }
  652.   }
  653.   else
  654.   {
  655.     ptLevelOffset8x8 = LevelOffset8x8Comp[0];
  656.   }
  657. }
  658. void SelectColorType (int colour_id)
  659. {
  660.   switch (colour_id)
  661.   {
  662.   case 0:
  663.   default:
  664.     ptLevelOffset8x8   = LevelOffset8x8Comp[0];
  665.     break;
  666.   case 1:
  667.     ptLevelOffset8x8   = LevelOffset8x8Comp[1];
  668.     break;
  669.   case 2:
  670.     ptLevelOffset8x8   = LevelOffset8x8Comp[2];
  671.     break;
  672.   }
  673. }