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@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 *************************/
52VAStatus 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******************************************************************************/
78void 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
121static 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
167static 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
313void 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 *************************/
344IMG_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
369static 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
577IMG_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
700IMG_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
724IMG_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