changeset 10491:74e51b86b934 libavcodec

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.
author alexc
date Tue, 03 Nov 2009 22:50:02 +0000
parents 27750570f2d4
children 63910f7ba293
files aac.c aac.h
diffstat 2 files changed, 23 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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;
 }
 
--- 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 */