mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 06:30:10 +01:00
frontends/vdpau: Alloc interlaced surface for interlaced pics
When decoding interlaced pics, the output surface should also be allocated as interlaced to make the deinterlace postproc filter work correctly. Reviewed-by: Ruijing Dong <ruijing.dong@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24361>
This commit is contained in:
parent
578e10e157
commit
0ee4506c3a
1 changed files with 49 additions and 36 deletions
|
|
@ -552,6 +552,16 @@ vlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsign
|
|||
sizes[0] = 4;
|
||||
}
|
||||
|
||||
static bool
|
||||
vlVdpQueryInterlacedH264(struct pipe_h264_picture_desc *h264)
|
||||
{
|
||||
if (h264->pps->sps->frame_mbs_only_flag)
|
||||
return false;
|
||||
|
||||
return h264->field_pic_flag || /* PAFF */
|
||||
h264->pps->sps->mb_adaptive_frame_field_flag; /* MBAFF */
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a compressed field/frame and render the result into a VdpVideoSurface.
|
||||
*/
|
||||
|
|
@ -583,6 +593,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
struct pipe_h264_picture_desc h264;
|
||||
struct pipe_h265_picture_desc h265;
|
||||
} desc;
|
||||
bool picture_interlaced = false;
|
||||
|
||||
if (!(picture_info && bitstream_buffers))
|
||||
return VDP_STATUS_INVALID_POINTER;
|
||||
|
|
@ -605,42 +616,6 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
// TODO: Recreate decoder with correct chroma
|
||||
return VDP_STATUS_INVALID_CHROMA_TYPE;
|
||||
|
||||
buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
|
||||
buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
|
||||
|
||||
if (vlsurf->video_buffer == NULL ||
|
||||
!screen->is_video_format_supported(screen, vlsurf->video_buffer->buffer_format,
|
||||
dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
|
||||
!buffer_support[vlsurf->video_buffer->interlaced]) {
|
||||
|
||||
mtx_lock(&vlsurf->device->mutex);
|
||||
|
||||
/* destroy the old one */
|
||||
if (vlsurf->video_buffer)
|
||||
vlsurf->video_buffer->destroy(vlsurf->video_buffer);
|
||||
|
||||
/* set the buffer format to the prefered one */
|
||||
vlsurf->templat.buffer_format = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_PREFERED_FORMAT);
|
||||
|
||||
/* also set interlacing to decoders preferences */
|
||||
vlsurf->templat.interlaced = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_PREFERS_INTERLACED);
|
||||
|
||||
/* and recreate the video buffer */
|
||||
vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
|
||||
|
||||
/* still no luck? get me out of here... */
|
||||
if (!vlsurf->video_buffer) {
|
||||
mtx_unlock(&vlsurf->device->mutex);
|
||||
return VDP_STATUS_NO_IMPLEMENTATION;
|
||||
}
|
||||
vlVdpVideoSurfaceClear(vlsurf);
|
||||
mtx_unlock(&vlsurf->device->mutex);
|
||||
}
|
||||
|
||||
for (i = 0; i < bitstream_buffer_count; ++i) {
|
||||
buffers[i] = bitstream_buffers[i].bitstream;
|
||||
sizes[i] = bitstream_buffers[i].bitstream_bytes;
|
||||
|
|
@ -663,6 +638,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
desc.h264.pps = &pps_h264;
|
||||
ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info, dec->level);
|
||||
picture_interlaced = vlVdpQueryInterlacedH264(&desc.h264);
|
||||
break;
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
desc.h265.pps = &pps_h265;
|
||||
|
|
@ -675,6 +651,43 @@ vlVdpDecoderRender(VdpDecoder decoder,
|
|||
if (ret != VDP_STATUS_OK)
|
||||
return ret;
|
||||
|
||||
buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
|
||||
buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
|
||||
|
||||
if (vlsurf->video_buffer == NULL ||
|
||||
!screen->is_video_format_supported(screen, vlsurf->video_buffer->buffer_format,
|
||||
dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
|
||||
!buffer_support[vlsurf->video_buffer->interlaced] ||
|
||||
(picture_interlaced && !vlsurf->video_buffer->interlaced && buffer_support[1])) {
|
||||
|
||||
mtx_lock(&vlsurf->device->mutex);
|
||||
|
||||
/* destroy the old one */
|
||||
if (vlsurf->video_buffer)
|
||||
vlsurf->video_buffer->destroy(vlsurf->video_buffer);
|
||||
|
||||
/* set the buffer format to the prefered one */
|
||||
vlsurf->templat.buffer_format = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_PREFERED_FORMAT);
|
||||
|
||||
/* also set interlacing to decoders preferences */
|
||||
vlsurf->templat.interlaced = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
|
||||
PIPE_VIDEO_CAP_PREFERS_INTERLACED) || picture_interlaced;
|
||||
|
||||
/* and recreate the video buffer */
|
||||
vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
|
||||
|
||||
/* still no luck? get me out of here... */
|
||||
if (!vlsurf->video_buffer) {
|
||||
mtx_unlock(&vlsurf->device->mutex);
|
||||
return VDP_STATUS_NO_IMPLEMENTATION;
|
||||
}
|
||||
vlVdpVideoSurfaceClear(vlsurf);
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue