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