Sigrid Solveig Haflínudóttirinline and unroll more6b5e8cc56 years agoHistory
963 lines · 34.6 KB · C
RawDownload
/* * Copyright © 2018, VideoLAN and dav1d authors * Copyright © 2018, Two Orioles, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this *    list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include <stdlib.h>#include <string.h> #include "common/attributes.h"#include "common/intops.h" #include "src/mc.h"#include "src/tables.h" #if BITDEPTH == 8#define get_intermediate_bits(bitdepth_max) 4// Output in interval [-5132, 9212], fits in int16_t as is#define PREP_BIAS 0#else// 4 for 10 bits/component, 2 for 12 bits/component#define get_intermediate_bits(bitdepth_max) (14 - bitdepth_from_max(bitdepth_max))// Output in interval [-20588, 36956] (10-bit), [-20602, 36983] (12-bit)// Subtract a bias to ensure the output fits in int16_t#define PREP_BIAS 8192#endif static NOINLINE voidput_c(pixel *dst, const ptrdiff_t dst_stride,      const pixel *src, const ptrdiff_t src_stride, const int w, int h){    do {        pixel_copy(dst, src, w);         dst += dst_stride;        src += src_stride;    } while (--h);} static NOINLINE voidprep_c(int16_t *tmp, const pixel *src, const ptrdiff_t src_stride,       const int w, int h HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    do {        for (int x = 0; x < w; x++)            tmp[x] = (src[x] << intermediate_bits) - PREP_BIAS;         tmp += w;        src += src_stride;    } while (--h);} #define FILTER_8TAP(src, x, F, stride) \    (F[0] * src[x + -3 * stride] + \     F[1] * src[x + -2 * stride] + \     F[2] * src[x + -1 * stride] + \     F[3] * src[x + +0 * stride] + \     F[4] * src[x + +1 * stride] + \     F[5] * src[x + +2 * stride] + \     F[6] * src[x + +3 * stride] + \     F[7] * src[x + +4 * stride]) #define DAV1D_FILTER_8TAP_RND(src, x, F, stride, sh) \    ((FILTER_8TAP(src, x, F, stride) + ((1 << (sh)) >> 1)) >> (sh)) #define DAV1D_FILTER_8TAP_CLIP(src, x, F, stride, sh) \    iclip_pixel(DAV1D_FILTER_8TAP_RND(src, x, F, stride, sh)) #define GET_H_FILTER(mx) \    const int8_t *const fh = !(mx) ? NULL : w > 4 ? \        dav1d_mc_subpel_filters[filter_type & 3][(mx) - 1] : \        dav1d_mc_subpel_filters[3 + (filter_type & 1)][(mx) - 1] #define GET_V_FILTER(my) \    const int8_t *const fv = !(my) ? NULL : h > 4 ? \        dav1d_mc_subpel_filters[filter_type >> 2][(my) - 1] : \        dav1d_mc_subpel_filters[3 + ((filter_type >> 2) & 1)][(my) - 1] #define GET_FILTERS() \    GET_H_FILTER(mx); \    GET_V_FILTER(my) static NOINLINE voidput_etap_c(pixel *dst, ptrdiff_t dst_stride,           const pixel *src, ptrdiff_t src_stride,           const int w, int h, const int mx, const int my,           const int filter_type HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    const int intermediate_rnd = (1 << intermediate_bits) >> 1;     GET_FILTERS();    dst_stride = PXSTRIDE(dst_stride);    src_stride = PXSTRIDE(src_stride);     if (fh) {        if (fv) {            int tmp_h = h + 7;            int16_t mid[128 * 135], *mid_ptr = mid;             src -= src_stride * 3;            do {                for (int x = 0; x < w; x++)                    mid_ptr[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1,                                                       6 - intermediate_bits);                 mid_ptr += 128;                src += src_stride;            } while (--tmp_h);             mid_ptr = mid + 128 * 3;            do {                for (int x = 0; x < w; x++)                    dst[x] = DAV1D_FILTER_8TAP_CLIP(mid_ptr, x, fv, 128,                                                    6 + intermediate_bits);                 mid_ptr += 128;                dst += dst_stride;            } while (--h);        } else {            do {                for (int x = 0; x < w; x++) {                    const int px = DAV1D_FILTER_8TAP_RND(src, x, fh, 1,                                                         6 - intermediate_bits);                    dst[x] = iclip_pixel((px + intermediate_rnd) >> intermediate_bits);                }                 dst += dst_stride;                src += src_stride;            } while (--h);        }    } else if (fv) {        do {            for (int x = 0; x < w; x++)                dst[x] = DAV1D_FILTER_8TAP_CLIP(src, x, fv, src_stride, 6);             dst += dst_stride;            src += src_stride;        } while (--h);    } else        put_c(dst, dst_stride, src, src_stride, w, h);} static NOINLINE voidput_etap_scaled_c(pixel *dst, const ptrdiff_t dst_stride,                  const pixel *src, ptrdiff_t src_stride,                  const int w, int h, const int mx, int my,                  const int dx, const int dy, const int filter_type                  HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    const int intermediate_rnd = (1 << intermediate_bits) >> 1;    int tmp_h = (((h - 1) * dy + my) >> 10) + 8;    int16_t mid[128 * (256 + 7)], *mid_ptr = mid;    src_stride = PXSTRIDE(src_stride);     src -= src_stride * 3;    do {        int x;        int imx = mx, ioff = 0;         for (x = 0; x < w; x++) {            GET_H_FILTER(imx >> 6);            mid_ptr[x] = fh ? DAV1D_FILTER_8TAP_RND(src, ioff, fh, 1,                                                    6 - intermediate_bits) :                              src[ioff] << intermediate_bits;            imx += dx;            ioff += imx >> 10;            imx &= 0x3ff;        }         mid_ptr += 128;        src += src_stride;    } while (--tmp_h);     mid_ptr = mid + 128 * 3;    for (int y = 0; y < h; y++) {        int x;        GET_V_FILTER(my >> 6);         for (x = 0; x < w; x++)            dst[x] = fv ? DAV1D_FILTER_8TAP_CLIP(mid_ptr, x, fv, 128,                                                 6 + intermediate_bits) :                          iclip_pixel((mid_ptr[x] + intermediate_rnd) >>                                              intermediate_bits);         my += dy;        mid_ptr += (my >> 10) * 128;        my &= 0x3ff;        dst += PXSTRIDE(dst_stride);    }} static NOINLINE voidprep_etap_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride,            const int w, int h, const int mx, const int my,            const int filter_type HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    GET_FILTERS();    src_stride = PXSTRIDE(src_stride);     if (fh) {        if (fv) {            int tmp_h = h + 7;            int16_t mid[128 * 135], *mid_ptr = mid;             src -= src_stride * 3;            do {                for (int x = 0; x < w; x++)                    mid_ptr[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1,                                                       6 - intermediate_bits);                 mid_ptr += 128;                src += src_stride;            } while (--tmp_h);             mid_ptr = mid + 128 * 3;            do {                for (int x = 0; x < w; x++) {                    int t = DAV1D_FILTER_8TAP_RND(mid_ptr, x, fv, 128, 6) -                                  PREP_BIAS;                    assert(t >= INT16_MIN && t <= INT16_MAX);                    tmp[x] = t;                }                 mid_ptr += 128;                tmp += w;            } while (--h);        } else {            do {                for (int x = 0; x < w; x++)                    tmp[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1,                                                   6 - intermediate_bits) -                             PREP_BIAS;                 tmp += w;                src += src_stride;            } while (--h);        }    } else if (fv) {        do {            for (int x = 0; x < w; x++)                tmp[x] = DAV1D_FILTER_8TAP_RND(src, x, fv, src_stride,                                               6 - intermediate_bits) -                         PREP_BIAS;             tmp += w;            src += src_stride;        } while (--h);    } else        prep_c(tmp, src, src_stride, w, h HIGHBD_TAIL_SUFFIX);} static NOINLINE voidprep_etap_scaled_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride,                   const int w, int h, const int mx, int my,                   const int dx, const int dy, const int filter_type                   HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    int tmp_h = (((h - 1) * dy + my) >> 10) + 8;    int16_t mid[128 * (256 + 7)], *mid_ptr = mid;    src_stride = PXSTRIDE(src_stride);     src -= src_stride * 3;    do {        int x;        int imx = mx, ioff = 0;         for (x = 0; x < w; x++) {            GET_H_FILTER(imx >> 6);            mid_ptr[x] = fh ? DAV1D_FILTER_8TAP_RND(src, ioff, fh, 1,                                                    6 - intermediate_bits) :                              src[ioff] << intermediate_bits;            imx += dx;            ioff += imx >> 10;            imx &= 0x3ff;        }         mid_ptr += 128;        src += src_stride;    } while (--tmp_h);     mid_ptr = mid + 128 * 3;    for (int y = 0; y < h; y++) {        int x;        GET_V_FILTER(my >> 6);         for (x = 0; x < w; x++)            tmp[x] = (fv ? DAV1D_FILTER_8TAP_RND(mid_ptr, x, fv, 128, 6)                         : mid_ptr[x]) - PREP_BIAS;         my += dy;        mid_ptr += (my >> 10) * 128;        my &= 0x3ff;        tmp += w;    }} #define filter_fns(type, type_h, type_v) \static void put_etap_##type##_c(pixel *const dst, \                                const ptrdiff_t dst_stride, \                                const pixel *const src, \                                const ptrdiff_t src_stride, \                                const int w, const int h, \                                const int mx, const int my \                                HIGHBD_DECL_SUFFIX) \{ \    put_etap_c(dst, dst_stride, src, src_stride, w, h, mx, my, \               type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} \static void put_etap_##type##_scaled_c(pixel *const dst, \                                       const ptrdiff_t dst_stride, \                                       const pixel *const src, \                                       const ptrdiff_t src_stride, \                                       const int w, const int h, \                                       const int mx, const int my, \                                       const int dx, const int dy \                                       HIGHBD_DECL_SUFFIX) \{ \    put_etap_scaled_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, \                      type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} \static void prep_etap_##type##_c(int16_t *const tmp, \                                 const pixel *const src, \                                 const ptrdiff_t src_stride, \                                 const int w, const int h, \                                 const int mx, const int my \                                 HIGHBD_DECL_SUFFIX) \{ \    prep_etap_c(tmp, src, src_stride, w, h, mx, my, \                type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} \static void prep_etap_##type##_scaled_c(int16_t *const tmp, \                                        const pixel *const src, \                                        const ptrdiff_t src_stride, \                                        const int w, const int h, \                                        const int mx, const int my, \                                        const int dx, const int dy \                                        HIGHBD_DECL_SUFFIX) \{ \    prep_etap_scaled_c(tmp, src, src_stride, w, h, mx, my, dx, dy, \                       type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} filter_fns(regular,        DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_REGULAR)filter_fns(regular_sharp,  DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SHARP)filter_fns(regular_smooth, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SMOOTH)filter_fns(smooth,         DAV1D_FILTER_8TAP_SMOOTH,  DAV1D_FILTER_8TAP_SMOOTH)filter_fns(smooth_regular, DAV1D_FILTER_8TAP_SMOOTH,  DAV1D_FILTER_8TAP_REGULAR)filter_fns(smooth_sharp,   DAV1D_FILTER_8TAP_SMOOTH,  DAV1D_FILTER_8TAP_SHARP)filter_fns(sharp,          DAV1D_FILTER_8TAP_SHARP,   DAV1D_FILTER_8TAP_SHARP)filter_fns(sharp_regular,  DAV1D_FILTER_8TAP_SHARP,   DAV1D_FILTER_8TAP_REGULAR)filter_fns(sharp_smooth,   DAV1D_FILTER_8TAP_SHARP,   DAV1D_FILTER_8TAP_SMOOTH) #define FILTER_BILIN(src, x, mxy, stride) \    (16 * src[x] + ((mxy) * (src[x + stride] - src[x]))) #define FILTER_BILIN_RND(src, x, mxy, stride, sh) \    ((FILTER_BILIN(src, x, mxy, stride) + ((1 << (sh)) >> 1)) >> (sh)) #define FILTER_BILIN_CLIP(src, x, mxy, stride, sh) \    iclip_pixel(FILTER_BILIN_RND(src, x, mxy, stride, sh)) static void put_bilin_c(pixel *dst, ptrdiff_t dst_stride,                        const pixel *src, ptrdiff_t src_stride,                        const int w, int h, const int mx, const int my                        HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    const int intermediate_rnd = (1 << intermediate_bits) >> 1;    dst_stride = PXSTRIDE(dst_stride);    src_stride = PXSTRIDE(src_stride);     if (mx) {        if (my) {            int16_t mid[128 * 129], *mid_ptr = mid;            int tmp_h = h + 1;             do {                for (int x = 0; x < w; x++)                    mid_ptr[x] = FILTER_BILIN_RND(src, x, mx, 1,                                                  4 - intermediate_bits);                 mid_ptr += 128;                src += src_stride;            } while (--tmp_h);             mid_ptr = mid;            do {                for (int x = 0; x < w; x++)                    dst[x] = FILTER_BILIN_CLIP(mid_ptr, x, my, 128,                                               4 + intermediate_bits);                 mid_ptr += 128;                dst += dst_stride;            } while (--h);        } else {            do {                for (int x = 0; x < w; x++) {                    const int px = FILTER_BILIN_RND(src, x, mx, 1,                                                    4 - intermediate_bits);                    dst[x] = iclip_pixel((px + intermediate_rnd) >> intermediate_bits);                }                 dst += dst_stride;                src += src_stride;            } while (--h);        }    } else if (my) {        do {            for (int x = 0; x < w; x++)                dst[x] = FILTER_BILIN_CLIP(src, x, my, src_stride, 4);             dst += dst_stride;            src += src_stride;        } while (--h);    } else        put_c(dst, dst_stride, src, src_stride, w, h);} static void put_bilin_scaled_c(pixel *dst, ptrdiff_t dst_stride,                               const pixel *src, ptrdiff_t src_stride,                               const int w, int h, const int mx, int my,                               const int dx, const int dy                               HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    int tmp_h = (((h - 1) * dy + my) >> 10) + 2;    int16_t mid[128 * (256 + 1)], *mid_ptr = mid;     do {        int x;        int imx = mx, ioff = 0;         for (x = 0; x < w; x++) {            mid_ptr[x] = FILTER_BILIN_RND(src, ioff, imx >> 6, 1,                                          4 - intermediate_bits);            imx += dx;            ioff += imx >> 10;            imx &= 0x3ff;        }         mid_ptr += 128;        src += PXSTRIDE(src_stride);    } while (--tmp_h);     mid_ptr = mid;    do {        int x;         for (x = 0; x < w; x++)            dst[x] = FILTER_BILIN_CLIP(mid_ptr, x, my >> 6, 128,                                       4 + intermediate_bits);         my += dy;        mid_ptr += (my >> 10) * 128;        my &= 0x3ff;        dst += PXSTRIDE(dst_stride);    } while (--h);} static void prep_bilin_c(int16_t *tmp,                         const pixel *src, ptrdiff_t src_stride,                         const int w, int h, const int mx, const int my                         HIGHBD_DECL_SUFFIX){    const int intermediate_bits = get_intermediate_bits(bitdepth_max);    src_stride = PXSTRIDE(src_stride);     if (mx) {        if (my) {            int16_t mid[128 * 129], *mid_ptr = mid;            int tmp_h = h + 1; 

Lines 1–500 of 963.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t