mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
va: decoder: store output buffer rather than surface
GstVaDecodePicture stored the processed VASurfaceID, under the assumption that the bufferpool with keep the referenced buffers, but this approach is fragil. This patch changes GstVaDecodePicture to store the output buffer, which already contains its VASurfaceID, and provides a new method to retrieve the VASurfaceID directly from picture. Based on He Junyan <junyan.he@intel.com> patches for https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1587 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1594>
This commit is contained in:
parent
6c26d0e1a0
commit
755d769045
3 changed files with 40 additions and 16 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "gstvadecoder.h"
|
#include "gstvadecoder.h"
|
||||||
|
|
||||||
|
#include "gstvaallocator.h"
|
||||||
#include "gstvacaps.h"
|
#include "gstvacaps.h"
|
||||||
#include "gstvadisplay_wrapped.h"
|
#include "gstvadisplay_wrapped.h"
|
||||||
#include "gstvavideoformat.h"
|
#include "gstvavideoformat.h"
|
||||||
|
@ -568,18 +569,25 @@ gst_va_decoder_decode (GstVaDecoder * self, GstVaDecodePicture * pic)
|
||||||
{
|
{
|
||||||
VADisplay dpy;
|
VADisplay dpy;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
VASurfaceID surface;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_VA_DECODER (self), FALSE);
|
g_return_val_if_fail (GST_IS_VA_DECODER (self), FALSE);
|
||||||
g_return_val_if_fail (self->context != VA_INVALID_ID, FALSE);
|
g_return_val_if_fail (self->context != VA_INVALID_ID, FALSE);
|
||||||
g_return_val_if_fail (pic && pic->surface != VA_INVALID_ID, FALSE);
|
g_return_val_if_fail (pic, FALSE);
|
||||||
|
|
||||||
GST_TRACE_OBJECT (self, "Decode to surface %#x", pic->surface);
|
surface = gst_va_decode_picture_get_surface (pic);
|
||||||
|
if (surface == VA_INVALID_ID) {
|
||||||
|
GST_ERROR_OBJECT (self, "Decode picture without VASurfaceID");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_TRACE_OBJECT (self, "Decode to surface %#x", surface);
|
||||||
|
|
||||||
dpy = gst_va_display_get_va_dpy (self->display);
|
dpy = gst_va_display_get_va_dpy (self->display);
|
||||||
|
|
||||||
gst_va_display_lock (self->display);
|
gst_va_display_lock (self->display);
|
||||||
status = vaBeginPicture (dpy, self->context, pic->surface);
|
status = vaBeginPicture (dpy, self->context, surface);
|
||||||
gst_va_display_unlock (self->display);
|
gst_va_display_unlock (self->display);
|
||||||
if (status != VA_STATUS_SUCCESS) {
|
if (status != VA_STATUS_SUCCESS) {
|
||||||
GST_WARNING_OBJECT (self, "vaBeginPicture: %s", vaErrorStr (status));
|
GST_WARNING_OBJECT (self, "vaBeginPicture: %s", vaErrorStr (status));
|
||||||
|
@ -638,13 +646,20 @@ gst_va_decoder_destroy_buffers (GstVaDecoder * self, GstVaDecodePicture * pic)
|
||||||
VABufferID buffer;
|
VABufferID buffer;
|
||||||
VADisplay dpy;
|
VADisplay dpy;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
VASurfaceID surface;
|
||||||
guint i;
|
guint i;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_VA_DECODER (self), FALSE);
|
g_return_val_if_fail (GST_IS_VA_DECODER (self), FALSE);
|
||||||
g_return_val_if_fail (pic && pic->surface != VA_INVALID_ID, FALSE);
|
g_return_val_if_fail (pic, FALSE);
|
||||||
|
|
||||||
GST_TRACE_OBJECT (self, "Destroy buffers of surface %#x", pic->surface);
|
surface = gst_va_decode_picture_get_surface (pic);
|
||||||
|
if (surface == VA_INVALID_ID) {
|
||||||
|
GST_ERROR_OBJECT (self, "Decode picture without VASurfaceID");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_TRACE_OBJECT (self, "Destroy buffers of surface %#x", surface);
|
||||||
|
|
||||||
dpy = gst_va_display_get_va_dpy (self->display);
|
dpy = gst_va_display_get_va_dpy (self->display);
|
||||||
|
|
||||||
|
@ -679,20 +694,29 @@ gst_va_decoder_destroy_buffers (GstVaDecoder * self, GstVaDecodePicture * pic)
|
||||||
|
|
||||||
|
|
||||||
GstVaDecodePicture *
|
GstVaDecodePicture *
|
||||||
gst_va_decode_picture_new (VASurfaceID surface)
|
gst_va_decode_picture_new (GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstVaDecodePicture *pic;
|
GstVaDecodePicture *pic;
|
||||||
|
|
||||||
g_return_val_if_fail (surface != VA_INVALID_ID, NULL);
|
g_return_val_if_fail (buffer && GST_IS_BUFFER (buffer), NULL);
|
||||||
|
|
||||||
pic = g_slice_new (GstVaDecodePicture);
|
pic = g_slice_new (GstVaDecodePicture);
|
||||||
pic->surface = surface;
|
pic->gstbuffer = gst_buffer_ref (buffer);
|
||||||
pic->buffers = g_array_sized_new (FALSE, FALSE, sizeof (VABufferID), 16);
|
pic->buffers = g_array_sized_new (FALSE, FALSE, sizeof (VABufferID), 16);
|
||||||
pic->slices = g_array_sized_new (FALSE, FALSE, sizeof (VABufferID), 64);
|
pic->slices = g_array_sized_new (FALSE, FALSE, sizeof (VABufferID), 64);
|
||||||
|
|
||||||
return pic;
|
return pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VASurfaceID
|
||||||
|
gst_va_decode_picture_get_surface (GstVaDecodePicture * pic)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (pic, VA_INVALID_ID);
|
||||||
|
g_return_val_if_fail (pic->gstbuffer, VA_INVALID_ID);
|
||||||
|
|
||||||
|
return gst_va_buffer_get_surface (pic->gstbuffer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_va_decode_picture_free (GstVaDecodePicture * pic)
|
gst_va_decode_picture_free (GstVaDecodePicture * pic)
|
||||||
{
|
{
|
||||||
|
@ -701,6 +725,7 @@ gst_va_decode_picture_free (GstVaDecodePicture * pic)
|
||||||
if (pic->buffers->len > 0 || pic->slices->len > 0)
|
if (pic->buffers->len > 0 || pic->slices->len > 0)
|
||||||
GST_WARNING ("VABufferID are leaked");
|
GST_WARNING ("VABufferID are leaked");
|
||||||
|
|
||||||
|
gst_buffer_unref (pic->gstbuffer);
|
||||||
g_clear_pointer (&pic->buffers, g_array_unref);
|
g_clear_pointer (&pic->buffers, g_array_unref);
|
||||||
g_clear_pointer (&pic->slices, g_array_unref);
|
g_clear_pointer (&pic->slices, g_array_unref);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct _GstVaDecodePicture
|
||||||
{
|
{
|
||||||
GArray *buffers;
|
GArray *buffers;
|
||||||
GArray *slices;
|
GArray *slices;
|
||||||
VASurfaceID surface;
|
GstBuffer *gstbuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_TYPE_VA_DECODER (gst_va_decoder_get_type())
|
#define GST_TYPE_VA_DECODER (gst_va_decoder_get_type())
|
||||||
|
@ -69,7 +69,8 @@ gboolean gst_va_decoder_decode (GstVaDecoder * self,
|
||||||
gboolean gst_va_decoder_destroy_buffers (GstVaDecoder * self,
|
gboolean gst_va_decoder_destroy_buffers (GstVaDecoder * self,
|
||||||
GstVaDecodePicture * pic);
|
GstVaDecodePicture * pic);
|
||||||
|
|
||||||
GstVaDecodePicture * gst_va_decode_picture_new (VASurfaceID surface);
|
GstVaDecodePicture * gst_va_decode_picture_new (GstBuffer * buffer);
|
||||||
|
VASurfaceID gst_va_decode_picture_get_surface (GstVaDecodePicture * pic);
|
||||||
void gst_va_decode_picture_free (GstVaDecodePicture * pic);
|
void gst_va_decode_picture_free (GstVaDecodePicture * pic);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -240,7 +240,7 @@ _fill_vaapi_pic (VAPictureH264 * va_picture, GstH264Picture * picture)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_picture->picture_id = va_pic->surface;
|
va_picture->picture_id = gst_va_decode_picture_get_surface (va_pic);
|
||||||
va_picture->flags = 0;
|
va_picture->flags = 0;
|
||||||
|
|
||||||
if (picture->ref && picture->long_term) {
|
if (picture->ref && picture->long_term) {
|
||||||
|
@ -553,19 +553,17 @@ gst_va_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||||
GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
|
GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
|
||||||
GstVaDecodePicture *pic;
|
GstVaDecodePicture *pic;
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
VASurfaceID surface;
|
|
||||||
|
|
||||||
self->last_ret = gst_video_decoder_allocate_output_frame (vdec, frame);
|
self->last_ret = gst_video_decoder_allocate_output_frame (vdec, frame);
|
||||||
if (self->last_ret != GST_FLOW_OK)
|
if (self->last_ret != GST_FLOW_OK)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
surface = gst_va_buffer_get_surface (frame->output_buffer, NULL);
|
pic = gst_va_decode_picture_new (frame->output_buffer);
|
||||||
|
|
||||||
pic = gst_va_decode_picture_new (surface);
|
|
||||||
gst_h264_picture_set_user_data (picture, pic,
|
gst_h264_picture_set_user_data (picture, pic,
|
||||||
(GDestroyNotify) gst_va_decode_picture_free);
|
(GDestroyNotify) gst_va_decode_picture_free);
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic, pic->surface);
|
GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic,
|
||||||
|
gst_va_decode_picture_get_surface (pic));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue