1 /* $Id: encac3.c,v 1.23 2005/10/13 23:47:06 titer Exp $
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. */
11 struct hb_work_private_s
14 AVCodecContext * context;
16 int out_discrete_channels;
17 unsigned long input_samples;
18 unsigned long output_bytes;
24 int encac3Init( hb_work_object_t *, hb_job_t * );
25 int encac3Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
26 void encac3Close( hb_work_object_t * );
28 #define AC3_SAMPLES_PER_FRAME 1536
29 #define AC3_MAX_CODED_FRAME_SIZE 3840
31 hb_work_object_t hb_encac3 =
34 "AC-3 encoder (libavcodec)",
40 int encac3Init( hb_work_object_t * w, hb_job_t * job )
43 AVCodecContext * context;
44 hb_audio_t * audio = w->audio;
46 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
51 pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
52 pv->input_samples = AC3_SAMPLES_PER_FRAME * pv->out_discrete_channels;
53 pv->output_bytes = AC3_MAX_CODED_FRAME_SIZE;
55 pv->buf = malloc( pv->input_samples * sizeof( float ) );
56 pv->samples = malloc( pv->input_samples * sizeof( int16_t ) );
58 codec = avcodec_find_encoder( CODEC_ID_AC3 );
61 hb_log( "encac3Init: avcodec_find_encoder "
64 context = avcodec_alloc_context();
66 context->channel_layout = CH_LAYOUT_STEREO;
67 switch( audio->config.out.mixdown )
69 case HB_AMIXDOWN_MONO:
70 context->channel_layout = CH_LAYOUT_MONO;
73 case HB_AMIXDOWN_STEREO:
74 case HB_AMIXDOWN_DOLBY:
75 case HB_AMIXDOWN_DOLBYPLII:
76 context->channel_layout = CH_LAYOUT_STEREO;
80 context->channel_layout = CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY;
84 hb_log(" encac3Init: bad mixdown" );
88 context->bit_rate = audio->config.out.bitrate * 1000;
89 context->sample_rate = audio->config.out.samplerate;
90 context->channels = pv->out_discrete_channels;
92 if( hb_avcodec_open( context, codec ) )
94 hb_log( "encac3Init: avcodec_open failed" );
96 pv->context = context;
98 pv->list = hb_list_init();
103 /***********************************************************************
105 ***********************************************************************
107 **********************************************************************/
108 void encac3Close( hb_work_object_t * w )
110 hb_work_private_t * pv = w->private_data;
116 hb_deep_log( 2, "encac3: closing libavcodec" );
117 if ( pv->context->codec )
118 avcodec_flush_buffers( pv->context );
119 hb_avcodec_close( pv->context );
135 hb_list_empty( &pv->list );
138 w->private_data = NULL;
142 static hb_buffer_t * Encode( hb_work_object_t * w )
144 hb_work_private_t * pv = w->private_data;
146 hb_audio_t * audio = w->audio;
150 if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) )
155 hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
158 hb_chan_map_t *map = NULL;
159 if ( audio->config.in.codec == HB_ACODEC_AC3 )
161 map = &hb_ac3_chan_map;
163 else if ( audio->config.in.codec == HB_ACODEC_DCA )
165 map = &hb_qt_chan_map;
170 switch (audio->config.out.mixdown)
172 case HB_AMIXDOWN_MONO:
173 layout = HB_INPUT_CH_LAYOUT_MONO;
175 case HB_AMIXDOWN_STEREO:
176 case HB_AMIXDOWN_DOLBY:
177 case HB_AMIXDOWN_DOLBYPLII:
178 layout = HB_INPUT_CH_LAYOUT_STEREO;
180 case HB_AMIXDOWN_6CH:
182 layout = HB_INPUT_CH_LAYOUT_3F2R | HB_INPUT_CH_LAYOUT_HAS_LFE;
185 hb_layout_remap( map, &hb_smpte_chan_map, layout,
186 (float*)pv->buf, AC3_SAMPLES_PER_FRAME);
189 for (ii = 0; ii < pv->input_samples; ii++)
191 pv->samples[ii] = (int16_t)((float*)pv->buf)[ii];
194 buf = hb_buffer_init( pv->output_bytes );
195 buf->size = avcodec_encode_audio( pv->context, buf->data, buf->alloc,
198 buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
199 buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME / audio->config.out.samplerate;
201 buf->frametype = HB_FRAME_AUDIO;
205 hb_buffer_close( &buf );
208 else if (buf->size < 0)
210 hb_log( "encac3: avcodec_encode_audio failed" );
211 hb_buffer_close( &buf );
218 /***********************************************************************
220 ***********************************************************************
222 **********************************************************************/
223 int encac3Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
224 hb_buffer_t ** buf_out )
226 hb_work_private_t * pv = w->private_data;
227 hb_buffer_t * in = *buf_in, * buf;
231 /* EOF on input - send it downstream & say we're done */
237 if ( pv->context == NULL || pv->context->codec == NULL )
239 // No encoder context. Nothing we can do.
243 hb_list_add( pv->list, in );
246 *buf_out = buf = Encode( w );
250 buf->next = Encode( w );