All pastes #1033764 Raw Edit

jbrjake: render VBV trial

public diff v1 · immutable
#1033764 ·published 2008-05-30 04:21 UTC
rendered paste body
Index: libhb/render.c===================================================================--- libhb/render.c	(revision 1472)+++ libhb/render.c	(working copy)@@ -207,6 +207,7 @@     hb_title_t * title = job->title;     hb_buffer_t * in = *buf_in, * buf_tmp_in = *buf_in;     hb_buffer_t * ivtc_buffer = NULL;+    hb_buffer_t * buf_render = NULL;      if(!in->data)     {@@ -246,9 +247,6 @@         in->new_chap = 0;     } -    /* Setup render buffer */-    hb_buffer_t * buf_render = hb_buffer_init( 3 * job->width * job->height / 2 );-     /* Apply filters */     if( job->filters )     {@@ -339,6 +337,117 @@         pv->last_stop[0] = pv->last_start[0] + (in->stop - in->start);     } +    /*+     * Process the buffers in a delayed fashion if doing VFR+     */+    if ( job->vfr ) +    {+        if ( buf_tmp_in )+        {+            hb_buffer_t *duplicate;+            /*+             * Duplicate frame.+             */+            duplicate = hb_buffer_init( buf_tmp_in->size );+            hb_buffer_copy_settings( duplicate, buf_tmp_in );+            memcpy( duplicate->data, buf_tmp_in->data, buf_tmp_in->size );+            duplicate->sequence = buf_tmp_in->sequence;+            hb_fifo_push( pv->delay_queue, duplicate );+            buf_tmp_in = NULL;+        }++        /*+         * Keep the last three frames in our queue, this ensures that we have the last+         * two always in there should we need to rewrite the durations on them.+         */+        if( hb_fifo_size( pv->delay_queue ) >= 3 )+        {+            /*+             * pop off the oldest and replace our buffer with it+             */+            buf_tmp_in = hb_fifo_get( pv->delay_queue );+        }++        if( buf_tmp_in )+        {+            /* The current frame exists. That means it hasn't been dropped by a filter.+               Make it accessible as ivtc_buffer so we can edit its duration if needed. */+            ivtc_buffer = buf_tmp_in;+            +            if( pv->lost_time[3] > 0 )+            {+                /*+                 * A frame's been dropped earlier by VFR detelecine.+                 * Gotta make up the lost time. This will also+                 * slow down the video.+                 * The dropped frame's has to be accounted for, so+                 * divvy it up amongst the 4 frames left behind.+                 * This is what the delay_queue is for;+                 * telecined sequences start 2 frames before+                 * the dropped frame, so to slow down the right+                 * ones you need a 2 frame delay between+                 * reading input and writing output.+                 */+                +                /* We want to extend the outputted frame's duration by the value+                   stored in the 4th slot of the lost_time array. Because we need+                   to adjust all the values in the array so they're contiguous,+                   extend the duration inside the array first, before applying+                   it to the current frame buffer. */+                pv->last_stop[3] += pv->lost_time[3];+                +                /* Log how much time has been added back in to the video. */+                pv->total_gained_time += pv->lost_time[3];+                +                /* We've pulled the 4th value from the lost_time array+                   and added it to the last_stop array's 4th slot. Now, rotate the+                   lost_time array so the 4th slot now holds the 3rd's value, and+                   so on down the line, and set the 0 index to a value of 0. */+                int i;+                for( i=2; i >=  0; i--)+                {+                    pv->lost_time[i+1] = pv->lost_time[i];+                }+                pv->lost_time[0] = 0;+                +                /* Log how many frames have had their durations extended. */+                pv->extended_frames++;+            }+            +            /* We can't use the given time stamps. Previous frames+               might already have been extended, throwing off the+               raw values fed to render.c. Instead, their+               stop and start times are stored in arrays.+               The 4th cached frame will be the to use.+               If it needed its duration extended to make up+               lost time, it will have happened above. */+            ivtc_buffer->start = pv->last_start[3];+            ivtc_buffer->stop = pv->last_stop[3];+            +            /* Set the 3rd cached frame to start when this one stops,+               and so on down the line. If any of them need to be+               extended as well to make up lost time, it'll be handled+               on the next loop through the renderer.  */+            int i;+            for (i = 2; i >= 0; i--)+            {+                int temp_duration = pv->last_stop[i] - pv->last_start[i];+                pv->last_start[i] = pv->last_stop[i+1];+                pv->last_stop[i] = pv->last_start[i] + temp_duration;+            }+            +            /* If we have a pending chapter mark and this frame is at+               or after the time of the mark, mark this frame & clear+               our pending mark. */+            if( pv->chapter_time && pv->chapter_time <= ivtc_buffer->start )+            {+                ivtc_buffer->new_chap = pv->chapter_val;+                pv->chapter_time = 0;+            }+            +        }+    }         +     /* Apply subtitles */     if( buf_tmp_in )     {@@ -349,6 +458,13 @@         }     } +    /* +     * Setup render buffer into which we will copy the original input frame+     * resizing and cropping as appropriate. This is the buffer that we will+     * output.+     */+    buf_render = hb_buffer_init( 3 * job->width * job->height / 2 );+     /* Apply crop/scale if specified */     if( buf_tmp_in && pv->context )     {@@ -371,16 +487,26 @@                   pv->pic_tmp_out.data,  pv->pic_tmp_out.linesize);          hb_buffer_copy_settings( buf_render, buf_tmp_in );+        +        if( job->vfr )+        {+            /*+             * When doing VFR the buffer is a duplicate, so don't leak it.+             */+            hb_buffer_close( &buf_tmp_in );+        }          buf_tmp_in = buf_render;     }      /* Set output to render buffer */-    (*buf_out) = buf_render;+    *buf_out = buf_render;      if( buf_tmp_in == NULL )     {-        /* Teardown and cleanup buffers if we are emitting NULL */+        /* +         * Teardown and cleanup buffers if we are emitting NULL.+         */         if( buf_in && *buf_in )         {             hb_buffer_close( buf_in );@@ -391,110 +517,22 @@             hb_buffer_close( buf_out );             *buf_out = NULL;         }-    }-    else if( buf_tmp_in != buf_render )+    } else if( buf_tmp_in != buf_render )     {-        /* Copy temporary results and settings into render buffer */+        /*+         * Didn't do any resizing or rescaling, so Copy temporary+         * results and settings into unused render buffer+         */         memcpy( buf_render->data, buf_tmp_in->data, buf_render->size );         hb_buffer_copy_settings( buf_render, buf_tmp_in );-    }--    if (*buf_out && job->vfr)-    {-        hb_fifo_push( pv->delay_queue, *buf_out );-        *buf_out = NULL;-    }--    /*-     * Keep the last three frames in our queue, this ensures that we have the last-     * two always in there should we need to rewrite the durations on them.-     */--    if( job->vfr )-    {-        if( hb_fifo_size( pv->delay_queue ) >= 3 )+        +        if( job->vfr )         {-            *buf_out = hb_fifo_get( pv->delay_queue );-        }-    }--    if( *buf_out && job->vfr)-    {-        /* The current frame exists. That means it hasn't been dropped by a filter.-           Make it accessible as ivtc_buffer so we can edit its duration if needed. */-        ivtc_buffer = *buf_out;--        if( pv->lost_time[3] > 0 )-        {             /*-             * A frame's been dropped earlier by VFR detelecine.-             * Gotta make up the lost time. This will also-             * slow down the video.-             * The dropped frame's has to be accounted for, so-             * divvy it up amongst the 4 frames left behind.-             * This is what the delay_queue is for;-             * telecined sequences start 2 frames before-             * the dropped frame, so to slow down the right-             * ones you need a 2 frame delay between-             * reading input and writing output.+             * When doing VFR this is a duplicate and needs freeing              */--            /* We want to extend the outputted frame's duration by the value-              stored in the 4th slot of the lost_time array. Because we need-              to adjust all the values in the array so they're contiguous,-              extend the duration inside the array first, before applying-              it to the current frame buffer. */-            pv->last_stop[3] += pv->lost_time[3];--            /* Log how much time has been added back in to the video. */-            pv->total_gained_time += pv->lost_time[3];--            /* We've pulled the 4th value from the lost_time array-               and added it to the last_stop array's 4th slot. Now, rotate the-                lost_time array so the 4th slot now holds the 3rd's value, and-               so on down the line, and set the 0 index to a value of 0. */-            int i;-            for( i=2; i >=  0; i--)-            {-                pv->lost_time[i+1] = pv->lost_time[i];-            }-            pv->lost_time[0] = 0;--            /* Log how many frames have had their durations extended. */-            pv->extended_frames++;+            hb_buffer_close( &buf_tmp_in );         }--        /* We can't use the given time stamps. Previous frames-           might already have been extended, throwing off the-           raw values fed to render.c. Instead, their-           stop and start times are stored in arrays.-           The 4th cached frame will be the to use.-           If it needed its duration extended to make up-           lost time, it will have happened above. */-        ivtc_buffer->start = pv->last_start[3];-        ivtc_buffer->stop = pv->last_stop[3];--        /* Set the 3rd cached frame to start when this one stops,-           and so on down the line. If any of them need to be-           extended as well to make up lost time, it'll be handled-           on the next loop through the renderer.  */-        int i;-        for (i = 2; i >= 0; i--)-        {-            int temp_duration = pv->last_stop[i] - pv->last_start[i];-            pv->last_start[i] = pv->last_stop[i+1];-            pv->last_stop[i] = pv->last_start[i] + temp_duration;-        }--        /* If we have a pending chapter mark and this frame is at-           or after the time of the mark, mark this frame & clear-           our pending mark. */-        if( pv->chapter_time && pv->chapter_time <= ivtc_buffer->start )-        {-            ivtc_buffer->new_chap = pv->chapter_val;-            pv->chapter_time = 0;-        }-     }      return HB_WORK_OK;