OSDN Git Service

Added chapter markers in a chapter text track in mp4 files.
[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
140 /***********************************************************************
141  * Work
142  ***********************************************************************
143  * The root routine of this work abject
144  **********************************************************************/
145 int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
146                  hb_buffer_t ** unused2 )
147 {
148     hb_work_private_t * pv = w->private_data;
149     int i;
150
151     /* If we ever got a video frame, handle audio now */
152     if( pv->pts_offset != INT64_MIN )
153     {
154         for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
155         {
156             SyncAudio( w, i );
157         }
158     }
159
160     /* Handle video */
161     return SyncVideo( w );
162 }
163
164 hb_work_object_t hb_sync =
165 {
166     WORK_SYNC,
167     "Synchronization",
168     syncInit,
169     syncWork,
170     syncClose
171 };
172
173 static void InitAudio( hb_work_object_t * w, int i )
174 {
175     hb_work_private_t * pv = w->private_data;
176     hb_job_t        * job   = pv->job;
177     hb_title_t      * title = job->title;
178     hb_sync_audio_t * sync;
179
180     sync        = &pv->sync_audio[i];
181     sync->audio = hb_list_item( title->list_audio, i );
182
183     if( job->acodec & HB_ACODEC_AC3 )
184     {
185         /* Have a silent AC-3 frame ready in case we have to fill a
186            gap */
187         AVCodec        * codec;
188         AVCodecContext * c;
189         short          * zeros;
190
191         codec = avcodec_find_encoder( CODEC_ID_AC3 );
192         c     = avcodec_alloc_context();
193
194         c->bit_rate    = sync->audio->bitrate;
195         c->sample_rate = sync->audio->rate;
196         c->channels    = sync->audio->channels;
197
198         if( avcodec_open( c, codec ) < 0 )
199         {
200             hb_log( "sync: avcodec_open failed" );
201             return;
202         }
203
204         zeros          = calloc( AC3_SAMPLES_PER_FRAME *
205                                  sizeof( short ) * c->channels, 1 );
206         sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
207                              sync->audio->rate / 8;
208         sync->ac3_buf  = malloc( sync->ac3_size );
209
210         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
211                                   zeros ) != sync->ac3_size )
212         {
213             hb_log( "sync: avcodec_encode_audio failed" );
214         }
215         
216         free( zeros );
217         avcodec_close( c );
218         av_free( c );
219     }
220     else
221     {
222         /* Initialize libsamplerate */
223         int error;
224         sync->state             = src_new( SRC_LINEAR, sync->audio->channelsused, &error );
225         sync->data.end_of_input = 0;
226     }
227 }
228
229
230
231 #define PTS_DISCONTINUITY_TOLERANCE 90000
232
233 /***********************************************************************
234  * SyncVideo
235  ***********************************************************************
236  * 
237  **********************************************************************/
238 static int SyncVideo( hb_work_object_t * w )
239 {
240     hb_work_private_t * pv = w->private_data;
241     hb_buffer_t * cur, * next, * sub = NULL;
242     hb_job_t * job = pv->job;
243     int64_t pts_expected;
244
245     if( pv->done )
246     {
247         return HB_WORK_DONE;
248     }
249
250     if( hb_thread_has_exited( job->reader ) &&
251         !hb_fifo_size( job->fifo_mpeg2 ) &&
252         !hb_fifo_size( job->fifo_raw ) )
253     {
254         /* All video data has been processed already, we won't get
255            more */
256         hb_log( "sync: got %lld frames, %lld expected",
257                 pv->count_frames, pv->count_frames_max );
258         pv->done = 1;
259         return HB_WORK_DONE;
260     }
261
262     if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
263     {
264         /* We haven't even got a frame yet */
265         return HB_WORK_OK;
266     }
267     cur = pv->cur;
268
269     /* At this point we have a frame to process. Let's check
270         1) if we will be able to push into the fifo ahead
271         2) if the next frame is there already, since we need it to
272            know whether we'll have to repeat the current frame or not */
273     while( !hb_fifo_is_full( job->fifo_sync ) &&
274            ( next = hb_fifo_see( job->fifo_raw ) ) )
275     {
276         hb_buffer_t * buf_tmp;
277
278         if( pv->pts_offset == INT64_MIN )
279         {
280             /* This is our first frame */
281             hb_log( "sync: first pts is %lld", cur->start );
282             pv->pts_offset = cur->start;
283         }
284
285         /* Check for PTS jumps over 0.5 second */
286         if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE ||
287             next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE )
288         {
289             hb_log( "PTS discontinuity (%lld, %lld)",
290                     cur->start, next->start );
291             
292             /* Trash all subtitles */
293             if( pv->subtitle )
294             {
295                 while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
296                 {
297                     hb_buffer_close( &sub );
298                 }
299             }
300
301             /* Trash current picture */
302             hb_buffer_close( &cur );
303             pv->cur = cur = hb_fifo_get( job->fifo_raw );
304
305             /* Calculate new offset */
306             pv->pts_offset_old = pv->pts_offset;
307             pv->pts_offset     = cur->start -
308                 pv->count_frames * pv->job->vrate_base / 300;
309             continue;
310         }
311
312         /* Look for a subtitle for this frame */
313         if( pv->subtitle )
314         {
315             hb_buffer_t * sub2;
316             while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
317             {
318                 /* If two subtitles overlap, make the first one stop
319                    when the second one starts */
320                 sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
321                 if( sub2 && sub->stop > sub2->start )
322                     sub->stop = sub2->start;
323
324                 if( sub->stop > cur->start )
325                     break;
326
327                 /* The subtitle is older than this picture, trash it */
328                 sub = hb_fifo_get( pv->subtitle->fifo_raw );
329                 hb_buffer_close( &sub );
330             }
331
332             /* If we have subtitles left in the fifo, check if we should
333                apply the first one to the current frame or if we should
334                keep it for later */
335             if( sub && sub->start > cur->start )
336             {
337                 sub = NULL;
338             }
339         }
340
341         /* The PTS of the frame we are expecting now */
342         pts_expected = pv->pts_offset +
343             pv->count_frames * pv->job->vrate_base / 300;
344
345         if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
346             next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
347         {
348             /* The current frame is too old but the next one matches,
349                let's trash */
350             hb_buffer_close( &cur );
351             pv->cur = cur = hb_fifo_get( job->fifo_raw );
352             continue;
353         }
354
355         if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
356         {
357             /* We'll need the current frame more than one time. Make a
358                copy of it and keep it */
359             buf_tmp = hb_buffer_init( cur->size );
360             memcpy( buf_tmp->data, cur->data, cur->size );
361         }
362         else
363         {
364             /* The frame has the expected date and won't have to be
365                duplicated, just put it through */
366             buf_tmp = cur;
367             pv->cur = cur = hb_fifo_get( job->fifo_raw );
368         }
369
370         /* Replace those MPEG-2 dates with our dates */
371         buf_tmp->start = (uint64_t) pv->count_frames *
372             pv->job->vrate_base / 300;
373         buf_tmp->stop  = (uint64_t) ( pv->count_frames + 1 ) *
374             pv->job->vrate_base / 300;
375
376         /* If we have a subtitle for this picture, copy it */
377         /* FIXME: we should avoid this memcpy */
378         if( sub )
379         {
380             buf_tmp->sub         = hb_buffer_init( sub->size );
381             buf_tmp->sub->x      = sub->x;
382             buf_tmp->sub->y      = sub->y;
383             buf_tmp->sub->width  = sub->width;
384             buf_tmp->sub->height = sub->height;
385             memcpy( buf_tmp->sub->data, sub->data, sub->size );
386         }
387
388         /* Push the frame to the renderer */
389         hb_fifo_push( job->fifo_sync, buf_tmp );
390
391         /* Update UI */
392         UpdateState( w );
393
394         /* Make sure we won't get more frames then expected */
395         if( pv->count_frames >= pv->count_frames_max )
396         {
397             hb_log( "sync: got %lld frames", pv->count_frames );
398             pv->done = 1;
399             break;
400         }
401     }
402
403     return HB_WORK_OK;
404 }
405
406 /***********************************************************************
407  * SyncAudio
408  ***********************************************************************
409  * 
410  **********************************************************************/
411 static void SyncAudio( hb_work_object_t * w, int i )
412 {
413     hb_work_private_t * pv = w->private_data;
414     hb_job_t        * job;
415     hb_audio_t      * audio;
416     hb_buffer_t     * buf;
417     hb_sync_audio_t * sync;
418
419     hb_fifo_t       * fifo;
420     int               rate;
421
422     int64_t           pts_expected;
423     int64_t           start;
424
425     job    = pv->job;
426     sync   = &pv->sync_audio[i];
427     audio  = sync->audio;
428
429     if( job->acodec & HB_ACODEC_AC3 )
430     {
431         fifo = audio->fifo_out;
432         rate = audio->rate;
433     }
434     else
435     {
436         fifo = audio->fifo_sync;
437         rate = job->arate;
438     }
439
440     while( !hb_fifo_is_full( fifo ) &&
441            ( buf = hb_fifo_see( audio->fifo_raw ) ) )
442     {
443         /* The PTS of the samples we are expecting now */
444         pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
445
446         if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
447               buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
448             pv->pts_offset_old > INT64_MIN )
449         {
450             /* There has been a PTS discontinuity, and this frame might
451                be from before the discontinuity */
452             pts_expected = pv->pts_offset_old + sync->count_frames *
453                 90000 / rate;
454
455             if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
456                 buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE )
457             {
458                 /* There is really nothing we can do with it */
459                 buf = hb_fifo_get( audio->fifo_raw );
460                 hb_buffer_close( &buf );
461                 continue;
462             }
463
464             /* Use the older offset */
465             start = pts_expected - pv->pts_offset_old;
466         }
467         else
468         {
469             start = pts_expected - pv->pts_offset;
470         }
471
472         /* Tolerance: 100 ms */
473         if( buf->start < pts_expected - 9000 )
474         {
475             /* Late audio, trash it */
476             hb_log( "sync: trashing late audio" );
477             buf = hb_fifo_get( audio->fifo_raw );
478             hb_buffer_close( &buf );
479             continue;
480         }
481         else if( buf->start > pts_expected + 9000 )
482         {
483             /* Missing audio, send a frame of silence */
484             InsertSilence( w, i );
485             continue;
486         }
487
488         if( job->acodec & HB_ACODEC_AC3 )
489         {
490             buf        = hb_fifo_get( audio->fifo_raw );
491             buf->start = start;
492             buf->stop  = start + 90000 * AC3_SAMPLES_PER_FRAME / rate;
493
494             sync->count_frames += AC3_SAMPLES_PER_FRAME;
495         }
496         else
497         {
498             hb_buffer_t * buf_raw = hb_fifo_get( audio->fifo_raw );
499
500             int count_in, count_out;
501
502             count_in  = buf_raw->size / audio->channelsused / sizeof( float );
503             count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
504             if( buf->start < pts_expected - 1500 )
505                 count_out--;
506             else if( buf->start > pts_expected + 1500 )
507                 count_out++;
508
509             sync->data.data_in      = (float *) buf_raw->data;
510             sync->data.input_frames = count_in;
511             sync->data.output_frames = count_out;
512
513             sync->data.src_ratio = (double) sync->data.output_frames /
514                                    (double) sync->data.input_frames;
515
516             buf = hb_buffer_init( sync->data.output_frames * audio->channelsused *
517                                   sizeof( float ) );
518             sync->data.data_out = (float *) buf->data;
519             if( src_process( sync->state, &sync->data ) )
520             {
521                 /* XXX If this happens, we're screwed */
522                 hb_log( "sync: src_process failed" );
523             }
524             hb_buffer_close( &buf_raw );
525
526             buf->size = sync->data.output_frames_gen * audio->channelsused * sizeof( float );
527
528             /* Set dates for resampled data */
529             buf->start = start;
530             buf->stop  = start + sync->data.output_frames_gen *
531                             90000 / job->arate;
532
533             sync->count_frames += sync->data.output_frames_gen;
534         }
535
536         buf->key = 1;
537         hb_fifo_push( fifo, buf );
538     }
539
540     if( NeedSilence( w, audio ) )
541     {
542         InsertSilence( w, i );
543     }
544 }
545
546 static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
547 {
548     hb_work_private_t * pv = w->private_data;
549     hb_job_t * job = pv->job;
550
551     if( hb_fifo_size( audio->fifo_in ) ||
552         hb_fifo_size( audio->fifo_raw ) ||
553         hb_fifo_size( audio->fifo_sync ) ||
554         hb_fifo_size( audio->fifo_out ) )
555     {
556         /* We have some audio, we are fine */
557         return 0;
558     }
559
560     /* No audio left in fifos */
561
562     if( hb_thread_has_exited( job->reader ) )
563     {
564         /* We might miss some audio to complete encoding and muxing
565            the video track */
566         return 1;
567     }
568
569     if( hb_fifo_is_full( job->fifo_mpeg2 ) &&
570         hb_fifo_is_full( job->fifo_raw ) &&
571         hb_fifo_is_full( job->fifo_sync ) &&
572         hb_fifo_is_full( job->fifo_render ) &&
573         hb_fifo_is_full( job->fifo_mpeg4 ) )
574     {
575         /* Too much video and no audio, oh-oh */
576         return 1;
577     }
578
579     return 0;
580 }
581
582 static void InsertSilence( hb_work_object_t * w, int i )
583 {
584     hb_work_private_t * pv = w->private_data;
585     hb_job_t        * job;
586     hb_sync_audio_t * sync;
587     hb_buffer_t     * buf;
588
589     job    = pv->job;
590     sync   = &pv->sync_audio[i];
591
592     if( job->acodec & HB_ACODEC_AC3 )
593     {
594         buf        = hb_buffer_init( sync->ac3_size );
595         buf->start = sync->count_frames * 90000 / sync->audio->rate;
596         buf->stop  = buf->start + 90000 * AC3_SAMPLES_PER_FRAME /
597                      sync->audio->rate;
598         memcpy( buf->data, sync->ac3_buf, buf->size );
599
600         hb_log( "sync: adding a silent AC-3 frame for track %x",
601                 sync->audio->id );
602         hb_fifo_push( sync->audio->fifo_out, buf );
603
604         sync->count_frames += AC3_SAMPLES_PER_FRAME;
605
606     }
607     else
608     {
609         buf        = hb_buffer_init( sync->audio->channelsused * job->arate / 20 *
610                                      sizeof( float ) );
611         buf->start = sync->count_frames * 90000 / job->arate;
612         buf->stop  = buf->start + 90000 / 20;
613         memset( buf->data, 0, buf->size );
614
615         hb_log( "sync: adding 50 ms of silence for track %x",
616                 sync->audio->id );
617         hb_fifo_push( sync->audio->fifo_sync, buf );
618
619         sync->count_frames += job->arate / 20;
620     }
621 }
622
623 static void UpdateState( hb_work_object_t * w )
624 {
625     hb_work_private_t * pv = w->private_data;
626     hb_state_t state;
627
628     if( !pv->count_frames )
629     {
630         pv->st_first = hb_get_date();
631     }
632     pv->count_frames++;
633
634     if( hb_get_date() > pv->st_dates[3] + 1000 )
635     {
636         memmove( &pv->st_dates[0], &pv->st_dates[1],
637                  3 * sizeof( uint64_t ) );
638         memmove( &pv->st_counts[0], &pv->st_counts[1],
639                  3 * sizeof( uint64_t ) );
640         pv->st_dates[3]  = hb_get_date();
641         pv->st_counts[3] = pv->count_frames;
642     } 
643
644 #define p state.param.working
645     state.state = HB_STATE_WORKING;
646     p.progress  = (float) pv->count_frames / (float) pv->count_frames_max;
647     if( p.progress > 1.0 )
648     {
649         p.progress = 1.0; 
650     }
651     p.rate_cur   = 1000.0 *
652         (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
653         (float) ( pv->st_dates[3] - pv->st_dates[0] );
654     if( hb_get_date() > pv->st_first + 4000 )
655     {
656         int eta;
657         p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
658             (float) ( pv->st_dates[3] - pv->st_first );
659         eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
660             p.rate_avg;
661         p.hours   = eta / 3600;
662         p.minutes = ( eta % 3600 ) / 60;
663         p.seconds = eta % 60;
664     }
665     else
666     {
667         p.rate_avg = 0.0;
668         p.hours    = -1;
669         p.minutes  = -1;
670         p.seconds  = -1;
671     }
672 #undef p
673
674     hb_set_state( pv->job->h, &state );
675 }