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;
30 int64_t next_start; /* start time of next output frame */
31 int64_t next_pts; /* start time of next input frame */
32 int64_t first_drop; /* PTS of first 'went backwards' frame dropped */
33 int drop_count; /* count of 'time went backwards' drops */
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 */
57 int chap_mark; /* to propagate chapter mark across a drop */
58 hb_buffer_t * cur; /* The next picture to process */
61 uint64_t st_counts[4];
66 struct hb_work_private_s
69 hb_sync_common_t * common;
72 hb_sync_video_t video;
73 hb_sync_audio_t audio;
77 /***********************************************************************
79 **********************************************************************/
80 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i );
81 static void InsertSilence( hb_work_object_t * w, int64_t d );
82 static void UpdateState( hb_work_object_t * w );
83 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
84 hb_sync_audio_t *sync );
86 /***********************************************************************
88 ***********************************************************************
89 * Initialize the work object
90 **********************************************************************/
91 int hb_sync_init( hb_job_t * job )
93 hb_title_t * title = job->title;
94 hb_chapter_t * chapter;
97 hb_work_private_t * pv;
98 hb_sync_video_t * sync;
101 pv = calloc( 1, sizeof( hb_work_private_t ) );
102 sync = &pv->type.video;
103 pv->common = calloc( 1, sizeof( hb_sync_common_t ) );
105 pv->common->mutex = hb_lock_init();
107 w = hb_get_work( WORK_SYNC_VIDEO );
108 w->private_data = pv;
109 w->fifo_in = job->fifo_raw;
110 w->fifo_out = job->fifo_sync;
113 sync->pts_offset = INT64_MIN;
117 /* We already have an accurate frame count from pass 1 */
118 hb_interjob_t * interjob = hb_interjob_get( job->h );
119 sync->count_frames_max = interjob->frame_count;
123 /* Calculate how many video frames we are expecting */
124 if ( job->pts_to_stop )
126 duration = job->pts_to_stop + 90000;
128 else if( job->frame_to_stop )
130 /* Set the duration to a rough estimate */
131 duration = ( job->frame_to_stop / ( title->rate / title->rate_base ) ) * 90000;
136 for( i = job->chapter_start; i <= job->chapter_end; i++ )
138 chapter = hb_list_item( title->list_chapter, i - 1 );
139 duration += chapter->duration;
142 /* 1 second safety so we're sure we won't miss anything */
144 sync->count_frames_max = duration * title->rate / title->rate_base / 90000;
146 hb_list_add( job->list_work, w );
148 hb_log( "sync: expecting %d video frames", sync->count_frames_max );
150 /* Initialize libsamplerate for every audio track we have */
151 if ( ! job->indepth_scan )
153 for( i = 0; i < hb_list_count( title->list_audio ) && i < 8; i++ )
155 InitAudio( job, pv->common, i );
162 /***********************************************************************
164 ***********************************************************************
166 **********************************************************************/
167 void syncVideoClose( hb_work_object_t * w )
169 hb_work_private_t * pv = w->private_data;
170 hb_job_t * job = pv->job;
171 hb_sync_video_t * sync = &pv->type.video;
175 hb_buffer_close( &sync->cur );
178 hb_log( "sync: got %d frames, %d expected",
179 pv->common->count_frames, sync->count_frames_max );
181 /* save data for second pass */
184 /* Preserve frame count for better accuracy in pass 2 */
185 hb_interjob_t * interjob = hb_interjob_get( job->h );
186 interjob->frame_count = pv->common->count_frames;
187 interjob->last_job = job->sequence_id;
188 interjob->total_time = sync->next_start;
191 if (sync->drops || sync->dups )
193 hb_log( "sync: %d frames dropped, %d duplicated",
194 sync->drops, sync->dups );
197 hb_lock( pv->common->mutex );
198 if ( --pv->common->ref == 0 )
200 hb_unlock( pv->common->mutex );
201 hb_lock_close( &pv->common->mutex );
206 hb_unlock( pv->common->mutex );
210 w->private_data = NULL;
213 /***********************************************************************
215 ***********************************************************************
217 **********************************************************************/
218 int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
219 hb_buffer_t ** buf_out )
221 hb_buffer_t * cur, * next, * sub = NULL;
222 hb_work_private_t * pv = w->private_data;
223 hb_job_t * job = pv->job;
224 hb_subtitle_t * subtitle;
225 hb_sync_video_t * sync = &pv->type.video;
233 if( sync->cur->size == 0 )
235 /* we got an end-of-stream as our first video packet?
236 * Feed it downstream & signal that we're done.
238 *buf_out = hb_buffer_init( 0 );
241 * Push through any subtitle EOFs in case they
242 * were not synced through.
244 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
246 subtitle = hb_list_item( job->list_subtitle, i );
247 if( subtitle->config.dest == PASSTHRUSUB )
249 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
259 if( job->frame_to_stop && pv->common->count_frames > job->frame_to_stop )
261 // Drop an empty buffer into our output to ensure that things
262 // get flushed all the way out.
263 hb_buffer_close( &sync->cur );
264 hb_buffer_close( &next );
265 *buf_out = hb_buffer_init( 0 );
266 hb_log( "sync: reached %d frames, exiting early",
267 pv->common->count_frames );
271 /* At this point we have a frame to process. Let's check
272 1) if we will be able to push into the fifo ahead
273 2) if the next frame is there already, since we need it to
274 compute the duration of the current frame*/
275 if( next->size == 0 )
277 hb_buffer_close( &next );
279 cur->start = sync->next_start;
280 cur->stop = cur->start + 90000. / ((double)job->vrate / (double)job->vrate_base);
282 /* Push the frame to the renderer */
283 hb_fifo_push( job->fifo_sync, cur );
286 /* we got an end-of-stream. Feed it downstream & signal that
287 * we're done. Note that this means we drop the final frame of
288 * video (we don't know its duration). On DVDs the final frame
289 * is often strange and dropping it seems to be a good idea. */
290 *buf_out = hb_buffer_init( 0 );
293 * Push through any subtitle EOFs in case they were not synced through.
295 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
297 subtitle = hb_list_item( job->list_subtitle, i );
298 if( subtitle->config.dest == PASSTHRUSUB )
300 if( subtitle->source == VOBSUB )
301 hb_fifo_push( subtitle->fifo_sync, hb_buffer_init( 0 ) );
303 hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
308 if( sync->pts_offset == INT64_MIN )
310 /* This is our first frame */
311 sync->pts_offset = 0;
312 if ( cur->start != 0 )
315 * The first pts from a dvd should always be zero but
316 * can be non-zero with a transport or program stream since
317 * we're not guaranteed to start on an IDR frame. If we get
318 * a non-zero initial PTS extend its duration so it behaves
319 * as if it started at zero so that our audio timing will
322 hb_log( "sync: first pts is %"PRId64, cur->start );
328 * since the first frame is always 0 and the upstream reader code
329 * is taking care of adjusting for pts discontinuities, we just have
330 * to deal with the next frame's start being in the past. This can
331 * happen when the PTS is adjusted after data loss but video frame
332 * reordering causes some frames with the old clock to appear after
333 * the clock change. This creates frames that overlap in time which
334 * looks to us like time going backward. The downstream muxing code
335 * can deal with overlaps of up to a frame time but anything larger
336 * we handle by dropping frames here.
338 hb_lock( pv->common->mutex );
339 if ( (int64_t)( next->start - pv->common->video_pts_slip - cur->start ) <= 0 )
341 if ( sync->first_drop == 0 )
343 sync->first_drop = next->start;
346 if (next->start - cur->start > 0)
348 sync->pts_skip += next->start - cur->start;
349 pv->common->video_pts_slip -= next->start - cur->start;
351 hb_unlock( pv->common->mutex );
352 if ( next->new_chap )
354 // don't drop a chapter mark when we drop the buffer
355 sync->chap_mark = next->new_chap;
357 hb_buffer_close( &next );
360 hb_unlock( pv->common->mutex );
361 if ( sync->first_drop )
363 hb_log( "sync: video time didn't advance - dropped %d frames "
364 "(delta %d ms, current %"PRId64", next %"PRId64", dur %d)",
365 sync->drop_count, (int)( cur->start - sync->first_drop ) / 90,
366 cur->start, next->start, (int)( next->start - cur->start ) );
367 sync->first_drop = 0;
368 sync->drop_count = 0;
372 * Track the video sequence number localy so that we can sync the audio
373 * to it using the sequence number as well as the PTS.
375 sync->video_sequence = cur->sequence;
378 * Look for a subtitle for this frame.
380 * If found then it will be tagged onto a video buffer of the correct time and
381 * sent in to the render pipeline. This only needs to be done for VOBSUBs which
382 * get rendered, other types of subtitles can just sit in their raw_queue until
383 * delt with at muxing.
385 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
387 subtitle = hb_list_item( job->list_subtitle, i );
390 * Rewrite timestamps on subtitles that need it (on raw queue).
392 if( subtitle->source == CC608SUB ||
393 subtitle->source == CC708SUB ||
394 subtitle->source == SRTSUB )
397 * Rewrite timestamps on subtitles that came from Closed Captions
398 * since they are using the MPEG2 timestamps.
400 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
403 * Rewrite the timestamps as and when the video
404 * (cur->start) reaches the same timestamp as a
405 * closed caption (sub->start).
407 * What about discontinuity boundaries - not delt
410 * Bypass the sync fifo altogether.
414 sub = hb_fifo_get( subtitle->fifo_raw );
415 hb_fifo_push( subtitle->fifo_out, sub );
420 * Sync the subtitles to the incoming video, and use
421 * the matching converted video timestamp.
423 * Note that it doesn't appear that we need to convert
424 * timestamps, I guess that they were already correct,
425 * so just push them through for rendering.
428 if( sub->start < cur->start )
430 sub = hb_fifo_get( subtitle->fifo_raw );
431 hb_fifo_push( subtitle->fifo_out, sub );
440 if( subtitle->source == VOBSUB )
443 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
448 * EOF, pass it through immediately.
453 /* If two subtitles overlap, make the first one stop
454 when the second one starts */
455 sub2 = hb_fifo_see2( subtitle->fifo_raw );
456 if( sub2 && sub->stop > sub2->start )
458 sub->stop = sub2->start;
461 // hb_log("0x%x: video seq: %lld subtitle sequence: %lld",
462 // sub, cur->sequence, sub->sequence);
464 if( sub->sequence > cur->sequence )
467 * The video is behind where we are, so wait until
468 * it catches up to the same reader point on the
469 * DVD. Then our PTS should be in the same region
476 if( sub->stop > cur->start ) {
478 * The stop time is in the future, so fall through
479 * and we'll deal with it in the next block of
484 * There is a valid subtitle, is it time to display it?
486 if( sub->stop > sub->start)
489 * Normal subtitle which ends after it starts,
490 * check to see that the current video is between
493 if( cur->start > sub->start &&
494 cur->start < sub->stop )
497 * We should be playing this, so leave the
500 * fall through to display
502 if( ( sub->stop - sub->start ) < ( 2 * 90000 ) )
505 * Subtitle is on for less than three
506 * seconds, extend the time that it is
507 * displayed to make it easier to read.
508 * Make it 3 seconds or until the next
509 * subtitle is displayed.
511 * This is in response to Indochine which
512 * only displays subs for 1 second -
515 sub->stop = sub->start + ( 2 * 90000 );
517 sub2 = hb_fifo_see2( subtitle->fifo_raw );
519 if( sub2 && sub->stop > sub2->start )
521 sub->stop = sub2->start;
528 * Defer until the play point is within
537 * The end of the subtitle is less than the start,
538 * this is a sign of a PTS discontinuity.
540 if( sub->start > cur->start )
543 * we haven't reached the start time yet, or
544 * we have jumped backwards after having
545 * already started this subtitle.
547 if( cur->start < sub->stop )
550 * We have jumped backwards and so should
551 * continue displaying this subtitle.
553 * fall through to display.
559 * Defer until the play point is
560 * within the subtitle
566 * Play this subtitle as the start is
567 * greater than our video point.
569 * fall through to display/
579 * The subtitle is older than this picture, trash it
581 sub = hb_fifo_get( subtitle->fifo_raw );
582 hb_buffer_close( &sub );
586 /* If we have a subtitle for this picture, copy it */
587 /* FIXME: we should avoid this memcpy */
592 if( subtitle->config.dest == RENDERSUB )
594 if ( cur->sub == NULL )
597 * Tack onto the video buffer for rendering
599 cur->sub = hb_buffer_init( sub->size );
600 cur->sub->x = sub->x;
601 cur->sub->y = sub->y;
602 cur->sub->width = sub->width;
603 cur->sub->height = sub->height;
604 memcpy( cur->sub->data, sub->data, sub->size );
608 * Pass-Through, pop it off of the raw queue,
610 sub = hb_fifo_get( subtitle->fifo_raw );
611 hb_fifo_push( subtitle->fifo_sync, sub );
615 * EOF - consume for rendered, else pass through
617 if( subtitle->config.dest == RENDERSUB )
619 sub = hb_fifo_get( subtitle->fifo_raw );
620 hb_buffer_close( &sub );
622 sub = hb_fifo_get( subtitle->fifo_raw );
623 hb_fifo_push( subtitle->fifo_sync, sub );
631 * Adjust the pts of the current frame so that it's contiguous
632 * with the previous frame. The start time of the current frame
633 * has to be the end time of the previous frame and the stop
634 * time has to be the start of the next frame. We don't
635 * make any adjustments to the source timestamps other than removing
636 * the clock offsets (which also removes pts discontinuities).
637 * This means we automatically encode at the source's frame rate.
638 * MP2 uses an implicit duration (frames end when the next frame
639 * starts) but more advanced containers like MP4 use an explicit
640 * duration. Since we're looking ahead one frame we set the
641 * explicit stop time from the start time of the next frame.
644 sync->cur = cur = next;
646 sync->next_pts = cur->start;
647 int64_t duration = cur->start - sync->pts_skip - (*buf_out)->start;
651 hb_log( "sync: invalid video duration %"PRId64", start %"PRId64", next %"PRId64"",
652 duration, (*buf_out)->start, next->start );
655 (*buf_out)->start = sync->next_start;
656 sync->next_start += duration;
657 (*buf_out)->stop = sync->next_start;
659 if ( sync->chap_mark )
661 // we have a pending chapter mark from a recent drop - put it on this
662 // buffer (this may make it one frame late but we can't do any better).
663 (*buf_out)->new_chap = sync->chap_mark;
673 // sync*Init does nothing because sync has a special initializer
674 // that takes care of initializing video and all audio tracks
675 int syncVideoInit( hb_work_object_t * w, hb_job_t * job)
680 hb_work_object_t hb_sync_video =
683 "Video Synchronization",
689 /***********************************************************************
691 ***********************************************************************
693 **********************************************************************/
694 void syncAudioClose( hb_work_object_t * w )
696 hb_work_private_t * pv = w->private_data;
697 hb_sync_audio_t * sync = &pv->type.audio;
699 if( w->audio->config.out.codec == HB_ACODEC_AC3 )
701 free( sync->ac3_buf );
705 src_delete( sync->state );
708 hb_lock( pv->common->mutex );
709 if ( --pv->common->ref == 0 )
711 hb_unlock( pv->common->mutex );
712 hb_lock_close( &pv->common->mutex );
717 hb_unlock( pv->common->mutex );
721 w->private_data = NULL;
724 int syncAudioInit( hb_work_object_t * w, hb_job_t * job)
729 /***********************************************************************
731 ***********************************************************************
733 **********************************************************************/
734 static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
735 hb_buffer_t ** buf_out )
737 hb_work_private_t * pv = w->private_data;
738 hb_job_t * job = pv->job;
739 hb_sync_audio_t * sync = &pv->type.audio;
747 hb_lock( pv->common->mutex );
748 start = buf->start - pv->common->audio_passthru_slip;
749 hb_unlock( pv->common->mutex );
750 /* if the next buffer is an eof send it downstream */
751 if ( buf->size <= 0 )
753 hb_buffer_close( &buf );
754 *buf_out = hb_buffer_init( 0 );
757 if( job->frame_to_stop && pv->common->count_frames >= job->frame_to_stop )
759 hb_buffer_close( &buf );
760 *buf_out = hb_buffer_init( 0 );
763 if ( (int64_t)( start - sync->next_pts ) < 0 )
765 // audio time went backwards.
766 // If our output clock is more than a half frame ahead of the
767 // input clock drop this frame to move closer to sync.
768 // Otherwise drop frames until the input clock matches the output clock.
769 if ( sync->first_drop || sync->next_start - start > 90*15 )
771 // Discard data that's in the past.
772 if ( sync->first_drop == 0 )
774 sync->first_drop = sync->next_pts;
777 hb_buffer_close( &buf );
780 sync->next_pts = start;
782 if ( sync->first_drop )
784 // we were dropping old data but input buf time is now current
785 hb_log( "sync: audio %d time went backwards %d ms, dropped %d frames "
786 "(next %"PRId64", current %"PRId64")", w->audio->id,
787 (int)( sync->next_pts - sync->first_drop ) / 90,
788 sync->drop_count, sync->first_drop, sync->next_pts );
789 sync->first_drop = 0;
790 sync->drop_count = 0;
791 sync->next_pts = start;
793 if ( start - sync->next_pts >= (90 * 70) )
795 if ( start - sync->next_pts > (90000LL * 60) )
797 // there's a gap of more than a minute between the last
798 // frame and this. assume we got a corrupted timestamp
799 // and just drop the next buf.
800 hb_log( "sync: %d minute time gap in audio %d - dropping buf"
801 " start %"PRId64", next %"PRId64,
802 (int)((start - sync->next_pts) / (90000*60)),
803 w->audio->id, start, sync->next_pts );
804 hb_buffer_close( &buf );
808 * there's a gap of at least 70ms between the last
809 * frame we processed & the next. Fill it with silence.
810 * Or in the case of DCA, skip some frames from the
813 if( w->audio->config.out.codec == HB_ACODEC_DCA )
815 hb_log( "sync: audio gap %d ms. Skipping frames. Audio %d"
816 " start %"PRId64", next %"PRId64,
817 (int)((start - sync->next_pts) / 90),
818 w->audio->id, start, sync->next_pts );
819 hb_lock( pv->common->mutex );
820 pv->common->audio_passthru_slip += (start - sync->next_pts);
821 pv->common->video_pts_slip += (start - sync->next_pts);
822 hb_unlock( pv->common->mutex );
826 hb_log( "sync: adding %d ms of silence to audio %d"
827 " start %"PRId64", next %"PRId64,
828 (int)((start - sync->next_pts) / 90),
829 w->audio->id, start, sync->next_pts );
830 InsertSilence( w, start - sync->next_pts );
836 * When we get here we've taken care of all the dups and gaps in the
837 * audio stream and are ready to inject the next input frame into
840 *buf_out = OutputAudioFrame( w->audio, buf, sync );
844 hb_work_object_t hb_sync_audio =
847 "AudioSynchronization",
853 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
855 hb_work_object_t * w;
856 hb_work_private_t * pv;
857 hb_title_t * title = job->title;
858 hb_sync_audio_t * sync;
860 pv = calloc( 1, sizeof( hb_work_private_t ) );
861 sync = &pv->type.audio;
866 w = hb_get_work( WORK_SYNC_AUDIO );
867 w->private_data = pv;
868 w->audio = hb_list_item( title->list_audio, i );
869 w->fifo_in = w->audio->priv.fifo_raw;
871 if( w->audio->config.out.codec == HB_ACODEC_AC3 ||
872 w->audio->config.out.codec == HB_ACODEC_DCA )
874 w->fifo_out = w->audio->priv.fifo_out;
878 w->fifo_out = w->audio->priv.fifo_sync;
881 if( w->audio->config.out.codec == HB_ACODEC_AC3 )
883 /* Have a silent AC-3 frame ready in case we have to fill a
889 codec = avcodec_find_encoder( CODEC_ID_AC3 );
890 c = avcodec_alloc_context();
892 c->bit_rate = w->audio->config.in.bitrate;
893 c->sample_rate = w->audio->config.in.samplerate;
894 c->channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( w->audio->config.in.channel_layout );
896 if( hb_avcodec_open( c, codec ) < 0 )
898 hb_log( "sync: avcodec_open failed" );
902 zeros = calloc( AC3_SAMPLES_PER_FRAME *
903 sizeof( short ) * c->channels, 1 );
904 sync->ac3_size = w->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /
905 w->audio->config.in.samplerate / 8;
906 sync->ac3_buf = malloc( sync->ac3_size );
908 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
909 zeros ) != sync->ac3_size )
911 hb_log( "sync: avcodec_encode_audio failed" );
915 hb_avcodec_close( c );
920 /* Initialize libsamplerate */
922 sync->state = src_new( SRC_SINC_MEDIUM_QUALITY,
923 HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
924 w->audio->config.out.mixdown), &error );
925 sync->data.end_of_input = 0;
927 hb_list_add( job->list_work, w );
930 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
931 hb_sync_audio_t *sync )
933 int64_t start = sync->next_start;
934 int64_t duration = buf->stop - buf->start;
936 sync->next_pts += duration;
938 if( audio->config.in.samplerate == audio->config.out.samplerate ||
939 audio->config.out.codec == HB_ACODEC_AC3 ||
940 audio->config.out.codec == HB_ACODEC_DCA )
943 * If we don't have to do sample rate conversion or this audio is
944 * pass-thru just send the input buffer downstream after adjusting
945 * its timestamps to make the output stream continuous.
950 /* Not pass-thru - do sample rate conversion */
951 int count_in, count_out;
952 hb_buffer_t * buf_raw = buf;
953 int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown) *
956 count_in = buf_raw->size / channel_count;
958 * When using stupid rates like 44.1 there will always be some
959 * truncation error. E.g., a 1536 sample AC3 frame will turn into a
960 * 1536*44.1/48.0 = 1411.2 sample frame. If we just truncate the .2
961 * the error will build up over time and eventually the audio will
962 * substantially lag the video. libsamplerate will keep track of the
963 * fractional sample & give it to us when appropriate if we give it
964 * an extra sample of space in the output buffer.
966 count_out = ( duration * audio->config.out.samplerate ) / 90000 + 1;
968 sync->data.input_frames = count_in;
969 sync->data.output_frames = count_out;
970 sync->data.src_ratio = (double)audio->config.out.samplerate /
971 (double)audio->config.in.samplerate;
973 buf = hb_buffer_init( count_out * channel_count );
974 sync->data.data_in = (float *) buf_raw->data;
975 sync->data.data_out = (float *) buf->data;
976 if( src_process( sync->state, &sync->data ) )
978 /* XXX If this happens, we're screwed */
979 hb_log( "sync: audio %d src_process failed", audio->id );
981 hb_buffer_close( &buf_raw );
983 buf->size = sync->data.output_frames_gen * channel_count;
984 duration = ( sync->data.output_frames_gen * 90000 ) /
985 audio->config.out.samplerate;
987 buf->frametype = HB_FRAME_AUDIO;
989 buf->stop = start + duration;
990 sync->next_start = start + duration;
994 static void InsertSilence( hb_work_object_t * w, int64_t duration )
996 hb_work_private_t * pv = w->private_data;
997 hb_sync_audio_t *sync = &pv->type.audio;
1001 // to keep pass-thru and regular audio in sync we generate silence in
1002 // AC3 frame-sized units. If the silence duration isn't an integer multiple
1003 // of the AC3 frame duration we will truncate or round up depending on
1004 // which minimizes the timing error.
1005 const int frame_dur = ( 90000 * AC3_SAMPLES_PER_FRAME ) /
1006 w->audio->config.in.samplerate;
1007 int frame_count = ( duration + (frame_dur >> 1) ) / frame_dur;
1009 while ( --frame_count >= 0 )
1011 if( w->audio->config.out.codec == HB_ACODEC_AC3 )
1013 buf = hb_buffer_init( sync->ac3_size );
1014 buf->start = sync->next_pts;
1015 buf->stop = buf->start + frame_dur;
1016 memcpy( buf->data, sync->ac3_buf, buf->size );
1017 fifo = w->audio->priv.fifo_out;
1021 buf = hb_buffer_init( AC3_SAMPLES_PER_FRAME * sizeof( float ) *
1022 HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
1023 w->audio->config.out.mixdown) );
1024 buf->start = sync->next_pts;
1025 buf->stop = buf->start + frame_dur;
1026 memset( buf->data, 0, buf->size );
1027 fifo = w->audio->priv.fifo_sync;
1029 buf = OutputAudioFrame( w->audio, buf, sync );
1030 hb_fifo_push( fifo, buf );
1034 static void UpdateState( hb_work_object_t * w )
1036 hb_work_private_t * pv = w->private_data;
1037 hb_sync_video_t * sync = &pv->type.video;
1040 if( !pv->common->count_frames )
1042 sync->st_first = hb_get_date();
1043 pv->job->st_pause_date = -1;
1044 pv->job->st_paused = 0;
1046 pv->common->count_frames++;
1048 if( hb_get_date() > sync->st_dates[3] + 1000 )
1050 memmove( &sync->st_dates[0], &sync->st_dates[1],
1051 3 * sizeof( uint64_t ) );
1052 memmove( &sync->st_counts[0], &sync->st_counts[1],
1053 3 * sizeof( uint64_t ) );
1054 sync->st_dates[3] = hb_get_date();
1055 sync->st_counts[3] = pv->common->count_frames;
1058 #define p state.param.working
1059 state.state = HB_STATE_WORKING;
1060 p.progress = (float) pv->common->count_frames / (float) sync->count_frames_max;
1061 if( p.progress > 1.0 )
1065 p.rate_cur = 1000.0 *
1066 (float) ( sync->st_counts[3] - sync->st_counts[0] ) /
1067 (float) ( sync->st_dates[3] - sync->st_dates[0] );
1068 if( hb_get_date() > sync->st_first + 4000 )
1071 p.rate_avg = 1000.0 * (float) sync->st_counts[3] /
1072 (float) ( sync->st_dates[3] - sync->st_first - pv->job->st_paused);
1073 eta = (float) ( sync->count_frames_max - sync->st_counts[3] ) /
1075 p.hours = eta / 3600;
1076 p.minutes = ( eta % 3600 ) / 60;
1077 p.seconds = eta % 60;
1088 hb_set_state( pv->job->h, &state );