summaryrefslogtreecommitdiffstats
path: root/contrib/ffmpeg/A01-mpegleak.patch
blob: 44a99274eefd79671c1d9d97057bb859c6a62003 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Index: libavcodec/mpegvideo.c
===================================================================
--- ffmpeg.orig/libavcodec/mpegvideo.c	(revision 22823)
+++ ffmpeg/libavcodec/mpegvideo.c	(working copy)
@@ -867,19 +867,18 @@
     }
 
     av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n");
-    /* We could return -1, but the codec would crash trying to draw into a
-     * non-existing frame anyway. This is safer than waiting for a random crash.
-     * Also the return of this is never useful, an encoder must only allocate
-     * as much as allowed in the specification. This has no relationship to how
-     * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large
-     * enough for such valid streams).
-     * Plus, a decoder has to check stream validity and remove frames if too
-     * many reference frames are around. Waiting for "OOM" is not correct at
-     * all. Similarly, missing reference frames have to be replaced by
-     * interpolated/MC frames, anything else is a bug in the codec ...
-     */
-    abort();
-    return -1;
+    /* XXX there seems to be a leak caused by h264 in mpeg transport
+     * streams: Over-the-air streams have a lot of errors. A picture
+     * may be marked as referenced but the actual references get lost
+     * so it never gets released. We take care of that here by releasing
+     * the oldest we have & reusing its slot. */
+    int oldest=0;
+    for(i=0; i<MAX_PICTURE_COUNT; i++){
+        if (s->picture[i].coded_picture_number < s->picture[oldest].coded_picture_number)
+            oldest = i;
+    }
+    s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[oldest]);
+    return oldest;
 }
 
 static void update_noise_reduction(MpegEncContext *s){
Index: libavcodec/h264.c
===================================================================
--- ffmpeg.orig/libavcodec/h264.c	(revision 22823)
+++ ffmpeg/libavcodec/h264.c	(working copy)
@@ -2772,8 +2772,8 @@
 
     if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){
         if (avctx->skip_frame >= AVDISCARD_NONREF)
             return 0;
-        av_log(avctx, AV_LOG_ERROR, "no frame!\n");
+        av_log(avctx, AV_LOG_DEBUG, "no frame!\n");
         return -1;
     }
 
Index: libavcodec/h264_refs.c
===================================================================
--- ffmpeg.orig/libavcodec/h264_refs.c	(revision 22823)
+++ ffmpeg/libavcodec/h264_refs.c	(working copy)
@@ -608,7 +608,7 @@
          * stream. Need to discard one frame. Prevents overrun of the
          * short_ref and long_ref buffers.
          */
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->s.avctx, AV_LOG_DEBUG,
                "number of reference frames (%d+%d) exceeds max (%d; probably "
                "corrupt input), discarding one\n");