diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 5c07887e9b..9dea62eb5f 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1101,6 +1101,17 @@ typedef struct AVFormatContext { */ unsigned int max_picture_buffer; + /** + * Number of chapters in AVChapter array. + * When muxing, chapters are normally written in the file header, + * so nb_chapters should normally be initialized before write_header + * is called. Some muxers (e.g. mov and mkv) can also write chapters + * in the trailer. To write chapters in the trailer, nb_chapters + * must be zero when write_header is called and non-zero when + * write_trailer is called. + * muxing : set by user + * demuxing: set by libavformat + */ unsigned int nb_chapters; AVChapter **chapters; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index aa979eab6e..b6cf9dd262 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -109,6 +109,7 @@ typedef struct MatroskaMuxContext { int64_t cluster_time_limit; uint32_t chapter_id_offset; + int wrote_chapters; } MatroskaMuxContext; @@ -790,7 +791,7 @@ static int mkv_write_chapters(AVFormatContext *s) AVRational scale = {1, 1E9}; int i, ret; - if (!s->nb_chapters) + if (!s->nb_chapters || mkv->wrote_chapters) return 0; ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, avio_tell(pb)); @@ -823,6 +824,8 @@ static int mkv_write_chapters(AVFormatContext *s) } end_ebml_master(pb, editionentry); end_ebml_master(pb, chapters); + + mkv->wrote_chapters = 1; return 0; } @@ -1610,6 +1613,11 @@ static int mkv_write_trailer(AVFormatContext *s) end_ebml_master(pb, mkv->cluster); } + if (mkv->mode != MODE_WEBM) { + ret = mkv_write_chapters(s); + if (ret < 0) return ret; + } + if (pb->seekable) { if (mkv->cues->num_entries) { if (mkv->reserve_cues_space) {