diff options
author | van <[email protected]> | 2008-08-18 01:54:15 +0000 |
---|---|---|
committer | van <[email protected]> | 2008-08-18 01:54:15 +0000 |
commit | 1c4d7309b2924c283f9922adda37d93ad1beca88 (patch) | |
tree | 75d0f6df7f08453a5b7225df000b5356f05fd681 /contrib/patch-ffmpeg-mpegleak.patch | |
parent | 6f5fe2aa5351c13739ea7dc9b9e357d96304c6fc (diff) |
- patch a reference picture leak in ffmpeg/libavcodec/mpegvideo.c that caused aborts on h264 transport stream encodes.
- patch the log level of some h264 decoder error messages so we don't fill our log with messages about stuff that's a very likely & not terribly significant.
- don't let hb.c set the ffmpeg av_log level to AV_LOG_DEBUG -- it fills the HB activity log with junk.
- add a count of the decoder errors to decavcodec's final report.
- when we don't have any chapter text (i.e., during a typical cli encode) just print the chapter number rather than empty quote marks.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1639 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'contrib/patch-ffmpeg-mpegleak.patch')
-rw-r--r-- | contrib/patch-ffmpeg-mpegleak.patch | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/contrib/patch-ffmpeg-mpegleak.patch b/contrib/patch-ffmpeg-mpegleak.patch new file mode 100644 index 000000000..88538922f --- /dev/null +++ b/contrib/patch-ffmpeg-mpegleak.patch @@ -0,0 +1,71 @@ +Index: libavcodec/h264.c +=================================================================== +--- libavcodec/h264.c (revision 14820) ++++ libavcodec/h264.c (working copy) +@@ -3355,7 +3355,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 exceeds max (probably " + "corrupt input), discarding one\n"); + +@@ -7557,7 +7557,7 @@ + + if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){ + if (avctx->skip_frame >= AVDISCARD_NONREF || s->hurry_up) return 0; +- av_log(avctx, AV_LOG_ERROR, "no frame!\n"); ++ av_log(avctx, AV_LOG_DEBUG, "no frame!\n"); + return -1; + } + +Index: libavcodec/mpegvideo.c +=================================================================== +--- libavcodec/mpegvideo.c (revision 14820) ++++ libavcodec/mpegvideo.c (working copy) +@@ -772,6 +772,15 @@ + }else{ + for(i=0; i<MAX_PICTURE_COUNT; i++){ + if(s->picture[i].data[0]==NULL && s->picture[i].type!=0) return i; //FIXME ++ /* 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 purging ++ * pictures that are impossibly old. ++ */ ++ if (s->coded_picture_number - s->picture[i].coded_picture_number > ++ 32*MAX_PICTURE_COUNT) ++ s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]); + } + for(i=0; i<MAX_PICTURE_COUNT; i++){ + if(s->picture[i].data[0]==NULL) return i; +@@ -779,19 +788,15 @@ + } + + 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; ++ /* assume that we don't have a picture because of the leak described above. ++ * just release the oldest we have & reuse 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){ |