OSDN Git Service

Don't drop subtitles when crossing PTS discontinuities by using buffer sequence numbe...
[handbrake-jp/handbrake-jp-git.git] / libhb / deca52.c
1 /* $Id: deca52.c,v 1.14 2005/03/03 17:21:57 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 "a52dec/a52.h"
10
11 struct hb_work_private_s
12 {
13     hb_job_t    * job;
14
15     /* liba52 handle */
16     a52_state_t * state;
17
18     int           flags_in;
19     int           flags_out;
20     int           rate;
21     int           bitrate;
22     float         level;
23     
24     int           error;
25     int           sync;
26     int           size;
27
28     int64_t       next_expected_pts;
29
30     int64_t       sequence;
31
32     uint8_t       frame[3840];
33
34     hb_list_t   * list;
35         
36         int           out_discrete_channels;
37         
38 };
39
40 int  deca52Init( hb_work_object_t *, hb_job_t * );
41 int  deca52Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
42 void deca52Close( hb_work_object_t * );
43
44 hb_work_object_t hb_deca52 =
45 {
46     WORK_DECA52,
47     "AC3 decoder",
48     deca52Init,
49     deca52Work,
50     deca52Close
51 };
52
53 /***********************************************************************
54  * Local prototypes
55  **********************************************************************/
56 static hb_buffer_t * Decode( hb_work_object_t * w );
57
58 /***********************************************************************
59  * hb_work_deca52_init
60  ***********************************************************************
61  * Allocate the work object, initialize liba52
62  **********************************************************************/
63 int deca52Init( hb_work_object_t * w, hb_job_t * job )
64 {
65     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
66     w->private_data = pv;
67
68     pv->job   = job;
69
70     pv->list      = hb_list_init();
71     pv->state     = a52_init( 0 );
72
73         /* Decide what format we want out of a52dec
74         work.c has already done some of this deduction for us in do_job() */
75         
76         pv->flags_out = HB_AMIXDOWN_GET_A52_FORMAT(w->amixdown);
77
78         /* pass the number of channels used into the private work data */
79         /* will only be actually used if we're not doing AC3 passthru */
80         pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
81
82     pv->level     = 32768.0;
83     pv->next_expected_pts = 0;
84     pv->sequence = 0;
85     
86     return 0;
87 }
88
89 /***********************************************************************
90  * Close
91  ***********************************************************************
92  * Free memory
93  **********************************************************************/
94 void deca52Close( hb_work_object_t * w )
95 {
96     hb_work_private_t * pv = w->private_data;
97     a52_free( pv->state );
98     hb_list_empty( &pv->list );
99     free( pv );
100     w->private_data = NULL;
101 }
102
103 /***********************************************************************
104  * Work
105  ***********************************************************************
106  * Add the given buffer to the data we already have, and decode as much
107  * as we can
108  **********************************************************************/
109 int deca52Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
110                 hb_buffer_t ** buf_out )
111 {
112     hb_work_private_t * pv = w->private_data;
113     hb_buffer_t * buf;
114
115     if( buf_in && *buf_in )
116     {
117         pv->sequence = (*buf_in)->sequence;
118     }
119
120     hb_list_add( pv->list, *buf_in );
121     *buf_in = NULL;
122
123     /* If we got more than a frame, chain raw buffers */
124     *buf_out = buf = Decode( w );
125     while( buf )
126     { 
127         buf->sequence = pv->sequence;
128         buf->next = Decode( w );
129         buf       = buf->next;
130     }
131
132     return HB_WORK_OK;
133 }
134
135 /***********************************************************************
136  * Decode
137  ***********************************************************************
138  * 
139  **********************************************************************/
140 static hb_buffer_t * Decode( hb_work_object_t * w )
141 {
142     hb_work_private_t * pv = w->private_data;
143     hb_buffer_t * buf;
144     int           i, j, k;
145     uint64_t      pts, pos;
146
147     /* Get a frame header if don't have one yet */
148     if( !pv->sync )
149     {
150         while( hb_list_bytes( pv->list ) >= 7 )
151         {
152             /* We have 7 bytes, check if this is a correct header */
153             hb_list_seebytes( pv->list, pv->frame, 7 );
154             pv->size = a52_syncinfo( pv->frame, &pv->flags_in, &pv->rate,
155                                     &pv->bitrate );
156             if( pv->size )
157             {
158                 /* It is. W00t. */
159                 if( pv->error )
160                 {
161                     hb_log( "a52_syncinfo ok" );
162                 }
163                 pv->error = 0;
164                 pv->sync  = 1;
165                 break;
166             }
167
168             /* It is not */
169             if( !pv->error )
170             {
171                 hb_log( "a52_syncinfo failed" );
172                 pv->error = 1;
173             }
174
175             /* Try one byte later */
176             hb_list_getbytes( pv->list, pv->frame, 1, NULL, NULL );
177         }
178     }
179
180     if( !pv->sync ||
181         hb_list_bytes( pv->list ) < pv->size )
182     {
183         /* Need more data */
184         return NULL;
185     }
186
187     /* Get the whole frame */
188     hb_list_getbytes( pv->list, pv->frame, pv->size, &pts, &pos );
189
190     /* AC3 passthrough: don't decode the AC3 frame */
191     if( pv->job->acodec & HB_ACODEC_AC3 )
192     {
193         buf = hb_buffer_init( pv->size );
194         memcpy( buf->data, pv->frame, pv->size );
195         buf->start = pts + ( pos / pv->size ) * 6 * 256 * 90000 / pv->rate;
196         buf->stop  = buf->start + 6 * 256 * 90000 / pv->rate;
197         pv->sync = 0;
198         return buf;
199     }
200
201     /* Feed liba52 */
202     a52_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 );
203
204     /* 6 blocks per frame, 256 samples per block, channelsused channels */
205     buf        = hb_buffer_init( 6 * 256 * pv->out_discrete_channels * sizeof( float ) );
206     if (pts == -1)
207     {
208       pts = pv->next_expected_pts;
209     }
210     buf->start = pts + ( pos / pv->size ) * 6 * 256 * 90000 / pv->rate;
211     buf->stop  = buf->start + 6 * 256 * 90000 / pv->rate;
212
213     /*
214        * To track AC3 PTS add this back in again.
215         *hb_log("AC3: pts is %lld, buf->start %lld buf->stop %lld", pts, buf->start, buf->stop); 
216         */
217     
218     pv->next_expected_pts = buf->stop;
219     
220     for( i = 0; i < 6; i++ )
221     {
222         sample_t * samples_in;
223         float    * samples_out;
224
225         a52_block( pv->state );
226         samples_in  = a52_samples( pv->state );
227         samples_out = ((float *) buf->data) + 256 * pv->out_discrete_channels * i;
228
229         /* Interleave */
230         for( j = 0; j < 256; j++ )
231         {
232                         for ( k = 0; k < pv->out_discrete_channels; k++ )
233                         {
234                                 samples_out[(pv->out_discrete_channels*j)+k]   = samples_in[(256*k)+j];
235                         }
236         }
237
238     }
239
240     pv->sync = 0;
241     return buf;
242 }
243