static void entry_added (GstIndex * index, GstIndexEntry * entry, App * app) { switch (entry->type) { case GST_INDEX_ENTRY_ID: GST_DEBUG ("id %d describes writer %s\n", entry->id, GST_INDEX_ID_DESCRIPTION (entry)); break; case GST_INDEX_ENTRY_FORMAT: GST_DEBUG ("%d: registered format %d for %s\n", entry->id, GST_INDEX_FORMAT_FORMAT (entry), GST_INDEX_FORMAT_KEY (entry)); break; case GST_INDEX_ENTRY_ASSOCIATION: { gint i; if (entry->id == 1 && GST_INDEX_NASSOCS (entry) == 2 && GST_INDEX_ASSOC_VALUE (entry, 1) != -1) { g_fprintf (app->f_epmap, "entrypoint: %" G_GINT64_FORMAT " ", GST_INDEX_ASSOC_VALUE (entry, 0)); g_fprintf (app->f_epmap, "%" G_GINT64_FORMAT "\n", GST_INDEX_ASSOC_VALUE (entry, 1)); fflush(app->f_epmap); } else { GST_DEBUG ("GST_INDEX_ENTRY_ASSOCIATION %p, %d: %08x ", entry, entry->id, GST_INDEX_ASSOC_FLAGS (entry)); for (i = 0; i < GST_INDEX_NASSOCS (entry); i++) { GST_DEBUG ("%d %" G_GINT64_FORMAT " ", GST_INDEX_ASSOC_FORMAT (entry, i), GST_INDEX_ASSOC_VALUE (entry, i)); } } break; } default: break; } }
static gint mem_index_compare (gconstpointer a, gconstpointer b, gpointer user_data) { GstMemIndexFormatIndex *index = user_data; gint64 val1, val2; gint64 diff; val1 = GST_INDEX_ASSOC_VALUE (((GstIndexEntry *) a), index->offset); val2 = GST_INDEX_ASSOC_VALUE (((GstIndexEntry *) b), index->offset); diff = (val2 - val1); return (diff == 0 ? 0 : (diff > 0 ? 1 : -1)); }
static gint mem_index_search (gconstpointer a, gconstpointer b) { GstMemIndexSearchData *data = (GstMemIndexSearchData *) b; GstMemIndexFormatIndex *index = data->index; gint64 val1, val2; gint64 diff; val1 = GST_INDEX_ASSOC_VALUE (((GstIndexEntry *) a), index->offset); val2 = data->value; diff = (val1 - val2); if (diff == 0) return 0; /* exact matching, don't update low/high */ if (data->exact) return (diff > 0 ? 1 : -1); if (diff < 0) { if (diff > data->low_diff) { data->low_diff = diff; data->lower = (GstIndexEntry *) a; } diff = -1; } else { if (diff < data->high_diff) { data->high_diff = diff; data->higher = (GstIndexEntry *) a; } diff = 1; } return diff; }
/** * gst_index_entry_assoc_map: * @entry: the index to search * @format: the format of the value the find * @value: a pointer to store the value * * Gets alternative formats associated with the indexentry. * * Returns: TRUE if there was a value associated with the given * format. */ gboolean gst_index_entry_assoc_map (GstIndexEntry * entry, GstFormat format, gint64 * value) { gint i; g_return_val_if_fail (entry != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); for (i = 0; i < GST_INDEX_NASSOCS (entry); i++) { if (GST_INDEX_ASSOC_FORMAT (entry, i) == format) { *value = GST_INDEX_ASSOC_VALUE (entry, i); return TRUE; } } return FALSE; }
static GstIndexEntry * gst_file_index_get_assoc_entry (GstIndex * index, gint id, GstIndexLookupMethod method, GstAssocFlags flags, GstFormat format, gint64 value, GCompareDataFunc _ignore_func, gpointer _ignore_user_data) { GstFileIndex *fileindex = GST_FILE_INDEX (index); GstFileIndexId *id_index; gint formatx = -1; gint fx; GstIndexAssociation sample; gint mx; gboolean exact; gpointer row_data; GstIndexEntry *entry; gint xx; g_return_val_if_fail (id > 0, NULL); id_index = g_hash_table_lookup (fileindex->id_index, &id); if (!id_index) { GST_WARNING_OBJECT (fileindex, "writer %d unavailable", id); return NULL; } for (fx = 0; fx < id_index->nformats; fx++) if (id_index->format[fx] == format) { formatx = fx; break; } if (formatx == -1) { GST_WARNING_OBJECT (fileindex, "format %d not available", format); return NULL; } /* this is a hack, we should use a private structure instead */ sample.format = formatx; sample.value = value; exact = _fc_bsearch (id_index->array, ARRAY_ROW_SIZE (id_index), &mx, file_index_compare, &sample, id_index); if (!exact) { if (method == GST_INDEX_LOOKUP_EXACT) return NULL; else if (method == GST_INDEX_LOOKUP_BEFORE) { if (mx == 0) return NULL; mx -= 1; } else if (method == GST_INDEX_LOOKUP_AFTER) { if (mx == id_index->array->len) return NULL; } } row_data = id_index->array->data + mx * ARRAY_ROW_SIZE (id_index); /* if exact then ignore flags (?) */ if (method != GST_INDEX_LOOKUP_EXACT) while ((GINT32_FROM_BE (ARRAY_ROW_FLAGS (row_data)) & flags) != flags) { if (method == GST_INDEX_LOOKUP_BEFORE) mx -= 1; else if (method == GST_INDEX_LOOKUP_AFTER) mx += 1; if (mx < 0 || mx >= id_index->array->len) return NULL; row_data = id_index->array->data + mx * ARRAY_ROW_SIZE (id_index); } /* entry memory management needs improvement FIXME */ if (!fileindex->ret_entry) fileindex->ret_entry = g_slice_new0 (GstIndexEntry); entry = fileindex->ret_entry; if (entry->data.assoc.assocs) { g_free (entry->data.assoc.assocs); entry->data.assoc.assocs = NULL; } entry->type = GST_INDEX_ENTRY_ASSOCIATION; GST_INDEX_NASSOCS (entry) = id_index->nformats; entry->data.assoc.assocs = g_new (GstIndexAssociation, id_index->nformats); { gint32 flags_be = ARRAY_ROW_FLAGS (row_data); GST_INDEX_ASSOC_FLAGS (entry) = GINT32_FROM_BE (flags_be); for (xx = 0; xx < id_index->nformats; xx++) { gint64 val_be = ARRAY_ROW_VALUE (row_data, xx); GST_INDEX_ASSOC_FORMAT (entry, xx) = id_index->format[xx]; GST_INDEX_ASSOC_VALUE (entry, xx) = GINT64_FROM_BE (val_be); } } return entry; }
static void gst_file_index_add_association (GstIndex * index, GstIndexEntry * entry) { GstFileIndex *fileindex = GST_FILE_INDEX (index); GstFileIndexId *id_index; gint mx; GstIndexAssociation sample; gboolean exact; id_index = g_hash_table_lookup (fileindex->id_index, &entry->id); if (!id_index) return; if (!id_index->nformats) { gint fx; id_index->nformats = GST_INDEX_NASSOCS (entry); GST_LOG_OBJECT (fileindex, "creating %d formats for %d", id_index->nformats, entry->id); id_index->format = g_new (GstFormat, id_index->nformats); for (fx = 0; fx < id_index->nformats; fx++) id_index->format[fx] = GST_INDEX_ASSOC_FORMAT (entry, fx); _fc_alloc_array (id_index); } else { /* only sanity checking */ if (id_index->nformats != GST_INDEX_NASSOCS (entry)) GST_WARNING_OBJECT (fileindex, "arity change %d -> %d", id_index->nformats, GST_INDEX_NASSOCS (entry)); else { gint fx; for (fx = 0; fx < id_index->nformats; fx++) if (id_index->format[fx] != GST_INDEX_ASSOC_FORMAT (entry, fx)) GST_WARNING_OBJECT (fileindex, "format[%d] changed %d -> %d", fx, id_index->format[fx], GST_INDEX_ASSOC_FORMAT (entry, fx)); } } /* this is a hack, we should use a private structure instead */ sample.format = 0; sample.value = GST_INDEX_ASSOC_VALUE (entry, 0); exact = _fc_bsearch (id_index->array, ARRAY_ROW_SIZE (id_index), &mx, file_index_compare, &sample, id_index); if (exact) { /* maybe overwrite instead? */ GST_DEBUG_OBJECT (index, "Ignoring duplicate index association at %" G_GINT64_FORMAT, GST_INDEX_ASSOC_VALUE (entry, 0)); return; } { gchar *row_data = (gchar *) g_malloc (ARRAY_ROW_SIZE (id_index)); gint fx; gint32 flags_host = GST_INDEX_ASSOC_FLAGS (entry); ARRAY_ROW_FLAGS (row_data) = GINT32_TO_BE (flags_host); for (fx = 0; fx < id_index->nformats; fx++) { gint64 val_host = GST_INDEX_ASSOC_VALUE (entry, fx); ARRAY_ROW_VALUE (row_data, fx) = GINT64_TO_BE (val_host); } g_array_insert_vals (id_index->array, mx, row_data, 1); g_free (row_data); } }