summaryrefslogtreecommitdiff
path: root/gst-libs/gst/vaapi/gstvaapiencoder.c
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2019-01-14 18:21:30 +0100
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2019-01-14 20:09:57 +0100
commit220016aa6cf9606f22307d02bd7b4e7cdf46faed (patch)
treeff3641e0f0f7d1776df424e754514ff444ca8361 /gst-libs/gst/vaapi/gstvaapiencoder.c
parentf50fb8748f02910bdc75e62d91032187a1b73756 (diff)
libs: encoder: h264/h265: flush pending ordered pictures
In order to flush the pending pictures, a new internal encoder vmethod is used: get_pending_reordered() This method follows an iterator pattern which will return the next picture to encode and push. The base encoder will call this function in a loop when flush() is called. For now, only H.264 and H.265 encoders implement this flushing mechanism.
Diffstat (limited to 'gst-libs/gst/vaapi/gstvaapiencoder.c')
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c
index 5c3caf02..d463d6e3 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder.c
@@ -419,7 +419,7 @@ _coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder)
}
/* Creates a new VA coded buffer object proxy, backed from a pool */
-GstVaapiCodedBufferProxy *
+static GstVaapiCodedBufferProxy *
gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder)
{
GstVaapiCodedBufferPool *const pool =
@@ -597,6 +597,17 @@ error_invalid_buffer:
}
}
+static inline gboolean
+_get_pending_reordered (GstVaapiEncoder * encoder,
+ GstVaapiEncPicture ** picture, gpointer * state)
+{
+ GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
+
+ if (!klass->get_pending_reordered)
+ return FALSE;
+ return klass->get_pending_reordered (encoder, picture, state);
+}
+
/**
* gst_vaapi_encoder_flush:
* @encoder: a #GstVaapiEncoder
@@ -609,8 +620,47 @@ GstVaapiEncoderStatus
gst_vaapi_encoder_flush (GstVaapiEncoder * encoder)
{
GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
+ GstVaapiCodedBufferProxy *codedbuf_proxy;
+ GstVaapiEncPicture *picture;
+ GstVaapiEncoderStatus status;
+ gpointer iter = NULL;
+
+ picture = NULL;
+ while (_get_pending_reordered (encoder, &picture, &iter)) {
+ if (!picture)
+ continue;
+
+ codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (encoder);
+ if (!codedbuf_proxy)
+ goto error_create_coded_buffer;
+
+ status = klass->encode (encoder, picture, codedbuf_proxy);
+ if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
+ goto error_encode;
+
+ gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy,
+ picture, (GDestroyNotify) gst_vaapi_mini_object_unref);
+ g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy);
+ encoder->num_codedbuf_queued++;
+ }
+ g_free (iter);
return klass->flush (encoder);
+
+ /* ERRORS */
+error_create_coded_buffer:
+ {
+ GST_ERROR ("failed to allocate coded buffer");
+ gst_vaapi_enc_picture_unref (picture);
+ return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+error_encode:
+ {
+ GST_ERROR ("failed to encode frame (status = %d)", status);
+ gst_vaapi_enc_picture_unref (picture);
+ gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy);
+ return status;
+ }
}
/**