OSDN Git Service

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