]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavcodec/aac.c
Allow parsing and decoding of ADTS AAC files with channel config = 0
[frescor/ffmpeg.git] / libavcodec / aac.c
index 4273e796beb21021438e94ea50d66b5d686b8b7d..5427d7c672c51f131f4646c91c10280c21391434 100644 (file)
@@ -78,7 +78,7 @@
 
 #include "avcodec.h"
 #include "internal.h"
-#include "bitstream.h"
+#include "get_bits.h"
 #include "dsputil.h"
 #include "lpc.h"
 
 #include <math.h>
 #include <string.h>
 
+union float754 { float f; uint32_t i; };
+
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
 
 
+static ChannelElement* get_che(AACContext *ac, int type, int elem_id) {
+    static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0 };
+    if (ac->tag_che_map[type][elem_id]) {
+        return ac->tag_che_map[type][elem_id];
+    }
+    if (ac->tags_mapped >= tags_per_config[ac->m4ac.chan_config]) {
+        return NULL;
+    }
+    switch (ac->m4ac.chan_config) {
+        case 7:
+            if (ac->tags_mapped == 3 && type == TYPE_CPE) {
+                ac->tags_mapped++;
+                return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2];
+            }
+        case 6:
+            /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
+               instead of SCE[0] CPE[0] CPE[0] LFE[0]. If we seem to have
+               encountered such a stream, transfer the LFE[0] element to SCE[1] */
+            if (ac->tags_mapped == tags_per_config[ac->m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
+                ac->tags_mapped++;
+                return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0];
+            }
+        case 5:
+            if (ac->tags_mapped == 2 && type == TYPE_CPE) {
+                ac->tags_mapped++;
+                return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1];
+            }
+        case 4:
+            if (ac->tags_mapped == 2 && ac->m4ac.chan_config == 4 && type == TYPE_SCE) {
+                ac->tags_mapped++;
+                return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
+            }
+        case 3:
+        case 2:
+            if (ac->tags_mapped == (ac->m4ac.chan_config != 2) && type == TYPE_CPE) {
+                ac->tags_mapped++;
+                return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0];
+            } else if (ac->m4ac.chan_config == 2) {
+                return NULL;
+            }
+        case 1:
+            if (!ac->tags_mapped && type == TYPE_SCE) {
+                ac->tags_mapped++;
+                return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0];
+            }
+        default:
+            return NULL;
+    }
+}
+
 /**
  * Configure output channel order based on the current program configuration element.
  *
@@ -106,13 +158,10 @@ static VLC vlc_spectral[11];
  * @return  Returns error status. 0 - OK, !0 - error
  */
 static int output_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_ELEM_ID],
-        enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]) {
+        enum ChannelPosition new_che_pos[4][MAX_ELEM_ID], int channel_config) {
     AVCodecContext *avctx = ac->avccontext;
     int i, type, channels = 0;
 
-    if(!memcmp(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])))
-        return 0; /* no change */
-
     memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
 
     /* Allocate or free elements depending on if they are in the
@@ -140,7 +189,16 @@ static int output_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_
         }
     }
 
+    if (channel_config) {
+        memset(ac->tag_che_map, 0,       4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
+        ac->tags_mapped = 0;
+    } else {
+        memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
+        ac->tags_mapped = 4*MAX_ELEM_ID;
+    }
+
     avctx->channels = channels;
+
     return 0;
 }
 
@@ -173,7 +231,7 @@ static int decode_pce(AACContext * ac, enum ChannelPosition new_che_pos[4][MAX_E
     skip_bits(gb, 2);  // object_type
 
     sampling_index = get_bits(gb, 4);
-    if(sampling_index > 11) {
+    if(sampling_index > 12) {
         av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index);
         return -1;
     }
@@ -286,7 +344,7 @@ static int decode_ga_specific_config(AACContext * ac, GetBitContext * gb, int ch
         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)))
+    if((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config)))
         return ret;
 
     if (extension_flag) {
@@ -326,7 +384,7 @@ static int decode_audio_specific_config(AACContext * ac, void *data, int data_si
 
     if((i = ff_mpeg4audio_get_config(&ac->m4ac, data, data_size)) < 0)
         return -1;
-    if(ac->m4ac.sampling_index > 11) {
+    if(ac->m4ac.sampling_index > 12) {
         av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index);
         return -1;
     }
@@ -394,12 +452,9 @@ static av_cold int aac_decode_init(AVCodecContext * avccontext) {
         memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
         if(set_default_channel_config(ac, new_che_pos, avccontext->channels - (avccontext->channels == 8)))
             return -1;
-        if(output_configure(ac, ac->che_pos, new_che_pos))
+        if(output_configure(ac, ac->che_pos, new_che_pos, 1))
             return -1;
         ac->m4ac.sample_rate = avccontext->sample_rate;
-    } else {
-        ff_log_missing_feature(ac->avccontext, "Implicit channel configuration is", 0);
-        return -1;
     }
 
     avccontext->sample_fmt  = SAMPLE_FMT_S16;
@@ -805,37 +860,37 @@ static int decode_spectrum_and_dequant(AACContext * ac, float coef[1024], GetBit
                                 if (vq_ptr[2]) coef[coef_tmp_idx + 2] = sign_lookup[get_bits1(gb)];
                                 if (vq_ptr[3]) coef[coef_tmp_idx + 3] = sign_lookup[get_bits1(gb)];
                             }
-                        }else {
-                            coef[coef_tmp_idx    ] = 1.0f;
-                            coef[coef_tmp_idx + 1] = 1.0f;
-                            if (dim == 4) {
-                                coef[coef_tmp_idx + 2] = 1.0f;
-                                coef[coef_tmp_idx + 3] = 1.0f;
-                            }
-                        }
-                        if (cur_band_type == ESC_BT) {
-                            for (j = 0; j < 2; j++) {
-                                if (vq_ptr[j] == 64.0f) {
-                                    int n = 4;
-                                    /* The total length of escape_sequence must be < 22 bits according
-                                       to the specification (i.e. max is 11111111110xxxxxxxxxx). */
-                                    while (get_bits1(gb) && n < 15) n++;
-                                    if(n == 15) {
-                                        av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
-                                        return -1;
-                                    }
-                                    n = (1<<n) + get_bits(gb, n);
-                                    coef[coef_tmp_idx + j] *= cbrtf(n) * n;
-                                }else
-                                    coef[coef_tmp_idx + j] *= vq_ptr[j];
+                            if (cur_band_type == ESC_BT) {
+                                for (j = 0; j < 2; j++) {
+                                    if (vq_ptr[j] == 64.0f) {
+                                        int n = 4;
+                                        /* The total length of escape_sequence must be < 22 bits according
+                                           to the specification (i.e. max is 11111111110xxxxxxxxxx). */
+                                        while (get_bits1(gb) && n < 15) n++;
+                                        if(n == 15) {
+                                            av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
+                                            return -1;
+                                        }
+                                        n = (1<<n) + get_bits(gb, n);
+                                        coef[coef_tmp_idx + j] *= cbrtf(n) * n;
+                                    }else
+                                        coef[coef_tmp_idx + j] *= vq_ptr[j];
+                                }
+                            }else
+                            {
+                                coef[coef_tmp_idx    ] *= vq_ptr[0];
+                                coef[coef_tmp_idx + 1] *= vq_ptr[1];
+                                if (dim == 4) {
+                                    coef[coef_tmp_idx + 2] *= vq_ptr[2];
+                                    coef[coef_tmp_idx + 3] *= vq_ptr[3];
+                                }
                             }
-                        }else
-                        {
-                            coef[coef_tmp_idx    ] *= vq_ptr[0];
-                            coef[coef_tmp_idx + 1] *= vq_ptr[1];
+                        }else {
+                            coef[coef_tmp_idx    ] = vq_ptr[0];
+                            coef[coef_tmp_idx + 1] = vq_ptr[1];
                             if (dim == 4) {
-                                coef[coef_tmp_idx + 2] *= vq_ptr[2];
-                                coef[coef_tmp_idx + 3] *= vq_ptr[3];
+                                coef[coef_tmp_idx + 2] = vq_ptr[2];
+                                coef[coef_tmp_idx + 3] = vq_ptr[3];
                             }
                         }
                         coef[coef_tmp_idx    ] *= sf[idx];
@@ -871,24 +926,24 @@ static int decode_spectrum_and_dequant(AACContext * ac, float coef[1024], GetBit
 }
 
 static av_always_inline float flt16_round(float pf) {
-    int exp;
-    pf = frexpf(pf, &exp);
-    pf = ldexpf(roundf(ldexpf(pf, 8)), exp-8);
-    return pf;
+    union float754 tmp;
+    tmp.f = pf;
+    tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
+    return tmp.f;
 }
 
 static av_always_inline float flt16_even(float pf) {
-    int exp;
-    pf = frexpf(pf, &exp);
-    pf = ldexpf(rintf(ldexpf(pf, 8)), exp-8);
-    return pf;
+    union float754 tmp;
+    tmp.f = pf;
+    tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U>>16)) & 0xFFFF0000U;
+    return tmp.f;
 }
 
 static av_always_inline float flt16_trunc(float pf) {
-    int exp;
-    pf = frexpf(pf, &exp);
-    pf = ldexpf(truncf(ldexpf(pf, 8)), exp-8);
-    return pf;
+    union float754 pun;
+    pun.f = pf;
+    pun.i &= 0xFFFF0000U;
+    return pun.f;
 }
 
 static void predict(AACContext * ac, PredictorState * ps, float* coef, int output_enable) {
@@ -1075,11 +1130,9 @@ static void apply_intensity_stereo(ChannelElement * cpe, int ms_present) {
  *
  * @return  Returns error status. 0 - OK, !0 - error
  */
-static int decode_cpe(AACContext * ac, GetBitContext * gb, int elem_id) {
+static int decode_cpe(AACContext * ac, GetBitContext * gb, ChannelElement * cpe) {
     int i, ret, common_window, ms_present = 0;
-    ChannelElement * cpe;
 
-    cpe = ac->che[TYPE_CPE][elem_id];
     common_window = get_bits1(gb);
     if (common_window) {
         if (decode_ics_info(ac, &cpe->ch[0].ics, gb, 1))
@@ -1140,14 +1193,7 @@ static int decode_cce(AACContext * ac, GetBitContext * gb, ChannelElement * che)
         } else
             coup->ch_select[c] = 2;
     }
-    coup->coupling_point += get_bits1(gb);
-
-    if (coup->coupling_point == 2) {
-        av_log(ac->avccontext, AV_LOG_ERROR,
-            "Independently switched CCE with 'invalid' domain signalled.\n");
-        memset(coup, 0, sizeof(ChannelCoupling));
-        return -1;
-    }
+    coup->coupling_point += get_bits1(gb) || (coup->coupling_point>>1);
 
     sign = get_bits(gb, 1);
     scale = pow(2., pow(2., (int)get_bits(gb, 2) - 3));
@@ -1165,22 +1211,26 @@ static int decode_cce(AACContext * ac, GetBitContext * gb, ChannelElement * che)
             gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
             gain_cache = pow(scale, -gain);
         }
-        for (g = 0; g < sce->ics.num_window_groups; g++) {
-            for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
-                if (sce->band_type[idx] != ZERO_BT) {
-                    if (!cge) {
-                        int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
-                        if (t) {
-                            int s = 1;
-                            t = gain += t;
-                            if (sign) {
-                                s  -= 2 * (t & 0x1);
-                                t >>= 1;
+        if (coup->coupling_point == AFTER_IMDCT) {
+            coup->gain[c][0] = gain_cache;
+        } else {
+            for (g = 0; g < sce->ics.num_window_groups; g++) {
+                for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
+                    if (sce->band_type[idx] != ZERO_BT) {
+                        if (!cge) {
+                            int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
+                                if (t) {
+                                int s = 1;
+                                t = gain += t;
+                                if (sign) {
+                                    s  -= 2 * (t & 0x1);
+                                    t >>= 1;
+                                }
+                                gain_cache = pow(scale, -t) * s;
                             }
-                            gain_cache = pow(scale, -t) * s;
                         }
+                        coup->gain[c][idx] = gain_cache;
                     }
-                    coup->gain[c][idx] = gain_cache;
                 }
             }
         }
@@ -1432,10 +1482,11 @@ static void apply_dependent_coupling(AACContext * ac, SingleChannelElement * tar
     for (g = 0; g < ics->num_window_groups; g++) {
         for (i = 0; i < ics->max_sfb; i++, idx++) {
             if (cce->ch[0].band_type[idx] != ZERO_BT) {
+                const float gain = cce->coup.gain[index][idx];
                 for (group = 0; group < ics->group_len[g]; group++) {
                     for (k = offsets[i]; k < offsets[i+1]; k++) {
                         // XXX dsputil-ize
-                        dest[group*128+k] += cce->coup.gain[index][idx] * src[group*128+k];
+                        dest[group*128+k] += gain * src[group*128+k];
                     }
                 }
             }
@@ -1452,8 +1503,13 @@ static void apply_dependent_coupling(AACContext * ac, SingleChannelElement * tar
  */
 static void apply_independent_coupling(AACContext * ac, SingleChannelElement * target, ChannelElement * cce, int index) {
     int i;
+    const float gain = cce->coup.gain[index][0];
+    const float bias = ac->add_bias;
+    const float* src = cce->ch[0].ret;
+    float* dest = target->ret;
+
     for (i = 0; i < 1024; i++)
-        target->ret[i] += cce->coup.gain[index][0] * (cce->ch[0].ret[i] - ac->add_bias);
+        dest[i] += gain * (src[i] - bias);
 }
 
 /**
@@ -1531,19 +1587,22 @@ static int parse_adts_frame_header(AACContext * ac, GetBitContext * gb) {
         ac->m4ac.sample_rate     = hdr_info.sample_rate;
         ac->m4ac.sampling_index  = hdr_info.sampling_index;
         ac->m4ac.object_type     = hdr_info.object_type;
-    }
-    if (hdr_info.num_aac_frames == 1) {
-        if (!hdr_info.crc_absent)
-            skip_bits(gb, 16);
-    } else {
-        ff_log_missing_feature(ac->avccontext, "More than one AAC RDB per ADTS frame is", 0);
-        return -1;
+        if (hdr_info.num_aac_frames == 1) {
+            if (!hdr_info.crc_absent)
+                skip_bits(gb, 16);
+        } else {
+            ff_log_missing_feature(ac->avccontext, "More than one AAC RDB per ADTS frame is", 0);
+            return -1;
+        }
     }
     return size;
 }
 
-static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, const uint8_t * buf, int buf_size) {
+static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, AVPacket *avpkt) {
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
     AACContext * ac = avccontext->priv_data;
+    ChannelElement * che = NULL;
     GetBitContext gb;
     enum RawDataBlockType elem_type;
     int err, elem_id, data_size_tmp;
@@ -1551,11 +1610,11 @@ static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data
     init_get_bits(&gb, buf, buf_size*8);
 
     if (show_bits(&gb, 12) == 0xfff) {
-        if ((err = parse_adts_frame_header(ac, &gb)) < 0) {
+        if (parse_adts_frame_header(ac, &gb) < 0) {
             av_log(avccontext, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
             return -1;
         }
-        if (ac->m4ac.sampling_index > 11) {
+        if (ac->m4ac.sampling_index > 12) {
             av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index);
             return -1;
         }
@@ -1564,37 +1623,28 @@ static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data
     // parse
     while ((elem_type = get_bits(&gb, 3)) != TYPE_END) {
         elem_id = get_bits(&gb, 4);
-        err = -1;
 
-        if(elem_type == TYPE_SCE && elem_id == 1 &&
-                !ac->che[TYPE_SCE][elem_id] && ac->che[TYPE_LFE][0]) {
-            /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
-               instead of SCE[0] CPE[0] CPE[0] LFE[0]. If we seem to have
-               encountered such a stream, transfer the LFE[0] element to SCE[1] */
-            ac->che[TYPE_SCE][elem_id] = ac->che[TYPE_LFE][0];
-            ac->che[TYPE_LFE][0] = NULL;
-        }
-        if(elem_type < TYPE_DSE) {
-            if(!ac->che[elem_type][elem_id])
-                return -1;
+        if(elem_type < TYPE_DSE && !(che=get_che(ac, elem_type, elem_id))) {
+            av_log(ac->avccontext, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id);
+            return -1;
         }
 
         switch (elem_type) {
 
         case TYPE_SCE:
-            err = decode_ics(ac, &ac->che[TYPE_SCE][elem_id]->ch[0], &gb, 0, 0);
+            err = decode_ics(ac, &che->ch[0], &gb, 0, 0);
             break;
 
         case TYPE_CPE:
-            err = decode_cpe(ac, &gb, elem_id);
+            err = decode_cpe(ac, &gb, che);
             break;
 
         case TYPE_CCE:
-            err = decode_cce(ac, &gb, ac->che[TYPE_CCE][elem_id]);
+            err = decode_cce(ac, &gb, che);
             break;
 
         case TYPE_LFE:
-            err = decode_ics(ac, &ac->che[TYPE_LFE][elem_id]->ch[0], &gb, 0, 0);
+            err = decode_ics(ac, &che->ch[0], &gb, 0, 0);
             break;
 
         case TYPE_DSE:
@@ -1608,7 +1658,7 @@ static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * 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;
-            err = output_configure(ac, ac->che_pos, new_che_pos);
+            err = output_configure(ac, ac->che_pos, new_che_pos, 0);
             break;
         }