OSDN Git Service

Fix Previous Bad commit for Cyanders Chapter Markers
[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     int chap_break;
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         
264         hb_buffer_t * buf_tmp;
265
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 );
270         
271         return HB_WORK_DONE;
272     }
273
274     if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
275     {
276         /* We haven't even got a frame yet */
277         return HB_WORK_OK;
278     }
279     cur = pv->cur;
280
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 ) ) )
287     {
288         hb_buffer_t * buf_tmp;
289
290         if( pv->pts_offset == INT64_MIN )
291         {
292             /* This is our first frame */
293             hb_log( "sync: first pts is %lld", cur->start );
294             pv->pts_offset = cur->start;
295         }
296
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 )
300         {
301             hb_log( "PTS discontinuity (%lld, %lld)",
302                     cur->start, next->start );
303             
304             /* Trash all subtitles */
305             if( pv->subtitle )
306             {
307                 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
308                 {
309                     hb_buffer_close( &sub );
310                 }
311             }
312
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
319
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;
324             continue;
325         }
326
327         /* Look for a subtitle for this frame */
328         if( pv->subtitle )
329         {
330             hb_buffer_t * sub2;
331             while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
332             {
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;
338
339                 if( sub->stop > cur->start )
340                     break;
341
342                 /* The subtitle is older than this picture, trash it */
343                 sub = hb_fifo_get( pv->subtitle->fifo_raw );
344                 hb_buffer_close( &sub );
345             }
346
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
349                keep it for later */
350             if( sub && sub->start > cur->start )
351             {
352                 sub = NULL;
353             }
354         }
355
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;
359
360         if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
361             next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
362         {
363             /* The current frame is too old but the next one matches,
364                let's trash */
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.
370             
371             continue;
372         }
373
374         if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
375         {
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 );
380         }
381         else
382         {
383             /* The frame has the expected date and won't have to be
384                duplicated, just put it through */
385             buf_tmp = cur;
386             pv->cur = cur = hb_fifo_get( job->fifo_raw );
387         }
388         
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;
394
395         /* If we have a subtitle for this picture, copy it */
396         /* FIXME: we should avoid this memcpy */
397         if( sub )
398         {
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 );
405         }
406
407         /* Push the frame to the renderer */
408         hb_fifo_push( job->fifo_sync, buf_tmp );
409
410         /* Update UI */
411         UpdateState( w );
412
413         /* Make sure we won't get more frames then expected */
414         if( pv->count_frames >= pv->count_frames_max )
415         {
416             hb_log( "sync: got %lld frames", pv->count_frames );
417             pv->done = 1;
418             
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 );
423             
424             break;
425         }
426     }
427
428     return HB_WORK_OK;
429 }
430
431 /***********************************************************************
432  * SyncAudio
433  ***********************************************************************
434  * 
435  **********************************************************************/
436 static void SyncAudio( hb_work_object_t * w, int i )
437 {
438     hb_work_private_t * pv = w->private_data;
439     hb_job_t        * job;
440     hb_audio_t      * audio;
441     hb_buffer_t     * buf;
442     hb_sync_audio_t * sync;
443
444     hb_fifo_t       * fifo;
445     int               rate;
446
447     int64_t           pts_expected;
448     int64_t           start;
449
450     job    = pv->job;
451     sync   = &pv->sync_audio[i];
452     audio  = sync->audio;
453
454     if( job->acodec & HB_ACODEC_AC3 )
455     {
456         fifo = audio->fifo_out;
457         rate = audio->rate;
458     }
459     else
460     {
461         fifo = audio->fifo_sync;
462         rate = job->arate;
463     }
464
465     while( !hb_fifo_is_full( fifo ) &&
466            ( buf = hb_fifo_see( audio->fifo_raw ) ) )
467     {
468         /* The PTS of the samples we are expecting now */
469         pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
470
471         if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
472               buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
473             pv->pts_offset_old > INT64_MIN )
474         {
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 *
478                 90000 / rate;
479
480             if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
481                 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
482             {
483                 /* There is really nothing we can do with it */
484                 buf = hb_fifo_get( audio->fifo_raw );
485                 hb_buffer_close( &buf );
486                 continue;
487             }
488
489             /* Use the older offset */
490             start = pts_expected - pv->pts_offset_old;
491         }
492         else
493         {
494             start = pts_expected - pv->pts_offset;
495         }
496
497         /* Tolerance: 100 ms */
498         if( buf->start < pts_expected - 9000 )
499         {
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 );
504             continue;
505         }
506         else if( buf->start > pts_expected + 9000 )
507         {
508             /* Missing audio, send a frame of silence */
509             InsertSilence( w, i );
510             continue;
511         }
512
513         if( job->acodec & HB_ACODEC_AC3 )
514         {
515             buf        = hb_fifo_get( audio->fifo_raw );
516             buf->start = start;
517             buf->stop  = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
518
519             sync->count_frames += AC3_SAMPLES_PER_FRAME;
520         }
521         else
522         {
523             hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
524
525             int count_in, count_out;
526
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 )
530                 count_out--;
531             else if( buf->start > pts_expected + 1500 )
532                 count_out++;
533
534             sync->data.data_in      = (float *) buf_raw->data;
535             sync->data.input_frames = count_in;
536             sync->data.output_frames = count_out;
537
538             sync->data.src_ratio = (double) sync->data.output_frames /
539                                    (double) sync->data.input_frames;
540
541             buf = hb_buffer_init( sync->data.output_frames * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *
542                                   sizeof( float ) );
543             sync->data.data_out = (float *) buf->data;
544             if( src_process( sync->state, &sync->data ) )
545             {
546                 /* XXX If this happens, we're screwed */
547                 hb_log( "sync: src_process failed" );
548             }
549             hb_buffer_close( &buf_raw );
550
551             buf->size = sync->data.output_frames_gen * HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) * sizeof( float );
552
553             /* Set dates for resampled data */
554             buf->start = start;
555             buf->stop  = start + sync->data.output_frames_gen *
556                             90000 / job->arate;
557
558             sync->count_frames += sync->data.output_frames_gen;
559         }
560
561         buf->key = 1;
562         hb_fifo_push( fifo, buf );
563     }
564
565     if( NeedSilence( w, audio ) )
566     {
567         InsertSilence( w, i );
568     }
569 }
570
571 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
572 {
573     hb_work_private_t * pv = w->private_data;
574     hb_job_t * job = pv->job;
575
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 ) )
580     {
581         /* We have some audio, we are fine */
582         return 0;
583     }
584
585     /* No audio left in fifos */
586
587     if( hb_thread_has_exited( job->reader ) )
588     {
589         /* We might miss some audio to complete encoding and muxing
590            the video track */
591         return 1;
592     }
593
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 ) )
599     {
600         /* Too much video and no audio, oh-oh */
601         return 1;
602     }
603
604     return 0;
605 }
606
607 static void InsertSilence( hb_work_object_t * w, int i )
608 {
609     hb_work_private_t * pv = w->private_data;
610     hb_job_t        * job;
611     hb_sync_audio_t * sync;
612     hb_buffer_t     * buf;
613
614     job    = pv->job;
615     sync   = &pv->sync_audio[i];
616
617     if( job->acodec & HB_ACODEC_AC3 )
618     {
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 /
622                      sync->audio->rate;
623         memcpy( buf->data, sync->ac3_buf, buf->size );
624
625         hb_log( "sync: adding a silent AC-3 frame for track %x",
626                 sync->audio->id );
627         hb_fifo_push( sync->audio->fifo_out, buf );
628
629         sync->count_frames += AC3_SAMPLES_PER_FRAME;
630
631     }
632     else
633     {
634         buf        = hb_buffer_init( HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) * job->arate / 20 *
635                                      sizeof( float ) );
636         buf->start = sync->count_frames * 90000 / job->arate;
637         buf->stop  = buf->start + 90000 / 20;
638         memset( buf->data, 0, buf->size );
639
640         hb_log( "sync: adding 50 ms of silence for track %x",
641                 sync->audio->id );
642         hb_fifo_push( sync->audio->fifo_sync, buf );
643
644         sync->count_frames += job->arate / 20;
645     }
646 }
647
648 static void UpdateState( hb_work_object_t * w )
649 {
650     hb_work_private_t * pv = w->private_data;
651     hb_state_t state;
652
653     if( !pv->count_frames )
654     {
655         pv->st_first = hb_get_date();
656     }
657     pv->count_frames++;
658
659     if( hb_get_date() > pv->st_dates[3] + 1000 )
660     {
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;
667     } 
668
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 )
673     {
674         p.progress = 1.0; 
675     }
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 )
680     {
681         int eta;
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] ) /
685             p.rate_avg;
686         p.hours   = eta / 3600;
687         p.minutes = ( eta % 3600 ) / 60;
688         p.seconds = eta % 60;
689     }
690     else
691     {
692         p.rate_avg = 0.0;
693         p.hours    = -1;
694         p.minutes  = -1;
695         p.seconds  = -1;
696     }
697 #undef p
698
699     hb_set_state( pv->job->h, &state );
700 }