summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/vp8.c4
-rw-r--r--libavutil/common.h15
-rw-r--r--libswscale/swscale.c35
3 files changed, 34 insertions, 20 deletions
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index f10e43c9cf..6bef32973d 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -1329,9 +1329,7 @@ static av_always_inline void filter_level_for_mb(VP8Context *s, VP8Macroblock *m
filter_level += s->lf_delta.mode[mb->mode];
}
-/* Like av_clip for inputs 0 and max, where max is equal to (2^n-1) */
-#define POW2CLIP(x,max) (((x) & ~max) ? (-(x))>>31 & max : (x));
- filter_level = POW2CLIP(filter_level, 63);
+ filter_level = av_clip_uintp2(filter_level, 6);
interior_limit = filter_level;
if (s->filter.sharpness) {
diff --git a/libavutil/common.h b/libavutil/common.h
index 493c3139aa..1cd2de2909 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -172,6 +172,18 @@ static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a)
}
/**
+ * Clip a signed integer to an unsigned power of two range.
+ * @param a value to clip
+ * @param p bit position to clip at
+ * @return clipped value
+ */
+static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
+{
+ if (a & ~((1<<p) - 1)) return -a >> 31 & ((1<<p) - 1);
+ else return a;
+}
+
+/**
* Clip a float value into the amin-amax range.
* @param a value to clip
* @param amin minimum value of the clip range
@@ -364,6 +376,9 @@ static av_always_inline av_const int av_popcount_c(uint32_t x)
#ifndef av_clipl_int32
# define av_clipl_int32 av_clipl_int32_c
#endif
+#ifndef av_clip_uintp2
+# define av_clip_uintp2 av_clip_uintp2_c
+#endif
#ifndef av_clipf
# define av_clipf av_clipf_c
#endif
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 16379182ac..c727408687 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -367,6 +367,20 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
//FIXME Optimize (just quickly written not optimized..)
int i;
+#define output_pixel(pos, val) \
+ if (big_endian) { \
+ if (output_bits == 16) { \
+ AV_WB16(pos, av_clip_uint16(val >> shift)); \
+ } else { \
+ AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
+ } \
+ } else { \
+ if (output_bits == 16) { \
+ AV_WL16(pos, av_clip_uint16(val >> shift)); \
+ } else { \
+ AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
+ } \
+ }
for (i = 0; i < dstW; i++) {
int val = 1 << 10;
int j;
@@ -374,11 +388,7 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
for (j = 0; j < lumFilterSize; j++)
val += lumSrc[j][i] * lumFilter[j];
- if (big_endian) {
- AV_WB16(&dest[i], av_clip_uint16(val >> 11));
- } else {
- AV_WL16(&dest[i], av_clip_uint16(val >> 11));
- }
+ output_pixel(&dest[i], val);
}
if (uDest) {
@@ -392,13 +402,8 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
v += chrSrc[j][i + VOFW] * chrFilter[j];
}
- if (big_endian) {
- AV_WB16(&uDest[i], av_clip_uint16(u >> 11));
- AV_WB16(&vDest[i], av_clip_uint16(v >> 11));
- } else {
- AV_WL16(&uDest[i], av_clip_uint16(u >> 11));
- AV_WL16(&vDest[i], av_clip_uint16(v >> 11));
- }
+ output_pixel(&uDest[i], u);
+ output_pixel(&vDest[i], v);
}
}
@@ -410,11 +415,7 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
for (j = 0; j < lumFilterSize; j++)
val += alpSrc[j][i] * lumFilter[j];
- if (big_endian) {
- AV_WB16(&aDest[i], av_clip_uint16(val >> 11));
- } else {
- AV_WL16(&aDest[i], av_clip_uint16(val >> 11));
- }
+ output_pixel(&aDest[i], val);
}
}
}