[FFmpeg-devel] [PATCH] aacdec: Reconfigure output as needed, disable pop_output_configuration()

Michael Niedermayer michaelni at gmx.at
Sat Feb 23 01:27:03 CET 2013


Fixes Ticket1694

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavcodec/aac.h    |    5 +++++
 libavcodec/aacdec.c |   41 +++++++++++++++--------------------------
 libavcodec/aacsbr.c |   13 +++++++------
 3 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 4ba989f..19d220c 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -329,6 +329,11 @@ struct AACContext {
 
 };
 
+int ff_aac_output_configure(AACContext *ac,
+                            uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
+                            enum OCStatus oc_type, int get_new_frame);
+
+
 void ff_aacdec_init_mips(AACContext *c);
 
 #endif /* AVCODEC_AAC_H */
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 87cb48a..6c319fe 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -115,10 +115,6 @@
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
 
-static int output_configure(AACContext *ac,
-                            uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
-                            enum OCStatus oc_type, int get_new_frame);
-
 #define overread_err "Input buffer exhausted before END element found\n"
 
 static int count_channels(uint8_t (*layout)[3], int tags)
@@ -408,11 +404,12 @@ static void push_output_configuration(AACContext *ac) {
  * configuration is unlocked.
  */
 static void pop_output_configuration(AACContext *ac) {
+    return;
     if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) {
         ac->oc[1] = ac->oc[0];
         ac->avctx->channels = ac->oc[1].channels;
         ac->avctx->channel_layout = ac->oc[1].channel_layout;
-        output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+        ff_aac_output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
                          ac->oc[1].status, 0);
     }
 }
@@ -422,7 +419,7 @@ static void pop_output_configuration(AACContext *ac) {
  *
  * @return  Returns error status. 0 - OK, !0 - error
  */
-static int output_configure(AACContext *ac,
+int ff_aac_output_configure(AACContext *ac,
                             uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
                             enum OCStatus oc_type, int get_new_frame)
 {
@@ -526,7 +523,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
         if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
                                        2) < 0)
             return NULL;
-        if (output_configure(ac, layout_map, layout_map_tags,
+        if (ff_aac_output_configure(ac, layout_map, layout_map_tags,
                              OC_TRIAL_FRAME, 1) < 0)
             return NULL;
 
@@ -544,7 +541,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
         if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
                                        1) < 0)
             return NULL;
-        if (output_configure(ac, layout_map, layout_map_tags,
+        if (ff_aac_output_configure(ac, layout_map, layout_map_tags,
                              OC_TRIAL_FRAME, 1) < 0)
             return NULL;
 
@@ -738,7 +735,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
     } else if (m4ac->sbr == 1 && m4ac->ps == -1)
         m4ac->ps = 1;
 
-    if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
+    if (ac && (ret = ff_aac_output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
         return ret;
 
     if (extension_flag) {
@@ -921,7 +918,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
             int ret = set_default_channel_config(avctx, layout_map,
                 &layout_map_tags, ac->oc[1].m4ac.chan_config);
             if (!ret)
-                output_configure(ac, layout_map, layout_map_tags,
+                ff_aac_output_configure(ac, layout_map, layout_map_tags,
                                  OC_GLOBAL_HDR, 0);
             else if (avctx->err_recognition & AV_EF_EXPLODE)
                 return AVERROR_INVALIDDATA;
@@ -2036,21 +2033,13 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
         if (!che) {
             av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n");
             return res;
-        } else if (!ac->oc[1].m4ac.sbr) {
-            av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n");
-            skip_bits_long(gb, 8 * cnt - 4);
-            return res;
-        } else if (ac->oc[1].m4ac.sbr == -1 && ac->oc[1].status == OC_LOCKED) {
-            av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n");
-            skip_bits_long(gb, 8 * cnt - 4);
-            return res;
-        } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) {
+        } else if (ac->oc[1].m4ac.sbr != 1) {
+            av_log(ac->avctx, AV_LOG_DEBUG, "SBR was found in the bitstream.\n");
             ac->oc[1].m4ac.sbr = 1;
-            ac->oc[1].m4ac.ps = 1;
-            output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+            if (ac->oc[1].m4ac.ps == -1 && ac->avctx->channels == 1)
+                ac->oc[1].m4ac.ps = 1;
+            ff_aac_output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
                              ac->oc[1].status, 1);
-        } else {
-            ac->oc[1].m4ac.sbr = 1;
         }
         res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
         break;
@@ -2441,7 +2430,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
             if (set_default_channel_config(ac->avctx, layout_map,
                     &layout_map_tags, hdr_info.chan_config))
                 return -7;
-            if (output_configure(ac, layout_map, layout_map_tags,
+            if (ff_aac_output_configure(ac, layout_map, layout_map_tags,
                                  FFMAX(ac->oc[1].status, OC_TRIAL_FRAME), 0))
                 return -7;
         } else {
@@ -2457,7 +2446,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
                 layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT;
                 layout_map[0][1] = 0;
                 layout_map[1][1] = 1;
-                if (output_configure(ac, layout_map, layout_map_tags,
+                if (ff_aac_output_configure(ac, layout_map, layout_map_tags,
                                      OC_TRIAL_FRAME, 0))
                     return -7;
             }
@@ -2561,7 +2550,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
                 av_log(avctx, AV_LOG_ERROR,
                        "Not evaluating a further program_config_element as this construct is dubious at best.\n");
             } else {
-                err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
+                err = ff_aac_output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
                 if (!err)
                     ac->oc[1].m4ac.chan_config = 0;
                 pce_found = 1;
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index aa728f6..40bbfd3 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -923,11 +923,13 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
 {
     switch (bs_extension_id) {
     case EXTENSION_ID_PS:
-        if (!ac->oc[1].m4ac.ps) {
-            av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n");
-            skip_bits_long(gb, *num_bits_left); // bs_fill_bits
-            *num_bits_left = 0;
-        } else {
+        if (ac->oc[1].m4ac.ps != 1) {
+            av_log(ac->avctx, AV_LOG_DEBUG, "Parametric Stereo was found in the bitstream.\n");
+            ac->oc[1].m4ac.ps = 1;
+            ff_aac_output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+                                    ac->oc[1].status, 1);
+        }
+        av_assert0(ac->oc[1].m4ac.ps);
 #if 1
             *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left);
 #else
@@ -935,7 +937,6 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
             skip_bits_long(gb, *num_bits_left); // bs_fill_bits
             *num_bits_left = 0;
 #endif
-        }
         break;
     default:
         // some files contain 0-padding
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list