From 4fc2368e3b77d8016798599fab6560d5d37702e1 Mon Sep 17 00:00:00 2001 From: Boyuan Zhang Date: Wed, 17 Oct 2018 15:03:24 -0400 Subject: st/va: get mjpeg slice header Move the previous get_mjpeg_slice_heaeder function and eoi from "radeon/vcn" to "st/va". Signed-off-by: Boyuan Zhang Reviewed-by: Leo Liu --- src/gallium/state_trackers/va/picture.c | 13 ++- src/gallium/state_trackers/va/picture_mjpeg.c | 142 ++++++++++++++++++++++++++ src/gallium/state_trackers/va/va_private.h | 11 ++ 3 files changed, 164 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index e2cdb2b40cd..04d2da0afeb 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -259,11 +259,12 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) { enum pipe_video_format format; unsigned num_buffers = 0; - void * const *buffers[2]; - unsigned sizes[2]; + void * const *buffers[3]; + unsigned sizes[3]; static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 }; static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 }; static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d }; + static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 }; format = u_reduce_video_profile(context->templat.profile); switch (format) { @@ -301,6 +302,9 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) sizes[num_buffers++] = context->mpeg4.start_code_size; break; case PIPE_VIDEO_FORMAT_JPEG: + vlVaGetJpegSliceHeader(context); + buffers[num_buffers] = (void *)context->mjpeg.slice_header; + sizes[num_buffers++] = context->mjpeg.slice_header_size; break; case PIPE_VIDEO_FORMAT_VP9: vlVaDecoderVP9BitstreamHeader(context, buf); @@ -313,6 +317,11 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) sizes[num_buffers] = buf->size; ++num_buffers; + if (format == PIPE_VIDEO_FORMAT_JPEG) { + buffers[num_buffers] = (void *const)&eoi_jpeg; + sizes[num_buffers++] = sizeof(eoi_jpeg); + } + if (context->needs_begin_frame) { context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); diff --git a/src/gallium/state_trackers/va/picture_mjpeg.c b/src/gallium/state_trackers/va/picture_mjpeg.c index 396b7434425..defb0b546de 100644 --- a/src/gallium/state_trackers/va/picture_mjpeg.c +++ b/src/gallium/state_trackers/va/picture_mjpeg.c @@ -114,3 +114,145 @@ void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) context->desc.mjpeg.slice_parameter.restart_interval = mjpeg->restart_interval; context->desc.mjpeg.slice_parameter.num_mcus = mjpeg->num_mcus; } + +void vlVaGetJpegSliceHeader(vlVaContext *context) +{ + int size = 0, saved_size, len_pos, i; + uint16_t *bs; + uint8_t *p = context->mjpeg.slice_header; + + /* SOI */ + p[size++] = 0xff; + p[size++] = 0xd8; + + /* DQT */ + p[size++] = 0xff; + p[size++] = 0xdb; + + len_pos = size++; + size++; + + for (i = 0; i < 4; ++i) { + if (context->desc.mjpeg.quantization_table.load_quantiser_table[i] == 0) + continue; + + p[size++] = i; + memcpy((p + size), &context->desc.mjpeg.quantization_table.quantiser_table[i], 64); + size += 64; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - 4); + + saved_size = size; + + /* DHT */ + p[size++] = 0xff; + p[size++] = 0xc4; + + len_pos = size++; + size++; + + for (i = 0; i < 2; ++i) { + int num = 0, j; + + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x00 | i; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 16); + size += 16; + for (j = 0; j < 16; ++j) + num += context->desc.mjpeg.huffman_table.table[i].num_dc_codes[j]; + assert(num <= 12); + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].dc_values, num); + size += num; + } + + for (i = 0; i < 2; ++i) { + int num = 0, j; + + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x10 | i; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 16); + size += 16; + for (j = 0; j < 16; ++j) + num += context->desc.mjpeg.huffman_table.table[i].num_ac_codes[j]; + assert(num <= 162); + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].ac_values, num); + size += num; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* DRI */ + if (context->desc.mjpeg.slice_parameter.restart_interval) { + p[size++] = 0xff; + p[size++] = 0xdd; + p[size++] = 0x00; + p[size++] = 0x04; + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.slice_parameter.restart_interval); + saved_size = ++size; + } + + /* SOF */ + p[size++] = 0xff; + p[size++] = 0xc0; + + len_pos = size++; + size++; + + p[size++] = 0x08; + + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_height); + size++; + + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_width); + size++; + + p[size++] = context->desc.mjpeg.picture_parameter.num_components; + + for (i = 0; i < context->desc.mjpeg.picture_parameter.num_components; ++i) { + p[size++] = context->desc.mjpeg.picture_parameter.components[i].component_id; + p[size++] = context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor << 4 | + context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor; + p[size++] = context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* SOS */ + p[size++] = 0xff; + p[size++] = 0xda; + + len_pos = size++; + size++; + + p[size++] = context->desc.mjpeg.slice_parameter.num_components; + + for (i = 0; i < context->desc.mjpeg.slice_parameter.num_components; ++i) { + p[size++] = context->desc.mjpeg.slice_parameter.components[i].component_selector; + p[size++] = context->desc.mjpeg.slice_parameter.components[i].dc_table_selector << 4 | + context->desc.mjpeg.slice_parameter.components[i].ac_table_selector; + } + + p[size++] = 0x00; + p[size++] = 0x3f; + p[size++] = 0x00; + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + context->mjpeg.slice_header_size = size; +} diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index b19b66d2aa8..c4b49e30509 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -55,6 +55,14 @@ #define UINT_TO_PTR(x) ((void*)(uintptr_t)(x)) #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) +#define SOI 2 +#define DQT (4 + 4 * 65) +#define DHT (4 + 2 * 29 + 2 * 179) +#define DRI 6 +#define SOF (10 + 255 * 3) +#define SOS (8 + 4 * 2) +#define MAX_MJPEG_SLICE_HEADER_SIZE (SOI + DQT + DHT + DRI + SOF + SOS) + static inline unsigned handle_hash(void *key) { return PTR_TO_UINT(key); @@ -294,6 +302,8 @@ typedef struct { struct { unsigned sampling_factor; + uint8_t slice_header[MAX_MJPEG_SLICE_HEADER_SIZE]; + unsigned int slice_header_size; } mjpeg; struct vl_deint_filter *deint; @@ -430,6 +440,7 @@ void vlVaHandlePictureParameterBufferMPEG4(vlVaDriver *drv, vlVaContext *context void vlVaHandleIQMatrixBufferMPEG4(vlVaContext *context, vlVaBuffer *buf); void vlVaHandleSliceParameterBufferMPEG4(vlVaContext *context, vlVaBuffer *buf); void vlVaDecoderFixMPEG4Startcode(vlVaContext *context); +void vlVaGetJpegSliceHeader(vlVaContext *context); void vlVaHandlePictureParameterBufferHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); void vlVaHandleIQMatrixBufferHEVC(vlVaContext *context, vlVaBuffer *buf); void vlVaHandleSliceParameterBufferHEVC(vlVaContext *context, vlVaBuffer *buf); -- cgit v1.2.3