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; } }
/** * 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 void gst_mem_index_index_format (GstMemIndexId * id_index, GstIndexEntry * entry, gint assoc) { GstMemIndexFormatIndex *index; GstFormat *format; format = &GST_INDEX_ASSOC_FORMAT (entry, assoc); index = g_hash_table_lookup (id_index->format_index, format); if (!index) { index = g_slice_new0 (GstMemIndexFormatIndex); index->format = *format; index->offset = assoc; index->tree = g_tree_new_with_data (mem_index_compare, index); g_hash_table_insert (id_index->format_index, &index->format, index); } g_tree_insert (index->tree, entry, entry); }
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); } }