avformat/matroskaenc: Avoid unnecessary seek

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@gmail.com>
This commit is contained in:
Andreas Rheinhardt 2019-12-29 12:50:46 +01:00
parent 8c89fc18e6
commit b1c3d711df
1 changed files with 11 additions and 12 deletions

View File

@ -437,24 +437,23 @@ 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 * and seek to destpos afterwards. When error_on_seek_failure
* is not set, failure to seek to the position designated for the * is not set, failure to seek to the position designated for the
* SeekHead is not considered an error; failure to seek back afterwards * SeekHead is not considered an error and it is presumed that
* is always an error. * destpos is the current position; failure to seek to destpos
* afterwards is always an error.
* *
* @return 0 on success, < 0 on error. * @return 0 on success, < 0 on error.
*/ */
static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv, 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; AVIOContext *dyn_cp;
mkv_seekhead *seekhead = &mkv->seekhead; mkv_seekhead *seekhead = &mkv->seekhead;
ebml_master seekentry; ebml_master seekentry;
int64_t currentpos, remaining, ret64; int64_t remaining, ret64;
int i, ret; int i, ret;
currentpos = avio_tell(pb);
if ((ret64 = avio_seek(pb, seekhead->filepos, SEEK_SET)) < 0) if ((ret64 = avio_seek(pb, seekhead->filepos, SEEK_SET)) < 0)
return error_on_seek_failure ? ret64 : 0; return error_on_seek_failure ? ret64 : 0;
@ -479,7 +478,7 @@ static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv,
remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb); remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
put_ebml_void(pb, remaining); put_ebml_void(pb, remaining);
if ((ret64 = avio_seek(pb, currentpos, SEEK_SET)) < 0) if ((ret64 = avio_seek(pb, destpos, SEEK_SET)) < 0)
return ret64; return ret64;
return 0; return 0;
@ -1927,7 +1926,7 @@ static int mkv_write_header(AVFormatContext *s)
return ret; return ret;
if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) { 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) if (ret < 0)
return ret; return ret;
} }
@ -2539,16 +2538,16 @@ static int mkv_write_trailer(AVFormatContext *s)
mkv_add_seekhead_entry(mkv, MATROSKA_ID_CUES, cuespos); 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) if (ret < 0)
return ret; return ret;
// update the duration // update the duration
av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->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); avio_seek(mkv->info_bc, mkv->duration_offset, SEEK_SET);
put_ebml_float(mkv->info_bc, MATROSKA_ID_DURATION, mkv->duration); 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); end_ebml_master_crc32(pb, &mkv->info_bc, mkv);
// write tracks master // write tracks master