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_object_s
42 hb_subtitle_t * subtitle;
44 int64_t pts_offset_old;
46 int64_t count_frames_max;
47 hb_buffer_t * cur; /* The next picture to process */
50 hb_sync_audio_t sync_audio[8];
53 uint64_t st_counts[4];
58 /***********************************************************************
60 **********************************************************************/
61 static void InitAudio( hb_work_object_t * w, int i );
62 static void Close( hb_work_object_t ** _w );
63 static int Work( hb_work_object_t * w, hb_buffer_t ** unused1,
64 hb_buffer_t ** unused2 );
65 static int SyncVideo( hb_work_object_t * w );
66 static void SyncAudio( hb_work_object_t * w, int i );
67 static int NeedSilence( hb_work_object_t * w, hb_audio_t * );
68 static void InsertSilence( hb_work_object_t * w, int i );
69 static void UpdateState( hb_work_object_t * w );
71 /***********************************************************************
73 ***********************************************************************
74 * Initialize the work object
75 **********************************************************************/
76 hb_work_object_t * hb_work_sync_init( hb_job_t * job )
79 hb_title_t * title = job->title;
80 hb_chapter_t * chapter;
84 w = calloc( sizeof( hb_work_object_t ), 1 );
85 w->name = strdup( "Synchronization" );
90 w->pts_offset = INT64_MIN;
91 w->pts_offset_old = INT64_MIN;
94 /* Calculate how many video frames we are expecting */
96 for( i = job->chapter_start; i <= job->chapter_end; i++ )
98 chapter = hb_list_item( title->list_chapter, i - 1 );
99 duration += chapter->duration;
102 /* 1 second safety so we're sure we won't miss anything */
103 w->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
105 hb_log( "sync: expecting %lld video frames", w->count_frames_max );
107 /* Initialize libsamplerate for every audio track we have */
108 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
113 /* Get subtitle info, if any */
114 w->subtitle = hb_list_item( title->list_subtitle, 0 );
119 static void InitAudio( hb_work_object_t * w, int i )
121 hb_job_t * job = w->job;
122 hb_title_t * title = job->title;
123 hb_sync_audio_t * sync;
125 sync = &w->sync_audio[i];
126 sync->audio = hb_list_item( title->list_audio, i );
128 if( job->acodec & HB_ACODEC_AC3 )
130 /* Have a silent AC-3 frame ready in case we have to fill a
136 codec = avcodec_find_encoder( CODEC_ID_AC3 );
137 c = avcodec_alloc_context();
139 c->bit_rate = sync->audio->bitrate;
140 c->sample_rate = sync->audio->rate;
141 c->channels = sync->audio->channels;
143 if( avcodec_open( c, codec ) < 0 )
145 hb_log( "sync: avcodec_open failed" );
149 zeros = calloc( AC3_SAMPLES_PER_FRAME *
150 sizeof( short ) * c->channels, 1 );
151 sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
152 sync->audio->rate / 8;
153 sync->ac3_buf = malloc( sync->ac3_size );
155 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
156 zeros ) != sync->ac3_size )
158 hb_log( "sync: avcodec_encode_audio failed" );
167 /* Initialize libsamplerate */
169 sync->state = src_new( SRC_LINEAR, 2, &error );
170 sync->data.end_of_input = 0;
174 /***********************************************************************
176 ***********************************************************************
178 **********************************************************************/
179 static void Close( hb_work_object_t ** _w )
181 hb_work_object_t * w = *_w;
182 hb_job_t * job = w->job;
183 hb_title_t * title = job->title;
187 if( w->cur ) hb_buffer_close( &w->cur );
189 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
191 if( job->acodec & HB_ACODEC_AC3 )
193 free( w->sync_audio[i].ac3_buf );
197 src_delete( w->sync_audio[i].state );
206 /***********************************************************************
208 ***********************************************************************
209 * The root routine of this work abject
210 **********************************************************************/
211 static int Work( hb_work_object_t * w, hb_buffer_t ** unused1,
212 hb_buffer_t ** unused2 )
216 /* If we ever got a video frame, handle audio now */
217 if( w->pts_offset != INT64_MIN )
219 for( i = 0; i < hb_list_count( w->job->title->list_audio ); i++ )
226 return SyncVideo( w );
229 #define PTS_DISCONTINUITY_TOLERANCE 90000
231 /***********************************************************************
233 ***********************************************************************
235 **********************************************************************/
236 static int SyncVideo( hb_work_object_t * w )
238 hb_buffer_t * cur, * next, * sub = NULL;
239 hb_job_t * job = w->job;
240 int64_t pts_expected;
247 if( hb_thread_has_exited( job->reader ) &&
248 !hb_fifo_size( job->fifo_mpeg2 ) &&
249 !hb_fifo_size( job->fifo_raw ) )
251 /* All video data has been processed already, we won't get
253 hb_log( "sync: got %lld frames, %lld expected",
254 w->count_frames, w->count_frames_max );
259 if( !w->cur && !( w->cur = hb_fifo_get( job->fifo_raw ) ) )
261 /* We haven't even got a frame yet */
266 /* At this point we have a frame to process. Let's check
267 1) if we will be able to push into the fifo ahead
268 2) if the next frame is there already, since we need it to
269 know whether we'll have to repeat the current frame or not */
270 while( !hb_fifo_is_full( job->fifo_sync ) &&
271 ( next = hb_fifo_see( job->fifo_raw ) ) )
273 hb_buffer_t * buf_tmp;
275 if( w->pts_offset == INT64_MIN )
277 /* This is our first frame */
278 hb_log( "sync: first pts is %lld", cur->start );
279 w->pts_offset = cur->start;
282 /* Check for PTS jumps over 0.5 second */
283 if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||
284 next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )
286 hb_log( "PTS discontinuity (%lld, %lld)",
287 cur->start, next->start );
289 /* Trash all subtitles */
292 while( ( sub = hb_fifo_get( w->subtitle->fifo_raw ) ) )
294 hb_buffer_close( &sub );
298 /* Trash current picture */
299 hb_buffer_close( &cur );
300 w->cur = cur = hb_fifo_get( job->fifo_raw );
302 /* Calculate new offset */
303 w->pts_offset_old = w->pts_offset;
304 w->pts_offset = cur->start -
305 w->count_frames * w->job->vrate_base / 300;
309 /* Look for a subtitle for this frame */
313 while( ( sub = hb_fifo_see( w->subtitle->fifo_raw ) ) )
315 /* If two subtitles overlap, make the first one stop
316 when the second one starts */
317 sub2 = hb_fifo_see2( w->subtitle->fifo_raw );
318 if( sub2 && sub->stop > sub2->start )
319 sub->stop = sub2->start;
321 if( sub->stop > cur->start )
324 /* The subtitle is older than this picture, trash it */
325 sub = hb_fifo_get( w->subtitle->fifo_raw );
326 hb_buffer_close( &sub );
329 /* If we have subtitles left in the fifo, check if we should
330 apply the first one to the current frame or if we should
332 if( sub && sub->start > cur->start )
338 /* The PTS of the frame we are expecting now */
339 pts_expected = w->pts_offset +
340 w->count_frames * w->job->vrate_base / 300;
342 if( cur->start < pts_expected - w->job->vrate_base / 300 / 2 &&
343 next->start < pts_expected + w->job->vrate_base / 300 / 2 )
345 /* The current frame is too old but the next one matches,
347 hb_buffer_close( &cur );
348 w->cur = cur = hb_fifo_get( job->fifo_raw );
352 if( next->start > pts_expected + 3 * w->job->vrate_base / 300 / 2 )
354 /* We'll need the current frame more than one time. Make a
355 copy of it and keep it */
356 buf_tmp = hb_buffer_init( cur->size );
357 memcpy( buf_tmp->data, cur->data, cur->size );
361 /* The frame has the expected date and won't have to be
362 duplicated, just put it through */
364 w->cur = cur = hb_fifo_get( job->fifo_raw );
367 /* Replace those MPEG-2 dates with our dates */
368 buf_tmp->start = (uint64_t) w->count_frames *
369 w->job->vrate_base / 300;
370 buf_tmp->stop = (uint64_t) ( w->count_frames + 1 ) *
371 w->job->vrate_base / 300;
373 /* If we have a subtitle for this picture, copy it */
374 /* FIXME: we should avoid this memcpy */
377 buf_tmp->sub = hb_buffer_init( sub->size );
378 buf_tmp->sub->x = sub->x;
379 buf_tmp->sub->y = sub->y;
380 buf_tmp->sub->width = sub->width;
381 buf_tmp->sub->height = sub->height;
382 memcpy( buf_tmp->sub->data, sub->data, sub->size );
385 /* Push the frame to the renderer */
386 hb_fifo_push( job->fifo_sync, buf_tmp );
391 /* Make sure we won't get more frames then expected */
392 if( w->count_frames >= w->count_frames_max )
394 hb_log( "sync: got %lld frames", w->count_frames );
403 /***********************************************************************
405 ***********************************************************************
407 **********************************************************************/
408 static void SyncAudio( hb_work_object_t * w, int i )
413 hb_sync_audio_t * sync;
418 int64_t pts_expected;
422 sync = &w->sync_audio[i];
425 if( job->acodec & HB_ACODEC_AC3 )
427 fifo = audio->fifo_out;
432 fifo = audio->fifo_sync;
436 while( !hb_fifo_is_full( fifo ) &&
437 ( buf = hb_fifo_see( audio->fifo_raw ) ) )
439 /* The PTS of the samples we are expecting now */
440 pts_expected = w->pts_offset + sync->count_frames * 90000 / rate;
442 if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
443 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
444 w->pts_offset_old > INT64_MIN )
446 /* There has been a PTS discontinuity, and this frame might
447 be from before the discontinuity */
448 pts_expected = w->pts_offset_old + sync->count_frames *
451 if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
452 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
454 /* There is really nothing we can do with it */
455 buf = hb_fifo_get( audio->fifo_raw );
456 hb_buffer_close( &buf );
460 /* Use the older offset */
461 start = pts_expected - w->pts_offset_old;
465 start = pts_expected - w->pts_offset;
468 /* Tolerance: 100 ms */
469 if( buf->start < pts_expected - 9000 )
471 /* Late audio, trash it */
472 hb_log( "sync: trashing late audio" );
473 buf = hb_fifo_get( audio->fifo_raw );
474 hb_buffer_close( &buf );
477 else if( buf->start > pts_expected + 9000 )
479 /* Missing audio, send a frame of silence */
480 InsertSilence( w, i );
484 if( job->acodec & HB_ACODEC_AC3 )
486 buf = hb_fifo_get( audio->fifo_raw );
488 buf->stop = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
490 sync->count_frames += AC3_SAMPLES_PER_FRAME;
494 hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
496 int count_in, count_out;
498 count_in = buf_raw->size / 2 / sizeof( float );
499 count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
500 if( buf->start < pts_expected - 1500 )
502 else if( buf->start > pts_expected + 1500 )
505 sync->data.data_in = (float *) buf_raw->data;
506 sync->data.input_frames = count_in;
507 sync->data.output_frames = count_out;
509 sync->data.src_ratio = (double) sync->data.output_frames /
510 (double) sync->data.input_frames;
512 buf = hb_buffer_init( sync->data.output_frames * 2 *
514 sync->data.data_out = (float *) buf->data;
515 if( src_process( sync->state, &sync->data ) )
517 /* XXX If this happens, we're screwed */
518 hb_log( "sync: src_process failed" );
520 hb_buffer_close( &buf_raw );
522 buf->size = sync->data.output_frames_gen * 2 * sizeof( float );
524 /* Set dates for resampled data */
526 buf->stop = start + sync->data.output_frames_gen *
529 sync->count_frames += sync->data.output_frames_gen;
533 hb_fifo_push( fifo, buf );
536 if( NeedSilence( w, audio ) )
538 InsertSilence( w, i );
542 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
544 hb_job_t * job = w->job;
546 if( hb_fifo_size( audio->fifo_in ) ||
547 hb_fifo_size( audio->fifo_raw ) ||
548 hb_fifo_size( audio->fifo_sync ) ||
549 hb_fifo_size( audio->fifo_out ) )
551 /* We have some audio, we are fine */
555 /* No audio left in fifos */
557 if( hb_thread_has_exited( job->reader ) )
559 /* We might miss some audio to complete encoding and muxing
564 if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
565 hb_fifo_is_full( job->fifo_raw ) &&
566 hb_fifo_is_full( job->fifo_sync ) &&
567 hb_fifo_is_full( job->fifo_render ) &&
568 hb_fifo_is_full( job->fifo_mpeg4 ) )
570 /* Too much video and no audio, oh-oh */
577 static void InsertSilence( hb_work_object_t * w, int i )
580 hb_sync_audio_t * sync;
584 sync = &w->sync_audio[i];
586 if( job->acodec & HB_ACODEC_AC3 )
588 buf = hb_buffer_init( sync->ac3_size );
589 buf->start = sync->count_frames * 90000 / sync->audio->rate;
590 buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
592 memcpy( buf->data, sync->ac3_buf, buf->size );
594 hb_log( "sync: adding a silent AC-3 frame for track %x",
596 hb_fifo_push( sync->audio->fifo_out, buf );
598 sync->count_frames += AC3_SAMPLES_PER_FRAME;
603 buf = hb_buffer_init( 2 * job->arate / 20 *
605 buf->start = sync->count_frames * 90000 / job->arate;
606 buf->stop = buf->start + 90000 / 20;
607 memset( buf->data, 0, buf->size );
609 hb_log( "sync: adding 50 ms of silence for track %x",
611 hb_fifo_push( sync->audio->fifo_sync, buf );
613 sync->count_frames += job->arate / 20;
617 static void UpdateState( hb_work_object_t * w )
621 if( !w->count_frames )
623 w->st_first = hb_get_date();
627 if( hb_get_date() > w->st_dates[3] + 1000 )
629 memmove( &w->st_dates[0], &w->st_dates[1],
630 3 * sizeof( uint64_t ) );
631 memmove( &w->st_counts[0], &w->st_counts[1],
632 3 * sizeof( uint64_t ) );
633 w->st_dates[3] = hb_get_date();
634 w->st_counts[3] = w->count_frames;
637 #define p state.param.working
638 state.state = HB_STATE_WORKING;
639 p.progress = (float) w->count_frames / (float) w->count_frames_max;
640 if( p.progress > 1.0 )
644 p.rate_cur = 1000.0 *
645 (float) ( w->st_counts[3] - w->st_counts[0] ) /
646 (float) ( w->st_dates[3] - w->st_dates[0] );
647 if( hb_get_date() > w->st_first + 4000 )
650 p.rate_avg = 1000.0 * (float) w->st_counts[3] /
651 (float) ( w->st_dates[3] - w->st_first );
652 eta = (float) ( w->count_frames_max - w->st_counts[3] ) /
654 p.hours = eta / 3600;
655 p.minutes = ( eta % 3600 ) / 60;
656 p.seconds = eta % 60;
667 hb_set_state( w->job->h, &state );