Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
      3  * Copyright (c) Imagination Technologies Limited, UK
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial portions
     15  * of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  * Authors:
     26  *    Edward Lin <edward.lin (at) intel.com>
     27  *
     28  */
     29 
     30 #include <unistd.h>
     31 #include <stdio.h>
     32 #include <malloc.h>
     33 #include <memory.h>
     34 #include "psb_drv_video.h"
     35 #include "psb_drv_debug.h"
     36 #include "tng_hostdefs.h"
     37 #include "tng_hostcode.h"
     38 #include "tng_hostair.h"
     39 
     40 /***********************************************************************************
     41  * Function Name     : functions of pi8AIR_Table table
     42  ************************************************************************************/
     43 VAStatus tng_air_buf_create(context_ENC_p ctx)
     44 {
     45     IMG_UINT32 ui32MbNum = (ctx->ui16PictureHeight * ctx->ui16Width) >> 8;
     46     ctx->sAirInfo.pi8AIR_Table = (IMG_INT8 *)malloc(ui32MbNum);
     47     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ui32MbNum = %d\n", __FUNCTION__, ui32MbNum);
     48     if (!ctx->sAirInfo.pi8AIR_Table) {
     49         drv_debug_msg(VIDEO_DEBUG_ERROR,
     50             "\nERROR: Error allocating Adaptive Intra Refresh table of Application context (APP_SetVideoParams)");
     51         return VA_STATUS_ERROR_ALLOCATION_FAILED;
     52     }
     53     memset(ctx->sAirInfo.pi8AIR_Table, 0, ui32MbNum);
     54     return VA_STATUS_SUCCESS;
     55 }
     56 
     57 static void tng_air_buf_clear(context_ENC_p ctx)
     58 {
     59 #if 0
     60     IMG_UINT32 ui32MbNum = (ctx->ui16PictureHeight * ctx->ui16Width) >> 8;
     61     drv_debug_msg(VIDEO_DEBUG_ERROR,"%s: ui32MbNum = %d, ctx->sAirInfo.pi8AIR_Table = 0x%08x\n", __FUNCTION__, ui32MbNum, ctx->sAirInfo.pi8AIR_Table);
     62     memset(ctx->sAirInfo.pi8AIR_Table, 0, ui32MbNum);
     63     drv_debug_msg(VIDEO_DEBUG_ERROR,"%s: ui32MbNum = %d, ctx->sAirInfo.pi8AIR_Table = 0x%08x\n", __FUNCTION__, ui32MbNum, ctx->sAirInfo.pi8AIR_Table);
     64 #endif
     65     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
     66         MTX_CMDID_SW_AIR_BUF_CLEAR, 0, 0, 0);
     67     return ;
     68 }
     69 
     70 void tng_air_buf_free(context_ENC_p ctx)
     71 {
     72     if (ctx->sAirInfo.pi8AIR_Table != NULL)
     73         free(ctx->sAirInfo.pi8AIR_Table);
     74     return ;
     75 }
     76 
     77 /***********************************************************************************
     78  * Function Name     : functions for input control
     79  ************************************************************************************/
     80 static IMG_UINT16 tng__rand(context_ENC_p ctx)
     81 {
     82     IMG_UINT16 ui16ret = 0;
     83     ctx->ui32pseudo_rand_seed =  (IMG_UINT32) ((ctx->ui32pseudo_rand_seed * 1103515245 + 12345) & 0xffffffff); //Using mask, just in case
     84     ui16ret = (IMG_UINT16)(ctx->ui32pseudo_rand_seed / 65536) % 32768;
     85     return ui16ret;
     86 }
     87 
     88 //APP_FillSliceMap
     89 IMG_UINT32 tng_fill_slice_map(context_ENC_p ctx, IMG_INT32 i32SlotNum, IMG_UINT32 ui32StreamIndex)
     90 {
     91     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
     92     unsigned char *pvBuffer;
     93     IMG_UINT8 ui8SlicesPerPicture;
     94     IMG_UINT8 ui8HalfWaySlice;
     95     IMG_UINT32 ui32HalfwayBU;
     96 
     97     ui8SlicesPerPicture = ctx->ui8SlicesPerPicture;
     98     ui32HalfwayBU = 0;
     99     ui8HalfWaySlice=ui8SlicesPerPicture/2;
    100     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: slot num = %d, aso = %d\n", __FUNCTION__, i32SlotNum, ctx->bArbitrarySO);
    101     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: stream id = %d, addr = 0x%x\n", __FUNCTION__, ui32StreamIndex, ps_mem->bufs_slice_map.virtual_addr);
    102 
    103     psb_buffer_map(&(ps_mem->bufs_slice_map), &(ps_mem->bufs_slice_map.virtual_addr));
    104     if (ps_mem->bufs_slice_map.virtual_addr == NULL) {
    105         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice map\n", __FUNCTION__);
    106         goto out1;
    107     }
    108 
    109     pvBuffer = (unsigned char*)(ps_mem->bufs_slice_map.virtual_addr + (i32SlotNum * ctx->ctx_mem_size.slice_map));
    110     if (pvBuffer == NULL) {
    111         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: pvBuffer == NULL\n", __FUNCTION__);
    112         goto out1;
    113     }
    114 
    115     if (ctx->bArbitrarySO) {
    116         IMG_UINT8 ui8Index;
    117         IMG_UINT8 ui32FirstBUInSlice;
    118         IMG_UINT8 ui8SizeInKicks;
    119         IMG_UINT8 ui8TotalBUs;
    120         IMG_UINT8 aui8SliceNumbers[MAX_SLICESPERPIC];
    121 
    122 	memset(aui8SliceNumbers, 0, MAX_SLICESPERPIC);
    123 
    124         ui8SlicesPerPicture = tng__rand(ctx) % ctx->ui8SlicesPerPicture + 1;
    125         // Fill slice map
    126         // Fill number of slices
    127         * pvBuffer = ui8SlicesPerPicture;
    128         pvBuffer++;
    129 
    130         for (ui8Index = 0; ui8Index < ui8SlicesPerPicture; ui8Index++)
    131             aui8SliceNumbers[ui8Index] = ui8Index;
    132 
    133 	// randomise slice numbers
    134         for (ui8Index = 0; ui8Index < 20; ui8Index++) {
    135             IMG_UINT8 ui8FirstCandidate;
    136             IMG_UINT8 ui8SecondCandidate;
    137             IMG_UINT8 ui8Temp;
    138 
    139             ui8FirstCandidate = tng__rand(ctx) % ui8SlicesPerPicture;
    140             ui8SecondCandidate = tng__rand(ctx) % ui8SlicesPerPicture;
    141 
    142             ui8Temp = aui8SliceNumbers[ui8FirstCandidate];
    143             aui8SliceNumbers[ui8FirstCandidate] = aui8SliceNumbers[ui8SecondCandidate];
    144             aui8SliceNumbers[ui8SecondCandidate] = ui8Temp;
    145         }
    146 
    147         ui8TotalBUs = (ctx->ui16PictureHeight / 16) * (ctx->ui16Width / 16) / ctx->sRCParams.ui32BUSize;
    148 
    149         ui32FirstBUInSlice = 0;
    150 
    151         for (ui8Index = 0; ui8Index < ui8SlicesPerPicture - 1; ui8Index++) {
    152             IMG_UINT32 ui32BUsCalc;
    153             if (ui8Index==ui8HalfWaySlice) ui32HalfwayBU=ui32FirstBUInSlice;
    154 
    155             ui32BUsCalc=(ui8TotalBUs - 1 * (ui8SlicesPerPicture - ui8Index));
    156             if(ui32BUsCalc)
    157                 ui8SizeInKicks = tng__rand(ctx) %ui32BUsCalc  + 1;
    158             else
    159                 ui8SizeInKicks = 1;
    160             ui8TotalBUs -= ui8SizeInKicks;
    161 
    162             // slice number
    163             * pvBuffer = aui8SliceNumbers[ui8Index];
    164             pvBuffer++;
    165 
    166             // SizeInKicks BU
    167             * pvBuffer = ui8SizeInKicks;
    168             pvBuffer++;
    169             ui32FirstBUInSlice += (IMG_UINT32) ui8SizeInKicks;
    170         }
    171         ui8SizeInKicks = ui8TotalBUs;
    172         // slice number
    173         * pvBuffer = aui8SliceNumbers[ui8SlicesPerPicture - 1];
    174         pvBuffer++;
    175 
    176         // last BU
    177         * pvBuffer = ui8SizeInKicks;
    178         pvBuffer++;
    179     } else {
    180         // Fill standard Slice Map (non arbitrary)
    181         IMG_UINT8 ui8Index;
    182         IMG_UINT8 ui8SliceNumber;
    183         IMG_UINT8 ui32FirstBUInSlice;
    184         IMG_UINT8 ui8SizeInKicks;
    185         IMG_UINT32 ui32SliceHeight;
    186 
    187         // Fill number of slices
    188         * pvBuffer = ui8SlicesPerPicture;
    189         pvBuffer++;
    190 
    191 
    192         ui32SliceHeight = (ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture) & ~15;
    193 
    194         ui32FirstBUInSlice = 0;
    195         ui8SliceNumber = 0;
    196         for (ui8Index = 0; ui8Index < ui8SlicesPerPicture - 1; ui8Index++) {
    197             if (ui8Index==ui8HalfWaySlice) ui32HalfwayBU=ui32FirstBUInSlice;
    198             ui8SizeInKicks = ((ui32SliceHeight / 16)*(ctx->ui16Width/16))/ctx->sRCParams.ui32BUSize;
    199 
    200             // slice number
    201             * pvBuffer = ui8SliceNumber;
    202             pvBuffer++;
    203             // SizeInKicks BU
    204             * pvBuffer = ui8SizeInKicks;
    205             pvBuffer++;
    206 
    207             ui8SliceNumber++;
    208             ui32FirstBUInSlice += (IMG_UINT32) ui8SizeInKicks;
    209         }
    210         ui32SliceHeight = ctx->ui16PictureHeight - ui32SliceHeight * (ctx->ui8SlicesPerPicture - 1);
    211         if (ui8Index==ui8HalfWaySlice) ui32HalfwayBU=ui32FirstBUInSlice;
    212         ui8SizeInKicks = ((ui32SliceHeight / 16)*(ctx->ui16Width/16))/ctx->sRCParams.ui32BUSize;
    213 
    214         // slice number
    215         * pvBuffer = ui8SliceNumber;    pvBuffer++;
    216         // last BU
    217         * pvBuffer = ui8SizeInKicks;    pvBuffer++;
    218     }
    219 
    220 out1:
    221     psb_buffer_unmap(&(ps_mem->bufs_slice_map));
    222     ctx->ui32HalfWayBU[i32SlotNum] = ui32HalfwayBU;
    223     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ui32HalfWayBU = %d\n", __FUNCTION__, ctx->ui32HalfWayBU[i32SlotNum]);
    224     return ui32HalfwayBU;
    225 }
    226 
    227 //IMG_V_GetInpCtrlBuf
    228 static VAStatus tng__map_inp_ctrl_buf(
    229     context_ENC_p ctx,
    230     IMG_UINT8   ui8SlotNumber,
    231     IMG_UINT8 **ppsInpCtrlBuf)
    232 {
    233     VAStatus vaStatus = VA_STATUS_SUCCESS;
    234     context_ENC_mem* ps_mem = &(ctx->ctx_mem[0]);
    235     context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
    236     if (ppsInpCtrlBuf == NULL) {
    237         drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ppsInpCtrlBuf == NULL\n", __FUNCTION__);
    238         return VA_STATUS_ERROR_INVALID_PARAMETER;
    239     }
    240 
    241     *ppsInpCtrlBuf = NULL; // Not enabled
    242 
    243     // if enabled, return the input-control buffer corresponding to this slot
    244     if (ctx->bEnableInpCtrl) {
    245         vaStatus = psb_buffer_map(&(ps_mem->bufs_mb_ctrl_in_params), ppsInpCtrlBuf);
    246         if (vaStatus == VA_STATUS_SUCCESS)
    247             *ppsInpCtrlBuf += ui8SlotNumber * ps_mem_size->mb_ctrl_in_params;
    248         else
    249             psb_buffer_unmap(&(ps_mem->bufs_mb_ctrl_in_params));
    250     }
    251 
    252     return vaStatus;
    253 }
    254 
    255 static VAStatus tng__unmap_inp_ctrl_buf(
    256     context_ENC_p ctx,
    257     IMG_UINT8   __maybe_unused ui8SlotNumber,
    258     IMG_UINT8 **ppsInpCtrlBuf)
    259 {
    260     VAStatus vaStatus = VA_STATUS_SUCCESS;
    261     context_ENC_mem* ps_mem = &(ctx->ctx_mem[0]);
    262 
    263     // if enabled, return the input-control buffer corresponding to this slot
    264     if (*ppsInpCtrlBuf != NULL) {
    265         psb_buffer_unmap(&(ps_mem->bufs_mb_ctrl_in_params));
    266         *ppsInpCtrlBuf = NULL; // Not enabled
    267     }
    268     return vaStatus;
    269 }
    270 
    271 //APP_FillInpCtrlBuf
    272 #define DEFAULT_INTER_INTRA_SCALE_TBL_IDX   (0)
    273 #define DEFAULT_CODED_SKIPPED_SCALE_TBL_IDX (0)
    274 #define DEFAULT_INPUT_QP                    (0xF)
    275 #define SIZEOF_MB_IN_CTRL_PARAM     (2)
    276 
    277 static void tng__fill_inp_ctrl_buf(
    278     context_ENC_p ctx,
    279     IMG_UINT8 *pInpCtrlBuf,
    280     IMG_INT16 i16IntraRefresh,
    281     IMG_INT8* pi8QP,
    282     IMG_UINT32 __maybe_unused ui32HalfWayBU)
    283 {
    284     IMG_PVOID   pvBuffer;
    285     IMG_UINT32  ui32MBFrameWidth;
    286     IMG_UINT32  ui32MBPictureHeight;
    287     IMG_UINT32  ui32MBSliceHeight;
    288     IMG_UINT16  ui16DefaultParam;
    289     IMG_UINT16  ui16IntraParam;
    290     IMG_BOOL	bRefresh=IMG_FALSE;
    291     IMG_UINT32 ui32CurrentIndex;
    292     IMG_UINT32 ui32MBx, ui32MBy;
    293     IMG_UINT16 *pui16MBParam;
    294     IMG_INT8	i8QPInit;
    295     IMG_INT8	i8QP;
    296     IMG_INT8	iMaxQP;
    297 
    298 #ifdef BRN_30324
    299     IMG_UINT32 ui32HalfWayMB=ui32HalfWayBU * ctx->sRCParams.ui32BUSize;
    300 #endif
    301 
    302     if (pi8QP == NULL) {
    303         drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: start QP == NULL\n", __FUNCTION__);
    304         return ;
    305     }
    306 
    307     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: start QP = %d\n", __FUNCTION__, *pi8QP);
    308 
    309     if (i16IntraRefresh > 0) {
    310         bRefresh=IMG_TRUE;
    311     }
    312 
    313     iMaxQP = 31;
    314     if (ctx->eStandard == IMG_STANDARD_H264) {
    315         iMaxQP = 51;
    316     }
    317     if(pi8QP) {
    318         i8QPInit = * pi8QP;
    319     } else {
    320         i8QPInit = DEFAULT_INPUT_QP;
    321     }
    322     // get the buffer
    323     // IMG_C_GetBuffer(psActiveContext->hContext, pInpCtrlBuf, &pvBuffer,IMG_TRUE);
    324     pvBuffer = (IMG_PVOID) pInpCtrlBuf;
    325 
    326     //fill data
    327     ui32MBFrameWidth  = (ctx->ui16Width/16);
    328     ui32MBPictureHeight = (ctx->ui16PictureHeight/16);
    329     ui32MBSliceHeight = (ui32MBPictureHeight/ctx->ui8SlicesPerPicture);
    330 
    331     pui16MBParam = (IMG_UINT16 *)pvBuffer;
    332     ui32CurrentIndex=0;
    333 
    334     for(ui32MBy = 0; ui32MBy < (IMG_UINT32)(ctx->ui16PictureHeight / 16); ui32MBy++) {
    335         for(ui32MBx = 0; ui32MBx < ui32MBFrameWidth; ui32MBx++) {
    336             IMG_UINT16 ui16MBParam = 0;
    337 
    338 #ifdef BRN_30324
    339             if (ui32HalfWayMB && ui32CurrentIndex == ui32HalfWayMB)
    340                 if (ctx->ui8SlicesPerPicture > 1 && ctx->i32NumPipes > 1) {
    341                     ui32CurrentIndex=(((ui32CurrentIndex)+31)&(~31));
    342                 }
    343 #endif
    344             i8QP = i8QPInit + ((tng__rand(ctx)%6)-3);
    345             i8QP = tng__max(tng__min(i8QP, iMaxQP), ctx->sRCParams.iMinQP);
    346 
    347             ui16DefaultParam = ( i8QP<<10) | (3 <<7) |(3<<4);
    348             ui16IntraParam =  ( i8QP<<10)	| (0 <<7) |(0<<4);
    349 
    350             ui16MBParam = ui16DefaultParam;
    351             if (bRefresh) {
    352                 if ((IMG_INT32)ui32CurrentIndex > ctx->i32LastCIRIndex) {
    353                     ctx->i32LastCIRIndex = ui32CurrentIndex;
    354                     ui16MBParam = ui16IntraParam;
    355                     i16IntraRefresh--;
    356                     if(i16IntraRefresh <= 0)
    357                         bRefresh = IMG_FALSE;
    358                 }
    359             }
    360             pui16MBParam[ui32CurrentIndex++] = ui16MBParam;
    361         }
    362     }
    363 
    364     if (bRefresh) {
    365         ctx->i32LastCIRIndex = -1;
    366         while (i16IntraRefresh) {
    367             i8QP = i8QPInit + ((tng__rand(ctx)%6)-3);
    368             i8QP = tng__max(tng__min(i8QP, iMaxQP), ctx->sRCParams.iMinQP);
    369             ui16IntraParam = ( i8QP<<10) |(0 <<7) |(0<<4);
    370             pui16MBParam[++ctx->i32LastCIRIndex] = ui16IntraParam;
    371             i16IntraRefresh--;
    372         }
    373     }
    374 
    375     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: end QP = %d\n", __FUNCTION__, *pi8QP);
    376     //release buffer
    377     //IMG_C_ReleaseBuffer(psActiveContext->hContext, pInpCtrlBuf,IMG_TRUE);
    378     return ;
    379 }
    380 
    381 /***********************************************************************************
    382  * Function Name     : APP_FillInputControl
    383  * Inputs                   : psContext
    384  * Description           : Fills input control buffer for a given source picture
    385  ************************************************************************************/
    386 static void tng__fill_input_control(
    387     context_ENC_p ctx,
    388     IMG_UINT8 ui8SlotNum,
    389     IMG_UINT32 __maybe_unused ui32HalfWayBU)
    390 {
    391     IMG_UINT8 * pInpCtrlBuf = NULL;
    392     IMG_INT8 i8InitialQp = ctx->sRCParams.ui32InitialQp;
    393     // Get pointer to MB Control buffer for current source buffer (if input control is enabled, otherwise buffer is NULL)
    394     // Please refer to kernel tng_setup_cir_buf()
    395     /*
    396     tng__map_inp_ctrl_buf(ctx, ui8SlotNum, &pInpCtrlBuf);
    397     if (pInpCtrlBuf!= IMG_NULL) {
    398         tng__fill_inp_ctrl_buf(ctx, pInpCtrlBuf,(IMG_INT16)(ctx->ui16IntraRefresh), &i8InitialQp, ui32HalfWayBU);
    399     }
    400     tng__unmap_inp_ctrl_buf(ctx, ui8SlotNum, &pInpCtrlBuf);
    401     */
    402     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
    403         MTX_CMDID_SW_FILL_INPUT_CTRL, ui8SlotNum, 0, 0);
    404 
    405     return ;
    406 }
    407 
    408 static void tng__send_air_inp_ctrl_buf(context_ENC_p ctx, IMG_INT8 *pInpCtrlBuf)
    409 {
    410     //IMG_PVOID pvICBuffer;
    411     IMG_UINT16 ui16IntraParam;
    412     //IMG_BOOL bRefresh = IMG_FALSE;
    413     IMG_UINT32 ui32CurrentCnt, ui32SentCnt;
    414     IMG_UINT32 ui32MBMaxSize;
    415     IMG_UINT16 *pui16MBParam;
    416     IMG_UINT32 ui32NewScanPos, ui32Skip;
    417 
    418 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    419     IMG_CHAR TmpOutputTble[396]; //Debug only
    420 #endif
    421     ui16IntraParam = (0 << 7) | (0 << 4);
    422 
    423     if (ctx->ui32FrameCount[0] < 1)
    424         return;
    425 
    426     // get the buffer
    427     pui16MBParam = (IMG_UINT16 *) pInpCtrlBuf;
    428 
    429     //fill data
    430     ui32MBMaxSize = (IMG_UINT32)(ctx->ui16PictureHeight / 16) * (IMG_UINT32)(ctx->ui16Width / 16);
    431     ui32CurrentCnt = 0;
    432     if (ctx->sAirInfo.i16AIRSkipCnt >= 0)
    433         ui32Skip = ctx->sAirInfo.i16AIRSkipCnt;
    434     else
    435         //ui32Skip=APP_Rand() % psActiveContext->sAirInfo.i32NumAIRSPerFrame; // Pseudorandom skip.
    436         ui32Skip = (ctx->ui32FrameCount[0] & 0x7) + 1; // Pseudorandom skip.
    437 
    438 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    439         {
    440             IMG_UINT32 tsp;
    441             if (fp)
    442             {
    443                 fp = fopen("SADvals.txt", "a");
    444             }
    445             else
    446             {
    447                 fp = fopen("SADvals.txt", "w");
    448             }
    449 
    450             fprintf(fp, "\n---------------------------------------------------------------------------\n");
    451             fprintf(fp, "SENDING SADvals  (skip:%i)\n", ui32Skip);
    452 
    453             for (tsp = 0; tsp < ui32MBMaxSize; tsp++)
    454             {
    455                 if (ctx->sAirInfo.pi8AIR_Table[tsp] > 0)
    456                 {
    457                     TmpOutputTble[tsp] = 'x';
    458                 }
    459                 else
    460                 {
    461                     TmpOutputTble[tsp] = 'o';
    462                 }
    463             }
    464         }
    465 #endif
    466 
    467     ui32NewScanPos = (IMG_UINT32) (ctx->sAirInfo.ui16AIRScanPos + ui32Skip) % ui32MBMaxSize;
    468     ui32CurrentCnt = ui32SentCnt = 0;
    469 
    470     while (ui32CurrentCnt < ui32MBMaxSize &&
    471         ((ctx->sAirInfo.i32NumAIRSPerFrame == 0) ||
    472         ui32SentCnt < (IMG_UINT32) ctx->sAirInfo.i32NumAIRSPerFrame)) {
    473         IMG_UINT16 ui16MBParam;
    474 
    475         if (ctx->sAirInfo.pi8AIR_Table[ui32NewScanPos] >= 0) {
    476             // Mark the entry as 'touched'
    477             ctx->sAirInfo.pi8AIR_Table[ui32NewScanPos] = -1 - ctx->sAirInfo.pi8AIR_Table[ui32NewScanPos];
    478 
    479             if (ctx->sAirInfo.pi8AIR_Table[ui32NewScanPos] < -1) {
    480                 ui16MBParam = pui16MBParam[ui32NewScanPos] & (0xFF << 10);
    481                 ui16MBParam |= ui16IntraParam;
    482                 pui16MBParam[ui32NewScanPos] = ui16MBParam;
    483                 ctx->sAirInfo.pi8AIR_Table[ui32NewScanPos]++;
    484 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    485                 TmpOutputTble[ui32NewScanPos]='I';
    486 #endif
    487                 ui32NewScanPos += ui32Skip;
    488                 ui32SentCnt++;
    489             }
    490             ui32CurrentCnt++;
    491         }
    492 
    493         ui32NewScanPos++;
    494         ui32NewScanPos = ui32NewScanPos % ui32MBMaxSize;
    495         if (ui32NewScanPos == ctx->sAirInfo.ui16AIRScanPos) {
    496             /* we have looped around */
    497             break;
    498         }
    499     }
    500 
    501     ctx->sAirInfo.ui16AIRScanPos = ui32NewScanPos;
    502 
    503 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    504         {
    505             IMG_UINT32 tsp;
    506             for (tsp = 0; tsp < ui32MBMaxSize; tsp++)
    507             {
    508                 if (tsp % ((IMG_UINT32)(ctx->ui16Width/16)) == 0)
    509                 {
    510                     fprintf(fp, "\n%c", TmpOutputTble[tsp]);
    511                 }
    512                 else
    513                 {
    514                     fprintf(fp, "%c", TmpOutputTble[tsp]);
    515                 }
    516             }
    517 
    518             fprintf(fp, "\n---------------------------------------------------------------------------\n");
    519             fclose(fp);
    520         }
    521 #endif
    522 
    523     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: end\n", __FUNCTION__);
    524     return ;
    525 }
    526 
    527 // Adaptive Intra Refresh (AIR) - send the AIR values to the next bufferk
    528 // APP_UpdateAdaptiveIntraRefresh_Send
    529 static void tng__update_air_send(context_ENC_p ctx, IMG_UINT8 ui8SlotNum)
    530 {
    531     IMG_UINT8 *pInpCtrlBuf = NULL;
    532     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: start\n", __FUNCTION__);
    533     // Get pointer to MB Control buffer for current source buffer (if input control is enabled, otherwise buffer is NULL)
    534 #if 0
    535     tng__map_inp_ctrl_buf(ctx, ui8SlotNum, &pInpCtrlBuf);
    536     if(pInpCtrlBuf!= IMG_NULL) {
    537         tng__send_air_inp_ctrl_buf(ctx, (IMG_INT8 *)pInpCtrlBuf);
    538     }
    539     tng__unmap_inp_ctrl_buf(ctx, ui8SlotNum, &pInpCtrlBuf);
    540     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: end\n", __FUNCTION__);
    541 #endif
    542     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
    543         MTX_CMDID_SW_UPDATE_AIR_SEND, ui8SlotNum, 0, 0);
    544     return ;
    545 }
    546 
    547 /***********************************************************************************
    548  * Function Name     : functions for output control
    549  ************************************************************************************/
    550 //IMG_V_GetFirstPassOutBuf
    551 VAStatus tng__map_first_pass_out_buf(
    552     context_ENC_p ctx,
    553     IMG_UINT8   __maybe_unused ui8SlotNumber,
    554     IMG_UINT8 **ppsFirstPassOutBuf)
    555 {
    556     VAStatus vaStatus = VA_STATUS_SUCCESS;
    557     context_ENC_mem* ps_mem = &(ctx->ctx_mem[0]);
    558 
    559     if (ppsFirstPassOutBuf == NULL) {
    560         drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ppsFirstPassOutBuf == NULL\n", __FUNCTION__);
    561         return VA_STATUS_ERROR_INVALID_PARAMETER;
    562     }
    563 
    564     *ppsFirstPassOutBuf = NULL; // Not enabled
    565 
    566     // if enabled, return the input-control buffer corresponding to this slot
    567     if (ctx->bEnableInpCtrl) {
    568          vaStatus = psb_buffer_map(&(ps_mem->bufs_first_pass_out_params), ppsFirstPassOutBuf);
    569         if (vaStatus != VA_STATUS_SUCCESS)
    570             psb_buffer_unmap(&(ps_mem->bufs_first_pass_out_params));
    571     }
    572 
    573     return vaStatus;
    574 }
    575 
    576 VAStatus tng__unmap_first_pass_out_buf(
    577     context_ENC_p ctx,
    578     IMG_UINT8 __maybe_unused ui8SlotNumber,
    579     IMG_UINT8 **ppsFirstPassOutBuf)
    580 {
    581     VAStatus vaStatus = VA_STATUS_SUCCESS;
    582     context_ENC_mem* ps_mem = &(ctx->ctx_mem[0]);
    583 
    584     // if enabled, return the input-control buffer corresponding to this slot
    585     if (*ppsFirstPassOutBuf != NULL) {
    586         psb_buffer_unmap(&(ps_mem->bufs_first_pass_out_params));
    587         *ppsFirstPassOutBuf = NULL; // Not enabled
    588     }
    589 
    590     return vaStatus;
    591 }
    592 
    593 //IMG_V_GetBestMBDecisionOutBuf
    594 VAStatus tng__map_best_mb_decision_out_buf(
    595     context_ENC_p ctx,
    596     IMG_UINT8   __maybe_unused ui8SlotNumber,
    597     IMG_UINT8  **ppsBestMBDecisionOutBuf)
    598 {
    599     VAStatus vaStatus = VA_STATUS_SUCCESS;
    600     context_ENC_mem* ps_mem = &(ctx->ctx_mem[0]);
    601 
    602     // if enabled, return the input-control buffer corresponding to this slot
    603     if (ctx->bEnableInpCtrl)
    604         vaStatus = psb_buffer_map(&(ps_mem->bufs_first_pass_out_best_multipass_param), ppsBestMBDecisionOutBuf);
    605     else
    606         *ppsBestMBDecisionOutBuf = NULL; // Not enabled
    607 
    608     return vaStatus;
    609 }
    610 
    611 VAStatus tng__unmap_best_mb_decision_out_buf(
    612     context_ENC_p ctx,
    613     IMG_UINT8   __maybe_unused ui8SlotNumber,
    614     IMG_UINT8  **ppsBestMBDecisionOutBuf)
    615 {
    616     VAStatus vaStatus = VA_STATUS_SUCCESS;
    617     context_ENC_mem* ps_mem = &(ctx->ctx_mem[0]);
    618 
    619     // if enabled, return the input-control buffer corresponding to this slot
    620     if (*ppsBestMBDecisionOutBuf != NULL) {
    621         psb_buffer_unmap(&(ps_mem->bufs_first_pass_out_best_multipass_param));
    622         *ppsBestMBDecisionOutBuf = NULL; // Not enabled
    623      }
    624 
    625     return vaStatus;
    626 }
    627 
    628 // Calculate Adaptive Intra Refresh (AIR)
    629 static void tng__calc_air_inp_ctrl_buf(context_ENC_p ctx, IMG_UINT8 *pFirstPassOutBuf, IMG_UINT8 *pBestMBDecisionCtrlBuf)
    630 {
    631     IMG_UINT8 *pSADPointer;
    632     IMG_UINT8 *pvSADBuffer;
    633     IMG_UINT8 ui8IsAlreadyIntra;
    634     IMG_UINT32 ui32MBFrameWidth;
    635     IMG_UINT32 ui32MBPictureHeight;
    636     IMG_UINT16 ui16IntraParam;
    637     IMG_UINT32 ui32MBx, ui32MBy;
    638     IMG_UINT32 ui32SADParam;
    639     IMG_UINT32 ui32tSAD_Threshold, ui32tSAD_ThresholdLo, ui32tSAD_ThresholdHi;
    640     IMG_UINT32 ui32MaxMBs, ui32NumMBsOverThreshold, ui32NumMBsOverLo, ui32NumMBsOverHi;
    641     IMG_BEST_MULTIPASS_MB_PARAMS *psBestMB_Params;
    642     IMG_FIRST_STAGE_MB_PARAMS *psFirstMB_Params;
    643 
    644     ui16IntraParam = (0 << 7) | (0 << 4);
    645     ui32NumMBsOverThreshold = ui32NumMBsOverLo = ui32NumMBsOverHi = 0;
    646     //drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: start\n", __FUNCTION__);
    647 
    648 //    if (psActiveContext->ui32EncodeSent < (IMG_UINT32)psActiveContext->ui8MaxSourceSlots + 1)
    649 //    if (ctx->ui32FrameCount[0] < (IMG_UINT32)(ctx->ui8SlotsInUse + 1))
    650 //        return;
    651     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: start\n", __FUNCTION__);
    652     //fill data
    653     ui32MBFrameWidth  = (ctx->ui16Width/16);
    654     ui32MBPictureHeight = (ctx->ui16PictureHeight/16);
    655 
    656     // get the SAD results buffer (either IPE0 and IPE1 results or, preferably, the more accurate Best Multipass SAD results)
    657     if (pBestMBDecisionCtrlBuf) {
    658         pvSADBuffer = pBestMBDecisionCtrlBuf;
    659         drv_debug_msg(VIDEO_DEBUG_GENERAL,"AIR active: Using Best Multipass SAD values ");
    660 
    661 //#ifdef  MULTIPASS_MV_PLACEMENT_ISSUE_FIXED
    662 	if ((ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS))
    663 //#endif
    664 	{
    665             // The actual Param structures (which contain SADs) are located after the Multipass Motion Vector entries
    666 	    pvSADBuffer += (ui32MBPictureHeight * (ui32MBFrameWidth) * sizeof(IMG_BEST_MULTIPASS_MB_PARAMS_IPMV));
    667         }
    668     } else {
    669         pvSADBuffer = pFirstPassOutBuf;
    670         drv_debug_msg(VIDEO_DEBUG_GENERAL,"AIR active: Using IPE SAD values ");
    671     }
    672 
    673     if (ctx->sAirInfo.i32NumAIRSPerFrame == 0)
    674         ui32MaxMBs = ui32MBFrameWidth * ui32MBPictureHeight; // Default to ALL MB's in frame
    675     else if (ctx->sAirInfo.i32NumAIRSPerFrame < 0)
    676         ctx->sAirInfo.i32NumAIRSPerFrame = ui32MaxMBs = ((ui32MBFrameWidth * ui32MBPictureHeight) + 99) / 100; // Default to 1% of MB's in frame (min 1)
    677     else
    678         ui32MaxMBs = ctx->sAirInfo.i32NumAIRSPerFrame;
    679 
    680     pSADPointer = (IMG_UINT8 *)pvSADBuffer;
    681 
    682     if (ctx->sAirInfo.i32SAD_Threshold >= 0)
    683         ui32tSAD_Threshold = (IMG_UINT16)ctx->sAirInfo.i32SAD_Threshold;
    684     else {
    685         // Running auto adjust threshold adjust mode
    686         if (ctx->sAirInfo.i32SAD_Threshold == -1) {
    687             // This will occur only the first time
    688             if (pBestMBDecisionCtrlBuf) {
    689                 psBestMB_Params=(IMG_BEST_MULTIPASS_MB_PARAMS *) pSADPointer; // Auto seed the threshold with the first value
    690                 ui32SADParam = psBestMB_Params->ui32SAD_Inter_MBInfo & IMG_BEST_MULTIPASS_SAD_MASK;
    691             } else {
    692                 psFirstMB_Params=(IMG_FIRST_STAGE_MB_PARAMS *) pSADPointer; // Auto seed the threshold with the first value
    693                 ui32SADParam = (IMG_UINT32) psFirstMB_Params->ui16Ipe0Sad;
    694             }
    695             ctx->sAirInfo.i32SAD_Threshold = -1 - ui32SADParam; // Negative numbers indicate auto-adjusting threshold
    696         }
    697         ui32tSAD_Threshold = (IMG_UINT32) - (ctx->sAirInfo.i32SAD_Threshold + 1);
    698     }
    699 
    700     ui32tSAD_ThresholdLo = ui32tSAD_Threshold / 2;
    701     ui32tSAD_ThresholdHi = ui32tSAD_Threshold + ui32tSAD_ThresholdLo;
    702 
    703     drv_debug_msg(VIDEO_DEBUG_GENERAL,"Th:%u, MaxMbs:%u, Skp:%i\n", (unsigned int)ui32tSAD_Threshold, (unsigned int)ui32MaxMBs, ctx->sAirInfo.i16AIRSkipCnt);
    704 
    705 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    706 	if (fp)
    707 		fp=fopen("SADvals.txt","a");
    708 	else
    709 		fp=fopen("SADvals.txt","w");
    710 
    711 	if (ctx->sAirInfo.i32SAD_Threshold>=0)
    712 		if (ctx->sAirInfo.i32NumAIRSPerFrame>0)
    713 			fprintf(fp, "S_SADThreshold: %i	MaxMBs: %i\n", ui32tSAD_Threshold, ui32MaxMBs);
    714 		else
    715 			fprintf(fp, "S_SADThreshold: %i	MaxMBs: NA\n", ui32tSAD_Threshold, ui32MaxMBs);
    716 	else
    717 		fprintf(fp, "V_SADThreshold: %i	MaxMBs: %i\n", ui32tSAD_Threshold, ui32MaxMBs);
    718 
    719 	if (pBestMBDecisionCtrlBuf)
    720 		fprintf(fp, "Using Best Multipass SAD values\n");
    721 	else
    722 		fprintf(fp, "Using Motion Search Data IPE SAD values\n");
    723 #endif
    724 
    725     // This loop could be optimised to a single counter if necessary, retaining for clarity
    726     for (ui32MBy = 0; ui32MBy < ui32MBPictureHeight; ui32MBy++) {
    727         for( ui32MBx=0; ui32MBx<ui32MBFrameWidth; ui32MBx++) {
    728 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    729             IMG_CHAR cMarked;
    730             cMarked='_';
    731 #endif
    732             // Turn all negative table values to positive (reset 'touched' state of a block that may have been set in APP_SendAIRInpCtrlBuf())
    733 	    if (ctx->sAirInfo.pi8AIR_Table[ui32MBy *  ui32MBFrameWidth + ui32MBx] < 0)
    734                 ctx->sAirInfo.pi8AIR_Table[ui32MBy *  ui32MBFrameWidth + ui32MBx] = -1 - ctx->sAirInfo.pi8AIR_Table[ui32MBy *  ui32MBFrameWidth + ui32MBx];
    735 
    736             // This will read the SAD value from the buffer (either IPE0 SAD or the superior Best multipass parameter structure SAD value)
    737             if (pBestMBDecisionCtrlBuf) {
    738                 psBestMB_Params = (IMG_BEST_MULTIPASS_MB_PARAMS *) pSADPointer;
    739                 ui32SADParam = psBestMB_Params->ui32SAD_Inter_MBInfo & IMG_BEST_MULTIPASS_SAD_MASK;
    740 
    741                 if ((psBestMB_Params->ui32SAD_Intra_MBInfo & IMG_BEST_MULTIPASS_MB_TYPE_MASK) >> IMG_BEST_MULTIPASS_MB_TYPE_SHIFT == 1)
    742                     ui8IsAlreadyIntra = 1;
    743                 else
    744                     ui8IsAlreadyIntra = 0;
    745 
    746                 pSADPointer=(IMG_UINT8 *) &(psBestMB_Params[1]);
    747             } else {
    748                 psFirstMB_Params=(IMG_FIRST_STAGE_MB_PARAMS *) pSADPointer;
    749                 ui32SADParam = (IMG_UINT32) psFirstMB_Params->ui16Ipe0Sad;
    750                 ui32SADParam += (IMG_UINT32) psFirstMB_Params->ui16Ipe1Sad;
    751                 ui32SADParam /= 2;
    752                 ui8IsAlreadyIntra = 0; // We don't have the information to determine this
    753                 pSADPointer=(IMG_UINT8 *) &(psFirstMB_Params[1]);
    754             }
    755 
    756             if (ui32SADParam >= ui32tSAD_ThresholdLo) {
    757                 ui32NumMBsOverLo++;
    758 
    759                 if (ui32SADParam >= ui32tSAD_Threshold) {
    760 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    761                     cMarked='i';
    762 #endif
    763 
    764                     // if (!ui8IsAlreadyIntra) // Don't mark this block if it's just been encoded as an Intra block anyway
    765                     // (results seem better without this condition anyway)
    766                     {
    767                         ctx->sAirInfo.pi8AIR_Table[ui32MBy *  ui32MBFrameWidth + ui32MBx]++;
    768 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    769                         cMarked='I';
    770 #endif
    771                     }
    772                     ui32NumMBsOverThreshold++;
    773                     if (ui32SADParam >= ui32tSAD_ThresholdHi)
    774                         ui32NumMBsOverHi++;
    775                 }
    776             }
    777 
    778 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    779             fprintf(fp,"%4x[%i]%c,	",ui32SADParam, ctx->sAirInfo.pi8AIR_Table[ui32MBy * ui32MBFrameWidth + ui32MBx], cMarked);
    780 #endif
    781         }
    782         pSADPointer=(IMG_UINT8 *) ALIGN_64(((IMG_UINT32) pSADPointer));
    783 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    784 	fprintf(fp,"\n");
    785 #endif
    786     }
    787 
    788     // Test and process running adaptive threshold case
    789     if (ctx->sAirInfo.i32SAD_Threshold < 0) {
    790         // Adjust our threshold (to indicate it's auto-adjustable store it as a negative value minus 1)
    791         if (ui32NumMBsOverLo <= ui32MaxMBs)
    792             ctx->sAirInfo.i32SAD_Threshold = (IMG_INT32) - ((IMG_INT32)ui32tSAD_ThresholdLo) - 1;
    793         else
    794             if (ui32NumMBsOverHi >= ui32MaxMBs)
    795                 ctx->sAirInfo.i32SAD_Threshold = (IMG_INT32) - ((IMG_INT32)ui32tSAD_ThresholdHi) - 1;
    796             else {
    797                 if (ui32MaxMBs < ui32NumMBsOverThreshold) {
    798                     ctx->sAirInfo.i32SAD_Threshold = ((IMG_INT32)ui32tSAD_ThresholdHi - (IMG_INT32)ui32tSAD_Threshold);
    799                     ctx->sAirInfo.i32SAD_Threshold *= ((IMG_INT32)ui32MaxMBs - (IMG_INT32)ui32NumMBsOverThreshold);
    800                     ctx->sAirInfo.i32SAD_Threshold /= ((IMG_INT32)ui32NumMBsOverHi - (IMG_INT32)ui32NumMBsOverThreshold);
    801                     ctx->sAirInfo.i32SAD_Threshold += ui32tSAD_Threshold;
    802                 } else {
    803                     ctx->sAirInfo.i32SAD_Threshold = ((IMG_INT32)ui32tSAD_Threshold - (IMG_INT32)ui32tSAD_ThresholdLo);
    804                     ctx->sAirInfo.i32SAD_Threshold *= ((IMG_INT32)ui32MaxMBs - (IMG_INT32)ui32NumMBsOverLo);
    805                     ctx->sAirInfo.i32SAD_Threshold /= ((IMG_INT32)ui32NumMBsOverThreshold - (IMG_INT32)ui32NumMBsOverLo);
    806                     ctx->sAirInfo.i32SAD_Threshold += ui32tSAD_ThresholdLo;
    807                 }
    808                 ctx->sAirInfo.i32SAD_Threshold = -ctx->sAirInfo.i32SAD_Threshold - 1;
    809             }
    810 
    811 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    812             fprintf(fp,"THRESHOLDS ADJUSTMENT\nThrLo:%i	ThrMid:%i	ThrHi:%i\nMBsLo:%i	MBsMid:%i	MBsHi:%i\n",ui32tSAD_ThresholdLo, ui32tSAD_Threshold, ui32tSAD_ThresholdHi, ui32NumMBsOverLo, ui32NumMBsOverThreshold, ui32NumMBsOverHi);
    813             fprintf(fp,"Target No. MB's:%i\nThreshold adjusted to: %i\n",ui32MaxMBs, -(ctx->sAirInfo.i32SAD_Threshold));
    814 #endif
    815     }
    816 
    817 #ifdef ADAPTIVE_INTRA_REFRESH_DEBUG_OUTPUT
    818     fprintf(fp,"\n MBs tagged:%i\n", ui32NumMBsOverThreshold);
    819     fclose(fp);
    820 #endif
    821     drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: end\n", __FUNCTION__);
    822     return;
    823 }
    824 
    825 // Adaptive Intra Refresh (AIR) - Calculate the new AIR values based upon Motion Search feedback
    826 // APP_UpdateAdaptiveIntraRefresh_Calc
    827 static void tng_update_air_calc(context_ENC_p ctx, IMG_UINT8 ui8SlotNum)
    828 {
    829     IMG_UINT8  *pFirstPassOutBuf = NULL;
    830     IMG_UINT8  *pBestMBDecisionCtrlBuf = NULL;
    831 #if 0
    832     // Get pointer to MB Control buffer for current source buffer (if input control is enabled, otherwise buffer is NULL)
    833     tng__map_first_pass_out_buf(ctx, ui8SlotNum, &pFirstPassOutBuf);
    834     tng__map_best_mb_decision_out_buf(ctx, ui8SlotNum, &pBestMBDecisionCtrlBuf);
    835 
    836     if(pFirstPassOutBuf || pBestMBDecisionCtrlBuf)
    837 	tng__calc_air_inp_ctrl_buf (ctx, pFirstPassOutBuf, pBestMBDecisionCtrlBuf);
    838 
    839     tng__unmap_first_pass_out_buf(ctx, ui8SlotNum, &pFirstPassOutBuf);
    840     tng__unmap_best_mb_decision_out_buf(ctx, ui8SlotNum, &pBestMBDecisionCtrlBuf);
    841 #endif
    842     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
    843         MTX_CMDID_SW_UPDATE_AIR_CALC, ui8SlotNum, 0, 0);
    844 }
    845 
    846 /***********************************************************************************
    847  * Function Name     :
    848  * Inputs                   :
    849  * Description           :
    850  ************************************************************************************/
    851 void tng_air_set_input_control(context_ENC_p ctx, IMG_UINT8 __maybe_unused ui8StreamID)
    852 {
    853     IMG_UINT8 ui8SlotIndex = ctx->ui8SlotsCoded;
    854     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: slot index = %d\n", __FUNCTION__, ctx->ui8SlotsCoded);
    855     //IMG_UINT32 ui32HalfWayBU;
    856     //ui32HalfWayBU = tng_fill_slice_map(ctx, ui8SlotIndex, ui8StreamID);
    857 
    858     ////////////////////////////// INPUT CONTROL
    859     // Add input control stuff here
    860     tng__fill_input_control(ctx, ui8SlotIndex, ctx->ui32HalfWayBU[ui8SlotIndex]);
    861 
    862     // Adaptive Intra Refresh (AIR) - send the AIR values to the next buffer
    863     if (ctx->bEnableAIR)
    864         tng__update_air_send(ctx, ui8SlotIndex);
    865 }
    866 
    867 
    868 /***********************************************************************************
    869  * Function Name     :
    870  * Inputs                   :
    871  * Description           :
    872  ************************************************************************************/
    873 void tng_air_set_output_control(context_ENC_p ctx, IMG_UINT8 __maybe_unused ui8StreamID)
    874 {
    875     IMG_UINT8 ui8SlotIndex = ctx->ui8SlotsCoded;
    876 
    877     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: slot index = %d\n", __FUNCTION__, ctx->ui8SlotsCoded);
    878 
    879     if ((ctx->eFrameType == IMG_INTRA_IDR) ||
    880         (ctx->eFrameType == IMG_INTRA_FRAME))
    881         tng_air_buf_clear(ctx);
    882     else
    883         tng_update_air_calc(ctx, ui8SlotIndex);
    884 
    885     return;
    886 }
    887