OSDN Git Service

Merge the 5.1 branch into the trunk.
[handbrake-jp/handbrake-jp-git.git] / libhb / sync.c
1 /* $Id: sync.c,v 1.38 2005/04/14 21:57:58 titer Exp $
2
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. */
6
7 #include "hb.h"
8
9 #include "samplerate.h"
10 #include "ffmpeg/avcodec.h"
11
12 #ifdef INT64_MIN
13 #undef INT64_MIN /* Because it isn't defined correctly in Zeta */
14 #endif
15 #define INT64_MIN (-9223372036854775807LL-1)
16
17 #define AC3_SAMPLES_PER_FRAME 1536
18
19 typedef struct
20 {
21     hb_audio_t * audio;
22     int64_t      count_frames;
23     
24     /* Raw */
25     SRC_STATE  * state;
26     SRC_DATA     data;
27
28     /* AC-3 */
29     int          ac3_size;
30     uint8_t    * ac3_buf;
31
32 } hb_sync_audio_t;
33
34 struct hb_work_private_s
35 {
36     hb_job_t * job;
37     int        done;
38
39     /* Video */
40     hb_subtitle_t * subtitle;
41     int64_t pts_offset;
42     int64_t pts_offset_old;
43     int64_t count_frames;
44     int64_t count_frames_max;
45     hb_buffer_t * cur; /* The next picture to process */
46
47     /* Audio */
48     hb_sync_audio_t sync_audio[8];
49
50     /* Statistics */
51     uint64_t st_counts[4];
52     uint64_t st_dates[4];
53     uint64_t st_first;
54 };
55
56 /***********************************************************************
57  * Local prototypes
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 );
65
66 /***********************************************************************
67  * hb_work_sync_init
68  ***********************************************************************
69  * Initialize the work object
70  **********************************************************************/
71 int syncInit( hb_work_object_t * w, hb_job_t * job )
72 {
73     hb_title_t       * title = job->title;
74     hb_chapter_t     * chapter;
75     int                i;
76     uint64_t           duration;
77     hb_work_private_t * pv;
78
79     pv = calloc( 1, sizeof( hb_work_private_t ) );
80     w->private_data = pv;
81
82     pv->job            = job;
83     pv->pts_offset     = INT64_MIN;
84     pv->pts_offset_old = INT64_MIN;
85     pv->count_frames   = 0;
86
87     /* Calculate how many video frames we are expecting */
88     duration = 0;
89     for( i = job->chapter_start; i <= job->chapter_end; i++ )
90     {
91         chapter   = hb_list_item( title->list_chapter, i - 1 );
92         duration += chapter->duration;
93     }                                                                           
94     duration += 90000;
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;
97
98     hb_log( "sync: expecting %lld video frames", pv->count_frames_max );
99
100     /* Initialize libsamplerate for every audio track we have */
101     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
102     {
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 );
106     }
107
108     /* Get subtitle info, if any */
109     pv->subtitle = hb_list_item( title->list_subtitle, 0 );
110
111     return 0;
112 }
113
114 /***********************************************************************
115  * Close
116  ***********************************************************************
117  *
118  **********************************************************************/
119 void syncClose( hb_work_object_t * w )
120 {
121     hb_work_private_t * pv = w->private_data;
122     hb_job_t          * job   = pv->job;
123     hb_title_t        * title = job->title;
124     
125     int i;
126
127     if( pv->cur ) hb_buffer_close( &pv->cur );
128
129     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
130     {
131         if( job->acodec & HB_ACODEC_AC3 )
132         {
133             free( pv->sync_audio[i].ac3_buf );
134         }
135         else
136         {
137             src_delete( pv->sync_audio[i].state );
138         }
139     }
140 }
141
142 /***********************************************************************
143  * Work
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 )
149 {
150     hb_work_private_t * pv = w->private_data;
151     int i;
152
153     /* If we ever got a video frame, handle audio now */
154     if( pv->pts_offset != INT64_MIN )
155     {
156         for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
157         {
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 );
161         }
162     }
163
164     /* Handle video */
165     return SyncVideo( w );
166 }
167
168 hb_work_object_t hb_sync =
169 {
170     WORK_SYNC,
171     "Synchronization",
172     syncInit,
173     syncWork,
174     syncClose
175 };
176
177 static void InitAudio( hb_work_object_t * w, int i, int channelsused )
178 {
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;
183
184     sync        = &pv->sync_audio[i];
185     sync->audio = hb_list_item( title->list_audio, i );
186
187     if( job->acodec & HB_ACODEC_AC3 )
188     {
189         /* Have a silent AC-3 frame ready in case we have to fill a
190            gap */
191         AVCodec        * codec;
192         AVCodecContext * c;
193         short          * zeros;
194
195         codec = avcodec_find_encoder( CODEC_ID_AC3 );
196         c     = avcodec_alloc_context();
197
198         c->bit_rate    = sync->audio->bitrate;
199         c->sample_rate = sync->audio->rate;
200         c->channels    = sync->audio->channels;
201
202         if( avcodec_open( c, codec ) < 0 )
203         {
204             hb_log( "sync: avcodec_open failed" );
205             return;
206         }
207
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 );
213
214         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
215                                   zeros ) != sync->ac3_size )
216         {
217             hb_log( "sync: avcodec_encode_audio failed" );
218         }
219         
220         free( zeros );
221         avcodec_close( c );
222         av_free( c );
223     }
224     else
225     {
226         /* Initialize libsamplerate */
227         int error;
228         sync->state             = src_new( SRC_LINEAR, channelsused, &error );
229         sync->data.end_of_input = 0;
230     }
231 }
232
233
234
235 #define PTS_DISCONTINUITY_TOLERANCE 90000
236
237 /***********************************************************************
238  * SyncVideo
239  ***********************************************************************
240  * 
241  **********************************************************************/
242 static int SyncVideo( hb_work_object_t * w )
243 {
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;
248
249     if( pv->done )
250     {
251         return HB_WORK_DONE;
252     }
253
254     if( hb_thread_has_exited( job->reader ) &&
255         !hb_fifo_size( job->fifo_mpeg2 ) &&
256         !hb_fifo_size( job->fifo_raw ) )
257     {
258         /* All video data has been processed already, we won't get
259            more */
260         hb_log( "sync: got %lld frames, %lld expected",
261                 pv->count_frames, pv->count_frames_max );
262         pv->done = 1;
263         return HB_WORK_DONE;
264     }
265
266     if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
267     {
268         /* We haven't even got a frame yet */
269         return HB_WORK_OK;
270     }
271     cur = pv->cur;
272
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 ) ) )
279     {
280         hb_buffer_t * buf_tmp;
281
282         if( pv->pts_offset == INT64_MIN )
283         {
284             /* This is our first frame */
285             hb_log( "sync: first pts is %lld", cur->start );
286             pv->pts_offset = cur->start;
287         }
288
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 )
292         {
293             hb_log( "PTS discontinuity (%lld, %lld)",
294                     cur->start, next->start );
295             
296             /* Trash all subtitles */
297             if( pv->subtitle )
298             {
299                 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
300                 {
301                     hb_buffer_close( &sub );
302                 }
303             }
304
305             /* Trash current picture */
306             hb_buffer_close( &cur );
307             pv->cur = cur = hb_fifo_get( job->fifo_raw );
308
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;
313             continue;
314         }
315
316         /* Look for a subtitle for this frame */
317         if( pv->subtitle )
318         {
319             hb_buffer_t * sub2;
320             while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
321             {
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;
327
328                 if( sub->stop > cur->start )
329                     break;
330
331                 /* The subtitle is older than this picture, trash it */
332                 sub = hb_fifo_get( pv->subtitle->fifo_raw );
333                 hb_buffer_close( &sub );
334             }
335
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
338                keep it for later */
339             if( sub && sub->start > cur->start )
340             {
341                 sub = NULL;
342             }
343         }
344
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;
348
349         if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
350             next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
351         {
352             /* The current frame is too old but the next one matches,
353                let's trash */
354             hb_buffer_close( &cur );
355             pv->cur = cur = hb_fifo_get( job->fifo_raw );
356             continue;
357         }
358
359         if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
360         {
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 );
365         }
366         else
367         {
368             /* The frame has the expected date and won't have to be
369                duplicated, just put it through */
370             buf_tmp = cur;
371             pv->cur = cur = hb_fifo_get( job->fifo_raw );
372         }
373
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;
379
380         /* If we have a subtitle for this picture, copy it */
381         /* FIXME: we should avoid this memcpy */
382         if( sub )
383         {
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 );
390         }
391
392         /* Push the frame to the renderer */
393         hb_fifo_push( job->fifo_sync, buf_tmp );
394
395         /* Update UI */
396         UpdateState( w );
397
398         /* Make sure we won't get more frames then expected */
399         if( pv->count_frames >= pv->count_frames_max )
400         {
401             hb_log( "sync: got %lld frames", pv->count_frames );
402             pv->done = 1;
403             break;
404         }
405     }
406
407     return HB_WORK_OK;
408 }
409
410 /***********************************************************************
411  * SyncAudio
412  ***********************************************************************
413  * 
414  **********************************************************************/
415 static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
416 {
417     hb_work_private_t * pv = w->private_data;
418     hb_job_t        * job;
419     hb_audio_t      * audio;
420     hb_buffer_t     * buf;
421     hb_sync_audio_t * sync;
422
423     hb_fifo_t       * fifo;
424     int               rate;
425
426     int64_t           pts_expected;
427     int64_t           start;
428
429     job    = pv->job;
430     sync   = &pv->sync_audio[i];
431     audio  = sync->audio;
432
433     if( job->acodec & HB_ACODEC_AC3 )
434     {
435         fifo = audio->fifo_out;
436         rate = audio->rate;
437     }
438     else
439     {
440         fifo = audio->fifo_sync;
441         rate = job->arate;
442     }
443
444     while( !hb_fifo_is_full( fifo ) &&
445            ( buf = hb_fifo_see( audio->fifo_raw ) ) )
446     {
447         /* The PTS of the samples we are expecting now */
448         pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
449
450         if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
451               buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
452             pv->pts_offset_old > INT64_MIN )
453         {
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 *
457                 90000 / rate;
458
459             if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
460                 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
461             {
462                 /* There is really nothing we can do with it */
463                 buf = hb_fifo_get( audio->fifo_raw );
464                 hb_buffer_close( &buf );
465                 continue;
466             }
467
468             /* Use the older offset */
469             start = pts_expected - pv->pts_offset_old;
470         }
471         else
472         {
473             start = pts_expected - pv->pts_offset;
474         }
475
476         /* Tolerance: 100 ms */
477         if( buf->start < pts_expected - 9000 )
478         {
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 );
483             continue;
484         }
485         else if( buf->start > pts_expected + 9000 )
486         {
487             /* Missing audio, send a frame of silence */
488             InsertSilence( w, i, channelsused );
489             continue;
490         }
491
492         if( job->acodec & HB_ACODEC_AC3 )
493         {
494             buf        = hb_fifo_get( audio->fifo_raw );
495             buf->start = start;
496             buf->stop  = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
497
498             sync->count_frames += AC3_SAMPLES_PER_FRAME;
499         }
500         else
501         {
502             hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
503
504             int count_in, count_out;
505
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 )
509                 count_out--;
510             else if( buf->start > pts_expected + 1500 )
511                 count_out++;
512
513             sync->data.data_in      = (float *) buf_raw->data;
514             sync->data.input_frames = count_in;
515             sync->data.output_frames = count_out;
516
517             sync->data.src_ratio = (double) sync->data.output_frames /
518                                    (double) sync->data.input_frames;
519
520             buf = hb_buffer_init( sync->data.output_frames * channelsused *
521                                   sizeof( float ) );
522             sync->data.data_out = (float *) buf->data;
523             if( src_process( sync->state, &sync->data ) )
524             {
525                 /* XXX If this happens, we're screwed */
526                 hb_log( "sync: src_process failed" );
527             }
528             hb_buffer_close( &buf_raw );
529
530             buf->size = sync->data.output_frames_gen * channelsused * sizeof( float );
531
532             /* Set dates for resampled data */
533             buf->start = start;
534             buf->stop  = start + sync->data.output_frames_gen *
535                             90000 / job->arate;
536
537             sync->count_frames += sync->data.output_frames_gen;
538         }
539
540         buf->key = 1;
541         hb_fifo_push( fifo, buf );
542     }
543
544     if( NeedSilence( w, audio ) )
545     {
546         InsertSilence( w, i, channelsused );
547     }
548 }
549
550 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
551 {
552     hb_work_private_t * pv = w->private_data;
553     hb_job_t * job = pv->job;
554
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 ) )
559     {
560         /* We have some audio, we are fine */
561         return 0;
562     }
563
564     /* No audio left in fifos */
565
566     if( hb_thread_has_exited( job->reader ) )
567     {
568         /* We might miss some audio to complete encoding and muxing
569            the video track */
570         return 1;
571     }
572
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 ) )
578     {
579         /* Too much video and no audio, oh-oh */
580         return 1;
581     }
582
583     return 0;
584 }
585
586 static void InsertSilence( hb_work_object_t * w, int i, int channelsused )
587 {
588     hb_work_private_t * pv = w->private_data;
589     hb_job_t        * job;
590     hb_sync_audio_t * sync;
591     hb_buffer_t     * buf;
592
593     job    = pv->job;
594     sync   = &pv->sync_audio[i];
595
596     if( job->acodec & HB_ACODEC_AC3 )
597     {
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 /
601                      sync->audio->rate;
602         memcpy( buf->data, sync->ac3_buf, buf->size );
603
604         hb_log( "sync: adding a silent AC-3 frame for track %x",
605                 sync->audio->id );
606         hb_fifo_push( sync->audio->fifo_out, buf );
607
608         sync->count_frames += AC3_SAMPLES_PER_FRAME;
609
610     }
611     else
612     {
613         buf        = hb_buffer_init( channelsused * job->arate / 20 *
614                                      sizeof( float ) );
615         buf->start = sync->count_frames * 90000 / job->arate;
616         buf->stop  = buf->start + 90000 / 20;
617         memset( buf->data, 0, buf->size );
618
619         hb_log( "sync: adding 50 ms of silence for track %x",
620                 sync->audio->id );
621         hb_fifo_push( sync->audio->fifo_sync, buf );
622
623         sync->count_frames += job->arate / 20;
624     }
625 }
626
627 static void UpdateState( hb_work_object_t * w )
628 {
629     hb_work_private_t * pv = w->private_data;
630     hb_state_t state;
631
632     if( !pv->count_frames )
633     {
634         pv->st_first = hb_get_date();
635     }
636     pv->count_frames++;
637
638     if( hb_get_date() > pv->st_dates[3] + 1000 )
639     {
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;
646     } 
647
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 )
652     {
653         p.progress = 1.0; 
654     }
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 )
659     {
660         int eta;
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] ) /
664             p.rate_avg;
665         p.hours   = eta / 3600;
666         p.minutes = ( eta % 3600 ) / 60;
667         p.seconds = eta % 60;
668     }
669     else
670     {
671         p.rate_avg = 0.0;
672         p.hours    = -1;
673         p.minutes  = -1;
674         p.seconds  = -1;
675     }
676 #undef p
677
678     hb_set_state( pv->job->h, &state );
679 }