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 w->private_data = NULL;
143 /***********************************************************************
145 ***********************************************************************
146 * The root routine of this work abject
147 **********************************************************************/
148 int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
149 hb_buffer_t ** unused2 )
151 hb_work_private_t * pv = w->private_data;
154 /* If we ever got a video frame, handle audio now */
155 if( pv->pts_offset != INT64_MIN )
157 for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
164 return SyncVideo( w );
167 hb_work_object_t hb_sync =
176 static void InitAudio( hb_work_object_t * w, int i )
178 hb_work_private_t * pv = w->private_data;
179 hb_job_t * job = pv->job;
180 hb_title_t * title = job->title;
181 hb_sync_audio_t * sync;
183 sync = &pv->sync_audio[i];
184 sync->audio = hb_list_item( title->list_audio, i );
186 if( job->acodec & HB_ACODEC_AC3 )
188 /* Have a silent AC-3 frame ready in case we have to fill a
194 codec = avcodec_find_encoder( CODEC_ID_AC3 );
195 c = avcodec_alloc_context();
197 c->bit_rate = sync->audio->bitrate;
198 c->sample_rate = sync->audio->rate;
201 if( avcodec_open( c, codec ) < 0 )
203 hb_log( "sync: avcodec_open failed" );
207 zeros = calloc( AC3_SAMPLES_PER_FRAME *
208 sizeof( short ) * c->channels, 1 );
209 sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
210 sync->audio->rate / 8;
211 sync->ac3_buf = malloc( sync->ac3_size );
213 if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
214 zeros ) != sync->ac3_size )
216 hb_log( "sync: avcodec_encode_audio failed" );
225 /* Initialize libsamplerate */
227 sync->state = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown), &error );
228 sync->data.end_of_input = 0;
234 #define PTS_DISCONTINUITY_TOLERANCE 90000
236 /***********************************************************************
238 ***********************************************************************
240 **********************************************************************/
241 static int SyncVideo( hb_work_object_t * w )
243 hb_work_private_t * pv = w->private_data;
244 hb_buffer_t * cur, * next, * sub = NULL;
245 hb_job_t * job = pv->job;
246 int64_t pts_expected;
253 if( hb_thread_has_exited( job->reader ) &&
254 !hb_fifo_size( job->fifo_mpeg2 ) &&
255 !hb_fifo_size( job->fifo_raw ) )
257 /* All video data has been processed already, we won't get
259 hb_log( "sync: got %lld frames, %lld expected",
260 pv->count_frames, pv->count_frames_max );
263 hb_buffer_t * buf_tmp;
265 // Drop an empty buffer into our output to ensure that things
266 // get flushed all the way out.
267 buf_tmp = hb_buffer_init(0); // Empty end buffer
268 hb_fifo_push( job->fifo_sync, buf_tmp );
273 if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
275 /* We haven't even got a frame yet */
280 /* At this point we have a frame to process. Let's check
281 1) if we will be able to push into the fifo ahead
282 2) if the next frame is there already, since we need it to
283 know whether we'll have to repeat the current frame or not */
284 while( !hb_fifo_is_full( job->fifo_sync ) &&
285 ( next = hb_fifo_see( job->fifo_raw ) ) )
287 hb_buffer_t * buf_tmp;
289 if( pv->pts_offset == INT64_MIN )
291 /* This is our first frame */
292 hb_log( "sync: first pts is %lld", cur->start );
293 pv->pts_offset = cur->start;
296 /* Check for PTS jumps over 0.5 second */
297 if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||
298 next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )
300 hb_log( "PTS discontinuity (%lld, %lld)",
301 cur->start, next->start );
303 /* Trash all subtitles */
306 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
308 hb_buffer_close( &sub );
312 /* Trash current picture */
313 hb_buffer_close( &cur );
314 pv->cur = cur = hb_fifo_get( job->fifo_raw );
316 /* Calculate new offset */
317 pv->pts_offset_old = pv->pts_offset;
318 pv->pts_offset = cur->start -
319 pv->count_frames * pv->job->vrate_base / 300;
323 /* Look for a subtitle for this frame */
327 while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
329 /* If two subtitles overlap, make the first one stop
330 when the second one starts */
331 sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
332 if( sub2 && sub->stop > sub2->start )
333 sub->stop = sub2->start;
335 if( sub->stop > cur->start )
338 /* The subtitle is older than this picture, trash it */
339 sub = hb_fifo_get( pv->subtitle->fifo_raw );
340 hb_buffer_close( &sub );
343 /* If we have subtitles left in the fifo, check if we should
344 apply the first one to the current frame or if we should
346 if( sub && sub->start > cur->start )
352 /* The PTS of the frame we are expecting now */
353 pts_expected = pv->pts_offset +
354 pv->count_frames * pv->job->vrate_base / 300;
356 if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
357 next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
359 /* The current frame is too old but the next one matches,
361 hb_buffer_close( &cur );
362 pv->cur = cur = hb_fifo_get( job->fifo_raw );
366 if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
368 /* We'll need the current frame more than one time. Make a
369 copy of it and keep it */
370 buf_tmp = hb_buffer_init( cur->size );
371 memcpy( buf_tmp->data, cur->data, cur->size );
375 /* The frame has the expected date and won't have to be
376 duplicated, just put it through */
378 pv->cur = cur = hb_fifo_get( job->fifo_raw );
381 /* Replace those MPEG-2 dates with our dates */
382 buf_tmp->start = (uint64_t) pv->count_frames *
383 pv->job->vrate_base / 300;
384 buf_tmp->stop = (uint64_t) ( pv->count_frames + 1 ) *
385 pv->job->vrate_base / 300;
387 /* If we have a subtitle for this picture, copy it */
388 /* FIXME: we should avoid this memcpy */
391 buf_tmp->sub = hb_buffer_init( sub->size );
392 buf_tmp->sub->x = sub->x;
393 buf_tmp->sub->y = sub->y;
394 buf_tmp->sub->width = sub->width;
395 buf_tmp->sub->height = sub->height;
396 memcpy( buf_tmp->sub->data, sub->data, sub->size );
399 /* Push the frame to the renderer */
400 hb_fifo_push( job->fifo_sync, buf_tmp );
405 /* Make sure we won't get more frames then expected */
406 if( pv->count_frames >= pv->count_frames_max )
408 hb_log( "sync: got %lld frames", pv->count_frames );
411 // Drop an empty buffer into our output to ensure that things
412 // get flushed all the way out.
413 buf_tmp = hb_buffer_init(0); // Empty end buffer
414 hb_fifo_push( job->fifo_sync, buf_tmp );
423 /***********************************************************************
425 ***********************************************************************
427 **********************************************************************/
428 static void SyncAudio( hb_work_object_t * w, int i )
430 hb_work_private_t * pv = w->private_data;
434 hb_sync_audio_t * sync;
439 int64_t pts_expected;
443 sync = &pv->sync_audio[i];
446 if( job->acodec & HB_ACODEC_AC3 )
448 fifo = audio->fifo_out;
453 fifo = audio->fifo_sync;
457 while( !hb_fifo_is_full( fifo ) &&
458 ( buf = hb_fifo_see( audio->fifo_raw ) ) )
460 /* The PTS of the samples we are expecting now */
461 pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
463 if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
464 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
465 pv->pts_offset_old > INT64_MIN )
467 /* There has been a PTS discontinuity, and this frame might
468 be from before the discontinuity */
469 pts_expected = pv->pts_offset_old + sync->count_frames *
472 if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
473 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
475 /* There is really nothing we can do with it */
476 buf = hb_fifo_get( audio->fifo_raw );
477 hb_buffer_close( &buf );
481 /* Use the older offset */
482 start = pts_expected - pv->pts_offset_old;
486 start = pts_expected - pv->pts_offset;
489 /* Tolerance: 100 ms */
490 if( buf->start < pts_expected - 9000 )
492 /* Late audio, trash it */
493 hb_log( "sync: trashing late audio" );
494 buf = hb_fifo_get( audio->fifo_raw );
495 hb_buffer_close( &buf );
498 else if( buf->start > pts_expected + 9000 )
500 /* Missing audio, send a frame of silence */
501 InsertSilence( w, i );
505 if( job->acodec & HB_ACODEC_AC3 )
507 buf = hb_fifo_get( audio->fifo_raw );
509 buf->stop = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
511 sync->count_frames += AC3_SAMPLES_PER_FRAME;
515 hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
517 int count_in, count_out;
519 count_in = buf_raw->size / HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) / sizeof( float );
520 count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
521 if( buf->start < pts_expected - 1500 )
523 else if( buf->start > pts_expected + 1500 )
526 sync->data.data_in = (float *) buf_raw->data;
527 sync->data.input_frames = count_in;
528 sync->data.output_frames = count_out;
530 sync->data.src_ratio = (double) sync->data.output_frames /
531 (double) sync->data.input_frames;
533 buf = hb_buffer_init( sync->data.output_frames * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *
535 sync->data.data_out = (float *) buf->data;
536 if( src_process( sync->state, &sync->data ) )
538 /* XXX If this happens, we're screwed */
539 hb_log( "sync: src_process failed" );
541 hb_buffer_close( &buf_raw );
543 buf->size = sync->data.output_frames_gen * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) * sizeof( float );
545 /* Set dates for resampled data */
547 buf->stop = start + sync->data.output_frames_gen *
550 sync->count_frames += sync->data.output_frames_gen;
554 hb_fifo_push( fifo, buf );
557 if( NeedSilence( w, audio ) )
559 InsertSilence( w, i );
563 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
565 hb_work_private_t * pv = w->private_data;
566 hb_job_t * job = pv->job;
568 if( hb_fifo_size( audio->fifo_in ) ||
569 hb_fifo_size( audio->fifo_raw ) ||
570 hb_fifo_size( audio->fifo_sync ) ||
571 hb_fifo_size( audio->fifo_out ) )
573 /* We have some audio, we are fine */
577 /* No audio left in fifos */
579 if( hb_thread_has_exited( job->reader ) )
581 /* We might miss some audio to complete encoding and muxing
586 if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
587 hb_fifo_is_full( job->fifo_raw ) &&
588 hb_fifo_is_full( job->fifo_sync ) &&
589 hb_fifo_is_full( job->fifo_render ) &&
590 hb_fifo_is_full( job->fifo_mpeg4 ) )
592 /* Too much video and no audio, oh-oh */
599 static void InsertSilence( hb_work_object_t * w, int i )
601 hb_work_private_t * pv = w->private_data;
603 hb_sync_audio_t * sync;
607 sync = &pv->sync_audio[i];
609 if( job->acodec & HB_ACODEC_AC3 )
611 buf = hb_buffer_init( sync->ac3_size );
612 buf->start = sync->count_frames * 90000 / sync->audio->rate;
613 buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
615 memcpy( buf->data, sync->ac3_buf, buf->size );
617 hb_log( "sync: adding a silent AC-3 frame for track %x",
619 hb_fifo_push( sync->audio->fifo_out, buf );
621 sync->count_frames += AC3_SAMPLES_PER_FRAME;
626 buf = hb_buffer_init( HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) * job->arate / 20 *
628 buf->start = sync->count_frames * 90000 / job->arate;
629 buf->stop = buf->start + 90000 / 20;
630 memset( buf->data, 0, buf->size );
632 hb_log( "sync: adding 50 ms of silence for track %x",
634 hb_fifo_push( sync->audio->fifo_sync, buf );
636 sync->count_frames += job->arate / 20;
640 static void UpdateState( hb_work_object_t * w )
642 hb_work_private_t * pv = w->private_data;
645 if( !pv->count_frames )
647 pv->st_first = hb_get_date();
651 if( hb_get_date() > pv->st_dates[3] + 1000 )
653 memmove( &pv->st_dates[0], &pv->st_dates[1],
654 3 * sizeof( uint64_t ) );
655 memmove( &pv->st_counts[0], &pv->st_counts[1],
656 3 * sizeof( uint64_t ) );
657 pv->st_dates[3] = hb_get_date();
658 pv->st_counts[3] = pv->count_frames;
661 #define p state.param.working
662 state.state = HB_STATE_WORKING;
663 p.progress = (float) pv->count_frames / (float) pv->count_frames_max;
664 if( p.progress > 1.0 )
668 p.rate_cur = 1000.0 *
669 (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
670 (float) ( pv->st_dates[3] - pv->st_dates[0] );
671 if( hb_get_date() > pv->st_first + 4000 )
674 p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
675 (float) ( pv->st_dates[3] - pv->st_first );
676 eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
678 p.hours = eta / 3600;
679 p.minutes = ( eta % 3600 ) / 60;
680 p.seconds = eta % 60;
691 hb_set_state( pv->job->h, &state );