[FFmpeg-devel] [RFC] AAC encoder optimizations
Michael Niedermayer
michaelni
Sun Sep 14 18:13:46 CEST 2008
On Sun, Sep 14, 2008 at 05:09:56PM +0300, Kostya wrote:
> On Sun, Sep 14, 2008 at 02:34:09PM +0200, Michael Niedermayer wrote:
> > On Sun, Sep 14, 2008 at 08:34:11AM +0300, Kostya wrote:
[...]
> > > Oh, and headphones are one of the
> > > cheapest there.
> >
> > Once you cant find a difference anymore, it might be a good idea that someone
> > would donates some more expensive headphones to you.
>
> Gabriel has done that already, but I don't dare to take them to work
> and encoding at home is a waaay slower.
what about working remotely over ssh with some more powerfull computer?
[...]
> > [...]
> > > > >
> > > > > /**
> > > > > * structure used in optimal codebook search
> > > > > */
> > > > > typedef struct BandCodingPath {
> > > > > int prev_idx; ///< pointer to the previous path point
> > > > > int codebook; ///< codebook for coding band run
> > > > > float cost; ///< path cost
> > > > > int run;
> > > > > } BandCodingPath;
> > > > >
> > > > > /**
> > > > > * Encode band info for single window group bands.
> > > > > */
> > > > > static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
> > > > > int win, int group_len, const float lambda)
> > > > > {
> > > > > BandCodingPath path[120][12];
> > > > > int w, swb, cb, start, start2, size;
> > > > > int i, j;
> > > > > const int max_sfb = sce->ics.max_sfb;
> > > > > const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
> > > > > const int run_esc = (1 << run_bits) - 1;
> > > > > int idx, ppos, count;
> > > > > int stackrun[120], stackcb[120], stack_len;
> > > > >
> > > > > start = win*128;
> > > > > for(cb = 0; cb < 12; cb++){
> > > > > path[0][cb].cost = 0.0f;
> > > > > path[0][cb].prev_idx = -1;
> > > > > path[0][cb].run = 0;
> > > > > }
> > > > > for(swb = 0; swb < max_sfb; swb++){
> > > > > start2 = start;
> > > > > size = sce->ics.swb_sizes[swb];
> > > > > if(sce->zeroes[win*16 + swb]){
> > > > > for(cb = 0; cb < 12; cb++){
> > > > > path[swb+1][cb].prev_idx = cb;
> > > > > path[swb+1][cb].cost = path[swb][cb].cost;
> > > > > path[swb+1][cb].run = path[swb][cb].run + 1;
> > > > > }
> > > > > }else{
> > > > > float minrd = INFINITY;
> > > > > int mincb = 0;
> > > > > for(cb = 0; cb < 12; cb++){
> > > > > float rd = 0.0f;
> > > > > for(w = 0; w < group_len; w++){
> > > > > rd += quantize_band_cost(sce->coeffs + start + w*128, size, sce->sf_idx[(win+w)*16+swb], cb, lambda, minrd);
> > > > > }
> > > > > path[swb+1][cb].prev_idx = cb;
> > > > > path[swb+1][cb].cost = path[swb][cb].cost + rd;
> > > > > path[swb+1][cb].run = path[swb][cb].run + 1;
> > > > > if(rd < minrd){
> > > > > minrd = rd;
> > > > > mincb = cb;
> > > > > }
> > > > > }
> > > > > for(cb = 0; cb < 12; cb++){
> > > > > float cost = path[swb][cb].cost + minrd + run_bits + 4;
> > > > > if(cost < path[swb+1][cb].cost){
> > > > > path[swb+1][cb].prev_idx = mincb;
> > > > > path[swb+1][cb].cost = cost;
> > > > > path[swb+1][cb].run = 1;
> > > > > }
> > > > > }
> > > > > }
> > > > > start += sce->ics.swb_sizes[swb];
> > > > > }
> > > >
> > > > Have you tested this code against the previous cb viterbi search?
> > > > do they both find the global optimum? Iam asking because this code looks
> > > > wrong in several ways, but i may be missing something. Also the paper looked
> > > > wrong from what i remember though not in that many ways, the algo described
> > > > there for choosing cbs did seem to ignore the run escapes. This may or may not
> > > > be significant, but requires tests to understand what effect ignoring
> > > > run escapes has, the previous code and what i suggested did not ignore them.
> > >
> > > Well, run escape can happen only for run lengths >= 31 (with 51 max)
> > > for long window and >=7 of 15 bands for short windows. I will add check for
> > > that and recheck code.
> >
> > thanks, but note i do not think the run esc is the only bug in this code.
> > the non run case and where the min is added looks quite odd.
>
> In a nutshell, at each point it just calculates the cost of continuing the
> run sequence and then tests if the switch to the codebook with minimum cost
> results in less rate distortion.
i know that this is what it is supposed to do, but iam not sure if it does do
that, i mean:
> > > > > for(cb = 0; cb < 12; cb++){
> > > > > float rd = 0.0f;
> > > > > for(w = 0; w < group_len; w++){
> > > > > rd += quantize_band_cost(sce->coeffs + start + w*128, size, sce->sf_idx[(win+w)*16+swb], cb, lambda, minrd);
> > > > > }
> > > > > path[swb+1][cb].prev_idx = cb;
> > > > > path[swb+1][cb].cost = path[swb][cb].cost + rd;
> > > > > path[swb+1][cb].run = path[swb][cb].run + 1;
> > > > > if(rd < minrd){
> > > > > minrd = rd;
> > > > > mincb = cb;
> > > > > }
> > > > > }
> > > > > for(cb = 0; cb < 12; cb++){
> > > > > float cost = path[swb][cb].cost + minrd + run_bits + 4;
> > > > > if(cost < path[swb+1][cb].cost){
> > > > > path[swb+1][cb].prev_idx = mincb;
> > > > > path[swb+1][cb].cost = cost;
> > > > > path[swb+1][cb].run = 1;
> > > > > }
in this path[swb][cb].cost is the past cost for a cb run, minrd is the
best rd for any next cb with run=1, and that is stored in path[swb+1][cb].cost
but this really appears to be wrong, i mean shouldnt it be
that each current run (path[swb+1][cb].cost) is compared against the
best previous run (path[swb]["best"].cost) + current cb with run=1 ?
though of course it must be noted that either way this is ignoring run
escapes.
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Observe your enemies, for they first find out your faults. -- Antisthenes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080914/f5b6eb14/attachment.pgp>
More information about the ffmpeg-devel
mailing list