frontends/va: Remove H264 encode delayed flush

This was added for the VCE dual instance feature and it tries
to delay flush such as the flush is done only every second frame.
For this it requires applications not to call vaSyncSurface after
each vaEndPicture, otherwise every frame will be flushed.
When this was implemented in 2016, libva and applications were
different. Now applications will always sync surface after each
end frame, making this feature completely non-functional.

Another issue is that this is incorrect, the flush cannot be delayed
and every vaEndPicture needs to flush. This is needed to ensure
interop with other APIs (eg. sharing dmabufs with GL) works correctly.
Delaying the flush would also mean submitting the same surface
every frame for encoding (and changing the surface contents before
encoding each frame) will not work.

Reviewed-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31933>
This commit is contained in:
David Rosca
2024-11-01 08:33:10 +01:00
committed by Marge Bot
parent d6c08a4345
commit fa65224c86
3 changed files with 5 additions and 52 deletions

View File

@@ -1338,29 +1338,6 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
context->decoder->entrypoint,
PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME))
context->decoder->flush(context->decoder);
else {
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&
u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
int idr_period = context->desc.h264enc.gop_size / context->gop_coeff;
int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num;
surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt;
surf->force_flushed = false;
if (context->first_single_submitted) {
context->decoder->flush(context->decoder);
context->first_single_submitted = false;
surf->force_flushed = true;
}
if (p_remain_in_idr == 1) {
if ((context->desc.h264enc.frame_num_cnt % 2) != 0) {
context->decoder->flush(context->decoder);
context->first_single_submitted = true;
}
else
context->first_single_submitted = false;
surf->force_flushed = true;
}
}
}
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
switch (u_reduce_video_profile(context->templat.profile)) {

View File

@@ -198,31 +198,11 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo
if (context->decoder->fence_wait)
ret = context->decoder->fence_wait(context->decoder, surf->fence, timeout_ns);
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && surf->feedback) {
if (!drv->pipe->screen->get_video_param(drv->pipe->screen,
context->decoder->profile,
context->decoder->entrypoint,
PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME)) {
if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
int frame_diff;
if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt)
frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt;
else
frame_diff = 0xFFFFFFFF - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt;
if ((frame_diff == 0) &&
(surf->force_flushed == false) &&
(context->desc.h264enc.frame_num_cnt % 2 != 0)) {
context->decoder->flush(context->decoder);
context->first_single_submitted = true;
}
}
}
if (ret) {
context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size), &(surf->coded_buf->extended_metadata));
surf->feedback = NULL;
surf->coded_buf->feedback = NULL;
surf->coded_buf->associated_encode_input_surf = VA_INVALID_ID;
}
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && surf->feedback && ret) {
context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size), &(surf->coded_buf->extended_metadata));
surf->feedback = NULL;
surf->coded_buf->feedback = NULL;
surf->coded_buf->associated_encode_input_surf = VA_INVALID_ID;
}
mtx_unlock(&drv->mutex);
return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT;

View File

@@ -410,7 +410,6 @@ typedef struct {
struct vl_deint_filter *deint;
vlVaBuffer *coded_buf;
int target_id;
bool first_single_submitted;
int gop_coeff;
bool needs_begin_frame;
void *blit_cs;
@@ -441,9 +440,6 @@ typedef struct vlVaSurface {
vlVaContext *ctx;
vlVaBuffer *coded_buf;
void *feedback;
unsigned int frame_num_cnt;
bool force_flushed;
struct pipe_video_buffer *obsolete_buf;
bool full_range;
struct pipe_fence_handle *fence;
struct vlVaSurface *efc_surface; /* input surface for EFC */