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;
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 );
264 hb_buffer_t * buf_tmp;
266 // Drop an empty buffer into our output to ensure that things
267 // get flushed all the way out.
268 buf_tmp = hb_buffer_init(0); // Empty end buffer
269 hb_fifo_push( job->fifo_sync, buf_tmp );
274 if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
276 /* We haven't even got a frame yet */
281 /* At this point we have a frame to process. Let's check
282 1) if we will be able to push into the fifo ahead
283 2) if the next frame is there already, since we need it to
284 know whether we'll have to repeat the current frame or not */
285 while( !hb_fifo_is_full( job->fifo_sync ) &&
286 ( next = hb_fifo_see( job->fifo_raw ) ) )
288 hb_buffer_t * buf_tmp;
290 if( pv->pts_offset == INT64_MIN )
292 /* This is our first frame */
293 hb_log( "sync: first pts is %lld", cur->start );
294 pv->pts_offset = cur->start;
297 /* Check for PTS jumps over 0.5 second */
298 if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||
299 next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )
301 hb_log( "PTS discontinuity (%lld, %lld)",
302 cur->start, next->start );
304 /* Trash all subtitles */
307 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
309 hb_buffer_close( &sub );
313 /* Trash current picture */
314 /* Also, make sure we don't trash a chapter break */
315 chap_break = cur->new_chap;
316 hb_buffer_close( &cur );
317 pv->cur = cur = hb_fifo_get( job->fifo_raw );
318 cur->new_chap |= chap_break; // Don't stomp existing chapter breaks
320 /* Calculate new offset */
321 pv->pts_offset_old = pv->pts_offset;
322 pv->pts_offset = cur->start -
323 pv->count_frames * pv->job->vrate_base / 300;
327 /* Look for a subtitle for this frame */
331 while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
333 /* If two subtitles overlap, make the first one stop
334 when the second one starts */
335 sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
336 if( sub2 && sub->stop > sub2->start )
337 sub->stop = sub2->start;
339 if( sub->stop > cur->start )
342 /* The subtitle is older than this picture, trash it */
343 sub = hb_fifo_get( pv->subtitle->fifo_raw );
344 hb_buffer_close( &sub );
347 /* If we have subtitles left in the fifo, check if we should
348 apply the first one to the current frame or if we should
350 if( sub && sub->start > cur->start )
356 /* The PTS of the frame we are expecting now */
357 pts_expected = pv->pts_offset +
358 pv->count_frames * pv->job->vrate_base / 300;
360 if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
361 next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
363 /* The current frame is too old but the next one matches,
365 /* Also, make sure we don't trash a chapter break */
366 chap_break = cur->new_chap;
367 hb_buffer_close( &cur );
368 pv->cur = cur = hb_fifo_get( job->fifo_raw );
369 cur->new_chap |= chap_break; // Make sure we don't stomp the existing one.
374 if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
376 /* We'll need the current frame more than one time. Make a
377 copy of it and keep it */
378 buf_tmp = hb_buffer_init( cur->size );
379 memcpy( buf_tmp->data, cur->data, cur->size );
383 /* The frame has the expected date and won't have to be
384 duplicated, just put it through */
386 pv->cur = cur = hb_fifo_get( job->fifo_raw );
389 /* Replace those MPEG-2 dates with our dates */
390 buf_tmp->start = (uint64_t) pv->count_frames *
391 pv->job->vrate_base / 300;
392 buf_tmp->stop = (uint64_t) ( pv->count_frames + 1 ) *
393 pv->job->vrate_base / 300;
395 /* If we have a subtitle for this picture, copy it */
396 /* FIXME: we should avoid this memcpy */
399 buf_tmp->sub = hb_buffer_init( sub->size );
400 buf_tmp->sub->x = sub->x;
401 buf_tmp->sub->y = sub->y;
402 buf_tmp->sub->width = sub->width;
403 buf_tmp->sub->height = sub->height;
404 memcpy( buf_tmp->sub->data, sub->data, sub->size );
407 /* Push the frame to the renderer */
408 hb_fifo_push( job->fifo_sync, buf_tmp );
413 /* Make sure we won't get more frames then expected */
414 if( pv->count_frames >= pv->count_frames_max )
416 hb_log( "sync: got %lld frames", pv->count_frames );
419 // Drop an empty buffer into our output to ensure that things
420 // get flushed all the way out.
421 buf_tmp = hb_buffer_init(0); // Empty end buffer
422 hb_fifo_push( job->fifo_sync, buf_tmp );
431 /***********************************************************************
433 ***********************************************************************
435 **********************************************************************/
436 static void SyncAudio( hb_work_object_t * w, int i )
438 hb_work_private_t * pv = w->private_data;
442 hb_sync_audio_t * sync;
447 int64_t pts_expected;
451 sync = &pv->sync_audio[i];
454 if( job->acodec & HB_ACODEC_AC3 )
456 fifo = audio->fifo_out;
461 fifo = audio->fifo_sync;
465 while( !hb_fifo_is_full( fifo ) &&
466 ( buf = hb_fifo_see( audio->fifo_raw ) ) )
468 /* The PTS of the samples we are expecting now */
469 pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
471 if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
472 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
473 pv->pts_offset_old > INT64_MIN )
475 /* There has been a PTS discontinuity, and this frame might
476 be from before the discontinuity */
477 pts_expected = pv->pts_offset_old + sync->count_frames *
480 if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
481 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
483 /* There is really nothing we can do with it */
484 buf = hb_fifo_get( audio->fifo_raw );
485 hb_buffer_close( &buf );
489 /* Use the older offset */
490 start = pts_expected - pv->pts_offset_old;
494 start = pts_expected - pv->pts_offset;
497 /* Tolerance: 100 ms */
498 if( buf->start < pts_expected - 9000 )
500 /* Late audio, trash it */
501 hb_log( "sync: trashing late audio" );
502 buf = hb_fifo_get( audio->fifo_raw );
503 hb_buffer_close( &buf );
506 else if( buf->start > pts_expected + 9000 )
508 /* Missing audio, send a frame of silence */
509 InsertSilence( w, i );
513 if( job->acodec & HB_ACODEC_AC3 )
515 buf = hb_fifo_get( audio->fifo_raw );
517 buf->stop = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
519 sync->count_frames += AC3_SAMPLES_PER_FRAME;
523 hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
525 int count_in, count_out;
527 count_in = buf_raw->size / HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) / sizeof( float );
528 count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
529 if( buf->start < pts_expected - 1500 )
531 else if( buf->start > pts_expected + 1500 )
534 sync->data.data_in = (float *) buf_raw->data;
535 sync->data.input_frames = count_in;
536 sync->data.output_frames = count_out;
538 sync->data.src_ratio = (double) sync->data.output_frames /
539 (double) sync->data.input_frames;
541 buf = hb_buffer_init( sync->data.output_frames * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *
543 sync->data.data_out = (float *) buf->data;
544 if( src_process( sync->state, &sync->data ) )
546 /* XXX If this happens, we're screwed */
547 hb_log( "sync: src_process failed" );
549 hb_buffer_close( &buf_raw );
551 buf->size = sync->data.output_frames_gen * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) * sizeof( float );
553 /* Set dates for resampled data */
555 buf->stop = start + sync->data.output_frames_gen *
558 sync->count_frames += sync->data.output_frames_gen;
562 hb_fifo_push( fifo, buf );
565 if( NeedSilence( w, audio ) )
567 InsertSilence( w, i );
571 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
573 hb_work_private_t * pv = w->private_data;
574 hb_job_t * job = pv->job;
576 if( hb_fifo_size( audio->fifo_in ) ||
577 hb_fifo_size( audio->fifo_raw ) ||
578 hb_fifo_size( audio->fifo_sync ) ||
579 hb_fifo_size( audio->fifo_out ) )
581 /* We have some audio, we are fine */
585 /* No audio left in fifos */
587 if( hb_thread_has_exited( job->reader ) )
589 /* We might miss some audio to complete encoding and muxing
594 if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
595 hb_fifo_is_full( job->fifo_raw ) &&
596 hb_fifo_is_full( job->fifo_sync ) &&
597 hb_fifo_is_full( job->fifo_render ) &&
598 hb_fifo_is_full( job->fifo_mpeg4 ) )
600 /* Too much video and no audio, oh-oh */
607 static void InsertSilence( hb_work_object_t * w, int i )
609 hb_work_private_t * pv = w->private_data;
611 hb_sync_audio_t * sync;
615 sync = &pv->sync_audio[i];
617 if( job->acodec & HB_ACODEC_AC3 )
619 buf = hb_buffer_init( sync->ac3_size );
620 buf->start = sync->count_frames * 90000 / sync->audio->rate;
621 buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
623 memcpy( buf->data, sync->ac3_buf, buf->size );
625 hb_log( "sync: adding a silent AC-3 frame for track %x",
627 hb_fifo_push( sync->audio->fifo_out, buf );
629 sync->count_frames += AC3_SAMPLES_PER_FRAME;
634 buf = hb_buffer_init( HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) * job->arate / 20 *
636 buf->start = sync->count_frames * 90000 / job->arate;
637 buf->stop = buf->start + 90000 / 20;
638 memset( buf->data, 0, buf->size );
640 hb_log( "sync: adding 50 ms of silence for track %x",
642 hb_fifo_push( sync->audio->fifo_sync, buf );
644 sync->count_frames += job->arate / 20;
648 static void UpdateState( hb_work_object_t * w )
650 hb_work_private_t * pv = w->private_data;
653 if( !pv->count_frames )
655 pv->st_first = hb_get_date();
659 if( hb_get_date() > pv->st_dates[3] + 1000 )
661 memmove( &pv->st_dates[0], &pv->st_dates[1],
662 3 * sizeof( uint64_t ) );
663 memmove( &pv->st_counts[0], &pv->st_counts[1],
664 3 * sizeof( uint64_t ) );
665 pv->st_dates[3] = hb_get_date();
666 pv->st_counts[3] = pv->count_frames;
669 #define p state.param.working
670 state.state = HB_STATE_WORKING;
671 p.progress = (float) pv->count_frames / (float) pv->count_frames_max;
672 if( p.progress > 1.0 )
676 p.rate_cur = 1000.0 *
677 (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
678 (float) ( pv->st_dates[3] - pv->st_dates[0] );
679 if( hb_get_date() > pv->st_first + 4000 )
682 p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
683 (float) ( pv->st_dates[3] - pv->st_first );
684 eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
686 p.hours = eta / 3600;
687 p.minutes = ( eta % 3600 ) / 60;
688 p.seconds = eta % 60;
699 hb_set_state( pv->job->h, &state );