OSDN Git Service

Credit Nyx's b-frame work
[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 );
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 );
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         InitAudio( w, i );
104     }
105
106     /* Get subtitle info, if any */
107     pv->subtitle = hb_list_item( title->list_subtitle, 0 );
108
109     return 0;
110 }
111
112 /***********************************************************************
113  * Close
114  ***********************************************************************
115  *
116  **********************************************************************/
117 void syncClose( hb_work_object_t * w )
118 {
119     hb_work_private_t * pv = w->private_data;
120     hb_job_t          * job   = pv->job;
121     hb_title_t        * title = job->title;
122     
123     int i;
124
125     if( pv->cur ) hb_buffer_close( &pv->cur );
126
127     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
128     {
129         if( job->acodec & HB_ACODEC_AC3 )
130         {
131             free( pv->sync_audio[i].ac3_buf );
132         }
133         else
134         {
135             src_delete( pv->sync_audio[i].state );
136         }
137     }
138     
139     free( pv );
140     w->private_data = NULL;
141 }
142
143 /***********************************************************************
144  * Work
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 )
150 {
151     hb_work_private_t * pv = w->private_data;
152     int i;
153
154     /* If we ever got a video frame, handle audio now */
155     if( pv->pts_offset != INT64_MIN )
156     {
157         for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
158         {
159             SyncAudio( w, i );
160         }
161     }
162
163     /* Handle video */
164     return SyncVideo( w );
165 }
166
167 hb_work_object_t hb_sync =
168 {
169     WORK_SYNC,
170     "Synchronization",
171     syncInit,
172     syncWork,
173     syncClose
174 };
175
176 static void InitAudio( hb_work_object_t * w, int i )
177 {
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;
182
183     sync        = &pv->sync_audio[i];
184     sync->audio = hb_list_item( title->list_audio, i );
185
186     if( job->acodec & HB_ACODEC_AC3 )
187     {
188         /* Have a silent AC-3 frame ready in case we have to fill a
189            gap */
190         AVCodec        * codec;
191         AVCodecContext * c;
192         short          * zeros;
193
194         codec = avcodec_find_encoder( CODEC_ID_AC3 );
195         c     = avcodec_alloc_context();
196
197         c->bit_rate    = sync->audio->bitrate;
198         c->sample_rate = sync->audio->rate;
199         c->channels    = 2;
200
201         if( avcodec_open( c, codec ) < 0 )
202         {
203             hb_log( "sync: avcodec_open failed" );
204             return;
205         }
206
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 );
212
213         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
214                                   zeros ) != sync->ac3_size )
215         {
216             hb_log( "sync: avcodec_encode_audio failed" );
217         }
218         
219         free( zeros );
220         avcodec_close( c );
221         av_free( c );
222     }
223     else
224     {
225         /* Initialize libsamplerate */
226         int error;
227         sync->state             = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown), &error );
228         sync->data.end_of_input = 0;
229     }
230 }
231
232
233
234 #define PTS_DISCONTINUITY_TOLERANCE 90000
235
236 /***********************************************************************
237  * SyncVideo
238  ***********************************************************************
239  * 
240  **********************************************************************/
241 static int SyncVideo( hb_work_object_t * w )
242 {
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;
247
248     if( pv->done )
249     {
250         return HB_WORK_DONE;
251     }
252
253     if( hb_thread_has_exited( job->reader ) &&
254         !hb_fifo_size( job->fifo_mpeg2 ) &&
255         !hb_fifo_size( job->fifo_raw ) )
256     {
257         /* All video data has been processed already, we won't get
258            more */
259         hb_log( "sync: got %lld frames, %lld expected",
260                 pv->count_frames, pv->count_frames_max );
261         pv->done = 1;
262         
263         hb_buffer_t * buf_tmp;
264
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 );
269         
270         return HB_WORK_DONE;
271     }
272
273     if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
274     {
275         /* We haven't even got a frame yet */
276         return HB_WORK_OK;
277     }
278     cur = pv->cur;
279
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 ) ) )
286     {
287         hb_buffer_t * buf_tmp;
288
289         if( pv->pts_offset == INT64_MIN )
290         {
291             /* This is our first frame */
292             hb_log( "sync: first pts is %lld", cur->start );
293             pv->pts_offset = cur->start;
294         }
295
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 )
299         {
300             hb_log( "PTS discontinuity (%lld, %lld)",
301                     cur->start, next->start );
302             
303             /* Trash all subtitles */
304             if( pv->subtitle )
305             {
306                 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
307                 {
308                     hb_buffer_close( &sub );
309                 }
310             }
311
312             /* Trash current picture */
313             hb_buffer_close( &cur );
314             pv->cur = cur = hb_fifo_get( job->fifo_raw );
315
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;
320             continue;
321         }
322
323         /* Look for a subtitle for this frame */
324         if( pv->subtitle )
325         {
326             hb_buffer_t * sub2;
327             while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
328             {
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;
334
335                 if( sub->stop > cur->start )
336                     break;
337
338                 /* The subtitle is older than this picture, trash it */
339                 sub = hb_fifo_get( pv->subtitle->fifo_raw );
340                 hb_buffer_close( &sub );
341             }
342
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
345                keep it for later */
346             if( sub && sub->start > cur->start )
347             {
348                 sub = NULL;
349             }
350         }
351
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;
355
356         if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
357             next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
358         {
359             /* The current frame is too old but the next one matches,
360                let's trash */
361             hb_buffer_close( &cur );
362             pv->cur = cur = hb_fifo_get( job->fifo_raw );
363             continue;
364         }
365
366         if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
367         {
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 );
372         }
373         else
374         {
375             /* The frame has the expected date and won't have to be
376                duplicated, just put it through */
377             buf_tmp = cur;
378             pv->cur = cur = hb_fifo_get( job->fifo_raw );
379         }
380
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;
386
387         /* If we have a subtitle for this picture, copy it */
388         /* FIXME: we should avoid this memcpy */
389         if( sub )
390         {
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 );
397         }
398
399         /* Push the frame to the renderer */
400         hb_fifo_push( job->fifo_sync, buf_tmp );
401
402         /* Update UI */
403         UpdateState( w );
404
405         /* Make sure we won't get more frames then expected */
406         if( pv->count_frames >= pv->count_frames_max )
407         {
408             hb_log( "sync: got %lld frames", pv->count_frames );
409             pv->done = 1;
410             
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 );
415             
416             break;
417         }
418     }
419
420     return HB_WORK_OK;
421 }
422
423 /***********************************************************************
424  * SyncAudio
425  ***********************************************************************
426  * 
427  **********************************************************************/
428 static void SyncAudio( hb_work_object_t * w, int i )
429 {
430     hb_work_private_t * pv = w->private_data;
431     hb_job_t        * job;
432     hb_audio_t      * audio;
433     hb_buffer_t     * buf;
434     hb_sync_audio_t * sync;
435
436     hb_fifo_t       * fifo;
437     int               rate;
438
439     int64_t           pts_expected;
440     int64_t           start;
441
442     job    = pv->job;
443     sync   = &pv->sync_audio[i];
444     audio  = sync->audio;
445
446     if( job->acodec & HB_ACODEC_AC3 )
447     {
448         fifo = audio->fifo_out;
449         rate = audio->rate;
450     }
451     else
452     {
453         fifo = audio->fifo_sync;
454         rate = job->arate;
455     }
456
457     while( !hb_fifo_is_full( fifo ) &&
458            ( buf = hb_fifo_see( audio->fifo_raw ) ) )
459     {
460         /* The PTS of the samples we are expecting now */
461         pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
462
463         if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
464               buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
465             pv->pts_offset_old > INT64_MIN )
466         {
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 *
470                 90000 / rate;
471
472             if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
473                 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
474             {
475                 /* There is really nothing we can do with it */
476                 buf = hb_fifo_get( audio->fifo_raw );
477                 hb_buffer_close( &buf );
478                 continue;
479             }
480
481             /* Use the older offset */
482             start = pts_expected - pv->pts_offset_old;
483         }
484         else
485         {
486             start = pts_expected - pv->pts_offset;
487         }
488
489         /* Tolerance: 100 ms */
490         if( buf->start < pts_expected - 9000 )
491         {
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 );
496             continue;
497         }
498         else if( buf->start > pts_expected + 9000 )
499         {
500             /* Missing audio, send a frame of silence */
501             InsertSilence( w, i );
502             continue;
503         }
504
505         if( job->acodec & HB_ACODEC_AC3 )
506         {
507             buf        = hb_fifo_get( audio->fifo_raw );
508             buf->start = start;
509             buf->stop  = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
510
511             sync->count_frames += AC3_SAMPLES_PER_FRAME;
512         }
513         else
514         {
515             hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
516
517             int count_in, count_out;
518
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 )
522                 count_out--;
523             else if( buf->start > pts_expected + 1500 )
524                 count_out++;
525
526             sync->data.data_in      = (float *) buf_raw->data;
527             sync->data.input_frames = count_in;
528             sync->data.output_frames = count_out;
529
530             sync->data.src_ratio = (double) sync->data.output_frames /
531                                    (double) sync->data.input_frames;
532
533             buf = hb_buffer_init( sync->data.output_frames * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *
534                                   sizeof( float ) );
535             sync->data.data_out = (float *) buf->data;
536             if( src_process( sync->state, &sync->data ) )
537             {
538                 /* XXX If this happens, we're screwed */
539                 hb_log( "sync: src_process failed" );
540             }
541             hb_buffer_close( &buf_raw );
542
543             buf->size = sync->data.output_frames_gen * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) * sizeof( float );
544
545             /* Set dates for resampled data */
546             buf->start = start;
547             buf->stop  = start + sync->data.output_frames_gen *
548                             90000 / job->arate;
549
550             sync->count_frames += sync->data.output_frames_gen;
551         }
552
553         buf->key = 1;
554         hb_fifo_push( fifo, buf );
555     }
556
557     if( NeedSilence( w, audio ) )
558     {
559         InsertSilence( w, i );
560     }
561 }
562
563 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
564 {
565     hb_work_private_t * pv = w->private_data;
566     hb_job_t * job = pv->job;
567
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 ) )
572     {
573         /* We have some audio, we are fine */
574         return 0;
575     }
576
577     /* No audio left in fifos */
578
579     if( hb_thread_has_exited( job->reader ) )
580     {
581         /* We might miss some audio to complete encoding and muxing
582            the video track */
583         return 1;
584     }
585
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 ) )
591     {
592         /* Too much video and no audio, oh-oh */
593         return 1;
594     }
595
596     return 0;
597 }
598
599 static void InsertSilence( hb_work_object_t * w, int i )
600 {
601     hb_work_private_t * pv = w->private_data;
602     hb_job_t        * job;
603     hb_sync_audio_t * sync;
604     hb_buffer_t     * buf;
605
606     job    = pv->job;
607     sync   = &pv->sync_audio[i];
608
609     if( job->acodec & HB_ACODEC_AC3 )
610     {
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 /
614                      sync->audio->rate;
615         memcpy( buf->data, sync->ac3_buf, buf->size );
616
617         hb_log( "sync: adding a silent AC-3 frame for track %x",
618                 sync->audio->id );
619         hb_fifo_push( sync->audio->fifo_out, buf );
620
621         sync->count_frames += AC3_SAMPLES_PER_FRAME;
622
623     }
624     else
625     {
626         buf        = hb_buffer_init( HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) * job->arate / 20 *
627                                      sizeof( float ) );
628         buf->start = sync->count_frames * 90000 / job->arate;
629         buf->stop  = buf->start + 90000 / 20;
630         memset( buf->data, 0, buf->size );
631
632         hb_log( "sync: adding 50 ms of silence for track %x",
633                 sync->audio->id );
634         hb_fifo_push( sync->audio->fifo_sync, buf );
635
636         sync->count_frames += job->arate / 20;
637     }
638 }
639
640 static void UpdateState( hb_work_object_t * w )
641 {
642     hb_work_private_t * pv = w->private_data;
643     hb_state_t state;
644
645     if( !pv->count_frames )
646     {
647         pv->st_first = hb_get_date();
648     }
649     pv->count_frames++;
650
651     if( hb_get_date() > pv->st_dates[3] + 1000 )
652     {
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;
659     } 
660
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 )
665     {
666         p.progress = 1.0; 
667     }
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 )
672     {
673         int eta;
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] ) /
677             p.rate_avg;
678         p.hours   = eta / 3600;
679         p.minutes = ( eta % 3600 ) / 60;
680         p.seconds = eta % 60;
681     }
682     else
683     {
684         p.rate_avg = 0.0;
685         p.hours    = -1;
686         p.minutes  = -1;
687         p.seconds  = -1;
688     }
689 #undef p
690
691     hb_set_state( pv->job->h, &state );
692 }