Revision f82e8f34 libavcodec/adpcm.c

View differences:

libavcodec/adpcm.c
352 352
        TrellisNode *t = node_buf + frontier*(i&1);
353 353
        TrellisNode **u;
354 354
        int sample = samples[i*stride];
355
        int heap_pos = 0;
355 356
        memset(nodes_next, 0, frontier*sizeof(TrellisNode*));
356 357
        for(j=0; j<frontier && nodes[j]; j++) {
357 358
            // higher j have higher ssd already, so they're unlikely to use a suboptimal next sample too
......
369 370
#define STORE_NODE(NAME, STEP_INDEX)\
370 371
                    int d;\
371 372
                    uint32_t ssd;\
373
                    int pos;\
374
                    TrellisNode *u;\
372 375
                    dec_sample = av_clip_int16(dec_sample);\
373 376
                    d = sample - dec_sample;\
374 377
                    ssd = nodes[j]->ssd + d*d;\
375
                    if(nodes_next[frontier-1] && ssd >= nodes_next[frontier-1]->ssd)\
376
                        continue;\
377 378
                    /* Collapse any two states with the same previous sample value. \
378 379
                     * One could also distinguish states by step and by 2nd to last
379 380
                     * sample, but the effects of that are negligible. */\
......
383 384
                            goto next_##NAME;\
384 385
                        }\
385 386
                    }\
386
                    for(k=0; k<frontier; k++) {\
387
                        if(!nodes_next[k] || ssd < nodes_next[k]->ssd) {\
388
                            TrellisNode *u = nodes_next[frontier-1];\
387
                    if (heap_pos < frontier) {\
388
                        pos = heap_pos++;\
389
                    } else {\
390
                        /* Find the largest node in the heap, which is one \
391
                         * of the leaf nodes. */\
392
                        int maxpos = 0;\
393
                        uint32_t max_ssd = 0;\
394
                        for (k = frontier >> 1; k < frontier; k++) {\
395
                            if (nodes_next[k]->ssd > max_ssd) {\
396
                                maxpos = k;\
397
                                max_ssd = nodes_next[k]->ssd;\
398
                            }\
399
                        }\
400
                        pos = maxpos;\
401
                        if (ssd > max_ssd)\
402
                            goto next_##NAME;\
403
                    }\
404
                    u = nodes_next[pos];\
389 405
                            if(!u) {\
390 406
                                assert(pathn < FREEZE_INTERVAL<<avctx->trellis);\
391 407
                                u = t++;\
408
                                nodes_next[pos] = u;\
392 409
                                u->path = pathn++;\
393 410
                            }\
394 411
                            u->ssd = ssd;\
......
397 414
                            u->sample1 = dec_sample;\
398 415
                            paths[u->path].nibble = nibble;\
399 416
                            paths[u->path].prev = nodes[j]->path;\
400
                            memmove(&nodes_next[k+1], &nodes_next[k], (frontier-k-1)*sizeof(TrellisNode*));\
401
                            nodes_next[k] = u;\
417
                    /* Sift the newly inserted node down in the heap to \
418
                     * restore the heap property. */\
419
                    while (pos > 0) {\
420
                        int parent = (pos - 1) >> 1;\
421
                        if (nodes_next[parent]->ssd <= ssd)\
402 422
                            break;\
403
                        }\
423
                        FFSWAP(TrellisNode*, nodes_next[parent], nodes_next[pos]);\
424
                        pos = parent;\
404 425
                    }\
405 426
                    next_##NAME:;
406 427
                    STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8));

Also available in: Unified diff