diff --git a/ffmpeg.c b/ffmpeg.c
index 5e2e38a8707e35f3fb456bf1e620b7c7b759c63b..aac071e747a8d8e3160511034d3c06f9bb56e3f2 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -396,9 +396,17 @@ static int av_exit(int ret)
         if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
             url_fclose(s->pb);
         for(j=0;j<s->nb_streams;j++) {
+            av_metadata_free(&s->streams[j]->metadata);
             av_free(s->streams[j]->codec);
             av_free(s->streams[j]);
         }
+        for(j=0;j<s->nb_programs;j++) {
+            av_metadata_free(&s->programs[j]->metadata);
+        }
+        for(j=0;j<s->nb_chapters;j++) {
+            av_metadata_free(&s->chapters[j]->metadata);
+        }
+        av_metadata_free(&s->metadata);
         av_free(s);
     }
     for(i=0;i<nb_input_files;i++)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index e21b3ea182ecd218a38d7d84a14dad65f0c3a9b5..e8b71004e73b25286b7a747e717c618622565908 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -93,6 +93,11 @@ av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int f
  */
 int av_metadata_set(AVMetadata **m, AVMetadataTag tag);
 
+/**
+ * Free all the memory allocated for an AVMetadata struct.
+ */
+void av_metadata_free(AVMetadata **m);
+
 
 /* packet functions */
 
diff --git a/libavformat/metadata.c b/libavformat/metadata.c
index 5c7ef06199765654c2da3e26acb3ae26b5983541..70bfa3d35b42f83621ec529e520a34fc73f3d09a 100644
--- a/libavformat/metadata.c
+++ b/libavformat/metadata.c
@@ -74,6 +74,20 @@ int av_metadata_set(AVMetadata **pm, AVMetadataTag elem)
     return 0;
 }
 
+void av_metadata_free(AVMetadata **pm)
+{
+    AVMetadata *m= *pm;
+
+    if(m){
+        while(m->count--){
+            av_free(m->elems[m->count].key);
+            av_free(m->elems[m->count].value);
+        }
+        av_free(m->elems);
+    }
+    av_freep(pm);
+}
+
 #if LIBAVFORMAT_VERSION_MAJOR < 53
 #define FILL_METADATA(s, key, value) {                                        \
     if (value && *value &&                                                    \
diff --git a/libavformat/utils.c b/libavformat/utils.c
index e3fdd7f74498369a90d4e526e50c85e7b2b0e88f..eb5549979f5b5a9588feba1fdd2663d2431cab75 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2285,6 +2285,7 @@ void av_close_input_stream(AVFormatContext *s)
         if (st->parser) {
             av_parser_close(st->parser);
         }
+        av_metadata_free(&st->metadata);
         av_free(st->index_entries);
         av_free(st->codec->extradata);
         av_free(st->codec);
@@ -2295,6 +2296,7 @@ void av_close_input_stream(AVFormatContext *s)
     for(i=s->nb_programs-1; i>=0; i--) {
         av_freep(&s->programs[i]->provider_name);
         av_freep(&s->programs[i]->name);
+        av_metadata_free(&s->programs[i]->metadata);
         av_freep(&s->programs[i]->stream_index);
         av_freep(&s->programs[i]);
     }
@@ -2303,17 +2305,11 @@ void av_close_input_stream(AVFormatContext *s)
     av_freep(&s->priv_data);
     while(s->nb_chapters--) {
         av_free(s->chapters[s->nb_chapters]->title);
+        av_metadata_free(&s->chapters[s->nb_chapters]->metadata);
         av_free(s->chapters[s->nb_chapters]);
     }
     av_freep(&s->chapters);
-    if(s->metadata){
-        while(s->metadata->count--){
-            av_freep(&s->metadata->elems[s->metadata->count].key);
-            av_freep(&s->metadata->elems[s->metadata->count].value);
-        }
-        av_freep(&s->metadata->elems);
-    }
-    av_freep(&s->metadata);
+    av_metadata_free(&s->metadata);
     av_free(s);
 }