summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-03-09 10:54:48 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-03-09 10:56:07 +0100
commit7ff608889afc46b326a8d1d4fea1813a6fafab0f (patch)
treedc23703690389cc7c1ad1107fd1f752456a81974
parentb2a162ca771fd3969207028190b2c3166da5c171 (diff)
downloadgstreamer-plugins-base-7ff608889afc46b326a8d1d4fea1813a6fafab0f.tar.gz
audio{en,de}coder: Add optional open/close vfuncs
This can be used to do something in NULL->READY, like checking if a hardware codec is actually available and to error out early.
-rw-r--r--gst-libs/gst/audio/gstaudiodecoder.c20
-rw-r--r--gst-libs/gst/audio/gstaudiodecoder.h12
-rw-r--r--gst-libs/gst/audio/gstaudioencoder.c51
-rw-r--r--gst-libs/gst/audio/gstaudioencoder.h12
4 files changed, 93 insertions, 2 deletions
diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c
index 0198d849d..5dfd278e1 100644
--- a/gst-libs/gst/audio/gstaudiodecoder.c
+++ b/gst-libs/gst/audio/gstaudiodecoder.c
@@ -2070,12 +2070,18 @@ static GstStateChangeReturn
gst_audio_decoder_change_state (GstElement * element, GstStateChange transition)
{
GstAudioDecoder *codec;
+ GstAudioDecoderClass *klass;
GstStateChangeReturn ret;
codec = GST_AUDIO_DECODER (element);
+ klass = GST_AUDIO_DECODER_GET_CLASS (codec);
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
+ if (klass->open) {
+ if (!klass->open (codec))
+ goto open_failed;
+ }
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!gst_audio_decoder_start (codec)) {
@@ -2099,6 +2105,10 @@ gst_audio_decoder_change_state (GstElement * element, GstStateChange transition)
}
break;
case GST_STATE_CHANGE_READY_TO_NULL:
+ if (klass->close) {
+ if (!klass->close (codec))
+ goto close_failed;
+ }
break;
default:
break;
@@ -2116,6 +2126,16 @@ stop_failed:
GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec"));
return GST_STATE_CHANGE_FAILURE;
}
+open_failed:
+ {
+ GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to open codec"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+close_failed:
+ {
+ GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to close codec"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
}
GstFlowReturn
diff --git a/gst-libs/gst/audio/gstaudiodecoder.h b/gst-libs/gst/audio/gstaudiodecoder.h
index bd6cb8988..bf1c44e96 100644
--- a/gst-libs/gst/audio/gstaudiodecoder.h
+++ b/gst-libs/gst/audio/gstaudiodecoder.h
@@ -201,6 +201,12 @@ struct _GstAudioDecoder
* Called just prior to pushing (encoded data) buffer downstream.
* Subclass has full discretionary access to buffer,
* and a not OK flow return will abort downstream pushing.
+ * @open: Optional.
+ * Called when the element changes to GST_STATE_READY.
+ * Allows opening external resources. Since: 0.10.37.
+ * @close: Optional.
+ * Called when the element changes to GST_STATE_NULL.
+ * Allows closing external resources. Since: 0.10.37.
*
* Subclasses can override any of the available virtual methods or not, as
* needed. At minimum @handle_frame (and likely @set_format) needs to be
@@ -237,8 +243,12 @@ struct _GstAudioDecoderClass
gboolean (*event) (GstAudioDecoder *dec,
GstEvent *event);
+ gboolean (*open) (GstAudioDecoder *dec);
+
+ gboolean (*close) (GstAudioDecoder *dec);
+
/*< private >*/
- gpointer _gst_reserved[GST_PADDING_LARGE];
+ gpointer _gst_reserved[GST_PADDING_LARGE-2];
};
GType gst_audio_decoder_get_type (void);
diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c
index b915ae7f0..ea2595eef 100644
--- a/gst-libs/gst/audio/gstaudioencoder.c
+++ b/gst-libs/gst/audio/gstaudioencoder.c
@@ -301,6 +301,9 @@ static void gst_audio_encoder_set_property (GObject * object,
static void gst_audio_encoder_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
+static GstStateChangeReturn gst_audio_encoder_change_state (GstElement *
+ element, GstStateChange transition);
+
static gboolean gst_audio_encoder_sink_activate_push (GstPad * pad,
gboolean active);
@@ -317,8 +320,10 @@ static void
gst_audio_encoder_class_init (GstAudioEncoderClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
gobject_class = G_OBJECT_CLASS (klass);
+ gstelement_class = GST_ELEMENT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
GST_DEBUG_CATEGORY_INIT (gst_audio_encoder_debug, "audioencoder", 0,
@@ -349,6 +354,9 @@ gst_audio_encoder_class_init (GstAudioEncoderClass * klass)
"Consider discontinuity if timestamp jitter/imperfection exceeds tolerance (ns)",
0, G_MAXINT64, DEFAULT_TOLERANCE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ gstelement_class->change_state =
+ GST_DEBUG_FUNCPTR (gst_audio_encoder_change_state);
}
static void
@@ -460,6 +468,49 @@ gst_audio_encoder_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static GstStateChangeReturn
+gst_audio_encoder_change_state (GstElement * element, GstStateChange transition)
+{
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ GstAudioEncoder *enc = GST_AUDIO_ENCODER (element);
+ GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ if (klass->open) {
+ if (!klass->open (enc))
+ goto open_failed;
+ }
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ if (klass->close) {
+ if (!klass->close (enc))
+ goto close_failed;
+ }
+ default:
+ break;
+ }
+
+ return ret;
+
+open_failed:
+ {
+ GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), ("Failed to open codec"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+close_failed:
+ {
+ GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), ("Failed to close codec"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+}
+
/**
* gst_audio_encoder_finish_frame:
* @enc: a #GstAudioEncoder
diff --git a/gst-libs/gst/audio/gstaudioencoder.h b/gst-libs/gst/audio/gstaudioencoder.h
index aa4067722..2db19ab19 100644
--- a/gst-libs/gst/audio/gstaudioencoder.h
+++ b/gst-libs/gst/audio/gstaudioencoder.h
@@ -151,6 +151,12 @@ struct _GstAudioEncoder {
* for multichannel input specification). If not implemented,
* default returns gst_audio_encoder_proxy_getcaps
* applied to sink template caps.
+ * @open: Optional.
+ * Called when the element changes to GST_STATE_READY.
+ * Allows opening external resources. Since: 0.10.37.
+ * @close: Optional.
+ * Called when the element changes to GST_STATE_NULL.
+ * Allows closing external resources. Since: 0.10.37.
*
* Subclasses can override any of the available virtual methods or not, as
* needed. At minimum @set_format and @handle_frame needs to be overridden.
@@ -183,8 +189,12 @@ struct _GstAudioEncoderClass {
GstCaps * (*getcaps) (GstAudioEncoder *enc);
+ gboolean (*open) (GstAudioEncoder *enc);
+
+ gboolean (*close) (GstAudioEncoder *enc);
+
/*< private >*/
- gpointer _gst_reserved[GST_PADDING_LARGE];
+ gpointer _gst_reserved[GST_PADDING_LARGE-2];
};
GType gst_audio_encoder_get_type (void);