OSDN Git Service

Softer resampling when audio dates are messed up (fix for LPCM issues).
[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_object_s
35 {
36     HB_WORK_COMMON;
37
38     hb_job_t * job;
39     int        done;
40
41     /* Video */
42     hb_subtitle_t * subtitle;
43     int64_t pts_offset;
44     int64_t pts_offset_old;
45     int64_t count_frames;
46     int64_t count_frames_max;
47     hb_buffer_t * cur; /* The next picture to process */
48
49     /* Audio */
50     hb_sync_audio_t sync_audio[8];
51
52     /* Statistics */
53     uint64_t st_counts[4];
54     uint64_t st_dates[4];
55     uint64_t st_first;
56 };
57
58 /***********************************************************************
59  * Local prototypes
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 );
70
71 /***********************************************************************
72  * hb_work_sync_init
73  ***********************************************************************
74  * Initialize the work object
75  **********************************************************************/
76 hb_work_object_t * hb_work_sync_init( hb_job_t * job )
77 {
78     hb_work_object_t * w;
79     hb_title_t       * title = job->title;
80     hb_chapter_t     * chapter;
81     int                i;
82     uint64_t           duration;
83
84     w        = calloc( sizeof( hb_work_object_t ), 1 );
85     w->name  = strdup( "Synchronization" );
86     w->work  = Work;
87     w->close = Close;
88
89     w->job            = job;
90     w->pts_offset     = INT64_MIN;
91     w->pts_offset_old = INT64_MIN;
92     w->count_frames   = 0;
93
94     /* Calculate how many video frames we are expecting */
95     duration = 0;
96     for( i = job->chapter_start; i <= job->chapter_end; i++ )
97     {
98         chapter   = hb_list_item( title->list_chapter, i - 1 );
99         duration += chapter->duration;
100     }                                                                           
101     duration += 90000;
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;
104
105     hb_log( "sync: expecting %lld video frames", w->count_frames_max );
106
107     /* Initialize libsamplerate for every audio track we have */
108     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
109     {
110         InitAudio( w, i );
111     }
112
113     /* Get subtitle info, if any */
114     w->subtitle = hb_list_item( title->list_subtitle, 0 );
115
116     return w;
117 }
118
119 static void InitAudio( hb_work_object_t * w, int i )
120 {
121     hb_job_t        * job   = w->job;
122     hb_title_t      * title = job->title;
123     hb_sync_audio_t * sync;
124
125     sync        = &w->sync_audio[i];
126     sync->audio = hb_list_item( title->list_audio, i );
127
128     if( job->acodec & HB_ACODEC_AC3 )
129     {
130         /* Have a silent AC-3 frame ready in case we have to fill a
131            gap */
132         AVCodec        * codec;
133         AVCodecContext * c;
134         short          * zeros;
135
136         codec = avcodec_find_encoder( CODEC_ID_AC3 );
137         c     = avcodec_alloc_context();
138
139         c->bit_rate    = sync->audio->bitrate;
140         c->sample_rate = sync->audio->rate;
141         c->channels    = sync->audio->channels;
142
143         if( avcodec_open( c, codec ) < 0 )
144         {
145             hb_log( "sync: avcodec_open failed" );
146             return;
147         }
148
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 );
154
155         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
156                                   zeros ) != sync->ac3_size )
157         {
158             hb_log( "sync: avcodec_encode_audio failed" );
159         }
160         
161         free( zeros );
162         avcodec_close( c );
163         av_free( c );
164     }
165     else
166     {
167         /* Initialize libsamplerate */
168         int error;
169         sync->state             = src_new( SRC_LINEAR, 2, &error );
170         sync->data.end_of_input = 0;
171     }
172 }
173
174 /***********************************************************************
175  * Close
176  ***********************************************************************
177  *
178  **********************************************************************/
179 static void Close( hb_work_object_t ** _w )
180 {
181     hb_work_object_t * w     = *_w;
182     hb_job_t         * job   = w->job;
183     hb_title_t       * title = job->title;
184     
185     int i;
186
187     if( w->cur ) hb_buffer_close( &w->cur );
188
189     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
190     {
191         if( job->acodec & HB_ACODEC_AC3 )
192         {
193             free( w->sync_audio[i].ac3_buf );
194         }
195         else
196         {
197             src_delete( w->sync_audio[i].state );
198         }
199     }
200
201     free( w->name );    
202     free( w );
203     *_w = NULL;
204 }
205
206 /***********************************************************************
207  * Work
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 )
213 {
214     int i;
215
216     /* If we ever got a video frame, handle audio now */
217     if( w->pts_offset != INT64_MIN )
218     {
219         for( i = 0; i < hb_list_count( w->job->title->list_audio ); i++ )
220         {
221             SyncAudio( w, i );
222         }
223     }
224
225     /* Handle video */
226     return SyncVideo( w );
227 }
228
229 #define PTS_DISCONTINUITY_TOLERANCE 90000
230
231 /***********************************************************************
232  * SyncVideo
233  ***********************************************************************
234  * 
235  **********************************************************************/
236 static int SyncVideo( hb_work_object_t * w )
237 {
238     hb_buffer_t * cur, * next, * sub = NULL;
239     hb_job_t * job = w->job;
240     int64_t pts_expected;
241
242     if( w->done )
243     {
244         return HB_WORK_DONE;
245     }
246
247     if( hb_thread_has_exited( job->reader ) &&
248         !hb_fifo_size( job->fifo_mpeg2 ) &&
249         !hb_fifo_size( job->fifo_raw ) )
250     {
251         /* All video data has been processed already, we won't get
252            more */
253         hb_log( "sync: got %lld frames, %lld expected",
254                 w->count_frames, w->count_frames_max );
255         w->done = 1;
256         return HB_WORK_DONE;
257     }
258
259     if( !w->cur && !( w->cur = hb_fifo_get( job->fifo_raw ) ) )
260     {
261         /* We haven't even got a frame yet */
262         return HB_WORK_OK;
263     }
264     cur = w->cur;
265
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 ) ) )
272     {
273         hb_buffer_t * buf_tmp;
274
275         if( w->pts_offset == INT64_MIN )
276         {
277             /* This is our first frame */
278             hb_log( "sync: first pts is %lld", cur->start );
279             w->pts_offset = cur->start;
280         }
281
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 )
285         {
286             hb_log( "PTS discontinuity (%lld, %lld)",
287                     cur->start, next->start );
288             
289             /* Trash all subtitles */
290             if( w->subtitle )
291             {
292                 while( ( sub = hb_fifo_get( w->subtitle->fifo_raw ) ) )
293                 {
294                     hb_buffer_close( &sub );
295                 }
296             }
297
298             /* Trash current picture */
299             hb_buffer_close( &cur );
300             w->cur = cur = hb_fifo_get( job->fifo_raw );
301
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;
306             continue;
307         }
308
309         /* Look for a subtitle for this frame */
310         if( w->subtitle )
311         {
312             hb_buffer_t * sub2;
313             while( ( sub = hb_fifo_see( w->subtitle->fifo_raw ) ) )
314             {
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;
320
321                 if( sub->stop > cur->start )
322                     break;
323
324                 /* The subtitle is older than this picture, trash it */
325                 sub = hb_fifo_get( w->subtitle->fifo_raw );
326                 hb_buffer_close( &sub );
327             }
328
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
331                keep it for later */
332             if( sub && sub->start > cur->start )
333             {
334                 sub = NULL;
335             }
336         }
337
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;
341
342         if( cur->start < pts_expected - w->job->vrate_base / 300 / 2 &&
343             next->start < pts_expected + w->job->vrate_base / 300 / 2 )
344         {
345             /* The current frame is too old but the next one matches,
346                let's trash */
347             hb_buffer_close( &cur );
348             w->cur = cur = hb_fifo_get( job->fifo_raw );
349             continue;
350         }
351
352         if( next->start > pts_expected + 3 * w->job->vrate_base / 300 / 2 )
353         {
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 );
358         }
359         else
360         {
361             /* The frame has the expected date and won't have to be
362                duplicated, just put it through */
363             buf_tmp = cur;
364             w->cur = cur = hb_fifo_get( job->fifo_raw );
365         }
366
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;
372
373         /* If we have a subtitle for this picture, copy it */
374         /* FIXME: we should avoid this memcpy */
375         if( sub )
376         {
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 );
383         }
384
385         /* Push the frame to the renderer */
386         hb_fifo_push( job->fifo_sync, buf_tmp );
387
388         /* Update UI */
389         UpdateState( w );
390
391         /* Make sure we won't get more frames then expected */
392         if( w->count_frames >= w->count_frames_max )
393         {
394             hb_log( "sync: got %lld frames", w->count_frames );
395             w->done = 1;
396             break;
397         }
398     }
399
400     return HB_WORK_OK;
401 }
402
403 /***********************************************************************
404  * SyncAudio
405  ***********************************************************************
406  * 
407  **********************************************************************/
408 static void SyncAudio( hb_work_object_t * w, int i )
409 {
410     hb_job_t        * job;
411     hb_audio_t      * audio;
412     hb_buffer_t     * buf;
413     hb_sync_audio_t * sync;
414
415     hb_fifo_t       * fifo;
416     int               rate;
417
418     int64_t           pts_expected;
419     int64_t           start;
420
421     job    = w->job;
422     sync   = &w->sync_audio[i];
423     audio  = sync->audio;
424
425     if( job->acodec & HB_ACODEC_AC3 )
426     {
427         fifo = audio->fifo_out;
428         rate = audio->rate;
429     }
430     else
431     {
432         fifo = audio->fifo_sync;
433         rate = job->arate;
434     }
435
436     while( !hb_fifo_is_full( fifo ) &&
437            ( buf = hb_fifo_see( audio->fifo_raw ) ) )
438     {
439         /* The PTS of the samples we are expecting now */
440         pts_expected = w->pts_offset + sync->count_frames * 90000 / rate;
441
442         if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
443               buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
444             w->pts_offset_old > INT64_MIN )
445         {
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 *
449                 90000 / rate;
450
451             if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
452                 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
453             {
454                 /* There is really nothing we can do with it */
455                 buf = hb_fifo_get( audio->fifo_raw );
456                 hb_buffer_close( &buf );
457                 continue;
458             }
459
460             /* Use the older offset */
461             start = pts_expected - w->pts_offset_old;
462         }
463         else
464         {
465             start = pts_expected - w->pts_offset;
466         }
467
468         /* Tolerance: 100 ms */
469         if( buf->start < pts_expected - 9000 )
470         {
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 );
475             continue;
476         }
477         else if( buf->start > pts_expected + 9000 )
478         {
479             /* Missing audio, send a frame of silence */
480             InsertSilence( w, i );
481             continue;
482         }
483
484         if( job->acodec & HB_ACODEC_AC3 )
485         {
486             buf        = hb_fifo_get( audio->fifo_raw );
487             buf->start = start;
488             buf->stop  = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
489
490             sync->count_frames += AC3_SAMPLES_PER_FRAME;
491         }
492         else
493         {
494             hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
495
496             int count_in, count_out;
497
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 )
501                 count_out--;
502             else if( buf->start > pts_expected + 1500 )
503                 count_out++;
504
505             sync->data.data_in      = (float *) buf_raw->data;
506             sync->data.input_frames = count_in;
507             sync->data.output_frames = count_out;
508
509             sync->data.src_ratio = (double) sync->data.output_frames /
510                                    (double) sync->data.input_frames;
511
512             buf = hb_buffer_init( sync->data.output_frames * 2 *
513                                   sizeof( float ) );
514             sync->data.data_out = (float *) buf->data;
515             if( src_process( sync->state, &sync->data ) )
516             {
517                 /* XXX If this happens, we're screwed */
518                 hb_log( "sync: src_process failed" );
519             }
520             hb_buffer_close( &buf_raw );
521
522             buf->size = sync->data.output_frames_gen * 2 * sizeof( float );
523
524             /* Set dates for resampled data */
525             buf->start = start;
526             buf->stop  = start + sync->data.output_frames_gen *
527                             90000 / job->arate;
528
529             sync->count_frames += sync->data.output_frames_gen;
530         }
531
532         buf->key = 1;
533         hb_fifo_push( fifo, buf );
534     }
535
536     if( NeedSilence( w, audio ) )
537     {
538         InsertSilence( w, i );
539     }
540 }
541
542 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
543 {
544     hb_job_t * job = w->job;
545
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 ) )
550     {
551         /* We have some audio, we are fine */
552         return 0;
553     }
554
555     /* No audio left in fifos */
556
557     if( hb_thread_has_exited( job->reader ) )
558     {
559         /* We might miss some audio to complete encoding and muxing
560            the video track */
561         return 1;
562     }
563
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 ) )
569     {
570         /* Too much video and no audio, oh-oh */
571         return 1;
572     }
573
574     return 0;
575 }
576
577 static void InsertSilence( hb_work_object_t * w, int i )
578 {
579     hb_job_t        * job;
580     hb_sync_audio_t * sync;
581     hb_buffer_t     * buf;
582
583     job    = w->job;
584     sync   = &w->sync_audio[i];
585
586     if( job->acodec & HB_ACODEC_AC3 )
587     {
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 /
591                      sync->audio->rate;
592         memcpy( buf->data, sync->ac3_buf, buf->size );
593
594         hb_log( "sync: adding a silent AC-3 frame for track %x",
595                 sync->audio->id );
596         hb_fifo_push( sync->audio->fifo_out, buf );
597
598         sync->count_frames += AC3_SAMPLES_PER_FRAME;
599
600     }
601     else
602     {
603         buf        = hb_buffer_init( 2 * job->arate / 20 *
604                                      sizeof( float ) );
605         buf->start = sync->count_frames * 90000 / job->arate;
606         buf->stop  = buf->start + 90000 / 20;
607         memset( buf->data, 0, buf->size );
608
609         hb_log( "sync: adding 50 ms of silence for track %x",
610                 sync->audio->id );
611         hb_fifo_push( sync->audio->fifo_sync, buf );
612
613         sync->count_frames += job->arate / 20;
614     }
615 }
616
617 static void UpdateState( hb_work_object_t * w )
618 {
619     hb_state_t state;
620
621     if( !w->count_frames )
622     {
623         w->st_first = hb_get_date();
624     }
625     w->count_frames++;
626
627     if( hb_get_date() > w->st_dates[3] + 1000 )
628     {
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;
635     } 
636
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 )
641     {
642         p.progress = 1.0; 
643     }
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 )
648     {
649         int eta;
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] ) /
653             p.rate_avg;
654         p.hours   = eta / 3600;
655         p.minutes = ( eta % 3600 ) / 60;
656         p.seconds = eta % 60;
657     }
658     else
659     {
660         p.rate_avg = 0.0;
661         p.hours    = -1;
662         p.minutes  = -1;
663         p.seconds  = -1;
664     }
665 #undef p
666
667     hb_set_state( w->job->h, &state );
668 }