summaryrefslogtreecommitdiffstats
path: root/libhb/render.c
diff options
context:
space:
mode:
authorjbrjake <[email protected]>2007-11-10 01:51:36 +0000
committerjbrjake <[email protected]>2007-11-10 01:51:36 +0000
commitd95e8d52105a29a03750232c47949b37dc3075dc (patch)
tree94e4f7b25d65b692259241c7049dede3c9568ab7 /libhb/render.c
parent5e6725417750adb69ccbca26d1c7cbdbfd4fd142 (diff)
First attempt at variable frame rate detelecining for NTSC video sources.
This check-in includes the library code as well as the CLI implementation. Only works with MP4 and MKV, untested with high profile, results may vary with mixed content, consult a physician if condition persists for longer than four hours. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1051 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/render.c')
-rw-r--r--libhb/render.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/libhb/render.c b/libhb/render.c
index edbd18a80..07f38897e 100644
--- a/libhb/render.c
+++ b/libhb/render.c
@@ -19,6 +19,10 @@ struct hb_work_private_s
AVPicture pic_tmp_out;
hb_buffer_t * buf_scale;
hb_fifo_t * subtitle_queue;
+ hb_fifo_t * delay_queue;
+ int frames_to_extend;
+ int dropped_frames;
+ int extended_frames;
};
int renderInit( hb_work_object_t *, hb_job_t * );
@@ -153,10 +157,14 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_job_t * job = pv->job;
hb_title_t * title = job->title;
hb_buffer_t * in = *buf_in, * buf_tmp_in = *buf_in;
+ hb_buffer_t * ivtc_buffer = NULL;
if(!in->data)
{
- /* If the input buffer is end of stream, send out an empty one to the next stage as well. */
+ /* If the input buffer is end of stream, send out an empty one
+ * to the next stage as well. Note that this will result in us
+ * losing the current contents of the delay queue.
+ */
*buf_out = hb_buffer_init(0);
return HB_WORK_OK;
}
@@ -227,6 +235,11 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
{
hb_fifo_get( pv->subtitle_queue );
buf_tmp_in = NULL;
+ if( job->vfr )
+ {
+ pv->frames_to_extend += 4;
+ pv->dropped_frames++;
+ }
break;
}
}
@@ -291,6 +304,49 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
memcpy( buf_render->data, buf_tmp_in->data, buf_render->size );
hb_buffer_copy_settings( buf_render, buf_tmp_in );
}
+
+ if (*buf_out)
+ {
+ 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( hb_fifo_size( pv->delay_queue ) >= 3 )
+ {
+ *buf_out = hb_fifo_get( pv->delay_queue );
+ }
+
+ if( *buf_out )
+ {
+ if( pv->frames_to_extend )
+ {
+ /*
+ * A frame's been dropped by VFR detelecine.
+ * Gotta make up the lost time. This will also
+ * slow down the video to 23.976fps.
+ * The dropped frame ran for 3003 ticks, 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.
+ */
+ ivtc_buffer = *buf_out;
+
+ if (pv->frames_to_extend % 4)
+ ivtc_buffer->stop += 751;
+ else
+ ivtc_buffer->stop += 750;
+
+ pv->frames_to_extend--;
+ pv->extended_frames++;
+ }
+ }
return HB_WORK_OK;
}
@@ -299,12 +355,21 @@ void renderClose( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
+ hb_log("render: dropped frames: %i (%i ticks)", pv->dropped_frames, (pv->dropped_frames * 3003) );
+ hb_log("render: extended frames: %i (%i ticks)", pv->extended_frames, ( ( pv->extended_frames / 4 ) * 3003 ) );
+ hb_log("render: Lost time: %i frames (%i ticks)", (pv->dropped_frames * 4) - (pv->extended_frames), (pv->dropped_frames * 3003) - ( ( pv->extended_frames / 4 ) * 3003 ) );
+
/* Cleanup subtitle queue */
if( pv->subtitle_queue )
{
hb_fifo_close( &pv->subtitle_queue );
}
+ if( pv->delay_queue )
+ {
+ hb_fifo_close( &pv->delay_queue );
+ }
+
/* Cleanup filters */
/* TODO: Move to work.c? */
if( pv->job->filters )
@@ -352,6 +417,10 @@ int renderInit( hb_work_object_t * w, hb_job_t * job )
/* Setup FIFO queue for subtitle cache */
pv->subtitle_queue = hb_fifo_init( 8 );
+ pv->delay_queue = hb_fifo_init( 8 );
+ pv->frames_to_extend = 0;
+ pv->dropped_frames = 0;
+ pv->extended_frames = 0;
/* Setup filters */
/* TODO: Move to work.c? */