1 /* $Id: sync.c,v 1.38 2005/04/14 21:57:58 titer Exp $
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. */
10 #include "samplerate.h"
13 #undef INT64_MIN /* Because it isn't defined correctly in Zeta */
15 #define INT64_MIN (-9223372036854775807LL-1)
17 #define AC3_SAMPLES_PER_FRAME 1536
22 int ref; /* Reference count to tell us when it's unused */
24 int64_t audio_passthru_slip;
25 int64_t video_pts_slip;
28 /* Frame based point-to-point support */
29 int64_t audio_pts_thresh;
31 hb_cond_t * next_frame;
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 */
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 */
66 int chap_mark; /* to propagate chapter mark across a drop */
67 hb_buffer_t * cur; /* The next picture to process */
70 uint64_t st_counts[4];
75 struct hb_work_private_s
78 hb_sync_common_t * common;
81 hb_sync_video_t video;
82 hb_sync_audio_t audio;
86 /***********************************************************************
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 );
98 /***********************************************************************
100 ***********************************************************************
101 * Initialize the work object
102 **********************************************************************/
103 hb_work_object_t * hb_sync_init( hb_job_t * job )
105 hb_title_t * title = job->title;
106 hb_chapter_t * chapter;
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;
114 pv = calloc( 1, sizeof( hb_work_private_t ) );
115 sync = &pv->type.video;
116 pv->common = calloc( 1, sizeof( hb_sync_common_t ) );
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 )
124 pv->common->start_found = 0;
128 pv->common->start_found = 1;
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;
137 pv->common->pts_offset = INT64_MIN;
138 sync->first_frame = 1;
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;
148 /* Calculate how many video frames we are expecting */
149 if ( job->pts_to_stop )
151 duration = job->pts_to_stop + 90000;
153 else if( job->frame_to_stop )
155 /* Set the duration to a rough estimate */
156 duration = ( job->frame_to_stop / ( title->rate / title->rate_base ) ) * 90000;
161 for( i = job->chapter_start; i <= job->chapter_end; i++ )
163 chapter = hb_list_item( title->list_chapter, i - 1 );
164 duration += chapter->duration;
167 /* 1 second safety so we're sure we won't miss anything */
169 sync->count_frames_max = duration * title->rate / title->rate_base / 90000;
172 hb_log( "sync: expecting %d video frames", sync->count_frames_max );
174 /* Initialize libsamplerate for every audio track we have */
175 if ( ! job->indepth_scan )
177 for( i = 0; i < hb_list_count( title->list_audio ) && i < 8; i++ )
179 InitAudio( job, pv->common, i );
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;
189 /***********************************************************************
191 ***********************************************************************
193 **********************************************************************/
194 void syncVideoClose( hb_work_object_t * w )
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;
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 );
207 hb_buffer_close( &sync->cur );
210 hb_log( "sync: got %d frames, %d expected",
211 pv->common->count_frames, sync->count_frames_max );
213 /* save data for second pass */
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;
223 if (sync->drops || sync->dups )
225 hb_log( "sync: %d frames dropped, %d duplicated",
226 sync->drops, sync->dups );
229 hb_lock( pv->common->mutex );
230 if ( --pv->common->ref == 0 )
232 hb_unlock( pv->common->mutex );
233 hb_lock_close( &pv->common->mutex );
238 hb_unlock( pv->common->mutex );
242 w->private_data = NULL;
245 /***********************************************************************
247 ***********************************************************************
249 **********************************************************************/
250 int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
251 hb_buffer_t ** buf_out )
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;
264 /* Wait for start of point-to-point encoding */
265 if( !pv->common->start_found )
267 hb_sync_video_t * sync = &pv->type.video;
269 if( next->size == 0 )
272 pv->common->start_found = 1;
273 hb_cond_broadcast( pv->common->next_frame );
276 * Push through any subtitle EOFs in case they
277 * were not synced through.
279 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
281 subtitle = hb_list_item( job->list_subtitle, i );
282 if( subtitle->config.dest == PASSTHRUSUB )
284 if( subtitle->source == VOBSUB )
285 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
287 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
292 if ( pv->common->count_frames < job->frame_to_start ||
293 next->start < job->pts_to_start )
295 // Flush any subtitles that have pts prior to the
297 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
299 subtitle = hb_list_item( job->list_subtitle, i );
300 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
302 if ( sub->start > next->start )
304 sub = hb_fifo_get( subtitle->fifo_raw );
305 hb_buffer_close( &sub );
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 );
314 UpdateSearchState( w, next->start );
315 hb_buffer_close( &next );
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 );
327 /* Wait till we can determine the initial pts of all streams */
328 if( pv->common->pts_offset == INT64_MIN )
330 pv->common->first_pts[0] = next->start;
331 hb_lock( pv->common->mutex );
332 while( pv->common->pts_offset == INT64_MIN )
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 ) )
339 hb_cond_broadcast( pv->common->next_frame );
341 else if ( checkPtsOffset( w ) )
342 hb_cond_broadcast( pv->common->next_frame );
344 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
346 hb_unlock( pv->common->mutex );
352 if( sync->cur->size == 0 )
354 /* we got an end-of-stream as our first video packet?
355 * Feed it downstream & signal that we're done.
357 *buf_out = hb_buffer_init( 0 );
359 pv->common->start_found = 1;
360 hb_cond_broadcast( pv->common->next_frame );
363 * Push through any subtitle EOFs in case they
364 * were not synced through.
366 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
368 subtitle = hb_list_item( job->list_subtitle, i );
369 if( subtitle->config.dest == PASSTHRUSUB )
371 if( subtitle->source == VOBSUB )
372 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
374 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
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 )
388 hb_buffer_close( &next );
390 cur->start = sync->next_start;
391 cur->stop = cur->start + 90000. / ((double)job->vrate / (double)job->vrate_base);
393 /* Push the frame to the renderer */
394 hb_fifo_push( job->fifo_sync, cur );
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 );
404 * Push through any subtitle EOFs in case they were not synced through.
406 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
408 subtitle = hb_list_item( job->list_subtitle, i );
409 if( subtitle->config.dest == PASSTHRUSUB )
411 if( subtitle->source == VOBSUB )
412 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
414 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
417 pv->common->start_found = 1;
418 hb_cond_broadcast( pv->common->next_frame );
422 /* Check for end of point-to-point frame encoding */
423 if( job->frame_to_stop && pv->common->count_frames > job->frame_to_stop )
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 );
434 * Push through any subtitle EOFs in case they were not synced through.
436 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
438 subtitle = hb_list_item( job->list_subtitle, i );
439 if( subtitle->config.dest == PASSTHRUSUB )
441 if( subtitle->source == VOBSUB )
442 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
444 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
450 /* Check for end of point-to-point pts encoding */
451 if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
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",
457 hb_buffer_close( &sync->cur );
458 hb_buffer_close( &next );
459 *buf_out = hb_buffer_init( 0 );
462 * Push through any subtitle EOFs in case they were not synced through.
464 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
466 subtitle = hb_list_item( job->list_subtitle, i );
467 if( subtitle->config.dest == PASSTHRUSUB )
469 if( subtitle->source == VOBSUB )
470 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
472 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
478 if( sync->first_frame )
480 /* This is our first frame */
481 if ( cur->start > pv->common->pts_offset )
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
491 hb_log( "sync: first pts is %"PRId64, cur->start );
492 cur->start = pv->common->pts_offset;
494 sync->first_frame = 0;
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.
508 hb_lock( pv->common->mutex );
509 if ( (int64_t)( next->start - pv->common->video_pts_slip - cur->start ) <= 0 )
511 if ( sync->first_drop == 0 )
513 sync->first_drop = next->start;
516 if (next->start - cur->start > 0)
518 sync->pts_skip += next->start - cur->start;
519 pv->common->video_pts_slip -= next->start - cur->start;
521 hb_unlock( pv->common->mutex );
522 if ( next->new_chap )
524 // don't drop a chapter mark when we drop the buffer
525 sync->chap_mark = next->new_chap;
527 hb_buffer_close( &next );
530 hb_unlock( pv->common->mutex );
531 if ( sync->first_drop )
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;
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.
545 sync->video_sequence = cur->sequence;
548 * Look for a subtitle for this frame.
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.
555 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
557 subtitle = hb_list_item( job->list_subtitle, i );
560 * Rewrite timestamps on subtitles that need it (on raw queue).
562 if( subtitle->source == CC608SUB ||
563 subtitle->source == CC708SUB ||
564 subtitle->source == SRTSUB )
567 * Rewrite timestamps on subtitles that came from Closed Captions
568 * since they are using the MPEG2 timestamps.
570 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
573 * Rewrite the timestamps as and when the video
574 * (cur->start) reaches the same timestamp as a
575 * closed caption (sub->start).
577 * What about discontinuity boundaries - not delt
580 * Bypass the sync fifo altogether.
584 sub = hb_fifo_get( subtitle->fifo_raw );
585 hb_fifo_push( subtitle->fifo_out, sub );
590 * Sync the subtitles to the incoming video, and use
591 * the matching converted video timestamp.
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.
598 if( sub->start < cur->start )
600 sub = hb_fifo_get( subtitle->fifo_raw );
601 hb_fifo_push( subtitle->fifo_out, sub );
610 if( subtitle->source == VOBSUB )
613 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
618 * EOF, pass it through immediately.
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 )
628 sub->stop = sub2->start;
631 // hb_log("0x%x: video seq: %"PRId64" subtitle sequence: %"PRId64,
632 // sub, cur->sequence, sub->sequence);
634 if( sub->sequence > cur->sequence )
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
646 if( sub->stop > cur->start ) {
648 * The stop time is in the future, so fall through
649 * and we'll deal with it in the next block of
654 * There is a valid subtitle, is it time to display it?
656 if( sub->stop > sub->start)
659 * Normal subtitle which ends after it starts,
660 * check to see that the current video is between
663 if( cur->start > sub->start &&
664 cur->start < sub->stop )
667 * We should be playing this, so leave the
670 * fall through to display
672 if( ( sub->stop - sub->start ) < ( 2 * 90000 ) )
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.
681 * This is in response to Indochine which
682 * only displays subs for 1 second -
685 sub->stop = sub->start + ( 2 * 90000 );
687 sub2 = hb_fifo_see2( subtitle->fifo_raw );
689 if( sub2 && sub->stop > sub2->start )
691 sub->stop = sub2->start;
698 * Defer until the play point is within
707 * The end of the subtitle is less than the start,
708 * this is a sign of a PTS discontinuity.
710 if( sub->start > cur->start )
713 * we haven't reached the start time yet, or
714 * we have jumped backwards after having
715 * already started this subtitle.
717 if( cur->start < sub->stop )
720 * We have jumped backwards and so should
721 * continue displaying this subtitle.
723 * fall through to display.
729 * Defer until the play point is
730 * within the subtitle
736 * Play this subtitle as the start is
737 * greater than our video point.
739 * fall through to display/
749 * The subtitle is older than this picture, trash it
751 sub = hb_fifo_get( subtitle->fifo_raw );
752 hb_buffer_close( &sub );
756 /* If we have a subtitle for this picture, copy it */
757 /* FIXME: we should avoid this memcpy */
762 if( subtitle->config.dest == RENDERSUB )
764 if ( cur->sub == NULL )
767 * Tack onto the video buffer for rendering
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 );
778 * Pass-Through, pop it off of the raw queue,
780 sub = hb_fifo_get( subtitle->fifo_raw );
781 hb_fifo_push( subtitle->fifo_sync, sub );
785 * EOF - consume for rendered, else pass through
787 if( subtitle->config.dest == RENDERSUB )
789 sub = hb_fifo_get( subtitle->fifo_raw );
790 hb_buffer_close( &sub );
792 sub = hb_fifo_get( subtitle->fifo_raw );
793 hb_fifo_push( subtitle->fifo_sync, sub );
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.
814 sync->cur = cur = next;
816 sync->next_pts = cur->start;
817 int64_t duration = cur->start - sync->pts_skip - (*buf_out)->start;
821 hb_log( "sync: invalid video duration %"PRId64", start %"PRId64", next %"PRId64"",
822 duration, (*buf_out)->start, next->start );
825 (*buf_out)->start = sync->next_start;
826 sync->next_start += duration;
827 (*buf_out)->stop = sync->next_start;
829 if ( sync->chap_mark )
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;
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)
850 hb_work_object_t hb_sync_video =
853 "Video Synchronization",
859 /***********************************************************************
861 ***********************************************************************
863 **********************************************************************/
864 void syncAudioClose( hb_work_object_t * w )
866 hb_work_private_t * pv = w->private_data;
867 hb_sync_audio_t * sync = &pv->type.audio;
869 if( w->audio->config.out.codec == HB_ACODEC_AC3 )
871 free( sync->ac3_buf );
875 src_delete( sync->state );
878 hb_lock( pv->common->mutex );
879 if ( --pv->common->ref == 0 )
881 hb_unlock( pv->common->mutex );
882 hb_lock_close( &pv->common->mutex );
887 hb_unlock( pv->common->mutex );
891 w->private_data = NULL;
894 int syncAudioInit( hb_work_object_t * w, hb_job_t * job)
899 /***********************************************************************
901 ***********************************************************************
903 **********************************************************************/
904 static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
905 hb_buffer_t ** buf_out )
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;
916 /* if the next buffer is an eof send it downstream */
917 if ( buf->size <= 0 )
919 hb_buffer_close( &buf );
920 *buf_out = hb_buffer_init( 0 );
924 /* Wait for start frame if doing point-to-point */
925 hb_lock( pv->common->mutex );
926 while ( !pv->common->start_found )
928 if ( buf->start < pv->common->audio_pts_thresh )
930 hb_buffer_close( &buf );
931 hb_unlock( pv->common->mutex );
934 while ( !pv->common->start_found &&
935 buf->start >= pv->common->audio_pts_thresh )
937 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
940 if ( buf->start < pv->common->audio_pts_thresh )
942 hb_buffer_close( &buf );
943 hb_unlock( pv->common->mutex );
946 hb_unlock( pv->common->mutex );
948 /* Wait till we can determine the initial pts of all streams */
949 if( pv->common->pts_offset == INT64_MIN )
951 pv->common->first_pts[sync->index+1] = buf->start;
952 hb_lock( pv->common->mutex );
953 while( pv->common->pts_offset == INT64_MIN )
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))
960 hb_cond_broadcast( pv->common->next_frame );
962 else if ( checkPtsOffset( w ) )
963 hb_cond_broadcast( pv->common->next_frame );
965 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
967 hb_unlock( pv->common->mutex );
970 if( job->frame_to_stop && pv->common->count_frames >= job->frame_to_stop )
972 hb_buffer_close( &buf );
973 *buf_out = hb_buffer_init( 0 );
977 if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
979 hb_buffer_close( &buf );
980 *buf_out = hb_buffer_init( 0 );
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 )
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 )
995 // Discard data that's in the past.
996 if ( sync->first_drop == 0 )
998 sync->first_drop = sync->next_pts;
1001 hb_buffer_close( &buf );
1004 sync->next_pts = start;
1006 if ( sync->first_drop )
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;
1017 if ( start - sync->next_pts >= (90 * 70) )
1019 if ( start - sync->next_pts > (90000LL * 60) )
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 );
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
1037 if( w->audio->config.out.codec == HB_ACODEC_DCA )
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 );
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 );
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.
1062 *buf_out = OutputAudioFrame( w->audio, buf, sync );
1066 hb_work_object_t hb_sync_audio =
1069 "AudioSynchronization",
1075 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
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;
1082 pv = calloc( 1, sizeof( hb_work_private_t ) );
1083 sync = &pv->type.audio;
1086 pv->common = common;
1088 pv->common->pts_count++;
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;
1095 if( w->audio->config.out.codec == HB_ACODEC_AC3 ||
1096 w->audio->config.out.codec == HB_ACODEC_DCA )
1098 w->fifo_out = w->audio->priv.fifo_out;
1102 w->fifo_out = w->audio->priv.fifo_sync;
1105 if( w->audio->config.out.codec == HB_ACODEC_AC3 )
1107 /* Have a silent AC-3 frame ready in case we have to fill a
1113 codec = avcodec_find_encoder( CODEC_ID_AC3 );
1114 c = avcodec_alloc_context();
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 );
1120 if( hb_avcodec_open( c, codec ) < 0 )
1122 hb_log( "sync: avcodec_open failed" );
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 );
1132 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
1133 zeros ) != sync->ac3_size )
1135 hb_log( "sync: avcodec_encode_audio failed" );
1139 hb_avcodec_close( c );
1144 /* Initialize libsamplerate */
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;
1151 hb_list_add( job->list_work, w );
1154 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
1155 hb_sync_audio_t *sync )
1157 int64_t start = sync->next_start;
1158 int64_t duration = buf->stop - buf->start;
1160 sync->next_pts += duration;
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 )
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.
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) *
1180 count_in = buf_raw->size / channel_count;
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.
1190 count_out = ( duration * audio->config.out.samplerate ) / 90000 + 1;
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;
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 ) )
1202 /* XXX If this happens, we're screwed */
1203 hb_log( "sync: audio %d src_process failed", audio->id );
1205 hb_buffer_close( &buf_raw );
1207 buf->size = sync->data.output_frames_gen * channel_count;
1208 duration = ( sync->data.output_frames_gen * 90000 ) /
1209 audio->config.out.samplerate;
1211 buf->frametype = HB_FRAME_AUDIO;
1213 buf->stop = start + duration;
1214 sync->next_start = start + duration;
1218 static void InsertSilence( hb_work_object_t * w, int64_t duration )
1220 hb_work_private_t * pv = w->private_data;
1221 hb_sync_audio_t *sync = &pv->type.audio;
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;
1233 while ( --frame_count >= 0 )
1235 if( w->audio->config.out.codec == HB_ACODEC_AC3 )
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;
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;
1253 buf = OutputAudioFrame( w->audio, buf, sync );
1254 hb_fifo_push( fifo, buf );
1258 static void UpdateState( hb_work_object_t * w )
1260 hb_work_private_t * pv = w->private_data;
1261 hb_sync_video_t * sync = &pv->type.video;
1264 if( !pv->common->count_frames )
1266 sync->st_first = hb_get_date();
1267 pv->job->st_pause_date = -1;
1268 pv->job->st_paused = 0;
1270 pv->common->count_frames++;
1272 if( hb_get_date() > sync->st_dates[3] + 1000 )
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;
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 )
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 )
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] ) /
1299 p.hours = eta / 3600;
1300 p.minutes = ( eta % 3600 ) / 60;
1301 p.seconds = eta % 60;
1312 hb_set_state( pv->job->h, &state );
1315 static void UpdateSearchState( hb_work_object_t * w, int64_t start )
1317 hb_work_private_t * pv = w->private_data;
1318 hb_sync_video_t * sync = &pv->type.video;
1323 now = hb_get_date();
1324 if( !pv->common->count_frames )
1326 sync->st_first = now;
1327 pv->job->st_pause_date = -1;
1328 pv->job->st_paused = 0;
1330 pv->common->count_frames++;
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;
1341 if( p.progress > 1.0 )
1345 if (now > sync->st_first)
1349 if ( pv->job->frame_to_start )
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;
1354 else if ( pv->job->pts_to_start )
1356 avg = 1000.0 * (double)start / (now - sync->st_first);
1357 eta = ( pv->job->pts_to_start - start ) / avg;
1359 p.hours = eta / 3600;
1360 p.minutes = ( eta % 3600 ) / 60;
1361 p.seconds = eta % 60;
1372 hb_set_state( pv->job->h, &state );
1375 static void getPtsOffset( hb_work_object_t * w )
1377 hb_work_private_t * pv = w->private_data;
1379 int64_t first_pts = INT64_MAX;
1381 for( i = 0; i < pv->common->pts_count; i++ )
1383 if ( pv->common->first_pts[i] < first_pts )
1384 first_pts = pv->common->first_pts[i];
1386 pv->common->audio_passthru_slip = pv->common->pts_offset = first_pts;
1390 static int checkPtsOffset( hb_work_object_t * w )
1392 hb_work_private_t * pv = w->private_data;
1395 for( i = 0; i < pv->common->pts_count; i++ )
1397 if ( pv->common->first_pts[i] == INT64_MAX )