[FFmpeg-cvslog] avformat/matroskaenc: Check for failure when writing SeekHead

Andreas Rheinhardt git at videolan.org
Mon Mar 30 07:58:08 EEST 2020


ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at gmail.com> | Sun Dec 29 09:57:44 2019 +0100| [8c89fc18e6125ae0449091d82a2fe200ed848c43] | committer: Andreas Rheinhardt

avformat/matroskaenc: Check for failure when writing SeekHead

mkv_write_seekhead() would up until now try to seek to the position where
the SeekHead ought to be written, write the SeekHead and seek back. The
first of these seeks was checked as was writing, yet the seek back was
unchecked. Moreover the return value of mkv_write_seekhead() was unchecked
(the ordinary return value was the position where the SeekHead was written).

This commit changes this: Everything is checked. In the unseekable case
(where the first seek may nevertheless work when it happens in the buffer)
a failure at the first seek is not considered an error. In any case,
failure to seek back is an error.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>

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

 libavformat/matroskaenc.c | 48 +++++++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index c484d95c2f..8eb968445d 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -436,30 +436,31 @@ static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid,
 }
 
 /**
- * Write the SeekHead to the file at the location reserved for it.
+ * Write the SeekHead to the file at the location reserved for it
+ * and seek back to the initial position. When error_on_seek_failure
+ * is not set, failure to seek to the position designated for the
+ * SeekHead is not considered an error; failure to seek back afterwards
+ * is always an error.
  *
- * @return The file offset where the seekhead was written,
- * -1 if an error occurred.
+ * @return 0 on success, < 0 on error.
  */
-static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
+static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv,
+                              int error_on_seek_failure)
 {
     AVIOContext *dyn_cp;
     mkv_seekhead *seekhead = &mkv->seekhead;
     ebml_master seekentry;
-    int64_t currentpos, remaining;
-    int i;
+    int64_t currentpos, remaining, ret64;
+    int i, ret;
 
     currentpos = avio_tell(pb);
 
-        if (avio_seek(pb, seekhead->filepos, SEEK_SET) < 0) {
-            currentpos = -1;
-            goto fail;
-        }
+    if ((ret64 = avio_seek(pb, seekhead->filepos, SEEK_SET)) < 0)
+        return error_on_seek_failure ? ret64 : 0;
 
-    if (start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD) < 0) {
-        currentpos = -1;
-        goto fail;
-    }
+    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD);
+    if (ret < 0)
+        return ret;
 
     for (i = 0; i < seekhead->num_entries; i++) {
         mkv_seekhead_entry *entry = &seekhead->entries[i];
@@ -477,13 +478,11 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
 
     remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
         put_ebml_void(pb, remaining);
-        avio_seek(pb, currentpos, SEEK_SET);
 
-        currentpos = seekhead->filepos;
+    if ((ret64 = avio_seek(pb, currentpos, SEEK_SET)) < 0)
+        return ret64;
 
-fail:
-
-    return currentpos;
+    return 0;
 }
 
 static mkv_cues *mkv_start_cues(int64_t segment_offset)
@@ -1927,8 +1926,11 @@ static int mkv_write_header(AVFormatContext *s)
     if (ret < 0)
         return ret;
 
-    if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
-        mkv_write_seekhead(pb, mkv);
+    if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
+        ret = mkv_write_seekhead(pb, mkv, 0);
+        if (ret < 0)
+            return ret;
+    }
 
     mkv->cues = mkv_start_cues(mkv->segment_offset);
     if (!mkv->cues) {
@@ -2537,7 +2539,9 @@ static int mkv_write_trailer(AVFormatContext *s)
             mkv_add_seekhead_entry(mkv, MATROSKA_ID_CUES, cuespos);
         }
 
-        mkv_write_seekhead(pb, mkv);
+        ret = mkv_write_seekhead(pb, mkv, 1);
+        if (ret < 0)
+            return ret;
 
         // update the duration
         av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);



More information about the ffmpeg-cvslog mailing list