[FFmpeg-devel] [PATCH 07/13] avformat/matroskaenc: Don't segfault when seekability changes
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Mon May 18 02:50:27 EEST 2020
Andreas Rheinhardt:
> 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>
> ---
> It seems that the whole code was based around the presumption that the
> seekability does not change mid-stream. E.g. before add68dcca there were
> the way level 1 elements were written depended upon the seekability and
> the output would be corrupt if it changed between opening and closing.
>
> Given the lack of tickets about this it seems that this assumption holds
> true. Therefore this patch uses the existence of the Tracks buffer as
> proxy for seekability.
>
> libavformat/matroskaenc.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
> index 99b549ecc4..1a142403fa 100644
> --- a/libavformat/matroskaenc.c
> +++ b/libavformat/matroskaenc.c
> @@ -2186,7 +2186,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const 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->track.bc) {
> int filler, output_sample_rate = 0;
> ret = get_aac_sample_rates(s, side_data, side_data_size, &track->sample_rate,
> &output_sample_rate);
> @@ -2213,7 +2213,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const 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->track.bc) {
> uint8_t *old_extradata = par->extradata;
> if (side_data_size != par->extradata_size) {
> av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n",
> @@ -2229,8 +2229,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const 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->track.bc && !par->extradata_size) {
> AVIOContext *dyn_cp;
> uint8_t *codecpriv;
> int codecpriv_size;
> @@ -2541,6 +2540,7 @@ static int mkv_write_trailer(AVFormatContext *s)
> if (ret < 0)
> return ret;
>
> + if (mkv->info.bc) {
> // update the duration
> av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
> avio_seek(mkv->info.bc, mkv->duration_offset, SEEK_SET);
> @@ -2549,6 +2549,7 @@ static int mkv_write_trailer(AVFormatContext *s)
> MATROSKA_ID_INFO, 0, 0, 0);
> if (ret < 0)
> return ret;
> + }
>
> if (mkv->track.bc) {
> // write Tracks master
>
Will apply this patchset tomorrow unless there are objections.
- Andreas
More information about the ffmpeg-devel
mailing list