mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec/eac3: add support for dependent stream
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
e5819fa629
commit
ae92970976
@ -49,6 +49,7 @@ version <next>:
|
||||
- hapqa_extract bitstream filter
|
||||
- filter_units bitstream filter
|
||||
- AV1 Support through libaom
|
||||
- E-AC-3 dependent frames support
|
||||
|
||||
|
||||
version 3.4:
|
||||
|
@ -86,13 +86,16 @@ get_next:
|
||||
the frame). */
|
||||
if (avctx->codec_id != AV_CODEC_ID_AAC) {
|
||||
avctx->sample_rate = s->sample_rate;
|
||||
avctx->channels = s->channels;
|
||||
avctx->channel_layout = s->channel_layout;
|
||||
if (avctx->codec_id != AV_CODEC_ID_EAC3) {
|
||||
avctx->channels = s->channels;
|
||||
avctx->channel_layout = s->channel_layout;
|
||||
}
|
||||
s1->duration = s->samples;
|
||||
avctx->audio_service_type = s->service_type;
|
||||
}
|
||||
|
||||
avctx->bit_rate = s->bit_rate;
|
||||
if (avctx->codec_id != AV_CODEC_ID_EAC3)
|
||||
avctx->bit_rate = s->bit_rate;
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -218,8 +218,8 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
|
||||
else if (hdr_info->codec_id == AV_CODEC_ID_NONE)
|
||||
hdr_info->codec_id = AV_CODEC_ID_AC3;
|
||||
|
||||
*need_next_header = (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT);
|
||||
*new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT);
|
||||
*need_next_header = *new_frame_start || (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT);
|
||||
return hdr.frame_size;
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,25 @@ static const uint8_t ac3_default_coeffs[8][5][2] = {
|
||||
{ { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
|
||||
};
|
||||
|
||||
static const uint64_t custom_channel_map_locations[16][2] = {
|
||||
{ 1, AV_CH_FRONT_LEFT },
|
||||
{ 1, AV_CH_FRONT_CENTER },
|
||||
{ 1, AV_CH_FRONT_RIGHT },
|
||||
{ 1, AV_CH_SIDE_LEFT },
|
||||
{ 1, AV_CH_SIDE_RIGHT },
|
||||
{ 0, AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER },
|
||||
{ 0, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
|
||||
{ 0, AV_CH_BACK_CENTER },
|
||||
{ 0, AV_CH_TOP_CENTER },
|
||||
{ 0, AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT },
|
||||
{ 0, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
|
||||
{ 0, AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT},
|
||||
{ 0, AV_CH_TOP_FRONT_CENTER },
|
||||
{ 0, AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT },
|
||||
{ 0, AV_CH_LOW_FREQUENCY_2 },
|
||||
{ 1, AV_CH_LOW_FREQUENCY },
|
||||
};
|
||||
|
||||
/**
|
||||
* Symmetrical Dequantization
|
||||
* reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
|
||||
@ -317,6 +336,7 @@ static int parse_frame_header(AC3DecodeContext *s)
|
||||
s->fbw_channels = s->channels - s->lfe_on;
|
||||
s->lfe_ch = s->fbw_channels + 1;
|
||||
s->frame_size = hdr.frame_size;
|
||||
s->superframe_size += hdr.frame_size;
|
||||
s->preferred_downmix = AC3_DMIXMOD_NOTINDICATED;
|
||||
s->center_mix_level = hdr.center_mix_level;
|
||||
s->center_mix_level_ltrt = 4; // -3.0dB
|
||||
@ -683,7 +703,7 @@ static void do_rematrixing(AC3DecodeContext *s)
|
||||
* Convert frequency domain coefficients to time-domain audio samples.
|
||||
* reference: Section 7.9.4 Transformation Equations
|
||||
*/
|
||||
static inline void do_imdct(AC3DecodeContext *s, int channels)
|
||||
static inline void do_imdct(AC3DecodeContext *s, int channels, int offset)
|
||||
{
|
||||
int ch;
|
||||
|
||||
@ -695,25 +715,25 @@ static inline void do_imdct(AC3DecodeContext *s, int channels)
|
||||
x[i] = s->transform_coeffs[ch][2 * i];
|
||||
s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
|
||||
#if USE_FIXED
|
||||
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
|
||||
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset],
|
||||
s->tmp_output, s->window, 128, 8);
|
||||
#else
|
||||
s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
|
||||
s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset],
|
||||
s->tmp_output, s->window, 128);
|
||||
#endif
|
||||
for (i = 0; i < 128; i++)
|
||||
x[i] = s->transform_coeffs[ch][2 * i + 1];
|
||||
s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
|
||||
s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1 + offset], x);
|
||||
} else {
|
||||
s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
|
||||
#if USE_FIXED
|
||||
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
|
||||
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset],
|
||||
s->tmp_output, s->window, 128, 8);
|
||||
#else
|
||||
s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
|
||||
s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset],
|
||||
s->tmp_output, s->window, 128);
|
||||
#endif
|
||||
memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(FFTSample));
|
||||
memcpy(s->delay[ch - 1 + offset], s->tmp_output + 128, 128 * sizeof(FFTSample));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1063,7 +1083,7 @@ static inline int coupling_coordinates(AC3DecodeContext *s, int blk)
|
||||
/**
|
||||
* Decode a single audio block from the AC-3 bitstream.
|
||||
*/
|
||||
static int decode_audio_block(AC3DecodeContext *s, int blk)
|
||||
static int decode_audio_block(AC3DecodeContext *s, int blk, int offset)
|
||||
{
|
||||
int fbw_channels = s->fbw_channels;
|
||||
int channel_mode = s->channel_mode;
|
||||
@ -1426,7 +1446,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
|
||||
ac3_upmix_delay(s);
|
||||
}
|
||||
|
||||
do_imdct(s, s->channels);
|
||||
do_imdct(s, s->channels, offset);
|
||||
|
||||
if (downmix_output) {
|
||||
#if USE_FIXED
|
||||
@ -1449,7 +1469,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
|
||||
s->out_channels, s->fbw_channels, 128);
|
||||
}
|
||||
|
||||
do_imdct(s, s->out_channels);
|
||||
do_imdct(s, s->out_channels, offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1463,14 +1483,19 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
{
|
||||
AVFrame *frame = data;
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
int buf_size, full_buf_size = avpkt->size;
|
||||
AC3DecodeContext *s = avctx->priv_data;
|
||||
int blk, ch, err, ret;
|
||||
int blk, ch, err, offset, ret;
|
||||
int got_independent_frame = 0;
|
||||
const uint8_t *channel_map;
|
||||
uint8_t extended_channel_map[AC3_MAX_CHANNELS * 2];
|
||||
const SHORTFLOAT *output[AC3_MAX_CHANNELS];
|
||||
enum AVMatrixEncoding matrix_encoding;
|
||||
AVDownmixInfo *downmix_info;
|
||||
|
||||
s->superframe_size = 0;
|
||||
|
||||
buf_size = full_buf_size;
|
||||
/* copy input buffer to decoder context to avoid reading past the end
|
||||
of the buffer, which can be caused by a damaged input stream. */
|
||||
if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {
|
||||
@ -1488,6 +1513,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
av_lfg_init_from_data(&s->dith_state, s->input_buffer, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
|
||||
|
||||
buf = s->input_buffer;
|
||||
dependent_frame:
|
||||
/* initialize the GetBitContext with the start of valid AC-3 Frame */
|
||||
if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0)
|
||||
return ret;
|
||||
@ -1511,11 +1537,11 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
break;
|
||||
case AAC_AC3_PARSE_ERROR_FRAME_TYPE:
|
||||
/* skip frame if CRC is ok. otherwise use error concealment. */
|
||||
/* TODO: add support for substreams and dependent frames */
|
||||
if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
|
||||
/* TODO: add support for substreams */
|
||||
if (s->substreamid) {
|
||||
av_log(avctx, AV_LOG_DEBUG,
|
||||
"unsupported frame type %d: skipping frame\n",
|
||||
s->frame_type);
|
||||
"unsupported substream %d: skipping frame\n",
|
||||
s->substreamid);
|
||||
*got_frame_ptr = 0;
|
||||
return buf_size;
|
||||
} else {
|
||||
@ -1546,10 +1572,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
/* if frame is ok, set audio parameters */
|
||||
if (!err) {
|
||||
avctx->sample_rate = s->sample_rate;
|
||||
avctx->bit_rate = s->bit_rate;
|
||||
if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT && !got_independent_frame) {
|
||||
av_log(avctx, AV_LOG_WARNING, "Ignoring dependent frame without independent frame.\n");
|
||||
*got_frame_ptr = 0;
|
||||
return FFMIN(full_buf_size, s->frame_size);
|
||||
}
|
||||
|
||||
/* channel config */
|
||||
@ -1594,29 +1620,25 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
if (s->bitstream_mode == 0x7 && s->channels > 1)
|
||||
avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
|
||||
|
||||
/* get output buffer */
|
||||
frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
|
||||
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
/* decode the audio blocks */
|
||||
channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
|
||||
offset = s->frame_type == EAC3_FRAME_TYPE_DEPENDENT ? AC3_MAX_CHANNELS : 0;
|
||||
for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {
|
||||
output[ch] = s->output[ch];
|
||||
s->outptr[ch] = s->output[ch];
|
||||
output[ch] = s->output[ch + offset];
|
||||
s->outptr[ch] = s->output[ch + offset];
|
||||
}
|
||||
for (ch = 0; ch < s->channels; ch++) {
|
||||
if (ch < s->out_channels)
|
||||
s->outptr[channel_map[ch]] = (SHORTFLOAT *)frame->data[ch];
|
||||
s->outptr[channel_map[ch]] = s->output_buffer[ch + offset];
|
||||
}
|
||||
for (blk = 0; blk < s->num_blocks; blk++) {
|
||||
if (!err && decode_audio_block(s, blk)) {
|
||||
if (!err && decode_audio_block(s, blk, offset)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
|
||||
err = 1;
|
||||
}
|
||||
if (err)
|
||||
for (ch = 0; ch < s->out_channels; ch++)
|
||||
memcpy(((SHORTFLOAT*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
|
||||
memcpy(s->output_buffer[ch + offset] + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
|
||||
for (ch = 0; ch < s->out_channels; ch++)
|
||||
output[ch] = s->outptr[channel_map[ch]];
|
||||
for (ch = 0; ch < s->out_channels; ch++) {
|
||||
@ -1625,11 +1647,100 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
|
||||
|
||||
/* keep last block for error concealment in next frame */
|
||||
for (ch = 0; ch < s->out_channels; ch++)
|
||||
memcpy(s->output[ch], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
|
||||
memcpy(s->output[ch + offset], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
|
||||
|
||||
/* check if there is dependent frame */
|
||||
if (buf_size > s->frame_size) {
|
||||
AC3HeaderInfo hdr;
|
||||
int err;
|
||||
|
||||
if ((ret = init_get_bits8(&s->gbc, buf + s->frame_size, buf_size - s->frame_size)) < 0)
|
||||
return ret;
|
||||
|
||||
err = ff_ac3_parse_header(&s->gbc, &hdr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (hdr.frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
|
||||
if (hdr.num_blocks != s->num_blocks || s->sample_rate != hdr.sample_rate) {
|
||||
av_log(avctx, AV_LOG_WARNING, "Ignoring non-compatible dependent frame.\n");
|
||||
} else {
|
||||
buf += s->frame_size;
|
||||
buf_size -= s->frame_size;
|
||||
s->prev_output_mode = s->output_mode;
|
||||
s->prev_bit_rate = s->bit_rate;
|
||||
got_independent_frame = 1;
|
||||
goto dependent_frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
|
||||
|
||||
/* if frame is ok, set audio parameters */
|
||||
if (!err) {
|
||||
avctx->sample_rate = s->sample_rate;
|
||||
avctx->bit_rate = s->bit_rate + s->prev_bit_rate;
|
||||
}
|
||||
|
||||
for (ch = 0; ch < 16; ch++)
|
||||
extended_channel_map[ch] = ch;
|
||||
|
||||
if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
|
||||
uint64_t ich_layout = avpriv_ac3_channel_layout_tab[s->prev_output_mode & ~AC3_OUTPUT_LFEON];
|
||||
uint64_t channel_layout;
|
||||
int extend = 0;
|
||||
|
||||
if (s->prev_output_mode & AC3_OUTPUT_LFEON)
|
||||
ich_layout |= AV_CH_LOW_FREQUENCY;
|
||||
|
||||
channel_layout = ich_layout;
|
||||
for (ch = 0; ch < 16; ch++) {
|
||||
if (s->channel_map & (1 << (15 - ch))) {
|
||||
channel_layout |= custom_channel_map_locations[ch][1];
|
||||
}
|
||||
}
|
||||
|
||||
avctx->channel_layout = channel_layout;
|
||||
avctx->channels = av_get_channel_layout_nb_channels(channel_layout);
|
||||
|
||||
for (ch = 0; ch < 16; ch++) {
|
||||
if (s->channel_map & (1 << (15 - ch))) {
|
||||
if (custom_channel_map_locations[ch][0]) {
|
||||
int index = av_get_channel_layout_channel_index(channel_layout,
|
||||
custom_channel_map_locations[ch][1]);
|
||||
if (index < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
extended_channel_map[index] = offset + channel_map[extend++];
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((1LL << i) & custom_channel_map_locations[ch][1]) {
|
||||
int index = av_get_channel_layout_channel_index(channel_layout,
|
||||
1LL << i);
|
||||
if (index < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
extended_channel_map[index] = offset + channel_map[extend++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
|
||||
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
for (ch = 0; ch < avctx->channels; ch++) {
|
||||
int map = extended_channel_map[ch];
|
||||
memcpy((SHORTFLOAT *)frame->data[ch], s->output_buffer[map],
|
||||
s->num_blocks * AC3_BLOCK_SIZE * sizeof(SHORTFLOAT));
|
||||
}
|
||||
|
||||
/*
|
||||
* AVMatrixEncoding
|
||||
@ -1689,7 +1800,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
|
||||
|
||||
*got_frame_ptr = 1;
|
||||
|
||||
return FFMIN(buf_size, s->frame_size);
|
||||
return FFMIN(full_buf_size, s->superframe_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,6 +76,7 @@ typedef struct AC3DecodeContext {
|
||||
///@{
|
||||
int frame_type; ///< frame type (strmtyp)
|
||||
int substreamid; ///< substream identification
|
||||
int superframe_size; ///< current superframe size, in bytes
|
||||
int frame_size; ///< current frame size, in bytes
|
||||
int bit_rate; ///< stream bit rate, in bits-per-second
|
||||
int sample_rate; ///< sample frequency, in Hz
|
||||
@ -87,7 +88,7 @@ typedef struct AC3DecodeContext {
|
||||
int dialog_normalization[2]; ///< dialog level in dBFS (dialnorm)
|
||||
int compression_exists[2]; ///< compression field is valid for frame (compre)
|
||||
int compression_gain[2]; ///< gain to apply for heavy compression (compr)
|
||||
int channel_map; ///< custom channel map
|
||||
int channel_map; ///< custom channel map (chanmap)
|
||||
int preferred_downmix; ///< Preferred 2-channel downmix mode (dmixmod)
|
||||
int center_mix_level; ///< Center mix level index
|
||||
int center_mix_level_ltrt; ///< Center mix level index for Lt/Rt (ltrtcmixlev)
|
||||
@ -164,7 +165,9 @@ typedef struct AC3DecodeContext {
|
||||
SHORTFLOAT *downmix_coeffs[2]; ///< stereo downmix coefficients
|
||||
int downmixed; ///< indicates if coeffs are currently downmixed
|
||||
int output_mode; ///< output channel configuration
|
||||
int prev_output_mode; ///< output channel configuration for previous frame
|
||||
int out_channels; ///< number of output channels
|
||||
int prev_bit_rate; ///< stream bit rate, in bits-per-second for previous frame
|
||||
///@}
|
||||
|
||||
///@name Dynamic range
|
||||
@ -239,11 +242,12 @@ typedef struct AC3DecodeContext {
|
||||
///@name Aligned arrays
|
||||
DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients
|
||||
DECLARE_ALIGNED(32, INTFLOAT, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients
|
||||
DECLARE_ALIGNED(32, INTFLOAT, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block
|
||||
DECLARE_ALIGNED(32, INTFLOAT, delay)[2 * AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block
|
||||
DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE]; ///< window coefficients
|
||||
DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing
|
||||
DECLARE_ALIGNED(32, SHORTFLOAT, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing
|
||||
DECLARE_ALIGNED(32, SHORTFLOAT, output)[2 * AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing
|
||||
DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread
|
||||
DECLARE_ALIGNED(32, SHORTFLOAT, output_buffer)[2 * AC3_MAX_CHANNELS][AC3_BLOCK_SIZE * 6]; ///< final output buffer
|
||||
///@}
|
||||
} AC3DecodeContext;
|
||||
|
||||
|
@ -303,13 +303,7 @@ static int ff_eac3_parse_header(AC3DecodeContext *s)
|
||||
/* An E-AC-3 stream can have multiple independent streams which the
|
||||
application can select from. each independent stream can also contain
|
||||
dependent streams which are used to add or replace channels. */
|
||||
if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
|
||||
if (!s->eac3_frame_dependent_found) {
|
||||
s->eac3_frame_dependent_found = 1;
|
||||
avpriv_request_sample(s->avctx, "Dependent substream decoding");
|
||||
}
|
||||
return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
|
||||
} else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) {
|
||||
if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n");
|
||||
return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
|
||||
}
|
||||
@ -355,7 +349,8 @@ static int ff_eac3_parse_header(AC3DecodeContext *s)
|
||||
/* dependent stream channel map */
|
||||
if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
|
||||
if (get_bits1(gbc)) {
|
||||
skip_bits(gbc, 16); // skip custom channel map
|
||||
s->channel_map = get_bits(gbc, 16);
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "channel_map: %0X\n", s->channel_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
1, 0, 0, 2880, 1536, 0x773ffeea, S=1, 1, 0x00bd00bd
|
||||
1, 2880, 2880, 2880, 1536, 0x6dc10748
|
||||
1, 5760, 5760, 2880, 1536, 0xbab5129c
|
||||
1, 8640, 8640, 2880, 1536, 0x602f034b
|
||||
1, 8640, 8640, 2880, 1536, 0x602f034b, S=1, 1, 0x00bd00bd
|
||||
1, 11520, 11520, 2880, 906, 0x69cdcbcd
|
||||
0, 32037, 36541, 1501, 114336, 0x37a215a8, S=1, 1, 0x00e000e0
|
||||
0, 33538, 33538, 1501, 12560, 0xb559a3d4, F=0x0, S=1, 1, 0x00e000e0
|
||||
|
@ -1,4 +1,4 @@
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 395 size: 278
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 696 size: 31082
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 696 size: 31082
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
@ -20,7 +20,7 @@ ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
|
||||
ret: 0 st: 0 flags:1 ts: 1.048000
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
|
||||
ret: 0 st: 1 flags:0 ts:-0.058000
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 395 size: 278
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 696 size: 31082
|
||||
ret: 0 st: 1 flags:1 ts: 2.836000
|
||||
ret: 0 st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size: 278
|
||||
ret: 0 st:-1 flags:0 ts: 1.730004
|
||||
@ -34,7 +34,7 @@ ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
|
||||
ret: 0 st: 1 flags:0 ts: 1.307000
|
||||
ret: 0 st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size: 278
|
||||
ret: 0 st: 1 flags:1 ts: 0.201000
|
||||
ret: 0 st: 1 flags:1 dts: 0.174000 pts: 0.174000 pos: 78977 size: 278
|
||||
ret: 0 st: 0 flags:0 dts: 0.200000 pts: 0.200000 pos: 79274 size: 11400
|
||||
ret: 0 st:-1 flags:0 ts:-0.904994
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 696 size: 31082
|
||||
ret: 0 st:-1 flags:1 ts: 1.989173
|
||||
|
Loading…
Reference in New Issue
Block a user