# HG changeset patch # User alexc # Date 1257288602 0 # Node ID 74e51b86b934976c283f3a7e4693127f8cc2b028 # Parent 27750570f2d45bbf8255ba47dd2d5e282068f957 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. diff -r 27750570f2d4 -r 74e51b86b934 aac.c --- a/aac.c Tue Nov 03 16:17:21 2009 +0000 +++ b/aac.c Tue Nov 03 22:50:02 2009 +0000 @@ -194,7 +194,7 @@ 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 @@ avctx->channels = channels; - ac->output_configured = 1; + ac->output_configured = oc_type; return 0; } @@ -390,7 +390,7 @@ 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 @@ 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 @@ 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 @@ 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 -r 27750570f2d4 -r 74e51b86b934 aac.h --- a/aac.h Tue Nov 03 16:17:21 2009 +0000 +++ b/aac.h Tue Nov 03 22:50:02 2009 +0000 @@ -103,6 +103,16 @@ }; /** + * 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 @@ DECLARE_ALIGNED(16, float, temp[128]); - int output_configured; + enum OCStatus output_configured; } AACContext; #endif /* AVCODEC_AAC_H */