summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Converse <alex.converse@gmail.com>2009-11-03 22:50:02 +0000
committerAlex Converse <alex.converse@gmail.com>2009-11-03 22:50:02 +0000
commit981b8fd777f8ea273c53a055cbbb45ad9fe872aa (patch)
tree70543497270a7ee525c164cc08066aec3612c720
parentcabc41b0c25d6b714f1a5fadb6d0895f17d7a495 (diff)
Don't lock the channel output configuration based on the first value seen for
non extradata formats. Instead lock it only after the successful decoding of a frame. This fixes issue 999. Originally committed as revision 20448 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/aac.c19
-rw-r--r--libavcodec/aac.h12
2 files changed, 23 insertions, 8 deletions
diff --git a/libavcodec/aac.c b/libavcodec/aac.c
index 5387740971..a74d5c769e 100644
--- a/libavcodec/aac.c
+++ b/libavcodec/aac.c
@@ -194,7 +194,7 @@ static int che_configure(AACContext *ac,
static int output_configure(AACContext *ac,
enum ChannelPosition che_pos[4][MAX_ELEM_ID],
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID],
- int channel_config)
+ int channel_config, enum OCStatus oc_type)
{
AVCodecContext *avctx = ac->avccontext;
int i, type, channels = 0, ret;
@@ -239,7 +239,7 @@ static int output_configure(AACContext *ac,
avctx->channels = channels;
- ac->output_configured = 1;
+ ac->output_configured = oc_type;
return 0;
}
@@ -390,7 +390,7 @@ static int decode_ga_specific_config(AACContext *ac, GetBitContext *gb,
if ((ret = set_default_channel_config(ac, new_che_pos, channel_config)))
return ret;
}
- if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config)))
+ if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config, OC_LOCKED)))
return ret;
if (extension_flag) {
@@ -1676,14 +1676,16 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
size = ff_aac_parse_header(gb, &hdr_info);
if (size > 0) {
- if (!ac->output_configured && hdr_info.chan_config) {
+ if (ac->output_configured != OC_LOCKED && hdr_info.chan_config) {
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
ac->m4ac.chan_config = hdr_info.chan_config;
if (set_default_channel_config(ac, new_che_pos, hdr_info.chan_config))
return -7;
- if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config))
+ if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME))
return -7;
+ } else if (ac->output_configured != OC_LOCKED) {
+ ac->output_configured = OC_NONE;
}
ac->m4ac.sample_rate = hdr_info.sample_rate;
ac->m4ac.sampling_index = hdr_info.sampling_index;
@@ -1760,11 +1762,11 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
if ((err = decode_pce(ac, new_che_pos, &gb)))
break;
- if (ac->output_configured)
+ if (ac->output_configured <= OC_TRIAL_PCE)
av_log(avccontext, AV_LOG_ERROR,
"Not evaluating a further program_config_element as this construct is dubious at best.\n");
else
- err = output_configure(ac, ac->che_pos, new_che_pos, 0);
+ err = output_configure(ac, ac->che_pos, new_che_pos, 0, OC_TRIAL_PCE);
break;
}
@@ -1804,6 +1806,9 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, 1024, avccontext->channels);
+ if (ac->output_configured)
+ ac->output_configured = OC_LOCKED;
+
return buf_size;
}
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index abe13268d5..bcfa9c7ee5 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -103,6 +103,16 @@ enum CouplingPoint {
};
/**
+ * Output configuration status
+ */
+enum OCStatus {
+ OC_NONE, //< Output unconfigured
+ OC_TRIAL_PCE, //< Output configuration under trial specified by an inband PCE
+ OC_TRIAL_FRAME, //< Output configuration under trial specified by a frame header
+ OC_LOCKED, //< Output configuration locked in place
+};
+
+/**
* Predictor State
*/
typedef struct {
@@ -275,7 +285,7 @@ typedef struct {
DECLARE_ALIGNED(16, float, temp[128]);
- int output_configured;
+ enum OCStatus output_configured;
} AACContext;
#endif /* AVCODEC_AAC_H */