OSDN Git Service

SunOS support fixed with new ffmpeg and x264
[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 <stdio.h>
9
10 #include "samplerate.h"
11 #include "libavcodec/avcodec.h"
12
13 #ifdef INT64_MIN
14 #undef INT64_MIN /* Because it isn't defined correctly in Zeta */
15 #endif
16 #define INT64_MIN (-9223372036854775807LL-1)
17
18 #define AC3_SAMPLES_PER_FRAME 1536
19
20 typedef struct
21 {
22     hb_audio_t * audio;
23
24     int64_t      next_start;    /* start time of next output frame */
25     int64_t      next_pts;      /* start time of next input frame */
26     int64_t      first_drop;    /* PTS of first 'went backwards' frame dropped */
27     int          drop_count;    /* count of 'time went backwards' drops */
28
29     /* Raw */
30     SRC_STATE  * state;
31     SRC_DATA     data;
32
33     /* AC-3 */
34     int          ac3_size;
35     uint8_t    * ac3_buf;
36
37 } hb_sync_audio_t;
38
39 struct hb_work_private_s
40 {
41     hb_job_t * job;
42     int        busy;            // bitmask with one bit for each active input
43                                 // (bit 0 = video; 1 = audio 0, 2 = audio 1, ...
44                                 // appropriate bit is cleared when input gets
45                                 // an eof buf. syncWork returns done when all
46                                 // bits are clear.
47     /* Video */
48     hb_subtitle_t * subtitle;
49     int64_t pts_offset;
50     int64_t next_start;         /* start time of next output frame */
51     int64_t next_pts;           /* start time of next input frame */
52     int64_t first_drop;         /* PTS of first 'went backwards' frame dropped */
53     int drop_count;             /* count of 'time went backwards' drops */
54     int drops;                  /* frames dropped to make a cbr video stream */
55     int dups;                   /* frames duplicated to make a cbr video stream */
56     int video_sequence;
57     int count_frames;
58     int count_frames_max;
59     int chap_mark;              /* to propagate chapter mark across a drop */
60     hb_buffer_t * cur; /* The next picture to process */
61
62     /* Audio */
63     hb_sync_audio_t sync_audio[8];
64
65     /* Statistics */
66     uint64_t st_counts[4];
67     uint64_t st_dates[4];
68     uint64_t st_first;
69 };
70
71 /***********************************************************************
72  * Local prototypes
73  **********************************************************************/
74 static void InitAudio( hb_work_object_t * w, int i );
75 static void SyncVideo( hb_work_object_t * w );
76 static void SyncAudio( hb_work_object_t * w, int i );
77 static void InsertSilence( hb_work_object_t * w, int i, int64_t d );
78 static void UpdateState( hb_work_object_t * w );
79
80 /***********************************************************************
81  * hb_work_sync_init
82  ***********************************************************************
83  * Initialize the work object
84  **********************************************************************/
85 int syncInit( hb_work_object_t * w, hb_job_t * job )
86 {
87     hb_title_t       * title = job->title;
88     hb_chapter_t     * chapter;
89     int                i;
90     uint64_t           duration;
91     hb_work_private_t * pv;
92
93     pv = calloc( 1, sizeof( hb_work_private_t ) );
94     w->private_data = pv;
95
96     pv->job            = job;
97     pv->pts_offset     = INT64_MIN;
98
99     /* Calculate how many video frames we are expecting */
100     duration = 0;
101     for( i = job->chapter_start; i <= job->chapter_end; i++ )
102     {
103         chapter   = hb_list_item( title->list_chapter, i - 1 );
104         duration += chapter->duration;
105     }
106     duration += 90000;
107         /* 1 second safety so we're sure we won't miss anything */
108     pv->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
109
110     hb_log( "sync: expecting %d video frames", pv->count_frames_max );
111     pv->busy |= 1;
112
113     /* Initialize libsamplerate for every audio track we have */
114     if ( ! job->indepth_scan )
115     {
116         for( i = 0; i < hb_list_count( title->list_audio ); i++ )
117         {
118             pv->busy |= ( 1 << (i + 1) );
119             InitAudio( w, i );
120         }
121     }
122
123     /* Get subtitle info, if any */
124     pv->subtitle = hb_list_item( title->list_subtitle, 0 );
125
126     return 0;
127 }
128
129 /***********************************************************************
130  * Close
131  ***********************************************************************
132  *
133  **********************************************************************/
134 void syncClose( hb_work_object_t * w )
135 {
136     hb_work_private_t * pv = w->private_data;
137     hb_job_t          * job   = pv->job;
138     hb_title_t        * title = job->title;
139     hb_audio_t        * audio = NULL;
140     int i;
141
142     if( pv->cur )
143     {
144         hb_buffer_close( &pv->cur );
145     }
146
147     hb_log( "sync: got %d frames, %d expected",
148             pv->count_frames, pv->count_frames_max );
149
150     if (pv->drops || pv->dups )
151     {
152         hb_log( "sync: %d frames dropped, %d duplicated", pv->drops, pv->dups );
153     }
154
155     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
156     {
157         audio = hb_list_item( title->list_audio, i );
158         if( audio->config.out.codec == HB_ACODEC_AC3 )
159         {
160             free( pv->sync_audio[i].ac3_buf );
161         }
162         else
163         {
164             src_delete( pv->sync_audio[i].state );
165         }
166     }
167
168     free( pv );
169     w->private_data = NULL;
170 }
171
172 /***********************************************************************
173  * Work
174  ***********************************************************************
175  * The root routine of this work abject
176  *
177  * The way this works is that we are syncing the audio to the PTS of
178  * the last video that we processed. That's why we skip the audio sync
179  * if we haven't got a valid PTS from the video yet.
180  *
181  **********************************************************************/
182 int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
183               hb_buffer_t ** unused2 )
184 {
185     hb_work_private_t * pv = w->private_data;
186     int i;
187
188     if ( pv->busy & 1 )
189         SyncVideo( w );
190
191     for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
192     {
193         if ( pv->busy & ( 1 << (i + 1) ) )
194             SyncAudio( w, i );
195     }
196
197     return ( pv->busy? HB_WORK_OK : HB_WORK_DONE );
198 }
199
200 hb_work_object_t hb_sync =
201 {
202     WORK_SYNC,
203     "Synchronization",
204     syncInit,
205     syncWork,
206     syncClose
207 };
208
209 static void InitAudio( hb_work_object_t * w, int i )
210 {
211     hb_work_private_t * pv = w->private_data;
212     hb_job_t        * job   = pv->job;
213     hb_title_t      * title = job->title;
214     hb_sync_audio_t * sync;
215
216     sync        = &pv->sync_audio[i];
217     sync->audio = hb_list_item( title->list_audio, i );
218
219     if( sync->audio->config.out.codec == HB_ACODEC_AC3 )
220     {
221         /* Have a silent AC-3 frame ready in case we have to fill a
222            gap */
223         AVCodec        * codec;
224         AVCodecContext * c;
225         short          * zeros;
226
227         codec = avcodec_find_encoder( CODEC_ID_AC3 );
228         c     = avcodec_alloc_context();
229
230         c->bit_rate    = sync->audio->config.in.bitrate;
231         c->sample_rate = sync->audio->config.in.samplerate;
232         c->channels    = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( sync->audio->config.in.channel_layout );
233
234         if( avcodec_open( c, codec ) < 0 )
235         {
236             hb_log( "sync: avcodec_open failed" );
237             return;
238         }
239
240         zeros          = calloc( AC3_SAMPLES_PER_FRAME *
241                                  sizeof( short ) * c->channels, 1 );
242         sync->ac3_size = sync->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /
243                              sync->audio->config.in.samplerate / 8;
244         sync->ac3_buf  = malloc( sync->ac3_size );
245
246         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
247                                   zeros ) != sync->ac3_size )
248         {
249             hb_log( "sync: avcodec_encode_audio failed" );
250         }
251
252         free( zeros );
253         avcodec_close( c );
254         av_free( c );
255     }
256     else
257     {
258         /* Initialize libsamplerate */
259         int error;
260         sync->state             = src_new( SRC_SINC_MEDIUM_QUALITY, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->config.out.mixdown), &error );
261         sync->data.end_of_input = 0;
262     }
263 }
264
265 /***********************************************************************
266  * SyncVideo
267  ***********************************************************************
268  *
269  **********************************************************************/
270 static void SyncVideo( hb_work_object_t * w )
271 {
272     hb_work_private_t * pv = w->private_data;
273     hb_buffer_t * cur, * next, * sub = NULL;
274     hb_job_t * job = pv->job;
275
276     if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
277     {
278         /* We haven't even got a frame yet */
279         return;
280     }
281     cur = pv->cur;
282     if( cur->size == 0 )
283     {
284         /* we got an end-of-stream. Feed it downstream & signal that we're done. */
285         hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
286         pv->busy &=~ 1;
287         return;
288     }
289
290     /* At this point we have a frame to process. Let's check
291         1) if we will be able to push into the fifo ahead
292         2) if the next frame is there already, since we need it to
293            compute the duration of the current frame*/
294     while( !hb_fifo_is_full( job->fifo_sync ) &&
295            ( next = hb_fifo_see( job->fifo_raw ) ) )
296     {
297         hb_buffer_t * buf_tmp;
298
299         if( next->size == 0 )
300         {
301             /* we got an end-of-stream. Feed it downstream & signal that
302              * we're done. Note that this means we drop the final frame of
303              * video (we don't know its duration). On DVDs the final frame
304              * is often strange and dropping it seems to be a good idea. */
305             hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
306             pv->busy &=~ 1;
307             return;
308         }
309         if( pv->pts_offset == INT64_MIN )
310         {
311             /* This is our first frame */
312             pv->pts_offset = 0;
313             if ( cur->start != 0 )
314             {
315                 /*
316                  * The first pts from a dvd should always be zero but
317                  * can be non-zero with a transport or program stream since
318                  * we're not guaranteed to start on an IDR frame. If we get
319                  * a non-zero initial PTS extend its duration so it behaves
320                  * as if it started at zero so that our audio timing will
321                  * be in sync.
322                  */
323                 hb_log( "sync: first pts is %lld", cur->start );
324                 cur->start = 0;
325             }
326         }
327
328         /*
329          * since the first frame is always 0 and the upstream reader code
330          * is taking care of adjusting for pts discontinuities, we just have
331          * to deal with the next frame's start being in the past. This can
332          * happen when the PTS is adjusted after data loss but video frame
333          * reordering causes some frames with the old clock to appear after
334          * the clock change. This creates frames that overlap in time which
335          * looks to us like time going backward. The downstream muxing code
336          * can deal with overlaps of up to a frame time but anything larger
337          * we handle by dropping frames here.
338          */
339         if ( (int64_t)( next->start - cur->start ) <= 0 )
340         {
341             if ( pv->first_drop == 0 )
342             {
343                 pv->first_drop = next->start;
344             }
345             ++pv->drop_count;
346             buf_tmp = hb_fifo_get( job->fifo_raw );
347             if ( buf_tmp->new_chap )
348             {
349                 // don't drop a chapter mark when we drop the buffer
350                 pv->chap_mark = buf_tmp->new_chap;
351             }
352             hb_buffer_close( &buf_tmp );
353             continue;
354         }
355         if ( pv->first_drop )
356         {
357             hb_log( "sync: video time didn't advance - dropped %d frames "
358                     "(delta %d ms, current %lld, next %lld, dur %d)",
359                     pv->drop_count, (int)( cur->start - pv->first_drop ) / 90,
360                     cur->start, next->start, (int)( next->start - cur->start ) );
361             pv->first_drop = 0;
362             pv->drop_count = 0;
363         }
364
365         /*
366          * Track the video sequence number localy so that we can sync the audio
367          * to it using the sequence number as well as the PTS.
368          */
369         pv->video_sequence = cur->sequence;
370
371         /* Look for a subtitle for this frame */
372         if( pv->subtitle )
373         {
374             hb_buffer_t * sub2;
375             while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
376             {
377                 /* If two subtitles overlap, make the first one stop
378                    when the second one starts */
379                 sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
380                 if( sub2 && sub->stop > sub2->start )
381                     sub->stop = sub2->start;
382
383                 // hb_log("0x%x: video seq: %lld  subtitle sequence: %lld",
384                 //       sub, cur->sequence, sub->sequence);
385
386                 if( sub->sequence > cur->sequence )
387                 {
388                     /*
389                      * The video is behind where we are, so wait until
390                      * it catches up to the same reader point on the
391                      * DVD. Then our PTS should be in the same region
392                      * as the video.
393                      */
394                     sub = NULL;
395                     break;
396                 }
397
398                 if( sub->stop > cur->start ) {
399                     /*
400                      * The stop time is in the future, so fall through
401                      * and we'll deal with it in the next block of
402                      * code.
403                      */
404                     break;
405                 }
406
407                 /*
408                  * The subtitle is older than this picture, trash it
409                  */
410                 sub = hb_fifo_get( pv->subtitle->fifo_raw );
411                 hb_buffer_close( &sub );
412             }
413
414             /*
415              * There is a valid subtitle, is it time to display it?
416              */
417             if( sub )
418             {
419                 if( sub->stop > sub->start)
420                 {
421                     /*
422                      * Normal subtitle which ends after it starts, check to
423                      * see that the current video is between the start and end.
424                      */
425                     if( cur->start > sub->start &&
426                         cur->start < sub->stop )
427                     {
428                         /*
429                          * We should be playing this, so leave the
430                          * subtitle in place.
431                          *
432                          * fall through to display
433                          */
434                         if( ( sub->stop - sub->start ) < ( 3 * 90000 ) )
435                         {
436                             /*
437                              * Subtitle is on for less than three seconds, extend
438                              * the time that it is displayed to make it easier
439                              * to read. Make it 3 seconds or until the next
440                              * subtitle is displayed.
441                              *
442                              * This is in response to Indochine which only
443                              * displays subs for 1 second - too fast to read.
444                              */
445                             sub->stop = sub->start + ( 3 * 90000 );
446
447                             sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
448
449                             if( sub2 && sub->stop > sub2->start )
450                             {
451                                 sub->stop = sub2->start;
452                             }
453                         }
454                     }
455                     else
456                     {
457                         /*
458                          * Defer until the play point is within the subtitle
459                          */
460                         sub = NULL;
461                     }
462                 }
463                 else
464                 {
465                     /*
466                      * The end of the subtitle is less than the start, this is a
467                      * sign of a PTS discontinuity.
468                      */
469                     if( sub->start > cur->start )
470                     {
471                         /*
472                          * we haven't reached the start time yet, or
473                          * we have jumped backwards after having
474                          * already started this subtitle.
475                          */
476                         if( cur->start < sub->stop )
477                         {
478                             /*
479                              * We have jumped backwards and so should
480                              * continue displaying this subtitle.
481                              *
482                              * fall through to display.
483                              */
484                         }
485                         else
486                         {
487                             /*
488                              * Defer until the play point is within the subtitle
489                              */
490                             sub = NULL;
491                         }
492                     } else {
493                         /*
494                          * Play this subtitle as the start is greater than our
495                          * video point.
496                          *
497                          * fall through to display/
498                          */
499                     }
500                 }
501             }
502         }
503
504         int64_t duration;
505         if ( job->mux & HB_MUX_AVI || job->cfr )
506         {
507             /*
508              * The concept of variable frame rate video was a bit too advanced
509              * for Microsoft so AVI doesn't support it. Since almost all dvd
510              * video is VFR we have to convert it to constant frame rate to
511              * put it in an AVI container. So here we duplicate, drop and
512              * otherwise trash video frames to appease the gods of Redmond.
513              */
514
515             /* mpeg durations are exact when expressed in ticks of the
516              * 27MHz System clock but not in HB's 90KHz PTS clock. To avoid
517              * a truncation bias that will eventually cause the audio to desync
518              * we compute the duration of the next frame using 27MHz ticks
519              * then truncate it to 90KHz. */
520             duration = ( (int64_t)(pv->count_frames + 1 ) * job->vrate_base ) / 300 -
521                        pv->next_start;
522
523             /* We don't want the input & output clocks to be exactly in phase
524              * otherwise small variations in the time will cause us to think
525              * we're a full frame off & there will be lots of drops and dups.
526              * We offset the input clock by half the duration so it's maximally
527              * out of phase with the output clock. */
528             if( cur->start < pv->next_start  - ( duration >> 1 ) )
529             {
530                 /* current frame too old - drop it */
531                 if ( cur->new_chap )
532                 {
533                     pv->chap_mark = cur->new_chap;
534                 }
535                 hb_buffer_close( &cur );
536                 pv->cur = cur = hb_fifo_get( job->fifo_raw );
537                 pv->next_pts = next->start;
538                 ++pv->drops;
539                 continue;
540             }
541
542             if( next->start > pv->next_start + duration + ( duration >> 1 ) )
543             {
544                 /* next frame too far ahead - dup current frame */
545                 buf_tmp = hb_buffer_init( cur->size );
546                 hb_buffer_copy_settings( buf_tmp, cur );
547                 memcpy( buf_tmp->data, cur->data, cur->size );
548                 buf_tmp->sequence = cur->sequence;
549                 ++pv->dups;
550             }
551             else
552             {
553                 /* this frame in our time window & doesn't need to be duped */
554                 buf_tmp = cur;
555                 pv->cur = cur = hb_fifo_get( job->fifo_raw );
556                 pv->next_pts = next->start;
557             }
558         }
559         else
560         {
561             /*
562              * Adjust the pts of the current frame so that it's contiguous
563              * with the previous frame. The start time of the current frame
564              * has to be the end time of the previous frame and the stop
565              * time has to be the start of the next frame.  We don't
566              * make any adjustments to the source timestamps other than removing
567              * the clock offsets (which also removes pts discontinuities).
568              * This means we automatically encode at the source's frame rate.
569              * MP2 uses an implicit duration (frames end when the next frame
570              * starts) but more advanced containers like MP4 use an explicit
571              * duration. Since we're looking ahead one frame we set the
572              * explicit stop time from the start time of the next frame.
573              */
574             buf_tmp = cur;
575             pv->cur = cur = hb_fifo_get( job->fifo_raw );
576             pv->next_pts = cur->start;
577             duration = cur->start - buf_tmp->start;
578             if ( duration <= 0 )
579             {
580                 hb_log( "sync: invalid video duration %lld, start %lld, next %lld",
581                         duration, buf_tmp->start, next->start );
582             }
583         }
584
585         buf_tmp->start = pv->next_start;
586         pv->next_start += duration;
587         buf_tmp->stop = pv->next_start;
588
589         if ( pv->chap_mark )
590         {
591             // we have a pending chapter mark from a recent drop - put it on this
592             // buffer (this may make it one frame late but we can't do any better).
593             buf_tmp->new_chap = pv->chap_mark;
594             pv->chap_mark = 0;
595         }
596
597         /* If we have a subtitle for this picture, copy it */
598         /* FIXME: we should avoid this memcpy */
599         if( sub )
600         {
601             buf_tmp->sub         = hb_buffer_init( sub->size );
602             buf_tmp->sub->x      = sub->x;
603             buf_tmp->sub->y      = sub->y;
604             buf_tmp->sub->width  = sub->width;
605             buf_tmp->sub->height = sub->height;
606             memcpy( buf_tmp->sub->data, sub->data, sub->size );
607         }
608
609         /* Push the frame to the renderer */
610         hb_fifo_push( job->fifo_sync, buf_tmp );
611
612         /* Update UI */
613         UpdateState( w );
614
615         /* Make sure we won't get more frames then expected */
616         if( pv->count_frames >= pv->count_frames_max * 2)
617         {
618             hb_log( "sync: got too many frames (%d), exiting early",
619                     pv->count_frames );
620
621             // Drop an empty buffer into our output to ensure that things
622             // get flushed all the way out.
623             hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
624             pv->busy &=~ 1;
625             return;
626         }
627     }
628 }
629
630 static void OutputAudioFrame( hb_job_t *job, hb_audio_t *audio, hb_buffer_t *buf,
631                               hb_sync_audio_t *sync, hb_fifo_t *fifo, int i )
632 {
633     int64_t start = sync->next_start;
634     int64_t duration = buf->stop - buf->start;
635
636     sync->next_pts += duration;
637
638     if( audio->config.in.samplerate == audio->config.out.samplerate ||
639         audio->config.out.codec == HB_ACODEC_AC3 ||
640         audio->config.out.codec == HB_ACODEC_DCA )
641     {
642         /*
643          * If we don't have to do sample rate conversion or this audio is 
644          * pass-thru just send the input buffer downstream after adjusting
645          * its timestamps to make the output stream continuous.
646          */
647     }
648     else
649     {
650         /* Not pass-thru - do sample rate conversion */
651         int count_in, count_out;
652         hb_buffer_t * buf_raw = buf;
653         int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown) *
654                             sizeof( float );
655
656         count_in  = buf_raw->size / channel_count;
657         /*
658          * When using stupid rates like 44.1 there will always be some
659          * truncation error. E.g., a 1536 sample AC3 frame will turn into a
660          * 1536*44.1/48.0 = 1411.2 sample frame. If we just truncate the .2
661          * the error will build up over time and eventually the audio will
662          * substantially lag the video. libsamplerate will keep track of the
663          * fractional sample & give it to us when appropriate if we give it
664          * an extra sample of space in the output buffer.
665          */
666         count_out = ( duration * audio->config.out.samplerate ) / 90000 + 1;
667
668         sync->data.input_frames = count_in;
669         sync->data.output_frames = count_out;
670         sync->data.src_ratio = (double)audio->config.out.samplerate /
671                                (double)audio->config.in.samplerate;
672
673         buf = hb_buffer_init( count_out * channel_count );
674         sync->data.data_in  = (float *) buf_raw->data;
675         sync->data.data_out = (float *) buf->data;
676         if( src_process( sync->state, &sync->data ) )
677         {
678             /* XXX If this happens, we're screwed */
679             hb_log( "sync: audio %d src_process failed", i );
680         }
681         hb_buffer_close( &buf_raw );
682
683         buf->size = sync->data.output_frames_gen * channel_count;
684         duration = ( sync->data.output_frames_gen * 90000 ) /
685                    audio->config.out.samplerate;
686     }
687     buf->frametype = HB_FRAME_AUDIO;
688     buf->start = start;
689     buf->stop  = start + duration;
690     sync->next_start = start + duration;
691     hb_fifo_push( fifo, buf );
692 }
693
694 /***********************************************************************
695  * SyncAudio
696  ***********************************************************************
697  *
698  **********************************************************************/
699 static void SyncAudio( hb_work_object_t * w, int i )
700 {
701     hb_work_private_t * pv = w->private_data;
702     hb_job_t        * job = pv->job;
703     hb_sync_audio_t * sync = &pv->sync_audio[i];
704     hb_audio_t      * audio = sync->audio;
705     hb_buffer_t     * buf;
706     hb_fifo_t       * fifo;
707
708     if( audio->config.out.codec == HB_ACODEC_AC3 )
709     {
710         fifo = audio->priv.fifo_out;
711     }
712     else
713     {
714         fifo = audio->priv.fifo_sync;
715     }
716
717     while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->priv.fifo_raw ) ) )
718     {
719         /* if the next buffer is an eof send it downstream */
720         if ( buf->size <= 0 )
721         {
722             buf = hb_fifo_get( audio->priv.fifo_raw );
723             hb_fifo_push( fifo, buf );
724             pv->busy &=~ (1 << (i + 1) );
725             return;
726         }
727         if ( (int64_t)( buf->start - sync->next_pts ) < 0 )
728         {
729             // audio time went backwards.
730             // If our output clock is more than a half frame ahead of the
731             // input clock drop this frame to move closer to sync.
732             // Otherwise drop frames until the input clock matches the output clock.
733             if ( sync->first_drop || sync->next_start - buf->start > 90*15 )
734             {
735                 // Discard data that's in the past.
736                 if ( sync->first_drop == 0 )
737                 {
738                     sync->first_drop = sync->next_pts;
739                 }
740                 ++sync->drop_count;
741                 buf = hb_fifo_get( audio->priv.fifo_raw );
742                 hb_buffer_close( &buf );
743                 continue;
744             }
745             sync->next_pts = buf->start;
746         }
747         if ( sync->first_drop )
748         {
749             // we were dropping old data but input buf time is now current
750             hb_log( "sync: audio %d time went backwards %d ms, dropped %d frames "
751                     "(next %lld, current %lld)", i,
752                     (int)( sync->next_pts - sync->first_drop ) / 90,
753                     sync->drop_count, sync->first_drop, sync->next_pts );
754             sync->first_drop = 0;
755             sync->drop_count = 0;
756             sync->next_pts = buf->start;
757         }
758         if ( buf->start - sync->next_pts >= (90 * 70) )
759         {
760             if ( buf->start - sync->next_pts > (90000LL * 60) )
761             {
762                 // there's a gap of more than a minute between the last
763                 // frame and this. assume we got a corrupted timestamp
764                 // and just drop the next buf.
765                 hb_log( "sync: %d minute time gap in audio %d - dropping buf"
766                         "  start %lld, next %lld",
767                         (int)((buf->start - sync->next_pts) / (90000*60)),
768                         i, buf->start, sync->next_pts );
769                 buf = hb_fifo_get( audio->priv.fifo_raw );
770                 hb_buffer_close( &buf );
771                 continue;
772             }
773             /*
774              * there's a gap of at least 70ms between the last
775              * frame we processed & the next. Fill it with silence.
776              */
777             hb_log( "sync: adding %d ms of silence to audio %d"
778                     "  start %lld, next %lld",
779                     (int)((buf->start - sync->next_pts) / 90),
780                     i, buf->start, sync->next_pts );
781             InsertSilence( w, i, buf->start - sync->next_pts );
782             return;
783         }
784
785         /*
786          * When we get here we've taken care of all the dups and gaps in the
787          * audio stream and are ready to inject the next input frame into
788          * the output stream.
789          */
790         buf = hb_fifo_get( audio->priv.fifo_raw );
791         OutputAudioFrame( job, audio, buf, sync, fifo, i );
792     }
793 }
794
795 static void InsertSilence( hb_work_object_t * w, int i, int64_t duration )
796 {
797     hb_work_private_t * pv = w->private_data;
798     hb_job_t        *job = pv->job;
799     hb_sync_audio_t *sync = &pv->sync_audio[i];
800     hb_buffer_t     *buf;
801     hb_fifo_t       *fifo;
802
803     // to keep pass-thru and regular audio in sync we generate silence in
804     // AC3 frame-sized units. If the silence duration isn't an integer multiple
805     // of the AC3 frame duration we will truncate or round up depending on
806     // which minimizes the timing error.
807     const int frame_dur = ( 90000 * AC3_SAMPLES_PER_FRAME ) /
808                           sync->audio->config.in.samplerate;
809     int frame_count = ( duration + (frame_dur >> 1) ) / frame_dur;
810
811     while ( --frame_count >= 0 )
812     {
813         if( sync->audio->config.out.codec == HB_ACODEC_AC3 )
814         {
815             buf        = hb_buffer_init( sync->ac3_size );
816             buf->start = sync->next_pts;
817             buf->stop  = buf->start + frame_dur;
818             memcpy( buf->data, sync->ac3_buf, buf->size );
819             fifo = sync->audio->priv.fifo_out;
820         }
821         else
822         {
823             buf = hb_buffer_init( AC3_SAMPLES_PER_FRAME * sizeof( float ) *
824                                      HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
825                                          sync->audio->config.out.mixdown) );
826             buf->start = sync->next_pts;
827             buf->stop  = buf->start + frame_dur;
828             memset( buf->data, 0, buf->size );
829             fifo = sync->audio->priv.fifo_sync;
830         }
831         OutputAudioFrame( job, sync->audio, buf, sync, fifo, i );
832     }
833 }
834
835 static void UpdateState( hb_work_object_t * w )
836 {
837     hb_work_private_t * pv = w->private_data;
838     hb_state_t state;
839
840     if( !pv->count_frames )
841     {
842         pv->st_first = hb_get_date();
843     }
844     pv->count_frames++;
845
846     if( hb_get_date() > pv->st_dates[3] + 1000 )
847     {
848         memmove( &pv->st_dates[0], &pv->st_dates[1],
849                  3 * sizeof( uint64_t ) );
850         memmove( &pv->st_counts[0], &pv->st_counts[1],
851                  3 * sizeof( uint64_t ) );
852         pv->st_dates[3]  = hb_get_date();
853         pv->st_counts[3] = pv->count_frames;
854     }
855
856 #define p state.param.working
857     state.state = HB_STATE_WORKING;
858     p.progress  = (float) pv->count_frames / (float) pv->count_frames_max;
859     if( p.progress > 1.0 )
860     {
861         p.progress = 1.0;
862     }
863     p.rate_cur   = 1000.0 *
864         (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
865         (float) ( pv->st_dates[3] - pv->st_dates[0] );
866     if( hb_get_date() > pv->st_first + 4000 )
867     {
868         int eta;
869         p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
870             (float) ( pv->st_dates[3] - pv->st_first );
871         eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
872             p.rate_avg;
873         p.hours   = eta / 3600;
874         p.minutes = ( eta % 3600 ) / 60;
875         p.seconds = eta % 60;
876     }
877     else
878     {
879         p.rate_avg = 0.0;
880         p.hours    = -1;
881         p.minutes  = -1;
882         p.seconds  = -1;
883     }
884 #undef p
885
886     hb_set_state( pv->job->h, &state );
887 }