1 /* $Id: encfaac.c,v 1.13 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. */
11 struct hb_work_private_s
16 unsigned long input_samples
;
17 unsigned long output_bytes
;
23 int out_discrete_channels
;
27 int encfaacInit( hb_work_object_t
*, hb_job_t
* );
28 int encfaacWork( hb_work_object_t
*, hb_buffer_t
**, hb_buffer_t
** );
29 void encfaacClose( hb_work_object_t
* );
31 hb_work_object_t hb_encfaac
=
34 "AAC encoder (libfaac)",
40 /***********************************************************************
41 * hb_work_encfaac_init
42 ***********************************************************************
44 **********************************************************************/
45 int encfaacInit( hb_work_object_t
* w
, hb_job_t
* job
)
47 hb_work_private_t
* pv
= calloc( 1, sizeof( hb_work_private_t
) );
48 faacEncConfigurationPtr cfg
;
56 /* pass the number of channels used into the private work data */
57 pv
->out_discrete_channels
= HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w
->amixdown
);
59 pv
->faac
= faacEncOpen( job
->arate
, pv
->out_discrete_channels
, &pv
->input_samples
,
61 pv
->buf
= malloc( pv
->input_samples
* sizeof( float ) );
63 cfg
= faacEncGetCurrentConfiguration( pv
->faac
);
64 cfg
->mpegVersion
= MPEG4
;
65 cfg
->aacObjectType
= LOW
;
66 cfg
->allowMidside
= 1;
68 if (pv
->out_discrete_channels
== 6) {
69 /* we are preserving 5.1 audio into 6-channel AAC,
70 so indicate that we have an lfe channel */
77 cfg
->bitRate
= job
->abitrate
* 1000 / pv
->out_discrete_channels
; /* Per channel */
79 cfg
->outputFormat
= 0;
80 cfg
->inputFormat
= FAAC_INPUT_FLOAT
;
82 if (w
->amixdown
== HB_AMIXDOWN_6CH
&& w
->source_acodec
== HB_ACODEC_AC3
)
84 /* we are preserving 5.1 AC-3 audio into 6-channel AAC, and need to
85 re-map the output of deca52 into our own mapping - the mapping
86 below is the default mapping expected by QuickTime */
87 /* DTS output from libdca is already in the right mapping for QuickTime */
88 /* This doesn't seem to be correct for VLC on Linux */
89 cfg
->channel_map
[0] = 2;
90 cfg
->channel_map
[1] = 1;
91 cfg
->channel_map
[2] = 3;
92 cfg
->channel_map
[3] = 4;
93 cfg
->channel_map
[4] = 5;
94 cfg
->channel_map
[5] = 0;
97 if( !faacEncSetConfiguration( pv
->faac
, cfg
) )
99 hb_log( "faacEncSetConfiguration failed" );
104 if( faacEncGetDecoderSpecificInfo( pv
->faac
, &bytes
, &length
) < 0 )
106 hb_log( "faacEncGetDecoderSpecificInfo failed" );
110 memcpy( w
->config
->aac
.bytes
, bytes
, length
);
111 w
->config
->aac
.length
= length
;
114 pv
->list
= hb_list_init();
120 /***********************************************************************
122 ***********************************************************************
124 **********************************************************************/
125 void encfaacClose( hb_work_object_t
* w
)
127 hb_work_private_t
* pv
= w
->private_data
;
128 faacEncClose( pv
->faac
);
130 hb_list_empty( &pv
->list
);
132 w
->private_data
= NULL
;
135 /***********************************************************************
137 ***********************************************************************
139 **********************************************************************/
140 static hb_buffer_t
* Encode( hb_work_object_t
* w
)
142 hb_work_private_t
* pv
= w
->private_data
;
146 if( hb_list_bytes( pv
->list
) < pv
->input_samples
* sizeof( float ) )
152 hb_list_getbytes( pv
->list
, pv
->buf
, pv
->input_samples
* sizeof( float ),
155 buf
= hb_buffer_init( pv
->output_bytes
);
156 buf
->start
= pts
+ 90000 * pos
/ pv
->out_discrete_channels
/ sizeof( float ) / pv
->job
->arate
;
157 buf
->stop
= buf
->start
+ 90000 * pv
->input_samples
/ pv
->job
->arate
/ pv
->out_discrete_channels
;
158 buf
->size
= faacEncEncode( pv
->faac
, (int32_t *) pv
->buf
,
159 pv
->input_samples
, buf
->data
, pv
->output_bytes
);
160 buf
->frametype
= HB_FRAME_AUDIO
;
164 /* Encoding was successful but we got no data. Try to encode
166 hb_buffer_close( &buf
);
169 else if( buf
->size
< 0 )
171 hb_log( "faacEncEncode failed" );
172 hb_buffer_close( &buf
);
179 /***********************************************************************
181 ***********************************************************************
183 **********************************************************************/
184 int encfaacWork( hb_work_object_t
* w
, hb_buffer_t
** buf_in
,
185 hb_buffer_t
** buf_out
)
187 hb_work_private_t
* pv
= w
->private_data
;
190 hb_list_add( pv
->list
, *buf_in
);
193 *buf_out
= buf
= Encode( w
);
197 buf
->next
= Encode( w
);