diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 7cf7724f89..67e0c7b877 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -349,6 +349,17 @@ static void end_ebml_master(AVIOContext *pb, ebml_master master) avio_seek(pb, pos, SEEK_SET); } +static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid, + uint64_t filepos) +{ + mkv_seekhead *seekhead = &mkv->seekhead; + + av_assert1(seekhead->num_entries < MAX_SEEKHEAD_ENTRIES); + + seekhead->entries[seekhead->num_entries].elementid = elementid; + seekhead->entries[seekhead->num_entries++].segmentpos = filepos - mkv->segment_offset; +} + static int start_ebml_master_crc32(AVIOContext **dyn_cp, MatroskaMuxContext *mkv) { int ret; @@ -364,11 +375,15 @@ static int start_ebml_master_crc32(AVIOContext **dyn_cp, MatroskaMuxContext *mkv static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv, uint32_t id, - int length_size, int keep_buffer) + int length_size, int keep_buffer, + int add_seekentry) { uint8_t *buf, crc[4]; int size, skip = 0; + if (add_seekentry) + mkv_add_seekhead_entry(mkv, id, avio_tell(pb)); + put_ebml_id(pb, id); size = avio_get_dyn_buf(*dyn_cp, &buf); put_ebml_length(pb, size, length_size); @@ -441,17 +456,6 @@ static void mkv_start_seekhead(MatroskaMuxContext *mkv, AVIOContext *pb) put_ebml_void(pb, mkv->seekhead.reserved_size); } -static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid, - uint64_t filepos) -{ - mkv_seekhead *seekhead = &mkv->seekhead; - - av_assert1(seekhead->num_entries < MAX_SEEKHEAD_ENTRIES); - - seekhead->entries[seekhead->num_entries].elementid = elementid; - seekhead->entries[seekhead->num_entries++].segmentpos = filepos - mkv->segment_offset; -} - /** * Write the SeekHead to the file at the location reserved for it * and seek to destpos afterwards. When error_on_seek_failure @@ -489,7 +493,7 @@ static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv, put_ebml_uint(dyn_cp, MATROSKA_ID_SEEKPOSITION, entry->segmentpos); end_ebml_master(dyn_cp, seekentry); } - end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD, 0, 0); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD, 0, 0, 0); remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb); put_ebml_void(pb, remaining); @@ -1421,7 +1425,8 @@ static int mkv_write_tracks(AVFormatContext *s) end_ebml_master_crc32_preliminary(pb, mkv->tracks_bc, MATROSKA_ID_TRACKS, &mkv->tracks_pos); else - end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, MATROSKA_ID_TRACKS, 0, 0); + end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, + MATROSKA_ID_TRACKS, 0, 0, 0); return 0; } @@ -1443,8 +1448,6 @@ static int mkv_write_chapters(AVFormatContext *s) break; } - mkv_add_seekhead_entry(mkv, MATROSKA_ID_CHAPTERS, avio_tell(pb)); - ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; @@ -1481,7 +1484,7 @@ static int mkv_write_chapters(AVFormatContext *s) end_ebml_master(dyn_cp, chapteratom); } end_ebml_master(dyn_cp, editionentry); - end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS, 0, 0); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS, 0, 0, 1); mkv->wrote_chapters = 1; return 0; @@ -1682,7 +1685,8 @@ static int mkv_write_tags(AVFormatContext *s) end_ebml_master_crc32_preliminary(s->pb, mkv->tags_bc, MATROSKA_ID_TAGS, &mkv->tags_pos); else - end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS, 0, 0); + end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, + MATROSKA_ID_TAGS, 0, 0, 0); } return 0; } @@ -1713,8 +1717,6 @@ static int mkv_write_attachments(AVFormatContext *s) if (!mkv->nb_attachments) return 0; - mkv_add_seekhead_entry(mkv, MATROSKA_ID_ATTACHMENTS, avio_tell(pb)); - ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; @@ -1746,7 +1748,7 @@ static int mkv_write_attachments(AVFormatContext *s) put_ebml_uid(dyn_cp, MATROSKA_ID_FILEUID, track->uid); end_ebml_master(dyn_cp, attached_file); } - end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS, 0, 0); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS, 0, 0, 1); return 0; } @@ -1868,7 +1870,8 @@ static int mkv_write_header(AVFormatContext *s) end_ebml_master_crc32_preliminary(s->pb, mkv->info_bc, MATROSKA_ID_INFO, &mkv->info_pos); else - end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO, 0, 0); + end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv, + MATROSKA_ID_INFO, 0, 0, 0); pb = s->pb; ret = mkv_write_tracks(s); @@ -2153,7 +2156,8 @@ static void mkv_end_cluster(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; - end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER, 0, 1); + end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, + MATROSKA_ID_CLUSTER, 0, 1, 0); if (!mkv->have_video) { for (unsigned i = 0; i < s->nb_streams; i++) mkv->tracks[i].has_cue = 0; @@ -2447,7 +2451,7 @@ static int mkv_write_trailer(AVFormatContext *s) if (mkv->cluster_pos != -1) { end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv, - MATROSKA_ID_CLUSTER, 0, 0); + MATROSKA_ID_CLUSTER, 0, 0, 0); } ret = mkv_write_chapters(s); @@ -2463,7 +2467,6 @@ static int mkv_write_trailer(AVFormatContext *s) if (mkv->cues.num_entries) { AVIOContext *cues = NULL; uint64_t size; - int64_t cuespos = endpos; int length_size = 0; ret = start_ebml_master_crc32(&cues, mkv); @@ -2490,7 +2493,6 @@ static int mkv_write_trailer(AVFormatContext *s) ffio_free_dyn_buf(&cues); goto after_cues; } else { - cuespos = mkv->cues_pos; if ((ret64 = avio_seek(pb, mkv->cues_pos, SEEK_SET)) < 0) { ffio_free_dyn_buf(&cues); return ret64; @@ -2506,9 +2508,8 @@ static int mkv_write_trailer(AVFormatContext *s) } } } - mkv_add_seekhead_entry(mkv, MATROSKA_ID_CUES, cuespos); end_ebml_master_crc32(pb, &cues, mkv, MATROSKA_ID_CUES, - length_size, 0); + length_size, 0, 1); if (mkv->reserve_cues_space) { if (size < mkv->reserve_cues_space) put_ebml_void(pb, mkv->reserve_cues_space - size); @@ -2525,13 +2526,13 @@ static int mkv_write_trailer(AVFormatContext *s) av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); avio_seek(mkv->info_bc, mkv->duration_offset, SEEK_SET); put_ebml_float(mkv->info_bc, MATROSKA_ID_DURATION, mkv->duration); - end_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO, 0, 0); + end_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO, 0, 0, 0); if (mkv->tracks_bc) { // write Tracks master avio_seek(pb, mkv->tracks_pos, SEEK_SET); end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, - MATROSKA_ID_TRACKS, 0, 0); + MATROSKA_ID_TRACKS, 0, 0, 0); } // update stream durations @@ -2559,7 +2560,8 @@ static int mkv_write_trailer(AVFormatContext *s) } avio_seek(pb, mkv->tags_pos, SEEK_SET); - end_ebml_master_crc32(pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS, 0, 0); + end_ebml_master_crc32(pb, &mkv->tags_bc, mkv, + MATROSKA_ID_TAGS, 0, 0, 0); } avio_seek(pb, endpos, SEEK_SET);