Fs_SBR as defined by the specification is the SBR internal sample rate and defined to be twice the core coder nominal sample rate (listed in Table 4.82 - Sampling Frequency Mapping). ExtensionSamplingFrequency is the SBR output sample rate.
The code currently uses ExtensionSamplingFrequency instead of Fs_SBR. This patch creates a new context variable to hold Fs_SBR. Caveats: *This doesn't support sample rates that are not nominal sample rates, however AFAIK FFmpeg's LC/Main decoder does not support them either. There are no official LC/Main test vectors for them. *This probably doesn't handle the 7350 Hz sample rate properly as 7350 is not listed in the table so presumably the nominal sample rate is 8000. FFmpeg does support AAC @ 7350 Hz. There are no official LC/Main test vectors for it, however I hacked one up. MPEG seems to have zero interest in this sample rate outside of scalable profiles, however it still appears to be legal in the mainstream profiles. [1] Ref: [1] http://lists.mpegif.org/pipermail/mp4-tech/2009-February/008661.html http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2009-February/061946.html
From 6276e7cf108001b43d5b4101f4c1251fe2daa6ec Mon Sep 17 00:00:00 2001 From: Alex Converse <alex.conve...@gmail.com> Date: Thu, 26 Nov 2009 22:02:32 -0500 Subject: [PATCH 1/6] Fs_SBR as defined by the specification is the SBR internal sample rate and defined to be twice the core coder nominal sample rate. ExtensionSamplingFrequency is the SBR output sample rate. MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------1" This is a multi-part message in MIME format. --------------1 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit --- aacsbr.c | 36 ++++++++++++++++++------------------ aacsbr.h | 1 + 2 files changed, 19 insertions(+), 18 deletions(-) --------------1 Content-Type: text/x-patch; name="0001-Fs_SBR-as-defined-by-the-specification-is-the-SBR-in.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="0001-Fs_SBR-as-defined-by-the-specification-is-the-SBR-in.patch" diff --git a/aacsbr.c b/aacsbr.c index 71ac9f6..d99239d 100644 --- a/aacsbr.c +++ b/aacsbr.c @@ -148,31 +148,31 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, const uint8_t *sbr_offset_ptr; int stop_dk[13]; - if (ac->m4ac.ext_sample_rate < 32000) { + if (sbr->sample_rate < 32000) { temp = 3000; - } else if (ac->m4ac.ext_sample_rate < 64000) { + } else if (sbr->sample_rate < 64000) { temp = 4000; } else temp = 5000; - start_min = (unsigned int)lroundf((temp << 7) / (float)ac->m4ac.ext_sample_rate); - stop_min = (unsigned int)lroundf((temp << 8) / (float)ac->m4ac.ext_sample_rate); + start_min = (unsigned int)lroundf((temp << 7) / (float)sbr->sample_rate); + stop_min = (unsigned int)lroundf((temp << 8) / (float)sbr->sample_rate); - if (ac->m4ac.ext_sample_rate == 16000) { + if (sbr->sample_rate == 16000) { sbr_offset_ptr = sbr_offset[0]; - } else if (ac->m4ac.ext_sample_rate == 22050) { + } else if (sbr->sample_rate == 22050) { sbr_offset_ptr = sbr_offset[1]; - } else if (ac->m4ac.ext_sample_rate == 24000) { + } else if (sbr->sample_rate == 24000) { sbr_offset_ptr = sbr_offset[2]; - } else if (ac->m4ac.ext_sample_rate == 32000) { + } else if (sbr->sample_rate == 32000) { sbr_offset_ptr = sbr_offset[3]; - } else if ((ac->m4ac.ext_sample_rate >= 44100) && - (ac->m4ac.ext_sample_rate <= 64000)) { + } else if ((sbr->sample_rate >= 44100) && + (sbr->sample_rate <= 64000)) { sbr_offset_ptr = sbr_offset[4]; - } else if (ac->m4ac.ext_sample_rate > 64000) { + } else if (sbr->sample_rate > 64000) { sbr_offset_ptr = sbr_offset[5]; } else { - av_log(ac->avccontext, AV_LOG_ERROR, "Unsupported sample rate for SBR: %d\n", ac->m4ac.ext_sample_rate); + av_log(ac->avccontext, AV_LOG_ERROR, "Unsupported sample rate for SBR: %d\n", sbr->sample_rate); return -1; } @@ -328,11 +328,11 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, return -1; } // temp == max number of QMF subbands - if (ac->m4ac.ext_sample_rate <= 32000) { + if (sbr->sample_rate <= 32000) { temp = 48; - } else if (ac->m4ac.ext_sample_rate == 44100) { + } else if (sbr->sample_rate == 44100) { temp = 35; - } else if (ac->m4ac.ext_sample_rate >= 48000) + } else if (sbr->sample_rate >= 48000) temp = 32; if (sbr->k[2] - sbr->k[0] > temp) { @@ -349,7 +349,7 @@ static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) int i, k, sb = 0; int msb = sbr->k[0]; int usb = sbr->k[3]; - int goal_sb = lroundf((1 << 11) * 1000 / (float)ac->m4ac.sample_rate); + int goal_sb = lroundf((1 << 11) * 1000 / (float)sbr->sample_rate); sbr->num_patches = 0; @@ -804,8 +804,8 @@ int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, GetBitContext *gb = &gbc; skip_bits_long(gb_host, cnt*8 - 4); - if (!ac->m4ac.ext_sample_rate) - ac->m4ac.ext_sample_rate = 2 * ac->m4ac.sample_rate; + if (!sbr->sample_rate) + sbr->sample_rate = 2 * ac->m4ac.sample_rate; if (crc) { skip_bits(gb, 10); // bs_sbr_crc_bits; FIXME - implement CRC check diff --git a/aacsbr.h b/aacsbr.h index f734f4c..20b928d 100644 --- a/aacsbr.h +++ b/aacsbr.h @@ -107,6 +107,7 @@ typedef struct { */ typedef struct { uint8_t start; + int32_t sample_rate; // SBR header bitstream variables uint8_t bs_amp_res; uint8_t bs_amp_res_header; --------------1--
_______________________________________________ FFmpeg-soc mailing list FFmpeg-soc@mplayerhq.hu https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc