summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Swain <robert.swain@gmail.com>2008-08-18 21:36:58 +0000
committerRobert Swain <robert.swain@gmail.com>2008-08-18 21:36:58 +0000
commit1dece0d2cda1898dc33b4f4a18766840b76831af (patch)
tree6d5fcaf177f0fa7b26e2bc70d2ec02ebe00b3460
parentc7f4d983a4d9d73a50b104cc9eb51acc534cef20 (diff)
More OKed AAC decoder code hunks
Originally committed as revision 14829 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/aac.c57
-rw-r--r--libavcodec/aac.h12
-rw-r--r--libavcodec/aacdectab.h35
3 files changed, 104 insertions, 0 deletions
diff --git a/libavcodec/aac.c b/libavcodec/aac.c
index 7dd0c5ea8b..27d8cee266 100644
--- a/libavcodec/aac.c
+++ b/libavcodec/aac.c
@@ -605,6 +605,44 @@ static void decode_pulses(Pulse * pulse, GetBitContext * gb, const uint16_t * sw
}
/**
+ * Decode Temporal Noise Shaping data; reference: table 4.48.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns,
+ GetBitContext * gb, const IndividualChannelStream * ics) {
+ int w, filt, i, coef_len, coef_res, coef_compress;
+ const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
+ const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
+ for (w = 0; w < ics->num_windows; w++) {
+ tns->n_filt[w] = get_bits(gb, 2 - is8);
+
+ if (tns->n_filt[w])
+ coef_res = get_bits1(gb);
+
+ for (filt = 0; filt < tns->n_filt[w]; filt++) {
+ int tmp2_idx;
+ tns->length[w][filt] = get_bits(gb, 6 - 2*is8);
+
+ if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) > tns_max_order) {
+ av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.",
+ tns->order[w][filt], tns_max_order);
+ tns->order[w][filt] = 0;
+ return -1;
+ }
+ tns->direction[w][filt] = get_bits1(gb);
+ coef_compress = get_bits1(gb);
+ coef_len = coef_res + 3 - coef_compress;
+ tmp2_idx = 2*coef_compress + coef_res;
+
+ for (i = 0; i < tns->order[w][filt]; i++)
+ tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
+ }
+ }
+ return 0;
+}
+
+/**
* Decode Mid/Side data; reference: table 4.54.
*
* @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
@@ -1066,6 +1104,25 @@ static int decode_extension_payload(AACContext * ac, GetBitContext * gb, int cnt
return res;
}
+ start = ics->swb_offset[FFMIN(bottom, mmm)];
+ end = ics->swb_offset[FFMIN( top, mmm)];
+ if ((size = end - start) <= 0)
+ continue;
+ if (tns->direction[w][filt]) {
+ inc = -1; start = end - 1;
+ } else {
+ inc = 1;
+ }
+ start += w * 128;
+
+ // ar filter
+ for (m = 0; m < size; m++, start += inc)
+ for (i = 1; i <= FFMIN(m, order); i++)
+ coef[start] -= coef[start - i*inc] * lpc[i];
+ }
+ }
+}
+
/**
* Conduct IMDCT and windowing.
*/
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index a64497db03..57bf09e027 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -149,6 +149,18 @@ typedef struct {
} IndividualChannelStream;
/**
+ * Temporal Noise Shaping
+ */
+typedef struct {
+ int present;
+ int n_filt[8];
+ int length[8][4];
+ int direction[8][4];
+ int order[8][4];
+ float coef[8][4][TNS_MAX_ORDER];
+} TemporalNoiseShaping;
+
+/**
* Dynamic Range Control - decoded from the bitstream but not processed further.
*/
typedef struct {
diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h
index c10eb71bd0..3c27c384a8 100644
--- a/libavcodec/aacdectab.h
+++ b/libavcodec/aacdectab.h
@@ -171,4 +171,39 @@ static const uint8_t tns_max_bands_128[] = {
};
// @}
+/* @name tns_tmp2_map
+ * Tables of the tmp2[] arrays of LPC coefficients used for TNS.
+ * The suffix _M_N[] indicate the values of coef_compress and coef_res
+ * respectively.
+ * @{
+ */
+static const float tns_tmp2_map_1_3[4] = {
+ 0.00000000, 0.43388373, -0.64278758, -0.34202015,
+};
+
+static const float tns_tmp2_map_0_3[8] = {
+ 0.00000000, 0.43388373, 0.78183150, 0.97492790,
+ -0.98480773, -0.86602539, -0.64278758, -0.34202015,
+};
+
+static const float tns_tmp2_map_1_4[8] = {
+ 0.00000000, 0.20791170, 0.40673664, 0.58778524,
+ -0.67369562, -0.52643216, -0.36124167, -0.18374951,
+};
+
+static const float tns_tmp2_map_0_4[16] = {
+ 0.00000000, 0.20791170, 0.40673664, 0.58778524,
+ 0.74314481, 0.86602539, 0.95105654, 0.99452192,
+ -0.99573416, -0.96182561, -0.89516330, -0.79801720,
+ -0.67369562, -0.52643216, -0.36124167, -0.18374951,
+};
+
+static const float *tns_tmp2_map[4] = {
+ tns_tmp2_map_0_3,
+ tns_tmp2_map_0_4,
+ tns_tmp2_map_1_3,
+ tns_tmp2_map_1_4
+};
+// @}
+
#endif /* FFMPEG_AACDECTAB_H */