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