pnw_jpeg.c revision 5b25aaf457f3ba02a4ff2a6243fa7c0f84f1e016
1/* 2 * INTEL CONFIDENTIAL 3 * Copyright 2007 Intel Corporation. All Rights Reserved. 4 * 5 * The source code contained or described herein and all documents related to 6 * the source code ("Material") are owned by Intel Corporation or its suppliers 7 * or licensors. Title to the Material remains with Intel Corporation or its 8 * suppliers and licensors. The Material may contain trade secrets and 9 * proprietary and confidential information of Intel Corporation and its 10 * suppliers and licensors, and is protected by worldwide copyright and trade 11 * secret laws and treaty provisions. No part of the Material may be used, 12 * copied, reproduced, modified, published, uploaded, posted, transmitted, 13 * distributed, or disclosed in any way without Intel's prior express written 14 * permission. 15 * 16 * No license under any patent, copyright, trade secret or other intellectual 17 * property right is granted to or conferred upon you by disclosure or delivery 18 * of the Materials, either expressly, by implication, inducement, estoppel or 19 * otherwise. Any license under such intellectual property rights must be 20 * express and approved by Intel in writing. 21 */ 22 23/* 24 * Authors: 25 * Elaine Wang <elaine.wang@intel.com> 26 * 27 */ 28 29 30#include <stdlib.h> 31#include <stdint.h> 32#include <string.h> 33 34#include "psb_def.h" 35#include "psb_surface.h" 36#include "psb_cmdbuf.h" 37#include "pnw_jpeg.h" 38#include "pnw_hostcode.h" 39#include "pnw_hostheader.h" 40#include "pnw_hostjpeg.h" 41 42#define INIT_CONTEXT_JPEG context_ENC_p ctx = (context_ENC_p) obj_context->format_data 43#define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 44#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id )) 45 46static const uint32_t aui32_jpg_mtx_num[PNW_JPEG_MAX_SCAN_NUM] = {0x1, 0x1, 0x1, 0x5, 0x15, 0x15, 0x55}; 47 48static void pnw_jpeg_QueryConfigAttributes( 49 VAProfile profile, 50 VAEntrypoint entrypoint, 51 VAConfigAttrib *attrib_list, 52 int num_attribs) 53{ 54 int i; 55 56 psb__information_message("pnw_jpeg_QueryConfigAttributes\n"); 57 58 /* RateControl attributes */ 59 for (i = 0; i < num_attribs; i++) { 60 switch (attrib_list[i].type) { 61 case VAConfigAttribRTFormat: 62 break; 63 default: 64 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; 65 break; 66 } 67 } 68 69 return; 70} 71 72 73static VAStatus pnw_jpeg_ValidateConfig( 74 object_config_p obj_config) 75{ 76 int i; 77 /* Check all attributes */ 78 for (i = 0; i < obj_config->attrib_count; i++) { 79 switch (obj_config->attrib_list[i].type) { 80 case VAConfigAttribRTFormat: 81 /* Ignore */ 82 break; 83 case VAConfigAttribRateControl: 84 break; 85 default: 86 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 87 } 88 } 89 90 return VA_STATUS_SUCCESS; 91 92} 93 94/*Init JPEG context. Ported from IMG_JPEG_EncoderInitialise*/ 95static VAStatus pnw_jpeg_CreateContext( 96 object_context_p obj_context, 97 object_config_p obj_config) 98{ 99 VAStatus vaStatus = VA_STATUS_SUCCESS; 100 context_ENC_p ctx; 101 TOPAZSC_JPEG_ENCODER_CONTEXT *jpeg_ctx_p; 102 int i; 103 104 psb__information_message("pnw_jpeg_CreateContext\n"); 105 106 vaStatus = pnw_CreateContext(obj_context, obj_config, 1); 107 if (VA_STATUS_SUCCESS != vaStatus) 108 return VA_STATUS_ERROR_ALLOCATION_FAILED; 109 110 ctx = (context_ENC_p) obj_context->format_data; 111 112 ctx->eCodec = IMG_CODEC_JPEG; 113 114 for (i = 0; i < obj_config->attrib_count; i++) { 115 if (VAConfigAttribRTFormat == obj_config->attrib_list[i].type) { 116 switch (obj_config->attrib_list[i].value) { 117 case VA_RT_FORMAT_YUV420: 118 ctx->eFormat = IMG_CODEC_PL12; 119 psb__information_message("JPEG encoding: Choose NV12 format\n"); 120 break; 121 case VA_RT_FORMAT_YUV422: 122 ctx->eFormat = IMG_CODEC_YV16; 123 psb__information_message("JPEG encoding: Choose YV16 format\n"); 124 break; 125 default: 126 psb__error_message("JPEG encoding: unsupported YUV format!\n"); 127 ctx->eFormat = IMG_CODEC_PL12; 128 break; 129 } 130 break; 131 } 132 } 133 134 ctx->Slices = 2; 135 ctx->ParallelCores = 2; 136 ctx->NumCores = 2; 137 ctx->jpeg_ctx = (TOPAZSC_JPEG_ENCODER_CONTEXT *)calloc(1, sizeof(TOPAZSC_JPEG_ENCODER_CONTEXT)); 138 139 if (NULL == ctx->jpeg_ctx) 140 return VA_STATUS_ERROR_ALLOCATION_FAILED; 141 142 jpeg_ctx_p = ctx->jpeg_ctx; 143 jpeg_ctx_p->eFormat = ctx->eFormat; 144 145 /*Chroma sampling step x_step X y_step*/ 146 jpeg_ctx_p->ui8ScanNum = JPEG_SCANNING_COUNT(ctx->Width, ctx->Height, ctx->NumCores, jpeg_ctx_p->eFormat); 147 148 if (jpeg_ctx_p->ui8ScanNum < 2 || jpeg_ctx_p->ui8ScanNum > PNW_JPEG_MAX_SCAN_NUM) { 149 psb__error_message("JPEG MCU scanning number(%d) is wrong!\n", jpeg_ctx_p->ui8ScanNum); 150 free(ctx->jpeg_ctx); 151 ctx->jpeg_ctx = NULL; 152 return VA_STATUS_ERROR_UNKNOWN; 153 } 154 155 jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers = jpeg_ctx_p->ui8ScanNum; 156 157 psb__information_message(" JPEG Scanning Number %d\n", jpeg_ctx_p->ui8ScanNum); 158 jpeg_ctx_p->sScan_Encode_Info.aBufferTable = 159 (TOPAZSC_JPEG_BUFFER_INFO *)calloc(1, sizeof(TOPAZSC_JPEG_BUFFER_INFO) 160 * jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers); 161 162 if (NULL == jpeg_ctx_p->sScan_Encode_Info.aBufferTable) 163 return VA_STATUS_ERROR_ALLOCATION_FAILED; 164 jpeg_ctx_p->ui32OutputWidth = ctx->Width; 165 jpeg_ctx_p->ui32OutputHeight = ctx->Height; 166 167 /*It will be figured out when known the size of whole coded buffer.*/ 168 jpeg_ctx_p->ui32SizePerCodedBuffer = 0; 169 170 jpeg_ctx_p->ctx = ctx; 171 /*Reuse header_mem(76*4 bytes) and pic_params_size(256 bytes) 172 * as pMemInfoMTXSetup(JPEG_MTX_DMA_SETUP 24x4 bytes) and 173 * pMemInfoTableBlock JPEG_MTX_QUANT_TABLE(128byes)*/ 174 return vaStatus; 175} 176 177 178static void pnw_jpeg_DestroyContext( 179 object_context_p obj_context) 180{ 181 context_ENC_p ctx; 182 183 psb__information_message("pnw_jpeg_DestroyPicture\n"); 184 185 ctx = (context_ENC_p)(obj_context->format_data); 186 187 if (ctx->jpeg_ctx) { 188 if (ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable) { 189 free(ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable); 190 ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable = NULL; 191 } 192 193 free(ctx->jpeg_ctx); 194 } 195 pnw_DestroyContext(obj_context); 196 197} 198 199static VAStatus pnw_jpeg_BeginPicture( 200 object_context_p obj_context) 201{ 202 INIT_CONTEXT_JPEG; 203 VAStatus vaStatus = VA_STATUS_SUCCESS; 204 int ret; 205 pnw_cmdbuf_p cmdbuf; 206 207 psb__information_message("pnw_jpeg_BeginPicture: Frame %d\n", ctx->obj_context->frame_count); 208 209 ctx->src_surface = ctx->obj_context->current_render_target; 210 211 /* Initialise the command buffer */ 212 ret = pnw_context_get_next_cmdbuf(ctx->obj_context); 213 if (ret) { 214 psb__information_message("get next cmdbuf fail\n"); 215 vaStatus = VA_STATUS_ERROR_UNKNOWN; 216 return vaStatus; 217 } 218 cmdbuf = ctx->obj_context->pnw_cmdbuf; 219 220 /* map start_pic param */ 221 vaStatus = psb_buffer_map(&cmdbuf->pic_params, &cmdbuf->pic_params_p); 222 if (vaStatus) { 223 return vaStatus; 224 } 225 vaStatus = psb_buffer_map(&cmdbuf->header_mem, &cmdbuf->header_mem_p); 226 if (vaStatus) { 227 psb_buffer_unmap(&cmdbuf->pic_params); 228 return vaStatus; 229 } 230 231 memset(ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable, 0, 232 sizeof(TOPAZSC_JPEG_BUFFER_INFO) * ctx->jpeg_ctx->sScan_Encode_Info.ui8NumberOfCodedBuffers); 233 234 /*Store the QMatrix data*/ 235 ctx->jpeg_ctx->pMemInfoTableBlock = cmdbuf->pic_params_p; 236 ctx->jpeg_ctx->psTablesBlock = (JPEG_MTX_QUANT_TABLE *)ctx->jpeg_ctx->pMemInfoTableBlock; 237 238 /*Store MTX_SETUP data*/ 239 ctx->jpeg_ctx->pMemInfoMTXSetup = cmdbuf->header_mem_p; 240 ctx->jpeg_ctx->pMTXSetup = (JPEG_MTX_DMA_SETUP*)ctx->jpeg_ctx->pMemInfoMTXSetup; 241 242 ctx->jpeg_ctx->pMTXSetup->ui32ComponentsInScan = PNW_JPEG_COMPONENTS_NUM; 243 244 if (ctx->obj_context->frame_count == 0) { /* first picture */ 245 246 psb_driver_data_p driver_data = ctx->obj_context->driver_data; 247 248 *cmdbuf->cmd_idx++ = ((MTX_CMDID_SW_NEW_CODEC & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) | 249 (((driver_data->drm_context & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT)); 250 pnw_cmdbuf_insert_command_param(ctx->eCodec); 251 pnw_cmdbuf_insert_command_param((ctx->Width << 16) | ctx->Height); 252 } 253 254 pnw_jpeg_set_default_qmatix(ctx->jpeg_ctx->pMemInfoTableBlock); 255 256 InitializeJpegEncode(ctx->jpeg_ctx, ctx->src_surface); 257 258 return vaStatus; 259} 260 261static VAStatus pnw__jpeg_process_picture_param(context_ENC_p ctx, object_buffer_p obj_buffer) 262{ 263 VAStatus vaStatus = VA_STATUS_SUCCESS; 264 VAEncPictureParameterBufferJPEG *pBuffer; 265 pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf; 266 BUFFER_HEADER *pBufHeader; 267 //unsigned long *pPictureHeaderMem; 268 //MTX_HEADER_PARAMS *psPicHeader; 269 int i; 270 TOPAZSC_JPEG_ENCODER_CONTEXT *jpeg_ctx = ctx->jpeg_ctx; 271 IMG_ERRORCODE rc; 272 273 ASSERT(obj_buffer->type == VAEncPictureParameterBufferType); 274 275 if ((obj_buffer->num_elements != 1) || 276 (obj_buffer->size != sizeof(VAEncPictureParameterBufferJPEG))) { 277 return VA_STATUS_ERROR_UNKNOWN; 278 } 279 280 /* Transfer ownership of VAEncPictureParameterBufferMPEG4 data */ 281 pBuffer = (VAEncPictureParameterBufferJPEG *) obj_buffer->buffer_data; 282 obj_buffer->buffer_data = NULL; 283 obj_buffer->size = 0; 284 285 ASSERT(ctx->Width == pBuffer->picture_width); 286 ASSERT(ctx->Height == pBuffer->picture_height); 287 288 ctx->coded_buf = BUFFER(pBuffer->coded_buf); 289 290 free(pBuffer); 291 292 if (NULL == ctx->coded_buf) { 293 psb__error_message("%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__); 294 return VA_STATUS_ERROR_INVALID_BUFFER; 295 } 296 297 psb__information_message("Set Quant Tables\n"); 298 /*Set Quant Tables*/ 299 for (i = ctx->NumCores - 1; i >= 0; i--) 300 pnw_cmdbuf_insert_command_package(ctx->obj_context, 301 i, 302 MTX_CMDID_SETQUANT, 303 &cmdbuf->pic_params, 304 0); 305 306 psb__information_message("Quant Table \n"); 307 308 for (i = 0; i < 128 ; i++) { 309 psb__information_message("%d \t", *((unsigned char *)cmdbuf->pic_params_p + i)); 310 if (((i + 1) % 8) == 0) 311 psb__information_message("\n"); 312 } 313 314 jpeg_ctx->ui32SizePerCodedBuffer = 315 JPEG_CODED_BUF_SEGMENT_SIZE(ctx->coded_buf->size, 316 ctx->Width, ctx->Height, ctx->NumCores, jpeg_ctx->eFormat); 317 318 psb__information_message("Coded buffer total size is %d," 319 "coded segment size per scan is %d\n", 320 ctx->coded_buf->size, jpeg_ctx->ui32SizePerCodedBuffer); 321 322 vaStatus = psb_buffer_map(ctx->coded_buf->psb_buffer, &jpeg_ctx->jpeg_coded_buf.pMemInfo); 323 if (vaStatus) { 324 psb__error_message("ERROR: Map coded_buf failed!"); 325 return vaStatus; 326 } 327 jpeg_ctx->jpeg_coded_buf.ui32Size = ctx->coded_buf->size; 328 jpeg_ctx->jpeg_coded_buf.sLock = BUFFER_FREE; 329 jpeg_ctx->jpeg_coded_buf.ui32BytesWritten = 0; 330 331 psb__information_message("Setup JPEG Tables\n"); 332 rc = SetupJPEGTables(ctx->jpeg_ctx, &jpeg_ctx->jpeg_coded_buf, ctx->src_surface); 333 334 if (rc != IMG_ERR_OK) 335 return VA_STATUS_ERROR_UNKNOWN; 336 337 psb__information_message("Write JPEG Headers to coded buf\n"); 338 339 pBufHeader = (BUFFER_HEADER *)jpeg_ctx->jpeg_coded_buf.pMemInfo; 340 pBufHeader->ui32BytesUsed = 0; /* Not include BUFFER_HEADER*/ 341 rc = PrepareHeader(jpeg_ctx, &jpeg_ctx->jpeg_coded_buf, sizeof(BUFFER_HEADER), IMG_TRUE); 342 if (rc != IMG_ERR_OK) 343 return VA_STATUS_ERROR_UNKNOWN; 344 345 pBufHeader->ui32Reserved3 = PNW_JPEG_HEADER_MAX_SIZE;//Next coded buffer offset 346 pBufHeader->ui32BytesUsed = jpeg_ctx->jpeg_coded_buf.ui32BytesWritten - sizeof(BUFFER_HEADER); 347 348 psb__information_message("JPEG Buffer Header size: %d, File Header size :%d, next codef buffer offset: %d\n", 349 sizeof(BUFFER_HEADER), pBufHeader->ui32BytesUsed, pBufHeader->ui32Reserved3); 350 return vaStatus; 351} 352 353static VAStatus pnw__jpeg_process_qmatrix_param(context_ENC_p ctx, object_buffer_p obj_buffer) 354{ 355 VAStatus vaStatus = VA_STATUS_SUCCESS; 356 VAQMatrixBufferJPEG *pBuffer; 357 JPEG_MTX_QUANT_TABLE* pQMatrix = (JPEG_MTX_QUANT_TABLE *) 358 (ctx->jpeg_ctx->pMemInfoTableBlock); 359 360 ASSERT(obj_buffer->type == VAQMatrixBufferType); 361 362 pBuffer = (VAQMatrixBufferJPEG *) obj_buffer->buffer_data; 363 364 if (0 != pBuffer->load_lum_quantiser_matrix) { 365 memcpy(pQMatrix->aui8LumaQuantParams, 366 pBuffer->lum_quantiser_matrix, 367 QUANT_TABLE_SIZE_BYTES); 368 } 369 370 if (0 != pBuffer->load_chroma_quantiser_matrix) { 371 memcpy(pQMatrix->aui8ChromaQuantParams, 372 pBuffer->chroma_quantiser_matrix, 373 QUANT_TABLE_SIZE_BYTES); 374 } 375 376 free(obj_buffer->buffer_data); 377 obj_buffer->buffer_data = NULL; 378 379 return vaStatus; 380} 381 382 383static VAStatus pnw_jpeg_RenderPicture( 384 object_context_p obj_context, 385 object_buffer_p *buffers, 386 int num_buffers) 387{ 388 INIT_CONTEXT_JPEG; 389 VAStatus vaStatus = VA_STATUS_SUCCESS; 390 int i; 391 392 psb__information_message("pnw_jpeg_RenderPicture\n"); 393 394 for (i = 0; i < num_buffers; i++) { 395 object_buffer_p obj_buffer = buffers[i]; 396 397 switch (obj_buffer->type) { 398 case VAQMatrixBufferType: 399 psb__information_message("pnw_jpeg_RenderPicture got VAEncSliceParameterBufferType\n"); 400 vaStatus = pnw__jpeg_process_qmatrix_param(ctx, obj_buffer); 401 DEBUG_FAILURE; 402 break; 403 case VAEncPictureParameterBufferType: 404 psb__information_message("pnw_jpeg_RenderPicture got VAEncPictureParameterBufferType\n"); 405 vaStatus = pnw__jpeg_process_picture_param(ctx, obj_buffer); 406 DEBUG_FAILURE; 407 break; 408 default: 409 vaStatus = VA_STATUS_ERROR_UNKNOWN; 410 DEBUG_FAILURE; 411 } 412 } 413 414 return vaStatus; 415} 416 417/* Add Restart interval termination (RSTm)to coded buf 1 ~ NumCores-1*/ 418static inline VAStatus pnw_OutputResetIntervalToCB(IMG_UINT8 *pui8Buf, IMG_UINT8 ui8_marker) 419{ 420 if (NULL == pui8Buf) 421 return VA_STATUS_ERROR_UNKNOWN; 422 /*Refer to CCITT Rec. T.81 (1992 E), B.2.1*/ 423 /*RSTm: Restart marker conditional marker which is placed between 424 * entropy-coded segments only if restartis enabled. There are 8 unique 425 * restart markers (m = 0 - 7) which repeat in sequence from 0 to 7, starting with 426 * zero for each scan, to provide a modulo 8 restart interval count*/ 427 *pui8Buf++ = 0xff; 428 *pui8Buf = (ui8_marker | 0xd0); 429 return 0; 430} 431 432 433static VAStatus pnw_jpeg_EndPicture( 434 object_context_p obj_context) 435{ 436 INIT_CONTEXT_JPEG; 437 IMG_UINT16 ui16BCnt; 438 TOPAZSC_JPEG_ENCODER_CONTEXT *pContext = ctx->jpeg_ctx; 439 IMG_UINT32 rc = 0; 440 pnw_cmdbuf_p cmdbuf = (pnw_cmdbuf_p)ctx->obj_context->pnw_cmdbuf; 441 VAStatus vaStatus = VA_STATUS_SUCCESS; 442 IMG_UINT32 ui32NoMCUsToEncode; 443 IMG_UINT32 ui32RemainMCUs; 444 445 psb__information_message("pnw_jpeg_EndPicture\n"); 446 447 ui32RemainMCUs = pContext->sScan_Encode_Info.ui32NumberMCUsToEncode; 448 449 for (ui16BCnt = 0; ui16BCnt < pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers 450 && pContext->sScan_Encode_Info.ui16SScan > 0; ui16BCnt++) { 451 pContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui16ScanNumber = 452 pContext->sScan_Encode_Info.ui16SScan--; 453 /*i8MTXNumber is the core number.*/ 454 pContext->sScan_Encode_Info.aBufferTable[ui16BCnt].i8MTXNumber = 455 (aui32_jpg_mtx_num[pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers - 2] 456 >> ui16BCnt) & 0x1; 457 458 if (pContext->sScan_Encode_Info.ui16SScan == 0) { 459 ui32NoMCUsToEncode = ui32RemainMCUs; 460 // Final scan, may need fewer MCUs than buffer size, calculate the remainder 461 } else 462 ui32NoMCUsToEncode = pContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan; 463 464 pContext->sScan_Encode_Info.ui32CurMCUsOffset = 465 pContext->sScan_Encode_Info.ui32NumberMCUsToEncode - ui32RemainMCUs; 466 467 rc = SubmitScanToMTX(pContext, ui16BCnt, 468 pContext->sScan_Encode_Info.aBufferTable[ui16BCnt].i8MTXNumber, ui32NoMCUsToEncode); 469 if (rc != IMG_ERR_OK) { 470 vaStatus = VA_STATUS_ERROR_UNKNOWN; 471 DEBUG_FAILURE; 472 return vaStatus; 473 } 474 475 ui32RemainMCUs -= ui32NoMCUsToEncode; 476 } 477 pnw_cmdbuf_insert_command_package(ctx->obj_context, 478 1 , 479 MTX_CMDID_NULL, 480 NULL, 481 0); 482 483 484 psb_buffer_unmap(&cmdbuf->pic_params); 485 cmdbuf->pic_params_p = NULL; 486 psb_buffer_unmap(&cmdbuf->header_mem); 487 cmdbuf->header_mem_p = NULL; 488 /*psb_buffer_unmap(&cmdbuf->slice_params); 489 cmdbuf->slice_params_p = NULL;*/ 490 psb_buffer_unmap(ctx->coded_buf->psb_buffer); 491 pContext->jpeg_coded_buf.pMemInfo = NULL; 492 if (pnw_context_flush_cmdbuf(ctx->obj_context)) { 493 vaStatus = VA_STATUS_ERROR_UNKNOWN; 494 return vaStatus; 495 } 496 497 ctx->obj_context->frame_count++; 498 return VA_STATUS_SUCCESS; 499} 500 501VAStatus pnw_jpeg_AppendMarkers(object_context_p obj_context, void *raw_coded_buf) 502{ 503 INIT_CONTEXT_JPEG; 504 IMG_UINT16 ui16BCnt; 505 TOPAZSC_JPEG_ENCODER_CONTEXT *pContext = ctx->jpeg_ctx; 506 BUFFER_HEADER* pBufHeader; 507 STREAMTYPEW s_streamW; 508 void *pSegStart = raw_coded_buf; 509 510 if (pSegStart == NULL) { 511 return VA_STATUS_ERROR_UNKNOWN; 512 } 513 514 pBufHeader = (BUFFER_HEADER *)pSegStart; 515 516 psb__information_message("Number of Coded buffers %d, Per Coded Buffer size : %d\n", 517 pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers, pContext->ui32SizePerCodedBuffer); 518 519 /*The first part of coded buffer contains JPEG headers*/ 520 pBufHeader->ui32Reserved3 = PNW_JPEG_HEADER_MAX_SIZE; 521 522 pContext->jpeg_coded_buf.ui32BytesWritten = 0; 523 524 for (ui16BCnt = 0; 525 ui16BCnt < pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers; 526 ui16BCnt++) { 527 pBufHeader = (BUFFER_HEADER *)pSegStart; 528 pBufHeader->ui32Reserved3 = 529 PNW_JPEG_HEADER_MAX_SIZE + pContext->ui32SizePerCodedBuffer * ui16BCnt ; 530 531 psb__information_message("Coded Buffer Part %d, size %d, next part offset: %d\n", 532 ui16BCnt, pBufHeader->ui32BytesUsed, pBufHeader->ui32Reserved3); 533 534 if (ui16BCnt > 0 && pContext->sScan_Encode_Info.ui8NumberOfCodedBuffers > 1) { 535 psb__information_message("Append 2 bytes Reset Interval %d " 536 "to Coded Buffer Part %d\n", ui16BCnt - 1, ui16BCnt); 537 538 pnw_OutputResetIntervalToCB( 539 (IMG_UINT8 *)(pSegStart + 540 sizeof(BUFFER_HEADER) + pBufHeader->ui32BytesUsed), 541 ui16BCnt - 1); 542 543 pBufHeader->ui32BytesUsed += 2; 544 } 545 546 pContext->jpeg_coded_buf.ui32BytesWritten += pBufHeader->ui32BytesUsed; 547 pSegStart = raw_coded_buf + pBufHeader->ui32Reserved3; 548 } 549 pBufHeader = (BUFFER_HEADER *)pSegStart; 550 pBufHeader->ui32Reserved3 = 0; /*Last Part of Coded Buffer*/ 551 pContext->jpeg_coded_buf.ui32BytesWritten += pBufHeader->ui32BytesUsed; 552 553 psb__information_message("Coded Buffer Part %d, size %d, next part offset: %d\n", 554 ui16BCnt, pBufHeader->ui32BytesUsed, pBufHeader->ui32Reserved3); 555 556 s_streamW.Buffer = pSegStart; 557 s_streamW.Offset = (sizeof(BUFFER_HEADER) + pBufHeader->ui32BytesUsed); 558 559 fPutBitsToBuffer(&s_streamW, 2, END_OF_IMAGE); 560 561 pBufHeader->ui32BytesUsed += 2; 562 pContext->jpeg_coded_buf.ui32BytesWritten += 2; 563 564 psb__information_message("Add two bytes to last part of coded buffer," 565 " total: %d\n", pContext->jpeg_coded_buf.ui32BytesWritten); 566 return VA_STATUS_SUCCESS; 567} 568 569struct format_vtable_s pnw_JPEG_vtable = { 570queryConfigAttributes: 571 pnw_jpeg_QueryConfigAttributes, 572validateConfig: 573 pnw_jpeg_ValidateConfig, 574createContext: 575 pnw_jpeg_CreateContext, 576destroyContext: 577 pnw_jpeg_DestroyContext, 578beginPicture: 579 pnw_jpeg_BeginPicture, 580renderPicture: 581 pnw_jpeg_RenderPicture, 582endPicture: 583 pnw_jpeg_EndPicture 584}; 585