*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
* SECTION:gsttypefindhelper
- * @short_description: Utility functions for typefinding
+ * @title: GstTypeFindHelper
+ * @short_description: Utility functions for typefinding
*
* Utility functions for elements doing typefinding:
* gst_type_find_helper() does typefinding in pull mode, while
/* ********************** typefinding in pull mode ************************ */
static void
-helper_find_suggest (gpointer data, guint probability, const GstCaps * caps);
+helper_find_suggest (gpointer data, guint probability, GstCaps * caps);
+
+typedef struct
+{
+ GstBuffer *buffer;
+ GstMapInfo map;
+} GstMappedBuffer;
typedef struct
{
* for performance reasons, but mostly because pointers returned by us need
* to stay valid until typefinding has finished)
*
- * Returns: address of the data or %NULL if buffer does not cover the
- * requested range.
+ * Returns: (nullable): address of the data or %NULL if buffer does not cover
+ * the requested range.
*/
static const guint8 *
helper_find_peek (gpointer data, gint64 offset, guint size)
GSList *insert_pos = NULL;
gsize buf_size;
guint64 buf_offset;
+ GstMappedBuffer *bmap;
#if 0
GstCaps *caps;
#endif
GSList *walk;
for (walk = helper->buffers; walk; walk = walk->next) {
- GstBuffer *buf = GST_BUFFER_CAST (walk->data);
- guint64 buf_offset = GST_BUFFER_OFFSET (buf);
- guint buf_size = gst_buffer_get_size (buf);
+ GstMappedBuffer *bmp = (GstMappedBuffer *) walk->data;
+ GstBuffer *buf = GST_BUFFER_CAST (bmp->buffer);
+
+ buf_offset = GST_BUFFER_OFFSET (buf);
+ buf_size = bmp->map.size;
/* buffers are kept sorted by end offset (highest first) in the list, so
- * at this point we save the current position and stop searching if
+ * at this point we save the current position and stop searching if
* we're after the searched end offset */
if (buf_offset <= offset) {
if ((offset + size) < (buf_offset + buf_size)) {
- guint8 *data;
-
- /* FIXME, unmap after usage */
- data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
-
- return data + (offset - buf_offset);
+ /* must already have been mapped before */
+ return (guint8 *) bmp->map.data + (offset - buf_offset);
}
} else if (offset + size >= buf_offset + buf_size) {
insert_pos = walk;
#endif
/* getrange might silently return shortened buffers at the end of a file,
- * we must, however, always return either the full requested data or NULL */
+ * we must, however, always return either the full requested data or %NULL */
buf_offset = GST_BUFFER_OFFSET (buffer);
buf_size = gst_buffer_get_size (buffer);
return NULL;
}
+ bmap = g_slice_new0 (GstMappedBuffer);
+
+ if (!gst_buffer_map (buffer, &bmap->map, GST_MAP_READ))
+ goto map_failed;
+
+ bmap->buffer = buffer;
+
if (insert_pos) {
- helper->buffers =
- g_slist_insert_before (helper->buffers, insert_pos, buffer);
+ helper->buffers = g_slist_insert_before (helper->buffers, insert_pos, bmap);
} else {
/* if insert_pos is not set, our offset is bigger than the largest offset
* we have so far; since we keep the list sorted with highest offsets
* first, we need to prepend the buffer to the list */
helper->last_offset = GST_BUFFER_OFFSET (buffer) + buf_size;
- helper->buffers = g_slist_prepend (helper->buffers, buffer);
+ helper->buffers = g_slist_prepend (helper->buffers, bmap);
}
- /* FIXME, unmap */
- return gst_buffer_map (buffer, NULL, NULL, GST_MAP_READ);
+ return bmap->map.data;
error:
{
GST_INFO ("typefind function returned: %s", gst_flow_get_name (ret));
return NULL;
}
+map_failed:
+ {
+ GST_ERROR ("map failed");
+ gst_buffer_unref (buffer);
+ g_slice_free (GstMappedBuffer, bmap);
+ return NULL;
+ }
}
/*
* If given @probability is higher, replace previously store caps.
*/
static void
-helper_find_suggest (gpointer data, GstTypeFindProbability probability,
- const GstCaps * caps)
+helper_find_suggest (gpointer data, guint probability, GstCaps * caps)
{
GstTypeFindHelper *helper = (GstTypeFindHelper *) data;
GST_OBJECT_NAME (helper->factory), probability, caps);
if (probability > helper->best_probability) {
- GstCaps *copy = gst_caps_copy (caps);
-
- gst_caps_replace (&helper->caps, copy);
- gst_caps_unref (copy);
+ gst_caps_replace (&helper->caps, caps);
helper->best_probability = probability;
}
}
/**
* gst_type_find_helper_get_range:
* @obj: A #GstObject that will be passed as first argument to @func
- * @parent: the parent of @obj or NULL
+ * @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: extension of the media
* @prob: (out) (allow-none): location to store the probability of the found
- * caps, or #NULL
+ * 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
* 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
+ * 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.
*
* Free-function: gst_caps_unref
*
- * Returns: (transfer full): the #GstCaps corresponding to the data stream.
- * Returns #NULL if no #GstCaps matches the data stream.
- *
- * Since: 0.10.26
+ * Returns: (transfer full) (nullable): the #GstCaps corresponding to the data
+ * stream. Returns %NULL if no #GstCaps matches the data stream.
*/
GstCaps *
gst_type_find_helper_get_range (GstObject * obj, GstObject * parent,
extension);
for (l = type_list; l; l = next) {
+ const gchar *const *ext;
GstTypeFindFactory *factory;
- gint i;
- gchar **ext;
next = l->next;
GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
GST_OBJECT_NAME (factory), extension);
- for (i = 0; ext[i]; i++) {
- if (strcmp (ext[i], extension) == 0) {
+ while (*ext != NULL) {
+ if (strcmp (*ext, extension) == 0) {
/* found extension, move in front */
GST_LOG_OBJECT (obj, "moving typefind for extension %s to head",
extension);
pos++;
break;
}
+ ++ext;
}
}
}
}
gst_plugin_feature_list_free (type_list);
- for (walk = helper.buffers; walk; walk = walk->next)
- gst_buffer_unref (GST_BUFFER_CAST (walk->data));
+ for (walk = helper.buffers; walk; walk = walk->next) {
+ GstMappedBuffer *bmap = (GstMappedBuffer *) walk->data;
+
+ gst_buffer_unmap (bmap->buffer, &bmap->map);
+ gst_buffer_unref (bmap->buffer);
+ g_slice_free (GstMappedBuffer, bmap);
+ }
g_slist_free (helper.buffers);
if (helper.best_probability > 0)
*
* Free-function: gst_caps_unref
*
- * Returns: (transfer full): the #GstCaps corresponding to the data stream.
- * Returns #NULL if no #GstCaps matches the data stream.
+ * Returns: (transfer full) (nullable): the #GstCaps corresponding to the data
+ * stream. Returns %NULL if no #GstCaps matches the data stream.
*/
GstCaps *
*
* Get data pointer within a buffer.
*
- * Returns: address inside the buffer or %NULL if buffer does not cover the
- * requested range.
+ * Returns: (nullable): address inside the buffer or %NULL if buffer does not
+ * cover the requested range.
*/
static const guint8 *
buf_helper_find_peek (gpointer data, gint64 off, guint size)
return NULL;
}
- if ((off + size) <= helper->size)
+ if (((guint64) off + size) <= helper->size)
return helper->data + off;
return NULL;
* If given @probability is higher, replace previously store caps.
*/
static void
-buf_helper_find_suggest (gpointer data, GstTypeFindProbability probability,
- const GstCaps * caps)
+buf_helper_find_suggest (gpointer data, guint probability, GstCaps * caps)
{
GstTypeFindBufHelper *helper = (GstTypeFindBufHelper *) data;
/* Note: not >= as we call typefinders in order of rank, highest first */
if (probability > helper->best_probability) {
- GstCaps *copy = gst_caps_copy (caps);
-
- gst_caps_replace (&helper->caps, copy);
- gst_caps_unref (copy);
+ gst_caps_replace (&helper->caps, caps);
helper->best_probability = probability;
}
}
/**
* gst_type_find_helper_for_data:
- * @obj: object doing the typefinding, or NULL (used for logging)
+ * @obj: (allow-none): object doing the typefinding, or %NULL (used for logging)
* @data: (in) (transfer none): a pointer with data to typefind
- * @size: (in) (transfer none): the size of @data
+ * @size: (in): the size of @data
* @prob: (out) (allow-none): location to store the probability of the found
- * caps, or #NULL
+ * caps, or %NULL
*
* Tries to find what type of data is contained in the given @data, the
* assumption being that the data represents the beginning of the stream or
* file.
*
* All available typefinders will be called on the data in order of rank. If
- * a typefinding function returns a probability of #GST_TYPE_FIND_MAXIMUM,
+ * a typefinding function returns a probability of %GST_TYPE_FIND_MAXIMUM,
* typefinding is stopped immediately and the found caps will be returned
* right away. Otherwise, all available typefind functions will the tried,
- * and the caps with the highest probability will be returned, or #NULL if
+ * and the caps with the highest probability will be returned, or %NULL if
* the content of @data could not be identified.
*
* Free-function: gst_caps_unref
*
- * Returns: (transfer full): the #GstCaps corresponding to the data, or #NULL
- * if no type could be found. The caller should free the caps returned
- * with gst_caps_unref().
+ * Returns: (transfer full) (nullable): the #GstCaps corresponding to the data,
+ * or %NULL if no type could be found. The caller should free the caps
+ * returned with gst_caps_unref().
*/
GstCaps *
gst_type_find_helper_for_data (GstObject * obj, const guint8 * data, gsize size,
/**
* gst_type_find_helper_for_buffer:
- * @obj: object doing the typefinding, or NULL (used for logging)
+ * @obj: (allow-none): object doing the typefinding, or %NULL (used for logging)
* @buf: (in) (transfer none): a #GstBuffer with data to typefind
* @prob: (out) (allow-none): location to store the probability of the found
- * caps, or #NULL
+ * caps, or %NULL
*
* Tries to find what type of data is contained in the given #GstBuffer, the
* assumption being that the buffer represents the beginning of the stream or
* file.
*
* All available typefinders will be called on the data in order of rank. If
- * a typefinding function returns a probability of #GST_TYPE_FIND_MAXIMUM,
+ * a typefinding function returns a probability of %GST_TYPE_FIND_MAXIMUM,
* typefinding is stopped immediately and the found caps will be returned
* right away. Otherwise, all available typefind functions will the tried,
- * and the caps with the highest probability will be returned, or #NULL if
+ * and the caps with the highest probability will be returned, or %NULL if
* the content of the buffer could not be identified.
*
* Free-function: gst_caps_unref
*
- * Returns: (transfer full): the #GstCaps corresponding to the data, or #NULL
- * if no type could be found. The caller should free the caps returned
- * with gst_caps_unref().
+ * Returns: (transfer full) (nullable): the #GstCaps corresponding to the data,
+ * or %NULL if no type could be found. The caller should free the caps
+ * returned with gst_caps_unref().
*/
GstCaps *
gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
GstTypeFindProbability * prob)
{
GstCaps *result;
- guint8 *data;
- gsize size;
+ GstMapInfo info;
g_return_val_if_fail (buf != NULL, NULL);
g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
g_return_val_if_fail (GST_BUFFER_OFFSET (buf) == 0 ||
GST_BUFFER_OFFSET (buf) == GST_BUFFER_OFFSET_NONE, NULL);
- data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
- result = gst_type_find_helper_for_data (obj, data, size, prob);
- gst_buffer_unmap (buf, data, size);
+ if (!gst_buffer_map (buf, &info, GST_MAP_READ))
+ return NULL;
+ result = gst_type_find_helper_for_data (obj, info.data, info.size, prob);
+ gst_buffer_unmap (buf, &info);
return result;
}
/**
* gst_type_find_helper_for_extension:
- * @obj: (allow-none): object doing the typefinding, or NULL (used for logging)
+ * @obj: (allow-none): object doing the typefinding, or %NULL (used for logging)
* @extension: an extension
*
* Tries to find the best #GstCaps associated with @extension.
*
* Free-function: gst_caps_unref
*
- * Returns: (transfer full): the #GstCaps corresponding to @extension, or
- * #NULL if no type could be found. The caller should free the caps
- * returned with gst_caps_unref().
- *
- * Since: 0.10.23
+ * Returns: (transfer full) (nullable): the #GstCaps corresponding to
+ * @extension, or %NULL if no type could be found. The caller should free
+ * the caps returned with gst_caps_unref().
*/
GstCaps *
gst_type_find_helper_for_extension (GstObject * obj, const gchar * extension)
for (l = type_list; l; l = g_list_next (l)) {
GstTypeFindFactory *factory;
- gchar **ext;
- gint i;
+ const gchar *const *ext;
factory = GST_TYPE_FIND_FACTORY (l->data);
/* we only want to check those factories without a function */
- if (factory->function != NULL)
+ if (gst_type_find_factory_has_function (factory))
continue;
/* get the extension that this typefind factory can handle */
/* there are extension, see if one of them matches the requested
* extension */
- for (i = 0; ext[i]; i++) {
- if (strcmp (ext[i], extension) == 0) {
+ while (*ext != NULL) {
+ if (strcmp (*ext, extension) == 0) {
/* we found a matching extension, take the caps */
if ((result = gst_type_find_factory_get_caps (factory))) {
gst_caps_ref (result);
goto done;
}
}
+ ++ext;
}
}
done: