mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
vaapiencode: optimize _handle_frame() to avoid extra allocation.
Optimize gst_vaapiencode_handle_frame() to avoid extra memory allocation, and in particular the GstVaapiEncObjUserData object. i.e. directly use the VA surface proxy from the source buffer. This also makes the user data attached to the GstVideoCodecFrame more consistent between both the decoder and encoder plug-in elements.
This commit is contained in:
parent
081ff63f9a
commit
30f382fcdf
3 changed files with 66 additions and 81 deletions
|
@ -25,6 +25,7 @@
|
|||
#include "gstvaapiencoder_objects.h"
|
||||
#include "gstvaapiencoder.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapisurfaceproxy_priv.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
@ -387,7 +388,7 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture)
|
|||
gst_vaapi_mini_object_replace (
|
||||
(GstVaapiMiniObject **) (&picture->sequence), NULL);
|
||||
|
||||
g_assert (picture->surface);
|
||||
gst_vaapi_surface_proxy_replace (&picture->proxy, NULL);
|
||||
picture->surface_id = VA_INVALID_ID;
|
||||
picture->surface = NULL;
|
||||
|
||||
|
@ -405,19 +406,22 @@ gboolean
|
|||
gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
GstVideoCodecFrame *frame;
|
||||
GstVaapiSurface *surface;
|
||||
GstVaapiEncObjUserDataHead *user_data;
|
||||
GstVideoCodecFrame *const frame = (GstVideoCodecFrame *)args->data;
|
||||
gboolean success;
|
||||
|
||||
g_assert (args->data);
|
||||
g_return_val_if_fail (args->data, FALSE);
|
||||
g_return_val_if_fail (frame != NULL, FALSE);
|
||||
|
||||
frame = (GstVideoCodecFrame *) args->data;
|
||||
user_data = gst_video_codec_frame_get_user_data (frame);
|
||||
g_assert (user_data);
|
||||
surface = user_data->surface;
|
||||
g_return_val_if_fail (surface, FALSE);
|
||||
picture->proxy = gst_video_codec_frame_get_user_data (frame);
|
||||
if (!gst_vaapi_surface_proxy_ref (picture->proxy))
|
||||
return FALSE;
|
||||
|
||||
picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (picture->proxy);
|
||||
if (!picture->surface)
|
||||
return FALSE;
|
||||
|
||||
picture->surface_id = GST_VAAPI_OBJECT_ID (picture->surface);
|
||||
if (picture->surface_id == VA_INVALID_ID)
|
||||
return FALSE;
|
||||
|
||||
picture->sequence = NULL;
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
|
||||
|
@ -446,10 +450,6 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture,
|
|||
return FALSE;
|
||||
|
||||
picture->frame = gst_video_codec_frame_ref (frame);
|
||||
picture->surface = surface;
|
||||
g_assert (picture->surface);
|
||||
picture->surface_id = gst_vaapi_surface_get_id (picture->surface);
|
||||
g_assert (picture->surface_id != VA_INVALID_SURFACE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -261,11 +261,6 @@ typedef enum
|
|||
#define GST_VAAPI_ENC_PICTURE_GET_FRAME(picture) \
|
||||
(picture)->frame
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstVaapiSurface *surface;
|
||||
} GstVaapiEncObjUserDataHead;
|
||||
|
||||
/**
|
||||
* GstVaapiEncPicture:
|
||||
*
|
||||
|
@ -276,6 +271,7 @@ struct _GstVaapiEncPicture
|
|||
/*< private > */
|
||||
GstVaapiCodecObject parent_instance;
|
||||
GstVideoCodecFrame *frame;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
GstVaapiSurface *surface;
|
||||
GstVaapiEncSequence *sequence;
|
||||
/*< private >, picture packed header */
|
||||
|
|
|
@ -41,12 +41,6 @@
|
|||
#define GST_VAAPI_ENCODE_FLOW_CONVERT_ERROR GST_FLOW_CUSTOM_ERROR_1
|
||||
#define GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR GST_FLOW_CUSTOM_ERROR_2
|
||||
|
||||
typedef struct _GstVaapiEncodeFrameUserData
|
||||
{
|
||||
GstVaapiEncObjUserDataHead head;
|
||||
GstBuffer *vaapi_buf;
|
||||
} GstVaapiEncodeFrameUserData;
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug);
|
||||
#define GST_CAT_DEFAULT gst_vaapiencode_debug
|
||||
|
||||
|
@ -630,7 +624,6 @@ get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer,
|
|||
gboolean success;
|
||||
#endif
|
||||
|
||||
*out_buffer_ptr = NULL;
|
||||
meta = gst_buffer_get_vaapi_video_meta (src_buffer);
|
||||
if (meta) {
|
||||
*out_buffer_ptr = gst_buffer_ref (src_buffer);
|
||||
|
@ -728,77 +721,73 @@ error_copy_buffer:
|
|||
}
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
_create_user_data (GstBuffer * buf)
|
||||
{
|
||||
GstVaapiVideoMeta *meta;
|
||||
GstVaapiSurface *surface;
|
||||
GstVaapiEncodeFrameUserData *user_data;
|
||||
|
||||
meta = gst_buffer_get_vaapi_video_meta (buf);
|
||||
if (!meta) {
|
||||
GST_DEBUG ("convert to vaapi buffer failed");
|
||||
return NULL;
|
||||
}
|
||||
surface = gst_vaapi_video_meta_get_surface (meta);
|
||||
if (!surface) {
|
||||
GST_DEBUG ("vaapi_meta of codec frame doesn't have vaapisurfaceproxy");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
user_data = g_slice_new0 (GstVaapiEncodeFrameUserData);
|
||||
user_data->head.surface = surface;
|
||||
user_data->vaapi_buf = gst_buffer_ref (buf);
|
||||
return user_data;
|
||||
}
|
||||
|
||||
static void
|
||||
_destroy_user_data (gpointer data)
|
||||
{
|
||||
GstVaapiEncodeFrameUserData *user_data = (GstVaapiEncodeFrameUserData *) data;
|
||||
|
||||
g_assert (data);
|
||||
if (!user_data)
|
||||
return;
|
||||
gst_buffer_replace (&user_data->vaapi_buf, NULL);
|
||||
g_slice_free (GstVaapiEncodeFrameUserData, user_data);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_vaapiencode_handle_frame (GstVideoEncoder * venc,
|
||||
GstVideoCodecFrame * frame)
|
||||
{
|
||||
GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc);
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
GstVaapiEncoderStatus status;
|
||||
GstVaapiVideoMeta *meta;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
GstFlowReturn ret;
|
||||
GstBuffer *buf;
|
||||
gpointer user_data;
|
||||
|
||||
g_assert (encode && encode->encoder);
|
||||
g_assert (frame && frame->input_buffer);
|
||||
|
||||
buf = NULL;
|
||||
ret = get_source_buffer (encode, frame->input_buffer, &buf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
goto error_buffer_invalid;
|
||||
|
||||
user_data = _create_user_data (buf);
|
||||
GST_VAAPI_ENCODER_CHECK_STATUS (user_data,
|
||||
ret, "create frame user data failed");
|
||||
gst_buffer_replace (&frame->input_buffer, buf);
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
gst_video_codec_frame_set_user_data (frame, user_data, _destroy_user_data);
|
||||
meta = gst_buffer_get_vaapi_video_meta (buf);
|
||||
if (!meta)
|
||||
goto error_buffer_no_meta;
|
||||
|
||||
proxy = gst_vaapi_video_meta_get_surface_proxy (meta);
|
||||
if (!proxy)
|
||||
goto error_buffer_no_surface_proxy;
|
||||
|
||||
gst_video_codec_frame_set_user_data (frame,
|
||||
gst_vaapi_surface_proxy_ref (proxy),
|
||||
(GDestroyNotify)gst_vaapi_surface_proxy_unref);
|
||||
|
||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (encode);
|
||||
/*encoding frames */
|
||||
status = gst_vaapi_encoder_put_frame (encode->encoder, frame);
|
||||
GST_VIDEO_ENCODER_STREAM_LOCK (encode);
|
||||
if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS)
|
||||
goto error_encode_frame;
|
||||
|
||||
GST_VAAPI_ENCODER_CHECK_STATUS (GST_VAAPI_ENCODER_STATUS_SUCCESS <=
|
||||
status, GST_FLOW_ERROR, "gst_vaapiencoder_encode failed.");
|
||||
|
||||
end:
|
||||
gst_video_codec_frame_unref (frame);
|
||||
gst_buffer_replace (&buf, NULL);
|
||||
return ret;
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* ERRORS */
|
||||
error_buffer_invalid:
|
||||
{
|
||||
if (buf)
|
||||
gst_buffer_unref (buf);
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return ret;
|
||||
}
|
||||
error_buffer_no_meta:
|
||||
{
|
||||
GST_ERROR ("failed to get GstVaapiVideoMeta information");
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_buffer_no_surface_proxy:
|
||||
{
|
||||
GST_ERROR ("failed to get VA surface proxy");
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_encode_frame:
|
||||
{
|
||||
GST_ERROR ("failed to encode frame %d (status %d)",
|
||||
frame->system_frame_number, status);
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
|
Loading…
Reference in a new issue