diff options
author | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2019-01-14 18:21:30 +0100 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2019-01-14 20:09:57 +0100 |
commit | 220016aa6cf9606f22307d02bd7b4e7cdf46faed (patch) | |
tree | ff3641e0f0f7d1776df424e754514ff444ca8361 /gst-libs/gst/vaapi/gstvaapiencoder.c | |
parent | f50fb8748f02910bdc75e62d91032187a1b73756 (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.c | 52 |
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; + } } /** |