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:
Feng Jiang 2022-09-29 11:38:20 +08:00 committed by Marge Bot
parent 69ed5f13d8
commit d3a203c969
6 changed files with 423 additions and 18 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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,

View file

@ -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 {

View file

@ -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

View file

@ -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 */