[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