All pastes #1176487 Raw Edit

Van patch to ffmpeg to handle st

public diff v1 · immutable
#1176487 ·published 2008-08-17 20:50 UTC
rendered paste body
Index: libhb/decavcodec.c===================================================================--- libhb/decavcodec.c	(revision 1627)+++ libhb/decavcodec.c	(working copy)@@ -90,10 +90,12 @@     double               pts_next;  // next pts we expect to generate     int64_t              pts;       // (video) pts passing from parser to decoder     int64_t              chap_time; // time of next chap mark (if new_chap != 0)+    int64_t              last_reset;// time of last video decoder reset     int                  new_chap;     int                  ignore_pts; // workaround M$ bugs-    int                  nframes;-    int                  ndrops;+    uint32_t             nframes;+    uint32_t             ndrops;+    uint32_t             decode_errors;     double               duration;  // frame duration (for video) }; @@ -340,7 +342,7 @@ static void log_chapter( hb_work_private_t *pv, int chap_num, int64_t pts ) {     hb_chapter_t *c = hb_list_item( pv->job->title->list_chapter, chap_num - 1 );-    hb_log( "%s: \"%s\" (%d) at frame %u time %lld", pv->context->codec->name,+    hb_log( "%s: Chapter \"%s\" (%d) at frame %u time %lld", pv->context->codec->name,             c->title, chap_num, pv->nframes, pts ); } @@ -349,7 +351,21 @@     int got_picture;     AVFrame frame; -    avcodec_decode_video( pv->context, &frame, &got_picture, data, size );+    if ( avcodec_decode_video( pv->context, &frame, &got_picture, data, size ) < 0 )+    {+        ++pv->decode_errors;     +        hb_log("%s: decode errors %u", pv->context->codec->name, pv->decode_errors );+        // XXX possible h264 decoder bug workaround: if we've processed 3 or more+        // hours of video since the last decoder reset, reset the decoder.+        //if ( pv->pts_next - pv->last_reset >= 90000*3600*3 )+        if( pv->decode_errors % 10 == 0 )+        {+            pv->last_reset = pv->pts_next;+            avcodec_flush_buffers( pv->context );+            hb_log( "%s: reset decoder at frame %u (%u decode errors)",+                    pv->context->codec->name, pv->nframes, pv->decode_errors );+        }+    }     if( got_picture )     {         // ffmpeg makes it hard to attach a pts to a frame. if the MPEG ES@@ -498,7 +514,8 @@         decodeVideo( pv, in->data, in->size, pts, dts );         hb_list_add( pv->list, in );         *buf_out = link_buf_list( pv );-        hb_log( "%s done: %d frames", pv->context->codec->name, pv->nframes );+        hb_log( "%s done: %u frames, %u decoder errors",+                pv->context->codec->name, pv->nframes, pv->decode_errors );         return HB_WORK_DONE;     } @@ -710,8 +727,9 @@         }         hb_list_add( pv->list, in );         *buf_out = link_buf_list( pv );-        hb_log( "%s done: %d frames %d drops", pv->context->codec->name,-                pv->nframes, pv->ndrops );+        hb_log( "%s done: %u frames, %u decoder errors, %u drops",+                pv->context->codec->name, pv->nframes, pv->decode_errors,+                pv->ndrops );         return HB_WORK_DONE;     } Index: contrib/patch-ffmpeg-error.patch===================================================================--- contrib/patch-ffmpeg-error.patch	(revision 0)+++ contrib/patch-ffmpeg-error.patch	(revision 0)@@ -0,0 +1,49 @@+Index: libavcodec/mpegvideo.c+===================================================================+--- libavcodec/mpegvideo.c	(revision 14773)++++ 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){Index: contrib/Jamfile===================================================================--- contrib/Jamfile	(revision 1627)+++ contrib/Jamfile	(working copy)@@ -79,6 +79,7 @@ {     FFMPEG_PATCH = "$(PATCH) -p0 < ../patch-ffmpeg.patch" ;     FFMPEG_PATCH += " && $(PATCH) -p0 < ../patch-ffmpeg-latm.patch " ;+    FFMPEG_PATCH += " && $(PATCH) -p0 < ../patch-ffmpeg-error.patch " ;     if $(OS) = CYGWIN     {         FFMPEG_PATCH += " && $(PATCH) -p1 < ../patch-ffmpeg-cygwin.patch " ;