summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivia Nikolaidou <vivia@ahiru.eu>2020-08-14 19:57:30 +0300
committerVivia Nikolaidou <vivia@ahiru.eu>2020-08-17 23:39:39 +0300
commitdc58065dfb849f04a23ec40e0989fb794dcfb2f7 (patch)
tree8cee1b09a16479525fc6c58abed612a312702836
parent5d4ab18ceddcb0621ceaa33c34445d0bcc6e439a (diff)
downloadgstreamer-plugins-bad-dc58065dfb849f04a23ec40e0989fb794dcfb2f7.tar.gz
fdkaacenc: Implement flush function
The internal fdk encoder always produces 1024 bytes even with no input, so special care should be taken to not drain it twice. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1515>
-rw-r--r--ext/fdkaac/gstfdkaacenc.c29
-rw-r--r--ext/fdkaac/gstfdkaacenc.h1
2 files changed, 28 insertions, 2 deletions
diff --git a/ext/fdkaac/gstfdkaacenc.c b/ext/fdkaac/gstfdkaacenc.c
index 4079f3693..368b3b87c 100644
--- a/ext/fdkaac/gstfdkaacenc.c
+++ b/ext/fdkaac/gstfdkaacenc.c
@@ -92,6 +92,7 @@ static GstFlowReturn gst_fdkaacenc_handle_frame (GstAudioEncoder * enc,
GstBuffer * in_buf);
static GstCaps *gst_fdkaacenc_get_caps (GstAudioEncoder * enc,
GstCaps * filter);
+static void gst_fdkaacenc_flush (GstAudioEncoder * enc);
G_DEFINE_TYPE (GstFdkAacEnc, gst_fdkaacenc, GST_TYPE_AUDIO_ENCODER);
@@ -146,9 +147,12 @@ gst_fdkaacenc_stop (GstAudioEncoder * enc)
GST_DEBUG_OBJECT (self, "stop");
- if (self->enc)
+ if (self->enc) {
aacEncClose (&self->enc);
+ self->enc = NULL;
+ }
+ self->is_drained = TRUE;
return TRUE;
}
@@ -199,10 +203,11 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
AACENC_InfoStruct enc_info = { 0 };
gint bitrate;
- if (self->enc) {
+ if (self->enc && !self->is_drained) {
/* drain */
gst_fdkaacenc_handle_frame (enc, NULL);
aacEncClose (&self->enc);
+ self->is_drained = TRUE;
}
allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (self));
@@ -457,6 +462,10 @@ gst_fdkaacenc_handle_frame (GstAudioEncoder * enc, GstBuffer * inbuf)
in_el_sizes = 0;
in_desc.numBufs = 0;
}
+ /* We unset is_drained even if there's no inbuf. Basically this is a
+ * workaround for aacEncEncode always producing 1024 bytes even without any
+ * input, thus messing up with the base class counting */
+ self->is_drained = FALSE;
in_desc.bufferIdentifiers = &in_id;
in_desc.bufs = (void *) &imap.data;
@@ -518,10 +527,25 @@ out:
}
static void
+gst_fdkaacenc_flush (GstAudioEncoder * enc)
+{
+ GstFdkAacEnc *self = GST_FDKAACENC (enc);
+ GstAudioInfo *info = gst_audio_encoder_get_audio_info (enc);
+
+ aacEncClose (&self->enc);
+ self->enc = NULL;
+ self->is_drained = TRUE;
+
+ if (GST_AUDIO_INFO_IS_VALID (info))
+ gst_fdkaacenc_set_format (enc, info);
+}
+
+static void
gst_fdkaacenc_init (GstFdkAacEnc * self)
{
self->bitrate = DEFAULT_BITRATE;
self->enc = NULL;
+ self->is_drained = TRUE;
gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (self), TRUE);
}
@@ -541,6 +565,7 @@ gst_fdkaacenc_class_init (GstFdkAacEncClass * klass)
base_class->set_format = GST_DEBUG_FUNCPTR (gst_fdkaacenc_set_format);
base_class->getcaps = GST_DEBUG_FUNCPTR (gst_fdkaacenc_get_caps);
base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_fdkaacenc_handle_frame);
+ base_class->flush = GST_DEBUG_FUNCPTR (gst_fdkaacenc_flush);
g_object_class_install_property (object_class, PROP_BITRATE,
g_param_spec_int ("bitrate",
diff --git a/ext/fdkaac/gstfdkaacenc.h b/ext/fdkaac/gstfdkaacenc.h
index 8c3df47a4..6dacc7db8 100644
--- a/ext/fdkaac/gstfdkaacenc.h
+++ b/ext/fdkaac/gstfdkaacenc.h
@@ -50,6 +50,7 @@ struct _GstFdkAacEnc {
guint outbuf_size, samples_per_frame;
gboolean need_reorder;
const GstAudioChannelPosition *aac_positions;
+ gboolean is_drained;
};
struct _GstFdkAacEncClass {