|
@@ -212,10 +212,11 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
|
|
|
static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
|
|
|
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
|
|
|
const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest,
|
|
|
- int dstW, int chrDstW, int big_endian)
|
|
|
+ int dstW, int chrDstW, int big_endian, int output_bits)
|
|
|
{
|
|
|
//FIXME Optimize (just quickly written not optimized..)
|
|
|
int i;
|
|
|
+ int shift = 11 + 16 - output_bits;
|
|
|
|
|
|
for (i = 0; i < dstW; i++) {
|
|
|
int val = 1 << 10;
|
|
@@ -225,9 +226,9 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
|
|
|
val += lumSrc[j][i] * lumFilter[j];
|
|
|
|
|
|
if (big_endian) {
|
|
|
- AV_WB16(&dest[i], av_clip_uint16(val >> 11));
|
|
|
+ AV_WB16(&dest[i], av_clip_uint16(val >> shift));
|
|
|
} else {
|
|
|
- AV_WL16(&dest[i], av_clip_uint16(val >> 11));
|
|
|
+ AV_WL16(&dest[i], av_clip_uint16(val >> shift));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -243,11 +244,11 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
|
|
|
}
|
|
|
|
|
|
if (big_endian) {
|
|
|
- AV_WB16(&uDest[i], av_clip_uint16(u >> 11));
|
|
|
- AV_WB16(&vDest[i], av_clip_uint16(v >> 11));
|
|
|
+ AV_WB16(&uDest[i], av_clip_uint16(u >> shift));
|
|
|
+ AV_WB16(&vDest[i], av_clip_uint16(v >> shift));
|
|
|
} else {
|
|
|
- AV_WL16(&uDest[i], av_clip_uint16(u >> 11));
|
|
|
- AV_WL16(&vDest[i], av_clip_uint16(v >> 11));
|
|
|
+ AV_WL16(&uDest[i], av_clip_uint16(u >> shift));
|
|
|
+ AV_WL16(&vDest[i], av_clip_uint16(v >> shift));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -261,9 +262,9 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
|
|
|
val += alpSrc[j][i] * lumFilter[j];
|
|
|
|
|
|
if (big_endian) {
|
|
|
- AV_WB16(&aDest[i], av_clip_uint16(val >> 11));
|
|
|
+ AV_WB16(&aDest[i], av_clip_uint16(val >> shift));
|
|
|
} else {
|
|
|
- AV_WL16(&aDest[i], av_clip_uint16(val >> 11));
|
|
|
+ AV_WL16(&aDest[i], av_clip_uint16(val >> shift));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -274,19 +275,28 @@ static inline void yuv2yuvX16inC(const int16_t *lumFilter, const int16_t **lumSr
|
|
|
const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, int dstW, int chrDstW,
|
|
|
enum PixelFormat dstFormat)
|
|
|
{
|
|
|
- if (isBE(dstFormat)) {
|
|
|
- yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize,
|
|
|
- chrFilter, chrSrc, chrFilterSize,
|
|
|
- alpSrc,
|
|
|
- dest, uDest, vDest, aDest,
|
|
|
- dstW, chrDstW, 1);
|
|
|
+#define conv16(bits) \
|
|
|
+ if (isBE(dstFormat)) { \
|
|
|
+ yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize, \
|
|
|
+ chrFilter, chrSrc, chrFilterSize, \
|
|
|
+ alpSrc, \
|
|
|
+ dest, uDest, vDest, aDest, \
|
|
|
+ dstW, chrDstW, 1, bits); \
|
|
|
+ } else { \
|
|
|
+ yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize, \
|
|
|
+ chrFilter, chrSrc, chrFilterSize, \
|
|
|
+ alpSrc, \
|
|
|
+ dest, uDest, vDest, aDest, \
|
|
|
+ dstW, chrDstW, 0, bits); \
|
|
|
+ }
|
|
|
+ if (is16BPS(dstFormat)) {
|
|
|
+ conv16(16);
|
|
|
+ } else if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
|
|
|
+ conv16(9);
|
|
|
} else {
|
|
|
- yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize,
|
|
|
- chrFilter, chrSrc, chrFilterSize,
|
|
|
- alpSrc,
|
|
|
- dest, uDest, vDest, aDest,
|
|
|
- dstW, chrDstW, 0);
|
|
|
+ conv16(10);
|
|
|
}
|
|
|
+#undef conv16
|
|
|
}
|
|
|
|
|
|
static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
|
|
@@ -1669,25 +1679,124 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
|
|
|
length*=2;
|
|
|
fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
|
|
|
} else {
|
|
|
- if(isNBPS(c->srcFormat)) {
|
|
|
- const int depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1;
|
|
|
- uint16_t *srcPtr2 = (uint16_t*)srcPtr;
|
|
|
+ if(is9_OR_10BPS(c->srcFormat)) {
|
|
|
+ const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1;
|
|
|
+ const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
|
|
|
+ const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
|
|
|
|
|
|
if (is16BPS(c->dstFormat)) {
|
|
|
uint16_t *dstPtr2 = (uint16_t*)dstPtr;
|
|
|
- for (i = 0; i < height; i++) {
|
|
|
- for (j = 0; j < length; j++)
|
|
|
- dstPtr2[j] = (srcPtr2[j]<<(16-depth)) | (srcPtr2[j]>>(2*depth-16));
|
|
|
- dstPtr2 += dstStride[plane]/2;
|
|
|
- srcPtr2 += srcStride[plane]/2;
|
|
|
+#define COPY9_OR_10TO16(rfunc, wfunc) \
|
|
|
+ for (i = 0; i < height; i++) { \
|
|
|
+ for (j = 0; j < length; j++) { \
|
|
|
+ int srcpx = rfunc(&srcPtr2[j]); \
|
|
|
+ wfunc(&dstPtr2[j], (srcpx<<(16-src_depth)) | (srcpx>>(2*src_depth-16))); \
|
|
|
+ } \
|
|
|
+ dstPtr2 += dstStride[plane]/2; \
|
|
|
+ srcPtr2 += srcStride[plane]/2; \
|
|
|
+ }
|
|
|
+ if (isBE(c->dstFormat)) {
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY9_OR_10TO16(AV_RB16, AV_WB16);
|
|
|
+ } else {
|
|
|
+ COPY9_OR_10TO16(AV_RL16, AV_WB16);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY9_OR_10TO16(AV_RB16, AV_WL16);
|
|
|
+ } else {
|
|
|
+ COPY9_OR_10TO16(AV_RL16, AV_WL16);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (is9_OR_10BPS(c->dstFormat)) {
|
|
|
+ uint16_t *dstPtr2 = (uint16_t*)dstPtr;
|
|
|
+#define COPY9_OR_10TO9_OR_10(loop) \
|
|
|
+ for (i = 0; i < height; i++) { \
|
|
|
+ for (j = 0; j < length; j++) { \
|
|
|
+ loop; \
|
|
|
+ } \
|
|
|
+ dstPtr2 += dstStride[plane]/2; \
|
|
|
+ srcPtr2 += srcStride[plane]/2; \
|
|
|
+ }
|
|
|
+#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \
|
|
|
+ if (dst_depth > src_depth) { \
|
|
|
+ COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \
|
|
|
+ wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \
|
|
|
+ } else if (dst_depth < src_depth) { \
|
|
|
+ COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]) >> 1)); \
|
|
|
+ } else { \
|
|
|
+ COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \
|
|
|
+ }
|
|
|
+ if (isBE(c->dstFormat)) {
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WB16);
|
|
|
+ } else {
|
|
|
+ COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WB16);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WL16);
|
|
|
+ } else {
|
|
|
+ COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WL16);
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
// FIXME Maybe dither instead.
|
|
|
- for (i = 0; i < height; i++) {
|
|
|
- for (j = 0; j < length; j++)
|
|
|
- dstPtr[j] = srcPtr2[j]>>(depth-8);
|
|
|
- dstPtr += dstStride[plane];
|
|
|
- srcPtr2 += srcStride[plane]/2;
|
|
|
+#define COPY9_OR_10TO8(rfunc) \
|
|
|
+ for (i = 0; i < height; i++) { \
|
|
|
+ for (j = 0; j < length; j++) { \
|
|
|
+ dstPtr[j] = rfunc(&srcPtr2[j])>>(src_depth-8); \
|
|
|
+ } \
|
|
|
+ dstPtr += dstStride[plane]; \
|
|
|
+ srcPtr2 += srcStride[plane]/2; \
|
|
|
+ }
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY9_OR_10TO8(AV_RB16);
|
|
|
+ } else {
|
|
|
+ COPY9_OR_10TO8(AV_RL16);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if(is9_OR_10BPS(c->dstFormat)) {
|
|
|
+ const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
|
|
|
+ uint16_t *dstPtr2 = (uint16_t*)dstPtr;
|
|
|
+
|
|
|
+ if (is16BPS(c->srcFormat)) {
|
|
|
+ const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
|
|
|
+#define COPY16TO9_OR_10(rfunc, wfunc) \
|
|
|
+ for (i = 0; i < height; i++) { \
|
|
|
+ for (j = 0; j < length; j++) { \
|
|
|
+ wfunc(&dstPtr2[j], rfunc(&srcPtr2[j])>>(16-dst_depth)); \
|
|
|
+ } \
|
|
|
+ dstPtr2 += dstStride[plane]/2; \
|
|
|
+ srcPtr2 += srcStride[plane]/2; \
|
|
|
+ }
|
|
|
+ if (isBE(c->dstFormat)) {
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY16TO9_OR_10(AV_RB16, AV_WB16);
|
|
|
+ } else {
|
|
|
+ COPY16TO9_OR_10(AV_RL16, AV_WB16);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (isBE(c->srcFormat)) {
|
|
|
+ COPY16TO9_OR_10(AV_RB16, AV_WL16);
|
|
|
+ } else {
|
|
|
+ COPY16TO9_OR_10(AV_RL16, AV_WL16);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else /* 8bit */ {
|
|
|
+#define COPY8TO9_OR_10(wfunc) \
|
|
|
+ for (i = 0; i < height; i++) { \
|
|
|
+ for (j = 0; j < length; j++) { \
|
|
|
+ const int srcpx = srcPtr[j]; \
|
|
|
+ wfunc(&dstPtr2[j], (srcpx<<(dst_depth-8)) | (srcpx >> (16-dst_depth))); \
|
|
|
+ } \
|
|
|
+ dstPtr2 += dstStride[plane]/2; \
|
|
|
+ srcPtr += srcStride[plane]; \
|
|
|
+ }
|
|
|
+ if (isBE(c->dstFormat)) {
|
|
|
+ COPY8TO9_OR_10(AV_WB16);
|
|
|
+ } else {
|
|
|
+ COPY8TO9_OR_10(AV_WL16);
|
|
|
}
|
|
|
}
|
|
|
} else if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
|