diff --git a/libavformat/segment.c b/libavformat/segment.c
index 97a0db21d4df1176ebf81bde7b6145dab1cb9c0c..1aac5817c4dd5ea8610650d615f15ea69b18df81 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -574,6 +574,13 @@ static int select_reference_stream(AVFormatContext *s)
     return 0;
 }
 
+static void seg_free_context(SegmentContext *seg)
+{
+    avio_closep(&seg->list_pb);
+    avformat_free_context(seg->avf);
+    seg->avf = NULL;
+}
+
 static int seg_write_header(AVFormatContext *s)
 {
     SegmentContext *seg = s->priv_data;
@@ -705,12 +712,9 @@ static int seg_write_header(AVFormatContext *s)
 
 fail:
     av_dict_free(&options);
-    if (ret) {
-        if (seg->list)
-            avio_close(seg->list_pb);
-        if (seg->avf)
-            avformat_free_context(seg->avf);
-    }
+    if (ret < 0)
+        seg_free_context(seg);
+
     return ret;
 }
 
@@ -725,6 +729,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
     int64_t usecs;
     int64_t wrapped_val;
 
+    if (!seg->avf)
+        return AVERROR(EINVAL);
+
     if (seg->times) {
         end_pts = seg->segment_count < seg->nb_times ?
             seg->times[seg->segment_count] : INT64_MAX;
@@ -815,6 +822,9 @@ fail:
         seg->segment_frame_count++;
     }
 
+    if (ret < 0)
+        seg_free_context(seg);
+
     return ret;
 }
 
@@ -823,8 +833,11 @@ static int seg_write_trailer(struct AVFormatContext *s)
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
     SegmentListEntry *cur, *next;
+    int ret = 0;
+
+    if (!oc)
+        goto fail;
 
-    int ret;
     if (!seg->write_header_trailer) {
         if ((ret = segment_end(s, 0, 1)) < 0)
             goto fail;