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 );
60 static int SyncVideo( hb_work_object_t * w );
61 static void SyncAudio( hb_work_object_t * w, int i );
62 static int NeedSilence( hb_work_object_t * w, hb_audio_t * );
63 static void InsertSilence( hb_work_object_t * w, int i );
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++ )
106 /* Get subtitle info, if any */
107 pv->subtitle = hb_list_item( title->list_subtitle, 0 );
112 /***********************************************************************
114 ***********************************************************************
116 **********************************************************************/
117 void syncClose( hb_work_object_t * w )
119 hb_work_private_t * pv = w->private_data;
120 hb_job_t * job = pv->job;
121 hb_title_t * title = job->title;
125 if( pv->cur ) hb_buffer_close( &pv->cur );
127 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
129 if( job->acodec & HB_ACODEC_AC3 )
131 free( pv->sync_audio[i].ac3_buf );
135 src_delete( pv->sync_audio[i].state );
140 /***********************************************************************
142 ***********************************************************************
143 * The root routine of this work abject
144 **********************************************************************/
145 int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
146 hb_buffer_t ** unused2 )
148 hb_work_private_t * pv = w->private_data;
151 /* If we ever got a video frame, handle audio now */
152 if( pv->pts_offset != INT64_MIN )
154 for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
161 return SyncVideo( w );
164 hb_work_object_t hb_sync =
173 static void InitAudio( hb_work_object_t * w, int i )
175 hb_work_private_t * pv = w->private_data;
176 hb_job_t * job = pv->job;
177 hb_title_t * title = job->title;
178 hb_sync_audio_t * sync;
180 sync = &pv->sync_audio[i];
181 sync->audio = hb_list_item( title->list_audio, i );
183 if( job->acodec & HB_ACODEC_AC3 )
185 /* Have a silent AC-3 frame ready in case we have to fill a
191 codec = avcodec_find_encoder( CODEC_ID_AC3 );
192 c = avcodec_alloc_context();
194 c->bit_rate = sync->audio->bitrate;
195 c->sample_rate = sync->audio->rate;
196 c->channels = sync->audio->channels;
198 if( avcodec_open( c, codec ) < 0 )
200 hb_log( "sync: avcodec_open failed" );
204 zeros = calloc( AC3_SAMPLES_PER_FRAME *
205 sizeof( short ) * c->channels, 1 );
206 sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
207 sync->audio->rate / 8;
208 sync->ac3_buf = malloc( sync->ac3_size );
210 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
211 zeros ) != sync->ac3_size )
213 hb_log( "sync: avcodec_encode_audio failed" );
222 /* Initialize libsamplerate */
224 sync->state = src_new( SRC_LINEAR, 2, &error );
225 sync->data.end_of_input = 0;
231 #define PTS_DISCONTINUITY_TOLERANCE 90000
233 /***********************************************************************
235 ***********************************************************************
237 **********************************************************************/
238 static int SyncVideo( hb_work_object_t * w )
240 hb_work_private_t * pv = w->private_data;
241 hb_buffer_t * cur, * next, * sub = NULL;
242 hb_job_t * job = pv->job;
243 int64_t pts_expected;
250 if( hb_thread_has_exited( job->reader ) &&
251 !hb_fifo_size( job->fifo_mpeg2 ) &&
252 !hb_fifo_size( job->fifo_raw ) )
254 /* All video data has been processed already, we won't get
256 hb_log( "sync: got %lld frames, %lld expected",
257 pv->count_frames, pv->count_frames_max );
262 if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
264 /* We haven't even got a frame yet */
269 /* At this point we have a frame to process. Let's check
270 1) if we will be able to push into the fifo ahead
271 2) if the next frame is there already, since we need it to
272 know whether we'll have to repeat the current frame or not */
273 while( !hb_fifo_is_full( job->fifo_sync ) &&
274 ( next = hb_fifo_see( job->fifo_raw ) ) )
276 hb_buffer_t * buf_tmp;
278 if( pv->pts_offset == INT64_MIN )
280 /* This is our first frame */
281 hb_log( "sync: first pts is %lld", cur->start );
282 pv->pts_offset = cur->start;
285 /* Check for PTS jumps over 0.5 second */
286 if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||
287 next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )
289 hb_log( "PTS discontinuity (%lld, %lld)",
290 cur->start, next->start );
292 /* Trash all subtitles */
295 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
297 hb_buffer_close( &sub );
301 /* Trash current picture */
302 hb_buffer_close( &cur );
303 pv->cur = cur = hb_fifo_get( job->fifo_raw );
305 /* Calculate new offset */
306 pv->pts_offset_old = pv->pts_offset;
307 pv->pts_offset = cur->start -
308 pv->count_frames * pv->job->vrate_base / 300;
312 /* Look for a subtitle for this frame */
316 while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
318 /* If two subtitles overlap, make the first one stop
319 when the second one starts */
320 sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
321 if( sub2 && sub->stop > sub2->start )
322 sub->stop = sub2->start;
324 if( sub->stop > cur->start )
327 /* The subtitle is older than this picture, trash it */
328 sub = hb_fifo_get( pv->subtitle->fifo_raw );
329 hb_buffer_close( &sub );
332 /* If we have subtitles left in the fifo, check if we should
333 apply the first one to the current frame or if we should
335 if( sub && sub->start > cur->start )
341 /* The PTS of the frame we are expecting now */
342 pts_expected = pv->pts_offset +
343 pv->count_frames * pv->job->vrate_base / 300;
345 if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
346 next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
348 /* The current frame is too old but the next one matches,
350 hb_buffer_close( &cur );
351 pv->cur = cur = hb_fifo_get( job->fifo_raw );
355 if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
357 /* We'll need the current frame more than one time. Make a
358 copy of it and keep it */
359 buf_tmp = hb_buffer_init( cur->size );
360 memcpy( buf_tmp->data, cur->data, cur->size );
364 /* The frame has the expected date and won't have to be
365 duplicated, just put it through */
367 pv->cur = cur = hb_fifo_get( job->fifo_raw );
370 /* Replace those MPEG-2 dates with our dates */
371 buf_tmp->start = (uint64_t) pv->count_frames *
372 pv->job->vrate_base / 300;
373 buf_tmp->stop = (uint64_t) ( pv->count_frames + 1 ) *
374 pv->job->vrate_base / 300;
376 /* If we have a subtitle for this picture, copy it */
377 /* FIXME: we should avoid this memcpy */
380 buf_tmp->sub = hb_buffer_init( sub->size );
381 buf_tmp->sub->x = sub->x;
382 buf_tmp->sub->y = sub->y;
383 buf_tmp->sub->width = sub->width;
384 buf_tmp->sub->height = sub->height;
385 memcpy( buf_tmp->sub->data, sub->data, sub->size );
388 /* Push the frame to the renderer */
389 hb_fifo_push( job->fifo_sync, buf_tmp );
394 /* Make sure we won't get more frames then expected */
395 if( pv->count_frames >= pv->count_frames_max )
397 hb_log( "sync: got %lld frames", pv->count_frames );
406 /***********************************************************************
408 ***********************************************************************
410 **********************************************************************/
411 static void SyncAudio( hb_work_object_t * w, int i )
413 hb_work_private_t * pv = w->private_data;
417 hb_sync_audio_t * sync;
422 int64_t pts_expected;
426 sync = &pv->sync_audio[i];
429 if( job->acodec & HB_ACODEC_AC3 )
431 fifo = audio->fifo_out;
436 fifo = audio->fifo_sync;
440 while( !hb_fifo_is_full( fifo ) &&
441 ( buf = hb_fifo_see( audio->fifo_raw ) ) )
443 /* The PTS of the samples we are expecting now */
444 pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
446 if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
447 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
448 pv->pts_offset_old > INT64_MIN )
450 /* There has been a PTS discontinuity, and this frame might
451 be from before the discontinuity */
452 pts_expected = pv->pts_offset_old + sync->count_frames *
455 if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
456 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
458 /* There is really nothing we can do with it */
459 buf = hb_fifo_get( audio->fifo_raw );
460 hb_buffer_close( &buf );
464 /* Use the older offset */
465 start = pts_expected - pv->pts_offset_old;
469 start = pts_expected - pv->pts_offset;
472 /* Tolerance: 100 ms */
473 if( buf->start < pts_expected - 9000 )
475 /* Late audio, trash it */
476 hb_log( "sync: trashing late audio" );
477 buf = hb_fifo_get( audio->fifo_raw );
478 hb_buffer_close( &buf );
481 else if( buf->start > pts_expected + 9000 )
483 /* Missing audio, send a frame of silence */
484 InsertSilence( w, i );
488 if( job->acodec & HB_ACODEC_AC3 )
490 buf = hb_fifo_get( audio->fifo_raw );
492 buf->stop = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
494 sync->count_frames += AC3_SAMPLES_PER_FRAME;
498 hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
500 int count_in, count_out;
502 count_in = buf_raw->size / 2 / sizeof( float );
503 count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
504 if( buf->start < pts_expected - 1500 )
506 else if( buf->start > pts_expected + 1500 )
509 sync->data.data_in = (float *) buf_raw->data;
510 sync->data.input_frames = count_in;
511 sync->data.output_frames = count_out;
513 sync->data.src_ratio = (double) sync->data.output_frames /
514 (double) sync->data.input_frames;
516 buf = hb_buffer_init( sync->data.output_frames * 2 *
518 sync->data.data_out = (float *) buf->data;
519 if( src_process( sync->state, &sync->data ) )
521 /* XXX If this happens, we're screwed */
522 hb_log( "sync: src_process failed" );
524 hb_buffer_close( &buf_raw );
526 buf->size = sync->data.output_frames_gen * 2 * sizeof( float );
528 /* Set dates for resampled data */
530 buf->stop = start + sync->data.output_frames_gen *
533 sync->count_frames += sync->data.output_frames_gen;
537 hb_fifo_push( fifo, buf );
540 if( NeedSilence( w, audio ) )
542 InsertSilence( w, i );
546 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
548 hb_work_private_t * pv = w->private_data;
549 hb_job_t * job = pv->job;
551 if( hb_fifo_size( audio->fifo_in ) ||
552 hb_fifo_size( audio->fifo_raw ) ||
553 hb_fifo_size( audio->fifo_sync ) ||
554 hb_fifo_size( audio->fifo_out ) )
556 /* We have some audio, we are fine */
560 /* No audio left in fifos */
562 if( hb_thread_has_exited( job->reader ) )
564 /* We might miss some audio to complete encoding and muxing
569 if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
570 hb_fifo_is_full( job->fifo_raw ) &&
571 hb_fifo_is_full( job->fifo_sync ) &&
572 hb_fifo_is_full( job->fifo_render ) &&
573 hb_fifo_is_full( job->fifo_mpeg4 ) )
575 /* Too much video and no audio, oh-oh */
582 static void InsertSilence( hb_work_object_t * w, int i )
584 hb_work_private_t * pv = w->private_data;
586 hb_sync_audio_t * sync;
590 sync = &pv->sync_audio[i];
592 if( job->acodec & HB_ACODEC_AC3 )
594 buf = hb_buffer_init( sync->ac3_size );
595 buf->start = sync->count_frames * 90000 / sync->audio->rate;
596 buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
598 memcpy( buf->data, sync->ac3_buf, buf->size );
600 hb_log( "sync: adding a silent AC-3 frame for track %x",
602 hb_fifo_push( sync->audio->fifo_out, buf );
604 sync->count_frames += AC3_SAMPLES_PER_FRAME;
609 buf = hb_buffer_init( 2 * job->arate / 20 *
611 buf->start = sync->count_frames * 90000 / job->arate;
612 buf->stop = buf->start + 90000 / 20;
613 memset( buf->data, 0, buf->size );
615 hb_log( "sync: adding 50 ms of silence for track %x",
617 hb_fifo_push( sync->audio->fifo_sync, buf );
619 sync->count_frames += job->arate / 20;
623 static void UpdateState( hb_work_object_t * w )
625 hb_work_private_t * pv = w->private_data;
628 if( !pv->count_frames )
630 pv->st_first = hb_get_date();
634 if( hb_get_date() > pv->st_dates[3] + 1000 )
636 memmove( &pv->st_dates[0], &pv->st_dates[1],
637 3 * sizeof( uint64_t ) );
638 memmove( &pv->st_counts[0], &pv->st_counts[1],
639 3 * sizeof( uint64_t ) );
640 pv->st_dates[3] = hb_get_date();
641 pv->st_counts[3] = pv->count_frames;
644 #define p state.param.working
645 state.state = HB_STATE_WORKING;
646 p.progress = (float) pv->count_frames / (float) pv->count_frames_max;
647 if( p.progress > 1.0 )
651 p.rate_cur = 1000.0 *
652 (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
653 (float) ( pv->st_dates[3] - pv->st_dates[0] );
654 if( hb_get_date() > pv->st_first + 4000 )
657 p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
658 (float) ( pv->st_dates[3] - pv->st_first );
659 eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
661 p.hours = eta / 3600;
662 p.minutes = ( eta % 3600 ) / 60;
663 p.seconds = eta % 60;
674 hb_set_state( pv->job->h, &state );