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 *************************/
tng_picmgmt_update(context_ENC_p ctx,IMG_PICMGMT_TYPE eType,unsigned int ref)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 ******************************************************************************/
tng__picmgmt_long_term_refs(context_ENC_p __maybe_unused ctx,IMG_UINT32 __maybe_unused ui32FrameNum)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
tng__H264ES_CalcCustomQuantSp(IMG_UINT8 list,IMG_UINT8 param,IMG_UINT8 customQuantQ)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
tng__set_custom_scaling_values(context_ENC_p ctx,IMG_UINT8 * aui8Sl4x4IntraY,IMG_UINT8 * aui8Sl4x4IntraCb,IMG_UINT8 * aui8Sl4x4IntraCr,IMG_UINT8 * aui8Sl4x4InterY,IMG_UINT8 * aui8Sl4x4InterCb,IMG_UINT8 * aui8Sl4x4InterCr,IMG_UINT8 * aui8Sl8x8IntraY,IMG_UINT8 * aui8Sl8x8InterY)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
tng__picmgmt_custom_scaling(context_ENC_p ctx,IMG_UINT32 ui32FrameNum)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 *************************/
tng_send_codedbuf(context_ENC_p ctx,IMG_UINT32 ui32SlotIndex)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
tng__set_component_offsets(context_ENC_p ctx,object_surface_p obj_surface_p,IMG_FRAME * psFrame)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
tng_send_source_frame(context_ENC_p ctx,IMG_UINT32 ui32SlotIndex,IMG_UINT32 ui32DisplayOrder)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
tng_send_rec_frames(context_ENC_p ctx,IMG_INT8 i8HeaderSlotNum,IMG_BOOL bLongTerm)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
tng_send_ref_frames(context_ENC_p ctx,IMG_UINT32 ui32refindex,IMG_BOOL __maybe_unused bLongTerm)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