From 11f121859c3d3f81f3de3153a18752a70c689580 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 31 Dec 2015 17:26:46 +0100 Subject: [PATCH] ass: add ass_set_check_readorder() API function Not all API users will keep the event list on seeking. This also gives the opportunity to API users to handle severely broken files with duplicate ReadOrder entries. (It is not known whether this is really needed, however VSFilter does not deduplicate using the ReadOrder field.) --- Changelog | 2 ++ libass/ass.c | 12 ++++++++++-- libass/ass.h | 12 +++++++++++- libass/libass.sym | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index e7a25f4..ebb6825 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,6 @@ libass (0.13.2 - unreleased) + * Add ass_set_check_readorder() API function to disable use of the ReadOrder + field for duplicate checking in ass_process_chunk(). * Bug fixes * Fix an issue with the new duplicate checking, which could lead to missing subtitles after seeking. diff --git a/libass/ass.c b/libass/ass.c index 6cfa361..14264dc 100644 --- a/libass/ass.c +++ b/libass/ass.c @@ -57,6 +57,7 @@ struct parser_priv { // contains bitmap of ReadOrder IDs of all read events uint32_t *read_order_bitmap; int read_order_elems; // size in uint32_t units of read_order_bitmap + int check_readorder; }; #define ASS_STYLES_ALLOC 20 @@ -899,6 +900,11 @@ static int check_duplicate_event(ASS_Track *track, int ReadOrder) return 0; } +void ass_set_check_readorder(ASS_Track *track, int check_readorder) +{ + track->parser_priv->check_readorder = check_readorder == 1; +} + /** * \brief Process a chunk of subtitle stream data. In Matroska, this contains exactly 1 event (or a commentary). * \param track track @@ -915,8 +921,9 @@ void ass_process_chunk(ASS_Track *track, char *data, int size, char *p; char *token; ASS_Event *event; + int check_readorder = track->parser_priv->check_readorder; - if (!track->parser_priv->read_order_bitmap) { + if (check_readorder && !track->parser_priv->read_order_bitmap) { for (int i = 0; i < track->n_events; i++) { if (test_and_set_read_order_bit(track, track->events[i].ReadOrder) < 0) break; @@ -944,7 +951,7 @@ void ass_process_chunk(ASS_Track *track, char *data, int size, do { NEXT(p, token); event->ReadOrder = atoi(token); - if (check_duplicate_event(track, event->ReadOrder)) + if (check_readorder && check_duplicate_event(track, event->ReadOrder)) break; NEXT(p, token); @@ -1332,6 +1339,7 @@ ASS_Track *ass_new_track(ASS_Library *library) free(track); return NULL; } + track->parser_priv->check_readorder = 1; return track; } diff --git a/libass/ass.h b/libass/ass.h index c2802f7..bafbe8a 100644 --- a/libass/ass.h +++ b/libass/ass.h @@ -24,7 +24,7 @@ #include #include "ass_types.h" -#define LIBASS_VERSION 0x01301000 +#define LIBASS_VERSION 0x01302000 #ifdef __cplusplus extern "C" { @@ -576,6 +576,16 @@ void ass_process_codec_private(ASS_Track *track, char *data, int size); void ass_process_chunk(ASS_Track *track, char *data, int size, long long timecode, long long duration); +/** + * \brief Set whether the ReadOrder field when processing a packet with + * ass_process_chunk() should be used for eliminating duplicates. + * \param check_readorder 0 means do not try to eliminate duplicates; 1 means + * use the ReadOrder field embedded in the packet as unique identifier, and + * discard the packet if there was already a packet with the same ReadOrder. + * Other values are undefined. + */ +void ass_set_check_readorder(ASS_Track *track, int check_readorder); + /** * \brief Flush buffered events. * \param track track diff --git a/libass/libass.sym b/libass/libass.sym index 5cdca1f..42ca0cd 100644 --- a/libass/libass.sym +++ b/libass/libass.sym @@ -42,3 +42,4 @@ ass_set_line_position ass_set_pixel_aspect ass_set_selective_style_override_enabled ass_set_selective_style_override +ass_set_check_readorder -- 2.40.0