[FFmpeg-cvslog] Get audio_service_type for AC-3 based on bitstream mode in the AC-3 parser
Justin Ruggles
git at videolan.org
Sat Mar 26 03:10:00 CET 2011
ffmpeg | branch: master | Justin Ruggles <justin.ruggles at gmail.com> | Thu Mar 24 12:10:38 2011 -0400| [be18738801b1723cc6aee126dfea466584012793] | committer: Justin Ruggles
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.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=be18738801b1723cc6aee126dfea466584012793
---
libavcodec/aac_ac3_parser.c | 1 +
libavcodec/aac_ac3_parser.h | 1 +
libavcodec/ac3.h | 1 +
libavcodec/ac3_parser.c | 5 ++++-
libavcodec/ac3dec.c | 5 +++++
libavcodec/ac3dec.h | 1 +
libavcodec/ac3enc.c | 16 +++++++++++++++-
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 f65a4aa..58f30a4 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 257ea91..c4ed816 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 607baa5..e653b2e 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 16cffe8..82eeda3 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 071cc6a..a1c8640 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 7e6483d..9d0ffc3 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 6a7610c..a58a2c1 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 0c9d8e0..5400768 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
More information about the ffmpeg-cvslog
mailing list