All pastes #742806 Raw Edit

Stuff

public diff v1 · immutable
·published 2007-10-19 20:56 UTC
rendered paste body
Index: ../hb-0.9.0/libhb/detelecine.c===================================================================--- ../hb-0.9.0/libhb/detelecine.c	(revision 1022)+++ ../hb-0.9.0/libhb/detelecine.c	(working copy)@@ -975,10 +975,12 @@         }         else         {-            goto output_frame;+            goto discard_frame;         }     }     +   // hb_log("frame length: %i", frame->length);+         /* Check to see if frame should be dropped */     if( frame->length < 2 )     {@@ -987,7 +989,7 @@          		if (!frame)          {-            goto output_frame;+            goto discard_frame;         } 		if( frame->length < 2 )          {@@ -995,19 +997,19 @@  			if( !(buf_in->flags & PIC_FLAG_REPEAT_FIRST_FIELD) )             {-                goto output_frame;+                goto discard_frame;             } 			             frame = pullup_get_frame( ctx ); 			             if( !frame )              {-                goto output_frame;+                goto discard_frame;             } 			if( frame->length < 2 )              { 				pullup_release_frame( frame );-                goto output_frame;+                goto discard_frame; 			} 		}     }@@ -1029,11 +1031,34 @@     memcpy( pv->pic_out.data[2], frame->buffer->planes[2],               pv->width[2] * pv->height[2] * sizeof(uint8_t) );     +    if (frame->length != 2)+    {+        /* Interlaced material always seems to have a length of 2+           coming out of pullup, whereas ivtc'd content doesn't.+           So this is one potential way of knowing whether NTSC+           video is interlaced or telecined.                      */+        //pullup_release_frame ( frame );+        //goto output_ivtc_frame;+    } +     pullup_release_frame( frame );      output_frame:         *buf_out = pv->buf_out;         return FILTER_OK;++/* This and all discard_frame calls shown above are+   the result of me restoring the functionality in+   pullup that huevos_rancheros disabled because+   HB couldn't handle it.                           */+discard_frame:    +    *buf_out = pv->buf_out;+    return FILTER_DROP;++/*This lets render.c know when the fraeme length is varying. */+output_ivtc_frame:    +    *buf_out = pv->buf_out;    +    return FILTER_OK_IVTC;+ } -Index: ../hb-0.9.0/libhb/muxmp4.c===================================================================--- ../hb-0.9.0/libhb/muxmp4.c	(revision 1022)+++ ../hb-0.9.0/libhb/muxmp4.c	(working copy)@@ -380,7 +380,7 @@         /* Because we use the audio samplerate as the timescale,            we have to use potentially variable durations so the video            doesn't go out of sync */-        duration    = ( buf->stop * job->arate / 90000 ) - m->sum_dur;+        duration    = ( ( buf->stop * job->arate / 90000 ) - ( buf->start * job->arate / 90000 ) );         m->sum_dur += duration;     }     elseIndex: ../hb-0.9.0/libhb/sync.c===================================================================--- ../hb-0.9.0/libhb/sync.c	(revision 1022)+++ ../hb-0.9.0/libhb/sync.c	(working copy)@@ -52,6 +52,11 @@     uint64_t st_counts[4];     uint64_t st_dates[4];     uint64_t st_first;++    /* Throttle message flags */+    int   trashing_audio;+    int   inserting_silence;+    int   way_out_of_sync; };  /***********************************************************************@@ -85,6 +90,10 @@     pv->pts_offset_old = INT64_MIN;     pv->count_frames   = 0; +    pv->trashing_audio = 0;+    pv->inserting_silence = 0;+    pv->way_out_of_sync = 0;+     /* Calculate how many video frames we are expecting */     duration = 0;     for( i = job->chapter_start; i <= job->chapter_end; i++ )@@ -313,8 +322,8 @@         if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||             next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )         {-	    hb_log( "Sync: Video PTS discontinuity (current buffer start=%lld, next buffer start=%lld), trash Video",-                    cur->start, next->start );+	    //hb_log( "Sync: Video PTS discontinuity (current buffer start=%lld, next buffer start=%lld), trash Video",+            //        cur->start, next->start );                          /*              * Do we need to trash the subtitle, is it from the next->start period@@ -607,28 +616,39 @@         pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;          // hb_log("Video Sequence: %lld, Audio Sequence: %lld", pv->video_sequence, buf->sequence);+         /*          * Using the same logic as the Video have we crossed a VOB          * boundary as detected by the expected PTS and the PTS of our          * audio being out by more than the tolerance value.          */-        if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||-              buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&-            pv->pts_offset_old > INT64_MIN )+        if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||+            buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )         { 	    /*              * Useful debug, but too verbose for normal use.-             */+             *             hb_log("Sync: Audio discontinuity (sequence: vid %lld aud %lld) (pts %lld < %lld < %lld)",                    pv->video_sequence, buf->sequence, 		   pts_expected - PTS_DISCONTINUITY_TOLERANCE, buf->start, 		   pts_expected + PTS_DISCONTINUITY_TOLERANCE );+            */ 	                 /* There has been a PTS discontinuity, and this frame might                be from before the discontinuity*/-            pts_expected = pv->pts_offset_old + sync->count_frames *-                90000 / rate; +            if( pv->pts_offset_old > INT64_MIN )+            {+                pts_expected = pv->pts_offset_old + sync->count_frames *+                    90000 / rate;+            } +            else +            {+                pv->pts_offset_old = pv->pts_offset;+                pts_expected = pv->pts_offset_old + sync->count_frames *+                    90000 / rate;+            }+             /*              * Is the audio from a valid period given the previous              * Video PTS. I.e. has there just been a video PTS@@ -651,7 +671,11 @@                  * up diverging even more. We need to hold on to the                  * audio until the video catches up.                  */-                hb_log("Sync: Audio is way out of sync, attempt to reconverge from current video PTS");+                if( !pv->way_out_of_sync )+                {+                    hb_log("Sync: Audio is way out of sync, attempt to reconverge from current video PTS");+                    pv->way_out_of_sync = 1;+                } 		                 /*                  * It wasn't from the old place, so we must be from@@ -674,9 +698,13 @@         /* Tolerance: 100 ms */         if( buf->start < pts_expected - 9000 )         {-	    /* Audio is behind the Video, trash it, can't use it now. */-	    hb_log( "Sync: Audio PTS (%lld) < Video PTS (%lld) by greater than 100ms, trashing audio to reconverge",-		      buf->start, pts_expected);+            if( !pv->trashing_audio )+            {+                /* Audio is behind the Video, trash it, can't use it now. */+                hb_log( "Sync: Audio PTS (%lld) < Video PTS (%lld) by greater than 100ms, trashing audio to reconverge",+                        buf->start, pts_expected);+                pv->trashing_audio = 1;+            }             buf = hb_fifo_get( audio->fifo_raw );             hb_buffer_close( &buf );             continue;@@ -684,9 +712,28 @@         else if( buf->start > pts_expected + 9000 )         {             /* Audio is ahead of the Video, insert silence until we catch up*/-	    hb_log("Sync: Audio PTS (%lld) >  Video PTS (%lld) by greater than 100ms insert silence until reconverged", buf->start, pts_expected);+            if( !pv->inserting_silence )+            {+                hb_log("Sync: Audio PTS (%lld) >  Video PTS (%lld) by greater than 100ms insert silence until reconverged", buf->start, pts_expected);+                pv->inserting_silence = 1;+            }             InsertSilence( w, i );             continue;+        } +        else +        {+            if( pv->trashing_audio || pv->inserting_silence )+            {+                hb_log( "Sync: Audio back in Sync at PTS %lld", buf->start );+                pv->trashing_audio = 0;+                pv->inserting_silence = 0;+            }+            if( pv->way_out_of_sync )+            {+                hb_log( "Sync: Audio no longer way out of sync at PTS %lld",+                        buf->start );+                pv->way_out_of_sync = 0;+            }         }          if( job->acodec & HB_ACODEC_AC3 )@@ -741,6 +788,16 @@         hb_fifo_push( fifo, buf );     } +    if( hb_fifo_is_full( fifo ) &&+        pv->way_out_of_sync ) +    {+        /*+         * Trash the top audio packet to avoid dead lock as we reconverge.+         */+        buf = hb_fifo_get( audio->fifo_raw );+        hb_buffer_close( &buf ); +    }+     if( NeedSilence( w, audio ) )     {         InsertSilence( w, i );@@ -818,8 +875,6 @@         buf->stop  = buf->start + 90000 / 20;         memset( buf->data, 0, buf->size ); -        hb_log( "sync: adding 50 ms of silence for track %x",-                sync->audio->id );         hb_fifo_push( sync->audio->fifo_sync, buf );          sync->count_frames += job->arate / 20;Index: ../hb-0.9.0/libhb/render.c===================================================================--- ../hb-0.9.0/libhb/render.c	(revision 1022)+++ ../hb-0.9.0/libhb/render.c	(working copy)@@ -9,6 +9,14 @@ #include "ffmpeg/avcodec.h" #include "ffmpeg/swscale.h" +/* Used for keeping track of when frames are dropped by detelecine. */+int ivtc_cadence[12];+int frame_length[12];+uint32_t dropped_frames = 0;+uint32_t extended_durations = 0;++hb_buffer_t * temp = NULL;+ struct hb_work_private_s {     hb_job_t * job;@@ -184,6 +192,14 @@     /* Setup render buffer */     hb_buffer_t * buf_render = hb_buffer_init( 3 * job->width * job->height / 2 );   +    /*  Rotate the cadence tracking. */+    int i = 0;+    for(i=11; i > 0; i--)+    {+        ivtc_cadence[i] = ivtc_cadence[i-1];+        frame_length[i] = frame_length[i-1];+    }+     /* Apply filters */     if( job->filters )     {@@ -217,6 +233,8 @@             if( result == FILTER_OK )             {                 buf_tmp_in = buf_tmp_out;+                ivtc_cadence[0] = 0;+                frame_length[0] = 0;             }             else if( result == FILTER_DELAY )             {@@ -225,13 +243,97 @@             }                         else if( result == FILTER_DROP )             {+                /* A drop means detelecine's latched its teeth onto+                   something and has duped frames to discard. */+                ivtc_cadence[0] = 1;+                frame_length[0] = 0;                 hb_fifo_get( pv->subtitle_queue );                 buf_tmp_in = NULL;+                dropped_frames++;+                //hb_log("RENDER: dropped frames: %i", dropped_frames);+//                buf_tmp_in = buf_tmp_out;                 break;             }+            else if( result == FILTER_OK_IVTC )+            {+                /* Frame length isnt' 2 */+                buf_tmp_in = buf_tmp_out;+                ivtc_cadence[0] = 0;+                frame_length[0] = 1;+            }         }-    }   ++        if ( (dropped_frames) && (dropped_frames * 4) > extended_durations && (buf_tmp_in != NULL) )+        {+          //  hb_log("dropped: %i >= extended / 4: %f", dropped_frames, (float)extended_durations / (float)4 );+            //in->stop = in->stop + 751;+            in->stop = in->stop + (90090000 / 120000);+            extended_durations++;+        }+        else if (in->flags & 16)+        {+       //     in->stop = in->stop + 751;+        }         +        /* Here's where the magic happens for VFR. The muxers sense VFR by frame durations. So here are+        a few methods for detecting whether a frame should be displayed at 23.976 or 29.87 speed.    */+        +        /* Uncomment this section to set frame durations based+           on the lengths that come out of detelecine.c */+/*           +        if ( (frame_length[0] == 1) || (frame_length[1] == 1) || (frame_length[2] == 1) ) +        {+            if (job->vrate_base != 1126125)+            {+                in->stop = in->stop + 751;+            }+        }+        else+        {+            if  ( job->vrate_base == 1126125 )+            {+                in->stop = in->stop - 751;+            }+        }+*/++        /*This, more conservative method, watches for dropped frames in the filters above. When it+          finds one, it extends the durations of the next 4 frames to make up for the lost time. It's+          not perfect, of course. A buffering system is needed to do this accurately. We should be+          stretching the duration of 2 frames before the dropped 1m and 2 after, not 4 after..       */++//         if ( (ivtc_cadence[1] == 1) || (ivtc_cadence[2] == 1) || (ivtc_cadence[3] == 1) || (ivtc_cadence[4] == 1) /*|| (ivtc_cadence[5] == 1)*/ )       +//        {+            /* One of the last 4 frames was ditched by detelecine.+               That's telecined stuff, and the frames need to be +               displayed with a a 23.976 duration, so extend+               their durations from ~3003 to ~3754 ticks.     */+//            if (job->vrate_base != 1126125)+//            {+                /* Only extend ivtc frames if the FPS isn't set to 23.976 already. */+//                in->stop = in->stop + 751 ;+//                extended_durations++;+                //hb_log("RENDER: extended durations: %i / 4: %i", extended_durations, extended_durations / 4);+//            }+//      }+//      else if ( in->flags & 16 )       +//      {+            /* The frame is progressive. If you want to blindly assume it really is+               a 23.976 frame, extend its duration by uncommenting the line of code+               below. Otherwise, have faith in detelecine.c.                          */+           //in->stop = in->stop + 751 ;+//      }+//      else+//      {+//          if  ( (job->vrate_base == 1126125) && !(in->flags & 16) )+//          {+                /* Shorten frame durations for non-ivtc video stuff when using 23.976 */+             // in->stop = in->stop - 751;+//          }++//      }+  }+                 /* Apply subtitles */     if( buf_tmp_in )     {@@ -268,6 +370,11 @@         buf_tmp_in = buf_render;     }   +    /* Pass VFR NTSC IVTC frame durations on through the workflow.+       I totally wish I could slip some cryptic abbreviations into+       the last sentence.                                          */ +    buf_render->stop = in->stop;+     /* Set output to render buffer */     (*buf_out) = buf_render; @@ -297,6 +404,14 @@  void renderClose( hb_work_object_t * w ) {+    /* (90090000 / 120000) is the rational equivalent of 750.75.+      That's the number of ticks by which a 23.976 frame is +      longer than a 29.97 frame. God I hate fractions.+    */+    hb_log("RENDER: dropped frames: %i (%i ticks)", dropped_frames, (dropped_frames * 3003) );+    hb_log("RENDER: extended frames: %i (%i ticks)", extended_durations, (extended_durations * (90090000 / 120000) ) );+    hb_log("RENDER: Lost time: %i ticks", (dropped_frames * 3003) - (extended_durations *  (90090000 / 120000) ) );+         hb_work_private_t * pv = w->private_data;                 /* Cleanup subtitle queue */Index: ../hb-0.9.0/libhb/common.h===================================================================--- ../hb-0.9.0/libhb/common.h	(revision 1022)+++ ../hb-0.9.0/libhb/common.h	(working copy)@@ -528,6 +528,7 @@ #define FILTER_DELAY   1 #define FILTER_FAILED  2 #define FILTER_DROP    3+#define FILTER_OK_IVTC 4  struct hb_filter_object_s {