Commit be187388 authored by Justin Ruggles's avatar 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.
parent c70a6a41
...@@ -94,6 +94,7 @@ get_next: ...@@ -94,6 +94,7 @@ get_next:
avctx->channel_layout = s->channel_layout; avctx->channel_layout = s->channel_layout;
} }
avctx->frame_size = s->samples; avctx->frame_size = s->samples;
avctx->audio_service_type = s->service_type;
} }
avctx->bit_rate = s->bit_rate; avctx->bit_rate = s->bit_rate;
......
...@@ -49,6 +49,7 @@ typedef struct AACAC3ParseContext { ...@@ -49,6 +49,7 @@ typedef struct AACAC3ParseContext {
int bit_rate; int bit_rate;
int samples; int samples;
int64_t channel_layout; int64_t channel_layout;
int service_type;
int remaining_size; int remaining_size;
uint64_t state; uint64_t state;
......
...@@ -87,6 +87,7 @@ typedef struct { ...@@ -87,6 +87,7 @@ typedef struct {
uint16_t crc1; uint16_t crc1;
uint8_t sr_code; uint8_t sr_code;
uint8_t bitstream_id; uint8_t bitstream_id;
uint8_t bitstream_mode;
uint8_t channel_mode; uint8_t channel_mode;
uint8_t lfe_on; uint8_t lfe_on;
uint8_t frame_type; uint8_t frame_type;
......
...@@ -69,7 +69,7 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) ...@@ -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, 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); hdr->channel_mode = get_bits(gbc, 3);
if(hdr->channel_mode == AC3_CHMODE_STEREO) { if(hdr->channel_mode == AC3_CHMODE_STEREO) {
...@@ -151,6 +151,9 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, ...@@ -151,6 +151,9 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
hdr_info->channels = hdr.channels; hdr_info->channels = hdr.channels;
hdr_info->channel_layout = hdr.channel_layout; hdr_info->channel_layout = hdr.channel_layout;
hdr_info->samples = hdr.num_blocks * 256; 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) if(hdr.bitstream_id>10)
hdr_info->codec_id = CODEC_ID_EAC3; hdr_info->codec_id = CODEC_ID_EAC3;
else if (hdr_info->codec_id == CODEC_ID_NONE) else if (hdr_info->codec_id == CODEC_ID_NONE)
......
...@@ -273,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s) ...@@ -273,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s)
/* get decoding parameters from header info */ /* get decoding parameters from header info */
s->bit_alloc_params.sr_code = hdr.sr_code; s->bit_alloc_params.sr_code = hdr.sr_code;
s->bitstream_mode = hdr.bitstream_mode;
s->channel_mode = hdr.channel_mode; s->channel_mode = hdr.channel_mode;
s->channel_layout = hdr.channel_layout; s->channel_layout = hdr.channel_layout;
s->lfe_on = hdr.lfe_on; s->lfe_on = hdr.lfe_on;
...@@ -1399,6 +1400,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, ...@@ -1399,6 +1400,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
if(s->out_channels < s->channels) if(s->out_channels < s->channels)
s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; 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 */ /* decode the audio blocks */
channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
......
...@@ -79,6 +79,7 @@ typedef struct { ...@@ -79,6 +79,7 @@ typedef struct {
int bit_rate; ///< stream bit rate, in bits-per-second int bit_rate; ///< stream bit rate, in bits-per-second
int sample_rate; ///< sample frequency, in Hz int sample_rate; ///< sample frequency, in Hz
int num_blocks; ///< number of audio blocks int num_blocks; ///< number of audio blocks
int bitstream_mode; ///< bitstream mode (bsmod)
int channel_mode; ///< channel mode (acmod) int channel_mode; ///< channel mode (acmod)
int channel_layout; ///< channel layout int channel_layout; ///< channel layout
int lfe_on; ///< lfe channel in use int lfe_on; ///< lfe channel in use
......
...@@ -1657,6 +1657,18 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) ...@@ -1657,6 +1657,18 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
if (s->cutoff > (s->sample_rate >> 1)) if (s->cutoff > (s->sample_rate >> 1))
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; return 0;
} }
...@@ -1799,7 +1811,9 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx) ...@@ -1799,7 +1811,9 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx)
return ret; return ret;
s->bitstream_id = 8 + s->bit_alloc.sr_shift; 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->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
s->bits_written = 0; s->bits_written = 0;
......
...@@ -410,7 +410,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s) ...@@ -410,7 +410,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
/* informational metadata */ /* informational metadata */
if (get_bits1(gbc)) { 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 skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
if (s->channel_mode == AC3_CHMODE_STEREO) { if (s->channel_mode == AC3_CHMODE_STEREO) {
skip_bits(gbc, 4); // skip Dolby surround and headphone mode skip_bits(gbc, 4); // skip Dolby surround and headphone mode
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment