1 /* $Id: deca52.c,v 1.14 2005/03/03 17:21:57 titer Exp $
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. */
9 #include "a52dec/a52.h"
11 struct hb_work_private_s
28 int64_t next_expected_pts
;
34 int out_discrete_channels
;
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
* );
42 hb_work_object_t hb_deca52
=
51 /***********************************************************************
53 **********************************************************************/
54 static hb_buffer_t
* Decode( hb_work_object_t
* w
);
56 /***********************************************************************
58 ***********************************************************************
59 * Allocate the work object, initialize liba52
60 **********************************************************************/
61 int deca52Init( hb_work_object_t
* w
, hb_job_t
* job
)
63 hb_work_private_t
* pv
= calloc( 1, sizeof( hb_work_private_t
) );
68 pv
->list
= hb_list_init();
69 pv
->state
= a52_init( 0 );
71 /* Decide what format we want out of a52dec
72 work.c has already done some of this deduction for us in do_job() */
74 pv
->flags_out
= HB_AMIXDOWN_GET_A52_FORMAT(w
->amixdown
);
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
);
81 pv
->next_expected_pts
= 0;
86 /***********************************************************************
88 ***********************************************************************
90 **********************************************************************/
91 void deca52Close( hb_work_object_t
* w
)
93 hb_work_private_t
* pv
= w
->private_data
;
94 a52_free( pv
->state
);
95 hb_list_empty( &pv
->list
);
97 w
->private_data
= NULL
;
100 /***********************************************************************
102 ***********************************************************************
103 * Add the given buffer to the data we already have, and decode as much
105 **********************************************************************/
106 int deca52Work( hb_work_object_t
* w
, hb_buffer_t
** buf_in
,
107 hb_buffer_t
** buf_out
)
109 hb_work_private_t
* pv
= w
->private_data
;
112 hb_list_add( pv
->list
, *buf_in
);
115 /* If we got more than a frame, chain raw buffers */
116 *buf_out
= buf
= Decode( w
);
119 buf
->next
= Decode( w
);
126 /***********************************************************************
128 ***********************************************************************
130 **********************************************************************/
131 static hb_buffer_t
* Decode( hb_work_object_t
* w
)
133 hb_work_private_t
* pv
= w
->private_data
;
138 /* Get a frame header if don't have one yet */
141 while( hb_list_bytes( pv
->list
) >= 7 )
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
,
152 hb_log( "a52_syncinfo ok" );
162 hb_log( "a52_syncinfo failed" );
166 /* Try one byte later */
167 hb_list_getbytes( pv
->list
, pv
->frame
, 1, NULL
, NULL
);
172 hb_list_bytes( pv
->list
) < pv
->size
)
178 /* Get the whole frame */
179 hb_list_getbytes( pv
->list
, pv
->frame
, pv
->size
, &pts
, &pos
);
181 /* AC3 passthrough: don't decode the AC3 frame */
182 if( pv
->job
->acodec
& HB_ACODEC_AC3
)
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
;
193 a52_frame( pv
->state
, pv
->frame
, &pv
->flags_out
, &pv
->level
, 0 );
195 /* 6 blocks per frame, 256 samples per block, channelsused channels */
196 buf
= hb_buffer_init( 6 * 256 * pv
->out_discrete_channels
* sizeof( float ) );
199 pts
= pv
->next_expected_pts
;
201 buf
->start
= pts
+ ( pos
/ pv
->size
) * 6 * 256 * 90000 / pv
->rate
;
202 buf
->stop
= buf
->start
+ 6 * 256 * 90000 / pv
->rate
;
204 pv
->next_expected_pts
= buf
->stop
;
206 for( i
= 0; i
< 6; i
++ )
208 sample_t
* samples_in
;
211 a52_block( pv
->state
);
212 samples_in
= a52_samples( pv
->state
);
213 samples_out
= ((float *) buf
->data
) + 256 * pv
->out_discrete_channels
* i
;
216 for( j
= 0; j
< 256; j
++ )
218 for ( k
= 0; k
< pv
->out_discrete_channels
; k
++ )
220 samples_out
[(pv
->out_discrete_channels
*j
)+k
] = samples_in
[(256*k
)+j
];