[FFmpeg-devel] [PATCH] lavf/matroskaenc: avoid assert failure in case of cuepoints with duplicated PTS

Stefano Sabatini stefasab at gmail.com
Sun Feb 10 21:44:35 CET 2013


Avoid to write more than one cuepoint per track and PTS in
mkv_write_cues(). This avoids a later assertion failure on "(bytes >=
needed_bytes)" in put_ebml_num() called from end_ebml_master(), in case
there are several cuepoints per track with the same PTS.

This may happen with files containing packets with duplicated PTS in the
same track.
---
 libavformat/matroskaenc.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 5c1e2f1..2542ca9 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -384,12 +384,16 @@ static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t clus
     return 0;
 }
 
-static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, int num_tracks)
+static int mkv_write_cues(AVIOContext *pb, int64_t *currentpos_ptr, mkv_cues *cues, int num_tracks)
 {
     ebml_master cues_element;
     int64_t currentpos;
+    int *track_has_cue;
     int i, j;
 
+    if (!(track_has_cue = av_malloc(sizeof(int)*num_tracks)))
+        return AVERROR(ENOMEM);
+
     currentpos = avio_tell(pb);
     cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0);
 
@@ -403,18 +407,24 @@ static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, int num_tracks)
 
         // put all the entries from different tracks that have the exact same
         // timestamp into the same CuePoint
+        memset(track_has_cue, 0, sizeof(track_has_cue) * num_tracks);
         for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {
+            if (track_has_cue[entry[j].tracknum])
+                continue;
             track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);
             put_ebml_uint(pb, MATROSKA_ID_CUETRACK          , entry[j].tracknum   );
             put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos);
             end_ebml_master(pb, track_positions);
+            track_has_cue[entry[j].tracknum] = 1;
         }
         i += j - 1;
         end_ebml_master(pb, cuepoint);
     }
     end_ebml_master(pb, cues_element);
 
-    return currentpos;
+    *currentpos_ptr = currentpos;
+    av_free(track_has_cue);
+    return 0;
 }
 
 static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec)
@@ -1335,7 +1345,8 @@ static int mkv_write_trailer(AVFormatContext *s)
 
     if (pb->seekable) {
         if (mkv->cues->num_entries) {
-            cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
+            if ((ret = mkv_write_cues(pb, &cuespos, mkv->cues, s->nb_streams)) < 0)
+                return ret;
 
             ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES, cuespos);
             if (ret < 0) return ret;
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list