diff --git a/src/gallium/frontends/vdpau/decode.c b/src/gallium/frontends/vdpau/decode.c index 08c3754e12a..9ba5deb470b 100644 --- a/src/gallium/frontends/vdpau/decode.c +++ b/src/gallium/frontends/vdpau/decode.c @@ -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; } diff --git a/src/gallium/frontends/vdpau/surface.c b/src/gallium/frontends/vdpau/surface.c index ac9a2e2cfcd..13604603d44 100644 --- a/src/gallium/frontends/vdpau/surface.c +++ b/src/gallium/frontends/vdpau/surface.c @@ -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); diff --git a/src/gallium/frontends/vdpau/vdpau_private.h b/src/gallium/frontends/vdpau/vdpau_private.h index ffa8aa6f41b..36bb3908a86 100644 --- a/src/gallium/frontends/vdpau/vdpau_private.h +++ b/src/gallium/frontends/vdpau/vdpau_private.h @@ -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