From 04e0bbef178e6e0b5012266c0291455ca21889c3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 4 Jul 2012 19:52:22 +0200 Subject: [PATCH] matroska: Update for new GstToc API TOC support in matroskamux is disabled for now as it was broken anyway. --- gst/matroska/matroska-demux.c | 2 +- gst/matroska/matroska-mux.c | 40 +++++++---- gst/matroska/matroska-read-common.c | 128 +++++++++++++++++------------------- 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index b7cbaa5..e6e2537 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -2276,7 +2276,7 @@ gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent, GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid); res = FALSE; } else { - gst_toc_entry_get_start_stop (entry, &start_pos, NULL); + gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL); GST_OBJECT_UNLOCK (demux); seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME, diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index 32a3603..1a60eeb 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -2338,6 +2338,7 @@ gst_matroska_mux_track_header (GstMatroskaMux * mux, context->codec_priv, context->codec_priv_size); } +#if 0 static void gst_matroska_mux_write_chapter_title (const gchar * title, GstEbmlWrite * ebml) { @@ -2385,7 +2386,7 @@ gst_matroska_mux_write_chapter (GstMatroskaMux * mux, GstTocEntry * edition, } uid = gst_matroska_mux_create_uid (); - gst_toc_entry_get_start_stop (entry, &start, &stop); + gst_toc_entry_get_start_stop_times (entry, &start, &stop); master_chapteratom = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERATOM); @@ -2430,7 +2431,7 @@ gst_matroska_mux_write_chapter_edition (GstMatroskaMux * mux, GList *cur; GstTocEntry *subentry; - cur = entry->subentries; + cur = gst_toc_entry_get_sub_entries (entry); while (cur != NULL) { subentry = cur->data; gst_matroska_mux_write_chapter (mux, entry, subentry, ebml, master_chapters, @@ -2442,6 +2443,7 @@ gst_matroska_mux_write_chapter_edition (GstMatroskaMux * mux, if (G_LIKELY (master_edition != 0)) gst_ebml_write_master_finish (ebml, master_edition); } +#endif /** * gst_matroska_mux_start: @@ -2470,7 +2472,9 @@ gst_matroska_mux_start (GstMatroskaMux * mux) GstClockTime duration = 0; guint32 segment_uid[4]; GTimeVal time = { 0, 0 }; +#if 0 GstToc *toc; +#endif /* if not streaming, check if downstream is seekable */ if (!mux->streamable) { @@ -2622,6 +2626,9 @@ gst_matroska_mux_start (GstMatroskaMux * mux) } gst_ebml_write_master_finish (ebml, master); + /* FIXME: Check if we get a TOC that is supported by Matroska + * and clean up the code below */ +#if 0 /* chapters */ toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux)); if (toc != NULL && !mux->streamable) { @@ -2637,22 +2644,22 @@ gst_matroska_mux_start (GstMatroskaMux * mux) if (toc_entry->type != GST_TOC_ENTRY_TYPE_EDITION) { toc_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ""); - gst_toc_entry_set_start_stop (toc_entry, -1, -1); + gst_toc_entry_set_start_stop_times (toc_entry, -1, -1); /* aggregate all chapters without root edition */ - cur = toc->entries; + cur = gst_toc_get_entries (toc); while (cur != NULL) { toc_entry->subentries = g_list_prepend (toc_entry->subentries, cur->data); cur = cur->next; } - gst_toc_entry_get_start_stop (((GstTocEntry *) toc_entry->subentries-> - data), &start, NULL); + gst_toc_entry_get_start_stop_times (((GstTocEntry *) + toc_entry->subentries->data), &start, NULL); toc_entry->subentries = g_list_reverse (toc_entry->subentries); - gst_toc_entry_get_start_stop (((GstTocEntry *) toc_entry->subentries-> - data), NULL, &stop); - gst_toc_entry_set_start_stop (toc_entry, start, stop); + gst_toc_entry_get_start_stop_times (((GstTocEntry *) + toc_entry->subentries->data), NULL, &stop); + gst_toc_entry_set_start_stop_times (toc_entry, start, stop); to_write = g_list_append (to_write, toc_entry); } else { @@ -2681,12 +2688,15 @@ gst_matroska_mux_start (GstMatroskaMux * mux) g_list_free (to_write); } } +#endif /* lastly, flush the cache */ gst_ebml_write_flush_cache (ebml, FALSE, 0); +#if 0 if (toc != NULL) gst_toc_unref (toc); +#endif } static void @@ -2748,6 +2758,7 @@ gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag, } } +#if 0 static void gst_matroska_mux_write_toc_entry_tags (GstMatroskaMux * mux, const GstTocEntry * entry, guint64 * master_tags) @@ -2786,6 +2797,7 @@ gst_matroska_mux_write_toc_entry_tags (GstMatroskaMux * mux, cur = cur->next; } } +#endif /** * gst_matroska_mux_finish: @@ -2842,12 +2854,15 @@ gst_matroska_mux_finish (GstMatroskaMux * mux) if ((tags != NULL && !gst_tag_list_is_empty (tags)) || gst_toc_setter_get_toc (GST_TOC_SETTER (mux)) != NULL) { guint64 master_tags = 0, master_tag; - GList *cur; +#if 0 const GstToc *toc; +#endif GST_DEBUG_OBJECT (mux, "Writing tags"); +#if 0 toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux)); +#endif if (tags != NULL) { /* TODO: maybe limit via the TARGETS id by looking at the source pad */ @@ -2857,13 +2872,15 @@ gst_matroska_mux_finish (GstMatroskaMux * mux) if (tags != NULL) gst_tag_list_foreach (tags, gst_matroska_mux_write_simple_tag, ebml); +#if 0 if (toc != NULL) gst_tag_list_foreach (toc->tags, gst_matroska_mux_write_simple_tag, ebml); +#endif gst_ebml_write_master_finish (ebml, master_tag); } - +#if 0 if (toc != NULL) { cur = toc->entries; while (cur != NULL) { @@ -2871,6 +2888,7 @@ gst_matroska_mux_finish (GstMatroskaMux * mux) cur = cur->next; } } +#endif if (master_tags != 0) gst_ebml_write_master_finish (ebml, master_tags); diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c index 54083c2..74e53cf 100644 --- a/gst/matroska/matroska-read-common.c +++ b/gst/matroska/matroska-read-common.c @@ -729,25 +729,30 @@ gst_matroska_read_common_parse_toc_tag (GstTocEntry * entry, guint64 tgt; GArray *targets; GList *cur; + GstTagList *etags; targets = - (entry->type == + (gst_toc_entry_get_entry_type (entry) == GST_TOC_ENTRY_TYPE_EDITION) ? edition_targets : chapter_targtes; + etags = gst_tag_list_new_empty (); + for (i = 0; i < targets->len; ++i) { tgt = g_array_index (targets, guint64, i); if (tgt == 0) - gst_tag_list_insert (entry->tags, tags, GST_TAG_MERGE_APPEND); + gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND); else { uid = g_strdup_printf ("%" G_GUINT64_FORMAT, tgt); - if (g_strcmp0 (entry->uid, uid) == 0) - gst_tag_list_insert (entry->tags, tags, GST_TAG_MERGE_APPEND); + if (g_strcmp0 (gst_toc_entry_get_uid (entry), uid) == 0) + gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND); g_free (uid); } } - cur = entry->subentries; + gst_toc_entry_merge_tags (entry, etags, GST_TAG_MERGE_APPEND); + + cur = gst_toc_entry_get_sub_entries (entry); while (cur != NULL) { gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets, chapter_targtes, tags); @@ -804,31 +809,22 @@ gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries, { GstTocEntry *cur_info, *prev_info, *next_info; GList *cur_list, *prev_list, *next_list; - gchar *iter_digit; - gint i = 0; gint64 cur_start, prev_start, stop; cur_list = toc_entries; while (cur_list != NULL) { - ++i; cur_info = cur_list->data; - iter_digit = g_strdup_printf ("%d", i); - - switch (cur_info->type) { + switch (gst_toc_entry_get_entry_type (cur_info)) { case GST_TOC_ENTRY_TYPE_ANGLE: case GST_TOC_ENTRY_TYPE_VERSION: case GST_TOC_ENTRY_TYPE_EDITION: /* in Matroska terms edition has duration of full track */ - gst_toc_entry_set_start_stop (cur_info, 0, max); + gst_toc_entry_set_start_stop_times (cur_info, 0, max); - if (cur_info->uid == NULL) - cur_info->uid = - g_strconcat (parent_uid, "/", GST_MATROSKA_TOC_UID_EDITION, - iter_digit, NULL); - - gst_matroska_read_common_postprocess_toc_entries (cur_info->subentries, - max, cur_info->uid); + gst_matroska_read_common_postprocess_toc_entries + (gst_toc_entry_get_sub_entries (cur_info), max, + gst_toc_entry_get_uid (cur_info)); break; case GST_TOC_ENTRY_TYPE_TITLE: @@ -847,41 +843,37 @@ gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries, else next_info = NULL; - if (cur_info->uid == NULL) - cur_info->uid = - g_strconcat (parent_uid, "/", GST_MATROSKA_TOC_UID_CHAPTER, - iter_digit, NULL); - /* updated stop time in previous chapter and it's subchapters */ if (prev_info != NULL) { - gst_toc_entry_get_start_stop (prev_info, &prev_start, &stop); - gst_toc_entry_get_start_stop (cur_info, &cur_start, &stop); + gst_toc_entry_get_start_stop_times (prev_info, &prev_start, &stop); + gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop); stop = cur_start; - gst_toc_entry_set_start_stop (prev_info, prev_start, stop); + gst_toc_entry_set_start_stop_times (prev_info, prev_start, stop); gst_matroska_read_common_postprocess_toc_entries - (prev_info->subentries, cur_start, prev_info->uid); + (gst_toc_entry_get_sub_entries (prev_info), cur_start, + gst_toc_entry_get_uid (prev_info)); } /* updated stop time in current chapter and it's subchapters */ if (next_info == NULL) { - gst_toc_entry_get_start_stop (cur_info, &cur_start, &stop); + gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop); if (stop == -1) { stop = max; - gst_toc_entry_set_start_stop (cur_info, cur_start, stop); + gst_toc_entry_set_start_stop_times (cur_info, cur_start, stop); } gst_matroska_read_common_postprocess_toc_entries - (cur_info->subentries, stop, cur_info->uid); + (gst_toc_entry_get_sub_entries (cur_info), stop, + gst_toc_entry_get_uid (cur_info)); } break; case GST_TOC_ENTRY_TYPE_INVALID: break; } cur_list = cur_list->next; - g_free (iter_digit); } } @@ -929,14 +921,16 @@ gst_matroska_read_common_parse_chapter_titles (GstMatroskaReadCommon * common, static GstFlowReturn gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common, - GstEbmlRead * ebml, GstTocEntry * toc_entry) + GstEbmlRead * ebml, GList ** subentries) { guint32 id; guint64 start_time = -1, stop_time = -1; guint64 is_hidden = 0, is_enabled = 1, uid = 0; GstFlowReturn ret = GST_FLOW_OK; GstTocEntry *chapter_info; - GstTagList *titles; + GstTagList *tags; + gchar *uid_str; + GList *subsubentries = NULL, *l; DEBUG_ELEMENT_START (common, ebml, "ChaptersElement"); @@ -945,9 +939,7 @@ gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common, return ret; } - titles = gst_tag_list_new_empty (); - chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, - GST_MATROSKA_TOC_UID_EMPTY); + tags = gst_tag_list_new_empty (); while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) @@ -969,13 +961,12 @@ gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common, case GST_MATROSKA_ID_CHAPTERATOM: ret = gst_matroska_read_common_parse_chapter_element (common, ebml, - chapter_info); + &subsubentries); break; case GST_MATROSKA_ID_CHAPTERDISPLAY: ret = - gst_matroska_read_common_parse_chapter_titles (common, ebml, - titles); + gst_matroska_read_common_parse_chapter_titles (common, ebml, tags); break; case GST_MATROSKA_ID_CHAPTERFLAGHIDDEN: @@ -994,29 +985,29 @@ gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common, } } - gst_toc_entry_set_start_stop (chapter_info, start_time, stop_time); + if (uid == 0) + uid = (((guint64) g_random_int ()) << 32) | g_random_int (); + uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid); + chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid_str); + g_free (uid_str); - DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret); + gst_toc_entry_set_tags (chapter_info, tags); + gst_toc_entry_set_start_stop_times (chapter_info, start_time, stop_time); - g_free (chapter_info->uid); + for (l = subsubentries; l; l = l->next) + gst_toc_entry_append_sub_entry (chapter_info, l->data); + g_list_free (subsubentries); - if (uid != 0) - chapter_info->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid); - else - chapter_info->uid = NULL; + DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret); /* start time is mandatory and has no default value, * so we should skip chapters without it */ if (is_hidden == 0 && is_enabled > 0 && start_time != -1 && ret == GST_FLOW_OK) { - if (!gst_tag_list_is_empty (titles)) - gst_tag_list_insert (chapter_info->tags, titles, GST_TAG_MERGE_APPEND); - - toc_entry->subentries = g_list_append (toc_entry->subentries, chapter_info); + *subentries = g_list_append (*subentries, chapter_info); } else gst_toc_entry_unref (chapter_info); - gst_tag_list_free (titles); return ret; } @@ -1028,6 +1019,8 @@ gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common, guint64 is_hidden = 0, uid = 0; GstFlowReturn ret = GST_FLOW_OK; GstTocEntry *edition_info; + GList *subentries = NULL, *l; + gchar *uid_str; DEBUG_ELEMENT_START (common, ebml, "ChaptersEdition"); @@ -1036,11 +1029,6 @@ gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common, return ret; } - edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, - GST_MATROSKA_TOC_UID_EMPTY); - - gst_toc_entry_set_start_stop (edition_info, -1, -1); - while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) break; @@ -1053,7 +1041,7 @@ gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common, case GST_MATROSKA_ID_CHAPTERATOM: ret = gst_matroska_read_common_parse_chapter_element (common, ebml, - edition_info); + &subentries); break; case GST_MATROSKA_ID_EDITIONFLAGHIDDEN: @@ -1070,15 +1058,18 @@ gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common, DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret); - g_free (edition_info->uid); + if (uid == 0) + uid = (((guint64) g_random_int ()) << 32) | g_random_int (); + uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid); + edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, uid_str); + gst_toc_entry_set_start_stop_times (edition_info, -1, -1); + g_free (uid_str); - if (uid != 0) - edition_info->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid); - else - edition_info->uid = NULL; + for (l = subentries; l; l = l->next) + gst_toc_entry_append_sub_entry (edition_info, l->data); - if (is_hidden == 0 && edition_info->subentries != NULL && ret == GST_FLOW_OK) - toc->entries = g_list_prepend (toc->entries, edition_info); + if (is_hidden == 0 && subentries != NULL && ret == GST_FLOW_OK) + gst_toc_append_entry (toc, edition_info); else { GST_DEBUG_OBJECT (common, "Skipping empty or hidden edition in the chapters TOC"); @@ -1122,9 +1113,8 @@ gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common, } } - if (toc->entries != NULL) { - toc->entries = g_list_reverse (toc->entries); - gst_matroska_read_common_postprocess_toc_entries (toc->entries, + if (gst_toc_get_entries (toc) != NULL) { + gst_matroska_read_common_postprocess_toc_entries (gst_toc_get_entries (toc), common->segment.duration, ""); common->toc = toc; @@ -1927,7 +1917,7 @@ gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common, GST_WARNING_OBJECT (common, "Found chapter/edition specific tag, but TOC doesn't present"); else { - cur = common->toc->entries; + cur = gst_toc_get_entries (common->toc); while (cur != NULL) { gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets, chapter_targets, taglist); -- 2.7.4