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