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