OSDN Git Service

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