mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-09 16:38:17 +02:00
virgl/video: Add support for H.264 encoding
Implement encoding framework and support H.264 encoding. Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Signed-off-by: Ming Xie <xieming@kylinos.cn> Signed-off-by: Liming Sun <sunliming@kylinos.cn> Reviewed-by: Gert Wollny <gert.wollny@collabora.com> Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18831>
This commit is contained in:
parent
69ed5f13d8
commit
d3a203c969
6 changed files with 423 additions and 18 deletions
|
|
@ -1706,6 +1706,19 @@ void virgl_encode_decode_bitstream(struct virgl_context *ctx,
|
|||
virgl_encoder_write_dword(ctx->cbuf, cdc->bs_size);
|
||||
}
|
||||
|
||||
void virgl_encode_encode_bitstream(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf,
|
||||
struct virgl_resource *tgt)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_ENCODE_BITSTREAM, 0, 5));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
|
||||
virgl_encoder_write_dword(ctx->cbuf, buf->handle);
|
||||
virgl_encoder_write_res(ctx, tgt);
|
||||
virgl_encoder_write_res(ctx, virgl_resource(cdc->desc_buffers[cdc->cur_buffer]));
|
||||
virgl_encoder_write_res(ctx, virgl_resource(cdc->feed_buffers[cdc->cur_buffer]));
|
||||
}
|
||||
|
||||
void virgl_encode_end_frame(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf)
|
||||
|
|
|
|||
|
|
@ -340,6 +340,11 @@ void virgl_encode_decode_bitstream(struct virgl_context *ctx,
|
|||
struct virgl_video_buffer *buf,
|
||||
void *desc, uint32_t desc_size);
|
||||
|
||||
void virgl_encode_encode_bitstream(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf,
|
||||
struct virgl_resource *tgt);
|
||||
|
||||
void virgl_encode_end_frame(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,50 @@
|
|||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Virgl video driver implementation.
|
||||
*
|
||||
* The virgl video driver acts as the frontend, and the virglrenderer acts as
|
||||
* the backend. Currently, the backend is implemented via VA-API, but it is
|
||||
* not limited to this.
|
||||
*
|
||||
* The relationship between vaSurface and video buffer objects:
|
||||
*
|
||||
* GUEST (Mesa) | HOST (Virglrenderer)
|
||||
* |
|
||||
* +------------+ | +------------+
|
||||
* | vaSurface | | | vaSurface | <------+
|
||||
* +------------+ | +------------+ |
|
||||
* | | |
|
||||
* +---------------------------+ | +-------------------------+ |
|
||||
* | virgl_video_buffer | | | vrend_video_buffer | |
|
||||
* | +-----------------------+ | | | +-------------------+ | |
|
||||
* | | vl_video_buffer | | | | | vrend_resource(s) | | |
|
||||
* | | +-------------------+ | |<--+-->| +-------------------+ | |
|
||||
* | | | virgl_resource(s) | | | | | +--------------------+ | |
|
||||
* | | +-------------------+ | | | | | virgl_video_buffer |-+--+
|
||||
* | +-----------------------+ | | | +--------------------+ |
|
||||
* +---------------------------+ | +-------------------------+
|
||||
*
|
||||
* The relationship between vaContext and video codec objects:
|
||||
*
|
||||
* GUEST (Mesa) | HOST (Virglrenderer)
|
||||
* |
|
||||
* +------------+ | +------------+
|
||||
* | vaContext | | | vaContext | <-------+
|
||||
* +------------+ | +------------+ |
|
||||
* | | |
|
||||
* +------------------------+ | +--------------------------+ |
|
||||
* | virgl_video_codec | <--+--> | vrend_video_codec | |
|
||||
* +------------------------+ | | +--------------------+ | |
|
||||
* | | | virgl_video_codec | -+--+
|
||||
* | | +--------------------+ |
|
||||
* | +--------------------------+
|
||||
*
|
||||
* @author Feng Jiang <jiangfeng@kylinos.cn>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
|
|
@ -149,6 +193,112 @@ static int fill_h264_picture_desc(const struct pipe_picture_desc *desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fill_h264_enc_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_h264_enc_picture_desc *vh264 = &vdsc->h264_enc;
|
||||
struct pipe_h264_enc_picture_desc *h264 = (struct pipe_h264_enc_picture_desc *)desc;
|
||||
|
||||
fill_base_picture_desc(desc, &vh264->base);
|
||||
|
||||
/* seq param */
|
||||
ITEM_SET(vh264, h264, seq.enc_constraint_set_flags);
|
||||
ITEM_SET(vh264, h264, seq.enc_frame_cropping_flag);
|
||||
ITEM_SET(vh264, h264, seq.enc_frame_crop_left_offset);
|
||||
ITEM_SET(vh264, h264, seq.enc_frame_crop_right_offset);
|
||||
ITEM_SET(vh264, h264, seq.enc_frame_crop_top_offset);
|
||||
ITEM_SET(vh264, h264, seq.enc_frame_crop_bottom_offset);
|
||||
ITEM_SET(vh264, h264, seq.pic_order_cnt_type);
|
||||
ITEM_SET(vh264, h264, seq.num_temporal_layers);
|
||||
ITEM_SET(vh264, h264, seq.vui_parameters_present_flag);
|
||||
ITEM_SET(vh264, h264, seq.vui_flags.aspect_ratio_info_present_flag);
|
||||
ITEM_SET(vh264, h264, seq.vui_flags.timing_info_present_flag);
|
||||
ITEM_SET(vh264, h264, seq.aspect_ratio_idc);
|
||||
ITEM_SET(vh264, h264, seq.sar_width);
|
||||
ITEM_SET(vh264, h264, seq.sar_height);
|
||||
ITEM_SET(vh264, h264, seq.num_units_in_tick);
|
||||
ITEM_SET(vh264, h264, seq.time_scale);
|
||||
|
||||
/* rate_ctrl */
|
||||
for (i = 0; i < 4; i++) {
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].rate_ctrl_method);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].target_bitrate);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].peak_bitrate);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].frame_rate_num);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].frame_rate_den);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].vbv_buffer_size);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].vbv_buf_lv);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].target_bits_picture);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].peak_bits_picture_integer);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].peak_bits_picture_fraction);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].fill_data_enable);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].skip_frame_enable);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].enforce_hrd);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].max_au_size);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].max_qp);
|
||||
ITEM_SET(vh264, h264, rate_ctrl[i].min_qp);
|
||||
}
|
||||
|
||||
/* motion_est */
|
||||
ITEM_SET(vh264, h264, motion_est.motion_est_quarter_pixel);
|
||||
ITEM_SET(vh264, h264, motion_est.enc_disable_sub_mode);
|
||||
ITEM_SET(vh264, h264, motion_est.lsmvert);
|
||||
ITEM_SET(vh264, h264, motion_est.enc_en_ime_overw_dis_subm);
|
||||
ITEM_SET(vh264, h264, motion_est.enc_ime_overw_dis_subm_no);
|
||||
ITEM_SET(vh264, h264, motion_est.enc_ime2_search_range_x);
|
||||
ITEM_SET(vh264, h264, motion_est.enc_ime2_search_range_y);
|
||||
|
||||
/* pic_ctrl */
|
||||
ITEM_SET(vh264, h264, pic_ctrl.enc_cabac_enable);
|
||||
ITEM_SET(vh264, h264, pic_ctrl.enc_cabac_init_idc);
|
||||
|
||||
ITEM_SET(vh264, h264, intra_idr_period);
|
||||
|
||||
ITEM_SET(vh264, h264, quant_i_frames);
|
||||
ITEM_SET(vh264, h264, quant_p_frames);
|
||||
ITEM_SET(vh264, h264, quant_b_frames);
|
||||
|
||||
ITEM_SET(vh264, h264, picture_type);
|
||||
ITEM_SET(vh264, h264, frame_num);
|
||||
ITEM_SET(vh264, h264, frame_num_cnt);
|
||||
ITEM_SET(vh264, h264, p_remain);
|
||||
ITEM_SET(vh264, h264, i_remain);
|
||||
ITEM_SET(vh264, h264, idr_pic_id);
|
||||
ITEM_SET(vh264, h264, gop_cnt);
|
||||
ITEM_SET(vh264, h264, pic_order_cnt);
|
||||
ITEM_SET(vh264, h264, num_ref_idx_l0_active_minus1);
|
||||
ITEM_SET(vh264, h264, num_ref_idx_l1_active_minus1);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
ITEM_SET(vh264, h264, ref_idx_l0_list[i]);
|
||||
ITEM_SET(vh264, h264, ref_idx_l1_list[i]);
|
||||
ITEM_SET(vh264, h264, l0_is_long_term[i]);
|
||||
ITEM_SET(vh264, h264, l1_is_long_term[i]);
|
||||
}
|
||||
|
||||
ITEM_SET(vh264, h264, gop_size);
|
||||
|
||||
ITEM_SET(vh264, h264, quality_modes.level);
|
||||
ITEM_SET(vh264, h264, quality_modes.preset_mode);
|
||||
ITEM_SET(vh264, h264, quality_modes.pre_encode_mode);
|
||||
ITEM_SET(vh264, h264, quality_modes.vbaq_mode);
|
||||
|
||||
ITEM_SET(vh264, h264, not_referenced);
|
||||
ITEM_SET(vh264, h264, is_ltr);
|
||||
ITEM_SET(vh264, h264, ltr_index);
|
||||
ITEM_SET(vh264, h264, enable_vui);
|
||||
|
||||
ITEM_SET(vh264, h264, num_slice_descriptors);
|
||||
for (i = 0; i < vh264->num_slice_descriptors; i++) {
|
||||
ITEM_SET(vh264, h264, slices_descriptors[i].macroblock_address);
|
||||
ITEM_SET(vh264, h264, slices_descriptors[i].num_macroblocks);
|
||||
ITEM_SET(vh264, h264, slices_descriptors[i].slice_type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_h265_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
|
|
@ -312,6 +462,17 @@ static int fill_picture_desc(const struct pipe_picture_desc *desc,
|
|||
}
|
||||
}
|
||||
|
||||
static int fill_enc_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
switch (u_reduce_video_profile(desc->profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
return fill_h264_enc_picture_desc(desc, vdsc);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void virgl_video_begin_frame(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *target,
|
||||
struct pipe_picture_desc *picture)
|
||||
|
|
@ -319,6 +480,9 @@ static void virgl_video_begin_frame(struct pipe_video_codec *codec,
|
|||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_video_buffer *vbuf = virgl_video_buffer(target);
|
||||
|
||||
if (codec->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
|
||||
fill_enc_picture_desc(picture, &vcdc->desc);
|
||||
|
||||
virgl_encode_begin_frame(vcdc->vctx, vcdc, vbuf);
|
||||
}
|
||||
|
||||
|
|
@ -390,6 +554,51 @@ static void virgl_video_decode_bitstream(struct pipe_video_codec *codec,
|
|||
virgl_encode_decode_bitstream(vctx, vcdc, vbuf, &vdsc, sizeof(vdsc));
|
||||
}
|
||||
|
||||
static void virgl_video_encode_bitstream(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *source,
|
||||
struct pipe_resource *target,
|
||||
void **feedback)
|
||||
{
|
||||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_context *vctx = vcdc->vctx;
|
||||
struct virgl_screen *vs = virgl_screen(vctx->base.screen);
|
||||
struct virgl_resource *vres;
|
||||
struct virgl_video_encode_feedback *fb;
|
||||
struct pipe_transfer *xfer = NULL;
|
||||
void *ptr;
|
||||
|
||||
/* Transfer picture desc */
|
||||
vres = virgl_resource(vcdc->desc_buffers[vcdc->cur_buffer]);
|
||||
vs->vws->resource_wait(vs->vws, vres->hw_res);
|
||||
ptr = pipe_buffer_map(&vctx->base, vcdc->desc_buffers[vcdc->cur_buffer],
|
||||
PIPE_MAP_WRITE, &xfer);
|
||||
if (!ptr)
|
||||
return;
|
||||
memcpy(ptr, &vcdc->desc, sizeof(vcdc->desc));
|
||||
pipe_buffer_unmap(&vctx->base, xfer);
|
||||
|
||||
/* Init feedback */
|
||||
vres = virgl_resource(vcdc->feed_buffers[vcdc->cur_buffer]);
|
||||
vs->vws->resource_wait(vs->vws, vres->hw_res);
|
||||
fb = pipe_buffer_map(&vctx->base, vcdc->feed_buffers[vcdc->cur_buffer],
|
||||
PIPE_MAP_WRITE, &xfer);
|
||||
if (!fb)
|
||||
return;
|
||||
fb->stat = VIRGL_VIDEO_ENCODE_STAT_NOT_STARTED;
|
||||
fb->coded_size = 0;
|
||||
pipe_buffer_unmap(&vctx->base, xfer);
|
||||
*feedback = vres;
|
||||
|
||||
/*
|
||||
* These objects do not need to be transferred manually:
|
||||
* source - corresponds to VASurface in VA-API
|
||||
* target - corresponds to VACodedBuffer in VA-API
|
||||
*/
|
||||
|
||||
virgl_encode_encode_bitstream(vctx, vcdc, virgl_video_buffer(source),
|
||||
virgl_resource(target));
|
||||
}
|
||||
|
||||
static void virgl_video_end_frame(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *target,
|
||||
struct pipe_picture_desc *picture)
|
||||
|
|
@ -406,16 +615,43 @@ static void virgl_video_end_frame(struct pipe_video_codec *codec,
|
|||
|
||||
static void virgl_video_flush(struct pipe_video_codec *codec)
|
||||
{
|
||||
(void)codec;
|
||||
struct pipe_context *ctx = codec->context;
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
|
||||
ctx->flush(ctx, &fence, 0);
|
||||
if (fence) {
|
||||
ctx->screen->fence_finish(ctx->screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
|
||||
ctx->screen->fence_reference(ctx->screen, &fence, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void virgl_video_get_feedback(struct pipe_video_codec *codec,
|
||||
void *feedback,
|
||||
unsigned *size)
|
||||
{
|
||||
(void)codec;
|
||||
(void)feedback;
|
||||
(void)size;
|
||||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_context *vctx = vcdc->vctx;
|
||||
struct virgl_screen *vs = virgl_screen(vctx->base.screen);
|
||||
struct virgl_resource *vres = feedback;
|
||||
struct virgl_video_encode_feedback *fb;
|
||||
struct pipe_transfer *xfer;
|
||||
|
||||
if (!feedback || !size)
|
||||
return;
|
||||
|
||||
vs->vws->resource_wait(vs->vws, vres->hw_res);
|
||||
fb = pipe_buffer_map(&vctx->base, &vres->b, PIPE_MAP_READ, &xfer);
|
||||
if (!fb)
|
||||
return;
|
||||
if (fb->stat == VIRGL_VIDEO_ENCODE_STAT_SUCCESS) {
|
||||
*size = fb->coded_size;
|
||||
} else {
|
||||
*size = 0;
|
||||
if (virgl_debug & VIRGL_DEBUG_VIDEO) {
|
||||
debug_printf("unexpected encode feedback: %u\n", fb->stat);
|
||||
}
|
||||
}
|
||||
pipe_buffer_unmap(&vctx->base, xfer);
|
||||
}
|
||||
|
||||
static void virgl_video_destroy_codec(struct pipe_video_codec *codec)
|
||||
|
|
@ -425,7 +661,11 @@ static void virgl_video_destroy_codec(struct pipe_video_codec *codec)
|
|||
struct virgl_context *vctx = virgl_context(vcdc->base.context);
|
||||
|
||||
for (i = 0; i < VIRGL_VIDEO_CODEC_BUF_NUM; i++) {
|
||||
pipe_resource_reference(&vcdc->bs_buffers[i], NULL);
|
||||
if (codec->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
|
||||
pipe_resource_reference(&vcdc->bs_buffers[i], NULL);
|
||||
} else {
|
||||
pipe_resource_reference(&vcdc->feed_buffers[i], NULL);
|
||||
}
|
||||
pipe_resource_reference(&vcdc->desc_buffers[i], NULL);
|
||||
}
|
||||
|
||||
|
|
@ -451,11 +691,6 @@ virgl_video_create_codec(struct pipe_context *ctx,
|
|||
templ->chroma_format, templ->width, templ->height,
|
||||
templ->max_references, templ->expect_chunked_decode);
|
||||
|
||||
/* encode: not supported now */
|
||||
if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
|
||||
return NULL;
|
||||
|
||||
/* decode: */
|
||||
switch (u_reduce_video_profile(templ->profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG4: /* fall through */
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
|
|
@ -480,6 +715,7 @@ virgl_video_create_codec(struct pipe_context *ctx,
|
|||
vcdc->base.begin_frame = virgl_video_begin_frame;
|
||||
vcdc->base.decode_macroblock = virgl_video_decode_macroblock;
|
||||
vcdc->base.decode_bitstream = virgl_video_decode_bitstream;
|
||||
vcdc->base.encode_bitstream = virgl_video_encode_bitstream;
|
||||
vcdc->base.end_frame = virgl_video_end_frame;
|
||||
vcdc->base.flush = virgl_video_flush;
|
||||
vcdc->base.get_feedback = virgl_video_get_feedback;
|
||||
|
|
@ -487,9 +723,15 @@ virgl_video_create_codec(struct pipe_context *ctx,
|
|||
vcdc->bs_size = 0;
|
||||
vcdc->cur_buffer = 0;
|
||||
for (i = 0; i < VIRGL_VIDEO_CODEC_BUF_NUM; i++) {
|
||||
vcdc->bs_buffers[i] = pipe_buffer_create(ctx->screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING,
|
||||
BS_BUF_DEFAULT_SIZE(width, height));
|
||||
if (templ->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
|
||||
vcdc->bs_buffers[i] = pipe_buffer_create(ctx->screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING,
|
||||
BS_BUF_DEFAULT_SIZE(width, height));
|
||||
} else {
|
||||
vcdc->feed_buffers[i] = pipe_buffer_create(ctx->screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING,
|
||||
sizeof(struct virgl_video_encode_feedback));
|
||||
}
|
||||
|
||||
vcdc->desc_buffers[i] = pipe_buffer_create(ctx->screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "virgl_context.h"
|
||||
#include "vl/vl_video_buffer.h"
|
||||
#include "pipe/p_video_codec.h"
|
||||
#include "virtio-gpu/virgl_video_hw.h"
|
||||
|
||||
#define VIRGL_VIDEO_CODEC_BUF_NUM 10
|
||||
|
||||
|
|
@ -47,11 +48,13 @@ struct virgl_video_codec {
|
|||
|
||||
uint32_t handle;
|
||||
struct virgl_context *vctx;
|
||||
union virgl_picture_desc desc;
|
||||
|
||||
uint32_t bs_size; /* size of data in bs_buffer */
|
||||
uint32_t cur_buffer; /* index of current bs/desc buffer */
|
||||
struct pipe_resource *bs_buffers[VIRGL_VIDEO_CODEC_BUF_NUM];
|
||||
struct pipe_resource *desc_buffers[VIRGL_VIDEO_CODEC_BUF_NUM];
|
||||
struct pipe_resource *feed_buffers[VIRGL_VIDEO_CODEC_BUF_NUM];
|
||||
};
|
||||
|
||||
struct virgl_video_buffer {
|
||||
|
|
|
|||
|
|
@ -720,7 +720,7 @@ enum vrend_tweak_type {
|
|||
#define VIRGL_CREATE_VIDEO_CODEC_MAX_REF 8
|
||||
|
||||
/* VIRGL_CCMD_DESTROY_VIDEO_CODEC */
|
||||
#define VIRGL_DESTROY_VIDEO_CODEC_SIZE 1
|
||||
#define VIRGL_DESTROY_VIDEO_CODEC_MIN_SIZE 1
|
||||
#define VIRGL_DESTROY_VIDEO_CODEC_HANDLE 1
|
||||
|
||||
/* VIRGL_CCMD_CREATE_VIDEO_BUFFER */
|
||||
|
|
@ -732,18 +732,18 @@ enum vrend_tweak_type {
|
|||
#define VIRGL_CREATE_VIDEO_BUFFER_RES_BASE 5
|
||||
|
||||
/* VIRGL_CCMD_DESTROY_VIDEO_BUFFER */
|
||||
#define VIRGL_DESTROY_VIDEO_BUFFER_SIZE 1
|
||||
#define VIRGL_DESTROY_VIDEO_BUFFER_MIN_SIZE 1
|
||||
#define VIRGL_DESTROY_VIDEO_BUFFER_HANDLE 1
|
||||
|
||||
/* VIRGL_CCMD_BEGIN_FRAME */
|
||||
#define VIRGL_BEGIN_FRAME_SIZE 2
|
||||
#define VIRGL_BEGIN_FRAME_MIN_SIZE 2
|
||||
#define VIRGL_BEGIN_FRAME_CDC_HANDLE 1
|
||||
#define VIRGL_BEGIN_FRAME_TGT_HANDLE 2
|
||||
|
||||
/* VIRGL_CCMD_DECODE_MACROBLOCK */
|
||||
|
||||
/* VIRGL_CCMD_DECODE_BITSTREAM */
|
||||
#define VIRGL_DECODE_BS_SIZE 5
|
||||
#define VIRGL_DECODE_BS_MIN_SIZE 5
|
||||
#define VIRGL_DECODE_BS_CDC_HANDLE 1
|
||||
#define VIRGL_DECODE_BS_TGT_HANDLE 2
|
||||
#define VIRGL_DECODE_BS_DSC_HANDLE 3
|
||||
|
|
@ -751,9 +751,15 @@ enum vrend_tweak_type {
|
|||
#define VIRGL_DECODE_BS_BUF_SIZE 5
|
||||
|
||||
/* VIRGL_CCMD_ENCODE_BITSTREAM */
|
||||
#define VIRGL_ENCODE_BS_MIN_SIZE 5
|
||||
#define VIRGL_ENCODE_BS_CDC_HANDLE 1
|
||||
#define VIRGL_ENCODE_BS_SRC_HANDLE 2
|
||||
#define VIRGL_ENCODE_BS_DEST_HANDLE 3
|
||||
#define VIRGL_ENCODE_BS_DESC_HANDLE 4
|
||||
#define VIRGL_ENCODE_BS_FEED_HANDLE 5
|
||||
|
||||
/* VIRGL_CCMD_END_FRAME */
|
||||
#define VIRGL_END_FRAME_SIZE 2
|
||||
#define VIRGL_END_FRAME_MIN_SIZE 2
|
||||
#define VIRGL_END_FRAME_CDC_HANDLE 1
|
||||
#define VIRGL_END_FRAME_TGT_HANDLE 2
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ struct virgl_base_picture_desc {
|
|||
|
||||
};
|
||||
|
||||
struct virgl_enc_quality_modes {
|
||||
uint32_t level;
|
||||
uint32_t preset_mode;
|
||||
uint32_t pre_encode_mode;
|
||||
uint32_t vbaq_mode;
|
||||
};
|
||||
|
||||
/* H.264 sequence parameter set */
|
||||
struct virgl_h264_sps {
|
||||
uint8_t level_idc;
|
||||
|
|
@ -140,6 +147,120 @@ struct virgl_h264_picture_desc {
|
|||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
struct virgl_h264_enc_seq_param
|
||||
{
|
||||
uint32_t enc_constraint_set_flags;
|
||||
uint32_t enc_frame_cropping_flag;
|
||||
uint32_t enc_frame_crop_left_offset;
|
||||
uint32_t enc_frame_crop_right_offset;
|
||||
uint32_t enc_frame_crop_top_offset;
|
||||
uint32_t enc_frame_crop_bottom_offset;
|
||||
uint32_t pic_order_cnt_type;
|
||||
uint32_t num_temporal_layers;
|
||||
uint32_t vui_parameters_present_flag;
|
||||
struct {
|
||||
uint32_t aspect_ratio_info_present_flag: 1;
|
||||
uint32_t timing_info_present_flag: 1;
|
||||
uint32_t reserved:30;
|
||||
} vui_flags;
|
||||
uint32_t aspect_ratio_idc;
|
||||
uint32_t sar_width;
|
||||
uint32_t sar_height;
|
||||
uint32_t num_units_in_tick;
|
||||
uint32_t time_scale;
|
||||
};
|
||||
|
||||
struct virgl_h264_enc_rate_control
|
||||
{
|
||||
uint32_t target_bitrate;
|
||||
uint32_t peak_bitrate;
|
||||
uint32_t frame_rate_num;
|
||||
uint32_t frame_rate_den;
|
||||
uint32_t vbv_buffer_size;
|
||||
uint32_t vbv_buf_lv;
|
||||
uint32_t target_bits_picture;
|
||||
uint32_t peak_bits_picture_integer;
|
||||
uint32_t peak_bits_picture_fraction;
|
||||
uint32_t fill_data_enable;
|
||||
uint32_t skip_frame_enable;
|
||||
uint32_t enforce_hrd;
|
||||
uint32_t max_au_size;
|
||||
uint32_t max_qp;
|
||||
uint32_t min_qp;
|
||||
|
||||
uint8_t rate_ctrl_method; /* see enum pipe_h2645_enc_rate_control_method */
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
|
||||
struct virgl_h264_enc_motion_estimation
|
||||
{
|
||||
uint32_t motion_est_quarter_pixel;
|
||||
uint32_t enc_disable_sub_mode;
|
||||
uint32_t lsmvert;
|
||||
uint32_t enc_en_ime_overw_dis_subm;
|
||||
uint32_t enc_ime_overw_dis_subm_no;
|
||||
uint32_t enc_ime2_search_range_x;
|
||||
uint32_t enc_ime2_search_range_y;
|
||||
};
|
||||
|
||||
struct virgl_h264_enc_pic_control
|
||||
{
|
||||
uint32_t enc_cabac_enable;
|
||||
uint32_t enc_cabac_init_idc;
|
||||
};
|
||||
|
||||
struct virgl_h264_slice_descriptor
|
||||
{
|
||||
uint32_t macroblock_address;
|
||||
uint32_t num_macroblocks;
|
||||
|
||||
uint8_t slice_type; /* see enum pipe_h264_slice_type */
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
|
||||
struct virgl_h264_enc_picture_desc
|
||||
{
|
||||
struct virgl_base_picture_desc base;
|
||||
|
||||
struct virgl_h264_enc_seq_param seq;
|
||||
struct virgl_h264_enc_rate_control rate_ctrl[4];
|
||||
struct virgl_h264_enc_motion_estimation motion_est;
|
||||
struct virgl_h264_enc_pic_control pic_ctrl;
|
||||
|
||||
uint32_t intra_idr_period;
|
||||
|
||||
uint32_t quant_i_frames;
|
||||
uint32_t quant_p_frames;
|
||||
uint32_t quant_b_frames;
|
||||
|
||||
uint32_t frame_num;
|
||||
uint32_t frame_num_cnt;
|
||||
uint32_t p_remain;
|
||||
uint32_t i_remain;
|
||||
uint32_t idr_pic_id;
|
||||
uint32_t gop_cnt;
|
||||
uint32_t pic_order_cnt;
|
||||
uint32_t num_ref_idx_l0_active_minus1;
|
||||
uint32_t num_ref_idx_l1_active_minus1;
|
||||
uint32_t ref_idx_l0_list[32];
|
||||
uint8_t l0_is_long_term[32];
|
||||
uint32_t ref_idx_l1_list[32];
|
||||
uint8_t l1_is_long_term[32];
|
||||
uint32_t gop_size;
|
||||
struct virgl_enc_quality_modes quality_modes;
|
||||
|
||||
uint32_t num_slice_descriptors;
|
||||
struct virgl_h264_slice_descriptor slices_descriptors[128];
|
||||
|
||||
uint8_t picture_type; /* see enum pipe_h2645_enc_picture_type */
|
||||
uint8_t not_referenced;
|
||||
uint8_t is_ltr;
|
||||
uint8_t enable_vui;
|
||||
|
||||
uint32_t ltr_index;
|
||||
};
|
||||
|
||||
|
||||
struct virgl_h265_sps
|
||||
{
|
||||
uint32_t pic_width_in_luma_samples;
|
||||
|
|
@ -305,6 +426,21 @@ union virgl_picture_desc {
|
|||
struct virgl_h264_picture_desc h264;
|
||||
struct virgl_h265_picture_desc h265;
|
||||
struct virgl_mpeg4_picture_desc mpeg4;
|
||||
struct virgl_h264_enc_picture_desc h264_enc;
|
||||
};
|
||||
|
||||
enum virgl_video_encode_stat {
|
||||
VIRGL_VIDEO_ENCODE_STAT_NOT_STARTED = 0,
|
||||
VIRGL_VIDEO_ENCODE_STAT_IN_PROGRESS,
|
||||
VIRGL_VIDEO_ENCODE_STAT_SUCCESS,
|
||||
VIRGL_VIDEO_ENCODE_STAT_FAILURE,
|
||||
};
|
||||
|
||||
struct virgl_video_encode_feedback {
|
||||
uint8_t stat; /* see enum virgl_video_encode_stat */
|
||||
uint8_t reserved[3];
|
||||
|
||||
uint32_t coded_size; /* size of encoded data in bytes */
|
||||
};
|
||||
|
||||
#endif /* VIRGL_VIDEO_HW_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue