WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / vfr.c
blob8f62c92419dff7a4279edc6aa5d2684473fde544
1 /* vfr.c
3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
8 */
10 #include "hb.h"
12 struct hb_filter_private_s
14 hb_job_t * job;
15 int cfr;
16 hb_rational_t input_vrate;
17 hb_rational_t vrate;
18 hb_fifo_t * delay_queue;
19 int dropped_frames;
20 int extended_frames;
21 uint64_t last_start[4];
22 uint64_t last_stop[4];
23 uint64_t lost_time[4];
24 uint64_t total_lost_time;
25 uint64_t total_gained_time;
26 int count_frames; // frames output so far
27 double frame_rate; // 90KHz ticks per frame (for CFR/PFR)
28 uint64_t out_last_stop; // where last frame ended (for CFR/PFR)
29 int drops; // frames dropped (for CFR/PFR)
30 int dups; // frames duped (for CFR/PFR)
32 // Duplicate frame detection members
33 float max_metric; // highest motion metric since
34 // last output frame
35 float frame_metric; // motion metric of last frame
36 float out_metric; // motion metric of last output frame
37 int sync_parity;
38 unsigned gamma_lut[256];
41 static int hb_vfr_init( hb_filter_object_t * filter,
42 hb_filter_init_t * init );
44 static int hb_vfr_work( hb_filter_object_t * filter,
45 hb_buffer_t ** buf_in,
46 hb_buffer_t ** buf_out );
48 static void hb_vfr_close( hb_filter_object_t * filter );
49 static int hb_vfr_info( hb_filter_object_t * filter, hb_filter_info_t * info );
51 hb_filter_object_t hb_filter_vfr =
53 .id = HB_FILTER_VFR,
54 .enforce_order = 1,
55 .name = "Framerate Shaper",
56 .settings = NULL,
57 .init = hb_vfr_init,
58 .work = hb_vfr_work,
59 .close = hb_vfr_close,
60 .info = hb_vfr_info,
63 // Create gamma lookup table.
64 // Note that we are creating a scaled integer lookup table that will
65 // not cause overflows in sse_block16() below. This results in
66 // small values being truncated to 0 which is ok for this usage.
67 static void build_gamma_lut( hb_filter_private_t * pv )
69 int i;
70 for( i = 0; i < 256; i++ )
72 pv->gamma_lut[i] = 4095 * pow( ( (float)i / (float)255 ), 2.2f );
76 // insert buffer 'succ' after buffer chain element 'pred'.
77 // caller must guarantee that 'pred' and 'succ' are non-null.
78 static hb_buffer_t *insert_buffer_in_chain(
79 hb_buffer_t *pred,
80 hb_buffer_t *succ )
82 succ->next = pred->next;
83 pred->next = succ;
84 return succ;
87 #define DUP_THRESH_SSE 5.0
89 // Compute ths sum of squared errors for a 16x16 block
90 // Gamma adjusts pixel values so that less visible diffreences
91 // count less.
92 static inline unsigned sse_block16( hb_filter_private_t *pv, uint8_t *a, uint8_t *b, int stride )
94 int x, y;
95 unsigned sum = 0;
96 int diff;
97 unsigned *g = pv->gamma_lut;
99 for( y = 0; y < 16; y++ )
101 for( x = 0; x < 16; x++ )
103 diff = g[a[x]] - g[b[x]];
104 sum += diff * diff;
106 a += stride;
107 b += stride;
109 return sum;
112 // Sum of squared errors. Computes and sums the SSEs for all
113 // 16x16 blocks in the images. Only checks the Y component.
114 static float motion_metric( hb_filter_private_t * pv, hb_buffer_t * a, hb_buffer_t * b )
116 int bw = a->f.width / 16;
117 int bh = a->f.height / 16;
118 int stride = a->plane[0].stride;
119 uint8_t * pa = a->plane[0].data;
120 uint8_t * pb = b->plane[0].data;
121 int x, y;
122 uint64_t sum = 0;
124 for( y = 0; y < bh; y++ )
126 for( x = 0; x < bw; x++ )
128 sum += sse_block16( pv, pa + y * 16 * stride + x * 16,
129 pb + y * 16 * stride + x * 16, stride );
132 return (float)sum / ( a->f.width * a->f.height );;
135 // This section of the code implements video frame rate control.
136 // Since filters are allowed to duplicate and drop frames (which
137 // changes the timing), this has to be the last thing done in render.
139 // There are three options, selected by the value of cfr:
140 // 0 - Variable Frame Rate (VFR) or 'same as source': frame times
141 // are left alone
142 // 1 - Constant Frame Rate (CFR): Frame timings are adjusted so that all
143 // frames are exactly vrate.den ticks apart. Frames are dropped
144 // or duplicated if necessary to maintain this spacing.
145 // 2 - Peak Frame Rate (PFR): vrate.den is treated as the peak
146 // average frame rate. I.e., the average frame rate (current frame
147 // end time divided by number of frames so far) is never allowed to be
148 // greater than vrate.den and frames are dropped if necessary
149 // to keep the average under this value. Other than those drops, frame
150 // times are left alone.
153 static void adjust_frame_rate( hb_filter_private_t *pv, hb_buffer_t **buf_out )
155 hb_buffer_t *out = *buf_out;
157 if ( out && out->size > 0 )
159 if ( pv->cfr == 0 )
161 ++pv->count_frames;
162 pv->out_last_stop = out->s.stop;
163 return;
166 // compute where this frame would stop if the frame rate were constant
167 // (this is our target stopping time for CFR and earliest possible
168 // stopping time for PFR).
169 double cfr_stop = pv->frame_rate * ( pv->count_frames + 1 );
171 hb_buffer_t * next = hb_fifo_see( pv->delay_queue );
173 float next_metric = 0;
174 if( next )
175 next_metric = motion_metric( pv, out, next );
177 if( pv->out_last_stop >= out->s.stop )
179 ++pv->drops;
180 hb_buffer_close( buf_out );
182 pv->frame_metric = next_metric;
183 if( next_metric > pv->max_metric )
184 pv->max_metric = next_metric;
186 return;
189 if( out->s.start <= pv->out_last_stop &&
190 out->s.stop > pv->out_last_stop &&
191 next && next->s.stop < cfr_stop )
193 // This frame starts before the end of the last output
194 // frame and ends after the end of the last output
195 // frame (i.e. it straddles it). Also the next frame
196 // ends before the end of the next output frame. If the
197 // next frame is not a duplicate, and we haven't seen
198 // a changed frame since the last output frame,
199 // then drop this frame.
201 // This causes us to sync to the pattern of progressive
202 // 23.976 fps content that has been upsampled to
203 // progressive 59.94 fps.
204 if( pv->out_metric > pv->max_metric &&
205 next_metric > pv->max_metric )
207 // Pattern: N R R N
208 // o c n
209 // N == new frame
210 // R == repeat frame
211 // o == last output frame
212 // c == current frame
213 // n == next frame
214 // We haven't seen a frame change since the last output
215 // frame and the next frame changes. Use the next frame,
216 // drop this one.
217 ++pv->drops;
218 pv->frame_metric = next_metric;
219 pv->max_metric = next_metric;
220 pv->sync_parity = 1;
221 hb_buffer_close( buf_out );
222 return;
224 else if( pv->sync_parity &&
225 pv->out_metric < pv->max_metric &&
226 pv->max_metric > pv->frame_metric &&
227 pv->frame_metric < next_metric )
229 // Pattern: R N R N
230 // o c n
231 // N == new frame
232 // R == repeat frame
233 // o == last output frame
234 // c == current frame
235 // n == next frame
236 // If we see this pattern, we must not use the next
237 // frame when straddling the current frame.
238 pv->sync_parity = 0;
240 else if( pv->sync_parity )
242 // The pattern is indeterminate. Continue dropping
243 // frames on the same schedule
244 ++pv->drops;
245 pv->frame_metric = next_metric;
246 pv->max_metric = next_metric;
247 pv->sync_parity = 1;
248 hb_buffer_close( buf_out );
249 return;
254 // this frame has to start where the last one stopped.
255 out->s.start = pv->out_last_stop;
257 pv->out_metric = pv->frame_metric;
258 pv->frame_metric = next_metric;
259 pv->max_metric = next_metric;
261 // at this point we know that this frame doesn't push the average
262 // rate over the limit so we just pass it on for PFR. For CFR we're
263 // going to return it (with its start & stop times modified) and
264 // we may have to dup it.
265 ++pv->count_frames;
266 if ( pv->cfr > 1 )
268 // PFR - we're going to keep the frame but may need to
269 // adjust it's stop time to meet the average rate constraint.
270 if ( out->s.stop <= cfr_stop )
272 out->s.stop = cfr_stop;
274 pv->out_last_stop = out->s.stop;
276 else
278 // we're doing CFR so we have to either trim some time from a
279 // buffer that ends too far in the future or, if the buffer is
280 // two or more frame times long, split it into multiple pieces,
281 // each of which is a frame time long.
282 double excess_dur = (double)out->s.stop - cfr_stop;
283 out->s.stop = cfr_stop;
284 pv->out_last_stop = out->s.stop;
285 for ( ; excess_dur >= pv->frame_rate; excess_dur -= pv->frame_rate )
287 /* next frame too far ahead - dup current frame */
288 hb_buffer_t *dup = hb_buffer_dup( out );
289 dup->s.new_chap = 0;
290 dup->s.start = cfr_stop;
291 cfr_stop += pv->frame_rate;
292 dup->s.stop = cfr_stop;
293 pv->out_last_stop = dup->s.stop;
294 out = insert_buffer_in_chain( out, dup );
295 ++pv->dups;
296 ++pv->count_frames;
302 static int hb_vfr_init(hb_filter_object_t *filter, hb_filter_init_t *init)
304 filter->private_data = calloc(1, sizeof(struct hb_filter_private_s));
305 hb_filter_private_t *pv = filter->private_data;
306 build_gamma_lut(pv);
308 pv->cfr = init->cfr;
309 pv->input_vrate = pv->vrate = init->vrate;
310 if (filter->settings != NULL)
312 sscanf(filter->settings, "%d:%d:%d",
313 &pv->cfr, &pv->vrate.num, &pv->vrate.den);
316 pv->job = init->job;
318 /* Setup FIFO queue for subtitle cache */
319 pv->delay_queue = hb_fifo_init( 8, 1 );
321 /* VFR IVTC needs a bunch of time-keeping variables to track
322 how many frames are dropped, how many are extended, what the
323 last 4 start and stop times were (so they can be modified),
324 how much time has been lost and gained overall, how much time
325 the latest 4 frames should be extended by */
326 pv->dropped_frames = 0;
327 pv->extended_frames = 0;
328 pv->last_start[0] = 0;
329 pv->last_stop[0] = 0;
330 pv->total_lost_time = 0;
331 pv->total_gained_time = 0;
332 pv->lost_time[0] = 0; pv->lost_time[1] = 0; pv->lost_time[2] = 0; pv->lost_time[3] = 0;
333 pv->frame_metric = 1000; // Force first frame
335 if (pv->cfr == 2)
337 // For PFR, we want the framerate based on the source's actual
338 // framerate, unless it's higher than the specified peak framerate.
339 double source_fps = (double)init->vrate.num / init->vrate.den;
340 double peak_fps = (double)pv->vrate.num / pv->vrate.den;
341 if (source_fps > peak_fps)
343 // peak framerate is lower than the source framerate.
344 // so signal that the framerate will be the peak fps.
345 init->vrate = pv->vrate;
348 else
350 init->vrate = pv->vrate;
352 pv->frame_rate = (double)pv->vrate.den * 90000. / pv->vrate.num;
353 init->cfr = pv->cfr;
355 return 0;
358 static int hb_vfr_info( hb_filter_object_t * filter,
359 hb_filter_info_t * info )
361 hb_filter_private_t * pv = filter->private_data;
363 if( !pv )
364 return 1;
366 memset( info, 0, sizeof( hb_filter_info_t ) );
367 info->out.vrate = pv->input_vrate;
368 if (pv->cfr == 2)
370 // For PFR, we want the framerate based on the source's actual
371 // framerate, unless it's higher than the specified peak framerate.
372 double source_fps = (double)pv->input_vrate.num / pv->input_vrate.den;
373 double peak_fps = (double)pv->vrate.num / pv->vrate.den;
374 if (source_fps > peak_fps)
376 // peak framerate is lower than the source framerate.
377 // so signal that the framerate will be the peak fps.
378 info->out.vrate = pv->vrate;
381 else
383 info->out.vrate = pv->vrate;
385 info->out.cfr = pv->cfr;
386 if ( pv->cfr == 0 )
388 /* Ensure we're using "Same as source" FPS */
389 sprintf( info->human_readable_desc,
390 "frame rate: same as source (around %.3f fps)",
391 (float)pv->vrate.num / pv->vrate.den );
393 else if ( pv->cfr == 2 )
395 // For PFR, we want the framerate based on the source's actual
396 // framerate, unless it's higher than the specified peak framerate.
397 double source_fps = (double)pv->input_vrate.num / pv->input_vrate.den;
398 double peak_fps = (double)pv->vrate.num / pv->vrate.den;
399 sprintf( info->human_readable_desc,
400 "frame rate: %.3f fps -> peak rate limited to %.3f fps",
401 source_fps , peak_fps );
403 else
405 // Constant framerate. Signal the framerate we are using.
406 double source_fps = (double)pv->input_vrate.num / pv->input_vrate.den;
407 double constant_fps = (double)pv->vrate.num / pv->vrate.den;
408 sprintf( info->human_readable_desc,
409 "frame rate: %.3f fps -> constant %.3f fps",
410 source_fps , constant_fps );
413 return 0;
416 static void hb_vfr_close( hb_filter_object_t * filter )
418 hb_filter_private_t * pv = filter->private_data;
420 if( !pv )
421 return;
423 if ( pv->cfr )
425 hb_log("render: %d frames output, %d dropped and %d duped for CFR/PFR",
426 pv->count_frames, pv->drops, pv->dups );
429 if( pv->job )
431 hb_interjob_t * interjob = hb_interjob_get( pv->job->h );
433 /* Preserve dropped frame count for more accurate
434 * framerates in 2nd passes.
436 interjob->out_frame_count = pv->count_frames;
437 interjob->total_time = pv->out_last_stop;
440 hb_log("render: lost time: %"PRId64" (%i frames)",
441 pv->total_lost_time, pv->dropped_frames);
442 hb_log("render: gained time: %"PRId64" (%i frames) (%"PRId64" not accounted for)",
443 pv->total_gained_time, pv->extended_frames,
444 pv->total_lost_time - pv->total_gained_time);
446 if (pv->dropped_frames)
448 hb_log("render: average dropped frame duration: %"PRId64,
449 (pv->total_lost_time / pv->dropped_frames) );
452 if( pv->delay_queue )
454 hb_fifo_close( &pv->delay_queue );
457 /* Cleanup render work structure */
458 free( pv );
459 filter->private_data = NULL;
462 static int hb_vfr_work( hb_filter_object_t * filter,
463 hb_buffer_t ** buf_in,
464 hb_buffer_t ** buf_out )
466 hb_filter_private_t * pv = filter->private_data;
467 hb_buffer_t * in = *buf_in;
468 hb_buffer_t * out = NULL;
470 *buf_in = NULL;
471 *buf_out = NULL;
473 if (in->s.flags & HB_BUF_FLAG_EOF)
475 hb_buffer_t *head = NULL, *tail = NULL, *next;
476 int counter = 2;
478 /* If the input buffer is end of stream, send out an empty one
479 * to the next stage as well. To avoid losing the contents of
480 * the delay queue connect the buffers in the delay queue in
481 * the correct order, and add the end of stream buffer to the
482 * end.
484 while( ( next = hb_fifo_get( pv->delay_queue ) ) != NULL )
487 /* We can't use the given time stamps. Previous frames
488 might already have been extended, throwing off the
489 raw values fed to render.c. Instead, their
490 stop and start times are stored in arrays.
491 The 4th cached frame will be the to use.
492 If it needed its duration extended to make up
493 lost time, it will have happened above. */
494 next->s.start = pv->last_start[counter];
495 next->s.stop = pv->last_stop[counter--];
497 adjust_frame_rate( pv, &next );
499 if( next )
501 if( !head && !tail )
503 head = next;
504 } else {
505 tail->next = next;
507 // Move tail to the end of the list that
508 // adjust_frame_rate could return
509 while (next)
511 tail = next;
512 next = next->next;
516 if( tail )
518 tail->next = in;
519 *buf_out = head;
520 } else {
521 *buf_out = in;
523 return HB_FILTER_DONE;
526 // If there is a gap between the last stop and the current start
527 // then frame(s) were dropped.
528 if ( in->s.start > pv->last_stop[0] )
530 /* We need to compensate for the time lost by dropping frame(s).
531 Spread its duration out in quarters, because usually dropped frames
532 maintain a 1-out-of-5 pattern and this spreads it out amongst
533 the remaining ones. Store these in the lost_time array, which
534 has 4 slots in it. Because not every frame duration divides
535 evenly by 4, and we can't lose the remainder, we have to go
536 through an awkward process to preserve it in the 4th array index.
538 uint64_t temp_duration = in->s.start - pv->last_stop[0];
539 pv->lost_time[0] += (temp_duration / 4);
540 pv->lost_time[1] += (temp_duration / 4);
541 pv->lost_time[2] += (temp_duration / 4);
542 pv->lost_time[3] += ( temp_duration - 3 * (temp_duration / 4) );
544 pv->total_lost_time += temp_duration;
546 else if ( in->s.stop <= pv->last_stop[0] )
548 // This is generally an error somewhere (bad source or hb bug).
549 // But lets do our best to straighten out the mess.
550 ++pv->drops;
551 hb_buffer_close(&in);
552 return HB_FILTER_OK;
555 /* Cache frame start and stop times, so we can renumber
556 time stamps if dropping frames for VFR. */
557 int i;
558 for( i = 3; i >= 1; i-- )
560 pv->last_start[i] = pv->last_start[i-1];
561 pv->last_stop[i] = pv->last_stop[i-1];
564 /* In order to make sure we have continuous time stamps, store
565 the current frame's duration as starting when the last one stopped. */
566 pv->last_start[0] = pv->last_stop[1];
567 pv->last_stop[0] = pv->last_start[0] + (in->s.stop - in->s.start);
569 hb_fifo_push( pv->delay_queue, in );
572 * Keep the last three frames in our queue, this ensures that we have
573 * the last two always in there should we need to rewrite the
574 * durations on them.
577 if( hb_fifo_size( pv->delay_queue ) >= 4 )
579 out = hb_fifo_get( pv->delay_queue );
582 if( out )
584 /* The current frame exists. That means it hasn't been dropped by a
585 * filter. We may edit its duration if needed.
587 if( pv->lost_time[3] > 0 )
589 int time_shift = 0;
591 for( i = 3; i >= 0; i-- )
594 * A frame's been dropped earlier by VFR detelecine.
595 * Gotta make up the lost time. This will also
596 * slow down the video.
597 * The dropped frame's has to be accounted for, so
598 * divvy it up amongst the 4 frames left behind.
599 * This is what the delay_queue is for;
600 * telecined sequences start 2 frames before
601 * the dropped frame, so to slow down the right
602 * ones you need a 2 frame delay between
603 * reading input and writing output.
606 /* We want to extend the outputted frame's duration by the value
607 stored in the 4th slot of the lost_time array. Because we need
608 to adjust all the values in the array so they're contiguous,
609 extend the duration inside the array first, before applying
610 it to the current frame buffer. */
611 pv->last_start[i] += time_shift;
612 pv->last_stop[i] += pv->lost_time[i] + time_shift;
614 /* Log how much time has been added back in to the video. */
615 pv->total_gained_time += pv->lost_time[i];
616 time_shift += pv->lost_time[i];
618 pv->lost_time[i] = 0;
620 /* Log how many frames have had their durations extended. */
621 pv->extended_frames++;
625 /* We can't use the given time stamps. Previous frames
626 might already have been extended, throwing off the
627 raw values fed to render.c. Instead, their
628 stop and start times are stored in arrays.
629 The 4th cached frame will be the to use.
630 If it needed its duration extended to make up
631 lost time, it will have happened above. */
632 out->s.start = pv->last_start[3];
633 out->s.stop = pv->last_stop[3];
635 adjust_frame_rate( pv, &out );
638 *buf_out = out;
639 return HB_FILTER_OK;