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.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
9 #include "samplerate.h"
10 #include "ffmpeg/avcodec.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
34 struct hb_work_private_s
40 hb_subtitle_t * subtitle;
42 int64_t pts_offset_old;
44 int64_t count_frames_max;
45 hb_buffer_t * cur; /* The next picture to process */
48 hb_sync_audio_t sync_audio[8];
51 uint64_t st_counts[4];
56 /***********************************************************************
58 **********************************************************************/
59 static void InitAudio( hb_work_object_t * w, int i, int channelsused );
60 static int SyncVideo( hb_work_object_t * w );
61 static void SyncAudio( hb_work_object_t * w, int i, int channelsused );
62 static int NeedSilence( hb_work_object_t * w, hb_audio_t * );
63 static void InsertSilence( hb_work_object_t * w, int i, int channelsused );
64 static void UpdateState( hb_work_object_t * w );
66 /***********************************************************************
68 ***********************************************************************
69 * Initialize the work object
70 **********************************************************************/
71 int syncInit( hb_work_object_t * w, hb_job_t * job )
73 hb_title_t * title = job->title;
74 hb_chapter_t * chapter;
77 hb_work_private_t * pv;
79 pv = calloc( 1, sizeof( hb_work_private_t ) );
83 pv->pts_offset = INT64_MIN;
84 pv->pts_offset_old = INT64_MIN;
87 /* Calculate how many video frames we are expecting */
89 for( i = job->chapter_start; i <= job->chapter_end; i++ )
91 chapter = hb_list_item( title->list_chapter, i - 1 );
92 duration += chapter->duration;
95 /* 1 second safety so we're sure we won't miss anything */
96 pv->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
98 hb_log( "sync: expecting %lld video frames", pv->count_frames_max );
100 /* Initialize libsamplerate for every audio track we have */
101 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
103 /* this should really pass in a channelsused value for this audio
104 but for now, it uses the global job value of channelsused */
105 InitAudio( w, i, job->channelsused );
108 /* Get subtitle info, if any */
109 pv->subtitle = hb_list_item( title->list_subtitle, 0 );
114 /***********************************************************************
116 ***********************************************************************
118 **********************************************************************/
119 void syncClose( hb_work_object_t * w )
121 hb_work_private_t * pv = w->private_data;
122 hb_job_t * job = pv->job;
123 hb_title_t * title = job->title;
127 if( pv->cur ) hb_buffer_close( &pv->cur );
129 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
131 if( job->acodec & HB_ACODEC_AC3 )
133 free( pv->sync_audio[i].ac3_buf );
137 src_delete( pv->sync_audio[i].state );
142 /***********************************************************************
144 ***********************************************************************
145 * The root routine of this work abject
146 **********************************************************************/
147 int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
148 hb_buffer_t ** unused2 )
150 hb_work_private_t * pv = w->private_data;
153 /* If we ever got a video frame, handle audio now */
154 if( pv->pts_offset != INT64_MIN )
156 for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
158 /* this should really pass in a channelsused value for this audio
159 but for now, it uses the global job value of channelsused */
160 SyncAudio( w, i, pv->job->channelsused );
165 return SyncVideo( w );
168 hb_work_object_t hb_sync =
177 static void InitAudio( hb_work_object_t * w, int i, int channelsused )
179 hb_work_private_t * pv = w->private_data;
180 hb_job_t * job = pv->job;
181 hb_title_t * title = job->title;
182 hb_sync_audio_t * sync;
184 sync = &pv->sync_audio[i];
185 sync->audio = hb_list_item( title->list_audio, i );
187 if( job->acodec & HB_ACODEC_AC3 )
189 /* Have a silent AC-3 frame ready in case we have to fill a
195 codec = avcodec_find_encoder( CODEC_ID_AC3 );
196 c = avcodec_alloc_context();
198 c->bit_rate = sync->audio->bitrate;
199 c->sample_rate = sync->audio->rate;
200 c->channels = sync->audio->channels;
202 if( avcodec_open( c, codec ) < 0 )
204 hb_log( "sync: avcodec_open failed" );
208 zeros = calloc( AC3_SAMPLES_PER_FRAME *
209 sizeof( short ) * c->channels, 1 );
210 sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
211 sync->audio->rate / 8;
212 sync->ac3_buf = malloc( sync->ac3_size );
214 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
215 zeros ) != sync->ac3_size )
217 hb_log( "sync: avcodec_encode_audio failed" );
226 /* Initialize libsamplerate */
228 sync->state = src_new( SRC_LINEAR, channelsused, &error );
229 sync->data.end_of_input = 0;
235 #define PTS_DISCONTINUITY_TOLERANCE 90000
237 /***********************************************************************
239 ***********************************************************************
241 **********************************************************************/
242 static int SyncVideo( hb_work_object_t * w )
244 hb_work_private_t * pv = w->private_data;
245 hb_buffer_t * cur, * next, * sub = NULL;
246 hb_job_t * job = pv->job;
247 int64_t pts_expected;
254 if( hb_thread_has_exited( job->reader ) &&
255 !hb_fifo_size( job->fifo_mpeg2 ) &&
256 !hb_fifo_size( job->fifo_raw ) )
258 /* All video data has been processed already, we won't get
260 hb_log( "sync: got %lld frames, %lld expected",
261 pv->count_frames, pv->count_frames_max );
266 if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
268 /* We haven't even got a frame yet */
273 /* At this point we have a frame to process. Let's check
274 1) if we will be able to push into the fifo ahead
275 2) if the next frame is there already, since we need it to
276 know whether we'll have to repeat the current frame or not */
277 while( !hb_fifo_is_full( job->fifo_sync ) &&
278 ( next = hb_fifo_see( job->fifo_raw ) ) )
280 hb_buffer_t * buf_tmp;
282 if( pv->pts_offset == INT64_MIN )
284 /* This is our first frame */
285 hb_log( "sync: first pts is %lld", cur->start );
286 pv->pts_offset = cur->start;
289 /* Check for PTS jumps over 0.5 second */
290 if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||
291 next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )
293 hb_log( "PTS discontinuity (%lld, %lld)",
294 cur->start, next->start );
296 /* Trash all subtitles */
299 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
301 hb_buffer_close( &sub );
305 /* Trash current picture */
306 hb_buffer_close( &cur );
307 pv->cur = cur = hb_fifo_get( job->fifo_raw );
309 /* Calculate new offset */
310 pv->pts_offset_old = pv->pts_offset;
311 pv->pts_offset = cur->start -
312 pv->count_frames * pv->job->vrate_base / 300;
316 /* Look for a subtitle for this frame */
320 while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
322 /* If two subtitles overlap, make the first one stop
323 when the second one starts */
324 sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
325 if( sub2 && sub->stop > sub2->start )
326 sub->stop = sub2->start;
328 if( sub->stop > cur->start )
331 /* The subtitle is older than this picture, trash it */
332 sub = hb_fifo_get( pv->subtitle->fifo_raw );
333 hb_buffer_close( &sub );
336 /* If we have subtitles left in the fifo, check if we should
337 apply the first one to the current frame or if we should
339 if( sub && sub->start > cur->start )
345 /* The PTS of the frame we are expecting now */
346 pts_expected = pv->pts_offset +
347 pv->count_frames * pv->job->vrate_base / 300;
349 if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
350 next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
352 /* The current frame is too old but the next one matches,
354 hb_buffer_close( &cur );
355 pv->cur = cur = hb_fifo_get( job->fifo_raw );
359 if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
361 /* We'll need the current frame more than one time. Make a
362 copy of it and keep it */
363 buf_tmp = hb_buffer_init( cur->size );
364 memcpy( buf_tmp->data, cur->data, cur->size );
368 /* The frame has the expected date and won't have to be
369 duplicated, just put it through */
371 pv->cur = cur = hb_fifo_get( job->fifo_raw );
374 /* Replace those MPEG-2 dates with our dates */
375 buf_tmp->start = (uint64_t) pv->count_frames *
376 pv->job->vrate_base / 300;
377 buf_tmp->stop = (uint64_t) ( pv->count_frames + 1 ) *
378 pv->job->vrate_base / 300;
380 /* If we have a subtitle for this picture, copy it */
381 /* FIXME: we should avoid this memcpy */
384 buf_tmp->sub = hb_buffer_init( sub->size );
385 buf_tmp->sub->x = sub->x;
386 buf_tmp->sub->y = sub->y;
387 buf_tmp->sub->width = sub->width;
388 buf_tmp->sub->height = sub->height;
389 memcpy( buf_tmp->sub->data, sub->data, sub->size );
392 /* Push the frame to the renderer */
393 hb_fifo_push( job->fifo_sync, buf_tmp );
398 /* Make sure we won't get more frames then expected */
399 if( pv->count_frames >= pv->count_frames_max )
401 hb_log( "sync: got %lld frames", pv->count_frames );
410 /***********************************************************************
412 ***********************************************************************
414 **********************************************************************/
415 static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
417 hb_work_private_t * pv = w->private_data;
421 hb_sync_audio_t * sync;
426 int64_t pts_expected;
430 sync = &pv->sync_audio[i];
433 if( job->acodec & HB_ACODEC_AC3 )
435 fifo = audio->fifo_out;
440 fifo = audio->fifo_sync;
444 while( !hb_fifo_is_full( fifo ) &&
445 ( buf = hb_fifo_see( audio->fifo_raw ) ) )
447 /* The PTS of the samples we are expecting now */
448 pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
450 if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
451 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
452 pv->pts_offset_old > INT64_MIN )
454 /* There has been a PTS discontinuity, and this frame might
455 be from before the discontinuity */
456 pts_expected = pv->pts_offset_old + sync->count_frames *
459 if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
460 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
462 /* There is really nothing we can do with it */
463 buf = hb_fifo_get( audio->fifo_raw );
464 hb_buffer_close( &buf );
468 /* Use the older offset */
469 start = pts_expected - pv->pts_offset_old;
473 start = pts_expected - pv->pts_offset;
476 /* Tolerance: 100 ms */
477 if( buf->start < pts_expected - 9000 )
479 /* Late audio, trash it */
480 hb_log( "sync: trashing late audio" );
481 buf = hb_fifo_get( audio->fifo_raw );
482 hb_buffer_close( &buf );
485 else if( buf->start > pts_expected + 9000 )
487 /* Missing audio, send a frame of silence */
488 InsertSilence( w, i, channelsused );
492 if( job->acodec & HB_ACODEC_AC3 )
494 buf = hb_fifo_get( audio->fifo_raw );
496 buf->stop = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
498 sync->count_frames += AC3_SAMPLES_PER_FRAME;
502 hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
504 int count_in, count_out;
506 count_in = buf_raw->size / channelsused / sizeof( float );
507 count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
508 if( buf->start < pts_expected - 1500 )
510 else if( buf->start > pts_expected + 1500 )
513 sync->data.data_in = (float *) buf_raw->data;
514 sync->data.input_frames = count_in;
515 sync->data.output_frames = count_out;
517 sync->data.src_ratio = (double) sync->data.output_frames /
518 (double) sync->data.input_frames;
520 buf = hb_buffer_init( sync->data.output_frames * channelsused *
522 sync->data.data_out = (float *) buf->data;
523 if( src_process( sync->state, &sync->data ) )
525 /* XXX If this happens, we're screwed */
526 hb_log( "sync: src_process failed" );
528 hb_buffer_close( &buf_raw );
530 buf->size = sync->data.output_frames_gen * channelsused * sizeof( float );
532 /* Set dates for resampled data */
534 buf->stop = start + sync->data.output_frames_gen *
537 sync->count_frames += sync->data.output_frames_gen;
541 hb_fifo_push( fifo, buf );
544 if( NeedSilence( w, audio ) )
546 InsertSilence( w, i, channelsused );
550 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
552 hb_work_private_t * pv = w->private_data;
553 hb_job_t * job = pv->job;
555 if( hb_fifo_size( audio->fifo_in ) ||
556 hb_fifo_size( audio->fifo_raw ) ||
557 hb_fifo_size( audio->fifo_sync ) ||
558 hb_fifo_size( audio->fifo_out ) )
560 /* We have some audio, we are fine */
564 /* No audio left in fifos */
566 if( hb_thread_has_exited( job->reader ) )
568 /* We might miss some audio to complete encoding and muxing
573 if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
574 hb_fifo_is_full( job->fifo_raw ) &&
575 hb_fifo_is_full( job->fifo_sync ) &&
576 hb_fifo_is_full( job->fifo_render ) &&
577 hb_fifo_is_full( job->fifo_mpeg4 ) )
579 /* Too much video and no audio, oh-oh */
586 static void InsertSilence( hb_work_object_t * w, int i, int channelsused )
588 hb_work_private_t * pv = w->private_data;
590 hb_sync_audio_t * sync;
594 sync = &pv->sync_audio[i];
596 if( job->acodec & HB_ACODEC_AC3 )
598 buf = hb_buffer_init( sync->ac3_size );
599 buf->start = sync->count_frames * 90000 / sync->audio->rate;
600 buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
602 memcpy( buf->data, sync->ac3_buf, buf->size );
604 hb_log( "sync: adding a silent AC-3 frame for track %x",
606 hb_fifo_push( sync->audio->fifo_out, buf );
608 sync->count_frames += AC3_SAMPLES_PER_FRAME;
613 buf = hb_buffer_init( channelsused * job->arate / 20 *
615 buf->start = sync->count_frames * 90000 / job->arate;
616 buf->stop = buf->start + 90000 / 20;
617 memset( buf->data, 0, buf->size );
619 hb_log( "sync: adding 50 ms of silence for track %x",
621 hb_fifo_push( sync->audio->fifo_sync, buf );
623 sync->count_frames += job->arate / 20;
627 static void UpdateState( hb_work_object_t * w )
629 hb_work_private_t * pv = w->private_data;
632 if( !pv->count_frames )
634 pv->st_first = hb_get_date();
638 if( hb_get_date() > pv->st_dates[3] + 1000 )
640 memmove( &pv->st_dates[0], &pv->st_dates[1],
641 3 * sizeof( uint64_t ) );
642 memmove( &pv->st_counts[0], &pv->st_counts[1],
643 3 * sizeof( uint64_t ) );
644 pv->st_dates[3] = hb_get_date();
645 pv->st_counts[3] = pv->count_frames;
648 #define p state.param.working
649 state.state = HB_STATE_WORKING;
650 p.progress = (float) pv->count_frames / (float) pv->count_frames_max;
651 if( p.progress > 1.0 )
655 p.rate_cur = 1000.0 *
656 (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
657 (float) ( pv->st_dates[3] - pv->st_dates[0] );
658 if( hb_get_date() > pv->st_first + 4000 )
661 p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
662 (float) ( pv->st_dates[3] - pv->st_first );
663 eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
665 p.hours = eta / 3600;
666 p.minutes = ( eta % 3600 ) / 60;
667 p.seconds = eta % 60;
678 hb_set_state( pv->job->h, &state );