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 = -1;
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++ )
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 static hb_buffer_t * copy_subtitle( hb_buffer_t * src );
252 int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
253 hb_buffer_t ** buf_out )
255 hb_buffer_t * cur, * next, * sub = NULL;
256 hb_work_private_t * pv = w->private_data;
257 hb_job_t * job = pv->job;
258 hb_subtitle_t * subtitle;
259 hb_sync_video_t * sync = &pv->type.video;
266 /* Wait for start of point-to-point encoding */
267 if( !pv->common->start_found )
269 hb_sync_video_t * sync = &pv->type.video;
271 if( next->size == 0 )
274 pv->common->start_found = 1;
275 hb_cond_broadcast( pv->common->next_frame );
278 * Push through any subtitle EOFs in case they
279 * were not synced through.
281 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
283 subtitle = hb_list_item( job->list_subtitle, i );
284 if( subtitle->config.dest == PASSTHRUSUB )
286 if( subtitle->source == VOBSUB )
287 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
289 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
294 if ( pv->common->count_frames < job->frame_to_start ||
295 next->start < job->pts_to_start )
297 // Flush any subtitles that have pts prior to the
299 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
301 subtitle = hb_list_item( job->list_subtitle, i );
302 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
304 if ( sub->start > next->start )
306 sub = hb_fifo_get( subtitle->fifo_raw );
307 hb_buffer_close( &sub );
310 hb_lock( pv->common->mutex );
311 // Tell the audio threads what must be dropped
312 pv->common->audio_pts_thresh = next->start;
313 hb_cond_broadcast( pv->common->next_frame );
314 hb_unlock( pv->common->mutex );
316 UpdateSearchState( w, next->start );
317 hb_buffer_close( &next );
321 hb_lock( pv->common->mutex );
322 pv->common->start_found = 1;
323 pv->common->count_frames = 0;
324 hb_cond_broadcast( pv->common->next_frame );
325 hb_unlock( pv->common->mutex );
329 /* Wait till we can determine the initial pts of all streams */
330 if( next->size != 0 && pv->common->pts_offset == INT64_MIN )
332 pv->common->first_pts[0] = next->start;
333 hb_lock( pv->common->mutex );
334 while( pv->common->pts_offset == INT64_MIN )
336 // Full fifos will make us wait forever, so get the
337 // pts offset from the available streams if full
338 if ( hb_fifo_is_full( job->fifo_raw ) )
341 hb_cond_broadcast( pv->common->next_frame );
343 else if ( checkPtsOffset( w ) )
344 hb_cond_broadcast( pv->common->next_frame );
346 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
348 hb_unlock( pv->common->mutex );
354 if( sync->cur->size == 0 )
356 /* we got an end-of-stream as our first video packet?
357 * Feed it downstream & signal that we're done.
359 *buf_out = hb_buffer_init( 0 );
361 pv->common->start_found = 1;
362 hb_cond_broadcast( pv->common->next_frame );
365 * Push through any subtitle EOFs in case they
366 * were not synced through.
368 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
370 subtitle = hb_list_item( job->list_subtitle, i );
371 if( subtitle->config.dest == PASSTHRUSUB )
373 if( subtitle->source == VOBSUB )
374 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
376 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
384 /* At this point we have a frame to process. Let's check
385 1) if we will be able to push into the fifo ahead
386 2) if the next frame is there already, since we need it to
387 compute the duration of the current frame*/
388 if( next->size == 0 )
390 hb_buffer_close( &next );
392 cur->start = sync->next_start;
393 cur->stop = cur->start + 90000. / ((double)job->vrate / (double)job->vrate_base);
395 /* Make sure last frame is reflected in frame count */
396 pv->common->count_frames++;
398 /* Push the frame to the renderer */
399 hb_fifo_push( job->fifo_sync, cur );
402 /* we got an end-of-stream. Feed it downstream & signal that
403 * we're done. Note that this means we drop the final frame of
404 * video (we don't know its duration). On DVDs the final frame
405 * is often strange and dropping it seems to be a good idea. */
406 *buf_out = hb_buffer_init( 0 );
409 * Push through any subtitle EOFs in case they were not synced through.
411 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
413 subtitle = hb_list_item( job->list_subtitle, i );
414 if( subtitle->config.dest == PASSTHRUSUB )
416 if( subtitle->source == VOBSUB )
417 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
419 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
422 pv->common->start_found = 1;
423 hb_cond_broadcast( pv->common->next_frame );
427 /* Check for end of point-to-point frame encoding */
428 if( job->frame_to_stop && pv->common->count_frames > job->frame_to_stop )
430 // Drop an empty buffer into our output to ensure that things
431 // get flushed all the way out.
432 hb_buffer_close( &sync->cur );
433 hb_buffer_close( &next );
434 *buf_out = hb_buffer_init( 0 );
435 hb_log( "sync: reached %d frames, exiting early",
436 pv->common->count_frames );
439 * Push through any subtitle EOFs in case they were not synced through.
441 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
443 subtitle = hb_list_item( job->list_subtitle, i );
444 if( subtitle->config.dest == PASSTHRUSUB )
446 if( subtitle->source == VOBSUB )
447 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
449 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
455 /* Check for end of point-to-point pts encoding */
456 if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
458 // Drop an empty buffer into our output to ensure that things
459 // get flushed all the way out.
460 hb_log( "sync: reached pts %"PRId64", exiting early",
462 hb_buffer_close( &sync->cur );
463 hb_buffer_close( &next );
464 *buf_out = hb_buffer_init( 0 );
467 * Push through any subtitle EOFs in case they were not synced through.
469 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
471 subtitle = hb_list_item( job->list_subtitle, i );
472 if( subtitle->config.dest == PASSTHRUSUB )
474 if( subtitle->source == VOBSUB )
475 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
477 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
483 if( sync->first_frame )
485 /* This is our first frame */
486 if ( cur->start > pv->common->pts_offset )
489 * The first pts from a dvd should always be zero but
490 * can be non-zero with a transport or program stream since
491 * we're not guaranteed to start on an IDR frame. If we get
492 * a non-zero initial PTS extend its duration so it behaves
493 * as if it started at zero so that our audio timing will
496 hb_log( "sync: first pts is %"PRId64, cur->start );
497 cur->start = pv->common->pts_offset;
499 sync->first_frame = 0;
503 * since the first frame is always 0 and the upstream reader code
504 * is taking care of adjusting for pts discontinuities, we just have
505 * to deal with the next frame's start being in the past. This can
506 * happen when the PTS is adjusted after data loss but video frame
507 * reordering causes some frames with the old clock to appear after
508 * the clock change. This creates frames that overlap in time which
509 * looks to us like time going backward. The downstream muxing code
510 * can deal with overlaps of up to a frame time but anything larger
511 * we handle by dropping frames here.
513 hb_lock( pv->common->mutex );
514 if ( (int64_t)( next->start - pv->common->video_pts_slip - cur->start ) <= 0 )
516 if ( sync->first_drop == 0 )
518 sync->first_drop = next->start;
521 if (next->start - cur->start > 0)
523 sync->pts_skip += next->start - cur->start;
524 pv->common->video_pts_slip -= next->start - cur->start;
526 hb_unlock( pv->common->mutex );
527 if ( next->new_chap )
529 // don't drop a chapter mark when we drop the buffer
530 sync->chap_mark = next->new_chap;
532 hb_buffer_close( &next );
535 hb_unlock( pv->common->mutex );
536 if ( sync->first_drop )
538 hb_log( "sync: video time didn't advance - dropped %d frames "
539 "(delta %d ms, current %"PRId64", next %"PRId64", dur %d)",
540 sync->drop_count, (int)( cur->start - sync->first_drop ) / 90,
541 cur->start, next->start, (int)( next->start - cur->start ) );
542 sync->first_drop = 0;
543 sync->drop_count = 0;
547 * Track the video sequence number localy so that we can sync the audio
548 * to it using the sequence number as well as the PTS.
550 sync->video_sequence = cur->sequence;
553 * Look for a subtitle for this frame.
555 * If found then it will be tagged onto a video buffer of the correct time and
556 * sent in to the render pipeline. This only needs to be done for VOBSUBs which
557 * get rendered, other types of subtitles can just sit in their raw_queue until
558 * delt with at muxing.
560 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
562 subtitle = hb_list_item( job->list_subtitle, i );
565 * Rewrite timestamps on subtitles that need it (on raw queue).
567 // NOTE: It's probably fine to use this logic for passthru VOBSUBs as well,
568 // but I am currently preserving backwards compatibility with the old
569 // VOBSUB behavior, which uses the more complex logic following this if-statement.
570 if( subtitle->config.dest == PASSTHRUSUB && subtitle->source != VOBSUB )
573 * Rewrite timestamps on subtitles that came from Closed Captions
574 * since they are using the MPEG2 timestamps.
576 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
579 * Rewrite the timestamps as and when the video
580 * (cur->start) reaches the same timestamp as a
581 * closed caption (sub->start).
583 * What about discontinuity boundaries - not delt
586 * Bypass the sync fifo altogether.
590 sub = hb_fifo_get( subtitle->fifo_raw );
591 hb_fifo_push( subtitle->fifo_out, sub );
596 * Sync the subtitles to the incoming video, and use
597 * the matching converted video timestamp.
599 * Note that it doesn't appear that we need to convert
600 * timestamps, I guess that they were already correct,
601 * so just push them through for rendering.
604 if( sub->start < cur->start )
606 sub = hb_fifo_get( subtitle->fifo_raw );
607 hb_fifo_push( subtitle->fifo_out, sub );
618 // For rendered subtitles (and, for backward compatibility, passthru VOBSUBs),
619 // delay pushing subtitle packets through the pipeline until the video catches up
620 if( subtitle->config.dest == RENDERSUB || subtitle->source == VOBSUB )
623 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
628 * EOF, pass it through immediately.
633 /* If two subtitles overlap, make the first one stop
634 when the second one starts */
635 sub2 = hb_fifo_see2( subtitle->fifo_raw );
636 if( sub2 && sub->stop > sub2->start )
638 sub->stop = sub2->start;
641 // hb_log("0x%x: video seq: %"PRId64" subtitle sequence: %"PRId64,
642 // sub, cur->sequence, sub->sequence);
644 if( sub->sequence > cur->sequence )
647 * The video is behind where we are, so wait until
648 * it catches up to the same reader point on the
649 * DVD. Then our PTS should be in the same region
656 if( sub->stop > cur->start ) {
658 * The stop time is in the future, so fall through
659 * and we'll deal with it in the next block of
664 * There is a valid subtitle, is it time to display it?
666 if( sub->stop > sub->start)
669 * Normal subtitle which ends after it starts,
670 * check to see that the current video is between
673 if( cur->start > sub->start &&
674 cur->start < sub->stop )
677 * We should be playing this, so leave the
680 * fall through to display
682 if( ( sub->stop - sub->start ) < ( 2 * 90000 ) )
685 * Subtitle is on for less than three
686 * seconds, extend the time that it is
687 * displayed to make it easier to read.
688 * Make it 2 seconds or until the next
689 * subtitle is displayed.
691 * This is in response to Indochine which
692 * only displays subs for 1 second -
695 sub->stop = sub->start + ( 2 * 90000 );
697 sub2 = hb_fifo_see2( subtitle->fifo_raw );
699 if( sub2 && sub->stop > sub2->start )
701 sub->stop = sub2->start;
708 * Defer until the play point is within
717 * The end of the subtitle is less than the start,
718 * this is a sign of a PTS discontinuity.
720 if( sub->start > cur->start )
723 * we haven't reached the start time yet, or
724 * we have jumped backwards after having
725 * already started this subtitle.
727 if( cur->start < sub->stop )
730 * We have jumped backwards and so should
731 * continue displaying this subtitle.
733 * fall through to display.
739 * Defer until the play point is
740 * within the subtitle
746 * Play this subtitle as the start is
747 * greater than our video point.
749 * fall through to display/
759 * The subtitle is older than this picture, trash it
761 sub = hb_fifo_get( subtitle->fifo_raw );
762 hb_buffer_close( &sub );
766 /* If we have a subtitle for this picture, copy it */
771 if( subtitle->config.dest == RENDERSUB )
773 // Only allow one subtitle to be showing at once; ignore others
774 if ( cur->sub == NULL )
777 * Tack onto the video buffer for rendering
779 /* FIXME: we should avoid this memcpy */
780 cur->sub = copy_subtitle( sub );
782 // Leave the subtitle on the raw queue
783 // (until it no longer needs to be displayed)
787 * Pass-Through, pop it off of the raw queue,
789 sub = hb_fifo_get( subtitle->fifo_raw );
790 hb_fifo_push( subtitle->fifo_sync, sub );
794 * EOF - consume for rendered, else pass through
796 if( subtitle->config.dest == RENDERSUB )
798 sub = hb_fifo_get( subtitle->fifo_raw );
799 hb_buffer_close( &sub );
801 sub = hb_fifo_get( subtitle->fifo_raw );
802 hb_fifo_push( subtitle->fifo_sync, sub );
810 * Adjust the pts of the current frame so that it's contiguous
811 * with the previous frame. The start time of the current frame
812 * has to be the end time of the previous frame and the stop
813 * time has to be the start of the next frame. We don't
814 * make any adjustments to the source timestamps other than removing
815 * the clock offsets (which also removes pts discontinuities).
816 * This means we automatically encode at the source's frame rate.
817 * MP2 uses an implicit duration (frames end when the next frame
818 * starts) but more advanced containers like MP4 use an explicit
819 * duration. Since we're looking ahead one frame we set the
820 * explicit stop time from the start time of the next frame.
823 sync->cur = cur = next;
825 sync->next_pts = cur->start;
826 int64_t duration = cur->start - sync->pts_skip - (*buf_out)->start;
830 hb_log( "sync: invalid video duration %"PRId64", start %"PRId64", next %"PRId64"",
831 duration, (*buf_out)->start, next->start );
834 (*buf_out)->start = sync->next_start;
835 sync->next_start += duration;
836 (*buf_out)->stop = sync->next_start;
838 if ( sync->chap_mark )
840 // we have a pending chapter mark from a recent drop - put it on this
841 // buffer (this may make it one frame late but we can't do any better).
842 (*buf_out)->new_chap = sync->chap_mark;
852 static hb_buffer_t * copy_subtitle( hb_buffer_t * src_list )
854 hb_buffer_t * dst_list = NULL;
858 hb_buffer_t ** dst_ptr = &dst_list;
859 for ( src = src_list, dst_ptr = &dst_list;
861 src = src->next_subpicture, dst_ptr = &dst->next_subpicture )
863 (*dst_ptr) = hb_buffer_init( src->size );
867 dst->width = src->width;
868 dst->height = src->height;
869 memcpy( dst->data, src->data, src->size );
875 // sync*Init does nothing because sync has a special initializer
876 // that takes care of initializing video and all audio tracks
877 int syncVideoInit( hb_work_object_t * w, hb_job_t * job)
882 hb_work_object_t hb_sync_video =
885 "Video Synchronization",
891 /***********************************************************************
893 ***********************************************************************
895 **********************************************************************/
896 void syncAudioClose( hb_work_object_t * w )
898 hb_work_private_t * pv = w->private_data;
899 hb_sync_audio_t * sync = &pv->type.audio;
901 if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
903 free( sync->ac3_buf );
907 src_delete( sync->state );
910 hb_lock( pv->common->mutex );
911 if ( --pv->common->ref == 0 )
913 hb_unlock( pv->common->mutex );
914 hb_lock_close( &pv->common->mutex );
919 hb_unlock( pv->common->mutex );
923 w->private_data = NULL;
926 int syncAudioInit( hb_work_object_t * w, hb_job_t * job)
931 /***********************************************************************
933 ***********************************************************************
935 **********************************************************************/
936 static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
937 hb_buffer_t ** buf_out )
939 hb_work_private_t * pv = w->private_data;
940 hb_job_t * job = pv->job;
941 hb_sync_audio_t * sync = &pv->type.audio;
948 /* if the next buffer is an eof send it downstream */
949 if ( buf->size <= 0 )
951 hb_buffer_close( &buf );
952 *buf_out = hb_buffer_init( 0 );
956 /* Wait for start frame if doing point-to-point */
957 hb_lock( pv->common->mutex );
958 while ( !pv->common->start_found )
960 if ( pv->common->audio_pts_thresh < 0 )
962 // I would initialize this in hb_sync_init, but
963 // job->pts_to_start can be modified by reader
964 // after hb_sync_init is called.
965 pv->common->audio_pts_thresh = job->pts_to_start;
967 if ( buf->start < pv->common->audio_pts_thresh )
969 hb_buffer_close( &buf );
970 hb_unlock( pv->common->mutex );
973 while ( !pv->common->start_found &&
974 buf->start >= pv->common->audio_pts_thresh )
976 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
979 if ( buf->start < pv->common->audio_pts_thresh )
981 hb_buffer_close( &buf );
982 hb_unlock( pv->common->mutex );
985 hb_unlock( pv->common->mutex );
987 /* Wait till we can determine the initial pts of all streams */
988 if( pv->common->pts_offset == INT64_MIN )
990 pv->common->first_pts[sync->index+1] = buf->start;
991 hb_lock( pv->common->mutex );
992 while( pv->common->pts_offset == INT64_MIN )
994 // Full fifos will make us wait forever, so get the
995 // pts offset from the available streams if full
996 if (hb_fifo_is_full(w->fifo_in))
999 hb_cond_broadcast( pv->common->next_frame );
1001 else if ( checkPtsOffset( w ) )
1002 hb_cond_broadcast( pv->common->next_frame );
1004 hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
1006 hb_unlock( pv->common->mutex );
1009 if( job->frame_to_stop && pv->common->count_frames >= job->frame_to_stop )
1011 hb_buffer_close( &buf );
1012 *buf_out = hb_buffer_init( 0 );
1013 return HB_WORK_DONE;
1016 if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
1018 hb_buffer_close( &buf );
1019 *buf_out = hb_buffer_init( 0 );
1020 return HB_WORK_DONE;
1023 hb_lock( pv->common->mutex );
1024 start = buf->start - pv->common->audio_passthru_slip;
1025 hb_unlock( pv->common->mutex );
1026 if ( (int64_t)( start - sync->next_pts ) < 0 )
1028 // audio time went backwards.
1029 // If our output clock is more than a half frame ahead of the
1030 // input clock drop this frame to move closer to sync.
1031 // Otherwise drop frames until the input clock matches the output clock.
1032 if ( sync->first_drop || sync->next_start - start > 90*15 )
1034 // Discard data that's in the past.
1035 if ( sync->first_drop == 0 )
1037 sync->first_drop = sync->next_pts;
1040 hb_buffer_close( &buf );
1043 sync->next_pts = start;
1045 if ( sync->first_drop )
1047 // we were dropping old data but input buf time is now current
1048 hb_log( "sync: audio %d time went backwards %d ms, dropped %d frames "
1049 "(next %"PRId64", current %"PRId64")", w->audio->id,
1050 (int)( sync->next_pts - sync->first_drop ) / 90,
1051 sync->drop_count, sync->first_drop, sync->next_pts );
1052 sync->first_drop = 0;
1053 sync->drop_count = 0;
1054 sync->next_pts = start;
1056 if ( start - sync->next_pts >= (90 * 70) )
1058 if ( start - sync->next_pts > (90000LL * 60) )
1060 // there's a gap of more than a minute between the last
1061 // frame and this. assume we got a corrupted timestamp
1062 // and just drop the next buf.
1063 hb_log( "sync: %d minute time gap in audio %d - dropping buf"
1064 " start %"PRId64", next %"PRId64,
1065 (int)((start - sync->next_pts) / (90000*60)),
1066 w->audio->id, start, sync->next_pts );
1067 hb_buffer_close( &buf );
1071 * there's a gap of at least 70ms between the last
1072 * frame we processed & the next. Fill it with silence.
1073 * Or in the case of DCA, skip some frames from the
1076 if( w->audio->config.out.codec == HB_ACODEC_DCA_PASS )
1078 hb_log( "sync: audio gap %d ms. Skipping frames. Audio %d"
1079 " start %"PRId64", next %"PRId64,
1080 (int)((start - sync->next_pts) / 90),
1081 w->audio->id, start, sync->next_pts );
1082 hb_lock( pv->common->mutex );
1083 pv->common->audio_passthru_slip += (start - sync->next_pts);
1084 pv->common->video_pts_slip += (start - sync->next_pts);
1085 hb_unlock( pv->common->mutex );
1089 hb_log( "sync: adding %d ms of silence to audio %d"
1090 " start %"PRId64", next %"PRId64,
1091 (int)((start - sync->next_pts) / 90),
1092 w->audio->id, start, sync->next_pts );
1093 InsertSilence( w, start - sync->next_pts );
1097 * When we get here we've taken care of all the dups and gaps in the
1098 * audio stream and are ready to inject the next input frame into
1099 * the output stream.
1101 *buf_out = OutputAudioFrame( w->audio, buf, sync );
1105 hb_work_object_t hb_sync_audio =
1108 "AudioSynchronization",
1114 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
1116 hb_work_object_t * w;
1117 hb_work_private_t * pv;
1118 hb_title_t * title = job->title;
1119 hb_sync_audio_t * sync;
1121 pv = calloc( 1, sizeof( hb_work_private_t ) );
1122 sync = &pv->type.audio;
1125 pv->common = common;
1127 pv->common->pts_count++;
1129 w = hb_get_work( WORK_SYNC_AUDIO );
1130 w->private_data = pv;
1131 w->audio = hb_list_item( title->list_audio, i );
1132 w->fifo_in = w->audio->priv.fifo_raw;
1134 if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
1135 w->audio->config.out.codec == HB_ACODEC_DCA_PASS )
1137 w->fifo_out = w->audio->priv.fifo_out;
1141 w->fifo_out = w->audio->priv.fifo_sync;
1144 if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
1146 /* Have a silent AC-3 frame ready in case we have to fill a
1152 codec = avcodec_find_encoder( CODEC_ID_AC3 );
1153 c = avcodec_alloc_context();
1155 c->bit_rate = w->audio->config.in.bitrate;
1156 c->sample_rate = w->audio->config.in.samplerate;
1157 c->channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( w->audio->config.in.channel_layout );
1159 if( hb_avcodec_open( c, codec ) < 0 )
1161 hb_log( "sync: avcodec_open failed" );
1165 zeros = calloc( AC3_SAMPLES_PER_FRAME *
1166 sizeof( short ) * c->channels, 1 );
1167 sync->ac3_size = w->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /
1168 w->audio->config.in.samplerate / 8;
1169 sync->ac3_buf = malloc( sync->ac3_size );
1171 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
1172 zeros ) != sync->ac3_size )
1174 hb_log( "sync: avcodec_encode_audio failed" );
1178 hb_avcodec_close( c );
1183 /* Initialize libsamplerate */
1185 sync->state = src_new( SRC_SINC_MEDIUM_QUALITY,
1186 HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
1187 w->audio->config.out.mixdown), &error );
1188 sync->data.end_of_input = 0;
1190 hb_list_add( job->list_work, w );
1193 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
1194 hb_sync_audio_t *sync )
1196 int64_t start = sync->next_start;
1197 int64_t duration = buf->stop - buf->start;
1199 sync->next_pts += duration;
1201 if( audio->config.in.samplerate == audio->config.out.samplerate ||
1202 audio->config.out.codec == HB_ACODEC_AC3_PASS ||
1203 audio->config.out.codec == HB_ACODEC_DCA_PASS )
1206 * If we don't have to do sample rate conversion or this audio is
1207 * pass-thru just send the input buffer downstream after adjusting
1208 * its timestamps to make the output stream continuous.
1213 /* Not pass-thru - do sample rate conversion */
1214 int count_in, count_out;
1215 hb_buffer_t * buf_raw = buf;
1216 int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown) *
1219 count_in = buf_raw->size / channel_count;
1221 * When using stupid rates like 44.1 there will always be some
1222 * truncation error. E.g., a 1536 sample AC3 frame will turn into a
1223 * 1536*44.1/48.0 = 1411.2 sample frame. If we just truncate the .2
1224 * the error will build up over time and eventually the audio will
1225 * substantially lag the video. libsamplerate will keep track of the
1226 * fractional sample & give it to us when appropriate if we give it
1227 * an extra sample of space in the output buffer.
1229 count_out = ( duration * audio->config.out.samplerate ) / 90000 + 1;
1231 sync->data.input_frames = count_in;
1232 sync->data.output_frames = count_out;
1233 sync->data.src_ratio = (double)audio->config.out.samplerate /
1234 (double)audio->config.in.samplerate;
1236 buf = hb_buffer_init( count_out * channel_count );
1237 sync->data.data_in = (float *) buf_raw->data;
1238 sync->data.data_out = (float *) buf->data;
1239 if( src_process( sync->state, &sync->data ) )
1241 /* XXX If this happens, we're screwed */
1242 hb_log( "sync: audio %d src_process failed", audio->id );
1244 hb_buffer_close( &buf_raw );
1246 buf->size = sync->data.output_frames_gen * channel_count;
1247 duration = ( sync->data.output_frames_gen * 90000 ) /
1248 audio->config.out.samplerate;
1250 buf->frametype = HB_FRAME_AUDIO;
1252 buf->stop = start + duration;
1253 sync->next_start = start + duration;
1257 static void InsertSilence( hb_work_object_t * w, int64_t duration )
1259 hb_work_private_t * pv = w->private_data;
1260 hb_sync_audio_t *sync = &pv->type.audio;
1264 // to keep pass-thru and regular audio in sync we generate silence in
1265 // AC3 frame-sized units. If the silence duration isn't an integer multiple
1266 // of the AC3 frame duration we will truncate or round up depending on
1267 // which minimizes the timing error.
1268 const int frame_dur = ( 90000 * AC3_SAMPLES_PER_FRAME ) /
1269 w->audio->config.in.samplerate;
1270 int frame_count = ( duration + (frame_dur >> 1) ) / frame_dur;
1272 while ( --frame_count >= 0 )
1274 if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
1276 buf = hb_buffer_init( sync->ac3_size );
1277 buf->start = sync->next_pts;
1278 buf->stop = buf->start + frame_dur;
1279 memcpy( buf->data, sync->ac3_buf, buf->size );
1280 fifo = w->audio->priv.fifo_out;
1284 buf = hb_buffer_init( AC3_SAMPLES_PER_FRAME * sizeof( float ) *
1285 HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
1286 w->audio->config.out.mixdown) );
1287 buf->start = sync->next_pts;
1288 buf->stop = buf->start + frame_dur;
1289 memset( buf->data, 0, buf->size );
1290 fifo = w->audio->priv.fifo_sync;
1292 buf = OutputAudioFrame( w->audio, buf, sync );
1293 hb_fifo_push( fifo, buf );
1297 static void UpdateState( hb_work_object_t * w )
1299 hb_work_private_t * pv = w->private_data;
1300 hb_sync_video_t * sync = &pv->type.video;
1303 if( !pv->common->count_frames )
1305 sync->st_first = hb_get_date();
1306 pv->job->st_pause_date = -1;
1307 pv->job->st_paused = 0;
1309 pv->common->count_frames++;
1311 if( hb_get_date() > sync->st_dates[3] + 1000 )
1313 memmove( &sync->st_dates[0], &sync->st_dates[1],
1314 3 * sizeof( uint64_t ) );
1315 memmove( &sync->st_counts[0], &sync->st_counts[1],
1316 3 * sizeof( uint64_t ) );
1317 sync->st_dates[3] = hb_get_date();
1318 sync->st_counts[3] = pv->common->count_frames;
1321 #define p state.param.working
1322 state.state = HB_STATE_WORKING;
1323 p.progress = (float) pv->common->count_frames / (float) sync->count_frames_max;
1324 if( p.progress > 1.0 )
1328 p.rate_cur = 1000.0 *
1329 (float) ( sync->st_counts[3] - sync->st_counts[0] ) /
1330 (float) ( sync->st_dates[3] - sync->st_dates[0] );
1331 if( hb_get_date() > sync->st_first + 4000 )
1334 p.rate_avg = 1000.0 * (float) sync->st_counts[3] /
1335 (float) ( sync->st_dates[3] - sync->st_first - pv->job->st_paused);
1336 eta = (float) ( sync->count_frames_max - sync->st_counts[3] ) /
1338 p.hours = eta / 3600;
1339 p.minutes = ( eta % 3600 ) / 60;
1340 p.seconds = eta % 60;
1351 hb_set_state( pv->job->h, &state );
1354 static void UpdateSearchState( hb_work_object_t * w, int64_t start )
1356 hb_work_private_t * pv = w->private_data;
1357 hb_sync_video_t * sync = &pv->type.video;
1362 now = hb_get_date();
1363 if( !pv->common->count_frames )
1365 sync->st_first = now;
1366 pv->job->st_pause_date = -1;
1367 pv->job->st_paused = 0;
1369 pv->common->count_frames++;
1371 #define p state.param.working
1372 state.state = HB_STATE_SEARCHING;
1373 if ( pv->job->frame_to_start )
1374 p.progress = (float) pv->common->count_frames /
1375 (float) pv->job->frame_to_start;
1376 else if ( pv->job->pts_to_start )
1377 p.progress = (float) start / (float) pv->job->pts_to_start;
1380 if( p.progress > 1.0 )
1384 if (now > sync->st_first)
1388 if ( pv->job->frame_to_start )
1390 avg = 1000.0 * (double)pv->common->count_frames / (now - sync->st_first);
1391 eta = ( pv->job->frame_to_start - pv->common->count_frames ) / avg;
1393 else if ( pv->job->pts_to_start )
1395 avg = 1000.0 * (double)start / (now - sync->st_first);
1396 eta = ( pv->job->pts_to_start - start ) / avg;
1398 p.hours = eta / 3600;
1399 p.minutes = ( eta % 3600 ) / 60;
1400 p.seconds = eta % 60;
1411 hb_set_state( pv->job->h, &state );
1414 static void getPtsOffset( hb_work_object_t * w )
1416 hb_work_private_t * pv = w->private_data;
1418 int64_t first_pts = INT64_MAX;
1420 for( i = 0; i < pv->common->pts_count; i++ )
1422 if ( pv->common->first_pts[i] < first_pts )
1423 first_pts = pv->common->first_pts[i];
1425 pv->common->audio_passthru_slip = pv->common->pts_offset = first_pts;
1429 static int checkPtsOffset( hb_work_object_t * w )
1431 hb_work_private_t * pv = w->private_data;
1434 for( i = 0; i < pv->common->pts_count; i++ )
1436 if ( pv->common->first_pts[i] == INT64_MAX )