mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
frontends/vdpau: Use extra reference buffer for AV1 film grain
AV1 applies film grain to decode target only, references in DPB must be stored without film grain. Fixes film grain decoding on drivers that use decode target buffers directly for references. Reviewed-by: Leo Liu <leo.liu@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33640>
This commit is contained in:
parent
5da76df4cd
commit
367735551d
3 changed files with 31 additions and 10 deletions
|
|
@ -215,7 +215,7 @@ vlVdpGetReferenceFrame(VdpVideoSurface handle, struct pipe_video_buffer **ref_fr
|
|||
if (!surface)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
||||
*ref_frame = surface->video_buffer;
|
||||
*ref_frame = surface->ref_buffer ? surface->ref_buffer : surface->video_buffer;
|
||||
if (!*ref_frame)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
||||
|
|
@ -619,13 +619,10 @@ copyAV1TileInfo(struct pipe_av1_picture_desc *picture,
|
|||
|
||||
static VdpStatus
|
||||
vlVdpDecoderRenderAV1(struct pipe_av1_picture_desc *picture,
|
||||
VdpVideoSurface target,
|
||||
const VdpPictureInfoAV1 *picture_info)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
picture->film_grain_target = NULL;
|
||||
|
||||
picture->picture_parameter.profile = picture_info->profile;
|
||||
picture->picture_parameter.order_hint_bits_minus_1 = picture_info->order_hint_bits_minus1;
|
||||
picture->picture_parameter.bit_depth_idx = picture_info->bit_depth_minus8 >> 1;
|
||||
|
|
@ -660,7 +657,6 @@ vlVdpDecoderRenderAV1(struct pipe_av1_picture_desc *picture,
|
|||
picture->picture_parameter.seq_info_fields.subsampling_y =
|
||||
picture_info->subsampling_y;
|
||||
|
||||
picture->picture_parameter.current_frame_id = target;
|
||||
picture->picture_parameter.frame_width = picture_info->width;
|
||||
picture->picture_parameter.frame_height = picture_info->height;
|
||||
picture->picture_parameter.max_width = picture_info->width;
|
||||
|
|
@ -1035,6 +1031,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
struct pipe_av1_picture_desc av1;
|
||||
} desc;
|
||||
bool picture_interlaced = false;
|
||||
struct pipe_video_buffer *target_buf;
|
||||
|
||||
if (!(picture_info && bitstream_buffers))
|
||||
return VDP_STATUS_INVALID_POINTER;
|
||||
|
|
@ -1086,7 +1083,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
ret = vlVdpDecoderRenderH265(&desc.h265, (VdpPictureInfoHEVC *)picture_info);
|
||||
break;
|
||||
case PIPE_VIDEO_FORMAT_AV1:
|
||||
ret = vlVdpDecoderRenderAV1(&desc.av1, target, (VdpPictureInfoAV1 *)picture_info);
|
||||
ret = vlVdpDecoderRenderAV1(&desc.av1, (VdpPictureInfoAV1 *)picture_info);
|
||||
break;
|
||||
default:
|
||||
return VDP_STATUS_INVALID_DECODER_PROFILE;
|
||||
|
|
@ -1132,10 +1129,32 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
mtx_unlock(&vlsurf->device->mutex);
|
||||
}
|
||||
|
||||
target_buf = vlsurf->video_buffer;
|
||||
|
||||
if (u_reduce_video_profile(dec->profile) == PIPE_VIDEO_FORMAT_AV1) {
|
||||
desc.av1.film_grain_target = NULL;
|
||||
if (desc.av1.picture_parameter.film_grain_info.film_grain_info_fields.apply_grain) {
|
||||
if (!vlsurf->ref_buffer) {
|
||||
mtx_lock(&vlsurf->device->mutex);
|
||||
vlsurf->ref_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
|
||||
mtx_unlock(&vlsurf->device->mutex);
|
||||
if (!vlsurf->ref_buffer)
|
||||
return VDP_STATUS_RESOURCES;
|
||||
}
|
||||
desc.av1.film_grain_target = target_buf;
|
||||
target_buf = vlsurf->ref_buffer;
|
||||
} else if (vlsurf->ref_buffer) {
|
||||
mtx_lock(&vlsurf->device->mutex);
|
||||
vlsurf->ref_buffer->destroy(vlsurf->ref_buffer);
|
||||
vlsurf->ref_buffer = NULL;
|
||||
mtx_unlock(&vlsurf->device->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
mtx_lock(&vldecoder->mutex);
|
||||
dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
|
||||
dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
|
||||
dec->end_frame(dec, vlsurf->video_buffer, &desc.base);
|
||||
dec->begin_frame(dec, target_buf, &desc.base);
|
||||
dec->decode_bitstream(dec, target_buf, &desc.base, bitstream_buffer_count, buffers, sizes);
|
||||
dec->end_frame(dec, target_buf, &desc.base);
|
||||
mtx_unlock(&vldecoder->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ vlVdpVideoSurfaceDestroy(VdpVideoSurface surface)
|
|||
mtx_lock(&p_surf->device->mutex);
|
||||
if (p_surf->video_buffer)
|
||||
p_surf->video_buffer->destroy(p_surf->video_buffer);
|
||||
if (p_surf->ref_buffer)
|
||||
p_surf->ref_buffer->destroy(p_surf->ref_buffer);
|
||||
mtx_unlock(&p_surf->device->mutex);
|
||||
|
||||
vlRemoveDataHTAB(surface);
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
vlVdpDevice *device;
|
||||
struct pipe_video_buffer templat, *video_buffer;
|
||||
struct pipe_video_buffer templat, *video_buffer, *ref_buffer;
|
||||
} vlVdpSurface;
|
||||
|
||||
typedef struct
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue