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