Module: Mesa Branch: main Commit: e1b8e4d7fc0c56496c1f6aa003cb60a44d701e32 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e1b8e4d7fc0c56496c1f6aa003cb60a44d701e32
Author: Honglei Huang <[email protected]> Date: Thu Dec 15 15:54:47 2022 +0800 virgl/video: Add support for jpeg decoding Implement for virgl jpeg decoding. Signed-off-by: Honglei Huang <[email protected]> Reviewed-by: Leo Liu <[email protected]> Reviewed-by: Boyuan Zhang <[email protected]> Reviewed-by: Daniel Almeida <[email protected]> Reviewed-by: Feng Jiang <[email protected]> Signed-off-by: Huang Rui <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22108> --- src/gallium/drivers/virgl/virgl_screen.c | 1 + src/gallium/drivers/virgl/virgl_video.c | 59 ++++++++++++++++++++++++++++- src/virtio/virtio-gpu/virgl_video_hw.h | 64 ++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index dc2f3706d26..3afb34526be 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -500,6 +500,7 @@ virgl_get_video_param(struct pipe_screen *screen, break; case PIPE_VIDEO_FORMAT_MPEG12: case PIPE_VIDEO_FORMAT_VC1: + case PIPE_VIDEO_FORMAT_JPEG: drv_supported = (entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM); break; default: diff --git a/src/gallium/drivers/virgl/virgl_video.c b/src/gallium/drivers/virgl/virgl_video.c index de8e6d15b70..7efd6f27b48 100644 --- a/src/gallium/drivers/virgl/virgl_video.c +++ b/src/gallium/drivers/virgl/virgl_video.c @@ -639,6 +639,60 @@ static int fill_vc1_picture_desc(const struct pipe_picture_desc *desc, return 0; } +static int fill_mjpeg_picture_desc(const struct pipe_picture_desc *desc, + union virgl_picture_desc *vdsc) +{ + unsigned i; + struct virgl_mjpeg_picture_desc *vmjpeg = &vdsc->mjpeg; + struct pipe_mjpeg_picture_desc *mjpeg = (struct pipe_mjpeg_picture_desc *)desc; + + fill_base_picture_desc(desc, &vmjpeg->base); + + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, picture_width); + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, picture_height); + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, crop_x); + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, crop_y); + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, crop_width); + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, crop_height); + + ITEM_SET(&vmjpeg->picture_parameter, &mjpeg->picture_parameter, num_components); + for (i = 0; i < mjpeg->picture_parameter.num_components; ++i) { + ITEM_SET(&vmjpeg->picture_parameter.components[i], &mjpeg->picture_parameter.components[i], component_id); + ITEM_SET(&vmjpeg->picture_parameter.components[i], &mjpeg->picture_parameter.components[i], h_sampling_factor); + ITEM_SET(&vmjpeg->picture_parameter.components[i], &mjpeg->picture_parameter.components[i], v_sampling_factor); + ITEM_SET(&vmjpeg->picture_parameter.components[i], &mjpeg->picture_parameter.components[i], quantiser_table_selector); + } + + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, slice_data_size); + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, slice_data_offset); + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, slice_data_flag); + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, slice_horizontal_position); + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, slice_vertical_position); + + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, num_components); + for (i = 0; i < mjpeg->slice_parameter.num_components; ++i) { + ITEM_SET(&vmjpeg->slice_parameter.components[i], &mjpeg->slice_parameter.components[i], component_selector); + ITEM_SET(&vmjpeg->slice_parameter.components[i], &mjpeg->slice_parameter.components[i], dc_table_selector); + ITEM_SET(&vmjpeg->slice_parameter.components[i], &mjpeg->slice_parameter.components[i], ac_table_selector); + } + + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, restart_interval); + ITEM_SET(&vmjpeg->slice_parameter, &mjpeg->slice_parameter, num_mcus); + + ITEM_CPY(&vmjpeg->quantization_table, &mjpeg->quantization_table, load_quantiser_table); + ITEM_CPY(&vmjpeg->quantization_table, &mjpeg->quantization_table, quantiser_table); + + for (i = 0; i < 2; ++i) { + ITEM_SET(&vmjpeg->huffman_table, &mjpeg->huffman_table, load_huffman_table[i]); + ITEM_CPY(&vmjpeg->huffman_table.table[i], &mjpeg->huffman_table.table[i], num_dc_codes); + ITEM_CPY(&vmjpeg->huffman_table.table[i], &mjpeg->huffman_table.table[i], dc_values); + ITEM_CPY(&vmjpeg->huffman_table.table[i], &mjpeg->huffman_table.table[i], num_ac_codes); + ITEM_CPY(&vmjpeg->huffman_table.table[i], &mjpeg->huffman_table.table[i], ac_values); + ITEM_CPY(&vmjpeg->huffman_table.table[i], &mjpeg->huffman_table.table[i], pad); + } + return 0; +} + #undef ITEM_SET #undef ITEM_CPY @@ -656,6 +710,8 @@ static int fill_picture_desc(const struct pipe_picture_desc *desc, return fill_mpeg12_picture_desc(desc, vdsc); case PIPE_VIDEO_FORMAT_VC1: return fill_vc1_picture_desc(desc, vdsc); + case PIPE_VIDEO_FORMAT_JPEG: + return fill_mjpeg_picture_desc(desc, vdsc); default: return -1; } @@ -910,7 +966,8 @@ virgl_video_create_codec(struct pipe_context *ctx, break; case PIPE_VIDEO_FORMAT_HEVC: case PIPE_VIDEO_FORMAT_MPEG12: - case PIPE_VIDEO_FORMAT_VC1: /* fall through */ + case PIPE_VIDEO_FORMAT_VC1: + case PIPE_VIDEO_FORMAT_JPEG: /* fall through */ default: break; } diff --git a/src/virtio/virtio-gpu/virgl_video_hw.h b/src/virtio/virtio-gpu/virgl_video_hw.h index a9b66ae5991..812fa1521c5 100644 --- a/src/virtio/virtio-gpu/virgl_video_hw.h +++ b/src/virtio/virtio-gpu/virgl_video_hw.h @@ -619,6 +619,69 @@ struct virgl_vc1_picture_desc uint32_t ref[2]; }; +struct virgl_mjpeg_picture_desc +{ + struct virgl_base_picture_desc base; + + struct + { + uint16_t picture_width; + uint16_t picture_height; + + struct { + uint8_t component_id; + uint8_t h_sampling_factor; + uint8_t v_sampling_factor; + uint8_t quantiser_table_selector; + } components[255]; + + uint8_t num_components; + uint16_t crop_x; + uint16_t crop_y; + uint16_t crop_width; + uint16_t crop_height; + } picture_parameter; + + struct + { + uint8_t load_quantiser_table[4]; + uint8_t quantiser_table[4][64]; + } quantization_table; + + struct + { + uint8_t load_huffman_table[2]; + + struct { + uint8_t num_dc_codes[16]; + uint8_t dc_values[12]; + uint8_t num_ac_codes[16]; + uint8_t ac_values[162]; + uint8_t pad[2]; + } table[2]; + } huffman_table; + + struct + { + unsigned slice_data_size; + unsigned slice_data_offset; + unsigned slice_data_flag; + unsigned slice_horizontal_position; + unsigned slice_vertical_position; + + struct { + uint8_t component_selector; + uint8_t dc_table_selector; + uint8_t ac_table_selector; + } components[4]; + + uint8_t num_components; + + uint16_t restart_interval; + unsigned num_mcus; + } slice_parameter; +}; + union virgl_picture_desc { struct virgl_base_picture_desc base; struct virgl_h264_picture_desc h264; @@ -626,6 +689,7 @@ union virgl_picture_desc { struct virgl_mpeg4_picture_desc mpeg4; struct virgl_mpeg12_picture_desc mpeg12; struct virgl_vc1_picture_desc vc1; + struct virgl_mjpeg_picture_desc mjpeg; struct virgl_h264_enc_picture_desc h264_enc; struct virgl_h265_enc_picture_desc h265_enc; };
