[FFmpeg-devel] [RFC] AAC encoder optimizations

Michael Niedermayer michaelni
Sun Sep 14 18:23:55 CEST 2008


On Sun, Sep 14, 2008 at 06:13:46PM +0200, Michael Niedermayer wrote:
> 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:
[...]
> [...]
> > > [...]
> > > > > > 
> > > > > > /**
> > > > > >  * 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

actually no, i read just half of your sentance
it IMHO should
at each point calculate the cost of continuing the run sequence and test if its
cheaper to rather use the previous best run sequence.
In the code this would look very similar to yours ...

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The worst form of inequality is to try to make unequal things equal.
-- Aristotle
-------------- 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/e1cbbf74/attachment.pgp>



More information about the ffmpeg-devel mailing list