Mercurial > libavcodec.hg
comparison ac3enc.c @ 9513:24532a2d9d2c libavcodec
Add channel layout support to the AC-3 encoder.
author | jbr |
---|---|
date | Sun, 19 Apr 2009 15:06:13 +0000 |
parents | 42803399ba8a |
children | f15a920ce40e |
comparison
equal
deleted
inserted
replaced
9512:ba5d9a97ab2f | 9513:24532a2d9d2c |
---|---|
28 #include "libavutil/crc.h" | 28 #include "libavutil/crc.h" |
29 #include "avcodec.h" | 29 #include "avcodec.h" |
30 #include "get_bits.h" // for ff_reverse | 30 #include "get_bits.h" // for ff_reverse |
31 #include "put_bits.h" | 31 #include "put_bits.h" |
32 #include "ac3.h" | 32 #include "ac3.h" |
33 #include "audioconvert.h" | |
33 | 34 |
34 typedef struct AC3EncodeContext { | 35 typedef struct AC3EncodeContext { |
35 PutBitContext pb; | 36 PutBitContext pb; |
36 int nb_channels; | 37 int nb_channels; |
37 int nb_all_channels; | 38 int nb_all_channels; |
607 } | 608 } |
608 #endif | 609 #endif |
609 return 0; | 610 return 0; |
610 } | 611 } |
611 | 612 |
613 static av_cold int set_channel_info(AC3EncodeContext *s, int channels, | |
614 int64_t *channel_layout) | |
615 { | |
616 int ch_layout; | |
617 | |
618 if (channels < 1 || channels > AC3_MAX_CHANNELS) | |
619 return -1; | |
620 if ((uint64_t)*channel_layout > 0x7FF) | |
621 return -1; | |
622 ch_layout = *channel_layout; | |
623 if (!ch_layout) | |
624 ch_layout = avcodec_guess_channel_layout(channels, CODEC_ID_AC3, NULL); | |
625 if (avcodec_channel_layout_num_channels(ch_layout) != channels) | |
626 return -1; | |
627 | |
628 s->lfe = !!(ch_layout & CH_LOW_FREQUENCY); | |
629 s->nb_all_channels = channels; | |
630 s->nb_channels = channels - s->lfe; | |
631 s->lfe_channel = s->lfe ? s->nb_channels : -1; | |
632 if (s->lfe) | |
633 ch_layout -= CH_LOW_FREQUENCY; | |
634 | |
635 switch (ch_layout) { | |
636 case CH_LAYOUT_MONO: s->channel_mode = AC3_CHMODE_MONO; break; | |
637 case CH_LAYOUT_STEREO: s->channel_mode = AC3_CHMODE_STEREO; break; | |
638 case CH_LAYOUT_SURROUND: s->channel_mode = AC3_CHMODE_3F; break; | |
639 case CH_LAYOUT_2_1: s->channel_mode = AC3_CHMODE_2F1R; break; | |
640 case CH_LAYOUT_4POINT0: s->channel_mode = AC3_CHMODE_3F1R; break; | |
641 case CH_LAYOUT_QUAD: | |
642 case CH_LAYOUT_2_2: s->channel_mode = AC3_CHMODE_2F2R; break; | |
643 case CH_LAYOUT_5POINT0: | |
644 case CH_LAYOUT_5POINT0_BACK: s->channel_mode = AC3_CHMODE_3F2R; break; | |
645 default: | |
646 return -1; | |
647 } | |
648 | |
649 s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe]; | |
650 *channel_layout = ch_layout; | |
651 if (s->lfe) | |
652 *channel_layout |= CH_LOW_FREQUENCY; | |
653 | |
654 return 0; | |
655 } | |
656 | |
612 static av_cold int AC3_encode_init(AVCodecContext *avctx) | 657 static av_cold int AC3_encode_init(AVCodecContext *avctx) |
613 { | 658 { |
614 int freq = avctx->sample_rate; | 659 int freq = avctx->sample_rate; |
615 int bitrate = avctx->bit_rate; | 660 int bitrate = avctx->bit_rate; |
616 int channels = avctx->channels; | |
617 AC3EncodeContext *s = avctx->priv_data; | 661 AC3EncodeContext *s = avctx->priv_data; |
618 int i, j, ch; | 662 int i, j, ch; |
619 float alpha; | 663 float alpha; |
620 int bw_code; | 664 int bw_code; |
621 static const uint8_t channel_mode_defs[6] = { | |
622 0x01, /* C */ | |
623 0x02, /* L R */ | |
624 0x03, /* L C R */ | |
625 0x06, /* L R SL SR */ | |
626 0x07, /* L C R SL SR */ | |
627 0x07, /* L C R SL SR (+LFE) */ | |
628 }; | |
629 | 665 |
630 avctx->frame_size = AC3_FRAME_SIZE; | 666 avctx->frame_size = AC3_FRAME_SIZE; |
631 | 667 |
632 ac3_common_init(); | 668 ac3_common_init(); |
633 | 669 |
634 /* number of channels */ | 670 if (set_channel_info(s, avctx->channels, &avctx->channel_layout)) { |
635 if (channels < 1 || channels > 6) | 671 av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n"); |
636 return -1; | 672 return -1; |
637 s->channel_mode = channel_mode_defs[channels - 1]; | 673 } |
638 s->lfe = (channels == 6) ? 1 : 0; | |
639 s->nb_all_channels = channels; | |
640 s->nb_channels = channels > 5 ? 5 : channels; | |
641 s->lfe_channel = s->lfe ? 5 : -1; | |
642 s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe]; | |
643 | 674 |
644 /* frequency */ | 675 /* frequency */ |
645 for(i=0;i<3;i++) { | 676 for(i=0;i<3;i++) { |
646 for(j=0;j<3;j++) | 677 for(j=0;j<3;j++) |
647 if ((ff_ac3_sample_rate_tab[j] >> i) == freq) | 678 if ((ff_ac3_sample_rate_tab[j] >> i) == freq) |
1366 AC3_encode_frame, | 1397 AC3_encode_frame, |
1367 AC3_encode_close, | 1398 AC3_encode_close, |
1368 NULL, | 1399 NULL, |
1369 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, | 1400 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, |
1370 .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), | 1401 .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), |
1402 .channel_layouts = (int64_t[]){ | |
1403 CH_LAYOUT_MONO, | |
1404 CH_LAYOUT_STEREO, | |
1405 CH_LAYOUT_2_1, | |
1406 CH_LAYOUT_SURROUND, | |
1407 CH_LAYOUT_2_2, | |
1408 CH_LAYOUT_QUAD, | |
1409 CH_LAYOUT_4POINT0, | |
1410 CH_LAYOUT_5POINT0, | |
1411 CH_LAYOUT_5POINT0_BACK, | |
1412 (CH_LAYOUT_MONO | CH_LOW_FREQUENCY), | |
1413 (CH_LAYOUT_STEREO | CH_LOW_FREQUENCY), | |
1414 (CH_LAYOUT_2_1 | CH_LOW_FREQUENCY), | |
1415 (CH_LAYOUT_SURROUND | CH_LOW_FREQUENCY), | |
1416 (CH_LAYOUT_2_2 | CH_LOW_FREQUENCY), | |
1417 (CH_LAYOUT_QUAD | CH_LOW_FREQUENCY), | |
1418 (CH_LAYOUT_4POINT0 | CH_LOW_FREQUENCY), | |
1419 CH_LAYOUT_5POINT1, | |
1420 CH_LAYOUT_5POINT1_BACK, | |
1421 0 }, | |
1371 }; | 1422 }; |