[FFmpeg-devel] [PATCH 25/54] avformat/mov: Simplify cleanup after read_header failure

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Wed Jun 16 02:32:14 EEST 2021


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 at outlook.com>
---
 libavformat/mov.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 47a8e41236..2e061a55d1 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7556,13 +7556,12 @@ static int mov_read_header(AVFormatContext *s)
             avio_seek(pb, 0, SEEK_SET);
         if ((err = mov_read_default(mov, pb, atom)) < 0) {
             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++);
     if (!mov->found_moov) {
         av_log(s, AV_LOG_ERROR, "moov atom not found\n");
-        err = AVERROR_INVALIDDATA;
-        goto fail;
+        return AVERROR_INVALIDDATA;
     }
     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 ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
-                    goto fail;
+                    return err;
             }
         }
         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) {
                     av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
                            sc->data_size, sc->time_scale);
-                    err = AVERROR_INVALIDDATA;
-                    goto fail;
+                    return AVERROR_INVALIDDATA;
                 }
                 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) {
                     av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
                            sc->data_size, sc->time_scale);
-                    err = AVERROR_INVALIDDATA;
-                    goto fail;
+                    return AVERROR_INVALIDDATA;
                 }
                 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
                     sc->duration_for_fps;
@@ -7676,14 +7673,14 @@ static int mov_read_header(AVFormatContext *s)
         case AVMEDIA_TYPE_AUDIO:
             err = ff_replaygain_export(st, s->metadata);
             if (err < 0)
-                goto fail;
+                return err;
             break;
         case AVMEDIA_TYPE_VIDEO:
             if (sc->display_matrix) {
                 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
                                               sizeof(int32_t) * 9);
                 if (err < 0)
-                    goto fail;
+                    return err;
 
                 sc->display_matrix = NULL;
             }
@@ -7692,7 +7689,7 @@ static int mov_read_header(AVFormatContext *s)
                                               (uint8_t *)sc->stereo3d,
                                               sizeof(*sc->stereo3d));
                 if (err < 0)
-                    goto fail;
+                    return err;
 
                 sc->stereo3d = NULL;
             }
@@ -7701,7 +7698,7 @@ static int mov_read_header(AVFormatContext *s)
                                               (uint8_t *)sc->spherical,
                                               sc->spherical_size);
                 if (err < 0)
-                    goto fail;
+                    return err;
 
                 sc->spherical = NULL;
             }
@@ -7710,7 +7707,7 @@ static int mov_read_header(AVFormatContext *s)
                                               (uint8_t *)sc->mastering,
                                               sizeof(*sc->mastering));
                 if (err < 0)
-                    goto fail;
+                    return err;
 
                 sc->mastering = NULL;
             }
@@ -7719,7 +7716,7 @@ static int mov_read_header(AVFormatContext *s)
                                               (uint8_t *)sc->coll,
                                               sc->coll_size);
                 if (err < 0)
-                    goto fail;
+                    return err;
 
                 sc->coll = NULL;
             }
@@ -7733,9 +7730,6 @@ static int mov_read_header(AVFormatContext *s)
             mov->frag_index.item[i].headers_read = 1;
 
     return 0;
-fail:
-    mov_read_close(s);
-    return err;
 }
 
 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
@@ -8205,6 +8199,7 @@ const AVInputFormat ff_mov_demuxer = {
     .priv_class     = &mov_class,
     .priv_data_size = sizeof(MOVContext),
     .extensions     = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
+    .flags_internal = FF_FMT_INIT_CLEANUP,
     .read_probe     = mov_probe,
     .read_header    = mov_read_header,
     .read_packet    = mov_read_packet,
-- 
2.27.0



More information about the ffmpeg-devel mailing list