1/************************************************************************** 2 * 3 * Copyright 2017 Advanced Micro Devices, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "va_private.h" 29 30void vlVaHandlePictureParameterBufferMJPEG(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 31{ 32 VAPictureParameterBufferJPEGBaseline *mjpeg = buf->data; 33 unsigned sf; 34 int i; 35 36 assert(buf->size >= sizeof(VAPictureParameterBufferJPEGBaseline) && buf->num_elements == 1); 37 38 context->desc.mjpeg.picture_parameter.picture_width = mjpeg->picture_width; 39 context->desc.mjpeg.picture_parameter.picture_height = mjpeg->picture_height; 40 41 for (i = 0; i < mjpeg->num_components; ++i) { 42 context->desc.mjpeg.picture_parameter.components[i].component_id = 43 mjpeg->components[i].component_id; 44 context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor = 45 mjpeg->components[i].h_sampling_factor; 46 context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor = 47 mjpeg->components[i].v_sampling_factor; 48 context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector = 49 mjpeg->components[i].quantiser_table_selector; 50 51 sf = mjpeg->components[i].h_sampling_factor << 4 | mjpeg->components[i].v_sampling_factor; 52 context->mjpeg.sampling_factor <<= 8; 53 context->mjpeg.sampling_factor |= sf; 54 } 55 56 context->desc.mjpeg.picture_parameter.num_components = mjpeg->num_components; 57} 58 59void vlVaHandleIQMatrixBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) 60{ 61 VAIQMatrixBufferJPEGBaseline *mjpeg = buf->data; 62 63 assert(buf->size >= sizeof(VAIQMatrixBufferJPEGBaseline) && buf->num_elements == 1); 64 65 memcpy(&context->desc.mjpeg.quantization_table.load_quantiser_table, mjpeg->load_quantiser_table, 4); 66 memcpy(&context->desc.mjpeg.quantization_table.quantiser_table, mjpeg->quantiser_table, 4 * 64); 67} 68 69void vlVaHandleHuffmanTableBufferType(vlVaContext *context, vlVaBuffer *buf) 70{ 71 VAHuffmanTableBufferJPEGBaseline *mjpeg = buf->data; 72 int i; 73 74 assert(buf->size >= sizeof(VASliceParameterBufferJPEGBaseline) && buf->num_elements == 1); 75 76 for (i = 0; i < 2; ++i) { 77 context->desc.mjpeg.huffman_table.load_huffman_table[i] = mjpeg->load_huffman_table[i]; 78 79 memcpy(&context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 80 mjpeg->huffman_table[i].num_dc_codes, 16); 81 memcpy(&context->desc.mjpeg.huffman_table.table[i].dc_values, 82 mjpeg->huffman_table[i].dc_values, 12); 83 memcpy(&context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 84 mjpeg->huffman_table[i].num_ac_codes, 16); 85 memcpy(&context->desc.mjpeg.huffman_table.table[i].ac_values, 86 mjpeg->huffman_table[i].ac_values, 162); 87 memcpy(&context->desc.mjpeg.huffman_table.table[i].pad, mjpeg->huffman_table[i].pad, 2); 88 } 89} 90 91void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) 92{ 93 VASliceParameterBufferJPEGBaseline *mjpeg = buf->data; 94 int i; 95 96 assert(buf->size >= sizeof(VASliceParameterBufferJPEGBaseline) && buf->num_elements == 1); 97 98 context->desc.mjpeg.slice_parameter.slice_data_size = mjpeg->slice_data_size; 99 context->desc.mjpeg.slice_parameter.slice_data_offset = mjpeg->slice_data_offset; 100 context->desc.mjpeg.slice_parameter.slice_data_flag = mjpeg->slice_data_flag; 101 context->desc.mjpeg.slice_parameter.slice_horizontal_position = mjpeg->slice_horizontal_position; 102 context->desc.mjpeg.slice_parameter.slice_vertical_position = mjpeg->slice_vertical_position; 103 104 for (i = 0; i < mjpeg->num_components; ++i) { 105 context->desc.mjpeg.slice_parameter.components[i].component_selector = 106 mjpeg->components[i].component_selector; 107 context->desc.mjpeg.slice_parameter.components[i].dc_table_selector = 108 mjpeg->components[i].dc_table_selector; 109 context->desc.mjpeg.slice_parameter.components[i].ac_table_selector = 110 mjpeg->components[i].ac_table_selector; 111 } 112 113 context->desc.mjpeg.slice_parameter.num_components = mjpeg->num_components; 114 context->desc.mjpeg.slice_parameter.restart_interval = mjpeg->restart_interval; 115 context->desc.mjpeg.slice_parameter.num_mcus = mjpeg->num_mcus; 116} 117 118void vlVaGetJpegSliceHeader(vlVaContext *context) 119{ 120 int size = 0, saved_size, len_pos, i; 121 uint16_t *bs; 122 uint8_t *p = context->mjpeg.slice_header; 123 124 /* SOI */ 125 p[size++] = 0xff; 126 p[size++] = 0xd8; 127 128 /* DQT */ 129 p[size++] = 0xff; 130 p[size++] = 0xdb; 131 132 len_pos = size++; 133 size++; 134 135 for (i = 0; i < 4; ++i) { 136 if (context->desc.mjpeg.quantization_table.load_quantiser_table[i] == 0) 137 continue; 138 139 p[size++] = i; 140 memcpy((p + size), &context->desc.mjpeg.quantization_table.quantiser_table[i], 64); 141 size += 64; 142 } 143 144 bs = (uint16_t*)&p[len_pos]; 145 *bs = util_bswap16(size - 4); 146 147 saved_size = size; 148 149 /* DHT */ 150 p[size++] = 0xff; 151 p[size++] = 0xc4; 152 153 len_pos = size++; 154 size++; 155 156 for (i = 0; i < 2; ++i) { 157 int num = 0, j; 158 159 if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) 160 continue; 161 162 p[size++] = 0x00 | i; 163 memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 16); 164 size += 16; 165 for (j = 0; j < 16; ++j) 166 num += context->desc.mjpeg.huffman_table.table[i].num_dc_codes[j]; 167 assert(num <= 12); 168 memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].dc_values, num); 169 size += num; 170 } 171 172 for (i = 0; i < 2; ++i) { 173 int num = 0, j; 174 175 if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) 176 continue; 177 178 p[size++] = 0x10 | i; 179 memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 16); 180 size += 16; 181 for (j = 0; j < 16; ++j) 182 num += context->desc.mjpeg.huffman_table.table[i].num_ac_codes[j]; 183 assert(num <= 162); 184 memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].ac_values, num); 185 size += num; 186 } 187 188 bs = (uint16_t*)&p[len_pos]; 189 *bs = util_bswap16(size - saved_size - 2); 190 191 saved_size = size; 192 193 /* DRI */ 194 if (context->desc.mjpeg.slice_parameter.restart_interval) { 195 p[size++] = 0xff; 196 p[size++] = 0xdd; 197 p[size++] = 0x00; 198 p[size++] = 0x04; 199 bs = (uint16_t*)&p[size++]; 200 *bs = util_bswap16(context->desc.mjpeg.slice_parameter.restart_interval); 201 saved_size = ++size; 202 } 203 204 /* SOF */ 205 p[size++] = 0xff; 206 p[size++] = 0xc0; 207 208 len_pos = size++; 209 size++; 210 211 p[size++] = 0x08; 212 213 bs = (uint16_t*)&p[size++]; 214 *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_height); 215 size++; 216 217 bs = (uint16_t*)&p[size++]; 218 *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_width); 219 size++; 220 221 p[size++] = context->desc.mjpeg.picture_parameter.num_components; 222 223 for (i = 0; i < context->desc.mjpeg.picture_parameter.num_components; ++i) { 224 p[size++] = context->desc.mjpeg.picture_parameter.components[i].component_id; 225 p[size++] = context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor << 4 | 226 context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor; 227 p[size++] = context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector; 228 } 229 230 bs = (uint16_t*)&p[len_pos]; 231 *bs = util_bswap16(size - saved_size - 2); 232 233 saved_size = size; 234 235 /* SOS */ 236 p[size++] = 0xff; 237 p[size++] = 0xda; 238 239 len_pos = size++; 240 size++; 241 242 p[size++] = context->desc.mjpeg.slice_parameter.num_components; 243 244 for (i = 0; i < context->desc.mjpeg.slice_parameter.num_components; ++i) { 245 p[size++] = context->desc.mjpeg.slice_parameter.components[i].component_selector; 246 p[size++] = context->desc.mjpeg.slice_parameter.components[i].dc_table_selector << 4 | 247 context->desc.mjpeg.slice_parameter.components[i].ac_table_selector; 248 } 249 250 p[size++] = 0x00; 251 p[size++] = 0x3f; 252 p[size++] = 0x00; 253 254 bs = (uint16_t*)&p[len_pos]; 255 *bs = util_bswap16(size - saved_size - 2); 256 257 context->mjpeg.slice_header_size = size; 258} 259