17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2017 Advanced Micro Devices, Inc. 47ec681f3Smrg * All Rights Reserved. 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the 87ec681f3Smrg * "Software"), to deal in the Software without restriction, including 97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 127ec681f3Smrg * the following conditions: 137ec681f3Smrg * 147ec681f3Smrg * The above copyright notice and this permission notice (including the 157ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 167ec681f3Smrg * of the Software. 177ec681f3Smrg * 187ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 207ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 217ec681f3Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 227ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 237ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 247ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 267ec681f3Smrg **************************************************************************/ 277ec681f3Smrg 287ec681f3Smrg#include "va_private.h" 297ec681f3Smrg 307ec681f3Smrgvoid vlVaHandlePictureParameterBufferMJPEG(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 317ec681f3Smrg{ 327ec681f3Smrg VAPictureParameterBufferJPEGBaseline *mjpeg = buf->data; 337ec681f3Smrg unsigned sf; 347ec681f3Smrg int i; 357ec681f3Smrg 367ec681f3Smrg assert(buf->size >= sizeof(VAPictureParameterBufferJPEGBaseline) && buf->num_elements == 1); 377ec681f3Smrg 387ec681f3Smrg context->desc.mjpeg.picture_parameter.picture_width = mjpeg->picture_width; 397ec681f3Smrg context->desc.mjpeg.picture_parameter.picture_height = mjpeg->picture_height; 407ec681f3Smrg 417ec681f3Smrg for (i = 0; i < mjpeg->num_components; ++i) { 427ec681f3Smrg context->desc.mjpeg.picture_parameter.components[i].component_id = 437ec681f3Smrg mjpeg->components[i].component_id; 447ec681f3Smrg context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor = 457ec681f3Smrg mjpeg->components[i].h_sampling_factor; 467ec681f3Smrg context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor = 477ec681f3Smrg mjpeg->components[i].v_sampling_factor; 487ec681f3Smrg context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector = 497ec681f3Smrg mjpeg->components[i].quantiser_table_selector; 507ec681f3Smrg 517ec681f3Smrg sf = mjpeg->components[i].h_sampling_factor << 4 | mjpeg->components[i].v_sampling_factor; 527ec681f3Smrg context->mjpeg.sampling_factor <<= 8; 537ec681f3Smrg context->mjpeg.sampling_factor |= sf; 547ec681f3Smrg } 557ec681f3Smrg 567ec681f3Smrg context->desc.mjpeg.picture_parameter.num_components = mjpeg->num_components; 577ec681f3Smrg} 587ec681f3Smrg 597ec681f3Smrgvoid vlVaHandleIQMatrixBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) 607ec681f3Smrg{ 617ec681f3Smrg VAIQMatrixBufferJPEGBaseline *mjpeg = buf->data; 627ec681f3Smrg 637ec681f3Smrg assert(buf->size >= sizeof(VAIQMatrixBufferJPEGBaseline) && buf->num_elements == 1); 647ec681f3Smrg 657ec681f3Smrg memcpy(&context->desc.mjpeg.quantization_table.load_quantiser_table, mjpeg->load_quantiser_table, 4); 667ec681f3Smrg memcpy(&context->desc.mjpeg.quantization_table.quantiser_table, mjpeg->quantiser_table, 4 * 64); 677ec681f3Smrg} 687ec681f3Smrg 697ec681f3Smrgvoid vlVaHandleHuffmanTableBufferType(vlVaContext *context, vlVaBuffer *buf) 707ec681f3Smrg{ 717ec681f3Smrg VAHuffmanTableBufferJPEGBaseline *mjpeg = buf->data; 727ec681f3Smrg int i; 737ec681f3Smrg 747ec681f3Smrg assert(buf->size >= sizeof(VASliceParameterBufferJPEGBaseline) && buf->num_elements == 1); 757ec681f3Smrg 767ec681f3Smrg for (i = 0; i < 2; ++i) { 777ec681f3Smrg context->desc.mjpeg.huffman_table.load_huffman_table[i] = mjpeg->load_huffman_table[i]; 787ec681f3Smrg 797ec681f3Smrg memcpy(&context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 807ec681f3Smrg mjpeg->huffman_table[i].num_dc_codes, 16); 817ec681f3Smrg memcpy(&context->desc.mjpeg.huffman_table.table[i].dc_values, 827ec681f3Smrg mjpeg->huffman_table[i].dc_values, 12); 837ec681f3Smrg memcpy(&context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 847ec681f3Smrg mjpeg->huffman_table[i].num_ac_codes, 16); 857ec681f3Smrg memcpy(&context->desc.mjpeg.huffman_table.table[i].ac_values, 867ec681f3Smrg mjpeg->huffman_table[i].ac_values, 162); 877ec681f3Smrg memcpy(&context->desc.mjpeg.huffman_table.table[i].pad, mjpeg->huffman_table[i].pad, 2); 887ec681f3Smrg } 897ec681f3Smrg} 907ec681f3Smrg 917ec681f3Smrgvoid vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) 927ec681f3Smrg{ 937ec681f3Smrg VASliceParameterBufferJPEGBaseline *mjpeg = buf->data; 947ec681f3Smrg int i; 957ec681f3Smrg 967ec681f3Smrg assert(buf->size >= sizeof(VASliceParameterBufferJPEGBaseline) && buf->num_elements == 1); 977ec681f3Smrg 987ec681f3Smrg context->desc.mjpeg.slice_parameter.slice_data_size = mjpeg->slice_data_size; 997ec681f3Smrg context->desc.mjpeg.slice_parameter.slice_data_offset = mjpeg->slice_data_offset; 1007ec681f3Smrg context->desc.mjpeg.slice_parameter.slice_data_flag = mjpeg->slice_data_flag; 1017ec681f3Smrg context->desc.mjpeg.slice_parameter.slice_horizontal_position = mjpeg->slice_horizontal_position; 1027ec681f3Smrg context->desc.mjpeg.slice_parameter.slice_vertical_position = mjpeg->slice_vertical_position; 1037ec681f3Smrg 1047ec681f3Smrg for (i = 0; i < mjpeg->num_components; ++i) { 1057ec681f3Smrg context->desc.mjpeg.slice_parameter.components[i].component_selector = 1067ec681f3Smrg mjpeg->components[i].component_selector; 1077ec681f3Smrg context->desc.mjpeg.slice_parameter.components[i].dc_table_selector = 1087ec681f3Smrg mjpeg->components[i].dc_table_selector; 1097ec681f3Smrg context->desc.mjpeg.slice_parameter.components[i].ac_table_selector = 1107ec681f3Smrg mjpeg->components[i].ac_table_selector; 1117ec681f3Smrg } 1127ec681f3Smrg 1137ec681f3Smrg context->desc.mjpeg.slice_parameter.num_components = mjpeg->num_components; 1147ec681f3Smrg context->desc.mjpeg.slice_parameter.restart_interval = mjpeg->restart_interval; 1157ec681f3Smrg context->desc.mjpeg.slice_parameter.num_mcus = mjpeg->num_mcus; 1167ec681f3Smrg} 1177ec681f3Smrg 1187ec681f3Smrgvoid vlVaGetJpegSliceHeader(vlVaContext *context) 1197ec681f3Smrg{ 1207ec681f3Smrg int size = 0, saved_size, len_pos, i; 1217ec681f3Smrg uint16_t *bs; 1227ec681f3Smrg uint8_t *p = context->mjpeg.slice_header; 1237ec681f3Smrg 1247ec681f3Smrg /* SOI */ 1257ec681f3Smrg p[size++] = 0xff; 1267ec681f3Smrg p[size++] = 0xd8; 1277ec681f3Smrg 1287ec681f3Smrg /* DQT */ 1297ec681f3Smrg p[size++] = 0xff; 1307ec681f3Smrg p[size++] = 0xdb; 1317ec681f3Smrg 1327ec681f3Smrg len_pos = size++; 1337ec681f3Smrg size++; 1347ec681f3Smrg 1357ec681f3Smrg for (i = 0; i < 4; ++i) { 1367ec681f3Smrg if (context->desc.mjpeg.quantization_table.load_quantiser_table[i] == 0) 1377ec681f3Smrg continue; 1387ec681f3Smrg 1397ec681f3Smrg p[size++] = i; 1407ec681f3Smrg memcpy((p + size), &context->desc.mjpeg.quantization_table.quantiser_table[i], 64); 1417ec681f3Smrg size += 64; 1427ec681f3Smrg } 1437ec681f3Smrg 1447ec681f3Smrg bs = (uint16_t*)&p[len_pos]; 1457ec681f3Smrg *bs = util_bswap16(size - 4); 1467ec681f3Smrg 1477ec681f3Smrg saved_size = size; 1487ec681f3Smrg 1497ec681f3Smrg /* DHT */ 1507ec681f3Smrg p[size++] = 0xff; 1517ec681f3Smrg p[size++] = 0xc4; 1527ec681f3Smrg 1537ec681f3Smrg len_pos = size++; 1547ec681f3Smrg size++; 1557ec681f3Smrg 1567ec681f3Smrg for (i = 0; i < 2; ++i) { 1577ec681f3Smrg int num = 0, j; 1587ec681f3Smrg 1597ec681f3Smrg if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) 1607ec681f3Smrg continue; 1617ec681f3Smrg 1627ec681f3Smrg p[size++] = 0x00 | i; 1637ec681f3Smrg memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 16); 1647ec681f3Smrg size += 16; 1657ec681f3Smrg for (j = 0; j < 16; ++j) 1667ec681f3Smrg num += context->desc.mjpeg.huffman_table.table[i].num_dc_codes[j]; 1677ec681f3Smrg assert(num <= 12); 1687ec681f3Smrg memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].dc_values, num); 1697ec681f3Smrg size += num; 1707ec681f3Smrg } 1717ec681f3Smrg 1727ec681f3Smrg for (i = 0; i < 2; ++i) { 1737ec681f3Smrg int num = 0, j; 1747ec681f3Smrg 1757ec681f3Smrg if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) 1767ec681f3Smrg continue; 1777ec681f3Smrg 1787ec681f3Smrg p[size++] = 0x10 | i; 1797ec681f3Smrg memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 16); 1807ec681f3Smrg size += 16; 1817ec681f3Smrg for (j = 0; j < 16; ++j) 1827ec681f3Smrg num += context->desc.mjpeg.huffman_table.table[i].num_ac_codes[j]; 1837ec681f3Smrg assert(num <= 162); 1847ec681f3Smrg memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].ac_values, num); 1857ec681f3Smrg size += num; 1867ec681f3Smrg } 1877ec681f3Smrg 1887ec681f3Smrg bs = (uint16_t*)&p[len_pos]; 1897ec681f3Smrg *bs = util_bswap16(size - saved_size - 2); 1907ec681f3Smrg 1917ec681f3Smrg saved_size = size; 1927ec681f3Smrg 1937ec681f3Smrg /* DRI */ 1947ec681f3Smrg if (context->desc.mjpeg.slice_parameter.restart_interval) { 1957ec681f3Smrg p[size++] = 0xff; 1967ec681f3Smrg p[size++] = 0xdd; 1977ec681f3Smrg p[size++] = 0x00; 1987ec681f3Smrg p[size++] = 0x04; 1997ec681f3Smrg bs = (uint16_t*)&p[size++]; 2007ec681f3Smrg *bs = util_bswap16(context->desc.mjpeg.slice_parameter.restart_interval); 2017ec681f3Smrg saved_size = ++size; 2027ec681f3Smrg } 2037ec681f3Smrg 2047ec681f3Smrg /* SOF */ 2057ec681f3Smrg p[size++] = 0xff; 2067ec681f3Smrg p[size++] = 0xc0; 2077ec681f3Smrg 2087ec681f3Smrg len_pos = size++; 2097ec681f3Smrg size++; 2107ec681f3Smrg 2117ec681f3Smrg p[size++] = 0x08; 2127ec681f3Smrg 2137ec681f3Smrg bs = (uint16_t*)&p[size++]; 2147ec681f3Smrg *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_height); 2157ec681f3Smrg size++; 2167ec681f3Smrg 2177ec681f3Smrg bs = (uint16_t*)&p[size++]; 2187ec681f3Smrg *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_width); 2197ec681f3Smrg size++; 2207ec681f3Smrg 2217ec681f3Smrg p[size++] = context->desc.mjpeg.picture_parameter.num_components; 2227ec681f3Smrg 2237ec681f3Smrg for (i = 0; i < context->desc.mjpeg.picture_parameter.num_components; ++i) { 2247ec681f3Smrg p[size++] = context->desc.mjpeg.picture_parameter.components[i].component_id; 2257ec681f3Smrg p[size++] = context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor << 4 | 2267ec681f3Smrg context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor; 2277ec681f3Smrg p[size++] = context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector; 2287ec681f3Smrg } 2297ec681f3Smrg 2307ec681f3Smrg bs = (uint16_t*)&p[len_pos]; 2317ec681f3Smrg *bs = util_bswap16(size - saved_size - 2); 2327ec681f3Smrg 2337ec681f3Smrg saved_size = size; 2347ec681f3Smrg 2357ec681f3Smrg /* SOS */ 2367ec681f3Smrg p[size++] = 0xff; 2377ec681f3Smrg p[size++] = 0xda; 2387ec681f3Smrg 2397ec681f3Smrg len_pos = size++; 2407ec681f3Smrg size++; 2417ec681f3Smrg 2427ec681f3Smrg p[size++] = context->desc.mjpeg.slice_parameter.num_components; 2437ec681f3Smrg 2447ec681f3Smrg for (i = 0; i < context->desc.mjpeg.slice_parameter.num_components; ++i) { 2457ec681f3Smrg p[size++] = context->desc.mjpeg.slice_parameter.components[i].component_selector; 2467ec681f3Smrg p[size++] = context->desc.mjpeg.slice_parameter.components[i].dc_table_selector << 4 | 2477ec681f3Smrg context->desc.mjpeg.slice_parameter.components[i].ac_table_selector; 2487ec681f3Smrg } 2497ec681f3Smrg 2507ec681f3Smrg p[size++] = 0x00; 2517ec681f3Smrg p[size++] = 0x3f; 2527ec681f3Smrg p[size++] = 0x00; 2537ec681f3Smrg 2547ec681f3Smrg bs = (uint16_t*)&p[len_pos]; 2557ec681f3Smrg *bs = util_bswap16(size - saved_size - 2); 2567ec681f3Smrg 2577ec681f3Smrg context->mjpeg.slice_header_size = size; 2587ec681f3Smrg} 259