GList *headers;
gboolean new_headers;
+
+ GstAllocator *allocator;
+ GstAllocationParams params;
} GstAudioEncoderContext;
struct _GstAudioEncoderPrivate
static GstStateChangeReturn gst_audio_encoder_change_state (GstElement *
element, GstStateChange transition);
+static gboolean gst_audio_encoder_decide_allocation_default (GstAudioEncoder *
+ enc, GstQuery * query);
+static gboolean gst_audio_encoder_propose_allocation_default (GstAudioEncoder *
+ enc, GstQuery * query);
+
static void
gst_audio_encoder_class_init (GstAudioEncoderClass * klass)
{
klass->getcaps = gst_audio_encoder_getcaps_default;
klass->sink_event = gst_audio_encoder_sink_event_default;
klass->src_event = gst_audio_encoder_src_event_default;
+ klass->propose_allocation = gst_audio_encoder_propose_allocation_default;
+ klass->decide_allocation = gst_audio_encoder_decide_allocation_default;
}
static void
g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL);
g_list_free (enc->priv->pending_events);
enc->priv->pending_events = NULL;
+
+ if (enc->priv->ctx.allocator)
+ gst_object_unref (enc->priv->ctx.allocator);
+ enc->priv->ctx.allocator = NULL;
}
gst_segment_init (&enc->input_segment, GST_FORMAT_TIME);
}
break;
}
+ case GST_QUERY_ALLOCATION:
+ {
+ GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
+
+ if (klass->propose_allocation)
+ res = klass->propose_allocation (enc, query);
+ break;
+ }
default:
res = gst_pad_query_default (pad, parent, query);
break;
return ret;
}
+static gboolean
+gst_audio_encoder_decide_allocation_default (GstAudioEncoder * enc,
+ GstQuery * query)
+{
+ GstAllocator *allocator = NULL;
+ GstAllocationParams params;
+ gboolean update_allocator;
+
+ /* we got configuration from our peer or the decide_allocation method,
+ * parse them */
+ if (gst_query_get_n_allocation_params (query) > 0) {
+ /* try the allocator */
+ gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
+ update_allocator = TRUE;
+ } else {
+ allocator = NULL;
+ gst_allocation_params_init (¶ms);
+ update_allocator = FALSE;
+ }
+
+ if (update_allocator)
+ gst_query_set_nth_allocation_param (query, 0, allocator, ¶ms);
+ else
+ gst_query_add_allocation_param (query, allocator, ¶ms);
+ if (allocator)
+ gst_object_unref (allocator);
+
+ return TRUE;
+}
+
+static gboolean
+gst_audio_encoder_propose_allocation_default (GstAudioEncoder * enc,
+ GstQuery * query)
+{
+ return TRUE;
+}
+
/*
* gst_audio_encoded_audio_convert:
* @fmt: audio format of the encoded audio
gboolean
gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps)
{
+ GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
gboolean res = FALSE;
GstCaps *templ_caps;
+ GstQuery *query = NULL;
+ GstAllocator *allocator;
+ GstAllocationParams params;
GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
gst_caps_unref (templ_caps);
res = gst_pad_set_caps (enc->srcpad, caps);
+ if (!res)
+ goto done;
+
+ query = gst_query_new_allocation (caps, TRUE);
+ if (!gst_pad_peer_query (enc->srcpad, query)) {
+ GST_DEBUG_OBJECT (enc, "didn't get downstream ALLOCATION hints");
+ }
+
+ g_assert (klass->decide_allocation != NULL);
+ res = klass->decide_allocation (enc, query);
+
+ GST_DEBUG_OBJECT (enc, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, res,
+ query);
+
+ if (!res)
+ goto no_decide_allocation;
+
+ /* we got configuration from our peer or the decide_allocation method,
+ * parse them */
+ if (gst_query_get_n_allocation_params (query) > 0) {
+ gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
+ } else {
+ allocator = NULL;
+ gst_allocation_params_init (¶ms);
+ }
+
+ if (enc->priv->ctx.allocator)
+ gst_object_unref (enc->priv->ctx.allocator);
+ enc->priv->ctx.allocator = allocator;
+ enc->priv->ctx.params = params;
done:
+ if (query)
+ gst_query_unref (query);
+
return res;
/* ERRORS */
res = FALSE;
goto done;
}
+ /* Errors */
+no_decide_allocation:
+ {
+ GST_WARNING_OBJECT (enc, "Subclass failed to decide allocation");
+ goto done;
+ }
+}
+
+/**
+ * gst_audio_encoder_allocate_output_buffer:
+ * @enc: a #GstAudioEncoder
+ * @size: size of the buffer
+ *
+ * Helper function that allocates a buffer to hold an encoded audio frame
+ * for @enc's current output format.
+ *
+ * Returns: (transfer full): allocated buffer
+ */
+GstBuffer *
+gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * enc, gsize size)
+{
+ GstBuffer *buffer;
+
+ g_return_val_if_fail (size > 0, NULL);
+
+ GST_DEBUG ("alloc src buffer");
+
+ GST_AUDIO_ENCODER_STREAM_LOCK (enc);
+
+ buffer =
+ gst_buffer_new_allocate (enc->priv->ctx.allocator, size,
+ &enc->priv->ctx.params);
+
+ GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
+
+ return buffer;
}