[FFmpeg-cvslog] avformat/matroskaenc: Don't segfault when seekability changes

Andreas Rheinhardt git at videolan.org
Wed May 20 12:16:05 EEST 2020


ffmpeg | branch: release/4.2 | Andreas Rheinhardt <andreas.rheinhardt at gmail.com> | Fri May  1 20:21:45 2020 +0200| [588d258ea430cea3e954da8e553746e6f1a4b5bc] | committer: Andreas Rheinhardt

avformat/matroskaenc: Don't segfault when seekability changes

If the Matroska muxer's AVIOContext was unseekable when writing the
header, but is seekable when writing the trailer, the code for writing
the trailer presumes that a dynamic buffer exists and tries to update
its content in order to overwrite data that has already been
preliminarily written when writing the header, yet said buffer doesn't
exist as it has been written finally and not preliminarily when writing
the header (because of the unseekability it was presumed that one won't
be able to update the data anyway).

This commit adds a check for this and also for a similar situation
involving updating extradata with new data from packet side-data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
(cherry picked from commit 8aabcf6c1151b9e50ae5447da6709a72022b9a60)

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=588d258ea430cea3e954da8e553746e6f1a4b5bc
---

 libavformat/matroskaenc.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index ce42ce7cc8..0f535f61d4 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -2300,7 +2300,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt)
 
     switch (par->codec_id) {
     case AV_CODEC_ID_AAC:
-        if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
+        if (side_data_size && mkv->tracks_bc) {
             int filler, output_sample_rate = 0;
             int64_t curpos;
             ret = get_aac_sample_rates(s, side_data, side_data_size, &track->sample_rate,
@@ -2331,7 +2331,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt)
         }
         break;
     case AV_CODEC_ID_FLAC:
-        if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
+        if (side_data_size && mkv->tracks_bc) {
             AVCodecParameters *codecpriv_par;
             int64_t curpos;
             if (side_data_size != par->extradata_size) {
@@ -2358,8 +2358,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt)
     // FIXME: Remove the following once libaom starts propagating extradata during init()
     //        See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012
     case AV_CODEC_ID_AV1:
-        if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live &&
-            !par->extradata_size) {
+        if (side_data_size && mkv->tracks_bc && !par->extradata_size) {
             AVIOContext *dyn_cp;
             uint8_t *codecpriv;
             int codecpriv_size;
@@ -2639,14 +2638,18 @@ static int mkv_write_trailer(AVFormatContext *s)
         // update the duration
         av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
         currentpos = avio_tell(pb);
+        if (mkv->info_bc) {
         avio_seek(mkv->info_bc, mkv->duration_offset, SEEK_SET);
         put_ebml_float(mkv->info_bc, MATROSKA_ID_DURATION, mkv->duration);
         avio_seek(pb, mkv->info_pos, SEEK_SET);
         end_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO);
+        }
 
+        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);
+        }
 
         // update stream durations
         if (!mkv->is_live && mkv->stream_durations) {



More information about the ffmpeg-cvslog mailing list