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