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  *    Guo Nana <nana.n.guo@intel.com>
27  *    Zeng Li <li.zeng@intel.com>
28  *
29  */
30 
31 #include "va/va_dec_jpeg.h"
32 #include "tng_jpegdec.h"
33 #include "tng_vld_dec.h"
34 #include "psb_def.h"
35 #include "psb_drv_debug.h"
36 
37 #include "hwdefs/reg_io2.h"
38 #include "hwdefs/msvdx_offsets.h"
39 #include "hwdefs/msvdx_cmds_io2.h"
40 #include "hwdefs/msvdx_vec_reg_io2.h"
41 #include "hwdefs/msvdx_vec_jpeg_reg_io2.h"
42 #include "hwdefs/dxva_fw_ctrl.h"
43 
44 #include <stdlib.h>
45 #include <stdint.h>
46 #include <string.h>
47 #include <stdio.h>
48 
49 #define GET_SURFACE_INFO_is_defined(psb_surface) ((int) (psb_surface->extra_info[0]))
50 #define SET_SURFACE_INFO_is_defined(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val;
51 #define GET_SURFACE_INFO_picture_structure(psb_surface) (psb_surface->extra_info[1])
52 #define SET_SURFACE_INFO_picture_structure(psb_surface, val) psb_surface->extra_info[1] = val;
53 #define GET_SURFACE_INFO_picture_coding_type(psb_surface) ((int) (psb_surface->extra_info[2]))
54 #define SET_SURFACE_INFO_picture_coding_type(psb_surface, val) psb_surface->extra_info[2] = (uint32_t) val;
55 
56 #define JPEG_MAX_SETS_HUFFMAN_TABLES 2
57 #define JPEG_MAX_QUANT_TABLES 4
58 
59 #define TABLE_CLASS_DC  0
60 #define TABLE_CLASS_AC  1
61 #define TABLE_CLASS_NUM 2
62 
63 #define JPEG_PROFILE_BASELINE 0
64 
65 /************************************/
66 /* VLC table defines and structures */
67 
68 /* max number of bits allowed in a VLC code */
69 #define JPG_VLC_MAX_CODE_LEN        (16)
70 
71 /* max num bits to decode in any one decode direct operation */
72 #define JPG_VLC_MAX_DIRECT_WIDTH    (6)
73 
74 static const uint8_t inverse_zigzag[64] =
75 {
76     0x00, 0x01, 0x05, 0x06, 0x0e, 0x0f, 0x1b, 0x1c,
77     0x02, 0x04, 0x07, 0x0D, 0x10, 0x1a, 0x1d, 0x2a,
78     0x03, 0x08, 0x0C, 0x11, 0x19, 0x1e, 0x29, 0x2b,
79     0x09, 0x0B, 0x12, 0x18, 0x1f, 0x28, 0x2c, 0x35,
80     0x0A, 0x13, 0x17, 0x20, 0x27, 0x2d, 0x34, 0x36,
81     0x14, 0x16, 0x21, 0x26, 0x2e, 0x33, 0x37, 0x3c,
82     0x15, 0x22, 0x25, 0x2f, 0x32, 0x38, 0x3b, 0x3d,
83     0x23, 0x24, 0x30, 0x31, 0x39, 0x3a, 0x3e, 0x3f
84 };
85 
86 
87 /*
88 ******************************************************************************
89 
90  This structure defines the VLC code used for a partiular symbol
91 
92 ******************************************************************************/
93 typedef struct
94 {
95     uint16_t code;    // VLC code with valid data in top-most bits
96     uint8_t code_length;   // VLC code length
97     uint8_t symbol;
98 
99 } vlc_symbol_code_jpeg; // VLCSymbolCodeJPEG
100 
101 
102 /*
103 ******************************************************************************
104 
105  This structure describes a set of VLC codes for a particular Huffman tree
106 
107 ******************************************************************************/
108 typedef struct
109 {
110     uint32_t num_codes;
111     uint32_t min_len;
112     uint32_t max_len;
113 
114 } vlc_symbol_stats_jpeg; // VLCSymbolStatsJPEG
115 
116 
117 /*
118 ******************************************************************************
119 
120  This structure describes the generated VLC code table
121 
122 ******************************************************************************/
123 typedef struct
124 {
125     uint32_t size;
126     uint32_t initial_width;
127     uint32_t initial_opcode;
128 
129 } vlc_table_stats_jpeg; // VLCTableStatsJPEG
130 
131 
132 /**************************************/
133 /* JPEG VLC Table defines and OpCodes */
134 
135 #define JPG_MAKE_MASK(X) ((1<<(X))-1)
136 
137 #define JPG_INSTR_OP_CODE_WIDTH (3)
138 #define JPG_INSTR_SHIFT_WIDTH   (3)
139 #define JPG_INSTR_OFFSET_WIDTH  (9)
140 
141 #define JPG_INSTR_OP_CODE_MASK  JPG_MAKE_MASK(JPG_JPG_INSTR_OP_CODE_WIDTH)
142 #define JPG_INSTR_SHIFT_MASK    JPG_MAKE_MASK(JPG_INSTR_SHIFT_WIDTH)
143 #define JPG_INSTR_OFFSET_MASK   JPG_MAKE_MASK(JPG_INSTR_OFFSET_WIDTH)
144 
145 
146 #define JPG_MAKE_OFFSET(code,width,leading) \
147 (((code<<leading) & JPG_MAKE_MASK(JPG_VLC_MAX_CODE_LEN)) >> (JPG_VLC_MAX_CODE_LEN-width))
148 
149 typedef enum {
150     JPG_OP_DECODE_DIRECT = 0,
151     JPG_OP_DECODE_LEADING_1,
152     JPG_OP_DECODE_LEADING_0,
153 
154     JPG_OP_CODE_INVALID,
155 
156     JPG_OP_VALID_SYMBOL,
157     JPG_OP_VALID_RANGE_EVEN,
158     JPG_OP_VALID_RANGE_ODD,
159     JPG_OP_VALID_RANGE_EVEN_SET_FLAG,
160 
161 } vlc_op_code_jpeg; // VLCOpCodeJPEG
162 
163 /**************************************/
164 
165 struct context_JPEG_s {
166     struct context_DEC_s dec_ctx;
167     object_context_p obj_context; /* back reference */
168 
169     uint32_t profile;
170 
171     /* Picture parameters */
172     VAPictureParameterBufferJPEGBaseline *pic_params;
173 
174     uint32_t display_picture_width;    /* in pixels */
175     uint32_t display_picture_height;    /* in pixels */
176 
177     uint32_t coded_picture_width;    /* in pixels */
178     uint32_t coded_picture_height;    /* in pixels */
179 
180     uint32_t MCU_width;
181     uint32_t MCU_height;
182     uint32_t size_mb;                /* in macroblocks */
183     uint32_t picture_width_mb;        /* in macroblocks */
184     uint32_t picture_height_mb;        /* in macroblocks */
185 
186     uint8_t max_scalingH;
187     uint8_t max_scalingV;
188 
189     /* VLC packed data */
190     struct psb_buffer_s vlc_packed_table;
191 
192     uint32_t vlctable_buffer_size;
193     uint32_t rendec_qmatrix[JPEG_MAX_QUANT_TABLES][16];
194 
195     /* Huffman table information as parsed from the bitstream */
196     vlc_symbol_code_jpeg* symbol_codes[TABLE_CLASS_NUM][JPEG_MAX_SETS_HUFFMAN_TABLES];
197     vlc_symbol_stats_jpeg symbol_stats[TABLE_CLASS_NUM][JPEG_MAX_SETS_HUFFMAN_TABLES];
198 
199     /*  Huffman table information compiled for the hardware */
200     uint32_t huffman_table_space;
201     uint16_t* huffman_table_RAM;
202     vlc_table_stats_jpeg table_stats[TABLE_CLASS_NUM][JPEG_MAX_SETS_HUFFMAN_TABLES];
203 };
204 
205 typedef struct context_JPEG_s *context_JPEG_p;
206 
207 #define INIT_CONTEXT_JPEG    context_JPEG_p ctx = (context_JPEG_p) obj_context->format_data;
208 
209 #define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
210 
tng_JPEG_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib __maybe_unused * attrib_list,int __maybe_unused num_attribs)211 static void tng_JPEG_QueryConfigAttributes(
212     VAProfile __maybe_unused profile,
213     VAEntrypoint __maybe_unused entrypoint,
214     VAConfigAttrib __maybe_unused * attrib_list,
215     int __maybe_unused num_attribs) {
216     /* No JPEG specific attributes */
217 }
218 
tng_JPEG_ValidateConfig(object_config_p obj_config)219 static VAStatus tng_JPEG_ValidateConfig(object_config_p obj_config) {
220     int i;
221     /* Check all attributes */
222     for (i = 0; i < obj_config->attrib_count; i++) {
223         switch (obj_config->attrib_list[i].type) {
224         case VAConfigAttribRTFormat:
225             /* Ignore */
226             break;
227 
228         default:
229             return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
230         }
231     }
232 
233     return VA_STATUS_SUCCESS;
234 }
235 
tng__JPEG_check_legal_picture(object_context_p obj_context,object_config_p obj_config)236 static VAStatus tng__JPEG_check_legal_picture(object_context_p obj_context, object_config_p obj_config) {
237     VAStatus vaStatus = VA_STATUS_SUCCESS;
238 
239     if (NULL == obj_context) {
240         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
241         DEBUG_FAILURE;
242         return vaStatus;
243     }
244 
245     if (NULL == obj_config) {
246         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
247         DEBUG_FAILURE;
248         return vaStatus;
249     }
250 
251     switch (obj_config->profile) {
252     case VAProfileJPEGBaseline:
253         if ((obj_context->picture_width <= 0) || (obj_context->picture_height <= 0)) {
254             vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
255         }
256         break;
257 
258     default:
259         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
260         break;
261     }
262 
263     return vaStatus;
264 }
265 
266 static void tng_JPEG_DestroyContext(object_context_p obj_context);
267 
268 static void tng__JPEG_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
269 static void tng__JPEG_end_slice(context_DEC_p dec_ctx);
270 static void tng__JPEG_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
271 static VAStatus tng_JPEG_process_buffer(context_DEC_p dec_ctx, object_buffer_p buffer);
272 
tng_JPEG_CreateContext(object_context_p obj_context,object_config_p obj_config)273 static VAStatus tng_JPEG_CreateContext(
274     object_context_p obj_context,
275     object_config_p obj_config) {
276     VAStatus vaStatus = VA_STATUS_SUCCESS;
277     context_JPEG_p ctx;
278 
279     /* Validate flag */
280     /* Validate picture dimensions */
281     vaStatus = tng__JPEG_check_legal_picture(obj_context, obj_config);
282     if (VA_STATUS_SUCCESS != vaStatus) {
283         DEBUG_FAILURE;
284         return vaStatus;
285     }
286 
287     ctx = (context_JPEG_p) calloc(1, sizeof(struct context_JPEG_s));
288     if (NULL == ctx) {
289         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
290         DEBUG_FAILURE;
291         return vaStatus;
292     }
293     obj_context->format_data = (void*) ctx;
294     ctx->obj_context = obj_context;
295     ctx->pic_params = NULL;
296 
297     ctx->dec_ctx.begin_slice = tng__JPEG_begin_slice;
298     ctx->dec_ctx.process_slice = tng__JPEG_process_slice_data;
299     ctx->dec_ctx.end_slice = tng__JPEG_end_slice;
300     ctx->dec_ctx.process_buffer = tng_JPEG_process_buffer;
301     ctx->dec_ctx.preload_buffer = NULL;
302 
303     switch (obj_config->profile) {
304     case VAProfileJPEGBaseline:
305         drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG_PROFILE_BASELINE\n");
306         ctx->profile = JPEG_PROFILE_BASELINE;
307         break;
308 
309     default:
310         ASSERT(0 == 1);
311         vaStatus = VA_STATUS_ERROR_UNKNOWN;
312     }
313 
314     ctx->vlctable_buffer_size = 1984 * 2;
315     if (vaStatus == VA_STATUS_SUCCESS) {
316         vaStatus = psb_buffer_create(obj_context->driver_data,
317                                      ctx->vlctable_buffer_size,
318                                      psb_bt_cpu_vpu,
319                                      &ctx->vlc_packed_table);
320         DEBUG_FAILURE;
321     }
322 
323     if (vaStatus == VA_STATUS_SUCCESS) {
324         vaStatus = vld_dec_CreateContext(&ctx->dec_ctx, obj_context);
325         DEBUG_FAILURE;
326     }
327 
328     if (vaStatus != VA_STATUS_SUCCESS) {
329         tng_JPEG_DestroyContext(obj_context);
330     }
331 
332     return vaStatus;
333 }
334 
tng_JPEG_DestroyContext(object_context_p obj_context)335 static void tng_JPEG_DestroyContext(
336     object_context_p obj_context) {
337     INIT_CONTEXT_JPEG
338     int i;
339 
340     vld_dec_DestroyContext(&ctx->dec_ctx);
341 
342     psb_buffer_destroy(&ctx->vlc_packed_table);
343 
344     if (ctx->pic_params) {
345         free(ctx->pic_params);
346         ctx->pic_params = NULL;
347     }
348 
349     if (ctx->symbol_codes[0][0]) {
350         free(ctx->symbol_codes[0][0]);
351         ctx->symbol_codes[0][0] = NULL;
352     }
353     if (ctx->symbol_codes[0][1]) {
354         free(ctx->symbol_codes[0][1]);
355         ctx->symbol_codes[0][1] = NULL;
356     }
357     if (ctx->symbol_codes[1][0]) {
358         free(ctx->symbol_codes[1][0]);
359         ctx->symbol_codes[1][0] = NULL;
360     }
361     if (ctx->symbol_codes[1][1]) {
362         free(ctx->symbol_codes[1][1]);
363         ctx->symbol_codes[1][1] = NULL;
364     }
365     free(obj_context->format_data);
366     obj_context->format_data = NULL;
367 }
368 
jpg_vlc_valid_symbol(const vlc_symbol_code_jpeg * symbol_code,const uint32_t leading)369 static uint16_t jpg_vlc_valid_symbol(const vlc_symbol_code_jpeg * symbol_code, const uint32_t leading) {
370     uint16_t entry = 0;
371     IMG_ASSERT( (symbol_code->code_length - leading - 1) >= 0 );
372 
373     /* VLC microcode entry for a valid symbol */
374     entry |= (JPG_OP_VALID_SYMBOL << (JPG_INSTR_SHIFT_WIDTH+JPG_INSTR_OFFSET_WIDTH));
375     entry |= ((symbol_code->code_length - leading - 1) << JPG_INSTR_OFFSET_WIDTH);
376     entry |= symbol_code->symbol;
377     return entry;
378 }
379 
380 static uint32_t
jpg_vlc_write_direct_command(uint16_t * const vlc_ram,uint32_t result_offset)381 jpg_vlc_write_direct_command(uint16_t * const vlc_ram, uint32_t result_offset) {
382     uint32_t width = 0x7fff & *vlc_ram;
383     uint16_t entry = 0;
384 
385     /* check that the max width read from the VLC entry is valid */
386     IMG_ASSERT( 0x8000 & *vlc_ram );
387 
388     /* limit to the maximum width for this algorithm */
389     width = (width > JPG_VLC_MAX_DIRECT_WIDTH)? JPG_VLC_MAX_DIRECT_WIDTH: width;
390 
391     /* VLC microcode for decode direct command */
392     entry |= (JPG_OP_DECODE_DIRECT << (JPG_INSTR_SHIFT_WIDTH+JPG_INSTR_OFFSET_WIDTH));
393     entry |= ((width - 1) << JPG_INSTR_OFFSET_WIDTH);
394     entry |= result_offset;
395 
396     /* write command */
397     *vlc_ram = entry;
398 
399     return width;
400 }
401 
402 static uint32_t
jpg_vlc_get_offset(const vlc_symbol_code_jpeg * symbol_code,uint32_t width,uint32_t leading)403 jpg_vlc_get_offset(const vlc_symbol_code_jpeg * symbol_code, uint32_t width, uint32_t leading) {
404     uint32_t offset;
405 
406     /* lose bits already decoded */
407     offset = symbol_code->code << leading;
408     offset &= JPG_MAKE_MASK(JPG_VLC_MAX_CODE_LEN);
409     /* convert truncated code to offset */
410     offset >>= (JPG_VLC_MAX_CODE_LEN - width);
411     return offset;
412 }
413 
414 static uint32_t
jpg_vlc_decode_direct_symbols(const vlc_symbol_code_jpeg * symbol_code,uint16_t * const table_ram,const uint32_t width,const uint32_t leading)415 jpg_vlc_decode_direct_symbols(const vlc_symbol_code_jpeg * symbol_code, uint16_t * const table_ram, const uint32_t width,
416     const uint32_t leading) {
417     uint32_t offset, limit;
418     uint16_t entry;
419 
420     /* this function is only for codes short enough to produce valid symbols */
421     IMG_ASSERT( symbol_code->code_length <= leading + width );
422     IMG_ASSERT( symbol_code->code_length > leading );
423 
424     /* lose bits already decoded */
425     offset = symbol_code->code << leading;
426     offset &= JPG_MAKE_MASK(JPG_VLC_MAX_CODE_LEN);
427 
428     /* convert truncated code to offset */
429     offset >>= (JPG_VLC_MAX_CODE_LEN - width);
430     /* expand offset to encorporate undefined code bits */
431     limit = offset + (1 << (width - (symbol_code->code_length - leading)));
432 
433     /* for all code variants - insert symbol into the decode direct result table */
434     entry = jpg_vlc_valid_symbol( symbol_code, leading );
435     for (; offset < limit; offset++) {
436         table_ram[offset] = entry;
437     }
438 
439     /* return the number of entries written */
440     return limit - offset - 1;
441 }
442 
443 static uint32_t
jpg_vlc_decode_direct(const vlc_symbol_code_jpeg * symbol_codes,const uint32_t num_codes,uint16_t * const table_ram,const uint32_t direct_width,const uint32_t leading_width,const uint32_t leading_pattern)444 jpg_vlc_decode_direct(
445     const vlc_symbol_code_jpeg * symbol_codes,
446     const uint32_t num_codes,
447     uint16_t * const table_ram,
448     const uint32_t direct_width,
449     const uint32_t leading_width,
450     const uint32_t leading_pattern) {
451     const uint32_t next_leading_width = leading_width + direct_width;
452     const uint32_t next_leading_mask = JPG_MAKE_MASK(next_leading_width) << (JPG_VLC_MAX_CODE_LEN-next_leading_width);
453     const uint32_t leading_mask = JPG_MAKE_MASK(leading_width) << (JPG_VLC_MAX_CODE_LEN-leading_width);
454 
455     uint32_t num_vlc_ops = 1 << direct_width;
456     uint32_t next_section, next_width, next_leading_pattern;
457     uint32_t offset;
458     uint32_t i;
459 
460     /* sanity - check this decode direct will not exceed the max code len */
461     IMG_ASSERT(next_leading_width <= JPG_VLC_MAX_CODE_LEN);
462 
463     /* set all VLC ops for this decode direct to invalid */
464     for (i = 0; i < num_vlc_ops; i++) {
465         table_ram[i] = (JPG_OP_CODE_INVALID << (JPG_INSTR_SHIFT_WIDTH+JPG_INSTR_OFFSET_WIDTH));
466     }
467 
468     /* iterate over code table and insert VLC ops until */
469     /* codes become too long for this iteration or we run out of codes */
470     for (i = 0; symbol_codes[i].code_length <= next_leading_width && i < num_codes; i++) {
471         /* only use codes that match the specified leading portion */
472         if ((((uint32_t)symbol_codes[i].code) & leading_mask) == leading_pattern) {
473             jpg_vlc_decode_direct_symbols(&symbol_codes[i], table_ram, direct_width, leading_width );
474         }
475     }
476     next_section = i;
477 
478     /* assign the longest code length for each remaining entry */
479     for (i = next_section; i < num_codes; i++) {
480         /* only use codes that match the specified leading portion */
481         if ((((uint32_t)symbol_codes[i].code) & leading_mask) == leading_pattern) {
482             /* enable the unused VLC bit to indicate this is not a command */
483             offset = jpg_vlc_get_offset(&symbol_codes[i], direct_width, leading_width);
484             table_ram[offset] = 0x8000 | (symbol_codes[i].code_length - next_leading_width);
485         }
486     }
487 
488     /* for the remaining (long) codes */
489     for (i = next_section; i < num_codes; i++) {
490         /* only use codes that match the specified leading portion */
491         if ((((uint32_t)symbol_codes[i].code) & leading_mask) == leading_pattern) {
492             /* if a command has not been written for this direct offset */
493             offset = jpg_vlc_get_offset(&symbol_codes[i], direct_width, leading_width);
494             if (table_ram[offset] & 0x8000) {
495                 /* write command the decode direct command */
496                 next_width = jpg_vlc_write_direct_command(
497                         &table_ram[offset],
498                         num_vlc_ops - offset );
499 
500                 next_leading_pattern = (uint32_t)symbol_codes[i].code & next_leading_mask;
501 
502                 /* decode direct recursive call */
503                 num_vlc_ops += jpg_vlc_decode_direct(
504                     &symbol_codes[i],
505                     num_codes - i,
506                     &table_ram[num_vlc_ops],
507                     next_width,
508                     next_leading_width,
509                     next_leading_pattern);
510             }
511         }
512     }
513     return num_vlc_ops;
514 }
515 
JPG_VLC_CompileTable(const vlc_symbol_code_jpeg * symbol_codes,const vlc_symbol_stats_jpeg * psSymbolStats,const uint32_t __maybe_unused ram_size,uint16_t * table_ram,vlc_table_stats_jpeg * ptable_stats)516 static void JPG_VLC_CompileTable(
517     const vlc_symbol_code_jpeg * symbol_codes,
518     const vlc_symbol_stats_jpeg * psSymbolStats,
519     const uint32_t __maybe_unused ram_size,
520     uint16_t * table_ram,
521     vlc_table_stats_jpeg * ptable_stats)
522 {
523     ptable_stats->initial_width = 5;
524     ptable_stats->initial_opcode = JPG_OP_DECODE_DIRECT;
525 
526     ptable_stats->size = jpg_vlc_decode_direct(
527         symbol_codes,
528         psSymbolStats->num_codes,
529         table_ram,
530         JPG_VLC_MAX_DIRECT_WIDTH,
531         0,
532         0);
533 
534     IMG_ASSERT( ptable_stats->size <= ram_size );
535 }
536 
compile_huffman_tables(context_JPEG_p ctx)537 static void compile_huffman_tables(context_JPEG_p ctx) {
538     VAStatus vaStatus = VA_STATUS_SUCCESS;
539     ctx->huffman_table_space = 1984;
540 
541     if (0 == psb_buffer_map(&ctx->vlc_packed_table, (unsigned char **)&ctx->huffman_table_RAM)) {
542         // Compile Tables
543         uint32_t table_class;
544         uint32_t table_id;
545         for (table_class = 0; table_class < TABLE_CLASS_NUM; table_class++) {
546             for (table_id = 0; table_id < JPEG_MAX_SETS_HUFFMAN_TABLES; table_id++) {
547                 if (ctx->symbol_stats[table_class][table_id].num_codes) {
548                     JPG_VLC_CompileTable(ctx->symbol_codes[table_class][table_id],
549                         &ctx->symbol_stats[table_class][table_id], ctx->huffman_table_space, ctx->huffman_table_RAM,
550                         &ctx->table_stats[table_class][table_id]);
551                     ctx->huffman_table_space -= ctx->table_stats[table_class][table_id].size;
552                     ctx->huffman_table_RAM += ctx->table_stats[table_class][table_id].size;
553                 }
554 
555             }
556         }
557         psb_buffer_unmap(&ctx->vlc_packed_table);
558     } else {
559         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
560         DEBUG_FAILURE;
561     }
562 
563 }
564 
tng__JPEG_process_picture_param(context_JPEG_p ctx,object_buffer_p obj_buffer)565 static VAStatus tng__JPEG_process_picture_param(context_JPEG_p ctx, object_buffer_p obj_buffer) {
566     VAStatus vaStatus;
567     ASSERT(obj_buffer->type == VAPictureParameterBufferType);
568     ASSERT(obj_buffer->num_elements == 1);
569     ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferJPEGBaseline));
570 
571     if ((obj_buffer->num_elements != 1) ||
572         (obj_buffer->size != sizeof(VAPictureParameterBufferJPEGBaseline))) {
573         return VA_STATUS_ERROR_UNKNOWN;
574     }
575 
576     /* Transfer ownership of VAPictureParameterBufferJPEGBaseline data */
577     if (ctx->pic_params) {
578         free(ctx->pic_params);
579     }
580     ctx->pic_params = (VAPictureParameterBufferJPEGBaseline *) obj_buffer->buffer_data;
581     ctx->display_picture_width = ctx->pic_params->picture_width;
582     ctx->display_picture_height = ctx->pic_params->picture_height;
583 
584     ctx->coded_picture_width = ( ctx->display_picture_width + 7 ) & ( ~7 );
585     ctx->coded_picture_height = ( ctx->display_picture_height + 7 ) & ( ~7 );
586     ctx->max_scalingH = 0;
587     ctx->max_scalingV = 0;
588 
589     uint8_t component_id;
590     for (component_id = 0; component_id < ctx->pic_params->num_components; component_id++) {
591         if (ctx->max_scalingH < ctx->pic_params->components->h_sampling_factor)
592             ctx->max_scalingH = ctx->pic_params->components->h_sampling_factor;
593         if (ctx->max_scalingV < ctx->pic_params->components->v_sampling_factor)
594             ctx->max_scalingV = ctx->pic_params->components->v_sampling_factor;
595     }
596 
597     ctx->MCU_width = (ctx->coded_picture_width + (8 * ctx->max_scalingH) - 1) / (8 * ctx->max_scalingH);
598     ctx->MCU_height = (ctx->coded_picture_height + (8 * ctx->max_scalingV) - 1) / (8 * ctx->max_scalingV);
599 
600     ctx->picture_width_mb = (ctx->coded_picture_width  + 15) / 16;
601     ctx->picture_height_mb = (ctx->coded_picture_height  + 15) / 16;
602     ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb;
603 
604 
605     obj_buffer->buffer_data = NULL;
606     obj_buffer->size = 0;
607 
608 
609     return VA_STATUS_SUCCESS;
610 }
611 
tng__JPEG_write_qmatrices(context_JPEG_p ctx)612 static void tng__JPEG_write_qmatrices(context_JPEG_p ctx) {
613     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
614     int i;
615 
616     psb_cmdbuf_rendec_start(cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET);
617 
618     for (i = 0; i < 16; i++) {
619         psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[0][i]);
620     }
621     for (i = 0; i < 16; i++) {
622         psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[1][i]);
623     }
624     for (i = 0; i < 16; i++) {
625         psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[2][i]);
626     }
627     for (i = 0; i < 16; i++) {
628         psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[3][i]);
629     }
630 
631     psb_cmdbuf_rendec_end(cmdbuf);
632 }
633 
tng__JPEG_process_iq_matrix(context_JPEG_p ctx,object_buffer_p obj_buffer)634 static VAStatus tng__JPEG_process_iq_matrix(context_JPEG_p ctx, object_buffer_p obj_buffer) {
635     VAIQMatrixBufferJPEGBaseline *qmatrix_data = (VAIQMatrixBufferJPEGBaseline *) obj_buffer->buffer_data;
636     ASSERT(obj_buffer->type == VAIQMatrixBufferType);
637     ASSERT(obj_buffer->num_elements == 1);
638     ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferJPEGBaseline));
639 
640     uint32_t dqt_ind;
641 
642     for (dqt_ind = 0; dqt_ind < 4; dqt_ind++) {
643         // Reorder Quant table for hardware
644         uint32_t table_ind = 0;
645         uint32_t rendec_table_ind = 0;
646         if (qmatrix_data->load_quantiser_table[dqt_ind]) {
647             while(table_ind < 64) {
648                 ctx->rendec_qmatrix[dqt_ind][rendec_table_ind] =
649                         (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind+3]] << 24) |
650                         (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind+2]] << 16) |
651                         (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind+1]] << 8) |
652                         (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind]]);
653 
654                 table_ind += 4;
655                 rendec_table_ind++;
656             }
657         }
658     }
659 
660     return VA_STATUS_SUCCESS;
661 }
662 
663 
tng__JPEG_write_huffman_tables(context_JPEG_p ctx)664 static void tng__JPEG_write_huffman_tables(context_JPEG_p ctx) {
665     uint32_t reg_value;
666     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
667 
668     // VLC Table
669     // Write a LLDMA Cmd to transfer VLD Table data
670     psb_cmdbuf_dma_write_cmdbuf(cmdbuf, &ctx->vlc_packed_table, 0,
671                                   ctx->vlctable_buffer_size, 0,
672                                   DMA_TYPE_VLC_TABLE);
673 
674     // Write Table addresses
675     psb_cmdbuf_reg_start_block(cmdbuf, 0);
676     reg_value = 0;
677     uint32_t table_address = 0;
678     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR0, table_address );
679     table_address += ctx->table_stats[0][0].size;
680     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR1, table_address );
681     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0 ), reg_value);
682 
683     reg_value = 0;
684     table_address += ctx->table_stats[0][1].size;
685     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR4, table_address );
686     table_address += ctx->table_stats[1][0].size;
687     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR5, table_address );
688     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2 ), reg_value);
689     psb_cmdbuf_reg_end_block(cmdbuf);
690 
691     // Write Initial Widths
692     psb_cmdbuf_reg_start_block(cmdbuf, 0);
693     reg_value = 0;
694     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH0,
695         ctx->table_stats[0][0].initial_width );
696     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH1,
697         ctx->table_stats[0][1].initial_width );
698     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH4,
699         ctx->table_stats[1][0].initial_width );
700     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH5,
701         ctx->table_stats[1][1].initial_width );
702     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0 ), reg_value);
703     psb_cmdbuf_reg_end_block(cmdbuf);
704 
705     // Write Initial Opcodes
706     psb_cmdbuf_reg_start_block(cmdbuf, 0);
707     reg_value = 0;
708     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE0,
709         ctx->table_stats[0][0].initial_opcode );
710     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE1,
711         ctx->table_stats[0][1].initial_opcode );
712     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE4,
713         ctx->table_stats[1][0].initial_opcode );
714     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE5,
715         ctx->table_stats[1][1].initial_opcode );
716     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0 ), reg_value);
717     psb_cmdbuf_reg_end_block(cmdbuf);
718 
719 }
720 
tng__JPEG_process_huffman_tables(context_JPEG_p ctx,object_buffer_p obj_buffer)721 static VAStatus tng__JPEG_process_huffman_tables(context_JPEG_p ctx, object_buffer_p obj_buffer) {
722 
723     VAHuffmanTableBufferJPEGBaseline *huff = (VAHuffmanTableBufferJPEGBaseline *) obj_buffer->buffer_data;
724     ASSERT(obj_buffer->type == VAHuffmanTableBufferType);
725     ASSERT(obj_buffer->num_elements == 1);
726     ASSERT(obj_buffer->size == sizeof(VAHuffmanTableBufferJPEGBaseline));
727 
728     uint32_t table_id;
729     for (table_id = 0; table_id < JPEG_MAX_SETS_HUFFMAN_TABLES; table_id++) {
730         // Find out the number of entries in the table
731         uint32_t table_entries = 0;
732         uint32_t bit_ind;
733         for (bit_ind = 0; bit_ind < 16; bit_ind++) {
734             table_entries += huff->huffman_table[table_id].num_dc_codes[bit_ind];
735         }
736 
737         ctx->symbol_codes[0][table_id] =(vlc_symbol_code_jpeg *)malloc(sizeof(vlc_symbol_code_jpeg) * table_entries);
738         // Parse huffman code sizes
739         uint32_t huff_ind = 0;
740         for (bit_ind = 0; bit_ind < 16; bit_ind++) {
741             uint32_t num_codes = huff->huffman_table[table_id].num_dc_codes[bit_ind];
742             while (num_codes) {
743                 ctx->symbol_codes[0][table_id][huff_ind].code_length = bit_ind + 1;
744                 num_codes--;
745                 huff_ind++;
746             }
747         }
748 
749         // Calculate huffman codes
750 
751         uint16_t code = 0;
752         uint8_t code_size = ctx->symbol_codes[0][table_id][0].code_length;
753         huff_ind = 0;
754 
755         while (huff_ind < table_entries) {
756             if (ctx->symbol_codes[0][table_id][huff_ind].code_length == code_size) {
757                 ctx->symbol_codes[0][table_id][huff_ind].code = code << ( 16 - code_size );
758                 huff_ind++;
759                 code++;
760             } else {
761                 code <<= 1;
762                 code_size++;
763             }
764         }
765 
766         // Create table of code values
767         uint32_t table_ind;
768         for (table_ind = 0; table_ind < table_entries; table_ind++) {
769             ctx->symbol_codes[0][table_id][table_ind].symbol = huff->huffman_table[table_id].dc_values[table_ind];
770         }
771 
772         // Store the number of codes in the table
773         ctx->symbol_stats[0][table_id].num_codes = table_entries;
774 
775         // for AC table
776         // Find out the number of entries in the table
777         table_entries = 0;
778         for (bit_ind = 0; bit_ind < 16; bit_ind++) {
779             table_entries += huff->huffman_table[table_id].num_ac_codes[bit_ind];
780         }
781 
782         // Allocate memory for huffman table codes
783         ctx->symbol_codes[1][table_id] = (vlc_symbol_code_jpeg *)malloc(sizeof(vlc_symbol_code_jpeg) * table_entries);
784 
785         // Parse huffman code sizes
786         huff_ind = 0;
787         for (bit_ind = 0; bit_ind < 16; bit_ind++) {
788             uint32_t num_codes = huff->huffman_table[table_id].num_ac_codes[bit_ind];
789             while (num_codes) {
790                 ctx->symbol_codes[1][table_id][huff_ind].code_length = bit_ind + 1;
791                 num_codes--;
792                 huff_ind++;
793             }
794         }
795 
796         // Calculate huffman codes
797         code = 0;
798         code_size = ctx->symbol_codes[1][table_id][0].code_length;
799         huff_ind = 0;
800         while (huff_ind < table_entries) {
801             if (ctx->symbol_codes[1][table_id][huff_ind].code_length == code_size) {
802                 ctx->symbol_codes[1][table_id][huff_ind].code = code << ( 16 - code_size );
803                 huff_ind++;
804                 code++;
805             } else {
806                 code <<= 1;
807                 code_size++;
808             }
809         }
810 
811         // Create table of code values
812         for (table_ind = 0; table_ind < table_entries; table_ind++) {
813             ctx->symbol_codes[1][table_id][table_ind].symbol = huff->huffman_table[table_id].ac_values[table_ind];;
814         }
815         // Store the number of codes in the table
816         ctx->symbol_stats[1][table_id].num_codes = table_entries;
817     }
818 
819     compile_huffman_tables(ctx);
820 
821     return VA_STATUS_SUCCESS;
822 }
823 
824 
tng__JPEG_set_operating_mode(context_JPEG_p ctx)825 static void tng__JPEG_set_operating_mode(context_JPEG_p ctx) {
826     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
827     ctx->obj_context->operating_mode = 0;
828 
829     REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, USE_EXT_ROW_STRIDE, 1 );
830     REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1 );
831     REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT,	1);
832 
833     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_CMDS, OPERATING_MODE ));
834 
835     psb_cmdbuf_rendec_write(cmdbuf, ctx->obj_context->operating_mode);
836 
837     psb_cmdbuf_rendec_end(cmdbuf);
838 
839 }
840 
tng__JPEG_set_reference_pictures(context_JPEG_p ctx)841 static void tng__JPEG_set_reference_pictures(context_JPEG_p ctx)
842 {
843     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
844     psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
845 
846     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
847 
848     uint32_t planr_size =  target_surface->chroma_offset;
849     psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs);
850     psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + planr_size);
851     psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + planr_size * 2);
852     // psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + planr_size * 3);
853     psb_cmdbuf_rendec_end(cmdbuf);
854 }
855 
tng__JPEG_set_ent_dec(context_JPEG_p ctx)856 static void tng__JPEG_set_ent_dec(context_JPEG_p ctx) {
857     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
858     uint32_t reg_value;
859 
860     psb_cmdbuf_reg_start_block(cmdbuf, 0);
861     reg_value = 0;
862     REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 0 );
863     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL ), reg_value);
864     psb_cmdbuf_reg_end_block(cmdbuf);
865 
866     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL ));
867     reg_value = 0;
868     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 0);
869     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
870     psb_cmdbuf_rendec_end(cmdbuf);
871 
872 }
873 
tng__JPEG_set_register(context_JPEG_p ctx,VASliceParameterBufferJPEGBaseline * slice_param)874 static void tng__JPEG_set_register(context_JPEG_p ctx, VASliceParameterBufferJPEGBaseline *slice_param) {
875     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
876     uint32_t reg_value;
877     const uint32_t num_MCUs = ctx->MCU_width * ctx->MCU_height;
878     const uint32_t num_MCUs_dec = slice_param->restart_interval ? min(slice_param->restart_interval, num_MCUs) :  num_MCUs;
879 
880     psb_cmdbuf_reg_start_block(cmdbuf, 0);
881     // CR_VEC_JPEG_FE_COMPONENTS
882     reg_value = 0;
883     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, MAX_V, ctx->max_scalingV);
884     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, MAX_H, ctx->max_scalingH);
885     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, FE_COMPONENTS,
886         slice_param->num_components);
887     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS ), reg_value);
888 
889     // CR_VEC_JPEG_FE_HEIGHT
890     reg_value = 0;
891     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_HEIGHT, FE_HEIGHT_MINUS1,
892         ctx->coded_picture_height - 1);
893     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_HEIGHT ), reg_value);
894 
895     // CR_VEC_JPEG_FE_RESTART_POS
896     reg_value = 0;
897     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_RESTART_POS), reg_value);
898 
899     // CR_VEC_JPEG_FE_WIDTH
900     reg_value = 0;
901     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_WIDTH, FE_WIDTH_MINUS1,
902         ctx->coded_picture_width - 1 );
903     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_WIDTH), reg_value);
904 
905     // CR_VEC_JPEG_FE_ENTROPY_CODING
906     reg_value = 0;
907     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, NUM_MCUS_LESS1, num_MCUs_dec - 1);
908 
909     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA3,
910         slice_param->components[3].ac_table_selector);
911     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD3,
912         slice_param->components[3].dc_table_selector);
913     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA2,
914         slice_param->components[2].ac_table_selector);
915     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD2,
916         slice_param->components[2].dc_table_selector);
917     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA1,
918         slice_param->components[1].ac_table_selector);
919     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD1,
920         slice_param->components[1].dc_table_selector );
921     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA0,
922         slice_param->components[0].ac_table_selector);
923     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD0,
924         slice_param->components[0].dc_table_selector);
925 
926     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING ), reg_value);
927 
928     // CR_VEC_JPEG_FE_SCALING
929     reg_value = 0;
930     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V3,
931         ctx->pic_params->components[3].v_sampling_factor);
932     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H3,
933         ctx->pic_params->components[3].h_sampling_factor );
934     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V2,
935         ctx->pic_params->components[2].v_sampling_factor);
936     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H2,
937         ctx->pic_params->components[2].h_sampling_factor );
938     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V1,
939         ctx->pic_params->components[1].v_sampling_factor );
940     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H1,
941         ctx->pic_params->components[1].h_sampling_factor );
942     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V0,
943         ctx->pic_params->components[0].v_sampling_factor );
944     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H0,
945         ctx->pic_params->components[0].h_sampling_factor );
946 
947     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING ), reg_value);
948     psb_cmdbuf_reg_end_block(cmdbuf);
949 
950     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_HEIGHT ));
951     // CR_VEC_JPEG_BE_HEIGHT
952     reg_value = 0;
953     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_HEIGHT, BE_HEIGHT_MINUS1,
954         ctx->coded_picture_height - 1);
955     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
956 
957     // CR_VEC_JPEG_BE_WIDTH
958     reg_value = 0;
959     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_WIDTH, BE_WIDTH_MINUS1, ctx->coded_picture_width - 1);
960     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
961 
962     // CR_VEC_JPEG_BE_QUANTISATION
963     reg_value = 0;
964     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ3,
965         ctx->pic_params->components[3].quantiser_table_selector);
966     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ2,
967         ctx->pic_params->components[2].quantiser_table_selector);
968     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ1,
969         ctx->pic_params->components[1].quantiser_table_selector);
970     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ0,
971         ctx->pic_params->components[0].quantiser_table_selector );
972     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
973 
974     // CR_VEC_JPEG_BE_CONTROL
975     reg_value = 0;
976     REGIO_WRITE_FIELD( reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_CONTROL, RGB, 0 );
977     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
978 
979     psb_cmdbuf_rendec_end(cmdbuf);
980 }
981 
tng__JPEG_begin_slice(context_DEC_p dec_ctx,VASliceParameterBufferBase __maybe_unused * vld_slice_param)982 static void tng__JPEG_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase __maybe_unused * vld_slice_param)
983 {
984     context_JPEG_p ctx = (context_JPEG_p)dec_ctx;
985 
986     dec_ctx->bits_offset = 0;
987     dec_ctx->SR_flags = CMD_ENABLE_RBDU_EXTRACTION;
988     *dec_ctx->cmd_params |=ctx->MCU_width * ctx->MCU_height;
989     *dec_ctx->slice_first_pic_last &= 0xfefe;
990     tng__JPEG_write_huffman_tables(ctx);
991     tng__JPEG_write_qmatrices(ctx);
992 }
993 
tng__JPEG_process_slice_data(context_DEC_p dec_ctx,VASliceParameterBufferBase * vld_slice_param)994 static void tng__JPEG_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param)
995 {
996     VASliceParameterBufferJPEGBaseline *slice_param = (VASliceParameterBufferJPEGBaseline *) vld_slice_param;
997     context_JPEG_p ctx = (context_JPEG_p)dec_ctx;
998 
999     tng__JPEG_set_operating_mode(ctx);
1000     tng__JPEG_set_reference_pictures(ctx);
1001     vld_dec_setup_alternative_frame(ctx->obj_context);
1002     tng__JPEG_set_ent_dec(ctx);
1003     tng__JPEG_set_register(ctx, slice_param);
1004 }
1005 
tng__JPEG_end_slice(context_DEC_p dec_ctx)1006 static void tng__JPEG_end_slice(context_DEC_p dec_ctx)
1007 {
1008     context_JPEG_p ctx = (context_JPEG_p)dec_ctx;
1009 
1010     ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH;
1011     ctx->obj_context->first_mb = 0;
1012     ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1);
1013     *(dec_ctx->slice_first_pic_last) = (ctx->obj_context->first_mb << 16) | ((ctx->obj_context->last_mb) & 0xfefe);
1014 
1015 }
1016 
tng_JPEG_BeginPicture(object_context_p obj_context)1017 static VAStatus tng_JPEG_BeginPicture(
1018     object_context_p obj_context) {
1019     INIT_CONTEXT_JPEG
1020 
1021     if (ctx->pic_params) {
1022         free(ctx->pic_params);
1023         ctx->pic_params = NULL;
1024     }
1025 
1026     return VA_STATUS_SUCCESS;
1027 }
1028 
tng_JPEG_process_buffer(context_DEC_p dec_ctx,object_buffer_p buffer)1029 static VAStatus tng_JPEG_process_buffer(
1030     context_DEC_p dec_ctx,
1031     object_buffer_p buffer) {
1032     context_JPEG_p ctx = (context_JPEG_p)dec_ctx;
1033     VAStatus vaStatus = VA_STATUS_SUCCESS;
1034     object_buffer_p obj_buffer = buffer;
1035 
1036     switch (obj_buffer->type) {
1037     case VAPictureParameterBufferType:
1038         drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_JPEG_RenderPicture got VAPictureParameterBuffer\n");
1039         vaStatus = tng__JPEG_process_picture_param(ctx, obj_buffer);
1040         DEBUG_FAILURE;
1041         break;
1042 
1043     case VAIQMatrixBufferType:
1044         drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_JPEG_RenderPicture got VAIQMatrixBufferType\n");
1045         vaStatus = tng__JPEG_process_iq_matrix(ctx, obj_buffer);
1046         DEBUG_FAILURE;
1047         break;
1048 
1049     case VAHuffmanTableBufferType:
1050         drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_JPEG_RenderPicture got VAIQMatrixBufferType\n");
1051         vaStatus = tng__JPEG_process_huffman_tables(ctx, obj_buffer);
1052         DEBUG_FAILURE;
1053         break;
1054 
1055     default:
1056         vaStatus = VA_STATUS_ERROR_UNKNOWN;
1057         DEBUG_FAILURE;
1058     }
1059 
1060     return vaStatus;
1061 }
1062 
tng_JPEG_EndPicture(object_context_p obj_context)1063 static VAStatus tng_JPEG_EndPicture(
1064     object_context_p obj_context) {
1065     INIT_CONTEXT_JPEG
1066 
1067     if (psb_context_flush_cmdbuf(ctx->obj_context)) {
1068         return VA_STATUS_ERROR_UNKNOWN;
1069     }
1070 
1071     if (ctx->pic_params) {
1072         free(ctx->pic_params);
1073         ctx->pic_params = NULL;
1074     }
1075 
1076     return VA_STATUS_SUCCESS;
1077 }
1078 
1079 struct format_vtable_s tng_JPEG_vtable = {
1080 queryConfigAttributes:
1081     tng_JPEG_QueryConfigAttributes,
1082 validateConfig:
1083     tng_JPEG_ValidateConfig,
1084 createContext:
1085     tng_JPEG_CreateContext,
1086 destroyContext:
1087     tng_JPEG_DestroyContext,
1088 beginPicture:
1089     tng_JPEG_BeginPicture,
1090 renderPicture:
1091     vld_dec_RenderPicture,
1092 endPicture:
1093     tng_JPEG_EndPicture
1094 };
1095