1 /* $Id: decdca.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. */
10 struct hb_work_private_s
28 /* max frame size of the 16 bits version is 16384 */
29 /* max frame size of the 14 bits version is 18726 */
34 int out_discrete_channels
;
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
* );
42 hb_work_object_t hb_decdca
=
51 /***********************************************************************
53 **********************************************************************/
54 static hb_buffer_t
* Decode( hb_work_object_t
* w
);
56 /***********************************************************************
58 ***********************************************************************
59 * Allocate the work object, initialize libdca
60 **********************************************************************/
61 int decdcaInit( 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
= dca_init( 0 );
71 /* Decide what format we want out of libdca
72 work.c has already done some of this deduction for us in do_job() */
74 pv
->flags_out
= HB_AMIXDOWN_GET_DCA_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
);
85 /***********************************************************************
87 ***********************************************************************
89 **********************************************************************/
90 void decdcaClose( hb_work_object_t
* w
)
92 hb_work_private_t
* pv
= w
->private_data
;
93 dca_free( pv
->state
);
94 hb_list_empty( &pv
->list
);
96 w
->private_data
= NULL
;
99 /***********************************************************************
101 ***********************************************************************
102 * Add the given buffer to the data we already have, and decode as much
104 **********************************************************************/
105 int decdcaWork( hb_work_object_t
* w
, hb_buffer_t
** buf_in
,
106 hb_buffer_t
** buf_out
)
108 hb_work_private_t
* pv
= w
->private_data
;
111 hb_list_add( pv
->list
, *buf_in
);
114 /* If we got more than a frame, chain raw buffers */
115 *buf_out
= buf
= Decode( w
);
118 buf
->next
= Decode( w
);
125 /***********************************************************************
127 ***********************************************************************
129 **********************************************************************/
130 static hb_buffer_t
* Decode( hb_work_object_t
* w
)
132 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
) >= 14 )
143 /* We have 14 bytes, check if this is a correct header */
144 hb_list_seebytes( pv
->list
, pv
->frame
, 14 );
145 pv
->size
= dca_syncinfo( pv
->state
, pv
->frame
, &pv
->flags_in
, &pv
->rate
,
146 &pv
->bitrate
, &pv
->frame_length
);
152 hb_log( "dca_syncinfo ok" );
162 hb_log( "dca_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
);
182 dca_frame( pv
->state
, pv
->frame
, &pv
->flags_out
, &pv
->level
, 0 );
184 /* find out how many blocks are in this frame */
185 num_blocks
= dca_blocks_num( pv
->state
);
187 /* num_blocks blocks per frame, 256 samples per block, channelsused channels */
188 buf
= hb_buffer_init( num_blocks
* 256 * pv
->out_discrete_channels
* sizeof( float ) );
189 buf
->start
= pts
+ ( pos
/ pv
->size
) * num_blocks
* 256 * 90000 / pv
->rate
;
190 buf
->stop
= buf
->start
+ num_blocks
* 256 * 90000 / pv
->rate
;
192 for( i
= 0; i
< num_blocks
; i
++ )
194 dca_sample_t
* samples_in
;
197 dca_block( pv
->state
);
198 samples_in
= dca_samples( pv
->state
);
199 samples_out
= ((float *) buf
->data
) + 256 * pv
->out_discrete_channels
* i
;
202 for( j
= 0; j
< 256; j
++ )
204 for ( k
= 0; k
< pv
->out_discrete_channels
; k
++ )
206 samples_out
[(pv
->out_discrete_channels
*j
)+k
] = samples_in
[(256*k
)+j
] * 16384;