You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
avformat/mov: Simplify cleanup after read_header failure
By default, a demuxer's read_close function is not called automatically if an error happens when reading the header; instead it is up to the demuxer to clean up after itself in this case. The mov demuxer did this by calling its read_close function when it encountered some errors when reading the header. This commit changes this by setting the FF_FMT_INIT_CLEANUP flag so that mov_read_close() is automatically called when an error happens when reading the header. (Btw: mov_read_close() is not idempotent: Calling it twice is dangerouos, because MOVContext.frag_index.item will be av_freep'ed, yet MOVContext.frag_index.nb_items won't be reset. So the calls to mov_read_close() have to be removed before the switch to freeing generically.) Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@@ -7556,13 +7556,12 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
avio_seek(pb, 0, SEEK_SET);
|
avio_seek(pb, 0, SEEK_SET);
|
||||||
if ((err = mov_read_default(mov, pb, atom)) < 0) {
|
if ((err = mov_read_default(mov, pb, atom)) < 0) {
|
||||||
av_log(s, AV_LOG_ERROR, "error reading header\n");
|
av_log(s, AV_LOG_ERROR, "error reading header\n");
|
||||||
goto fail;
|
return err;
|
||||||
}
|
}
|
||||||
} while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
|
} while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
|
||||||
if (!mov->found_moov) {
|
if (!mov->found_moov) {
|
||||||
av_log(s, AV_LOG_ERROR, "moov atom not found\n");
|
av_log(s, AV_LOG_ERROR, "moov atom not found\n");
|
||||||
err = AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
|
av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
|
||||||
|
|
||||||
@@ -7616,7 +7615,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
}
|
}
|
||||||
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
|
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
|
||||||
if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
|
if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
|
||||||
goto fail;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mov->handbrake_version &&
|
if (mov->handbrake_version &&
|
||||||
@@ -7635,8 +7634,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
|
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
|
||||||
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
|
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
|
||||||
sc->data_size, sc->time_scale);
|
sc->data_size, sc->time_scale);
|
||||||
err = AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
|
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
|
||||||
}
|
}
|
||||||
@@ -7651,8 +7649,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
|
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
|
||||||
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
|
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
|
||||||
sc->data_size, sc->time_scale);
|
sc->data_size, sc->time_scale);
|
||||||
err = AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
|
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
|
||||||
sc->duration_for_fps;
|
sc->duration_for_fps;
|
||||||
@@ -7676,14 +7673,14 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
err = ff_replaygain_export(st, s->metadata);
|
err = ff_replaygain_export(st, s->metadata);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
return err;
|
||||||
break;
|
break;
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
if (sc->display_matrix) {
|
if (sc->display_matrix) {
|
||||||
err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
|
err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
|
||||||
sizeof(int32_t) * 9);
|
sizeof(int32_t) * 9);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
return err;
|
||||||
|
|
||||||
sc->display_matrix = NULL;
|
sc->display_matrix = NULL;
|
||||||
}
|
}
|
||||||
@@ -7692,7 +7689,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
(uint8_t *)sc->stereo3d,
|
(uint8_t *)sc->stereo3d,
|
||||||
sizeof(*sc->stereo3d));
|
sizeof(*sc->stereo3d));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
return err;
|
||||||
|
|
||||||
sc->stereo3d = NULL;
|
sc->stereo3d = NULL;
|
||||||
}
|
}
|
||||||
@@ -7701,7 +7698,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
(uint8_t *)sc->spherical,
|
(uint8_t *)sc->spherical,
|
||||||
sc->spherical_size);
|
sc->spherical_size);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
return err;
|
||||||
|
|
||||||
sc->spherical = NULL;
|
sc->spherical = NULL;
|
||||||
}
|
}
|
||||||
@@ -7710,7 +7707,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
(uint8_t *)sc->mastering,
|
(uint8_t *)sc->mastering,
|
||||||
sizeof(*sc->mastering));
|
sizeof(*sc->mastering));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
return err;
|
||||||
|
|
||||||
sc->mastering = NULL;
|
sc->mastering = NULL;
|
||||||
}
|
}
|
||||||
@@ -7719,7 +7716,7 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
(uint8_t *)sc->coll,
|
(uint8_t *)sc->coll,
|
||||||
sc->coll_size);
|
sc->coll_size);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
return err;
|
||||||
|
|
||||||
sc->coll = NULL;
|
sc->coll = NULL;
|
||||||
}
|
}
|
||||||
@@ -7733,9 +7730,6 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
mov->frag_index.item[i].headers_read = 1;
|
mov->frag_index.item[i].headers_read = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
|
||||||
mov_read_close(s);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
|
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
|
||||||
@@ -8205,6 +8199,7 @@ const AVInputFormat ff_mov_demuxer = {
|
|||||||
.priv_class = &mov_class,
|
.priv_class = &mov_class,
|
||||||
.priv_data_size = sizeof(MOVContext),
|
.priv_data_size = sizeof(MOVContext),
|
||||||
.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
|
.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
|
||||||
|
.flags_internal = FF_FMT_INIT_CLEANUP,
|
||||||
.read_probe = mov_probe,
|
.read_probe = mov_probe,
|
||||||
.read_header = mov_read_header,
|
.read_header = mov_read_header,
|
||||||
.read_packet = mov_read_packet,
|
.read_packet = mov_read_packet,
|
||||||
|
Reference in New Issue
Block a user