aboutsummaryrefslogtreecommitdiffstats
path: root/libswscale
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2022-09-05 14:53:50 -0700
committerPhilip Langdale <philipl@overt.org>2022-09-10 12:29:12 -0700
commitcaf8d4d256cc21f09570bdcbdbe8dde4406834ca (patch)
treec983de742589183a3bd9be6eda0fab653b4dce31 /libswscale
parentd32a9f3137c91de86547601a38fea0693c3497f1 (diff)
downloadffmpeg-caf8d4d256cc21f09570bdcbdbe8dde4406834ca.tar.gz
swscale/output: add support for P012
This generalises the existing P010 support.
Diffstat (limited to 'libswscale')
-rw-r--r--libswscale/output.c140
-rw-r--r--libswscale/utils.c4
-rw-r--r--libswscale/version.h2
3 files changed, 84 insertions, 62 deletions
diff --git a/libswscale/output.c b/libswscale/output.c
index 40a4476c6d..da6c026916 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -460,17 +460,18 @@ static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
#define output_pixel(pos, val) \
if (big_endian) { \
- AV_WB16(pos, av_clip_uintp2(val >> shift, 10) << 6); \
+ AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits) << output_shift); \
} else { \
- AV_WL16(pos, av_clip_uintp2(val >> shift, 10) << 6); \
+ AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits) << output_shift); \
}
-static void yuv2p010l1_c(const int16_t *src,
+static void yuv2p01xl1_c(const int16_t *src,
uint16_t *dest, int dstW,
- int big_endian)
+ int big_endian, int output_bits)
{
int i;
- int shift = 5;
+ int shift = 15 - output_bits;
+ int output_shift = 16 - output_bits;
for (i = 0; i < dstW; i++) {
int val = src[i] + (1 << (shift - 1));
@@ -478,12 +479,13 @@ static void yuv2p010l1_c(const int16_t *src,
}
}
-static void yuv2p010lX_c(const int16_t *filter, int filterSize,
+static void yuv2p01xlX_c(const int16_t *filter, int filterSize,
const int16_t **src, uint16_t *dest, int dstW,
- int big_endian)
+ int big_endian, int output_bits)
{
int i, j;
- int shift = 17;
+ int shift = 11 + 16 - output_bits;
+ int output_shift = 16 - output_bits;
for (i = 0; i < dstW; i++) {
int val = 1 << (shift - 1);
@@ -495,14 +497,15 @@ static void yuv2p010lX_c(const int16_t *filter, int filterSize,
}
}
-static void yuv2p010cX_c(int big_endian, const uint8_t *chrDither,
+static void yuv2p01xcX_c(int big_endian, const uint8_t *chrDither,
const int16_t *chrFilter, int chrFilterSize,
const int16_t **chrUSrc, const int16_t **chrVSrc,
- uint8_t *dest8, int chrDstW)
+ uint8_t *dest8, int chrDstW, int output_bits)
{
uint16_t *dest = (uint16_t*)dest8;
- int shift = 17;
int i, j;
+ int shift = 11 + 16 - output_bits;
+ int output_shift = 16 - output_bits;
for (i = 0; i < chrDstW; i++) {
int u = 1 << (shift - 1);
@@ -518,52 +521,65 @@ static void yuv2p010cX_c(int big_endian, const uint8_t *chrDither,
}
}
-static void yuv2p010l1_LE_c(const int16_t *src,
- uint8_t *dest, int dstW,
- const uint8_t *dither, int offset)
-{
- yuv2p010l1_c(src, (uint16_t*)dest, dstW, 0);
-}
-
-static void yuv2p010l1_BE_c(const int16_t *src,
- uint8_t *dest, int dstW,
- const uint8_t *dither, int offset)
-{
- yuv2p010l1_c(src, (uint16_t*)dest, dstW, 1);
-}
-
-static void yuv2p010lX_LE_c(const int16_t *filter, int filterSize,
- const int16_t **src, uint8_t *dest, int dstW,
- const uint8_t *dither, int offset)
-{
- yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 0);
-}
-
-static void yuv2p010lX_BE_c(const int16_t *filter, int filterSize,
- const int16_t **src, uint8_t *dest, int dstW,
- const uint8_t *dither, int offset)
-{
- yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 1);
-}
-
-static void yuv2p010cX_LE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
- const int16_t *chrFilter, int chrFilterSize,
- const int16_t **chrUSrc, const int16_t **chrVSrc,
- uint8_t *dest8, int chrDstW)
-{
- yuv2p010cX_c(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW);
-}
-
-static void yuv2p010cX_BE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
- const int16_t *chrFilter, int chrFilterSize,
- const int16_t **chrUSrc, const int16_t **chrVSrc,
- uint8_t *dest8, int chrDstW)
-{
- yuv2p010cX_c(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW);
-}
-
#undef output_pixel
+#define yuv2p01x_wrapper(bits) \
+ static void yuv2p0 ## bits ## l1_LE_c(const int16_t *src, \
+ uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset) \
+ { \
+ yuv2p01xl1_c(src, (uint16_t*)dest, dstW, 0, bits); \
+ } \
+ \
+ static void yuv2p0 ## bits ## l1_BE_c(const int16_t *src, \
+ uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset) \
+ { \
+ yuv2p01xl1_c(src, (uint16_t*)dest, dstW, 1, bits); \
+ } \
+ \
+ static void yuv2p0 ## bits ## lX_LE_c(const int16_t *filter, \
+ int filterSize, const int16_t **src, \
+ uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset) \
+ { \
+ yuv2p01xlX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 0, bits); \
+ } \
+ \
+ static void yuv2p0 ## bits ## lX_BE_c(const int16_t *filter, \
+ int filterSize, const int16_t **src, \
+ uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset) \
+ { \
+ yuv2p01xlX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 1, bits); \
+ } \
+ \
+ static void yuv2p0 ## bits ## cX_LE_c(enum AVPixelFormat dstFormat, \
+ const uint8_t *chrDither, \
+ const int16_t *chrFilter, \
+ int chrFilterSize, \
+ const int16_t **chrUSrc, \
+ const int16_t **chrVSrc, \
+ uint8_t *dest8, int chrDstW) \
+ { \
+ yuv2p01xcX_c(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, \
+ dest8, chrDstW, bits); \
+ } \
+ \
+ static void yuv2p0 ## bits ## cX_BE_c(enum AVPixelFormat dstFormat, \
+ const uint8_t *chrDither, \
+ const int16_t *chrFilter, \
+ int chrFilterSize, \
+ const int16_t **chrUSrc, \
+ const int16_t **chrVSrc, \
+ uint8_t *dest8, int chrDstW) \
+ { \
+ yuv2p01xcX_c(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, \
+ dest8, chrDstW, bits); \
+ }
+
+yuv2p01x_wrapper(10)
+yuv2p01x_wrapper(12)
#define accumulate_bit(acc, val) \
acc <<= 1; \
@@ -2675,10 +2691,16 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) {
- av_assert0(desc->comp[0].depth == 10);
- *yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c;
- *yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c;
- *yuv2nv12cX = isBE(dstFormat) ? yuv2p010cX_BE_c : yuv2p010cX_LE_c;
+ if (desc->comp[0].depth == 10) {
+ *yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c;
+ *yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c;
+ *yuv2nv12cX = isBE(dstFormat) ? yuv2p010cX_BE_c : yuv2p010cX_LE_c;
+ } else if (desc->comp[0].depth == 12) {
+ *yuv2plane1 = isBE(dstFormat) ? yuv2p012l1_BE_c : yuv2p012l1_LE_c;
+ *yuv2planeX = isBE(dstFormat) ? yuv2p012lX_BE_c : yuv2p012lX_LE_c;
+ *yuv2nv12cX = isBE(dstFormat) ? yuv2p012cX_BE_c : yuv2p012cX_LE_c;
+ } else
+ av_assert0(0);
} else if (is16BPS(dstFormat)) {
*yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c : yuv2planeX_16LE_c;
*yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c : yuv2plane1_16LE_c;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index a5a9bc589a..599c326754 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -236,8 +236,8 @@ static const FormatEntry format_entries[] = {
[AV_PIX_FMT_AYUV64LE] = { 1, 1},
[AV_PIX_FMT_P010LE] = { 1, 1 },
[AV_PIX_FMT_P010BE] = { 1, 1 },
- [AV_PIX_FMT_P012LE] = { 1, 0 },
- [AV_PIX_FMT_P012BE] = { 1, 0 },
+ [AV_PIX_FMT_P012LE] = { 1, 1 },
+ [AV_PIX_FMT_P012BE] = { 1, 1 },
[AV_PIX_FMT_P016LE] = { 1, 1 },
[AV_PIX_FMT_P016BE] = { 1, 1 },
[AV_PIX_FMT_GRAYF32LE] = { 1, 1 },
diff --git a/libswscale/version.h b/libswscale/version.h
index 908995b7b0..284c13cc23 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -29,7 +29,7 @@
#include "version_major.h"
#define LIBSWSCALE_VERSION_MINOR 8
-#define LIBSWSCALE_VERSION_MICRO 108
+#define LIBSWSCALE_VERSION_MICRO 109
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
LIBSWSCALE_VERSION_MINOR, \