~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/imgresample.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc, Andrew Starr-Bochicchio, Lionel Le Folgoc
  • Date: 2008-12-26 00:10:06 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081226001006-2040ls9680bd1blt
Tags: 1.1.7-0.2ubuntu1
[ Andrew Starr-Bochicchio ]
* Merge from debian-multimedia (LP: #298547), Ubuntu Changes:
 - For ffmpeg-related build-deps, fix versionized dependencies
   as the ubuntu versioning is different than debian-multimedia's.

[ Lionel Le Folgoc ]
* LP: #311412 is fixed since the 1.1.7~rc1-0.1 revision.
* debian/patches/03_ffmpeg.diff: updated to fix FTBFS due to libswscale API
  change (cherry-pick from Gentoo #234383).

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "swscale.h"
29
29
#include "dsputil.h"
30
30
 
31
 
#ifdef USE_FASTMEMCPY
32
 
#include "libvo/fastmemcpy.h"
 
31
#ifdef HAVE_ALTIVEC
 
32
#include "ppc/imgresample_altivec.h"
33
33
#endif
34
34
 
35
35
#define NB_COMPONENTS 3
48
48
#define LINE_BUF_HEIGHT (NB_TAPS * 4)
49
49
 
50
50
struct SwsContext {
 
51
    const AVClass *av_class;
51
52
    struct ImgReSampleContext *resampling_ctx;
52
53
    enum PixelFormat src_pix_fmt, dst_pix_fmt;
53
54
};
282
283
    }
283
284
    emms();
284
285
}
285
 
#endif
286
 
 
287
 
#ifdef HAVE_ALTIVEC
288
 
typedef         union {
289
 
    vector unsigned char v;
290
 
    unsigned char c[16];
291
 
} vec_uc_t;
292
 
 
293
 
typedef         union {
294
 
    vector signed short v;
295
 
    signed short s[8];
296
 
} vec_ss_t;
297
 
 
298
 
void v_resample16_altivec(uint8_t *dst, int dst_width, const uint8_t *src,
299
 
                          int wrap, int16_t *filter)
300
 
{
301
 
    int sum, i;
302
 
    const uint8_t *s;
303
 
    vector unsigned char *tv, tmp, dstv, zero;
304
 
    vec_ss_t srchv[4], srclv[4], fv[4];
305
 
    vector signed short zeros, sumhv, sumlv;
306
 
    s = src;
307
 
 
308
 
    for(i=0;i<4;i++)
309
 
    {
310
 
        /*
311
 
           The vec_madds later on does an implicit >>15 on the result.
312
 
           Since FILTER_BITS is 8, and we have 15 bits of magnitude in
313
 
           a signed short, we have just enough bits to pre-shift our
314
 
           filter constants <<7 to compensate for vec_madds.
315
 
        */
316
 
        fv[i].s[0] = filter[i] << (15-FILTER_BITS);
317
 
        fv[i].v = vec_splat(fv[i].v, 0);
318
 
    }
319
 
 
320
 
    zero = vec_splat_u8(0);
321
 
    zeros = vec_splat_s16(0);
322
 
 
323
 
 
324
 
    /*
325
 
       When we're resampling, we'd ideally like both our input buffers,
326
 
       and output buffers to be 16-byte aligned, so we can do both aligned
327
 
       reads and writes. Sadly we can't always have this at the moment, so
328
 
       we opt for aligned writes, as unaligned writes have a huge overhead.
329
 
       To do this, do enough scalar resamples to get dst 16-byte aligned.
330
 
    */
331
 
    i = (-(int)dst) & 0xf;
332
 
    while(i>0) {
333
 
        sum = s[0 * wrap] * filter[0] +
334
 
        s[1 * wrap] * filter[1] +
335
 
        s[2 * wrap] * filter[2] +
336
 
        s[3 * wrap] * filter[3];
337
 
        sum = sum >> FILTER_BITS;
338
 
        if (sum<0) sum = 0; else if (sum>255) sum=255;
339
 
        dst[0] = sum;
340
 
        dst++;
341
 
        s++;
342
 
        dst_width--;
343
 
        i--;
344
 
    }
345
 
 
346
 
    /* Do our altivec resampling on 16 pixels at once. */
347
 
    while(dst_width>=16) {
348
 
        /*
349
 
           Read 16 (potentially unaligned) bytes from each of
350
 
           4 lines into 4 vectors, and split them into shorts.
351
 
           Interleave the multipy/accumulate for the resample
352
 
           filter with the loads to hide the 3 cycle latency
353
 
           the vec_madds have.
354
 
        */
355
 
        tv = (vector unsigned char *) &s[0 * wrap];
356
 
        tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[i * wrap]));
357
 
        srchv[0].v = (vector signed short) vec_mergeh(zero, tmp);
358
 
        srclv[0].v = (vector signed short) vec_mergel(zero, tmp);
359
 
        sumhv = vec_madds(srchv[0].v, fv[0].v, zeros);
360
 
        sumlv = vec_madds(srclv[0].v, fv[0].v, zeros);
361
 
 
362
 
        tv = (vector unsigned char *) &s[1 * wrap];
363
 
        tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[1 * wrap]));
364
 
        srchv[1].v = (vector signed short) vec_mergeh(zero, tmp);
365
 
        srclv[1].v = (vector signed short) vec_mergel(zero, tmp);
366
 
        sumhv = vec_madds(srchv[1].v, fv[1].v, sumhv);
367
 
        sumlv = vec_madds(srclv[1].v, fv[1].v, sumlv);
368
 
 
369
 
        tv = (vector unsigned char *) &s[2 * wrap];
370
 
        tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[2 * wrap]));
371
 
        srchv[2].v = (vector signed short) vec_mergeh(zero, tmp);
372
 
        srclv[2].v = (vector signed short) vec_mergel(zero, tmp);
373
 
        sumhv = vec_madds(srchv[2].v, fv[2].v, sumhv);
374
 
        sumlv = vec_madds(srclv[2].v, fv[2].v, sumlv);
375
 
 
376
 
        tv = (vector unsigned char *) &s[3 * wrap];
377
 
        tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[3 * wrap]));
378
 
        srchv[3].v = (vector signed short) vec_mergeh(zero, tmp);
379
 
        srclv[3].v = (vector signed short) vec_mergel(zero, tmp);
380
 
        sumhv = vec_madds(srchv[3].v, fv[3].v, sumhv);
381
 
        sumlv = vec_madds(srclv[3].v, fv[3].v, sumlv);
382
 
 
383
 
        /*
384
 
           Pack the results into our destination vector,
385
 
           and do an aligned write of that back to memory.
386
 
        */
387
 
        dstv = vec_packsu(sumhv, sumlv) ;
388
 
        vec_st(dstv, 0, (vector unsigned char *) dst);
389
 
 
390
 
        dst+=16;
391
 
        s+=16;
392
 
        dst_width-=16;
393
 
    }
394
 
 
395
 
    /*
396
 
       If there are any leftover pixels, resample them
397
 
       with the slow scalar method.
398
 
    */
399
 
    while(dst_width>0) {
400
 
        sum = s[0 * wrap] * filter[0] +
401
 
        s[1 * wrap] * filter[1] +
402
 
        s[2 * wrap] * filter[2] +
403
 
        s[3 * wrap] * filter[3];
404
 
        sum = sum >> FILTER_BITS;
405
 
        if (sum<0) sum = 0; else if (sum>255) sum=255;
406
 
        dst[0] = sum;
407
 
        dst++;
408
 
        s++;
409
 
        dst_width--;
410
 
    }
411
 
}
412
 
#endif
413
 
 
414
 
/* slow version to handle limit cases. Does not need optimisation */
 
286
#endif /* HAVE_MMX */
 
287
 
 
288
/* slow version to handle limit cases. Does not need optimization */
415
289
static void h_resample_slow(uint8_t *dst, int dst_width,
416
290
                            const uint8_t *src, int src_width,
417
291
                            int src_start, int src_incr, int16_t *filters)
517
391
            h_resample(new_line, owidth,
518
392
                       src_line, iwidth, - FCENTER * POS_FRAC, s->h_incr,
519
393
                       &s->h_filters[0][0]);
520
 
            /* handle ring buffer wraping */
 
394
            /* handle ring buffer wrapping */
521
395
            if (ring_y >= LINE_BUF_HEIGHT) {
522
396
                memcpy(s->line_buf + (ring_y - LINE_BUF_HEIGHT) * owidth,
523
397
                       new_line, owidth);
638
512
    av_free(s);
639
513
}
640
514
 
 
515
static const AVClass context_class = { "imgresample", NULL, NULL };
 
516
 
641
517
struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat,
642
518
                                  int dstW, int dstH, int dstFormat,
643
519
                                  int flags, SwsFilter *srcFilter,
646
522
    struct SwsContext *ctx;
647
523
 
648
524
    ctx = av_malloc(sizeof(struct SwsContext));
649
 
    if (ctx == NULL) {
 
525
    if (!ctx) {
650
526
        av_log(NULL, AV_LOG_ERROR, "Cannot allocate a resampling context!\n");
651
527
 
652
528
        return NULL;
653
529
    }
 
530
    ctx->av_class = &context_class;
654
531
 
655
532
    if ((srcH != dstH) || (srcW != dstW)) {
656
533
        if ((srcFormat != PIX_FMT_YUV420P) || (dstFormat != PIX_FMT_YUV420P)) {
802
679
            goto the_end;
803
680
        }
804
681
    } else if (resampled_picture != &dst_pict) {
805
 
        img_copy(&dst_pict, resampled_picture, current_pix_fmt,
 
682
        av_picture_copy(&dst_pict, resampled_picture, current_pix_fmt,
806
683
                        ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight);
807
684
    }
808
685
 
815
692
 
816
693
#ifdef TEST
817
694
#include <stdio.h>
 
695
#undef exit
818
696
 
819
697
/* input */
820
698
#define XSIZE 256
942
820
        exit(1);
943
821
    }
944
822
    av_log(NULL, AV_LOG_INFO, "MMX OK\n");
945
 
#endif
 
823
#endif /* HAVE_MMX */
946
824
    return 0;
947
825
}
948
826
 
949
 
#endif
 
827
#endif /* TEST */