You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-11-23 21:54:53 +02:00
swscale: support gray to 9bit and 10bit formats
With the input of Kostya and Ronald.
This commit is contained in:
@@ -61,6 +61,28 @@ static av_always_inline void fillPlane(uint8_t *plane, int stride, int width,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fill_plane9or10(uint8_t *plane, int stride, int width,
|
||||||
|
int height, int y, uint8_t val,
|
||||||
|
const int dst_depth, const int big_endian)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
uint16_t *dst = (uint16_t *) (plane + stride * y);
|
||||||
|
#define FILL8TO9_OR_10(wfunc) \
|
||||||
|
for (i = 0; i < height; i++) { \
|
||||||
|
for (j = 0; j < width; j++) { \
|
||||||
|
wfunc(&dst[j], (val << (dst_depth - 8)) | \
|
||||||
|
(val >> (16 - dst_depth))); \
|
||||||
|
} \
|
||||||
|
dst += stride / 2; \
|
||||||
|
}
|
||||||
|
if (big_endian) {
|
||||||
|
FILL8TO9_OR_10(AV_WB16);
|
||||||
|
} else {
|
||||||
|
FILL8TO9_OR_10(AV_WL16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW,
|
static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW,
|
||||||
const uint8_t *_src, const int16_t *filter,
|
const uint8_t *_src, const int16_t *filter,
|
||||||
const int32_t *filterPos, int filterSize)
|
const int32_t *filterPos, int filterSize)
|
||||||
@@ -658,8 +680,20 @@ static int swScale(SwsContext *c, const uint8_t *src[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf)
|
if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) {
|
||||||
fillPlane(dst[3], dstStride[3], dstW, dstY - lastDstY, lastDstY, 255);
|
int length = dstW;
|
||||||
|
int height = dstY - lastDstY;
|
||||||
|
if (is16BPS(c->dstFormat))
|
||||||
|
length *= 2;
|
||||||
|
|
||||||
|
if (is9_OR_10BPS(dstFormat)) {
|
||||||
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
|
||||||
|
fill_plane9or10(dst[3], dstStride[3], length, height, lastDstY,
|
||||||
|
255, desc->comp[3].depth_minus1 + 1,
|
||||||
|
isBE(dstFormat));
|
||||||
|
} else
|
||||||
|
fillPlane(dst[3], dstStride[3], length, height, lastDstY, 255);
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_MMXEXT_INLINE
|
#if HAVE_MMXEXT_INLINE
|
||||||
if (av_get_cpu_flags() & AV_CPU_FLAG_MMXEXT)
|
if (av_get_cpu_flags() & AV_CPU_FLAG_MMXEXT)
|
||||||
|
|||||||
@@ -98,6 +98,27 @@ static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fill_plane9or10(uint8_t *plane, int stride, int width,
|
||||||
|
int height, int y, uint8_t val,
|
||||||
|
const int dst_depth, const int big_endian)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
uint16_t *dst = (uint16_t *) (plane + stride * y);
|
||||||
|
#define FILL8TO9_OR_10(wfunc) \
|
||||||
|
for (i = 0; i < height; i++) { \
|
||||||
|
for (j = 0; j < width; j++) { \
|
||||||
|
wfunc(&dst[j], (val << (dst_depth - 8)) | \
|
||||||
|
(val >> (16 - dst_depth))); \
|
||||||
|
} \
|
||||||
|
dst += stride / 2; \
|
||||||
|
}
|
||||||
|
if (big_endian) {
|
||||||
|
FILL8TO9_OR_10(AV_WB16);
|
||||||
|
} else {
|
||||||
|
FILL8TO9_OR_10(AV_WL16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void copyPlane(const uint8_t *src, int srcStride,
|
static void copyPlane(const uint8_t *src, int srcStride,
|
||||||
int srcSliceY, int srcSliceH, int width,
|
int srcSliceY, int srcSliceH, int width,
|
||||||
uint8_t *dst, int dstStride)
|
uint8_t *dst, int dstStride)
|
||||||
@@ -677,10 +698,17 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
|
|||||||
// ignore palette for GRAY8
|
// ignore palette for GRAY8
|
||||||
if (plane == 1 && !dst[2]) continue;
|
if (plane == 1 && !dst[2]) continue;
|
||||||
if (!src[plane] || (plane == 1 && !src[2])) {
|
if (!src[plane] || (plane == 1 && !src[2])) {
|
||||||
|
int val = (plane == 3) ? 255 : 128;
|
||||||
if (is16BPS(c->dstFormat))
|
if (is16BPS(c->dstFormat))
|
||||||
length *= 2;
|
length *= 2;
|
||||||
|
if (is9_OR_10BPS(c->dstFormat)) {
|
||||||
|
fill_plane9or10(dst[plane], dstStride[plane],
|
||||||
|
length, height, y, val,
|
||||||
|
desc_dst->comp[plane].depth_minus1 + 1,
|
||||||
|
isBE(c->dstFormat));
|
||||||
|
} else
|
||||||
fillPlane(dst[plane], dstStride[plane], length, height, y,
|
fillPlane(dst[plane], dstStride[plane], length, height, y,
|
||||||
(plane == 3) ? 255 : 128);
|
val);
|
||||||
} else {
|
} else {
|
||||||
if (is9_OR_10BPS(c->srcFormat)) {
|
if (is9_OR_10BPS(c->srcFormat)) {
|
||||||
const int src_depth = desc_src->comp[plane].depth_minus1 + 1;
|
const int src_depth = desc_src->comp[plane].depth_minus1 + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user