summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2010-09-12 16:36:15 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2010-09-14 08:42:44 +0200
commitb54c4b486ab923c9708fbd9d6cf1d4bfb6a3f320 (patch)
tree5d498a3f0be1b87246a7c09fb707cfe615195625
parent168aceb3da00186f21297a679fcdf5a5e21e2ea0 (diff)
video: Refactor convert_frame a bit and fix some minor memory leaks in error cases
-rw-r--r--gst-libs/gst/video/convertframe.c174
1 files changed, 106 insertions, 68 deletions
diff --git a/gst-libs/gst/video/convertframe.c b/gst-libs/gst/video/convertframe.c
index f99a695df..6694a6c19 100644
--- a/gst-libs/gst/video/convertframe.c
+++ b/gst-libs/gst/video/convertframe.c
@@ -108,40 +108,14 @@ fail:
return encoder;
}
-/**
- * gst_video_convert_frame:
- * @buf: a #GstBuffer
- * @to_caps: the #GstCaps to convert to
- * @timeout: the maximum amount of time allowed for the processing.
- * @err: pointer to a #GError. Can be %NULL.
- *
- * Converts a raw video buffer into the specified output caps.
- *
- * The output caps can be any raw video formats or any image formats (jpeg, png, ...).
- *
- * The width, height and pixel-aspect-ratio can also be specified in the output caps.
- *
- * Returns: The converted #GstBuffer, or %NULL if an error happened (in which case @err
- * will point to the #GError).
- */
-GstBuffer *
-gst_video_convert_frame (GstBuffer * buf, const GstCaps * to_caps,
- GstClockTime timeout, GError ** err)
+static GstElement *
+build_convert_frame_pipeline (GstElement ** src_element,
+ GstElement ** sink_element, const GstCaps * from_caps,
+ const GstCaps * to_caps, GError ** err)
{
- GstElement *src = NULL, *csp = NULL, *vscale = NULL, *sink = NULL, *encoder =
- NULL, *pipeline;
- GstMessage *msg;
- GstBuffer *result = NULL;
+ GstElement *src = NULL, *csp = NULL, *vscale = NULL;
+ GstElement *sink = NULL, *encoder = NULL, *pipeline;
GError *error = NULL;
- GstBus *bus;
- GstCaps *from_caps;
- GstFlowReturn ret;
-
- g_return_val_if_fail (buf != NULL, NULL);
- g_return_val_if_fail (to_caps != NULL, NULL);
- g_return_val_if_fail (GST_BUFFER_CAPS (buf) != NULL, NULL);
-
- from_caps = GST_BUFFER_CAPS (buf);
/* videoscale is here to correct for the pixel-aspect-ratio for us */
GST_DEBUG ("creating elements");
@@ -194,6 +168,104 @@ gst_video_convert_frame (GstBuffer * buf, const GstCaps * to_caps,
goto link_failed;
}
+ *src_element = src;
+ *sink_element = sink;
+
+ return pipeline;
+ /* ERRORS */
+no_encoder:
+ {
+ gst_object_unref (pipeline);
+
+ GST_ERROR ("could not find an encoder for provided caps");
+ if (err)
+ *err = error;
+ else
+ g_error_free (error);
+
+ return NULL;
+ }
+no_elements:
+ {
+ if (src)
+ gst_object_unref (src);
+ if (csp)
+ gst_object_unref (csp);
+ if (vscale)
+ gst_object_unref (vscale);
+ if (sink)
+ gst_object_unref (sink);
+ GST_ERROR ("Could not convert video frame: %s", error->message);
+ if (err)
+ *err = error;
+ else
+ g_error_free (error);
+ return NULL;
+ }
+no_pipeline:
+ {
+ gst_object_unref (src);
+ gst_object_unref (csp);
+ gst_object_unref (vscale);
+ gst_object_unref (sink);
+
+ GST_ERROR ("Could not convert video frame: no pipeline (unknown error)");
+ if (err)
+ *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
+ "Could not convert video frame: no pipeline (unknown error)");
+ return NULL;
+ }
+link_failed:
+ {
+ gst_object_unref (pipeline);
+
+ GST_ERROR ("Could not convert video frame: failed to link elements");
+ if (err)
+ *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
+ "Could not convert video frame: failed to link elements");
+ return NULL;
+ }
+}
+
+/**
+ * gst_video_convert_frame:
+ * @buf: a #GstBuffer
+ * @to_caps: the #GstCaps to convert to
+ * @timeout: the maximum amount of time allowed for the processing.
+ * @err: pointer to a #GError. Can be %NULL.
+ *
+ * Converts a raw video buffer into the specified output caps.
+ *
+ * The output caps can be any raw video formats or any image formats (jpeg, png, ...).
+ *
+ * The width, height and pixel-aspect-ratio can also be specified in the output caps.
+ *
+ * Returns: The converted #GstBuffer, or %NULL if an error happened (in which case @err
+ * will point to the #GError).
+ */
+GstBuffer *
+gst_video_convert_frame (GstBuffer * buf, const GstCaps * to_caps,
+ GstClockTime timeout, GError ** err)
+{
+ GstMessage *msg;
+ GstBuffer *result = NULL;
+ GError *error = NULL;
+ GstBus *bus;
+ GstCaps *from_caps;
+ GstFlowReturn ret;
+ GstElement *pipeline, *src, *sink;
+
+ g_return_val_if_fail (buf != NULL, NULL);
+ g_return_val_if_fail (to_caps != NULL, NULL);
+ g_return_val_if_fail (GST_BUFFER_CAPS (buf) != NULL, NULL);
+
+ from_caps = GST_BUFFER_CAPS (buf);
+
+ pipeline =
+ build_convert_frame_pipeline (&src, &sink, from_caps, to_caps, &error);
+ if (!pipeline)
+ goto no_pipeline;
+
/* now set the pipeline to the paused state, after we push the buffer into
* appsrc, this should preroll the converted buffer in appsink */
GST_DEBUG ("running conversion pipeline to caps %" GST_PTR_FORMAT, to_caps);
@@ -258,47 +330,13 @@ gst_video_convert_frame (GstBuffer * buf, const GstCaps * to_caps,
return result;
/* ERRORS */
-no_encoder:
+no_pipeline:
{
- GST_ERROR ("could not find an encoder for provided caps");
if (err)
*err = error;
else
g_error_free (error);
- return NULL;
- }
-no_elements:
- {
- if (src)
- gst_object_unref (src);
- if (csp)
- gst_object_unref (csp);
- if (vscale)
- gst_object_unref (vscale);
- if (sink)
- gst_object_unref (sink);
- GST_ERROR ("Could not convert video frame: %s", error->message);
- if (err)
- *err = error;
- else
- g_error_free (error);
- return NULL;
- }
-no_pipeline:
- {
- GST_ERROR ("Could not convert video frame: no pipeline (unknown error)");
- if (err)
- *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
- "Could not convert video frame: no pipeline (unknown error)");
- return NULL;
- }
-link_failed:
- {
- GST_ERROR ("Could not convert video frame: failed to link elements");
- if (err)
- *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
- "Could not convert video frame: failed to link elements");
- gst_object_unref (pipeline);
+
return NULL;
}
}