OSDN Git Service

fix a problem with point-to-point (and live preview) when there are subtitles
[handbrake-jp/handbrake-jp-git.git] / libhb / sync.c
1 /* $Id: sync.c,v 1.38 2005/04/14 21:57:58 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8 #include "hbffmpeg.h"
9 #include <stdio.h>
10 #include "samplerate.h"
11
12 #ifdef INT64_MIN
13 #undef INT64_MIN /* Because it isn't defined correctly in Zeta */
14 #endif
15 #define INT64_MIN (-9223372036854775807LL-1)
16
17 #define AC3_SAMPLES_PER_FRAME 1536
18
19 typedef struct
20 {
21     hb_lock_t * mutex;
22     int         ref;        /* Reference count to tell us when it's unused */
23     int         count_frames;
24     int64_t     audio_passthru_slip;
25     int64_t     video_pts_slip;
26     int64_t     pts_offset;
27
28     /* Frame based point-to-point support */
29     int64_t     audio_pts_thresh;
30     int         start_found;
31     hb_cond_t * next_frame;
32     int         pts_count;
33     int64_t   * first_pts;
34 } hb_sync_common_t;
35
36 typedef struct
37 {
38     int          index;
39     int64_t      next_start;    /* start time of next output frame */
40     int64_t      next_pts;     /* start time of next input frame */
41     int64_t      first_drop;   /* PTS of first 'went backwards' frame dropped */
42     int          drop_count;   /* count of 'time went backwards' drops */
43
44     /* Raw */
45     SRC_STATE  * state;
46     SRC_DATA     data;
47
48     /* AC-3 */
49     int          ac3_size;
50     uint8_t    * ac3_buf;
51 } hb_sync_audio_t;
52
53 typedef struct
54 {
55     /* Video */
56     int        first_frame;
57     int64_t    pts_skip;
58     int64_t    next_start;    /* start time of next output frame */
59     int64_t    next_pts;      /* start time of next input frame */
60     int64_t    first_drop;    /* PTS of first 'went backwards' frame dropped */
61     int        drop_count;    /* count of 'time went backwards' drops */
62     int        drops;         /* frames dropped to make a cbr video stream */
63     int        dups;          /* frames duplicated to make a cbr video stream */
64     int        video_sequence;
65     int        count_frames_max;
66     int        chap_mark;     /* to propagate chapter mark across a drop */
67     hb_buffer_t * cur;        /* The next picture to process */
68
69     /* Statistics */
70     uint64_t   st_counts[4];
71     uint64_t   st_dates[4];
72     uint64_t   st_first;
73 } hb_sync_video_t;
74
75 struct hb_work_private_s
76 {
77     hb_job_t * job;
78     hb_sync_common_t * common;
79     union
80     {
81         hb_sync_video_t video;
82         hb_sync_audio_t audio;
83     } type;
84 };
85
86 /***********************************************************************
87  * Local prototypes
88  **********************************************************************/
89 static void getPtsOffset( hb_work_object_t * w );
90 static int  checkPtsOffset( hb_work_object_t * w );
91 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i );
92 static void InsertSilence( hb_work_object_t * w, int64_t d );
93 static void UpdateState( hb_work_object_t * w );
94 static void UpdateSearchState( hb_work_object_t * w, int64_t start );
95 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
96                                        hb_sync_audio_t *sync );
97
98 /***********************************************************************
99  * hb_work_sync_init
100  ***********************************************************************
101  * Initialize the work object
102  **********************************************************************/
103 hb_work_object_t * hb_sync_init( hb_job_t * job )
104 {
105     hb_title_t        * title = job->title;
106     hb_chapter_t      * chapter;
107     int                 i;
108     uint64_t            duration;
109     hb_work_private_t * pv;
110     hb_sync_video_t   * sync;
111     hb_work_object_t  * w;
112     hb_work_object_t  * ret = NULL;
113
114     pv = calloc( 1, sizeof( hb_work_private_t ) );
115     sync = &pv->type.video;
116     pv->common = calloc( 1, sizeof( hb_sync_common_t ) );
117     pv->common->ref++;
118     pv->common->mutex = hb_lock_init();
119     pv->common->audio_pts_thresh = 0;
120     pv->common->next_frame = hb_cond_init();
121     pv->common->pts_count = 1;
122     if ( job->frame_to_start || job->pts_to_start )
123     {
124         pv->common->start_found = 0;
125     }
126     else
127     {
128         pv->common->start_found = 1;
129     }
130
131     ret = w = hb_get_work( WORK_SYNC_VIDEO );
132     w->private_data = pv;
133     w->fifo_in = job->fifo_raw;
134     w->fifo_out = job->fifo_sync;
135
136     pv->job            = job;
137     pv->common->pts_offset   = INT64_MIN;
138     sync->first_frame = 1;
139
140     if( job->pass == 2 )
141     {
142         /* We already have an accurate frame count from pass 1 */
143         hb_interjob_t * interjob = hb_interjob_get( job->h );
144         sync->count_frames_max = interjob->frame_count;
145     }
146     else
147     {
148         /* Calculate how many video frames we are expecting */
149         if ( job->pts_to_stop )
150         {
151             duration = job->pts_to_stop + 90000;
152         }
153         else if( job->frame_to_stop )
154         {
155             /* Set the duration to a rough estimate */
156             duration = ( job->frame_to_stop / ( title->rate / title->rate_base ) ) * 90000;
157         }
158         else
159         {
160             duration = 0;
161             for( i = job->chapter_start; i <= job->chapter_end; i++ )
162             {
163                 chapter   = hb_list_item( title->list_chapter, i - 1 );
164                 duration += chapter->duration;
165             }
166             duration += 90000;
167             /* 1 second safety so we're sure we won't miss anything */
168         }
169         sync->count_frames_max = duration * title->rate / title->rate_base / 90000;
170     }
171
172     hb_log( "sync: expecting %d video frames", sync->count_frames_max );
173
174     /* Initialize libsamplerate for every audio track we have */
175     if ( ! job->indepth_scan )
176     {
177         for( i = 0; i < hb_list_count( title->list_audio ) && i < 8; i++ )
178         {
179             InitAudio( job, pv->common, i );
180         }
181     }
182     pv->common->first_pts = malloc( sizeof(int64_t) * pv->common->pts_count );
183     for ( i = 0; i < pv->common->pts_count; i++ )
184         pv->common->first_pts[i] = INT64_MAX;
185
186     return ret;
187 }
188
189 /***********************************************************************
190  * Close Video
191  ***********************************************************************
192  *
193  **********************************************************************/
194 void syncVideoClose( hb_work_object_t * w )
195 {
196     hb_work_private_t * pv = w->private_data;
197     hb_job_t          * job   = pv->job;
198     hb_sync_video_t   * sync = &pv->type.video;
199
200     // Wake up audio sync if it's still waiting on condition.
201     pv->common->pts_offset = 0;
202     pv->common->start_found = 1;
203     hb_cond_broadcast( pv->common->next_frame );
204
205     if( sync->cur )
206     {
207         hb_buffer_close( &sync->cur );
208     }
209
210     hb_log( "sync: got %d frames, %d expected",
211             pv->common->count_frames, sync->count_frames_max );
212
213     /* save data for second pass */
214     if( job->pass == 1 )
215     {
216         /* Preserve frame count for better accuracy in pass 2 */
217         hb_interjob_t * interjob = hb_interjob_get( job->h );
218         interjob->frame_count = pv->common->count_frames;
219         interjob->last_job = job->sequence_id;
220         interjob->total_time = sync->next_start;
221     }
222
223     if (sync->drops || sync->dups )
224     {
225         hb_log( "sync: %d frames dropped, %d duplicated", 
226                 sync->drops, sync->dups );
227     }
228
229     hb_lock( pv->common->mutex );
230     if ( --pv->common->ref == 0 )
231     {
232         hb_unlock( pv->common->mutex );
233         hb_lock_close( &pv->common->mutex );
234         free( pv->common );
235     }
236     else
237     {
238         hb_unlock( pv->common->mutex );
239     }
240
241     free( pv );
242     w->private_data = NULL;
243 }
244
245 /***********************************************************************
246  * syncVideoWork
247  ***********************************************************************
248  *
249  **********************************************************************/
250 int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
251               hb_buffer_t ** buf_out )
252 {
253     hb_buffer_t * cur, * next, * sub = NULL;
254     hb_work_private_t * pv = w->private_data;
255     hb_job_t          * job = pv->job;
256     hb_subtitle_t     * subtitle;
257     hb_sync_video_t   * sync = &pv->type.video;
258     int i;
259
260     *buf_out = NULL;
261     next = *buf_in;
262     *buf_in = NULL;
263
264     /* Wait for start of point-to-point encoding */
265     if( !pv->common->start_found )
266     {
267         hb_sync_video_t   * sync = &pv->type.video;
268
269         if( next->size == 0 )
270         {
271             *buf_out = next;
272             pv->common->start_found = 1;
273             hb_cond_broadcast( pv->common->next_frame );
274
275             /*
276              * Push through any subtitle EOFs in case they 
277              * were not synced through.
278              */
279             for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
280             {
281                 subtitle = hb_list_item( job->list_subtitle, i );
282                 if( subtitle->config.dest == PASSTHRUSUB )
283                 {
284                     if( subtitle->source == VOBSUB ) 
285                         hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
286                     else
287                         hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
288                 }
289             }
290             return HB_WORK_DONE;
291         }
292         if ( pv->common->count_frames < job->frame_to_start ||
293              next->start < job->pts_to_start )
294         {
295             // Flush any subtitles that have pts prior to the
296             // current frame
297             for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
298             {
299                 subtitle = hb_list_item( job->list_subtitle, i );
300                 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
301                 {
302                     if ( sub->start > next->start )
303                         break;
304                     sub = hb_fifo_get( subtitle->fifo_raw );
305                     hb_buffer_close( &sub );
306                 }
307             }
308             hb_lock( pv->common->mutex );
309             // Tell the audio threads what must be dropped
310             pv->common->audio_pts_thresh = next->start;
311             hb_cond_broadcast( pv->common->next_frame );
312             hb_unlock( pv->common->mutex );
313
314             UpdateSearchState( w, next->start );
315             hb_buffer_close( &next );
316
317             return HB_WORK_OK;
318         }
319         hb_lock( pv->common->mutex );
320         pv->common->start_found = 1;
321         pv->common->count_frames = 0;
322         hb_cond_broadcast( pv->common->next_frame );
323         hb_unlock( pv->common->mutex );
324         sync->st_first = 0;
325     }
326
327     /* Wait till we can determine the initial pts of all streams */
328     if( pv->common->pts_offset == INT64_MIN )
329     {
330         pv->common->first_pts[0] = next->start;
331         hb_lock( pv->common->mutex );
332         while( pv->common->pts_offset == INT64_MIN )
333         {
334             // Full fifos will make us wait forever, so get the
335             // pts offset from the available streams if full
336             if ( hb_fifo_is_full( job->fifo_raw ) )
337             {
338                 getPtsOffset( w );
339                 hb_cond_broadcast( pv->common->next_frame );
340             }
341             else if ( checkPtsOffset( w ) )
342                 hb_cond_broadcast( pv->common->next_frame );
343             else
344                 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
345         }
346         hb_unlock( pv->common->mutex );
347     }
348
349     if( !sync->cur )
350     {
351         sync->cur = next;
352         if( sync->cur->size == 0 )
353         {
354             /* we got an end-of-stream as our first video packet? 
355              * Feed it downstream & signal that we're done. 
356              */
357             *buf_out = hb_buffer_init( 0 );
358
359             pv->common->start_found = 1;
360             hb_cond_broadcast( pv->common->next_frame );
361
362             /*
363              * Push through any subtitle EOFs in case they 
364              * were not synced through.
365              */
366             for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
367             {
368                 subtitle = hb_list_item( job->list_subtitle, i );
369                 if( subtitle->config.dest == PASSTHRUSUB )
370                 {
371                     if( subtitle->source == VOBSUB ) 
372                         hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
373                     else
374                         hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
375                 }
376             }
377             return HB_WORK_DONE;
378         }
379         return HB_WORK_OK;
380     }
381     cur = sync->cur;
382     /* At this point we have a frame to process. Let's check
383         1) if we will be able to push into the fifo ahead
384         2) if the next frame is there already, since we need it to
385            compute the duration of the current frame*/
386     if( next->size == 0 )
387     {
388         hb_buffer_close( &next );
389
390         cur->start = sync->next_start;
391         cur->stop = cur->start + 90000. / ((double)job->vrate / (double)job->vrate_base);
392
393         /* Push the frame to the renderer */
394         hb_fifo_push( job->fifo_sync, cur );
395         sync->cur = NULL;
396
397         /* we got an end-of-stream. Feed it downstream & signal that
398          * we're done. Note that this means we drop the final frame of
399          * video (we don't know its duration). On DVDs the final frame
400          * is often strange and dropping it seems to be a good idea. */
401         *buf_out = hb_buffer_init( 0 );
402
403         /*
404          * Push through any subtitle EOFs in case they were not synced through.
405          */
406         for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
407         {
408             subtitle = hb_list_item( job->list_subtitle, i );
409             if( subtitle->config.dest == PASSTHRUSUB )
410             {
411                 if( subtitle->source == VOBSUB ) 
412                     hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
413                 else
414                     hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
415             }
416         }
417         pv->common->start_found = 1;
418         hb_cond_broadcast( pv->common->next_frame );
419         return HB_WORK_DONE;
420     }
421
422     /* Check for end of point-to-point frame encoding */
423     if( job->frame_to_stop && pv->common->count_frames > job->frame_to_stop )
424     {
425         // Drop an empty buffer into our output to ensure that things
426         // get flushed all the way out.
427         hb_buffer_close( &sync->cur );
428         hb_buffer_close( &next );
429         *buf_out = hb_buffer_init( 0 );
430         hb_log( "sync: reached %d frames, exiting early",
431                 pv->common->count_frames );
432
433         /*
434          * Push through any subtitle EOFs in case they were not synced through.
435          */
436         for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
437         {
438             subtitle = hb_list_item( job->list_subtitle, i );
439             if( subtitle->config.dest == PASSTHRUSUB )
440             {
441                 if( subtitle->source == VOBSUB ) 
442                     hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
443                 else
444                     hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
445             }
446         }
447         return HB_WORK_DONE;
448     }
449
450     /* Check for end of point-to-point pts encoding */
451     if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
452     {
453         // Drop an empty buffer into our output to ensure that things
454         // get flushed all the way out.
455         hb_log( "sync: reached pts %"PRId64", exiting early",
456                 sync->cur->start );
457         hb_buffer_close( &sync->cur );
458         hb_buffer_close( &next );
459         *buf_out = hb_buffer_init( 0 );
460
461         /*
462          * Push through any subtitle EOFs in case they were not synced through.
463          */
464         for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
465         {
466             subtitle = hb_list_item( job->list_subtitle, i );
467             if( subtitle->config.dest == PASSTHRUSUB )
468             {
469                 if( subtitle->source == VOBSUB ) 
470                     hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
471                 else
472                     hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
473             }
474         }
475         return HB_WORK_DONE;
476     }
477
478     if( sync->first_frame )
479     {
480         /* This is our first frame */
481         if ( cur->start > pv->common->pts_offset )
482         {
483             /*
484              * The first pts from a dvd should always be zero but
485              * can be non-zero with a transport or program stream since
486              * we're not guaranteed to start on an IDR frame. If we get
487              * a non-zero initial PTS extend its duration so it behaves
488              * as if it started at zero so that our audio timing will
489              * be in sync.
490              */
491             hb_log( "sync: first pts is %"PRId64, cur->start );
492             cur->start = pv->common->pts_offset;
493         }
494         sync->first_frame = 0;
495     }
496
497     /*
498      * since the first frame is always 0 and the upstream reader code
499      * is taking care of adjusting for pts discontinuities, we just have
500      * to deal with the next frame's start being in the past. This can
501      * happen when the PTS is adjusted after data loss but video frame
502      * reordering causes some frames with the old clock to appear after
503      * the clock change. This creates frames that overlap in time which
504      * looks to us like time going backward. The downstream muxing code
505      * can deal with overlaps of up to a frame time but anything larger
506      * we handle by dropping frames here.
507      */
508     hb_lock( pv->common->mutex );
509     if ( (int64_t)( next->start - pv->common->video_pts_slip - cur->start ) <= 0 )
510     {
511         if ( sync->first_drop == 0 )
512         {
513             sync->first_drop = next->start;
514         }
515         ++sync->drop_count;
516         if (next->start - cur->start > 0)
517         {
518             sync->pts_skip += next->start - cur->start;
519             pv->common->video_pts_slip -= next->start - cur->start;
520         }
521         hb_unlock( pv->common->mutex );
522         if ( next->new_chap )
523         {
524             // don't drop a chapter mark when we drop the buffer
525             sync->chap_mark = next->new_chap;
526         }
527         hb_buffer_close( &next );
528         return HB_WORK_OK;
529     }
530     hb_unlock( pv->common->mutex );
531     if ( sync->first_drop )
532     {
533         hb_log( "sync: video time didn't advance - dropped %d frames "
534                 "(delta %d ms, current %"PRId64", next %"PRId64", dur %d)",
535                 sync->drop_count, (int)( cur->start - sync->first_drop ) / 90,
536                 cur->start, next->start, (int)( next->start - cur->start ) );
537         sync->first_drop = 0;
538         sync->drop_count = 0;
539     }
540
541     /*
542      * Track the video sequence number localy so that we can sync the audio
543      * to it using the sequence number as well as the PTS.
544      */
545     sync->video_sequence = cur->sequence;
546
547     /*
548      * Look for a subtitle for this frame.
549      *
550      * If found then it will be tagged onto a video buffer of the correct time and 
551      * sent in to the render pipeline. This only needs to be done for VOBSUBs which
552      * get rendered, other types of subtitles can just sit in their raw_queue until
553      * delt with at muxing.
554      */
555     for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
556     {
557         subtitle = hb_list_item( job->list_subtitle, i );
558
559         /*
560          * Rewrite timestamps on subtitles that need it (on raw queue).
561          */
562         if( subtitle->source == CC608SUB ||
563             subtitle->source == CC708SUB ||
564             subtitle->source == SRTSUB )
565         {
566             /*
567              * Rewrite timestamps on subtitles that came from Closed Captions
568              * since they are using the MPEG2 timestamps.
569              */
570             while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
571             {
572                 /*
573                  * Rewrite the timestamps as and when the video
574                  * (cur->start) reaches the same timestamp as a
575                  * closed caption (sub->start).
576                  *
577                  * What about discontinuity boundaries - not delt
578                  * with here - Van?
579                  *
580                  * Bypass the sync fifo altogether.
581                  */
582                 if( sub->size <= 0 )
583                 {
584                     sub = hb_fifo_get( subtitle->fifo_raw );
585                     hb_fifo_push( subtitle->fifo_out, sub );
586                     sub = NULL;
587                     break;
588                 } else {
589                     /*
590                      * Sync the subtitles to the incoming video, and use
591                      * the matching converted video timestamp.
592                      *
593                      * Note that it doesn't appear that we need to convert 
594                      * timestamps, I guess that they were already correct,
595                      * so just push them through for rendering.
596                      *
597                      */
598                     if( sub->start < cur->start )
599                     {
600                         sub = hb_fifo_get( subtitle->fifo_raw );
601                         hb_fifo_push( subtitle->fifo_out, sub );
602                     } else {
603                         sub = NULL;
604                         break;
605                     }
606                 }
607             }
608         }
609
610         if( subtitle->source == VOBSUB ) 
611         {
612             hb_buffer_t * sub2;
613             while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
614             {
615                 if( sub->size == 0 )
616                 {
617                     /*
618                      * EOF, pass it through immediately.
619                      */
620                     break;
621                 }
622
623                 /* If two subtitles overlap, make the first one stop
624                    when the second one starts */
625                 sub2 = hb_fifo_see2( subtitle->fifo_raw );
626                 if( sub2 && sub->stop > sub2->start )
627                 {
628                     sub->stop = sub2->start;
629                 }
630                 
631                 // hb_log("0x%x: video seq: %"PRId64" subtitle sequence: %"PRId64,
632                 //       sub, cur->sequence, sub->sequence);
633                 
634                 if( sub->sequence > cur->sequence )
635                 {
636                     /*
637                      * The video is behind where we are, so wait until
638                      * it catches up to the same reader point on the
639                      * DVD. Then our PTS should be in the same region
640                      * as the video.
641                      */
642                     sub = NULL;
643                     break;
644                 }
645                 
646                 if( sub->stop > cur->start ) {
647                     /*
648                      * The stop time is in the future, so fall through
649                      * and we'll deal with it in the next block of
650                      * code.
651                      */
652
653                     /*
654                      * There is a valid subtitle, is it time to display it?
655                      */
656                     if( sub->stop > sub->start)
657                     {
658                         /*
659                          * Normal subtitle which ends after it starts, 
660                          * check to see that the current video is between 
661                          * the start and end.
662                          */
663                         if( cur->start > sub->start &&
664                             cur->start < sub->stop )
665                         {
666                             /*
667                             * We should be playing this, so leave the
668                             * subtitle in place.
669                             *
670                             * fall through to display
671                             */
672                             if( ( sub->stop - sub->start ) < ( 2 * 90000 ) )
673                             {
674                                 /*
675                                  * Subtitle is on for less than three 
676                                  * seconds, extend the time that it is 
677                                  * displayed to make it easier to read. 
678                                  * Make it 3 seconds or until the next
679                                  * subtitle is displayed.
680                                  *
681                                  * This is in response to Indochine which 
682                                  * only displays subs for 1 second - 
683                                  * too fast to read.
684                                  */
685                                 sub->stop = sub->start + ( 2 * 90000 );
686                             
687                                 sub2 = hb_fifo_see2( subtitle->fifo_raw );
688                             
689                                 if( sub2 && sub->stop > sub2->start )
690                                 {
691                                     sub->stop = sub2->start;
692                                 }
693                             }
694                         }
695                         else
696                         {
697                             /*
698                              * Defer until the play point is within 
699                              * the subtitle
700                              */
701                             sub = NULL;
702                         }
703                     }
704                     else
705                     {
706                         /*
707                          * The end of the subtitle is less than the start, 
708                          * this is a sign of a PTS discontinuity.
709                          */
710                         if( sub->start > cur->start )
711                         {
712                             /*
713                              * we haven't reached the start time yet, or
714                              * we have jumped backwards after having
715                              * already started this subtitle.
716                              */
717                             if( cur->start < sub->stop )
718                             {
719                                 /*
720                                  * We have jumped backwards and so should
721                                  * continue displaying this subtitle.
722                                  *
723                                  * fall through to display.
724                                  */
725                             }
726                             else
727                             {
728                                 /*
729                                  * Defer until the play point is 
730                                  * within the subtitle
731                                  */
732                                 sub = NULL;
733                             }
734                         } else {
735                             /*
736                             * Play this subtitle as the start is 
737                             * greater than our video point.
738                             *
739                             * fall through to display/
740                             */
741                         }
742                     }
743                         break;
744                 }
745                 else
746                 {
747                     
748                     /*
749                      * The subtitle is older than this picture, trash it
750                      */
751                     sub = hb_fifo_get( subtitle->fifo_raw );
752                     hb_buffer_close( &sub );
753                 }
754             }
755             
756             /* If we have a subtitle for this picture, copy it */
757             /* FIXME: we should avoid this memcpy */
758             if( sub )
759             {
760                 if( sub->size > 0 )
761                 {
762                     if( subtitle->config.dest == RENDERSUB )
763                     {
764                         if ( cur->sub == NULL )
765                         {
766                             /*
767                              * Tack onto the video buffer for rendering
768                              */
769                             cur->sub         = hb_buffer_init( sub->size );
770                             cur->sub->x      = sub->x;
771                             cur->sub->y      = sub->y;
772                             cur->sub->width  = sub->width;
773                             cur->sub->height = sub->height;
774                             memcpy( cur->sub->data, sub->data, sub->size ); 
775                         }
776                     } else {
777                         /*
778                          * Pass-Through, pop it off of the raw queue, 
779                          */
780                         sub = hb_fifo_get( subtitle->fifo_raw );
781                         hb_fifo_push( subtitle->fifo_sync, sub );
782                     }
783                 } else {
784                     /*
785                     * EOF - consume for rendered, else pass through
786                     */
787                     if( subtitle->config.dest == RENDERSUB )
788                     {
789                         sub = hb_fifo_get( subtitle->fifo_raw );
790                         hb_buffer_close( &sub );
791                     } else {
792                         sub = hb_fifo_get( subtitle->fifo_raw );
793                         hb_fifo_push( subtitle->fifo_sync, sub );
794                     }
795                 }
796             }
797         }
798     } // end subtitles
799
800     /*
801      * Adjust the pts of the current frame so that it's contiguous
802      * with the previous frame. The start time of the current frame
803      * has to be the end time of the previous frame and the stop
804      * time has to be the start of the next frame.  We don't
805      * make any adjustments to the source timestamps other than removing
806      * the clock offsets (which also removes pts discontinuities).
807      * This means we automatically encode at the source's frame rate.
808      * MP2 uses an implicit duration (frames end when the next frame
809      * starts) but more advanced containers like MP4 use an explicit
810      * duration. Since we're looking ahead one frame we set the
811      * explicit stop time from the start time of the next frame.
812      */
813     *buf_out = cur;
814     sync->cur = cur = next;
815     cur->sub = NULL;
816     sync->next_pts = cur->start;
817     int64_t duration = cur->start - sync->pts_skip - (*buf_out)->start;
818     sync->pts_skip = 0;
819     if ( duration <= 0 )
820     {
821         hb_log( "sync: invalid video duration %"PRId64", start %"PRId64", next %"PRId64"",
822                 duration, (*buf_out)->start, next->start );
823     }
824
825     (*buf_out)->start = sync->next_start;
826     sync->next_start += duration;
827     (*buf_out)->stop = sync->next_start;
828
829     if ( sync->chap_mark )
830     {
831         // we have a pending chapter mark from a recent drop - put it on this
832         // buffer (this may make it one frame late but we can't do any better).
833         (*buf_out)->new_chap = sync->chap_mark;
834         sync->chap_mark = 0;
835     }
836
837     /* Update UI */
838     UpdateState( w );
839
840     return HB_WORK_OK;
841 }
842
843 // sync*Init does nothing because sync has a special initializer
844 // that takes care of initializing video and all audio tracks
845 int syncVideoInit( hb_work_object_t * w, hb_job_t * job)
846 {
847     return 0;
848 }
849
850 hb_work_object_t hb_sync_video =
851 {
852     WORK_SYNC_VIDEO,
853     "Video Synchronization",
854     syncVideoInit,
855     syncVideoWork,
856     syncVideoClose
857 };
858
859 /***********************************************************************
860  * Close Audio
861  ***********************************************************************
862  *
863  **********************************************************************/
864 void syncAudioClose( hb_work_object_t * w )
865 {
866     hb_work_private_t * pv    = w->private_data;
867     hb_sync_audio_t   * sync  = &pv->type.audio;
868
869     if( w->audio->config.out.codec == HB_ACODEC_AC3 )
870     {
871         free( sync->ac3_buf );
872     }
873     else
874     {
875         src_delete( sync->state );
876     }
877
878     hb_lock( pv->common->mutex );
879     if ( --pv->common->ref == 0 )
880     {
881         hb_unlock( pv->common->mutex );
882         hb_lock_close( &pv->common->mutex );
883         free( pv->common );
884     }
885     else
886     {
887         hb_unlock( pv->common->mutex );
888     }
889
890     free( pv );
891     w->private_data = NULL;
892 }
893
894 int syncAudioInit( hb_work_object_t * w, hb_job_t * job)
895 {
896     return 0;
897 }
898
899 /***********************************************************************
900  * SyncAudio
901  ***********************************************************************
902  *
903  **********************************************************************/
904 static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
905                        hb_buffer_t ** buf_out )
906 {
907     hb_work_private_t * pv = w->private_data;
908     hb_job_t        * job = pv->job;
909     hb_sync_audio_t * sync = &pv->type.audio;
910     hb_buffer_t     * buf;
911     int64_t start;
912
913     *buf_out = NULL;
914     buf = *buf_in;
915     *buf_in = NULL;
916     /* if the next buffer is an eof send it downstream */
917     if ( buf->size <= 0 )
918     {
919         hb_buffer_close( &buf );
920         *buf_out = hb_buffer_init( 0 );
921         return HB_WORK_DONE;
922     }
923
924     /* Wait for start frame if doing point-to-point */
925     hb_lock( pv->common->mutex );
926     while ( !pv->common->start_found )
927     {
928         if ( buf->start < pv->common->audio_pts_thresh )
929         {
930             hb_buffer_close( &buf );
931             hb_unlock( pv->common->mutex );
932             return HB_WORK_OK;
933         }
934         while ( !pv->common->start_found && 
935                 buf->start >= pv->common->audio_pts_thresh )
936         {
937             hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
938         }
939     }
940     if ( buf->start < pv->common->audio_pts_thresh )
941     {
942         hb_buffer_close( &buf );
943         hb_unlock( pv->common->mutex );
944         return HB_WORK_OK;
945     }
946     hb_unlock( pv->common->mutex );
947
948     /* Wait till we can determine the initial pts of all streams */
949     if( pv->common->pts_offset == INT64_MIN )
950     {
951         pv->common->first_pts[sync->index+1] = buf->start;
952         hb_lock( pv->common->mutex );
953         while( pv->common->pts_offset == INT64_MIN )
954         {
955             // Full fifos will make us wait forever, so get the
956             // pts offset from the available streams if full
957             if (hb_fifo_is_full(w->fifo_in))
958             {
959                 getPtsOffset( w );
960                 hb_cond_broadcast( pv->common->next_frame );
961             }
962             else if ( checkPtsOffset( w ) )
963                 hb_cond_broadcast( pv->common->next_frame );
964             else
965                 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
966         }
967         hb_unlock( pv->common->mutex );
968     }
969
970     if( job->frame_to_stop && pv->common->count_frames >= job->frame_to_stop )
971     {
972         hb_buffer_close( &buf );
973         *buf_out = hb_buffer_init( 0 );
974         return HB_WORK_DONE;
975     }
976
977     if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
978     {
979         hb_buffer_close( &buf );
980         *buf_out = hb_buffer_init( 0 );
981         return HB_WORK_DONE;
982     }
983
984     hb_lock( pv->common->mutex );
985     start = buf->start - pv->common->audio_passthru_slip;
986     hb_unlock( pv->common->mutex );
987     if ( (int64_t)( start - sync->next_pts ) < 0 )
988     {
989         // audio time went backwards.
990         // If our output clock is more than a half frame ahead of the
991         // input clock drop this frame to move closer to sync.
992         // Otherwise drop frames until the input clock matches the output clock.
993         if ( sync->first_drop || sync->next_start - start > 90*15 )
994         {
995             // Discard data that's in the past.
996             if ( sync->first_drop == 0 )
997             {
998                 sync->first_drop = sync->next_pts;
999             }
1000             ++sync->drop_count;
1001             hb_buffer_close( &buf );
1002             return HB_WORK_OK;
1003         }
1004         sync->next_pts = start;
1005     }
1006     if ( sync->first_drop )
1007     {
1008         // we were dropping old data but input buf time is now current
1009         hb_log( "sync: audio %d time went backwards %d ms, dropped %d frames "
1010                 "(next %"PRId64", current %"PRId64")", w->audio->id,
1011                 (int)( sync->next_pts - sync->first_drop ) / 90,
1012                 sync->drop_count, sync->first_drop, sync->next_pts );
1013         sync->first_drop = 0;
1014         sync->drop_count = 0;
1015         sync->next_pts = start;
1016     }
1017     if ( start - sync->next_pts >= (90 * 70) )
1018     {
1019         if ( start - sync->next_pts > (90000LL * 60) )
1020         {
1021             // there's a gap of more than a minute between the last
1022             // frame and this. assume we got a corrupted timestamp
1023             // and just drop the next buf.
1024             hb_log( "sync: %d minute time gap in audio %d - dropping buf"
1025                     "  start %"PRId64", next %"PRId64,
1026                     (int)((start - sync->next_pts) / (90000*60)),
1027                     w->audio->id, start, sync->next_pts );
1028             hb_buffer_close( &buf );
1029             return HB_WORK_OK;
1030         }
1031         /*
1032          * there's a gap of at least 70ms between the last
1033          * frame we processed & the next. Fill it with silence.
1034          * Or in the case of DCA, skip some frames from the
1035          * other streams.
1036          */
1037         if( w->audio->config.out.codec == HB_ACODEC_DCA )
1038         {
1039             hb_log( "sync: audio gap %d ms. Skipping frames. Audio %d"
1040                     "  start %"PRId64", next %"PRId64,
1041                     (int)((start - sync->next_pts) / 90),
1042                     w->audio->id, start, sync->next_pts );
1043             hb_lock( pv->common->mutex );
1044             pv->common->audio_passthru_slip += (start - sync->next_pts);
1045             pv->common->video_pts_slip += (start - sync->next_pts);
1046             hb_unlock( pv->common->mutex );
1047             *buf_out = buf;
1048             return HB_WORK_OK;
1049         }
1050         hb_log( "sync: adding %d ms of silence to audio %d"
1051                 "  start %"PRId64", next %"PRId64,
1052                 (int)((start - sync->next_pts) / 90),
1053                 w->audio->id, start, sync->next_pts );
1054         InsertSilence( w, start - sync->next_pts );
1055     }
1056
1057     /*
1058      * When we get here we've taken care of all the dups and gaps in the
1059      * audio stream and are ready to inject the next input frame into
1060      * the output stream.
1061      */
1062     *buf_out = OutputAudioFrame( w->audio, buf, sync );
1063     return HB_WORK_OK;
1064 }
1065
1066 hb_work_object_t hb_sync_audio =
1067 {
1068     WORK_SYNC_AUDIO,
1069     "AudioSynchronization",
1070     syncAudioInit,
1071     syncAudioWork,
1072     syncAudioClose
1073 };
1074
1075 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
1076 {
1077     hb_work_object_t  * w;
1078     hb_work_private_t * pv;
1079     hb_title_t        * title = job->title;
1080     hb_sync_audio_t   * sync;
1081
1082     pv = calloc( 1, sizeof( hb_work_private_t ) );
1083     sync = &pv->type.audio;
1084     sync->index = i;
1085     pv->job    = job;
1086     pv->common = common;
1087     pv->common->ref++;
1088     pv->common->pts_count++;
1089
1090     w = hb_get_work( WORK_SYNC_AUDIO );
1091     w->private_data = pv;
1092     w->audio = hb_list_item( title->list_audio, i );
1093     w->fifo_in = w->audio->priv.fifo_raw;
1094
1095     if( w->audio->config.out.codec == HB_ACODEC_AC3 ||
1096         w->audio->config.out.codec == HB_ACODEC_DCA )
1097     {
1098         w->fifo_out = w->audio->priv.fifo_out;
1099     }
1100     else
1101     {
1102         w->fifo_out = w->audio->priv.fifo_sync;
1103     }
1104
1105     if( w->audio->config.out.codec == HB_ACODEC_AC3 )
1106     {
1107         /* Have a silent AC-3 frame ready in case we have to fill a
1108            gap */
1109         AVCodec        * codec;
1110         AVCodecContext * c;
1111         short          * zeros;
1112
1113         codec = avcodec_find_encoder( CODEC_ID_AC3 );
1114         c     = avcodec_alloc_context();
1115
1116         c->bit_rate    = w->audio->config.in.bitrate;
1117         c->sample_rate = w->audio->config.in.samplerate;
1118         c->channels    = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( w->audio->config.in.channel_layout );
1119
1120         if( hb_avcodec_open( c, codec ) < 0 )
1121         {
1122             hb_log( "sync: avcodec_open failed" );
1123             return;
1124         }
1125
1126         zeros          = calloc( AC3_SAMPLES_PER_FRAME *
1127                                  sizeof( short ) * c->channels, 1 );
1128         sync->ac3_size = w->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /
1129                              w->audio->config.in.samplerate / 8;
1130         sync->ac3_buf  = malloc( sync->ac3_size );
1131
1132         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
1133                                   zeros ) != sync->ac3_size )
1134         {
1135             hb_log( "sync: avcodec_encode_audio failed" );
1136         }
1137
1138         free( zeros );
1139         hb_avcodec_close( c );
1140         av_free( c );
1141     }
1142     else
1143     {
1144         /* Initialize libsamplerate */
1145         int error;
1146         sync->state = src_new( SRC_SINC_MEDIUM_QUALITY, 
1147             HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
1148                 w->audio->config.out.mixdown), &error );
1149         sync->data.end_of_input = 0;
1150     }
1151     hb_list_add( job->list_work, w );
1152 }
1153
1154 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
1155                                        hb_sync_audio_t *sync )
1156 {
1157     int64_t start = sync->next_start;
1158     int64_t duration = buf->stop - buf->start;
1159
1160     sync->next_pts += duration;
1161
1162     if( audio->config.in.samplerate == audio->config.out.samplerate ||
1163         audio->config.out.codec == HB_ACODEC_AC3 ||
1164         audio->config.out.codec == HB_ACODEC_DCA )
1165     {
1166         /*
1167          * If we don't have to do sample rate conversion or this audio is 
1168          * pass-thru just send the input buffer downstream after adjusting
1169          * its timestamps to make the output stream continuous.
1170          */
1171     }
1172     else
1173     {
1174         /* Not pass-thru - do sample rate conversion */
1175         int count_in, count_out;
1176         hb_buffer_t * buf_raw = buf;
1177         int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown) *
1178                             sizeof( float );
1179
1180         count_in  = buf_raw->size / channel_count;
1181         /*
1182          * When using stupid rates like 44.1 there will always be some
1183          * truncation error. E.g., a 1536 sample AC3 frame will turn into a
1184          * 1536*44.1/48.0 = 1411.2 sample frame. If we just truncate the .2
1185          * the error will build up over time and eventually the audio will
1186          * substantially lag the video. libsamplerate will keep track of the
1187          * fractional sample & give it to us when appropriate if we give it
1188          * an extra sample of space in the output buffer.
1189          */
1190         count_out = ( duration * audio->config.out.samplerate ) / 90000 + 1;
1191
1192         sync->data.input_frames = count_in;
1193         sync->data.output_frames = count_out;
1194         sync->data.src_ratio = (double)audio->config.out.samplerate /
1195                                (double)audio->config.in.samplerate;
1196
1197         buf = hb_buffer_init( count_out * channel_count );
1198         sync->data.data_in  = (float *) buf_raw->data;
1199         sync->data.data_out = (float *) buf->data;
1200         if( src_process( sync->state, &sync->data ) )
1201         {
1202             /* XXX If this happens, we're screwed */
1203             hb_log( "sync: audio %d src_process failed", audio->id );
1204         }
1205         hb_buffer_close( &buf_raw );
1206
1207         buf->size = sync->data.output_frames_gen * channel_count;
1208         duration = ( sync->data.output_frames_gen * 90000 ) /
1209                    audio->config.out.samplerate;
1210     }
1211     buf->frametype = HB_FRAME_AUDIO;
1212     buf->start = start;
1213     buf->stop  = start + duration;
1214     sync->next_start = start + duration;
1215     return buf;
1216 }
1217
1218 static void InsertSilence( hb_work_object_t * w, int64_t duration )
1219 {
1220     hb_work_private_t * pv = w->private_data;
1221     hb_sync_audio_t *sync = &pv->type.audio;
1222     hb_buffer_t     *buf;
1223     hb_fifo_t       *fifo;
1224
1225     // to keep pass-thru and regular audio in sync we generate silence in
1226     // AC3 frame-sized units. If the silence duration isn't an integer multiple
1227     // of the AC3 frame duration we will truncate or round up depending on
1228     // which minimizes the timing error.
1229     const int frame_dur = ( 90000 * AC3_SAMPLES_PER_FRAME ) /
1230                           w->audio->config.in.samplerate;
1231     int frame_count = ( duration + (frame_dur >> 1) ) / frame_dur;
1232
1233     while ( --frame_count >= 0 )
1234     {
1235         if( w->audio->config.out.codec == HB_ACODEC_AC3 )
1236         {
1237             buf        = hb_buffer_init( sync->ac3_size );
1238             buf->start = sync->next_pts;
1239             buf->stop  = buf->start + frame_dur;
1240             memcpy( buf->data, sync->ac3_buf, buf->size );
1241             fifo = w->audio->priv.fifo_out;
1242         }
1243         else
1244         {
1245             buf = hb_buffer_init( AC3_SAMPLES_PER_FRAME * sizeof( float ) *
1246                                      HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
1247                                          w->audio->config.out.mixdown) );
1248             buf->start = sync->next_pts;
1249             buf->stop  = buf->start + frame_dur;
1250             memset( buf->data, 0, buf->size );
1251             fifo = w->audio->priv.fifo_sync;
1252         }
1253         buf = OutputAudioFrame( w->audio, buf, sync );
1254         hb_fifo_push( fifo, buf );
1255     }
1256 }
1257
1258 static void UpdateState( hb_work_object_t * w )
1259 {
1260     hb_work_private_t * pv = w->private_data;
1261     hb_sync_video_t   * sync = &pv->type.video;
1262     hb_state_t state;
1263
1264     if( !pv->common->count_frames )
1265     {
1266         sync->st_first = hb_get_date();
1267         pv->job->st_pause_date = -1;
1268         pv->job->st_paused = 0;
1269     }
1270     pv->common->count_frames++;
1271
1272     if( hb_get_date() > sync->st_dates[3] + 1000 )
1273     {
1274         memmove( &sync->st_dates[0], &sync->st_dates[1],
1275                  3 * sizeof( uint64_t ) );
1276         memmove( &sync->st_counts[0], &sync->st_counts[1],
1277                  3 * sizeof( uint64_t ) );
1278         sync->st_dates[3]  = hb_get_date();
1279         sync->st_counts[3] = pv->common->count_frames;
1280     }
1281
1282 #define p state.param.working
1283     state.state = HB_STATE_WORKING;
1284     p.progress  = (float) pv->common->count_frames / (float) sync->count_frames_max;
1285     if( p.progress > 1.0 )
1286     {
1287         p.progress = 1.0;
1288     }
1289     p.rate_cur   = 1000.0 *
1290         (float) ( sync->st_counts[3] - sync->st_counts[0] ) /
1291         (float) ( sync->st_dates[3] - sync->st_dates[0] );
1292     if( hb_get_date() > sync->st_first + 4000 )
1293     {
1294         int eta;
1295         p.rate_avg = 1000.0 * (float) sync->st_counts[3] /
1296             (float) ( sync->st_dates[3] - sync->st_first - pv->job->st_paused);
1297         eta = (float) ( sync->count_frames_max - sync->st_counts[3] ) /
1298             p.rate_avg;
1299         p.hours   = eta / 3600;
1300         p.minutes = ( eta % 3600 ) / 60;
1301         p.seconds = eta % 60;
1302     }
1303     else
1304     {
1305         p.rate_avg = 0.0;
1306         p.hours    = -1;
1307         p.minutes  = -1;
1308         p.seconds  = -1;
1309     }
1310 #undef p
1311
1312     hb_set_state( pv->job->h, &state );
1313 }
1314
1315 static void UpdateSearchState( hb_work_object_t * w, int64_t start )
1316 {
1317     hb_work_private_t * pv = w->private_data;
1318     hb_sync_video_t   * sync = &pv->type.video;
1319     hb_state_t state;
1320     uint64_t now;
1321     double avg;
1322
1323     now = hb_get_date();
1324     if( !pv->common->count_frames )
1325     {
1326         sync->st_first = now;
1327         pv->job->st_pause_date = -1;
1328         pv->job->st_paused = 0;
1329     }
1330     pv->common->count_frames++;
1331
1332 #define p state.param.working
1333     state.state = HB_STATE_SEARCHING;
1334     if ( pv->job->frame_to_start )
1335         p.progress  = (float) pv->common->count_frames / 
1336                       (float) pv->job->frame_to_start;
1337     else if ( pv->job->pts_to_start )
1338         p.progress  = (float) start / (float) pv->job->pts_to_start;
1339     else
1340         p.progress = 0;
1341     if( p.progress > 1.0 )
1342     {
1343         p.progress = 1.0;
1344     }
1345     if (now > sync->st_first)
1346     {
1347         int eta;
1348
1349         if ( pv->job->frame_to_start )
1350         {
1351             avg = 1000.0 * (double)pv->common->count_frames / (now - sync->st_first);
1352             eta = ( pv->job->frame_to_start - pv->common->count_frames ) / avg;
1353         }
1354         else if ( pv->job->pts_to_start )
1355         {
1356             avg = 1000.0 * (double)start / (now - sync->st_first);
1357             eta = ( pv->job->pts_to_start - start ) / avg;
1358         }
1359         p.hours   = eta / 3600;
1360         p.minutes = ( eta % 3600 ) / 60;
1361         p.seconds = eta % 60;
1362     }
1363     else
1364     {
1365         p.rate_avg = 0.0;
1366         p.hours    = -1;
1367         p.minutes  = -1;
1368         p.seconds  = -1;
1369     }
1370 #undef p
1371
1372     hb_set_state( pv->job->h, &state );
1373 }
1374
1375 static void getPtsOffset( hb_work_object_t * w )
1376 {
1377     hb_work_private_t * pv = w->private_data;
1378     int           i ;
1379     int64_t       first_pts = INT64_MAX;
1380
1381     for( i = 0; i < pv->common->pts_count; i++ )
1382     {
1383         if ( pv->common->first_pts[i] < first_pts )
1384             first_pts = pv->common->first_pts[i];
1385     }
1386     pv->common->audio_passthru_slip = pv->common->pts_offset = first_pts;
1387     return;
1388 }
1389
1390 static int checkPtsOffset( hb_work_object_t * w )
1391 {
1392     hb_work_private_t * pv = w->private_data;
1393     int           i ;
1394
1395     for( i = 0; i < pv->common->pts_count; i++ )
1396     {
1397         if ( pv->common->first_pts[i] == INT64_MAX )
1398             return 0;
1399     }
1400     getPtsOffset( w );
1401     return 1;
1402 }