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 #include <stdlib.h>
31 #include <stdint.h>
32 #include <string.h>
33
34 #include "psb_def.h"
35 #include "psb_drv_debug.h"
36 #include "psb_surface.h"
37 #include "psb_cmdbuf.h"
38 #include "tng_hostcode.h"
39 #include "tng_hostheader.h"
40 #include "tng_jpegES.h"
41 #ifdef _TOPAZHP_PDUMP_
42 #include "tng_trace.h"
43 #endif
44
tng__trace_cmdbuf(tng_cmdbuf_p cmdbuf)45 static void tng__trace_cmdbuf(tng_cmdbuf_p cmdbuf)
46 {
47 int i;
48 IMG_UINT32 ui32CmdTmp[4];
49 IMG_UINT32 *ptmp = (IMG_UINT32 *)(cmdbuf->cmd_start);
50
51 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start\n", __FUNCTION__);
52
53 //skip the newcodec
54 if (*ptmp != MTX_CMDID_SW_NEW_CODEC) {
55 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: error new coded\n", __FUNCTION__);
56 return ;
57 }
58 ptmp += 6;
59
60 if ((*ptmp & 0xf) != MTX_CMDID_SETUP_INTERFACE) {
61 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: error setup interface\n", __FUNCTION__);
62 return ;
63 }
64
65 ui32CmdTmp[0] = *ptmp++;
66 ui32CmdTmp[1] = *ptmp++;
67 ui32CmdTmp[2] = *ptmp++;
68 ui32CmdTmp[3] = 0;
69 #ifdef _TOPAZHP_PDUMP_
70 topazhp_dump_command((unsigned int*)ui32CmdTmp);
71 #endif
72 for (i = 0; i < 3; i++) {
73 ui32CmdTmp[0] = *ptmp++;
74 ui32CmdTmp[1] = *ptmp++;
75 ui32CmdTmp[2] = 0;
76 ui32CmdTmp[3] = 0;
77 #ifdef _TOPAZHP_PDUMP_
78 topazhp_dump_command((unsigned int*)ui32CmdTmp);
79 #endif
80 }
81
82 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
83
84 return;
85 }
86
87 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
88 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id ))
89
90 #define PTG_JPEG_MAX_MCU_PER_SCAN (0x4000)
91 #define PTG_JPEG_HEADER_MAX_SIZE (1024)
92
93
94 #define C_INTERLEAVE 1
95 #define LC_YUYVINTERLEAVE 2
96 #define LC_YVYUINTERLEAVE 3
97 #define LC_UYVYINTERLEAVE 4
98 #define LC_VYUYINTERLEAVE 5
99
100 #define ISCHROMAINTERLEAVED(eSurfaceFormat) ((IMG_UINT)(eSurfaceFormat==IMG_CODEC_PL12) * C_INTERLEAVE)
101
102
103 /******************************************************************************
104 General definitions
105 ******************************************************************************/
106 #define BYTE 8
107 #define BYTES_IN_INT 4
108 #define BITS_IN_INT 32
109 #define BLOCK_SIZE 8
110 #define PELS_IN_BLOCK 64
111
112 /******************************************************************************
113 JPEG marker definitions
114 ******************************************************************************/
115 #define START_OF_IMAGE 0xFFD8
116 #define SOF_BASELINE_DCT 0xFFC0
117 #define END_OF_IMAGE 0xFFD9
118 #define START_OF_SCAN 0xFFDA
119
120 /* Definitions for the huffman table specification in the Marker segment */
121 #define DHT_MARKER 0xFFC4
122 #define LH_DC 0x001F
123 #define LH_AC 0x00B5
124 #define LEVEL_SHIFT 128
125
126 /* Definitions for the quantization table specification in the Marker segment */
127 #define DQT_MARKER 0xFFDB
128 #define ACMAX 0x03FF
129 #define DCMAX 0x07FF
130 /* Length and precision of the quantization table parameters */
131 #define LQPQ 0x00430
132 #define QMAX 255
133 #define CLIP(Number,Max,Min) if((Number) > (Max)) (Number) = (Max); \
134 else if((Number) < (Min)) (Number) = (Min)
135
136 /////////////////////////////////////////////////////////////////////////////////////
137 // BMP Reading Header Stuff
138 /////////////////////////////////////////////////////////////////////////////////////
139
140 static const IMG_UINT8 gQuantLuma[QUANT_TABLE_SIZE_BYTES] = {
141 16, 11, 10, 16, 24, 40, 51, 61,
142 12, 12, 14, 19, 26, 58, 60, 55,
143 14, 13, 16, 24, 40, 57, 69, 56,
144 14, 17, 22, 29, 51, 87, 80, 62,
145 18, 22, 37, 56, 68, 109, 103, 77,
146 24, 35, 55, 64, 81, 104, 113, 92,
147 49, 64, 78, 87, 103, 121, 120, 101,
148 72, 92, 95, 98, 112, 100, 103, 99
149 };
150
151 /*****************************************************************************/
152 /* \brief gQuantChroma */
153 /* */
154 /* Contains the data that needs to be sent in the marker segment of an */
155 /* interchange format JPEG stream or an abbreviated format table */
156 /* specification data stream. */
157 /* Quantizer table for the chrominance component */
158 /*****************************************************************************/
159 static const IMG_UINT8 gQuantChroma[QUANT_TABLE_SIZE_BYTES] = {
160 17, 18, 24, 47, 99, 99, 99, 99,
161 18, 21, 26, 66, 99, 99, 99, 99,
162 24, 26, 56, 99, 99, 99, 99, 99,
163 47, 66, 99, 99, 99, 99, 99, 99,
164 99, 99, 99, 99, 99, 99, 99, 99,
165 99, 99, 99, 99, 99, 99, 99, 99,
166 99, 99, 99, 99, 99, 99, 99, 99,
167 99, 99, 99, 99, 99, 99, 99, 99
168 };
169
170 /*****************************************************************************/
171 /* \brief gZigZag */
172 /* */
173 /* Zigzag scan pattern */
174 /*****************************************************************************/
175 static const IMG_UINT8 gZigZag[] = {
176 0, 1, 8, 16, 9, 2, 3, 10,
177 17, 24, 32, 25, 18, 11, 4, 5,
178 12, 19, 26, 33, 40, 48, 41, 34,
179 27, 20, 13, 6, 7, 14, 21, 28,
180 35, 42, 49, 56, 57, 50, 43, 36,
181 29, 22, 15, 23, 30, 37, 44, 51,
182 58, 59, 52, 45, 38, 31, 39, 46,
183 53, 60, 61, 54, 47, 55, 62, 63
184 };
185
186 /*****************************************************************************/
187 /* \brief gMarkerDataLumaDc */
188 /* */
189 /* Contains the data that needs to be sent in the marker segment of an */
190 /* interchange format JPEG stream or an abbreviated format table */
191 /* specification data stream. */
192 /* Specifies the huffman table used for encoding the luminance DC */
193 /* coefficient differences. The table represents Table K.3 of */
194 /* IS0/IEC 10918-1:1994(E) */
195 /*****************************************************************************/
196 static const IMG_UINT8 gMarkerDataLumaDc[] = {
197 //TcTh Li
198 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00,
200 // Vi
201 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
202 };
203
204 /*****************************************************************************/
205 /* \brief gMarkerDataLumaAc */
206 /* */
207 /* Contains the data that needs to be sent in the marker segment of an */
208 /* interchange format JPEG stream or an abbreviated format table */
209 /* specification data stream. */
210 /* Specifies the huffman table used for encoding the luminance AC */
211 /* coefficients. The table represents Table K.5 of IS0/IEC 10918-1:1994(E) */
212 /*****************************************************************************/
213 static const IMG_UINT8 gMarkerDataLumaAc[] = {
214 // TcTh Li
215 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
216 0x04, 0x00, 0x00, 0x01, 0x7D,
217 // Vi
218 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
219 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
220 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
221 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
222 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
223 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
224 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75,
225 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
226 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3,
227 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
228 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
229 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
230 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4,
231 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
232 };
233
234 /*****************************************************************************/
235 /* \brief gMarkerDataChromaDc */
236 /* */
237 /* Contains the data that needs to be sent in the marker segment of an */
238 /* interchange format JPEG stream or an abbreviated format table */
239 /* specification data stream. */
240 /* Specifies the huffman table used for encoding the chrominance DC */
241 /* coefficient differences. The table represents Table K.4 of */
242 /* IS0/IEC 10918-1:1994(E) */
243 /*****************************************************************************/
244 static const IMG_UINT8 gMarkerDataChromaDc[] = {
245 // TcTh Li
246 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
247 0x00, 0x00, 0x00, 0x00, 0x00,
248
249 // Vi
250 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
251 };
252
253 /*****************************************************************************/
254 /* \brief gMarkerDataChromaAc */
255 /* */
256 /* Contains the data that needs to be sent in the marker segment of an */
257 /* interchange format JPEG stream or an abbreviated format table */
258 /* specification data stream. */
259 /* Specifies the huffman table used for encoding the chrominance AC */
260 /* coefficients. The table represents Table K.6 of IS0/IEC 10918-1:1994(E) */
261 /*****************************************************************************/
262 static const IMG_UINT8 gMarkerDataChromaAc[] = {
263 // TcTh
264 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
265 0x04, 0x00, 0x01, 0x02, 0x77,
266
267 // Vi
268 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
269 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
270 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1,
271 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
272 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
273 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
274 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
275 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
276 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
277 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
278 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
279 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
280 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
281 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
282 };
283
CustomizeQuantizationTables(unsigned char * luma_matrix,unsigned char * chroma_matrix,unsigned int ui32Quality)284 static int CustomizeQuantizationTables(unsigned char *luma_matrix,
285 unsigned char *chroma_matrix,
286 unsigned int ui32Quality)
287 {
288 unsigned int uc_qVal;
289 unsigned int uc_j;
290
291 if((NULL == luma_matrix) || (NULL == chroma_matrix) ||
292 (ui32Quality < 1) || (ui32Quality > 100))
293 return 1;
294
295 /* Compute luma quantization table */
296 ui32Quality = (ui32Quality<50) ? (5000/ui32Quality) : (200-ui32Quality*2);
297 for(uc_j=0; uc_j<QUANT_TABLE_SIZE_BYTES; ++uc_j) {
298 uc_qVal = (gQuantLuma[uc_j] * ui32Quality + 50) / 100;
299 uc_qVal = (uc_qVal>0xFF)? 0xFF:uc_qVal;
300 uc_qVal = (uc_qVal<1)? 1:uc_qVal;
301 luma_matrix[uc_j] = (unsigned char)uc_qVal;
302 }
303
304 /* Compute chroma quantization table */
305 for(uc_j=0; uc_j<QUANT_TABLE_SIZE_BYTES; ++uc_j) {
306 uc_qVal = (gQuantChroma[uc_j] * ui32Quality + 50) / 100;
307 uc_qVal = (uc_qVal>0xFF)? 0xFF:uc_qVal;
308 uc_qVal = (uc_qVal<1)? 1:uc_qVal;
309 chroma_matrix[uc_j] = (unsigned char)uc_qVal;
310 }
311
312 return 0;
313 }
314
SetDefaultQmatix(void * pMemInfoTableBlock)315 static void SetDefaultQmatix(void *pMemInfoTableBlock)
316 {
317 JPEG_MTX_QUANT_TABLE *pQTable = pMemInfoTableBlock;
318 memcpy(pQTable->aui8LumaQuantParams, gQuantLuma, QUANT_TABLE_SIZE_BYTES);
319 memcpy(pQTable->aui8ChromaQuantParams, gQuantChroma, QUANT_TABLE_SIZE_BYTES);
320 return;
321 }
322
323
IssueQmatix(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)324 static void IssueQmatix(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
325 {
326 int i;
327 context_ENC_p ctx = (context_ENC_p)pJPEGContext->ctx;
328
329 /* Dump MTX setup data for debug */
330 ASSERT(NULL != pJPEGContext->pMemInfoTableBlock);
331
332 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Issue Quantization Table data\n");
333 for (i=0; i<128; i+=8) {
334 if (0 == i) {
335 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Table 0:\n");
336 }
337 else if (64 == i) {
338 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Table 1:\n");
339 }
340 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%d %d %d %d %d %d %d %d\n",
341 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i),
342 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+1),
343 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+2),
344 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+3),
345 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+4),
346 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+5),
347 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+6),
348 *((unsigned char *)ctx->obj_context->tng_cmdbuf->jpeg_pic_params_p+i+7));
349 }
350
351 tng_cmdbuf_insert_command(ctx->obj_context,
352 0,
353 MTX_CMDID_SETQUANT,
354 0,
355 &(ctx->obj_context->tng_cmdbuf->jpeg_pic_params),
356 0);
357 }
358
InitializeJpegEncode(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)359 static void InitializeJpegEncode(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
360 {
361 context_ENC_p ctx = (context_ENC_p)pJPEGContext->ctx;
362 IMG_UINT16 ui16_width;
363 IMG_UINT16 ui16_height;
364 IMG_UINT32 ui32UpperLimit;
365
366 /*********************************************************************/
367 /* Determine the horizonal and the vertical sampling frequency of */
368 /* each of components in the image */
369 /*********************************************************************/
370
371 ui16_width = ctx->ui16Width;
372 ui16_height = ctx->ui16FrameHeight; //pTFrame->height isn't the real height of image, because vaCreateSurface has made it aligned with 32
373
374 switch (pJPEGContext->eFormat) {
375 case IMG_CODEC_PL12:
376 default:
377 pJPEGContext->MCUComponent[0].ui32WidthBlocks = 16;
378 pJPEGContext->MCUComponent[0].ui32HeightBlocks = 16;
379 pJPEGContext->MCUComponent[0].ui32XLimit = ui16_width;
380 pJPEGContext->MCUComponent[0].ui32YLimit = ui16_height;
381
382 pJPEGContext->MCUComponent[1].ui32WidthBlocks = 8;
383 pJPEGContext->MCUComponent[1].ui32HeightBlocks = 8;
384 pJPEGContext->MCUComponent[1].ui32XLimit = ui16_width >> 1;
385 pJPEGContext->MCUComponent[1].ui32YLimit = ui16_height >> 1;
386
387 pJPEGContext->MCUComponent[2].ui32WidthBlocks = 8;
388 pJPEGContext->MCUComponent[2].ui32HeightBlocks = 8;
389 pJPEGContext->MCUComponent[2].ui32XLimit = ui16_width >> 1;
390 pJPEGContext->MCUComponent[2].ui32YLimit = ui16_height >> 1;
391
392 break;
393 }
394
395 switch (ISCHROMAINTERLEAVED(pJPEGContext->eFormat)) {
396 case C_INTERLEAVE:
397 default:
398 // Chroma format is byte interleaved, as the engine runs using planar colour surfaces we need
399 // to fool the engine into offsetting by 16 instead of 8
400 pJPEGContext->MCUComponent[1].ui32WidthBlocks +=
401 pJPEGContext->MCUComponent[2].ui32WidthBlocks;
402 pJPEGContext->MCUComponent[1].ui32XLimit +=
403 pJPEGContext->MCUComponent[2].ui32XLimit;
404 pJPEGContext->MCUComponent[2].ui32XLimit =
405 pJPEGContext->MCUComponent[2].ui32YLimit =
406 pJPEGContext->MCUComponent[2].ui32WidthBlocks =
407 pJPEGContext->MCUComponent[2].ui32HeightBlocks = 0;
408 break;
409 }
410
411 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsX =
412 (pJPEGContext->MCUComponent[0].ui32XLimit +
413 (pJPEGContext->MCUComponent[0].ui32WidthBlocks - 1)) /
414 pJPEGContext->MCUComponent[0].ui32WidthBlocks;
415 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsY =
416 (pJPEGContext->MCUComponent[0].ui32YLimit +
417 (pJPEGContext->MCUComponent[0].ui32HeightBlocks - 1)) /
418 pJPEGContext->MCUComponent[0].ui32HeightBlocks;
419 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncode =
420 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsX *
421 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsY;
422
423 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of X MCUs: %d\n", pJPEGContext->sScan_Encode_Info.ui32NumberMCUsX);
424 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of Y MCUs: %d\n", pJPEGContext->sScan_Encode_Info.ui32NumberMCUsY);
425 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of total MCUs: %d\n", pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncode);
426
427
428 // Number of MCUs sent for a scan _must_ lie at the beginning of a line so that the chroma component can't violate the 16 byte DMA start alignment constraint
429 // (Actual memory alignment for final DMA will have width aligned to 64, so start of line will automatically meet the 16 byte alignment required by the DMA engine)
430 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan =
431 (pJPEGContext->sScan_Encode_Info.ui32NumberMCUsY + (pJPEGContext->NumCores - 1)) / pJPEGContext->NumCores;
432 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan *=
433 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsX;
434
435 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of MCUs per core: %d\n", pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan);
436
437
438 // Limit the scan size to maximum useable (due to it being used as the 16 bit field for Restart Intervals) = 0xFFFF MCUs
439 // In reality, worst case allocatable bytes is less than this, something around 0x159739C == 0x4b96 MCUs = 139 x 139 MCUS = 2224 * 2224 pixels, approx.
440 // We'll give this upper limit some margin for error, and limit our MCUsPerScan to 2000 * 2000 pixels = 125 * 125 MCUS = 0x3D09 MCUS = 0x116F322 bytes (1170 worst case per MCU)
441 // If more MCUs are required, then the image will be automatically encoded with multiple scans on the same pipes
442 ui32UpperLimit = PTG_JPEG_MAX_MCU_PER_SCAN / pJPEGContext->sScan_Encode_Info.ui32NumberMCUsX;
443 ui32UpperLimit *= pJPEGContext->sScan_Encode_Info.ui32NumberMCUsX;
444
445 if (pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan > ui32UpperLimit) {
446 // Set MCUs to encode per scan to equal maximum limit and then truncate to ensure it lies at the first MCU of a line (to satisfy the 64 byte requirement)
447 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan = ui32UpperLimit;
448 }
449
450 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of MCUs per scan: %d\n", pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan);
451
452 //Need to set up CB Output slicenumber to equal number of slices required to encode image
453 // Set current CB scan to maximum scan number (will count down as scans are output)
454 pJPEGContext->sScan_Encode_Info.ui16ScansInImage =
455 (pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncode +
456 (pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan - 1)) /
457 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan;
458
459 pJPEGContext->sScan_Encode_Info.ui8NumberOfCodedBuffers =
460 pJPEGContext->sScan_Encode_Info.ui16ScansInImage;
461
462 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Scans in image: %d\n", pJPEGContext->sScan_Encode_Info.ui16ScansInImage);
463 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of coded buffers: %d\n", pJPEGContext->sScan_Encode_Info.ui8NumberOfCodedBuffers);
464
465 return;
466 }
467
AssignCodedDataBuffers(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)468 static void AssignCodedDataBuffers(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
469 {
470 IMG_UINT8 ui8Loop;
471 pJPEGContext->ui32SizePerCodedBuffer =
472 (pJPEGContext->jpeg_coded_buf.ui32Size - PTG_JPEG_HEADER_MAX_SIZE) /
473 pJPEGContext->sScan_Encode_Info.ui8NumberOfCodedBuffers;
474 pJPEGContext->ui32SizePerCodedBuffer &= ~0xf;
475
476 memset((void *)pJPEGContext->sScan_Encode_Info.aBufferTable, 0x0,
477 sizeof(TOPAZHP_JPEG_BUFFER_INFO)*pJPEGContext->sScan_Encode_Info.ui8NumberOfCodedBuffers);
478
479 drv_debug_msg(VIDEO_DEBUG_GENERAL, "jpeg_coded_buf.pMemInfo: 0x%x\n", (unsigned int)(pJPEGContext->jpeg_coded_buf.pMemInfo));
480
481 for (ui8Loop = 0 ; ui8Loop < pJPEGContext->sScan_Encode_Info.ui8NumberOfCodedBuffers; ui8Loop++) {
482 //pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui32DataBufferSizeBytes = DATA_BUFFER_SIZE(pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan);
483 //pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui32DataBufferSizeBytes = (pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui32DataBufferSizeBytes+sizeof(BUFFER_HEADER)) + 3 & ~3;
484 pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui32DataBufferUsedBytes = 0;
485 pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].i8PipeNumber = 0; // Indicates buffer is idle
486 pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].ui16ScanNumber = 0; // Indicates buffer is idle
487
488 pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo = (void *)
489 ((IMG_UINT32)pJPEGContext->jpeg_coded_buf.pMemInfo + PTG_JPEG_HEADER_MAX_SIZE +
490 ui8Loop * pJPEGContext->ui32SizePerCodedBuffer);
491 drv_debug_msg(VIDEO_DEBUG_GENERAL, "aBufferTable[%d].pMemInfo: 0x%x\n", ui8Loop,
492 (unsigned int)(pJPEGContext->sScan_Encode_Info.aBufferTable[ui8Loop].pMemInfo));
493 }
494
495 return;
496 }
497
SetSetupInterface(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)498 static void SetSetupInterface(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
499 {
500 context_ENC_p ctx = (context_ENC_p)pJPEGContext->ctx;
501 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
502 context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
503
504 tng_cmdbuf_set_phys(pJPEGContext->pMTXWritebackMemory->apWritebackRegions, WB_FIFO_SIZE,
505 &(ctx->bufs_writeback), 0, ps_mem_size->writeback);
506 }
507
IssueSetupInterface(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)508 static void IssueSetupInterface(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
509 {
510 int i;
511 context_ENC_p ctx = (context_ENC_p)pJPEGContext->ctx;
512
513 ASSERT(NULL != pJPEGContext->pMTXSetup);
514 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Issue SetupInterface\n");
515
516 for (i = 0; i < WB_FIFO_SIZE; i++) {
517 drv_debug_msg(VIDEO_DEBUG_GENERAL, "apWritebackRegions[%d]: 0x%x\n", i,
518 pJPEGContext->pMTXWritebackMemory->apWritebackRegions[i]);
519 }
520
521 tng_cmdbuf_insert_command(ctx->obj_context,
522 0,
523 MTX_CMDID_SETUP_INTERFACE,
524 0,
525 &(ctx->obj_context->tng_cmdbuf->jpeg_header_interface_mem),
526 0);
527 }
528
SetMTXSetup(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,object_surface_p pTFrame)529 static IMG_ERRORCODE SetMTXSetup(
530 TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext,
531 object_surface_p pTFrame)
532 {
533 IMG_UINT32 srf_buf_offset;
534 context_ENC_p ctx = (context_ENC_p)pJPEGContext->ctx;
535 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
536 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
537 context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
538
539 pJPEGContext->pMTXSetup->ui32ComponentsInScan = MTX_MAX_COMPONENTS;
540
541 switch (pJPEGContext->eFormat) {
542 case IMG_CODEC_PL12:
543 if (pTFrame->psb_surface->stride % 64) {
544 drv_debug_msg(VIDEO_DEBUG_ERROR, "Surface stride isn't aligned to 64 bytes as HW requires: %u!\n",
545 pTFrame->psb_surface->stride);
546 return IMG_ERR_INVALID_CONTEXT;
547 }
548 pJPEGContext->pMTXSetup->ComponentPlane[0].ui32Stride = pTFrame->psb_surface->stride;
549 pJPEGContext->pMTXSetup->ComponentPlane[1].ui32Stride = pTFrame->psb_surface->stride;
550 pJPEGContext->pMTXSetup->ComponentPlane[2].ui32Stride = pTFrame->psb_surface->stride;
551
552 pJPEGContext->pMTXSetup->ComponentPlane[0].ui32Height = pJPEGContext->MCUComponent[0].ui32YLimit;
553 pJPEGContext->pMTXSetup->ComponentPlane[1].ui32Height = pJPEGContext->MCUComponent[0].ui32YLimit / 2;
554 pJPEGContext->pMTXSetup->ComponentPlane[2].ui32Height = pJPEGContext->MCUComponent[0].ui32YLimit / 2;
555 break;
556 default:
557 drv_debug_msg(VIDEO_DEBUG_ERROR, "Not supported FOURCC: %x!\n", pJPEGContext->eFormat);
558 return IMG_ERR_INVALID_CONTEXT;
559 }
560
561 srf_buf_offset = pTFrame->psb_surface->buf.buffer_ofs;
562 RELOC_JPEG_PIC_PARAMS_PTG(&pJPEGContext->pMTXSetup->ComponentPlane[0].ui32PhysAddr, srf_buf_offset,
563 &pTFrame->psb_surface->buf);
564 switch (pJPEGContext->eFormat) {
565 case IMG_CODEC_PL12:
566 RELOC_JPEG_PIC_PARAMS_PTG(&pJPEGContext->pMTXSetup->ComponentPlane[1].ui32PhysAddr,
567 srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height,
568 &pTFrame->psb_surface->buf);
569 //Byte interleaved surface, so need to force chroma to use single surface by fooling it into
570 //thinking it's dealing with standard 8x8 planaerblocks
571 RELOC_JPEG_PIC_PARAMS_PTG(&pJPEGContext->pMTXSetup->ComponentPlane[2].ui32PhysAddr,
572 srf_buf_offset + pTFrame->psb_surface->stride * pTFrame->height + 8,
573 &pTFrame->psb_surface->buf);
574 break;
575 default:
576 drv_debug_msg(VIDEO_DEBUG_ERROR, "Not supported FOURCC: %x!\n", pJPEGContext->eFormat);
577 return IMG_ERR_INVALID_CONTEXT;
578 }
579
580 memcpy((void *)pJPEGContext->pMTXSetup->MCUComponent,
581 (void *)pJPEGContext->MCUComponent,
582 sizeof(pJPEGContext->MCUComponent));
583
584 pJPEGContext->pMTXSetup->ui32TableA = 0;
585 pJPEGContext->pMTXSetup->ui16DataInterleaveStatus = ISCHROMAINTERLEAVED(pJPEGContext->eFormat);
586 pJPEGContext->pMTXSetup->ui16MaxPipes = (IMG_UINT16)pJPEGContext->NumCores;
587
588 return IMG_ERR_OK;
589 }
590
IssueMTXSetup(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)591 static void IssueMTXSetup(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
592 {
593 uint32_t i;
594 context_ENC_p ctx = (context_ENC_p)pJPEGContext->ctx;
595
596 /* Dump MTX setup data for debug */
597 ASSERT(NULL != pJPEGContext->pMTXSetup);
598 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Issue MTX setup data\n");
599
600 for (i = 0; i < pJPEGContext->pMTXSetup->ui32ComponentsInScan; i++) {
601 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ComponentPlane[%d]: 0x%x, %d, %d\n", i,
602 pJPEGContext->pMTXSetup->ComponentPlane[i].ui32PhysAddr,
603 pJPEGContext->pMTXSetup->ComponentPlane[i].ui32Stride,
604 pJPEGContext->pMTXSetup->ComponentPlane[i].ui32Height);
605 drv_debug_msg(VIDEO_DEBUG_GENERAL, "MCUComponent[%d]: %d, %d, %d, %d\n", i,
606 pJPEGContext->pMTXSetup->MCUComponent[i].ui32WidthBlocks,
607 pJPEGContext->pMTXSetup->MCUComponent[i].ui32HeightBlocks,
608 pJPEGContext->pMTXSetup->MCUComponent[i].ui32XLimit,
609 pJPEGContext->pMTXSetup->MCUComponent[i].ui32YLimit);
610 }
611
612 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32ComponentsInScan: %d\n", pJPEGContext->pMTXSetup->ui32ComponentsInScan);
613 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32TableA: %d\n", pJPEGContext->pMTXSetup->ui32TableA);
614 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui16DataInterleaveStatus: %d\n", pJPEGContext->pMTXSetup->ui16DataInterleaveStatus);
615 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui16MaxPipes: %d\n", pJPEGContext->pMTXSetup->ui16MaxPipes);
616
617 tng_cmdbuf_insert_command(ctx->obj_context,
618 0,
619 MTX_CMDID_SETUP,
620 0,
621 &(ctx->obj_context->tng_cmdbuf->jpeg_header_mem),
622 0);
623
624 return;
625 }
626
627
628
fPutBitsToBuffer(STREAMTYPEW * BitStream,IMG_UINT8 NoOfBytes,IMG_UINT32 ActualBits)629 static void fPutBitsToBuffer(STREAMTYPEW *BitStream, IMG_UINT8 NoOfBytes, IMG_UINT32 ActualBits)
630 {
631 IMG_UINT8 ui8Lp;
632 IMG_UINT8 *pui8S;
633
634 pui8S = (IMG_UINT8 *)BitStream->Buffer;
635 pui8S += BitStream->Offset;
636
637 for (ui8Lp = NoOfBytes; ui8Lp > 0; ui8Lp--)
638 *(pui8S++) = ((IMG_UINT8 *) &ActualBits)[ui8Lp-1];
639
640 BitStream->Offset += NoOfBytes;
641 }
642
EncodeMarkerSegment(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_UINT8 * puc_stream_buff,IMG_BOOL bIncludeHuffmanTables)643 static IMG_UINT32 EncodeMarkerSegment(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext,
644 IMG_UINT8 *puc_stream_buff, IMG_BOOL bIncludeHuffmanTables)
645 {
646 STREAMTYPEW s_streamW;
647 IMG_UINT8 uc_i;
648
649 s_streamW.Offset = 0;
650 s_streamW.Buffer = puc_stream_buff;
651
652 /* Writing the start of image marker */
653 fPutBitsToBuffer(&s_streamW, 2, START_OF_IMAGE);
654
655 /* Writing the quantization table for luminance into the stream */
656 fPutBitsToBuffer(&s_streamW, 2, DQT_MARKER);
657
658 fPutBitsToBuffer(&s_streamW, 3, LQPQ << 4); // 20 bits = LQPQ, 4 bits = 0 (Destination identifier for the luminance quantizer tables)
659
660 IMG_ASSERT(PELS_IN_BLOCK <= QUANT_TABLE_SIZE_BYTES);
661 for (uc_i = 0; uc_i < PELS_IN_BLOCK; uc_i++) {
662 // Write zigzag ordered luma quantization values to our JPEG header
663 fPutBitsToBuffer(&s_streamW, 1, pJPEGContext->psTablesBlock->aui8LumaQuantParams[gZigZag[uc_i]]);
664 }
665
666 /* Writing the quantization table for chrominance into the stream */
667 fPutBitsToBuffer(&s_streamW, 2, DQT_MARKER);
668
669 fPutBitsToBuffer(&s_streamW, 3, (LQPQ << 4) | 1); // 20 bits = LQPQ, 4 bits = 1 (Destination identifier for the chrominance quantizer tables)
670
671 for (uc_i = 0; uc_i < PELS_IN_BLOCK; uc_i++) {
672 // Write zigzag ordered chroma quantization values to our JPEG header
673 fPutBitsToBuffer(&s_streamW, 1, pJPEGContext->psTablesBlock->aui8ChromaQuantParams[gZigZag[uc_i]]);
674 }
675
676
677
678
679 if (bIncludeHuffmanTables) {
680 /* Writing the huffman tables for luminance dc coeffs */
681 /* Write the DHT Marker */
682 fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
683 fPutBitsToBuffer(&s_streamW, 2, LH_DC);
684 for (uc_i = 0; uc_i < LH_DC - 2; uc_i++) {
685 fPutBitsToBuffer(&s_streamW, 1, gMarkerDataLumaDc[uc_i]);
686 }
687 /* Writing the huffman tables for luminance ac coeffs */
688 /* Write the DHT Marker */
689 fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
690 fPutBitsToBuffer(&s_streamW, 2, LH_AC);
691 for (uc_i = 0; uc_i < LH_AC - 2; uc_i++) {
692 fPutBitsToBuffer(&s_streamW, 1, gMarkerDataLumaAc[uc_i]);
693 }
694 /* Writing the huffman tables for chrominance dc coeffs */
695 fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
696 fPutBitsToBuffer(&s_streamW, 2, LH_DC);
697 for (uc_i = 0; uc_i < LH_DC - 2; uc_i++) {
698 fPutBitsToBuffer(&s_streamW, 1, gMarkerDataChromaDc[uc_i]);
699 }
700 /* Writing the huffman tables for luminance ac coeffs */
701 /* Write the DHT Marker */
702 fPutBitsToBuffer(&s_streamW, 2, DHT_MARKER);
703 fPutBitsToBuffer(&s_streamW, 2, LH_AC);
704 for (uc_i = 0; uc_i < LH_AC - 2; uc_i++) {
705 fPutBitsToBuffer(&s_streamW, 1, gMarkerDataChromaAc[uc_i]);
706 }
707 }
708
709 // Activate Restart markers
710 if (pJPEGContext->sScan_Encode_Info.ui16CScan > 1) {
711 // Only use restart intervals if we need them (ie. multiple Scan encode and/or parallel CB encode)
712 fPutBitsToBuffer(&s_streamW, 2, 0xFFDD); //Marker header
713 fPutBitsToBuffer(&s_streamW, 2, 4); // Byte size of marker (header not included)
714 fPutBitsToBuffer(&s_streamW, 2, pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan); // Restart Interval (same as MCUs per buffer)
715 }
716
717 return s_streamW.Offset;
718 }
719
EncodeFrameHeader(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_UINT8 * puc_stream_buff)720 static IMG_UINT32 EncodeFrameHeader(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext,
721 IMG_UINT8 *puc_stream_buff)
722 {
723 STREAMTYPEW ps_streamW;
724 IMG_UINT8 uc_num_comp_in_img;
725
726 uc_num_comp_in_img = pJPEGContext->pMTXSetup->ui32ComponentsInScan;
727
728 ps_streamW.Offset = 0;
729 ps_streamW.Buffer = puc_stream_buff;
730
731
732 //if(ps_jpeg_params->uc_isAbbreviated != 0)
733 // fPutBitsToBuffer(&ps_streamW, 2, START_OF_IMAGE);
734
735 /* Writing the frame header */
736 fPutBitsToBuffer(&ps_streamW, 2, SOF_BASELINE_DCT);
737 /* Frame header length */
738 fPutBitsToBuffer(&ps_streamW, 2, 8 + 3 * uc_num_comp_in_img);
739 /* Precision */
740 fPutBitsToBuffer(&ps_streamW, 1, 8);
741 /* Height : sample lines */
742 fPutBitsToBuffer(&ps_streamW, 2, pJPEGContext->ui32OutputHeight);
743 /* Width : samples per line */
744 fPutBitsToBuffer(&ps_streamW, 2, pJPEGContext->ui32OutputWidth);
745 /* Number of image components */
746 fPutBitsToBuffer(&ps_streamW, 1, uc_num_comp_in_img);
747
748
749 //Chroma Details
750 if (pJPEGContext->pMTXSetup->ui16DataInterleaveStatus < C_INTERLEAVE) {
751 //Luma Details
752 /* Component identifier */
753 fPutBitsToBuffer(&ps_streamW, 1, 1); //CompId 0 = 1, 1 = 2, 2 = 3
754 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks >> 3) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks >> 3));
755 fPutBitsToBuffer(&ps_streamW, 1, 0); // 0 = Luma(0), 1,2 = Chroma(1)
756
757 //Chroma planar
758 fPutBitsToBuffer(&ps_streamW, 1, 2); //CompId 0 = 1, 1 = 2, 2 = 3
759 /* 4 bit Horizontal and 4 bit vertical sampling factors */
760 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[1].ui32WidthBlocks >> 3) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[1].ui32HeightBlocks >> 3));
761 fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
762 fPutBitsToBuffer(&ps_streamW, 1, 3); //CompId 0 = 1, 1 = 2, 2 = 3
763 /* 4 bit Horizontal and 4 bit vertical sampling factors */
764 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[2].ui32WidthBlocks >> 3) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[2].ui32HeightBlocks >> 3));
765 fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
766 } else if (pJPEGContext->pMTXSetup->ui16DataInterleaveStatus == C_INTERLEAVE) {
767 //Luma Details
768 /* Component identifier */
769 fPutBitsToBuffer(&ps_streamW, 1, 1); //CompId 0 = 1, 1 = 2, 2 = 3
770 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks >> 3) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks >> 3));
771 fPutBitsToBuffer(&ps_streamW, 1, 0); // 0 = Luma(0), 1,2 = Chroma(1)
772
773 // Chroma Interleaved
774 fPutBitsToBuffer(&ps_streamW, 1, 2); //CompId 0 = 1, 1 = 2, 2 = 3
775 /* 4 bit Horizontal and 4 bit vertical sampling factors */
776 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[1].ui32WidthBlocks >> 4) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[1].ui32HeightBlocks >> 3));
777 fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
778
779 fPutBitsToBuffer(&ps_streamW, 1, 3); //CompId 0 = 1, 1 = 2, 2 = 3
780 /* 4 bit Horizontal and 4 bit vertical sampling factors */
781 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[1].ui32WidthBlocks >> 4) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[1].ui32HeightBlocks >> 3));
782 fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
783 } else {
784 //Luma Details
785 /* Component identifier */
786 fPutBitsToBuffer(&ps_streamW, 1, 1); //CompId 0 = 1, 1 = 2, 2 = 3
787 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks >> 4) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks >> 3));
788 fPutBitsToBuffer(&ps_streamW, 1, 0); // 0 = Luma(0), 1,2 = Chroma(1)
789
790 //Chroma YUYV - Special case
791 fPutBitsToBuffer(&ps_streamW, 1, 2); //CompId 0 = 1, 1 = 2, 2 = 3
792 /* 4 bit Horizontal and 4 bit vertical sampling factors */
793 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks >> 5) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks >> 3));
794 fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
795 fPutBitsToBuffer(&ps_streamW, 1, 3); //CompId 0 = 1, 1 = 2, 2 = 3
796 /* 4 bit Horizontal and 4 bit vertical sampling factors */
797 fPutBitsToBuffer(&ps_streamW, 1, ((pJPEGContext->pMTXSetup->MCUComponent[0].ui32WidthBlocks >> 5) << 4) | (pJPEGContext->pMTXSetup->MCUComponent[0].ui32HeightBlocks >> 3));
798 fPutBitsToBuffer(&ps_streamW, 1, 1); // 0 = Luma(0), 1,2 = Chroma(1)
799 }
800
801
802 //Use if you want start of scan (image data) to align to 32
803 //fPutBitsToBuffer(&ps_streamW, 1, 0xFF);
804
805 return ps_streamW.Offset;
806 }
807
JPGEncodeMarker(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_UINT8 * pui8BitStreamBuffer,IMG_UINT32 * pui32BytesWritten,IMG_BOOL bIncludeHuffmanTables)808 static IMG_UINT32 JPGEncodeMarker(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext ,
809 IMG_UINT8* pui8BitStreamBuffer ,
810 IMG_UINT32 *pui32BytesWritten, IMG_BOOL bIncludeHuffmanTables)
811 {
812 #ifdef JPEG_VERBOSE
813 drv_debug_msg(VIDEO_DEBUG_GENERAL, "PVRJPGEncodeMarker");
814 #endif
815
816
817 *pui32BytesWritten += EncodeMarkerSegment(pJPEGContext, pui8BitStreamBuffer + *pui32BytesWritten, bIncludeHuffmanTables);
818
819 return 0;
820 }
821
JPGEncodeHeader(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_UINT8 * pui8BitStreamBuffer,IMG_UINT32 * pui32BytesWritten)822 static IMG_UINT32 JPGEncodeHeader(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext,
823 IMG_UINT8* pui8BitStreamBuffer ,
824 IMG_UINT32* pui32BytesWritten)
825 {
826 #ifdef JPEG_VERBOSE
827 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPGEncodeHeader");
828 #endif
829
830 *pui32BytesWritten += EncodeFrameHeader(pJPEGContext, pui8BitStreamBuffer + *pui32BytesWritten);
831
832 return 0;
833 }
834
JPGEncodeSOSHeader(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_UINT8 * pui8BitStreamBuffer,IMG_UINT32 * pui32BytesWritten)835 static IMG_UINT32 JPGEncodeSOSHeader(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext,
836 IMG_UINT8* pui8BitStreamBuffer ,
837 IMG_UINT32* pui32BytesWritten)
838 {
839 IMG_UINT8 uc_comp_id, ui8Comp;
840 STREAMTYPEW s_streamW;
841
842 s_streamW.Offset = 0;
843 s_streamW.Buffer = pui8BitStreamBuffer + *pui32BytesWritten;
844
845 /* Start of scan */
846 fPutBitsToBuffer(&s_streamW, 2, START_OF_SCAN);
847 /* Scan header length */
848 fPutBitsToBuffer(&s_streamW, 2, 6 + (pJPEGContext->pMTXSetup->ui32ComponentsInScan << 1));
849 /* Number of image components in scan */
850 fPutBitsToBuffer(&s_streamW, 1, pJPEGContext->pMTXSetup->ui32ComponentsInScan);
851 for (ui8Comp = 0; ui8Comp < pJPEGContext->pMTXSetup->ui32ComponentsInScan; ui8Comp++) {
852 uc_comp_id = ui8Comp + 1;
853
854 /* Scan component selector */
855 fPutBitsToBuffer(&s_streamW, 1, uc_comp_id);
856
857 /*4 Bits Dc entropy coding table destination selector */
858 /*4 Bits Ac entropy coding table destination selector */
859 fPutBitsToBuffer(&s_streamW, 1, ((ui8Comp != 0 ? 1 : 0) << 4) | (ui8Comp != 0 ? 1 : 0)); // Huffman table refs = 0 Luma 1 Chroma
860 }
861
862 /* Start of spectral or predictor selection */
863 fPutBitsToBuffer(&s_streamW, 1, 0);
864 /* End of spectral selection */
865 fPutBitsToBuffer(&s_streamW, 1, 63);
866 /*4 Bits Successive approximation bit position high (0)*/
867 /*4 Bits Successive approximation bit position low or point transform (0)*/
868 fPutBitsToBuffer(&s_streamW, 1, 0);
869
870 *pui32BytesWritten += s_streamW.Offset;
871
872 return 0;
873 }
874
InitializeScanCounter(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext)875 static void InitializeScanCounter(TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext)
876 {
877 pJPEGContext->sScan_Encode_Info.ui16SScan =
878 pJPEGContext->sScan_Encode_Info.ui16CScan =
879 pJPEGContext->sScan_Encode_Info.ui16ScansInImage;
880 }
881
PrepareHeader(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_CODED_BUFFER * pCBuffer,IMG_UINT32 ui32StartOffset,IMG_BOOL bIncludeHuffmanTables)882 static IMG_ERRORCODE PrepareHeader(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext, IMG_CODED_BUFFER *pCBuffer, IMG_UINT32 ui32StartOffset, IMG_BOOL bIncludeHuffmanTables)
883 {
884 IMG_ERRORCODE rc;
885 IMG_UINT8 *ui8OutputBuffer;
886
887 //Locate our JPEG Coded buffer
888 ui8OutputBuffer = (IMG_UINT8 *)pCBuffer->pMemInfo;
889
890 pCBuffer->ui32BytesWritten = ui32StartOffset;
891 *((IMG_UINT32*)ui8OutputBuffer + pCBuffer->ui32BytesWritten) = 0;
892
893 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Before writing headers, ui32BytesWritten: %d\n", pCBuffer->ui32BytesWritten);
894
895 // JPGEncodeMarker - Currently misses out the APP0 header
896 rc = JPGEncodeMarker(pJPEGContext, (IMG_UINT8 *) ui8OutputBuffer, &pCBuffer->ui32BytesWritten, bIncludeHuffmanTables);
897 if (rc) return rc;
898 drv_debug_msg(VIDEO_DEBUG_GENERAL, "After JPGEncodeMarker, ui32BytesWritten: %d\n", pCBuffer->ui32BytesWritten);
899
900 rc = JPGEncodeHeader(pJPEGContext , (IMG_UINT8 *) ui8OutputBuffer , &pCBuffer->ui32BytesWritten);
901 if (rc) return rc;
902 drv_debug_msg(VIDEO_DEBUG_GENERAL, "After JPGEncodeHeader, ui32BytesWritten: %d\n", pCBuffer->ui32BytesWritten);
903
904 rc = JPGEncodeSOSHeader(pJPEGContext, (IMG_UINT8 *) ui8OutputBuffer, &pCBuffer->ui32BytesWritten);
905 if (rc) return rc;
906 drv_debug_msg(VIDEO_DEBUG_GENERAL, "After JPGEncodeSOSHeader, ui32BytesWritten: %d\n", pCBuffer->ui32BytesWritten);
907
908 return IMG_ERR_OK;
909 }
910
IssueBufferToHW(TOPAZHP_JPEG_ENCODER_CONTEXT * pJPEGContext,IMG_UINT16 ui16BCnt,IMG_INT8 i8PipeNumber,IMG_UINT32 ui32NoMCUsToEncode)911 static IMG_ERRORCODE IssueBufferToHW(
912 TOPAZHP_JPEG_ENCODER_CONTEXT *pJPEGContext,
913 IMG_UINT16 ui16BCnt,
914 IMG_INT8 i8PipeNumber,
915 IMG_UINT32 ui32NoMCUsToEncode)
916 {
917 MTX_ISSUE_BUFFERS *psBufferCmd;
918 context_ENC_p ctx = (context_ENC_p)(pJPEGContext->ctx);
919 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
920
921 pJPEGContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui32DataBufferUsedBytes = ((BUFFER_HEADER*)(pJPEGContext->sScan_Encode_Info.aBufferTable[ui16BCnt].pMemInfo))->ui32BytesUsed = -1; // Won't be necessary with SC Peek commands enabled
922
923 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Submit Scan %d which contains %d MCU in Buffer %d to MTX %d\n",
924 pJPEGContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui16ScanNumber,
925 ui32NoMCUsToEncode, ui16BCnt, i8PipeNumber);
926
927 // Issue to MTX ////////////////////////////
928
929 psBufferCmd = (MTX_ISSUE_BUFFERS *)(pJPEGContext->sScan_Encode_Info.aBufferTable[ui16BCnt].pMemInfo);
930 ASSERT(psBufferCmd);
931
932 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui16ScansInImage: %d\n", pJPEGContext->sScan_Encode_Info.ui16ScansInImage);
933 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui16ScanNumber: %d\n", pJPEGContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui16ScanNumber);
934 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32NumberMCUsToEncodePerScan: %d\n", pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan);
935
936 psBufferCmd->ui32MCUCntAndResetFlag = (ui32NoMCUsToEncode << 1) | 0x1;
937
938 psBufferCmd->ui32MCUPositionOfScanAndPipeNo =
939 (((pJPEGContext->sScan_Encode_Info.ui16ScansInImage -
940 pJPEGContext->sScan_Encode_Info.aBufferTable[ui16BCnt].ui16ScanNumber) *
941 pJPEGContext->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan)<<2)&(~2);
942
943 ASSERT(0 == i8PipeNumber);
944 if (i8PipeNumber <= 3)
945 psBufferCmd->ui32MCUPositionOfScanAndPipeNo |= i8PipeNumber;
946
947 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32MCUPositionOfScanAndPipeNo: 0x%x\n", psBufferCmd->ui32MCUPositionOfScanAndPipeNo);
948 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32MCUCntAndResetFlag: 0x%x\n", psBufferCmd->ui32MCUCntAndResetFlag);
949
950 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psBufferCmd: 0x%x\n", (unsigned int)(psBufferCmd));
951 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Command Data: 0x%x\n", (unsigned int)(PTG_JPEG_HEADER_MAX_SIZE + ui16BCnt * pJPEGContext->ui32SizePerCodedBuffer));
952
953 // Issue buffers
954 tng_cmdbuf_insert_command(ctx->obj_context,
955 0,
956 MTX_CMDID_ISSUEBUFF,
957 0,
958 ps_buf->coded_buf->psb_buffer,
959 PTG_JPEG_HEADER_MAX_SIZE + ui16BCnt * pJPEGContext->ui32SizePerCodedBuffer);
960
961 return IMG_ERR_OK;
962 }
963
tng_jpeg_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib * attrib_list,int num_attribs)964 static void tng_jpeg_QueryConfigAttributes(
965 VAProfile __maybe_unused profile,
966 VAEntrypoint __maybe_unused entrypoint,
967 VAConfigAttrib *attrib_list,
968 int num_attribs)
969 {
970 int i;
971
972 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_QueryConfigAttributes\n");
973
974 /* Return supported attributes */
975 for (i = 0; i < num_attribs; i++) {
976 switch (attrib_list[i].type) {
977 case VAConfigAttribRTFormat:
978 /* Already handled in psb_GetConfigAttributes */
979 break;
980 case VAConfigAttribEncJPEG:
981 /* The below JPEG ENC capabilities are fixed by TopazHP and not changable. */
982 {
983 VAConfigAttribValEncJPEG* ptr = (VAConfigAttribValEncJPEG *)&(attrib_list[i].value);
984 (ptr->bits).arithmatic_coding_mode = 0; /* Unsupported */
985 (ptr->bits).progressive_dct_mode = 0; /* Unsupported */
986 (ptr->bits).non_interleaved_mode = 1; /* Supported */
987 (ptr->bits).differential_mode = 0; /* Unsupported */
988 (ptr->bits).max_num_components = MTX_MAX_COMPONENTS; /* Only 3 is supported */
989 (ptr->bits).max_num_scans = PTG_JPEG_MAX_SCAN_NUM;
990 (ptr->bits).max_num_huffman_tables = 4; /* Only 4 is supported */
991 (ptr->bits).max_num_huffman_tables = 2; /* Only 2 is supported */
992 }
993 break;
994 case VAConfigAttribMaxPictureWidth:
995 case VAConfigAttribMaxPictureHeight:
996 /* No pure limitation on an image's width or height seperately,
997 as long as the image's MCUs need less than max_num_scans rounds of encoding
998 and a surface of that source size is allocatable. */
999 attrib_list[i].value = 0; /* No pure limitation */
1000 break;
1001 default:
1002 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1003 break;
1004 }
1005 }
1006
1007 return;
1008 }
1009
1010
tng_jpeg_ValidateConfig(object_config_p obj_config)1011 static VAStatus tng_jpeg_ValidateConfig(
1012 object_config_p obj_config)
1013 {
1014 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_ValidateConfig\n");
1015 int i;
1016 /* Check all attributes */
1017 for (i = 0; i < obj_config->attrib_count; i++) {
1018 switch (obj_config->attrib_list[i].type) {
1019 case VAConfigAttribRTFormat:
1020 /* Ignore */
1021 break;
1022 case VAConfigAttribRateControl:
1023 break;
1024 default:
1025 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1026 }
1027 }
1028
1029 return VA_STATUS_SUCCESS;
1030 }
1031
tng_jpeg_CreateContext(object_context_p obj_context,object_config_p obj_config)1032 static VAStatus tng_jpeg_CreateContext(
1033 object_context_p obj_context,
1034 object_config_p obj_config)
1035 {
1036 int i;
1037 VAStatus vaStatus = VA_STATUS_SUCCESS;
1038 context_ENC_p ctx;
1039 TOPAZHP_JPEG_ENCODER_CONTEXT *jpeg_ctx_p;
1040
1041 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_CreateContext\n");
1042
1043 vaStatus = tng_CreateContext(obj_context, obj_config, 1);
1044 if (VA_STATUS_SUCCESS != vaStatus)
1045 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1046
1047 ctx = (context_ENC_p) obj_context->format_data;
1048 ctx->eCodec = IMG_CODEC_JPEG;
1049
1050 ASSERT(0 == (ctx->ui16Width % 2));
1051 ASSERT(0 == (ctx->ui16FrameHeight % 2));
1052
1053 for (i = 0; i < obj_config->attrib_count; i++) {
1054 if (VAConfigAttribRTFormat == obj_config->attrib_list[i].type) {
1055 switch (obj_config->attrib_list[i].value) {
1056 case VA_RT_FORMAT_YUV420:
1057 ctx->eFormat = IMG_CODEC_PL12;
1058 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG encoding: NV12 format chose.\n");
1059 break;
1060 default:
1061 drv_debug_msg(VIDEO_DEBUG_ERROR, "JPEG encoding: unsupported YUV format and force it to be NV12!\n");
1062 ctx->eFormat = IMG_CODEC_PL12;
1063 break;
1064 }
1065 break;
1066 }
1067 }
1068
1069 ctx->jpeg_ctx = (TOPAZHP_JPEG_ENCODER_CONTEXT *)calloc(1, sizeof(TOPAZHP_JPEG_ENCODER_CONTEXT));
1070 if (NULL == ctx->jpeg_ctx)
1071 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1072 jpeg_ctx_p = ctx->jpeg_ctx;
1073 jpeg_ctx_p->ctx = ctx;
1074
1075 memset((void *)jpeg_ctx_p, 0x0, sizeof(jpeg_ctx_p));
1076
1077 jpeg_ctx_p->NumCores = TOPAZHP_PIPE_NUM;
1078 jpeg_ctx_p->eFormat = ctx->eFormat;
1079 jpeg_ctx_p->ui32OutputWidth = ctx->ui16Width;
1080 jpeg_ctx_p->ui32OutputHeight = ctx->ui16FrameHeight;
1081
1082 InitializeJpegEncode(jpeg_ctx_p);
1083
1084 if ((jpeg_ctx_p->sScan_Encode_Info.ui16ScansInImage < 1) ||
1085 (jpeg_ctx_p->sScan_Encode_Info.ui16ScansInImage > PTG_JPEG_MAX_SCAN_NUM)) {
1086 drv_debug_msg(VIDEO_DEBUG_ERROR, "JPEG MCU scanning number(%d) is wrong!\n", jpeg_ctx_p->sScan_Encode_Info.ui16ScansInImage);
1087 free(ctx->jpeg_ctx);
1088 ctx->jpeg_ctx = NULL;
1089 return VA_STATUS_ERROR_UNKNOWN;
1090 }
1091
1092 /*Allocate coded buffers' descripters */
1093 jpeg_ctx_p->sScan_Encode_Info.aBufferTable = (TOPAZHP_JPEG_BUFFER_INFO *)calloc(1, (jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers) * (sizeof(TOPAZHP_JPEG_BUFFER_INFO)));
1094 if (NULL == jpeg_ctx_p->sScan_Encode_Info.aBufferTable)
1095 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1096
1097 return vaStatus;
1098 }
1099
1100
tng_jpeg_DestroyContext(object_context_p obj_context)1101 static void tng_jpeg_DestroyContext(
1102 object_context_p obj_context)
1103 {
1104 context_ENC_p ctx;
1105
1106 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_DestroyPicture\n");
1107
1108 ctx = (context_ENC_p)(obj_context->format_data);
1109
1110 if (ctx->jpeg_ctx) {
1111 if (ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable) {
1112 free(ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable);
1113 ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable = NULL;
1114 }
1115
1116 free(ctx->jpeg_ctx);
1117 }
1118
1119 tng_DestroyContext(obj_context, 1);
1120 }
1121
tng__cmdbuf_lowpower(context_ENC_p ctx)1122 static VAStatus tng__cmdbuf_lowpower(context_ENC_p ctx)
1123 {
1124 VAStatus vaStatus = VA_STATUS_SUCCESS;
1125 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
1126 psb_driver_data_p driver_data = ctx->obj_context->driver_data;
1127
1128 *cmdbuf->cmd_idx++ =
1129 ((MTX_CMDID_SW_LEAVE_LOWPOWER & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
1130 ((ctx->ui32RawFrameCount & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
1131 (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
1132
1133 tng_cmdbuf_insert_command_param(ctx->eCodec);
1134
1135 return vaStatus;
1136 }
1137
tng_jpeg_BeginPicture(object_context_p obj_context)1138 static VAStatus tng_jpeg_BeginPicture(
1139 object_context_p obj_context)
1140 {
1141 VAStatus vaStatus = VA_STATUS_SUCCESS;
1142 int ret;
1143 tng_cmdbuf_p cmdbuf;
1144
1145 context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
1146 TOPAZHP_JPEG_ENCODER_CONTEXT *jpeg_ctx_p = ctx->jpeg_ctx;
1147 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
1148 psb_driver_data_p driver_data = ctx->obj_context->driver_data;
1149
1150 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_BeginPicture: Frame %d\n", ctx->obj_context->frame_count);
1151
1152
1153 /* Get the current surface */
1154 ps_buf->src_surface = ctx->obj_context->current_render_target;
1155
1156
1157 /* Initialize the command buffer */
1158 ret = tng_context_get_next_cmdbuf(ctx->obj_context);
1159 if (ret) {
1160 drv_debug_msg(VIDEO_DEBUG_ERROR, "get next cmdbuf fail\n");
1161 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1162 return vaStatus;
1163 }
1164 cmdbuf = ctx->obj_context->tng_cmdbuf;
1165
1166
1167 //For the first picture of a set to be encoded, need to ask kernel to perpare JPEG encoding
1168 if (ctx->obj_context->frame_count == 0) { /* first picture */
1169
1170 *cmdbuf->cmd_idx++ = ((MTX_CMDID_SW_NEW_CODEC & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
1171 ((ctx->eCodec) << MTX_CMDWORD_CORE_SHIFT) |
1172 (((driver_data->drm_context & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
1173 tng_cmdbuf_insert_command_param((ctx->ui16Width << 16) | ctx->ui16FrameHeight);
1174 }
1175
1176
1177 /* Map MTX setup buffer */
1178 vaStatus = psb_buffer_map(&cmdbuf->jpeg_header_mem, (unsigned char **)&cmdbuf->jpeg_header_mem_p);
1179 if (vaStatus) {
1180 drv_debug_msg(VIDEO_DEBUG_ERROR, "Fail to map MTX setup buffer\n");
1181 return vaStatus;
1182 }
1183 jpeg_ctx_p->pMemInfoMTXSetup = cmdbuf->jpeg_header_mem_p;
1184 jpeg_ctx_p->pMTXSetup = (JPEG_MTX_DMA_SETUP*)jpeg_ctx_p->pMemInfoMTXSetup;
1185 memset(jpeg_ctx_p->pMemInfoMTXSetup, 0x0, ctx->jpeg_header_mem_size);
1186
1187
1188 /* Map MTX setup interface buffer */
1189 vaStatus = psb_buffer_map(&cmdbuf->jpeg_header_interface_mem, (unsigned char **)&cmdbuf->jpeg_header_interface_mem_p);
1190 if (vaStatus) {
1191 drv_debug_msg(VIDEO_DEBUG_ERROR, "Fail to map MTX setup interface buffer\n");
1192 psb_buffer_unmap(&cmdbuf->jpeg_header_mem);
1193 return vaStatus;
1194 }
1195 jpeg_ctx_p->pMemInfoWritebackMemory = cmdbuf->jpeg_header_interface_mem_p;
1196 jpeg_ctx_p->pMTXWritebackMemory = (JPEG_MTX_WRITEBACK_MEMORY*)jpeg_ctx_p->pMemInfoWritebackMemory;
1197 memset(jpeg_ctx_p->pMemInfoWritebackMemory, 0x0, ctx->jpeg_header_interface_mem_size);
1198
1199
1200 /* Map quantization table buffer */
1201 vaStatus = psb_buffer_map(&cmdbuf->jpeg_pic_params, (unsigned char **)&cmdbuf->jpeg_pic_params_p);
1202 if (vaStatus) {
1203 drv_debug_msg(VIDEO_DEBUG_ERROR, "Fail to map quantization table buffer\n");
1204 psb_buffer_unmap(&cmdbuf->jpeg_header_mem);
1205 psb_buffer_unmap(&cmdbuf->jpeg_header_interface_mem);
1206 return vaStatus;
1207 }
1208 jpeg_ctx_p->pMemInfoTableBlock = cmdbuf->jpeg_pic_params_p;
1209 jpeg_ctx_p->psTablesBlock = (JPEG_MTX_QUANT_TABLE *)jpeg_ctx_p->pMemInfoTableBlock;
1210 memset(jpeg_ctx_p->pMemInfoTableBlock, 0x0, ctx->jpeg_pic_params_size);
1211
1212 vaStatus = tng__cmdbuf_lowpower(ctx);
1213 if (vaStatus != VA_STATUS_SUCCESS) {
1214 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
1215 }
1216
1217 /* Set SetupInterface*/
1218 SetSetupInterface(jpeg_ctx_p);
1219 IssueSetupInterface(jpeg_ctx_p);
1220
1221 /* Set MTX setup struture */
1222 ret = SetMTXSetup(jpeg_ctx_p, ps_buf->src_surface);
1223 if (ret != IMG_ERR_OK)
1224 return ret;
1225 IssueMTXSetup(jpeg_ctx_p);
1226
1227 /* Initialize the default quantization tables */
1228 SetDefaultQmatix(jpeg_ctx_p->pMemInfoTableBlock);
1229
1230 /* Initialize scan counters */
1231 InitializeScanCounter(jpeg_ctx_p);
1232
1233 tng_cmdbuf_buffer_ref(cmdbuf, &(ctx->obj_context->current_render_target->psb_surface->buf));
1234
1235 return vaStatus;
1236 }
1237
ProcessQmatrixParam(context_ENC_p ctx,object_buffer_p obj_buffer)1238 static VAStatus ProcessQmatrixParam(context_ENC_p ctx, object_buffer_p obj_buffer)
1239 {
1240 VAStatus vaStatus = VA_STATUS_SUCCESS;
1241 VAQMatrixBufferJPEG *pBuffer;
1242 JPEG_MTX_QUANT_TABLE* pQMatrix = (JPEG_MTX_QUANT_TABLE *)(ctx->jpeg_ctx->psTablesBlock);
1243
1244 ASSERT(obj_buffer->type == VAQMatrixBufferType);
1245
1246 pBuffer = (VAQMatrixBufferJPEG *)obj_buffer->buffer_data;
1247
1248 if (0 != pBuffer->load_lum_quantiser_matrix) {
1249 memcpy(pQMatrix->aui8LumaQuantParams,
1250 pBuffer->lum_quantiser_matrix,
1251 QUANT_TABLE_SIZE_BYTES);
1252 }
1253
1254 if (0 != pBuffer->load_chroma_quantiser_matrix) {
1255 memcpy(pQMatrix->aui8ChromaQuantParams,
1256 pBuffer->chroma_quantiser_matrix,
1257 QUANT_TABLE_SIZE_BYTES);
1258 }
1259
1260 free(obj_buffer->buffer_data);
1261 obj_buffer->buffer_data = NULL;
1262
1263 return vaStatus;
1264 }
1265
ProcessPictureParam(context_ENC_p ctx,object_buffer_p obj_buffer)1266 static VAStatus ProcessPictureParam(context_ENC_p ctx, object_buffer_p obj_buffer)
1267 {
1268 VAStatus vaStatus = VA_STATUS_SUCCESS;
1269 VAEncPictureParameterBufferJPEG *pBuffer = NULL;
1270 BUFFER_HEADER *pBufHeader = NULL;
1271 TOPAZHP_JPEG_ENCODER_CONTEXT *jpeg_ctx = ctx->jpeg_ctx;
1272 JPEG_MTX_QUANT_TABLE* pQMatrix = (JPEG_MTX_QUANT_TABLE *)
1273 (ctx->jpeg_ctx->pMemInfoTableBlock);
1274 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
1275 IMG_ERRORCODE rc;
1276
1277 /* Check the input buffer */
1278 ASSERT(obj_buffer->type == VAEncPictureParameterBufferType);
1279 if ((obj_buffer->num_elements != 1) ||
1280 (obj_buffer->size != sizeof(VAEncPictureParameterBufferJPEG))) {
1281 return VA_STATUS_ERROR_UNKNOWN;
1282 }
1283
1284
1285 /* Lookup and get coded buffer */
1286 pBuffer = (VAEncPictureParameterBufferJPEG *)obj_buffer->buffer_data;
1287
1288 /* Parameters checking */
1289 if (((pBuffer->pic_flags).bits.profile != 0) || /* Only "0 - Baseline" is supported */
1290 ((pBuffer->pic_flags).bits.progressive != 0) || /* Only "0 - sequential" is supported */
1291 ((pBuffer->pic_flags).bits.huffman != 1) || /* Only "1 - huffman" is supported */
1292 ((pBuffer->pic_flags).bits.interleaved != 0) || /* Only "0 - non interleaved" is supported */
1293 ((pBuffer->pic_flags).bits.differential != 0)) /* Only "0 - non differential" is supported */
1294 return VA_STATUS_ERROR_INVALID_PARAMETER;
1295
1296 if ((pBuffer->sample_bit_depth != 8) || /* Only 8-bits sample depth is supported */
1297 (pBuffer->num_components != MTX_MAX_COMPONENTS) || /* Only 3 components setting is supported */
1298 (pBuffer->quality > 100))
1299 return VA_STATUS_ERROR_INVALID_PARAMETER;
1300
1301 /* Set quality */
1302 if (pBuffer->quality != 0) { /* Quality value is set */
1303 CustomizeQuantizationTables(pQMatrix->aui8LumaQuantParams,
1304 pQMatrix->aui8ChromaQuantParams,
1305 pBuffer->quality);
1306 }
1307
1308 ASSERT(ctx->ui16Width == pBuffer->picture_width);
1309 ASSERT(ctx->ui16FrameHeight == pBuffer->picture_height);
1310
1311 ps_buf->coded_buf = BUFFER(pBuffer->coded_buf);
1312
1313 free(pBuffer);
1314 obj_buffer->buffer_data = NULL;
1315 obj_buffer->size = 0;
1316
1317 if (NULL == ps_buf->coded_buf) {
1318 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
1319 return VA_STATUS_ERROR_INVALID_BUFFER;
1320 }
1321
1322 /* Map coded buffer */
1323 vaStatus = psb_buffer_map(ps_buf->coded_buf->psb_buffer, (unsigned char **)&jpeg_ctx->jpeg_coded_buf.pMemInfo);
1324 if (vaStatus) {
1325 drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: Map coded_buf failed!");
1326 return vaStatus;
1327 }
1328 jpeg_ctx->jpeg_coded_buf.ui32Size = ps_buf->coded_buf->size;
1329 jpeg_ctx->jpeg_coded_buf.sLock = BUFFER_FREE;
1330 jpeg_ctx->jpeg_coded_buf.ui32BytesWritten = 0;
1331
1332 if ((jpeg_ctx->jpeg_coded_buf.ui32Size) < (9 + 6 + (4 * 3))) {
1333 return VA_STATUS_ERROR_INVALID_BUFFER;
1334 }
1335
1336
1337 /* Assign coded buffer to each scan */
1338 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Assign coded buffer to each scan\n");
1339 AssignCodedDataBuffers(jpeg_ctx);
1340
1341 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Coded buffer total size is %d,"
1342 "coded segment size per scan is %d\n",
1343 jpeg_ctx->jpeg_coded_buf.ui32Size, jpeg_ctx->ui32SizePerCodedBuffer);
1344
1345
1346 /* Write JPEG headers to coded buffer */
1347 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Write JPEG Headers to coded buf\n");
1348
1349 pBufHeader = (BUFFER_HEADER *)jpeg_ctx->jpeg_coded_buf.pMemInfo;
1350 pBufHeader->ui32BytesUsed = 0; /* Not include BUFFER_HEADER*/
1351
1352 rc = PrepareHeader(jpeg_ctx, &jpeg_ctx->jpeg_coded_buf, sizeof(BUFFER_HEADER), IMG_TRUE);
1353 if (rc != IMG_ERR_OK)
1354 return VA_STATUS_ERROR_UNKNOWN;
1355
1356 pBufHeader->ui32Reserved3 = PTG_JPEG_HEADER_MAX_SIZE;//Next coded buffer offset
1357 pBufHeader->ui32BytesUsed = jpeg_ctx->jpeg_coded_buf.ui32BytesWritten - sizeof(BUFFER_HEADER);
1358
1359 drv_debug_msg(VIDEO_DEBUG_GENERAL, "sizeof(BUFFER_HEADER): %d, ui32BytesUsed :%d, ui32Reserved3: %d, ui32BytesWritten: %d\n",
1360 sizeof(BUFFER_HEADER), pBufHeader->ui32BytesUsed, pBufHeader->ui32Reserved3, jpeg_ctx->jpeg_coded_buf.ui32BytesWritten);
1361
1362 return vaStatus;
1363 }
tng_jpeg_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)1364 static VAStatus tng_jpeg_RenderPicture(
1365 object_context_p obj_context,
1366 object_buffer_p *buffers,
1367 int num_buffers)
1368 {
1369 context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
1370 VAStatus vaStatus = VA_STATUS_SUCCESS;
1371 int i;
1372
1373 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_RenderPicture\n");
1374
1375 for (i = 0; i < num_buffers; i++) {
1376 object_buffer_p obj_buffer = buffers[i];
1377
1378 switch (obj_buffer->type) {
1379 case VAQMatrixBufferType:
1380 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_RenderPicture got VAEncSliceParameterBufferType\n");
1381 vaStatus = ProcessQmatrixParam(ctx, obj_buffer);
1382 DEBUG_FAILURE;
1383 break;
1384 case VAEncPictureParameterBufferType:
1385 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_RenderPicture got VAEncPictureParameterBufferType\n");
1386 vaStatus = ProcessPictureParam(ctx, obj_buffer);
1387 DEBUG_FAILURE;
1388 break;
1389 case VAEncSliceParameterBufferType:
1390 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_RenderPicture got VAEncSliceParameterBufferType\n");
1391 drv_debug_msg(VIDEO_DEBUG_WARNING, "VAEncSliceParameterBufferType is ignored on TopazHP\n");
1392 vaStatus = VA_STATUS_SUCCESS;
1393 DEBUG_FAILURE;
1394 break;
1395 default:
1396 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1397 DEBUG_FAILURE;
1398 }
1399 }
1400
1401 return vaStatus;
1402 }
1403
tng_jpeg_EndPicture(object_context_p obj_context)1404 static VAStatus tng_jpeg_EndPicture(
1405 object_context_p obj_context)
1406 {
1407 IMG_UINT16 ui16BCnt;
1408 IMG_UINT32 rc = 0;
1409 VAStatus vaStatus = VA_STATUS_SUCCESS;
1410 IMG_UINT32 ui32NoMCUsToEncode = 0;
1411 IMG_UINT32 ui32RemainMCUs = 0;
1412
1413 context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
1414 TOPAZHP_JPEG_ENCODER_CONTEXT *jpeg_ctx_p = ctx->jpeg_ctx;
1415 tng_cmdbuf_p cmdbuf = (tng_cmdbuf_p)ctx->obj_context->tng_cmdbuf;
1416 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
1417 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
1418
1419 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_jpeg_EndPicture\n");
1420
1421 IssueQmatix(jpeg_ctx_p);
1422
1423 /* Compute the next scan to be sent */
1424 ui32RemainMCUs = jpeg_ctx_p->sScan_Encode_Info.ui32NumberMCUsToEncode;
1425 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32RemainMCUs: %d\n", ui32RemainMCUs);
1426
1427 for (ui16BCnt = 0; (ui16BCnt < jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers)
1428 && (jpeg_ctx_p->sScan_Encode_Info.ui16SScan > 0); ui16BCnt++) {
1429
1430 jpeg_ctx_p->sScan_Encode_Info.aBufferTable[ui16BCnt].ui16ScanNumber = jpeg_ctx_p->sScan_Encode_Info.ui16SScan--;
1431 jpeg_ctx_p->sScan_Encode_Info.aBufferTable[ui16BCnt].i8PipeNumber =
1432 (1 == jpeg_ctx_p->NumCores) ? 0 : ((ui16BCnt+1) % jpeg_ctx_p->NumCores);
1433
1434 if (jpeg_ctx_p->sScan_Encode_Info.ui16SScan > 0) {
1435 ui32NoMCUsToEncode = jpeg_ctx_p->sScan_Encode_Info.ui32NumberMCUsToEncodePerScan;
1436 } else {
1437 // Final scan, may need fewer MCUs than buffer size, calculate the remainder
1438 ui32NoMCUsToEncode = ui32RemainMCUs;
1439 jpeg_ctx_p->sScan_Encode_Info.aBufferTable[ui16BCnt].i8PipeNumber = 0;
1440 }
1441
1442 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32NoMCUsToEncode: %d\n", ui32NoMCUsToEncode);
1443 //Send scan to MTX
1444 rc = IssueBufferToHW(jpeg_ctx_p, ui16BCnt,
1445 jpeg_ctx_p->sScan_Encode_Info.aBufferTable[ui16BCnt].i8PipeNumber,
1446 ui32NoMCUsToEncode);
1447 if (rc != IMG_ERR_OK) {
1448 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1449 DEBUG_FAILURE;
1450 return vaStatus;
1451 }
1452
1453 ui32RemainMCUs -= ui32NoMCUsToEncode;
1454 }
1455
1456
1457 psb_buffer_unmap(&cmdbuf->jpeg_pic_params);
1458 cmdbuf->jpeg_pic_params_p = NULL;
1459 psb_buffer_unmap(&cmdbuf->jpeg_header_mem);
1460 cmdbuf->jpeg_header_mem_p = NULL;
1461 psb_buffer_unmap(ps_buf->coded_buf->psb_buffer);
1462 jpeg_ctx_p->jpeg_coded_buf.pMemInfo = NULL;
1463
1464 psb_buffer_unmap(&(ctx->bufs_writeback));
1465
1466
1467 //tng__trace_cmdbuf(cmdbuf);
1468
1469 if (tng_context_flush_cmdbuf(ctx->obj_context)) {
1470 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1471 return vaStatus;
1472 }
1473
1474 ctx->obj_context->frame_count++;
1475 return VA_STATUS_SUCCESS;
1476 }
1477
1478 /* Add Restart interval termination (RSTm)to coded buf 1 ~ NumCores-1*/
tng_OutputResetIntervalToCB(IMG_UINT8 * pui8Buf,IMG_UINT8 ui8_marker)1479 static inline VAStatus tng_OutputResetIntervalToCB(IMG_UINT8 *pui8Buf, IMG_UINT8 ui8_marker)
1480 {
1481 if (NULL == pui8Buf)
1482 return VA_STATUS_ERROR_UNKNOWN;
1483 /*Refer to CCITT Rec. T.81 (1992 E), B.2.1*/
1484 /*RSTm: Restart marker conditional marker which is placed between
1485 * entropy-coded segments only if restartis enabled. There are 8 unique
1486 * restart markers (m = 0 - 7) which repeat in sequence from 0 to 7, starting with
1487 * zero for each scan, to provide a modulo 8 restart interval count*/
1488
1489 *pui8Buf++ = 0xff;
1490 *pui8Buf = (ui8_marker & 0x7) | 0xD0;
1491
1492 return 0;
1493 }
1494
tng_jpeg_AppendMarkers(object_context_p obj_context,void * raw_coded_buf)1495 VAStatus tng_jpeg_AppendMarkers(object_context_p obj_context, void *raw_coded_buf)
1496 {
1497 context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
1498 TOPAZHP_JPEG_ENCODER_CONTEXT *jpeg_ctx_p = ctx->jpeg_ctx;
1499
1500 IMG_UINT16 ui16BCnt;
1501 BUFFER_HEADER* pBufHeader;
1502 STREAMTYPEW s_streamW;
1503 void *pSegStart = raw_coded_buf;
1504
1505 if (pSegStart == NULL) {
1506 return VA_STATUS_ERROR_UNKNOWN;
1507 }
1508
1509 pBufHeader = (BUFFER_HEADER *)pSegStart;
1510
1511 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Number of Coded buffers %d, Per Coded Buffer size : %d\n",
1512 jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers,
1513 jpeg_ctx_p->ui32SizePerCodedBuffer);
1514
1515 /*The first part of coded buffer contains JPEG headers*/
1516 pBufHeader->ui32Reserved3 = PTG_JPEG_HEADER_MAX_SIZE;
1517 jpeg_ctx_p->jpeg_coded_buf.ui32BytesWritten = 0;
1518
1519 for (ui16BCnt = 0;
1520 ui16BCnt < jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers;
1521 ui16BCnt++) {
1522 pBufHeader = (BUFFER_HEADER *)pSegStart;
1523 pBufHeader->ui32Reserved3 =
1524 PTG_JPEG_HEADER_MAX_SIZE + jpeg_ctx_p->ui32SizePerCodedBuffer * ui16BCnt ;
1525
1526 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Coded Buffer Part %d, size %d, next part offset: %d\n",
1527 ui16BCnt, pBufHeader->ui32BytesUsed, pBufHeader->ui32Reserved3);
1528
1529 if (ui16BCnt > 0) {
1530 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Append 2 bytes Reset Interval %d "
1531 "to Coded Buffer Part %d\n", ui16BCnt - 1, ui16BCnt);
1532
1533 // OUTPUT RESTART INTERVAL TO CODED BUFFER
1534 tng_OutputResetIntervalToCB(
1535 (IMG_UINT8 *)((IMG_UINT32)pSegStart + sizeof(BUFFER_HEADER) + pBufHeader->ui32BytesUsed),
1536 ui16BCnt - 1);
1537
1538 pBufHeader->ui32BytesUsed += 2;
1539 }
1540
1541 jpeg_ctx_p->jpeg_coded_buf.ui32BytesWritten += pBufHeader->ui32BytesUsed;
1542 pSegStart = (void *)((IMG_UINT32)raw_coded_buf + pBufHeader->ui32Reserved3);
1543 }
1544
1545 pBufHeader = (BUFFER_HEADER *)pSegStart;
1546 pBufHeader->ui32Reserved3 = 0; /*Last Part of Coded Buffer*/
1547 jpeg_ctx_p->jpeg_coded_buf.ui32BytesWritten += pBufHeader->ui32BytesUsed;
1548
1549 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Coded Buffer Part %d, size %d, next part offset: %d\n",
1550 ui16BCnt, pBufHeader->ui32BytesUsed, pBufHeader->ui32Reserved3);
1551
1552 s_streamW.Buffer = pSegStart;
1553 s_streamW.Offset = (sizeof(BUFFER_HEADER) + pBufHeader->ui32BytesUsed);
1554
1555 fPutBitsToBuffer(&s_streamW, 2, END_OF_IMAGE);
1556
1557 pBufHeader->ui32BytesUsed += 2;
1558 jpeg_ctx_p->jpeg_coded_buf.ui32BytesWritten += 2;
1559
1560 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Add two bytes to last part of coded buffer,"
1561 " total: %d\n", jpeg_ctx_p->jpeg_coded_buf.ui32BytesWritten);
1562 return VA_STATUS_SUCCESS;
1563 }
1564
1565 struct format_vtable_s tng_JPEGES_vtable = {
1566 queryConfigAttributes:
1567 tng_jpeg_QueryConfigAttributes,
1568 validateConfig:
1569 tng_jpeg_ValidateConfig,
1570 createContext:
1571 tng_jpeg_CreateContext,
1572 destroyContext:
1573 tng_jpeg_DestroyContext,
1574 beginPicture:
1575 tng_jpeg_BeginPicture,
1576 renderPicture:
1577 tng_jpeg_RenderPicture,
1578 endPicture:
1579 tng_jpeg_EndPicture
1580 };
1581