adpcm: Replace any of the leaf nodes in the heap
authorMartin Storsjö <martin@martin.st>
Fri, 12 Nov 2010 12:30:27 +0000 (12:30 +0000)
committerMartin Storsjö <martin@martin.st>
Fri, 12 Nov 2010 12:30:27 +0000 (12:30 +0000)
By not looking for the exactly largest node, we avoid an O(n) seek through
the leaf nodes. Just pick one (not the same one every time) and try replacing
that node with the new one.

For -trellis 8, this lowers the run time from 190 to 158 seconds,
for a 30 second 44 kHz mono sample, on my machine.

Originally committed as revision 25733 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/adpcm.c

index bdcd9859499a9e83a59f154a557e7924faac22f7..60adebe8d078119f7a72a1745c81f9940db689fc 100644 (file)
@@ -387,18 +387,10 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples,
                     if (heap_pos < frontier) {\
                         pos = heap_pos++;\
                     } else {\
-                        /* Find the largest node in the heap, which is one \
-                         * of the leaf nodes. */\
-                        int maxpos = 0;\
-                        uint32_t max_ssd = 0;\
-                        for (k = frontier >> 1; k < frontier; k++) {\
-                            if (nodes_next[k]->ssd > max_ssd) {\
-                                maxpos = k;\
-                                max_ssd = nodes_next[k]->ssd;\
-                            }\
-                        }\
-                        pos = maxpos;\
-                        if (ssd > max_ssd)\
+                        /* Try to replace one of the leaf nodes with the new \
+                         * one, but try a different slot each time. */\
+                        pos = (frontier >> 1) + (heap_pos++ & ((frontier >> 1) - 1));\
+                        if (ssd > nodes_next[pos]->ssd)\
                             goto next_##NAME;\
                     }\
                     u = nodes_next[pos];\