| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -30,6 +30,7 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "get_bits.h" // for ff_reverse | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "put_bits.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "ac3.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "audioconvert.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			typedef struct AC3EncodeContext { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    PutBitContext pb; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -609,37 +610,67 @@ static int compute_bit_allocation(AC3EncodeContext *s, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static av_cold int set_channel_info(AC3EncodeContext *s, int channels, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                    int64_t *channel_layout) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int ch_layout; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (channels < 1 || channels > AC3_MAX_CHANNELS) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if ((uint64_t)*channel_layout > 0x7FF) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ch_layout = *channel_layout; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (!ch_layout) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        ch_layout = avcodec_guess_channel_layout(channels, CODEC_ID_AC3, NULL); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (avcodec_channel_layout_num_channels(ch_layout) != channels) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->lfe = !!(ch_layout & CH_LOW_FREQUENCY); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->nb_all_channels = channels; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->nb_channels = channels - s->lfe; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->lfe_channel = s->lfe ? s->nb_channels : -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (s->lfe) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        ch_layout -= CH_LOW_FREQUENCY; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    switch (ch_layout) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_MONO:           s->channel_mode = AC3_CHMODE_MONO;   break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_STEREO:         s->channel_mode = AC3_CHMODE_STEREO; break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_SURROUND:       s->channel_mode = AC3_CHMODE_3F;     break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_2_1:            s->channel_mode = AC3_CHMODE_2F1R;   break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_4POINT0:        s->channel_mode = AC3_CHMODE_3F1R;   break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_QUAD: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_2_2:            s->channel_mode = AC3_CHMODE_2F2R;   break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_5POINT0: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case CH_LAYOUT_5POINT0_BACK:   s->channel_mode = AC3_CHMODE_3F2R;   break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    *channel_layout = ch_layout; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (s->lfe) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        *channel_layout |= CH_LOW_FREQUENCY; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static av_cold int AC3_encode_init(AVCodecContext *avctx) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int freq = avctx->sample_rate; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int bitrate = avctx->bit_rate; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int channels = avctx->channels; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AC3EncodeContext *s = avctx->priv_data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int i, j, ch; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    float alpha; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int bw_code; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    static const uint8_t channel_mode_defs[6] = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0x01, /* C */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0x02, /* L R */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0x03, /* L C R */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0x06, /* L R SL SR */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0x07, /* L C R SL SR */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0x07, /* L C R SL SR (+LFE) */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    avctx->frame_size = AC3_FRAME_SIZE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ac3_common_init(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* number of channels */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (channels < 1 || channels > 6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (set_channel_info(s, avctx->channels, &avctx->channel_layout)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->channel_mode = channel_mode_defs[channels - 1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->lfe = (channels == 6) ? 1 : 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->nb_all_channels = channels; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->nb_channels = channels > 5 ? 5 : channels; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->lfe_channel = s->lfe ? 5 : -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* frequency */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for(i=0;i<3;i++) { | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1368,4 +1399,24 @@ AVCodec ac3_encoder = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    NULL, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .channel_layouts = (int64_t[]){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_MONO, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_STEREO, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_2_1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_SURROUND, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_2_2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_QUAD, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_4POINT0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_5POINT0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_5POINT0_BACK, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_MONO     | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_STEREO   | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_2_1      | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_SURROUND | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_2_2      | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_QUAD     | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       (CH_LAYOUT_4POINT0  | CH_LOW_FREQUENCY), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_5POINT1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        CH_LAYOUT_5POINT1_BACK, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        0 }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; |