ac3enc: modify mantissa bit counting to keep bap counts for all values of bap

instead of just 0 to 4.

This does all the actual bit counting as a final step.
pull/2/head
Justin Ruggles 14 years ago
parent 1323828a0f
commit 6ca23db9cc
  1. 42
      libavcodec/ac3dsp.c
  2. 20
      libavcodec/ac3dsp.h
  3. 92
      libavcodec/ac3enc.c
  4. 52
      libavcodec/arm/ac3dsp_arm.S
  5. 2
      libavcodec/arm/ac3dsp_init_arm.c
  6. 53
      libavcodec/x86/ac3dsp.asm
  7. 3
      libavcodec/x86/ac3dsp_mmx.c

@ -128,24 +128,33 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd,
} while (end > ff_ac3_band_start_tab[band++]);
}
static int ac3_compute_mantissa_size_c(int mant_cnt[5], uint8_t *bap,
int nb_coefs)
static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap,
int len)
{
int bits, b, i;
while (len-- >= 0)
mant_cnt[bap[len]]++;
}
bits = 0;
for (i = 0; i < nb_coefs; i++) {
b = bap[i];
if (b <= 4) {
// bap=1 to bap=4 will be counted in compute_mantissa_size_final
mant_cnt[b]++;
} else if (b <= 13) {
// bap=5 to bap=13 use (bap-1) bits
bits += b - 1;
} else {
// bap=14 uses 14 bits and bap=15 uses 16 bits
bits += (b == 14) ? 14 : 16;
}
DECLARE_ALIGNED(16, const uint16_t, ff_ac3_bap_bits)[16] = {
0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
};
static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16])
{
int blk, bap;
int bits = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
// bap=1 : 3 mantissas in 5 bits
bits += (mant_cnt[blk][1] / 3) * 5;
// bap=2 : 3 mantissas in 7 bits
// bap=4 : 2 mantissas in 7 bits
bits += ((mant_cnt[blk][2] / 3) + (mant_cnt[blk][4] >> 1)) * 7;
// bap=3 : 1 mantissa in 3 bits
bits += mant_cnt[blk][3] * 3;
// bap=5 to 15 : get bits per mantissa from table
for (bap = 5; bap < 16; bap++)
bits += mant_cnt[blk][bap] * ff_ac3_bap_bits[bap];
}
return bits;
}
@ -181,6 +190,7 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
c->ac3_rshift_int32 = ac3_rshift_int32_c;
c->float_to_fixed24 = float_to_fixed24_c;
c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c;
c->update_bap_counts = ac3_update_bap_counts_c;
c->compute_mantissa_size = ac3_compute_mantissa_size_c;
c->extract_exponents = ac3_extract_exponents_c;

@ -24,6 +24,12 @@
#include <stdint.h>
/**
* Number of mantissa bits written for each bap value.
* bap values with fractional bits are set to 0 and are calculated separately.
*/
extern const uint16_t ff_ac3_bap_bits[16];
typedef struct AC3DSPContext {
/**
* Set each encoded exponent in a block to the minimum of itself and the
@ -101,10 +107,22 @@ typedef struct AC3DSPContext {
int snr_offset, int floor,
const uint8_t *bap_tab, uint8_t *bap);
/**
* Update bap counts using the supplied array of bap.
*
* @param[out] mant_cnt bap counts for 1 block
* @param[in] bap array of bap, pointing to start coef bin
* @param[in] len number of elements to process
*/
void (*update_bap_counts)(uint16_t mant_cnt[16], uint8_t *bap, int len);
/**
* Calculate the number of bits needed to encode a set of mantissas.
*
* @param[in] mant_cnt bap counts for all blocks
* @return mantissa bit count
*/
int (*compute_mantissa_size)(int mant_cnt[5], uint8_t *bap, int nb_coefs);
int (*compute_mantissa_size)(uint16_t mant_cnt[6][16]);
void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs);
} AC3DSPContext;

@ -1423,22 +1423,6 @@ static void count_frame_bits(AC3EncodeContext *s)
}
/**
* Finalize the mantissa bit count by adding in the grouped mantissas.
*/
static int compute_mantissa_size_final(int mant_cnt[5])
{
// bap=1 : 3 mantissas in 5 bits
int bits = (mant_cnt[1] / 3) * 5;
// bap=2 : 3 mantissas in 7 bits
// bap=4 : 2 mantissas in 7 bits
bits += ((mant_cnt[2] / 3) + (mant_cnt[4] >> 1)) * 7;
// bap=3 : each mantissa is 3 bits
bits += mant_cnt[3] * 3;
return bits;
}
/**
* Calculate masking curve based on the final exponents.
* Also calculate the power spectral densities to use in future calculations.
@ -1491,38 +1475,60 @@ static void reset_block_bap(AC3EncodeContext *s)
}
static int count_mantissa_bits(AC3EncodeContext *s)
/**
* Initialize mantissa counts.
* These are set so that they are padded to the next whole group size when bits
* are counted in compute_mantissa_size.
*/
static void count_mantissa_bits_init(uint16_t mant_cnt[AC3_MAX_BLOCKS][16])
{
int blk, ch;
int mantissa_bits;
int mant_cnt[5];
int blk;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
memset(mant_cnt[blk], 0, sizeof(mant_cnt[blk]));
mant_cnt[blk][1] = mant_cnt[blk][2] = 2;
mant_cnt[blk][4] = 1;
}
}
/**
* Update mantissa bit counts for all blocks in 1 channel in a given bandwidth
* range.
*/
static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
uint16_t mant_cnt[AC3_MAX_BLOCKS][16],
int start, int end)
{
int blk;
mantissa_bits = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk];
int av_uninit(ch0);
int got_cpl = !block->cpl_in_use;
// initialize grouped mantissa counts. these are set so that they are
// padded to the next whole group size when bits are counted in
// compute_mantissa_size_final
mant_cnt[0] = mant_cnt[3] = 0;
mant_cnt[1] = mant_cnt[2] = 2;
mant_cnt[4] = 1;
for (ch = 1; ch <= s->channels; ch++) {
if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) {
ch0 = ch - 1;
ch = CPL_CH;
got_cpl = 1;
}
mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt,
s->ref_bap[ch][blk]+s->start_freq[ch],
block->end_freq[ch]-s->start_freq[ch]);
if (ch == CPL_CH)
ch = ch0;
}
mantissa_bits += compute_mantissa_size_final(mant_cnt);
if (ch == CPL_CH && !block->cpl_in_use)
continue;
s->ac3dsp.update_bap_counts(mant_cnt[blk],
s->ref_bap[ch][blk] + start,
FFMIN(end, block->end_freq[ch]) - start);
}
return mantissa_bits;
}
/**
* Count the number of mantissa bits in the frame based on the bap values.
*/
static int count_mantissa_bits(AC3EncodeContext *s)
{
int ch, max_end_freq;
LOCAL_ALIGNED_16(uint16_t, mant_cnt,[AC3_MAX_BLOCKS][16]);
count_mantissa_bits_init(mant_cnt);
max_end_freq = s->bandwidth_code * 3 + 73;
for (ch = !s->cpl_enabled; ch <= s->channels; ch++)
count_mantissa_bits_update_ch(s, ch, mant_cnt, s->start_freq[ch],
max_end_freq);
return s->ac3dsp.compute_mantissa_size(mant_cnt);
}

@ -1,52 +0,0 @@
/*
* Copyright (c) 2011 Mans Rullgard <mans@mansr.com>
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "asm.S"
function ff_ac3_compute_mantissa_size_arm, export=1
push {r4-r8,lr}
ldm r0, {r4-r8}
mov r3, r0
mov r0, #0
1:
ldrb lr, [r1], #1
subs r2, r2, #1
blt 2f
cmp lr, #4
bgt 3f
subs lr, lr, #1
addlt r4, r4, #1
addeq r5, r5, #1
ble 1b
subs lr, lr, #2
addlt r6, r6, #1
addeq r7, r7, #1
addgt r8, r8, #1
b 1b
3:
cmp lr, #14
sublt lr, lr, #1
addgt r0, r0, #16
addle r0, r0, lr
b 1b
2:
stm r3, {r4-r8}
pop {r4-r8,pc}
endfunc

@ -39,8 +39,6 @@ int ff_ac3_compute_mantissa_size_arm(int cnt[5], uint8_t *bap, int nb_coefs);
av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact)
{
c->compute_mantissa_size = ff_ac3_compute_mantissa_size_arm;
if (HAVE_ARMV6) {
c->bit_alloc_calc_bap = ff_ac3_bit_alloc_calc_bap_armv6;
}

@ -27,6 +27,11 @@ SECTION_RODATA
; 16777216.0f - used in ff_float_to_fixed24()
pf_1_24: times 4 dd 0x4B800000
; used in ff_ac3_compute_mantissa_size()
cextern ac3_bap_bits
pw_bap_mul1: dw 21846, 21846, 0, 32768, 21846, 21846, 0, 32768
pw_bap_mul2: dw 5, 7, 0, 7, 5, 7, 0, 7
SECTION .text
;-----------------------------------------------------------------------------
@ -293,3 +298,51 @@ cglobal float_to_fixed24_sse2, 3,3,9, dst, src, len
%endif
ja .loop
REP_RET
;------------------------------------------------------------------------------
; int ff_ac3_compute_mantissa_size(uint16_t mant_cnt[6][16])
;------------------------------------------------------------------------------
%macro PHADDD4 2 ; xmm src, xmm tmp
movhlps %2, %1
paddd %1, %2
pshufd %2, %1, 0x1
paddd %1, %2
%endmacro
INIT_XMM
cglobal ac3_compute_mantissa_size_sse2, 1,2,4, mant_cnt, sum
movdqa m0, [mant_cntq ]
movdqa m1, [mant_cntq+ 1*16]
paddw m0, [mant_cntq+ 2*16]
paddw m1, [mant_cntq+ 3*16]
paddw m0, [mant_cntq+ 4*16]
paddw m1, [mant_cntq+ 5*16]
paddw m0, [mant_cntq+ 6*16]
paddw m1, [mant_cntq+ 7*16]
paddw m0, [mant_cntq+ 8*16]
paddw m1, [mant_cntq+ 9*16]
paddw m0, [mant_cntq+10*16]
paddw m1, [mant_cntq+11*16]
pmaddwd m0, [ff_ac3_bap_bits ]
pmaddwd m1, [ff_ac3_bap_bits+16]
paddd m0, m1
PHADDD4 m0, m1
movd sumd, m0
movdqa m3, [pw_bap_mul1]
movhpd m0, [mant_cntq +2]
movlpd m0, [mant_cntq+1*32+2]
movhpd m1, [mant_cntq+2*32+2]
movlpd m1, [mant_cntq+3*32+2]
movhpd m2, [mant_cntq+4*32+2]
movlpd m2, [mant_cntq+5*32+2]
pmulhuw m0, m3
pmulhuw m1, m3
pmulhuw m2, m3
paddusw m0, m1
paddusw m0, m2
pmaddwd m0, [pw_bap_mul2]
PHADDD4 m0, m1
movd eax, m0
add eax, sumd
RET

@ -42,6 +42,8 @@ extern void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned i
extern void ff_float_to_fixed24_sse (int32_t *dst, const float *src, unsigned int len);
extern void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len);
extern int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]);
av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
{
int mm_flags = av_get_cpu_flags();
@ -69,6 +71,7 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
c->ac3_exponent_min = ff_ac3_exponent_min_sse2;
c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2;
c->float_to_fixed24 = ff_float_to_fixed24_sse2;
c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2;
if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2;
c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2;

Loading…
Cancel
Save