OSDN Git Service

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