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 <memory.h>
     33 #include <wsbm/wsbm_manager.h>
     34 #include "tng_picmgmt.h"
     35 #include "psb_drv_debug.h"
     36 
     37 #define MASK_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_0 0x0000007F
     38 #define SHIFT_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_0 0
     39 #define MASK_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_1 0x00007F00
     40 #define SHIFT_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_1 8
     41 #define MASK_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_2 0x007F0000
     42 #define SHIFT_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_2 16
     43 #define MASK_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_3 0x7F000000
     44 #define SHIFT_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_3 24
     45 
     46 #define MASK_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0 0x00003FFF
     47 #define SHIFT_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0 0
     48 #define MASK_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1 0x3FFF0000
     49 #define SHIFT_TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1 16
     50 
     51 /************************* MTX_CMDID_PICMGMT *************************/
     52 VAStatus tng_picmgmt_update(context_ENC_p ctx, IMG_PICMGMT_TYPE eType, unsigned int ref)
     53 {
     54     //VAStatus vaStatus = VA_STATUS_SUCCESS;
     55     IMG_UINT32 ui32CmdData = 0;
     56 
     57     //IMG_V_SetNextRefType  eFrameType
     58     //IMG_V_SkipFrame       bProcess
     59     //IMG_V_EndOfStream     ui32FrameCount
     60     //IMG_PICMGMT_FLUSH     ui32FrameCount
     61     ui32CmdData = F_ENCODE(eType, MTX_MSG_PICMGMT_SUBTYPE) |
     62         F_ENCODE(ref, MTX_MSG_PICMGMT_DATA);
     63 
     64     /* Send PicMgmt Command */
     65     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
     66         MTX_CMDID_PICMGMT | MTX_CMDID_PRIORITY,
     67         ui32CmdData, 0, 0);
     68 
     69     return VA_STATUS_SUCCESS;
     70 }
     71 
     72 /*!
     73 ******************************************************************************
     74 *
     75 * Picture management functions
     76 *
     77 ******************************************************************************/
     78 void tng__picmgmt_long_term_refs(context_ENC_p __maybe_unused ctx, IMG_UINT32 __maybe_unused ui32FrameNum)
     79 {
     80 #ifdef _TNG_ENABLE_PITMGMT_
     81     IMG_BOOL                bIsLongTermRef;
     82     IMG_BOOL                bUsesLongTermRef0;
     83     IMG_BOOL                bUsesLongTermRef1;
     84     IMG_UINT32              ui32FrameCnt;
     85 
     86     // Determine frame position in source stream
     87     // This assumes there are no IDR frames after the first one
     88     if (ui32FrameNum == 0) {
     89         // Initial IDR frame
     90         ui32FrameCnt = 0;
     91     } else if (((ui32FrameNum - 1) % (ctx->sRCParams.ui16BFrames + 1)) == 0) {
     92         // I or P frame
     93         ui32FrameCnt = ui32FrameNum + ctx->sRCParams.ui16BFrames;
     94         if (ui32FrameCnt >= ctx->ui32Framecount) ui32FrameCnt = ctx->ui32Framecount - 1;
     95     } else {
     96         // B frame
     97         // This will be incorrect for hierarchical B-pictures
     98         ui32FrameCnt = ui32FrameNum - 1;
     99     }
    100 
    101     // Decide if the current frame should be used as a long-term reference
    102     bIsLongTermRef = ctx->ui32LongTermRefFreq ?
    103                      (ui32FrameCnt % ctx->ui32LongTermRefFreq == 0) :
    104                      IMG_FALSE;
    105 
    106     // Decide if the current frame should refer to a long-term reference
    107     bUsesLongTermRef0 = ctx->ui32LongTermRefUsageFreq ?
    108                         (ui32FrameCnt % ctx->ui32LongTermRefUsageFreq == ctx->ui32LongTermRefUsageOffset) :
    109                         IMG_FALSE;
    110     bUsesLongTermRef1 = IMG_FALSE;
    111 
    112     if (bIsLongTermRef || bUsesLongTermRef0 || bUsesLongTermRef1) {
    113         // Reconstructed/reference frame to be written to host buffer
    114         // Send the buffer to be used as reference
    115         tng__send_ref_frames(ctx, 0, bIsLongTermRef);
    116         if (bIsLongTermRef) ctx->byCurBufPointer = (ctx->byCurBufPointer + 1) % 3;
    117     }
    118 #endif
    119 }
    120 
    121 static VAStatus tng__H264ES_CalcCustomQuantSp(IMG_UINT8 list, IMG_UINT8 param, IMG_UINT8 customQuantQ)
    122 {
    123     // Derived from sim/topaz/testbench/tests/mved1_tests.c
    124     IMG_UINT32 mfflat[2][16] = {
    125         {
    126             13107, 8066,   13107,  8066,
    127             8066,   5243,   8066,   5243,
    128             13107,  8066,   13107,  8066,
    129             8066,   5243,   8066,   5243
    130         }, // 4x4
    131         {
    132             13107, 12222,  16777,  12222,
    133             12222,  11428,  15481,  11428,
    134             16777,  15481,  20972,  15481,
    135             12222,  11428,  15481,  11428
    136         } // 8x8
    137     };
    138     IMG_UINT8 uVi[2][16] = {
    139         {
    140             20, 26,  20,  26,
    141             26,  32,  26,  32,
    142             20,  26,  20,  26,
    143             26,  32,  26,  32
    144         }, // 4x4
    145         {
    146             20, 19,  25,  19,
    147             19,  18,  24,  18,
    148             25,  24,  32,  24,
    149             19,  18,  24,  18
    150         } // 8x8
    151     };
    152 
    153     int mfnew;
    154     double fSp;
    155     int uSp;
    156 
    157     if (customQuantQ == 0) customQuantQ = 1;
    158     mfnew = (mfflat[list][param] * 16) / customQuantQ;
    159     fSp = ((double)(mfnew * uVi[list][param])) / (double)(1 << 22);
    160     fSp = (fSp * 100000000.0f) / 100000000.0f;
    161     uSp = (IMG_UINT16)(fSp * 65536);
    162 
    163     return uSp & 0x03FFF;
    164 }
    165 
    166 
    167 static VAStatus tng__set_custom_scaling_values(
    168     context_ENC_p ctx,
    169     IMG_UINT8* aui8Sl4x4IntraY,
    170     IMG_UINT8* aui8Sl4x4IntraCb,
    171     IMG_UINT8* aui8Sl4x4IntraCr,
    172     IMG_UINT8* aui8Sl4x4InterY,
    173     IMG_UINT8* aui8Sl4x4InterCb,
    174     IMG_UINT8* aui8Sl4x4InterCr,
    175     IMG_UINT8* aui8Sl8x8IntraY,
    176     IMG_UINT8* aui8Sl8x8InterY)
    177 {
    178     IMG_UINT8  *pui8QuantMem;
    179     IMG_UINT32 *pui32QuantReg;
    180     IMG_UINT8  *apui8QuantTables[8];
    181     IMG_UINT32  ui32Table, ui32Val;
    182     psb_buffer_p pCustomBuf = NULL;
    183     IMG_UINT32  custom_quant_size = 0;
    184 
    185     // Scanning order for coefficients, see section 8.5.5 of H.264 specification
    186     // Note that even for interlaced mode, hardware takes the scaling values as if frame zig-zag scanning were being used
    187     IMG_UINT8 aui8ZigZagScan4x4[16] = {
    188         0,  1,  5,  6,
    189         2,  4,  7,  12,
    190         3,  8,  11, 13,
    191         9,  10, 14, 15
    192     };
    193     IMG_UINT8 aui8ZigZagScan8x8[64] = {
    194         0,  1,  5,  6,  14, 15, 27, 28,
    195         2,  4,  7,  13, 16, 26, 29, 42,
    196         3,  8,  12, 17, 25, 30, 41, 43,
    197         9,  11, 18, 24, 31, 40, 44, 53,
    198         10, 19, 23, 32, 39, 45, 52, 54,
    199         20, 22, 33, 38, 46, 51, 55, 60,
    200         21, 34, 37, 47, 50, 56, 59, 61,
    201         35, 36, 48, 49, 57, 58, 62, 63
    202     };
    203 
    204 
    205     if (ctx == NULL) {
    206         return VA_STATUS_ERROR_UNKNOWN;
    207     }
    208 
    209     if (ctx->bCustomScaling == IMG_FALSE) {
    210         return VA_STATUS_ERROR_UNKNOWN;
    211     }
    212 
    213     pCustomBuf = &(ctx->ctx_mem[ctx->ui32StreamID].bufs_custom_quant);
    214     custom_quant_size = ctx->ctx_mem_size.custom_quant;
    215 
    216 
    217     /* Copy quantization values (in header order) */
    218     pui8QuantMem = (IMG_UINT8*)(pCustomBuf);
    219     memcpy(pui8QuantMem, aui8Sl4x4IntraY, 16);
    220     memcpy(pui8QuantMem + 16, aui8Sl4x4IntraCb, 16);
    221     memcpy(pui8QuantMem + 32, aui8Sl4x4IntraCr, 16);
    222     memcpy(pui8QuantMem + 48, aui8Sl4x4InterY, 16);
    223     memcpy(pui8QuantMem + 64, aui8Sl4x4InterCb, 16);
    224     memcpy(pui8QuantMem + 80, aui8Sl4x4InterCr, 16);
    225     memcpy(pui8QuantMem + 96, aui8Sl8x8IntraY, 64);
    226     memcpy(pui8QuantMem + 160, aui8Sl8x8InterY, 64);
    227 
    228     /* Create quantization register values */
    229 
    230     /* Assign based on the order values are written to registers */
    231     apui8QuantTables[0] = aui8Sl4x4IntraY;
    232     apui8QuantTables[1] = aui8Sl4x4InterY;
    233     apui8QuantTables[2] = aui8Sl4x4IntraCb;
    234     apui8QuantTables[3] = aui8Sl4x4InterCb;
    235     apui8QuantTables[4] = aui8Sl4x4IntraCr;
    236     apui8QuantTables[5] = aui8Sl4x4InterCr;
    237     apui8QuantTables[6] = aui8Sl8x8IntraY;
    238     apui8QuantTables[7] = aui8Sl8x8InterY;
    239 
    240     /* H264COMP_CUSTOM_QUANT_SP register values "psCustomQuantRegs4x4Sp"*/
    241     pui8QuantMem = (IMG_UINT8*)(pCustomBuf + custom_quant_size);
    242     pui32QuantReg = (IMG_UINT32 *)pui8QuantMem;
    243     for (ui32Table = 0; ui32Table < 6; ui32Table++) {
    244         for (ui32Val = 0; ui32Val < 16; ui32Val += 4) {
    245             *pui32QuantReg = F_ENCODE(tng__H264ES_CalcCustomQuantSp(0, ui32Val, apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0)
    246                              | F_ENCODE(tng__H264ES_CalcCustomQuantSp(0, ui32Val + 1, apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val + 1]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1);
    247             pui32QuantReg++;
    248             *pui32QuantReg = F_ENCODE(tng__H264ES_CalcCustomQuantSp(0, ui32Val + 2, apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val + 2]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0)
    249                              | F_ENCODE(tng__H264ES_CalcCustomQuantSp(0, ui32Val + 3, apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val + 3]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1);
    250             pui32QuantReg++;
    251         }
    252     }
    253 
    254     /*psCustomQuantRegs8x8Sp*/
    255     pui8QuantMem = (IMG_UINT8*)(pCustomBuf + custom_quant_size + custom_quant_size);
    256     pui32QuantReg = (IMG_UINT32 *)pui8QuantMem;
    257     for (; ui32Table < 8; ui32Table++) {
    258         for (ui32Val = 0; ui32Val < 64; ui32Val += 8) {
    259             *pui32QuantReg = F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1), apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0)
    260                              | F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1) + 1, apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 1]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1);
    261             pui32QuantReg++;
    262             *pui32QuantReg = F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1) + 2, apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 2]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0)
    263                              | F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1) + 3, apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 3]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1);
    264             pui32QuantReg++;
    265             *pui32QuantReg = F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1), apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 4]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0)
    266                              | F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1) + 1, apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 5]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1);
    267             pui32QuantReg++;
    268             *pui32QuantReg = F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1) + 2, apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 6]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_0)
    269                              | F_ENCODE(tng__H264ES_CalcCustomQuantSp(1, ((ui32Val & 24) >> 1) + 3, apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 7]]), TOPAZHP_CR_H264COMP_CUSTOM_QUANT_SP_1);
    270             pui32QuantReg++;
    271         }
    272     }
    273 
    274     /* H264COMP_CUSTOM_QUANT_Q register values "psCustomQuantRegs4x4Q" */
    275     pui8QuantMem = (IMG_UINT8*)(pCustomBuf + custom_quant_size + custom_quant_size + custom_quant_size);
    276     pui32QuantReg = (IMG_UINT32 *)pui8QuantMem;
    277     for (ui32Table = 0; ui32Table < 6; ui32Table++) {
    278         for (ui32Val = 0; ui32Val < 16; ui32Val += 4) {
    279             *pui32QuantReg = F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_0)
    280                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val + 1]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_1)
    281                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val + 2]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_2)
    282                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan4x4[ui32Val + 3]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_3);
    283             pui32QuantReg++;
    284         }
    285     }
    286 
    287     /*psCustomQuantRegs8x8Q)*/
    288     pui8QuantMem = (IMG_UINT8*)(pCustomBuf + custom_quant_size + custom_quant_size + custom_quant_size + custom_quant_size);
    289 
    290     pui32QuantReg = (IMG_UINT32 *)pui8QuantMem;
    291     for (; ui32Table < 8; ui32Table++) {
    292         for (ui32Val = 0; ui32Val < 64; ui32Val += 8) {
    293             *pui32QuantReg = F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_0)
    294                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 1]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_1)
    295                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 2]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_2)
    296                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 3]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_3);
    297             pui32QuantReg++;
    298             *pui32QuantReg = F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 4]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_0)
    299                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 5]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_1)
    300                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 6]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_2)
    301                              | F_ENCODE(apui8QuantTables[ui32Table][aui8ZigZagScan8x8[ui32Val + 7]], TOPAZHP_CR_H264COMP_CUSTOM_QUANT_Q_3);
    302             pui32QuantReg++;
    303         }
    304     }
    305 
    306     if (ctx->bPpsScaling)
    307         ctx->bInsertPicHeader = IMG_TRUE;
    308 
    309     return VA_STATUS_SUCCESS;
    310 }
    311 
    312 
    313 void tng__picmgmt_custom_scaling(context_ENC_p ctx, IMG_UINT32 ui32FrameNum)
    314 {
    315     if (ui32FrameNum % ctx->ui32PpsScalingCnt == 0) {
    316         // Swap inter and intra scaling lists on alternating picture parameter sets
    317         if (ui32FrameNum % (ctx->ui32PpsScalingCnt * 2) == 0) {
    318             tng__set_custom_scaling_values(
    319                 ctx,
    320                 ctx->aui8CustomQuantParams4x4[0],
    321                 ctx->aui8CustomQuantParams4x4[1],
    322                 ctx->aui8CustomQuantParams4x4[2],
    323                 ctx->aui8CustomQuantParams4x4[3],
    324                 ctx->aui8CustomQuantParams4x4[4],
    325                 ctx->aui8CustomQuantParams4x4[5],
    326                 ctx->aui8CustomQuantParams8x8[0],
    327                 ctx->aui8CustomQuantParams8x8[1]);
    328         } else {
    329             tng__set_custom_scaling_values(
    330                 ctx,
    331                 ctx->aui8CustomQuantParams4x4[3],
    332                 ctx->aui8CustomQuantParams4x4[4],
    333                 ctx->aui8CustomQuantParams4x4[5],
    334                 ctx->aui8CustomQuantParams4x4[0],
    335                 ctx->aui8CustomQuantParams4x4[1],
    336                 ctx->aui8CustomQuantParams4x4[2],
    337                 ctx->aui8CustomQuantParams8x8[1],
    338                 ctx->aui8CustomQuantParams8x8[0]);
    339         }
    340     }
    341 }
    342 
    343 /************************* MTX_CMDID_PROVIDE_BUFFER *************************/
    344 IMG_UINT32 tng_send_codedbuf(
    345     context_ENC_p ctx,
    346     IMG_UINT32 ui32SlotIndex)
    347 {
    348     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
    349     object_buffer_p object_buffer  = ps_buf->coded_buf;
    350     IMG_UINT32 ui32Offset = 0;
    351 
    352     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    353         "%s slot 1 = %x\n", __FUNCTION__, ui32SlotIndex);
    354 
    355     if ((ctx->ui8PipesToUse == 2) && ((ui32SlotIndex & 1) == 1))
    356 	ui32Offset = object_buffer->size >> 1;
    357 
    358     tng_cmdbuf_insert_command(
    359         ctx->obj_context, ctx->ui32StreamID,
    360         MTX_CMDID_PROVIDE_CODED_BUFFER,
    361         F_ENCODE(object_buffer->size, MTX_MSG_PROVIDE_CODED_BUFFER_SIZE) |
    362         F_ENCODE(ui32SlotIndex, MTX_MSG_PROVIDE_CODED_BUFFER_SLOT),
    363         object_buffer->psb_buffer, tng_align_KB(ui32Offset));
    364 
    365     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
    366     return  VA_STATUS_SUCCESS;
    367 }
    368 
    369 static VAStatus tng__set_component_offsets(
    370     context_ENC_p ctx,
    371     object_surface_p obj_surface_p,
    372     IMG_FRAME * psFrame
    373 )
    374 {
    375     IMG_FORMAT eFormat;
    376     IMG_UINT16 ui16Width;
    377     IMG_UINT16 ui16Stride;
    378     IMG_UINT16 ui16PictureHeight;
    379 
    380     if (!ctx)
    381         return VA_STATUS_ERROR_UNKNOWN;
    382     // if source slot is NULL then it's just a next portion of slices
    383     if (psFrame == IMG_NULL)
    384         return VA_STATUS_ERROR_UNKNOWN;
    385 
    386     eFormat = ctx->eFormat;
    387     ui16Width = obj_surface_p->width;
    388     ui16PictureHeight = obj_surface_p->height;
    389     ui16Stride = obj_surface_p->psb_surface->stride;
    390     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s eFormat = %d, w = %d, h = %d, stride = %d\n",
    391         __FUNCTION__, eFormat, ui16Width, ui16PictureHeight, ui16Stride);
    392     // 3 Components: Y, U, V
    393     // Y component is always at the beginning
    394     psFrame->i32YComponentOffset = 0;
    395     psFrame->ui16SrcYStride = ui16Stride;
    396 
    397     // Assume for now that field 0 comes first
    398     psFrame->i32Field0YOffset = 0;
    399     psFrame->i32Field0UOffset = 0;
    400     psFrame->i32Field0VOffset = 0;
    401 
    402 
    403     switch (eFormat) {
    404     case IMG_CODEC_YUV:
    405         psFrame->ui16SrcUVStride = ui16Stride / 2;              // ui16SrcUStride
    406 
    407         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight;   // ui16SrcUBase
    408         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight + (ui16Stride / 2) * (ui16PictureHeight / 2); // ui16SrcVBase
    409         break;
    410 
    411     case IMG_CODEC_PL8:
    412         psFrame->ui16SrcUVStride = ui16Stride / 2;              // ui16SrcUStride
    413 
    414         psFrame->i32UComponentOffset = 0;   // ui16SrcUBase
    415         psFrame->i32VComponentOffset = 0; // ui16SrcVBase
    416         break;
    417 
    418     case IMG_CODEC_PL12:
    419         psFrame->ui16SrcUVStride = ui16Stride;                         // ui16SrcUStride
    420         //FIXME
    421         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight; // ui16SrcUBase
    422         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight; // ui16SrcVBase
    423         break;
    424 
    425     case IMG_CODEC_YV12:    /* YV12 */
    426         psFrame->ui16SrcUVStride = ui16Stride / 2;              // ui16SrcUStride
    427 
    428         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight + (ui16Stride / 2) * (ui16PictureHeight / 2);   // ui16SrcUBase
    429         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight; // ui16SrcVBase
    430         break;
    431 
    432     case IMG_CODEC_IMC2:    /* IMC2 */
    433         psFrame->ui16SrcUVStride = ui16Stride;                  // ui16SrcUStride
    434 
    435         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight + (ui16Stride / 2);   // ui16SrcUBase
    436         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight; // ui16SrcVBase
    437         break;
    438 
    439     case IMG_CODEC_422_YUV:
    440         psFrame->ui16SrcUVStride = ui16Stride;          // ui16SrcUStride
    441 
    442         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight;   // ui16SrcUBase
    443         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight + (ui16Stride / 2) * ui16PictureHeight; // ui16SrcVBase
    444         break;
    445 
    446     case IMG_CODEC_422_YV12:        /* YV16 */
    447         psFrame->ui16SrcUVStride = ui16Stride;          // ui16SrcUStride
    448 
    449         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight + (ui16Stride / 2) * ui16PictureHeight;   // ui16SrcUBase
    450         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight; // ui16SrcVBase
    451         break;
    452 
    453     case IMG_CODEC_422_PL8:
    454         psFrame->ui16SrcUVStride = ui16Stride;          // ui16SrcUStride
    455 
    456         psFrame->i32UComponentOffset = 0;   // ui16SrcUBase
    457         psFrame->i32VComponentOffset = 0; // ui16SrcVBase
    458         break;
    459 
    460     case IMG_CODEC_422_IMC2:        /* IMC2 */
    461         psFrame->ui16SrcUVStride = ui16Stride * 2;                      // ui16SrcUStride
    462 
    463         psFrame->i32UComponentOffset = ui16Stride * ui16PictureHeight + (ui16Stride / 2);   // ui16SrcUBase
    464         psFrame->i32VComponentOffset = ui16Stride * ui16PictureHeight; // ui16SrcVBase
    465         break;
    466 
    467     case IMG_CODEC_422_PL12:
    468         psFrame->ui16SrcUVStride = ui16Stride * 2;                      // ui16SrcUStride
    469 
    470         psFrame->i32UComponentOffset = 0;   // ui16SrcUBase
    471         psFrame->i32VComponentOffset = 0; // ui16SrcVBase
    472         break;
    473 
    474     case IMG_CODEC_Y0UY1V_8888:
    475     case IMG_CODEC_Y0VY1U_8888:
    476     case IMG_CODEC_UY0VY1_8888:
    477     case IMG_CODEC_VY0UY1_8888:
    478         psFrame->ui16SrcUVStride = ui16Stride;                  // ui16SrcUStride
    479 
    480         psFrame->i32UComponentOffset = 0;   // ui16SrcUBase
    481         psFrame->i32VComponentOffset = 0; // ui16SrcVBase
    482         break;
    483 
    484     default:
    485         break;
    486     }
    487 
    488     if (ctx->bIsInterlaced) {
    489         if (ctx->bIsInterleaved) {
    490             switch (eFormat) {
    491             case IMG_CODEC_IMC2:
    492             case IMG_CODEC_422_IMC2:
    493                 psFrame->i32VComponentOffset *= 2;
    494                 psFrame->i32UComponentOffset = psFrame->i32VComponentOffset + (ui16Stride / 2);
    495                 break;
    496             default:
    497                 psFrame->i32UComponentOffset *= 2;
    498                 psFrame->i32VComponentOffset *= 2;
    499                 break;
    500             }
    501 
    502             psFrame->i32Field1YOffset = psFrame->i32Field0YOffset + psFrame->ui16SrcYStride;
    503             psFrame->i32Field1UOffset = psFrame->i32Field0UOffset + psFrame->ui16SrcUVStride;
    504             psFrame->i32Field1VOffset = psFrame->i32Field0VOffset + psFrame->ui16SrcUVStride;
    505 
    506             psFrame->ui16SrcYStride *= 2;                           // ui16SrcYStride
    507             psFrame->ui16SrcUVStride *= 2;                  // ui16SrcUStride
    508 
    509             if (!ctx->bTopFieldFirst)       {
    510                 IMG_INT32 i32Temp;
    511 
    512                 i32Temp = psFrame->i32Field1YOffset;
    513                 psFrame->i32Field1YOffset = psFrame->i32Field0YOffset;
    514                 psFrame->i32Field0YOffset = i32Temp;
    515 
    516                 i32Temp = psFrame->i32Field1UOffset;
    517                 psFrame->i32Field1UOffset = psFrame->i32Field0UOffset;
    518                 psFrame->i32Field0UOffset = i32Temp;
    519 
    520                 i32Temp = psFrame->i32Field1VOffset;
    521                 psFrame->i32Field1VOffset = psFrame->i32Field0VOffset;
    522                 psFrame->i32Field0VOffset = i32Temp;
    523             }
    524         } else {
    525             IMG_UINT32 ui32YFieldSize, ui32CFieldSize;
    526 
    527             switch (eFormat) {
    528             case IMG_CODEC_Y0UY1V_8888:
    529             case IMG_CODEC_UY0VY1_8888:
    530             case IMG_CODEC_Y0VY1U_8888:
    531             case IMG_CODEC_VY0UY1_8888:
    532                 ui32YFieldSize = ui16PictureHeight * ui16Stride * 2;
    533                 ui32CFieldSize = ui32YFieldSize;
    534                 break;
    535             case IMG_CODEC_PL8:
    536                 ui32YFieldSize = ui16PictureHeight * ui16Stride;
    537                 ui32CFieldSize = ui16PictureHeight * ui16Stride / 4;
    538                 break;
    539             case IMG_CODEC_PL12:
    540                 ui32YFieldSize = ui16PictureHeight * ui16Stride;
    541                 ui32CFieldSize = ui16PictureHeight * ui16Stride / 2;
    542                 break;
    543             case IMG_CODEC_422_YUV:
    544             case IMG_CODEC_422_YV12:
    545             case IMG_CODEC_422_IMC2:
    546                 ui32YFieldSize = ui16PictureHeight * ui16Stride * 2;
    547                 ui32CFieldSize = ui32YFieldSize;
    548                 break;
    549             case IMG_CODEC_422_PL8:
    550                 ui32YFieldSize = ui16PictureHeight * ui16Stride;
    551                 ui32CFieldSize = ui16PictureHeight * ui16Stride / 2;
    552                 break;
    553             case IMG_CODEC_422_PL12:
    554                 ui32YFieldSize = ui16PictureHeight * ui16Stride;
    555                 ui32CFieldSize = ui32YFieldSize;
    556                 break;
    557             default:
    558                 ui32YFieldSize = ui16PictureHeight * ui16Stride * 3 / 2;
    559                 ui32CFieldSize = ui32YFieldSize;
    560                 break;
    561             }
    562 
    563             psFrame->i32Field1YOffset = ui32YFieldSize;
    564             psFrame->i32Field1UOffset = ui32CFieldSize;
    565             psFrame->i32Field1VOffset = ui32CFieldSize;
    566         }
    567     } else {
    568         psFrame->i32Field1YOffset = psFrame->i32Field0YOffset;
    569         psFrame->i32Field1UOffset = psFrame->i32Field0UOffset;
    570         psFrame->i32Field1VOffset = psFrame->i32Field0VOffset;
    571     }
    572     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s i32YComponentOffset = %d, i32UComponentOffset = %d, i32VComponentOffset = %d\n",
    573         __FUNCTION__, (int)(psFrame->i32YComponentOffset), (int)(psFrame->i32UComponentOffset), (int)(psFrame->i32VComponentOffset));
    574      return VA_STATUS_SUCCESS;
    575 }
    576 
    577 IMG_UINT32 tng_send_source_frame(
    578     context_ENC_p ctx,
    579     IMG_UINT32 ui32SlotIndex,
    580     IMG_UINT32 ui32DisplayOrder)
    581 {
    582     VAStatus vaStatus = VA_STATUS_SUCCESS;
    583     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
    584     IMG_FRAME  sSrcFrame;
    585     IMG_FRAME  *psSrcFrame = &sSrcFrame;
    586     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
    587     IMG_SOURCE_BUFFER_PARAMS  *psSrcBufParams = NULL;
    588     object_surface_p src_surface = ps_buf->src_surface;
    589     unsigned int frame_mem_index = 0;
    590     unsigned int srf_buf_offset = src_surface->psb_surface->buf.buffer_ofs;
    591 
    592     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    593         "%s: ui32SlotIndex = %d, ui32DisplayOrder = %d\n",
    594         __FUNCTION__, ui32SlotIndex, ui32DisplayOrder);
    595 
    596     if (cmdbuf->frame_mem_index >= COMM_CMD_FRAME_BUF_NUM) {
    597         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Error: frame_mem buffer index overflow\n", __FUNCTION__);
    598         cmdbuf->frame_mem_index = 0;
    599     }
    600 
    601     vaStatus = psb_buffer_map(&cmdbuf->frame_mem, &(cmdbuf->frame_mem_p));
    602     if (vaStatus) {
    603         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: map frame buf\n", __FUNCTION__);
    604         return vaStatus;
    605     }
    606 
    607     frame_mem_index = cmdbuf->frame_mem_index * cmdbuf->mem_size;
    608     psSrcBufParams = (IMG_SOURCE_BUFFER_PARAMS *)(cmdbuf->frame_mem_p + frame_mem_index);
    609     memset(psSrcBufParams, 0, sizeof(IMG_SOURCE_BUFFER_PARAMS));
    610     memset(psSrcFrame, 0, sizeof(IMG_FRAME));
    611     tng__set_component_offsets(ctx, src_surface, psSrcFrame);
    612 
    613     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    614         "%s: cmdbuf->frame_mem_index = %d, frame_mem_index = 0x%08x, cmdbuf->frame_mem_p = 0x%08x\n",
    615         __FUNCTION__, cmdbuf->frame_mem_index, frame_mem_index, cmdbuf->frame_mem_p);
    616     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    617         "%s: frame_mem_index = %d, psBufferParams = 0x%08x\n",
    618         __FUNCTION__, frame_mem_index, (unsigned int)psSrcBufParams);
    619 
    620     /* Prepare ProvideBuffer data */
    621     {
    622         psSrcBufParams->ui8SlotNum = (IMG_UINT8)(ui32SlotIndex & 0xff);
    623         psSrcBufParams->ui8DisplayOrderNum = (IMG_UINT8)(ui32DisplayOrder & 0xff);
    624         psSrcBufParams->ui32HostContext = (IMG_UINT32)ctx;
    625 
    626 #ifdef _TNG_RELOC_
    627         TNG_RELOC_CMDBUF_FRAMES(
    628             &(psSrcBufParams->ui32PhysAddrYPlane_Field0),
    629             srf_buf_offset + psSrcFrame->i32YComponentOffset + psSrcFrame->i32Field0YOffset,
    630             &(src_surface->psb_surface->buf));
    631         TNG_RELOC_CMDBUF_FRAMES(
    632             &(psSrcBufParams->ui32PhysAddrUPlane_Field0),
    633             srf_buf_offset + psSrcFrame->i32UComponentOffset + psSrcFrame->i32Field0UOffset,
    634             &(src_surface->psb_surface->buf));
    635         TNG_RELOC_CMDBUF_FRAMES(
    636             &(psSrcBufParams->ui32PhysAddrVPlane_Field0),
    637             srf_buf_offset + psSrcFrame->i32VComponentOffset + psSrcFrame->i32Field0VOffset,
    638             &(src_surface->psb_surface->buf));
    639 
    640         TNG_RELOC_CMDBUF_FRAMES(
    641             &(psSrcBufParams->ui32PhysAddrYPlane_Field1),
    642             srf_buf_offset + psSrcFrame->i32YComponentOffset + psSrcFrame->i32Field1YOffset,
    643             &(src_surface->psb_surface->buf));
    644         TNG_RELOC_CMDBUF_FRAMES(
    645             &(psSrcBufParams->ui32PhysAddrUPlane_Field1),
    646             srf_buf_offset + psSrcFrame->i32UComponentOffset + psSrcFrame->i32Field1UOffset,
    647             &(src_surface->psb_surface->buf));
    648         TNG_RELOC_CMDBUF_FRAMES(
    649             &(psSrcBufParams->ui32PhysAddrVPlane_Field1),
    650             srf_buf_offset + psSrcFrame->i32VComponentOffset + psSrcFrame->i32Field1VOffset,
    651             &(src_surface->psb_surface->buf));
    652 #else
    653         tng_cmdbuf_set_phys(&(psSrcBufParams->ui32PhysAddrYPlane_Field0), 0,
    654             &(src_surface->psb_surface->buf),
    655             srf_buf_offset + psSrcFrame->i32YComponentOffset + psSrcFrame->i32Field0YOffset, 0);
    656         tng_cmdbuf_set_phys(&(psSrcBufParams->ui32PhysAddrUPlane_Field0), 0,
    657             &(src_surface->psb_surface->buf),
    658             srf_buf_offset + psSrcFrame->i32UComponentOffset + psSrcFrame->i32Field0UOffset, 0);
    659         tng_cmdbuf_set_phys(&(psSrcBufParams->ui32PhysAddrVPlane_Field0), 0,
    660             &(src_surface->psb_surface->buf),
    661             srf_buf_offset + psSrcFrame->i32VComponentOffset + psSrcFrame->i32Field0VOffset, 0);
    662 
    663         tng_cmdbuf_set_phys(&(psSrcBufParams->ui32PhysAddrYPlane_Field1), 0,
    664             &(src_surface->psb_surface->buf),
    665             srf_buf_offset + psSrcFrame->i32YComponentOffset + psSrcFrame->i32Field1YOffset, 0);
    666         tng_cmdbuf_set_phys(&(psSrcBufParams->ui32PhysAddrUPlane_Field1), 0,
    667             &(src_surface->psb_surface->buf),
    668             srf_buf_offset + psSrcFrame->i32UComponentOffset + psSrcFrame->i32Field1UOffset, 0);
    669         tng_cmdbuf_set_phys(&(psSrcBufParams->ui32PhysAddrVPlane_Field1), 0,
    670             &(src_surface->psb_surface->buf),
    671             srf_buf_offset + psSrcFrame->i32VComponentOffset + psSrcFrame->i32Field1VOffset, 0);
    672 #endif
    673     }
    674     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    675         "%s slot_idx = %d, frame_count = %d\n", __FUNCTION__,
    676         (int)(ui32SlotIndex), (int)(ctx->ui32FrameCount[ctx->ui32StreamID]));
    677     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    678         "%s: YPlane_Field0 = 0x%08x, UPlane_Field0 = 0x%08x, VPlane_Field0 = 0x%08x\n",
    679         __FUNCTION__, (unsigned int)(psSrcBufParams->ui32PhysAddrYPlane_Field0),
    680         (unsigned int)(psSrcBufParams->ui32PhysAddrUPlane_Field0),
    681         (unsigned int)(psSrcBufParams->ui32PhysAddrVPlane_Field0));
    682     drv_debug_msg(VIDEO_DEBUG_GENERAL,
    683         "%s: YPlane_Field1 = 0x%08x, UPlane_Field1 = 0x%08x, VPlane_Field1 = 0x%08x\n",
    684         __FUNCTION__, (unsigned int)(psSrcBufParams->ui32PhysAddrYPlane_Field1),
    685         (unsigned int)(psSrcBufParams->ui32PhysAddrUPlane_Field1),
    686         (unsigned int)(psSrcBufParams->ui32PhysAddrVPlane_Field1));
    687 
    688     /* Send ProvideBuffer Command */
    689     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
    690         MTX_CMDID_PROVIDE_SOURCE_BUFFER,
    691         0, &(cmdbuf->frame_mem), frame_mem_index);
    692 
    693     ++(cmdbuf->frame_mem_index);
    694     psb_buffer_unmap(&cmdbuf->frame_mem);
    695 
    696     return 0;
    697 }
    698 
    699 
    700 IMG_UINT32 tng_send_rec_frames(
    701     context_ENC_p ctx,
    702     IMG_INT8 i8HeaderSlotNum,
    703     IMG_BOOL bLongTerm)
    704 {
    705     //VAStatus vaStatus = VA_STATUS_SUCCESS;
    706     unsigned int srf_buf_offset;
    707     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
    708     object_surface_p rec_surface = ps_buf->rec_surface;
    709     IMG_UINT32 ui32CmdData = 0;
    710 
    711     srf_buf_offset = rec_surface->psb_surface->buf.buffer_ofs;
    712     /* Send ProvideBuffer Command */
    713     ui32CmdData = F_ENCODE(IMG_BUFFER_RECON, MTX_MSG_PROVIDE_REF_BUFFER_USE) |
    714         F_ENCODE(i8HeaderSlotNum, MTX_MSG_PROVIDE_REF_BUFFER_SLOT) |
    715         F_ENCODE(bLongTerm, MTX_MSG_PROVIDE_REF_BUFFER_LT);
    716 
    717     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
    718         MTX_CMDID_PROVIDE_REF_BUFFER,
    719         ui32CmdData, &(rec_surface->psb_surface->buf), 0);
    720 
    721     return 0;
    722 }
    723 
    724 IMG_UINT32 tng_send_ref_frames(
    725     context_ENC_p ctx,
    726     IMG_UINT32    ui32refindex,
    727     IMG_BOOL      __maybe_unused bLongTerm)
    728 {
    729     //VAStatus vaStatus = VA_STATUS_SUCCESS;
    730     unsigned int srf_buf_offset;
    731     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
    732     object_surface_p ref_surface = ps_buf->ref_surface[ui32refindex];
    733     IMG_UINT32 ui32CmdData = 0;
    734 
    735 #ifdef _TNG_FRAMES_
    736     if (ui32RefIndex == 0) {
    737         ref_surface = ps_buf->ref_surface;
    738         ui32CmdData = F_ENCODE(IMG_BUFFER_REF0, MTX_MSG_PROVIDE_REF_BUFFER_USE) |
    739             F_ENCODE(bLongTerm, MTX_MSG_PROVIDE_REF_BUFFER_LT);
    740     } else {
    741         ref_surface = ps_buf->ref_surface1;
    742         ui32CmdData = F_ENCODE(IMG_BUFFER_REF1, MTX_MSG_PROVIDE_REF_BUFFER_USE) |
    743         F_ENCODE(bLongTerm, MTX_MSG_PROVIDE_REF_BUFFER_LT);
    744     }
    745 #endif
    746     srf_buf_offset = ref_surface->psb_surface->buf.buffer_ofs;
    747     /* Send ProvideBuffer Command */
    748     tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
    749         MTX_CMDID_PROVIDE_REF_BUFFER,
    750         ui32CmdData, &(ref_surface->psb_surface->buf), 0);
    751 
    752     return VA_STATUS_SUCCESS;
    753 }
    754 
    755