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 };