From 47b8510aa2d5fe307021bb751ccc6d0807ab4c2e Mon Sep 17 00:00:00 2001 From: Francois Cartegnie Date: Wed, 11 Sep 2013 00:16:41 +0200 Subject: [PATCH] demux: ogg: correctly handle chapters. See http://wiki.xiph.org/Chapter_Extension --- modules/demux/xiph_metadata.c | 75 ++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/modules/demux/xiph_metadata.c b/modules/demux/xiph_metadata.c index 58b1da45de..482f898176 100644 --- a/modules/demux/xiph_metadata.c +++ b/modules/demux/xiph_metadata.c @@ -112,6 +112,42 @@ error: return p_attachment; } +typedef struct chapter_entry_t +{ + int i_index; + seekpoint_t *p_seekpoint; +} chapter_entry_t; + +typedef struct chapters_array_t +{ + int i_num; + chapter_entry_t ** pp_chapters; +} chapters_array_t; + +static chapter_entry_t * getChapterEntry( int i_index, chapters_array_t *p_array ) +{ + chapter_entry_t *p_chapter = NULL; + for( int i=0; ii_num; i++ ) + { + if ( p_array->pp_chapters[i]->i_index == i_index ) + { + p_chapter = p_array->pp_chapters[i]; + break; + } + } + if ( !p_chapter ) + { + p_chapter = malloc( sizeof(chapter_entry_t) ); + p_chapter->i_index = i_index; + p_chapter->p_seekpoint = vlc_seekpoint_New(); + if ( i_index > p_array->i_num ) i_index = p_array->i_num; + if ( p_array->i_num == 0 ) i_index = 0; + /* FIXME or not.. : won't sort chapters if chapter00 is missing */ + TAB_INSERT( p_array->i_num, p_array->pp_chapters, p_chapter, i_index ); + } + return p_chapter; +} + void vorbis_ParseComment( vlc_meta_t **pp_meta, const uint8_t *p_data, int i_data, int *i_attachments, input_attachment_t ***attachments, @@ -120,7 +156,6 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta, { int n; int i_comment; - seekpoint_t *sk = NULL; if( i_data < 8 ) return; @@ -167,6 +202,9 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta, bool hasEncodedBy = false; bool hasTrackTotal = false; + chapters_array_t chapters_array; + TAB_INIT( chapters_array.i_num, chapters_array.pp_chapters ); + for( ; i_comment > 0; i_comment-- ) { char *psz_comment; @@ -259,29 +297,28 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta, *i_attachments, *attachments, p_attachment ); } } - else if( !strncasecmp(psz_comment, "chapter", strlen("chapter")) ) + else if( !strncmp(psz_comment, "CHAPTER", 7) ) { - if( ppp_seekpoint == NULL ) - continue; - int i_chapt; - if( strstr( psz_comment, "name") && sscanf( psz_comment, "chapter%i=", &i_chapt ) == 1 ) + chapter_entry_t *p_chapter = NULL; + + if( strstr( psz_comment, "NAME=" ) && + sscanf( psz_comment, "CHAPTER%iNAME=", &i_chapt ) == 1 ) { char *p = strchr( psz_comment, '=' ); - *p++ = '\0'; - sk->psz_name = strdup( p ); + p_chapter = getChapterEntry( i_chapt, &chapters_array ); + if ( ! p_chapter->p_seekpoint->psz_name ) + p_chapter->p_seekpoint->psz_name = strdup( ++p ); } - else if( sscanf( psz_comment, "chapter %i=", &i_chapt ) == 1 ) + else if( sscanf( psz_comment, "CHAPTER%i=", &i_chapt ) == 1 ) { int h, m, s, ms; char *p = strchr( psz_comment, '=' ); - *p++ = '\0'; - - if( sscanf( p, "%d:%d:%d.%d", &h, &m, &s, &ms ) == 4 ) + if( p && sscanf( ++p, "%d:%d:%d.%d", &h, &m, &s, &ms ) == 4 ) { - sk = vlc_seekpoint_New(); - sk->i_time_offset = (((int64_t)h * 3600 + (int64_t)m * 60 + (int64_t)s) * 1000 + ms) * 1000; - TAB_APPEND_CAST( (seekpoint_t**), *i_seekpoint, *ppp_seekpoint, sk ); + p_chapter = getChapterEntry( i_chapt, &chapters_array ); + p_chapter->p_seekpoint->i_time_offset = + (((int64_t)h * 3600 + (int64_t)m * 60 + (int64_t)s) * 1000 + ms) * 1000; } } } @@ -302,6 +339,14 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta, free( psz_comment ); } #undef RM + + for ( int i=0; ip_seekpoint ); + free(chapters_array.pp_chapters[i]); + } + TAB_CLEAN( chapters_array.i_num, chapters_array.pp_chapters ); } const char *FindKateCategoryName( const char *psz_tag ) -- 2.39.2