OSDN Git Service

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