OSDN Git Service

28081900d1a6c9a40aa15a7b556a0826b539c9c6
[handbrake-jp/handbrake-jp-git.git] / libhb / decdca.c
1 /* $Id: decdca.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.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8 #include "dca.h"
9
10 struct hb_work_private_s
11 {
12     hb_job_t    * job;
13
14     /* libdca handle */
15     dca_state_t * state;
16
17     int           flags_in;
18     int           flags_out;
19     int           rate;
20     int           bitrate;
21     int           frame_length;
22     float         level;
23
24     int           error;
25     int           sync;
26     int           size;
27
28     /* max frame size of the 16 bits version is 16384 */
29     /* max frame size of the 14 bits version is 18726 */
30     uint8_t       frame[18726];
31
32     hb_list_t   * list;
33
34         int           out_discrete_channels;
35
36 };
37
38 int  decdcaInit( hb_work_object_t *, hb_job_t * );
39 int  decdcaWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
40 void decdcaClose( hb_work_object_t * );
41
42 hb_work_object_t hb_decdca =
43 {
44     WORK_DECDCA,
45     "DCA decoder",
46     decdcaInit,
47     decdcaWork,
48     decdcaClose
49 };
50
51 /***********************************************************************
52  * Local prototypes
53  **********************************************************************/
54 static hb_buffer_t * Decode( hb_work_object_t * w );
55
56 /***********************************************************************
57  * hb_work_decdca_init
58  ***********************************************************************
59  * Allocate the work object, initialize libdca
60  **********************************************************************/
61 int decdcaInit( hb_work_object_t * w, hb_job_t * job )
62 {
63     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
64     hb_audio_t * audio = w->audio;
65     w->private_data = pv;
66
67     pv->job   = job;
68
69     pv->list      = hb_list_init();
70     pv->state     = dca_init( 0 );
71
72         /* Decide what format we want out of libdca
73         work.c has already done some of this deduction for us in do_job() */
74
75         pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(audio->config.out.mixdown);
76
77         /* pass the number of channels used into the private work data */
78         /* will only be actually used if we're not doing AC3 passthru */
79     pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
80
81     pv->level     = 32768.0;
82
83     return 0;
84 }
85
86 /***********************************************************************
87  * Close
88  ***********************************************************************
89  * Free memory
90  **********************************************************************/
91 void decdcaClose( hb_work_object_t * w )
92 {
93     hb_work_private_t * pv = w->private_data;
94     dca_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 decdcaWork( 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     int           num_blocks;
138
139     /* Get a frame header if don't have one yet */
140     if( !pv->sync )
141     {
142         while( hb_list_bytes( pv->list ) >= 14 )
143         {
144             /* We have 14 bytes, check if this is a correct header */
145             hb_list_seebytes( pv->list, pv->frame, 14 );
146             pv->size = dca_syncinfo( pv->state, pv->frame, &pv->flags_in, &pv->rate,
147                                     &pv->bitrate, &pv->frame_length );
148             if( pv->size )
149             {
150                 /* It is. W00t. */
151                 if( pv->error )
152                 {
153                     hb_log( "dca_syncinfo ok" );
154                 }
155                 pv->error = 0;
156                 pv->sync  = 1;
157                 break;
158             }
159
160             /* It is not */
161             if( !pv->error )
162             {
163                 hb_log( "dca_syncinfo failed" );
164                 pv->error = 1;
165             }
166
167             /* Try one byte later */
168             hb_list_getbytes( pv->list, pv->frame, 1, NULL, NULL );
169         }
170     }
171
172     if( !pv->sync ||
173         hb_list_bytes( pv->list ) < pv->size )
174     {
175         /* Need more data */
176         return NULL;
177     }
178
179     /* Get the whole frame */
180     hb_list_getbytes( pv->list, pv->frame, pv->size, &pts, &pos );
181
182     /* Feed libdca */
183     dca_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 );
184
185     /* find out how many blocks are in this frame */
186     num_blocks = dca_blocks_num( pv->state );
187
188     /* num_blocks blocks per frame, 256 samples per block, channelsused channels */
189     buf        = hb_buffer_init( num_blocks * 256 * pv->out_discrete_channels * sizeof( float ) );
190     buf->start = pts + ( pos / pv->size ) * num_blocks * 256 * 90000 / pv->rate;
191     buf->stop  = buf->start + num_blocks * 256 * 90000 / pv->rate;
192
193     for( i = 0; i < num_blocks; i++ )
194     {
195         dca_sample_t * samples_in;
196         float    * samples_out;
197
198         dca_block( pv->state );
199         samples_in  = dca_samples( pv->state );
200         samples_out = ((float *) buf->data) + 256 * pv->out_discrete_channels * i;
201
202         /* Interleave */
203         for( j = 0; j < 256; j++ )
204         {
205                         for ( k = 0; k < pv->out_discrete_channels; k++ )
206                         {
207                                 samples_out[(pv->out_discrete_channels*j)+k]   = samples_in[(256*k)+j] * 16384;
208                         }
209         }
210
211     }
212
213     pv->sync = 0;
214     return buf;
215 }
216