[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