GstTypeFindFactory *factory; /* for logging */
GstObject *obj; /* for logging */
GstObject *parent;
+ GstFlowReturn flow_ret;
} GstTypeFindHelper;
/*
{
GstTypeFindHelper *helper;
GstBuffer *buffer;
- GstFlowReturn ret;
GSList *insert_pos = NULL;
gsize buf_size;
guint64 buf_offset;
* of the file is also not a problem here, we'll just get a truncated buffer
* in that case (and we'll have to double-check the size we actually get
* anyway, see below) */
- ret =
+ helper->flow_ret =
helper->func (helper->obj, helper->parent, offset, MAX (size, 4096),
&buffer);
- if (ret != GST_FLOW_OK)
+ if (helper->flow_ret != GST_FLOW_OK)
goto error;
#if 0
error:
{
- GST_INFO ("typefind function returned: %s", gst_flow_get_name (ret));
+ GST_INFO ("typefind function returned: %s",
+ gst_flow_get_name (helper->flow_ret));
return NULL;
}
map_failed:
GstTypeFindHelperGetRangeFunction func, guint64 size,
const gchar * extension, GstTypeFindProbability * prob)
{
+ GstCaps *caps = NULL;
+
+ gst_type_find_helper_get_range_full (obj, parent, func, size, extension,
+ &caps, prob);
+
+ return caps;
+}
+
+/**
+ * gst_type_find_helper_get_range_full:
+ * @obj: A #GstObject that will be passed as first argument to @func
+ * @parent: (allow-none): the parent of @obj or %NULL
+ * @func: (scope call): A generic #GstTypeFindHelperGetRangeFunction that will
+ * be used to access data at random offsets when doing the typefinding
+ * @size: The length in bytes
+ * @extension: (allow-none): extension of the media, or %NULL
+ * @caps: (out) (transfer full): returned caps
+ * @prob: (out) (allow-none): location to store the probability of the found
+ * caps, or %NULL
+ *
+ * Utility function to do pull-based typefinding. Unlike gst_type_find_helper()
+ * however, this function will use the specified function @func to obtain the
+ * data needed by the typefind functions, rather than operating on a given
+ * source pad. This is useful mostly for elements like tag demuxers which
+ * strip off data at the beginning and/or end of a file and want to typefind
+ * the stripped data stream before adding their own source pad (the specified
+ * callback can then call the upstream peer pad with offsets adjusted for the
+ * tag size, for example).
+ *
+ * When @extension is not %NULL, this function will first try the typefind
+ * functions for the given extension, which might speed up the typefinding
+ * in many cases.
+ *
+ * Returns: the last %GstFlowReturn from pulling a buffer or %GST_FLOW_OK if
+ * typefinding was successful.
+ *
+ * Since: 1.16
+ */
+GstFlowReturn
+gst_type_find_helper_get_range_full (GstObject * obj, GstObject * parent,
+ GstTypeFindHelperGetRangeFunction func, guint64 size,
+ const gchar * extension, GstCaps ** caps, GstTypeFindProbability * prob)
+{
GstTypeFindHelper helper;
GstTypeFind find;
GSList *walk;
GList *l, *type_list;
GstCaps *result = NULL;
- g_return_val_if_fail (GST_IS_OBJECT (obj), NULL);
- g_return_val_if_fail (func != NULL, NULL);
+ g_return_val_if_fail (GST_IS_OBJECT (obj), GST_FLOW_ERROR);
+ g_return_val_if_fail (func != NULL, GST_FLOW_ERROR);
+ g_return_val_if_fail (caps != NULL, GST_FLOW_ERROR);
+
+ *caps = NULL;
helper.buffers = NULL;
helper.size = size;
helper.caps = NULL;
helper.obj = obj;
helper.parent = parent;
+ helper.flow_ret = GST_FLOW_OK;
find.data = &helper;
find.peek = helper_find_peek;
for (l = type_list; l; l = l->next) {
helper.factory = GST_TYPE_FIND_FACTORY (l->data);
gst_type_find_factory_call_function (helper.factory, &find);
- if (helper.best_probability >= GST_TYPE_FIND_MAXIMUM)
+ if (helper.best_probability >= GST_TYPE_FIND_MAXIMUM) {
+ /* Any other flow return can be ignored here, we found
+ * something before any error with highest probability */
+ helper.flow_ret = GST_FLOW_OK;
+ break;
+ } else if (helper.flow_ret != GST_FLOW_OK
+ && helper.flow_ret != GST_FLOW_EOS) {
+ /* We had less than maximum probability and an error, don't return
+ * any caps as they might be with a lower probability than what
+ * we would've gotten when continuing if there was no error */
+ gst_caps_replace (&helper.caps, NULL);
break;
+ }
}
gst_plugin_feature_list_free (type_list);
if (prob)
*prob = helper.best_probability;
+ *caps = result;
+ if (helper.flow_ret == GST_FLOW_EOS) {
+ /* Some typefinder might've tried to read too much, if we
+ * didn't get any meaningful caps because of that this is
+ * just a normal error */
+ helper.flow_ret = GST_FLOW_ERROR;
+ }
+
GST_LOG_OBJECT (obj, "Returning %" GST_PTR_FORMAT " (probability = %u)",
result, (guint) helper.best_probability);
- return result;
+ return helper.flow_ret;
}
/**