[FFmpeg-devel] [PATCH 10/20] avformat/matroskaenc: Avoid unnecessary seek

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Wed Jan 1 02:58:27 EET 2020


When writing the SeekHead (a form of index) at the end of the muxing
process, mkv_write_seekhead() would first seek to the position where the
SeekHead ought to be written, then write it there and seek back to the
original position afterwards. Which means: To the end of the file.
Afterwards, a seek to the beginning of the file is performed to update
further values. This of course means that the second seek in
mkv_write_seekhead() was unnecessary.

This has been changed: A new parameter was added to mkv_write_seekhead()
containing the destination for the second seek, effectively eliminating
the seek to the end of the file after writing the SeekHead.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
 libavformat/matroskaenc.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index c7948fb643..8040c8311c 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -437,28 +437,26 @@ static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid,
 
 /**
  * Write the SeekHead to the file at the location reserved for it
- * and seek back to the initial position. When error_on_seek_failure
+ * and seek to destpos afterwards. 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.
+ * SeekHead is not considered an error; failure to seek to destpos
+ * afterwards is always an error.
  *
  * @return 0 on success, < 0 on error.
  */
 static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv,
-                              int error_on_seek_failure)
+                              int error_on_seek_failure, int64_t destpos)
 {
     AVIOContext *dyn_cp;
     mkv_seekhead *seekhead = &mkv->seekhead;
     ebml_master seekentry;
-    int64_t currentpos, remaining, ret64;
+    int64_t remaining, ret64;
     int i, ret;
 
-    currentpos = avio_tell(pb);
-
     if ((ret64 = avio_seek(pb, seekhead->filepos, SEEK_SET)) < 0) {
         if (error_on_seek_failure)
             return ret64;
-        goto seek_back;
+        goto seek;
     }
 
     ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD);
@@ -482,8 +480,8 @@ static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv,
     remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
         put_ebml_void(pb, remaining);
 
-seek_back:
-    if ((ret64 = avio_seek(pb, currentpos, SEEK_SET)) < 0)
+seek:
+    if ((ret64 = avio_seek(pb, destpos, SEEK_SET)) < 0)
         return ret64;
 
     return 0;
@@ -1929,7 +1927,7 @@ static int mkv_write_header(AVFormatContext *s)
         return ret;
 
     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) {
-        ret = mkv_write_seekhead(pb, mkv, 0);
+        ret = mkv_write_seekhead(pb, mkv, 0, avio_tell(pb));
         if (ret < 0)
             return ret;
     }
@@ -2533,16 +2531,16 @@ static int mkv_write_trailer(AVFormatContext *s)
             mkv_add_seekhead_entry(mkv, MATROSKA_ID_CUES, cuespos);
         }
 
-        ret = mkv_write_seekhead(pb, mkv, 1);
+        currentpos = avio_tell(pb);
+
+        ret = mkv_write_seekhead(pb, mkv, 1, mkv->info_pos);
         if (ret < 0)
             return ret;
 
         // update the duration
         av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
-        currentpos = avio_tell(pb);
         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);
 
         // write tracks master
-- 
2.20.1



More information about the ffmpeg-devel mailing list