diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-03-24 12:10:38 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-03-25 16:59:00 -0400 |
commit | be18738801b1723cc6aee126dfea466584012793 (patch) | |
tree | 5b2592d11b45a5c90dc9792695bdb9db41b90984 | |
parent | c70a6a41ddb759a5c6e8e810ebd603e39c36a315 (diff) | |
download | ffmpeg-be18738801b1723cc6aee126dfea466584012793.tar.gz |
Get audio_service_type for AC-3 based on bitstream mode in the AC-3 parser
and decoder, and vice-versa for the AC-3 encoder.
-rw-r--r-- | libavcodec/aac_ac3_parser.c | 1 | ||||
-rw-r--r-- | libavcodec/aac_ac3_parser.h | 1 | ||||
-rw-r--r-- | libavcodec/ac3.h | 1 | ||||
-rw-r--r-- | libavcodec/ac3_parser.c | 5 | ||||
-rw-r--r-- | libavcodec/ac3dec.c | 5 | ||||
-rw-r--r-- | libavcodec/ac3dec.h | 1 | ||||
-rw-r--r-- | libavcodec/ac3enc.c | 16 | ||||
-rw-r--r-- | libavcodec/eac3dec.c | 2 |
8 files changed, 29 insertions, 3 deletions
diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c index f65a4aa22b..58f30a4180 100644 --- a/libavcodec/aac_ac3_parser.c +++ b/libavcodec/aac_ac3_parser.c @@ -94,6 +94,7 @@ get_next: avctx->channel_layout = s->channel_layout; } avctx->frame_size = s->samples; + avctx->audio_service_type = s->service_type; } avctx->bit_rate = s->bit_rate; diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h index 257ea915a7..c4ed816d93 100644 --- a/libavcodec/aac_ac3_parser.h +++ b/libavcodec/aac_ac3_parser.h @@ -49,6 +49,7 @@ typedef struct AACAC3ParseContext { int bit_rate; int samples; int64_t channel_layout; + int service_type; int remaining_size; uint64_t state; diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index 607baa5ad6..e653b2e95d 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -87,6 +87,7 @@ typedef struct { uint16_t crc1; uint8_t sr_code; uint8_t bitstream_id; + uint8_t bitstream_mode; uint8_t channel_mode; uint8_t lfe_on; uint8_t frame_type; diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 16cffe822b..82eeda3e61 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -69,7 +69,7 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) skip_bits(gbc, 5); // skip bsid, already got it - skip_bits(gbc, 3); // skip bitstream mode + hdr->bitstream_mode = get_bits(gbc, 3); hdr->channel_mode = get_bits(gbc, 3); if(hdr->channel_mode == AC3_CHMODE_STEREO) { @@ -151,6 +151,9 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, hdr_info->channels = hdr.channels; hdr_info->channel_layout = hdr.channel_layout; hdr_info->samples = hdr.num_blocks * 256; + hdr_info->service_type = hdr.bitstream_mode; + if (hdr.bitstream_mode == 0x7 && hdr.channels > 1) + hdr_info->service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; if(hdr.bitstream_id>10) hdr_info->codec_id = CODEC_ID_EAC3; else if (hdr_info->codec_id == CODEC_ID_NONE) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 071cc6a54f..a1c8640599 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -273,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s) /* get decoding parameters from header info */ s->bit_alloc_params.sr_code = hdr.sr_code; + s->bitstream_mode = hdr.bitstream_mode; s->channel_mode = hdr.channel_mode; s->channel_layout = hdr.channel_layout; s->lfe_on = hdr.lfe_on; @@ -1399,6 +1400,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, if(s->out_channels < s->channels) s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; } + /* set audio service type based on bitstream mode for AC-3 */ + avctx->audio_service_type = s->bitstream_mode; + if (s->bitstream_mode == 0x7 && s->channels > 1) + avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; /* decode the audio blocks */ channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 7e6483ddb3..9d0ffc313e 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -79,6 +79,7 @@ typedef struct { int bit_rate; ///< stream bit rate, in bits-per-second int sample_rate; ///< sample frequency, in Hz int num_blocks; ///< number of audio blocks + int bitstream_mode; ///< bitstream mode (bsmod) int channel_mode; ///< channel mode (acmod) int channel_layout; ///< channel layout int lfe_on; ///< lfe channel in use diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 6a7610c322..a58a2c1e02 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -1657,6 +1657,18 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) if (s->cutoff > (s->sample_rate >> 1)) s->cutoff = s->sample_rate >> 1; + /* validate audio service type / channels combination */ + if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE && + avctx->channels == 1) || + ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY || + avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY || + avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER) + && avctx->channels > 1)) { + av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the " + "specified number of channels\n"); + return AVERROR(EINVAL); + } + return 0; } @@ -1799,7 +1811,9 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx) return ret; s->bitstream_id = 8 + s->bit_alloc.sr_shift; - s->bitstream_mode = 0; /* complete main audio service */ + s->bitstream_mode = avctx->audio_service_type; + if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE) + s->bitstream_mode = 0x7; s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code]; s->bits_written = 0; diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c index 0c9d8e028c..54007686dd 100644 --- a/libavcodec/eac3dec.c +++ b/libavcodec/eac3dec.c @@ -410,7 +410,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s) /* informational metadata */ if (get_bits1(gbc)) { - skip_bits(gbc, 3); // skip bit stream mode + s->bitstream_mode = get_bits(gbc, 3); skip_bits(gbc, 2); // skip copyright bit and original bitstream bit if (s->channel_mode == AC3_CHMODE_STEREO) { skip_bits(gbc, 4); // skip Dolby surround and headphone mode |