X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvc1dsp.c;h=09213ccb774823696f90aafd9f7bc2d5f2124c9c;hb=7c032a369aea3754213d7b79e28ff0c2496b2cf4;hp=518a690d3ab9cef73adcb62d83d0672b11eb9c87;hpb=b615c1edfcdf9fabfc1b92a3b155a7bce6543153;p=ffmpeg diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index 518a690d3ab..09213ccb774 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -17,7 +17,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * */ /** @@ -31,11 +30,12 @@ /** Apply overlap transform to horizontal edge */ -static void vc1_v_overlap_c(uint8_t* src, int stride, int rnd) +static void vc1_v_overlap_c(uint8_t* src, int stride) { int i; int a, b, c, d; int d1, d2; + int rnd = 1; for(i = 0; i < 8; i++) { a = src[-2*stride]; b = src[-stride]; @@ -49,16 +49,18 @@ static void vc1_v_overlap_c(uint8_t* src, int stride, int rnd) src[0] = c + d2; src[stride] = d + d1; src++; + rnd = !rnd; } } /** Apply overlap transform to vertical edge */ -static void vc1_h_overlap_c(uint8_t* src, int stride, int rnd) +static void vc1_h_overlap_c(uint8_t* src, int stride) { int i; int a, b, c, d; int d1, d2; + int rnd = 1; for(i = 0; i < 8; i++) { a = src[-2]; b = src[-1]; @@ -72,6 +74,7 @@ static void vc1_h_overlap_c(uint8_t* src, int stride, int rnd) src[0] = c + d2; src[1] = d + d1; src += stride; + rnd = !rnd; } } @@ -319,10 +322,30 @@ static void vc1_inv_trans_4x4_c(DCTELEM block[64], int n) } /* motion compensation functions */ +/** Filter in case of 2 filters */ +#define VC1_MSPEL_FILTER_16B(DIR, TYPE) \ +static av_always_inline int vc1_mspel_ ## DIR ## _filter_16bits(const TYPE *src, int stride, int mode) \ +{ \ + switch(mode){ \ + case 0: /* no shift - should not occur */ \ + return 0; \ + case 1: /* 1/4 shift */ \ + return -4*src[-stride] + 53*src[0] + 18*src[stride] - 3*src[stride*2]; \ + case 2: /* 1/2 shift */ \ + return -src[-stride] + 9*src[0] + 9*src[stride] - src[stride*2]; \ + case 3: /* 3/4 shift */ \ + return -3*src[-stride] + 18*src[0] + 53*src[stride] - 4*src[stride*2]; \ + } \ + return 0; /* should not occur */ \ +} + +VC1_MSPEL_FILTER_16B(ver, uint8_t); +VC1_MSPEL_FILTER_16B(hor, int16_t); + /** Filter used to interpolate fractional pel values */ -static always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int mode, int r) +static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int mode, int r) { switch(mode){ case 0: //no shift @@ -339,31 +362,58 @@ static always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int mo /** Function used to do motion compensation with bicubic interpolation */ -static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int mode, int rnd) +static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd) { - int i, j; - uint8_t tmp[8*11], *tptr; - int m, r; - - m = (mode & 3); - r = rnd; - src -= stride; - tptr = tmp; - for(j = 0; j < 11; j++) { - for(i = 0; i < 8; i++) - tptr[i] = clip_uint8(vc1_mspel_filter(src + i, 1, m, r)); - src += stride; - tptr += 8; + int i, j; + + if (vmode) { /* Horizontal filter to apply */ + int r; + + if (hmode) { /* Vertical filter to apply, output to tmp */ + static const int shift_value[] = { 0, 5, 1, 5 }; + int shift = (shift_value[hmode]+shift_value[vmode])>>1; + int16_t tmp[11*8], *tptr = tmp; + + r = (1<<(shift-1)) + rnd-1; + + src -= 1; + for(j = 0; j < 8; j++) { + for(i = 0; i < 11; i++) + tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode)+r)>>shift; + src += stride; + tptr += 11; + } + + r = 64-rnd; + tptr = tmp+1; + for(j = 0; j < 8; j++) { + for(i = 0; i < 8; i++) + dst[i] = av_clip_uint8((vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode)+r)>>7); + dst += stride; + tptr += 11; + } + + return; + } + else { /* No horizontal filter, output 8 lines to dst */ + r = 1-rnd; + + for(j = 0; j < 8; j++) { + for(i = 0; i < 8; i++) + dst[i] = av_clip_uint8(vc1_mspel_filter(src + i, stride, vmode, r)); + src += stride; + dst += stride; + } + return; + } } - r = 1 - rnd; - m = (mode >> 2) & 3; - tptr = tmp + 8; + /* Horizontal mode with no vertical mode */ for(j = 0; j < 8; j++) { for(i = 0; i < 8; i++) - dst[i] = clip_uint8(vc1_mspel_filter(tptr + i, 8, m, r)); + dst[i] = av_clip_uint8(vc1_mspel_filter(src + i, 1, hmode, rnd)); dst += stride; - tptr += 8; + src += stride; } } @@ -372,65 +422,29 @@ static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int mode, /* this one is defined in dsputil.c */ void ff_put_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd); -static void ff_put_vc1_mspel_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x1, rnd); -} - -static void ff_put_vc1_mspel_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x2, rnd); -} - -static void ff_put_vc1_mspel_mc30_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x3, rnd); -} - -static void ff_put_vc1_mspel_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x4, rnd); +#define PUT_VC1_MSPEL(a, b)\ +static void put_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ + vc1_mspel_mc(dst, src, stride, a, b, rnd); \ } -static void ff_put_vc1_mspel_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x5, rnd); -} +PUT_VC1_MSPEL(1, 0) +PUT_VC1_MSPEL(2, 0) +PUT_VC1_MSPEL(3, 0) -static void ff_put_vc1_mspel_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x6, rnd); -} +PUT_VC1_MSPEL(0, 1) +PUT_VC1_MSPEL(1, 1) +PUT_VC1_MSPEL(2, 1) +PUT_VC1_MSPEL(3, 1) -static void ff_put_vc1_mspel_mc31_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x7, rnd); -} +PUT_VC1_MSPEL(0, 2) +PUT_VC1_MSPEL(1, 2) +PUT_VC1_MSPEL(2, 2) +PUT_VC1_MSPEL(3, 2) -static void ff_put_vc1_mspel_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x8, rnd); -} - -static void ff_put_vc1_mspel_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x9, rnd); -} - -static void ff_put_vc1_mspel_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xA, rnd); -} - -static void ff_put_vc1_mspel_mc32_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xB, rnd); -} - -static void ff_put_vc1_mspel_mc03_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xC, rnd); -} - -static void ff_put_vc1_mspel_mc13_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xD, rnd); -} - -static void ff_put_vc1_mspel_mc23_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xE, rnd); -} - -static void ff_put_vc1_mspel_mc33_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xF, rnd); -} +PUT_VC1_MSPEL(0, 3) +PUT_VC1_MSPEL(1, 3) +PUT_VC1_MSPEL(2, 3) +PUT_VC1_MSPEL(3, 3) void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c; @@ -441,19 +455,19 @@ void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { dsp->vc1_v_overlap = vc1_v_overlap_c; dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c; - dsp->put_vc1_mspel_pixels_tab[ 1] = ff_put_vc1_mspel_mc10_c; - dsp->put_vc1_mspel_pixels_tab[ 2] = ff_put_vc1_mspel_mc20_c; - dsp->put_vc1_mspel_pixels_tab[ 3] = ff_put_vc1_mspel_mc30_c; - dsp->put_vc1_mspel_pixels_tab[ 4] = ff_put_vc1_mspel_mc01_c; - dsp->put_vc1_mspel_pixels_tab[ 5] = ff_put_vc1_mspel_mc11_c; - dsp->put_vc1_mspel_pixels_tab[ 6] = ff_put_vc1_mspel_mc21_c; - dsp->put_vc1_mspel_pixels_tab[ 7] = ff_put_vc1_mspel_mc31_c; - dsp->put_vc1_mspel_pixels_tab[ 8] = ff_put_vc1_mspel_mc02_c; - dsp->put_vc1_mspel_pixels_tab[ 9] = ff_put_vc1_mspel_mc12_c; - dsp->put_vc1_mspel_pixels_tab[10] = ff_put_vc1_mspel_mc22_c; - dsp->put_vc1_mspel_pixels_tab[11] = ff_put_vc1_mspel_mc32_c; - dsp->put_vc1_mspel_pixels_tab[12] = ff_put_vc1_mspel_mc03_c; - dsp->put_vc1_mspel_pixels_tab[13] = ff_put_vc1_mspel_mc13_c; - dsp->put_vc1_mspel_pixels_tab[14] = ff_put_vc1_mspel_mc23_c; - dsp->put_vc1_mspel_pixels_tab[15] = ff_put_vc1_mspel_mc33_c; + dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c; + dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_c; + dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_c; + dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_c; + dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_c; + dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_c; + dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_c; + dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_c; + dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_c; + dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_c; + dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_c; + dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_c; + dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_c; + dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_c; + dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_c; }