avformat/subtitles: drop duplicated events
authorClément Bœsch <u@pkh.me>
Thu, 10 Sep 2015 19:17:44 +0000 (21:17 +0200)
committerClément Bœsch <u@pkh.me>
Thu, 10 Sep 2015 19:18:34 +0000 (21:18 +0200)
Fix Ticket #4843

libavformat/subtitles.c

index 5bdbc8d..f25aa0e 100644 (file)
@@ -166,6 +166,34 @@ static int cmp_pkt_sub_pos_ts(const void *a, const void *b)
     return s1->pos > s2->pos ? 1 : -1;
 }
 
+static void drop_dups(FFDemuxSubtitlesQueue *q)
+{
+    int i, drop = 0;
+
+    for (i = 1; i < q->nb_subs; i++) {
+        const int last_id = i - 1 - drop;
+        const AVPacket *last = &q->subs[last_id];
+
+        if (q->subs[i].pts        == last->pts &&
+            q->subs[i].duration   == last->duration &&
+            !strcmp(q->subs[i].data, last->data)) {
+
+            av_free_packet(&q->subs[i]);
+            drop++;
+        } else if (drop) {
+            q->subs[last_id + 1] = q->subs[i];
+            memset(&q->subs[i], 0, sizeof(q->subs[i])); // for safety
+        }
+    }
+
+    if (drop) {
+        q->nb_subs -= drop;
+
+        // TODO: forward log context down here
+        av_log(NULL, AV_LOG_WARNING, "Dropping %d duplicated subtitle events\n", drop);
+    }
+}
+
 void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q)
 {
     int i;
@@ -176,6 +204,7 @@ void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q)
     for (i = 0; i < q->nb_subs; i++)
         if (q->subs[i].duration == -1 && i < q->nb_subs - 1)
             q->subs[i].duration = q->subs[i + 1].pts - q->subs[i].pts;
+    drop_dups(q);
 }
 
 int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)