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