aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBoyuan Zhang <[email protected]>2018-10-17 15:03:24 -0400
committerLeo Liu <[email protected]>2018-10-23 08:50:02 -0400
commit4fc2368e3b77d8016798599fab6560d5d37702e1 (patch)
tree0b7705cd03d0830b001b42bcbaa95cdc00083462 /src
parentc7a5ef26adecb6454039ae0bed672cbd30dbede6 (diff)
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 <[email protected]> Reviewed-by: Leo Liu <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/va/picture.c13
-rw-r--r--src/gallium/state_trackers/va/picture_mjpeg.c142
-rw-r--r--src/gallium/state_trackers/va/va_private.h11
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);