Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2014-02-09 23:38:19 +0400
committerHendrik Leppkes <h.leppkes@gmail.com>2014-02-09 23:38:19 +0400
commit2570be9c06135468568eefbd30d1c0953fbcfa69 (patch)
treef33cc2c55d59f43bef2dc816c79a792bbf135f5e /decoder/LAVVideo/pixconv
parent59a47eb95af4cf7ab87f4bc0cb3926c3aa17b480 (diff)
Use a dispatcher table to lookup YUV->RGB conversion functions.
Diffstat (limited to 'decoder/LAVVideo/pixconv')
-rw-r--r--decoder/LAVVideo/pixconv/yuv2rgb.cpp149
1 files changed, 58 insertions, 91 deletions
diff --git a/decoder/LAVVideo/pixconv/yuv2rgb.cpp b/decoder/LAVVideo/pixconv/yuv2rgb.cpp
index 4538df8c..6d2c11f4 100644
--- a/decoder/LAVVideo/pixconv/yuv2rgb.cpp
+++ b/decoder/LAVVideo/pixconv/yuv2rgb.cpp
@@ -485,106 +485,36 @@ inline int yuv2rgb_convert(const uint8_t *srcY, const uint8_t *srcU, const uint8
return 0;
}
-template <int out32, int dithertype, int ycgco>
-inline int yuv2rgb_dispatch(const uint8_t* const src[4], const int srcStride[4], uint8_t *dst, int dstStride, int width, int height, LAVPixelFormat inputFormat, int bpp, int numThreads, RGBCoeffs *coeffs, const uint16_t *dithers)
-{
- // Wrap the input format into template args
- switch (inputFormat) {
- case LAVPixFmt_YUV420:
- return yuv2rgb_convert<LAVPixFmt_YUV420, 0, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- case LAVPixFmt_NV12:
- return yuv2rgb_convert<LAVPixFmt_NV12, 0, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- case LAVPixFmt_YUV420bX:
- if (bpp == 9)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 1, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- else if (bpp == 10)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 2, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 11)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 3, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 12)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 4, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 13)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 5, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 14)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 6, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 15)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 7, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 16)
- return yuv2rgb_convert<LAVPixFmt_YUV420, 8, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- else
- ASSERT(0);
- break;
- case LAVPixFmt_YUV422:
- return yuv2rgb_convert<LAVPixFmt_YUV422, 0, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- case LAVPixFmt_YUV422bX:
- if (bpp == 9)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 1, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- else if (bpp == 10)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 2, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 11)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 3, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 12)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 4, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 13)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 5, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 14)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 6, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 15)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 7, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 16)
- return yuv2rgb_convert<LAVPixFmt_YUV422, 8, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- else
- ASSERT(0);
- break;
- case LAVPixFmt_YUV444:
- return yuv2rgb_convert<LAVPixFmt_YUV444, 0, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- case LAVPixFmt_YUV444bX:
- if (bpp == 9)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 1, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- else if (bpp == 10)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 2, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 11)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 3, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 12)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 4, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 13)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 5, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 14)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 6, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- /*else if (bpp == 15)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 7, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);*/
- else if (bpp == 16)
- return yuv2rgb_convert<LAVPixFmt_YUV444, 8, out32, dithertype, ycgco>(src[0], src[1], src[2], dst, width, height, srcStride[0], srcStride[1], dstStride, coeffs, dithers, numThreads);
- else
- ASSERT(0);
- break;
- default:
- ASSERT(0);
- }
- return 0;
- }
-
template <int out32>
DECLARE_CONV_FUNC_IMPL(convert_yuv_rgb)
{
RGBCoeffs *coeffs = getRGBCoeffs(width, height);
+ if (!m_bRGBConvInit) {
+ m_bRGBConvInit = TRUE;
+ InitRGBConvDispatcher();
+ }
+
+ BOOL bYCgCo = (m_ColorProps.VideoTransferMatrix == 7);
+ int shift = max(bpp - 8, 0);
+
+ ASSERT(shift >= 0 && shift <= 8);
+
LAVDitherMode ditherMode = m_pSettings->GetDitherMode();
const uint16_t *dithers = (ditherMode == LAVDither_Random) ? GetRandomDitherCoeffs(height, DITHER_STEPS * 3, 4, 0) : nullptr;
- if (ditherMode == LAVDither_Random && dithers != nullptr) {
- if (m_ColorProps.VideoTransferMatrix == 7) {
- yuv2rgb_dispatch<out32, 1, 1>(src, srcStride, dst[0], dstStride[0], width, height, inputFormat, bpp, m_NumThreads, coeffs, dithers);
- } else {
- yuv2rgb_dispatch<out32, 1, 0>(src, srcStride, dst[0], dstStride[0], width, height, inputFormat, bpp, m_NumThreads, coeffs, dithers);
- }
- } else {
- if (m_ColorProps.VideoTransferMatrix == 7) {
- yuv2rgb_dispatch<out32, 0, 1>(src, srcStride, dst[0], dstStride[0], width, height, inputFormat, bpp, m_NumThreads, coeffs, nullptr);
- } else {
- yuv2rgb_dispatch<out32, 0, 0>(src, srcStride, dst[0], dstStride[0], width, height, inputFormat, bpp, m_NumThreads, coeffs, nullptr);
- }
+ if (ditherMode == LAVDither_Random && dithers == nullptr) {
+ ditherMode = LAVDither_Ordered;
+ }
+
+ YUVRGBConversionFunc convFn = m_RGBConvFuncs[out32][ditherMode][bYCgCo][inputFormat][shift];
+ if (convFn == nullptr) {
+ ASSERT(0);
+ return E_FAIL;
}
+ // run conversion
+ convFn(src[0], src[1], src[2], dst[0], width, height, srcStride[0], srcStride[1], dstStride[0], coeffs, dithers, m_NumThreads);
+
return S_OK;
}
@@ -592,6 +522,43 @@ DECLARE_CONV_FUNC_IMPL(convert_yuv_rgb)
template HRESULT CLAVPixFmtConverter::convert_yuv_rgb<0>CONV_FUNC_PARAMS;
template HRESULT CLAVPixFmtConverter::convert_yuv_rgb<1>CONV_FUNC_PARAMS;
+#define CONV_FUNC_INT(out32, dither, ycgco, format, shift) \
+ m_RGBConvFuncs[out32][dither][ycgco][format][shift] = yuv2rgb_convert<format, shift, out32, dither, ycgco>;
+
+#define CONV_FUNC(format, shift) \
+ CONV_FUNC_INT(0, LAVDither_Ordered, 0, format, shift) \
+ CONV_FUNC_INT(1, LAVDither_Ordered, 0, format, shift) \
+ CONV_FUNC_INT(0, LAVDither_Random, 0, format, shift) \
+ CONV_FUNC_INT(1, LAVDither_Random, 0, format, shift) \
+ CONV_FUNC_INT(0, LAVDither_Ordered, 1, format, shift) \
+ CONV_FUNC_INT(1, LAVDither_Ordered, 1, format, shift) \
+ CONV_FUNC_INT(0, LAVDither_Random, 1, format, shift) \
+ CONV_FUNC_INT(1, LAVDither_Random, 1, format, shift)
+
+#define CONV_FUNCX(format) \
+ CONV_FUNC(format, 1) \
+ CONV_FUNC(format, 2) \
+ /* CONV_FUNC(format, 3) */ \
+ CONV_FUNC(format, 4) \
+ /* CONV_FUNC(format, 5) */ \
+ CONV_FUNC(format, 6) \
+ /* CONV_FUNC(format, 7) */ \
+ CONV_FUNC(format, 8)
+
+void CLAVPixFmtConverter::InitRGBConvDispatcher()
+{
+ ZeroMemory(&m_RGBConvFuncs, sizeof(m_RGBConvFuncs));
+
+ CONV_FUNC(LAVPixFmt_YUV420, 0);
+ CONV_FUNC(LAVPixFmt_NV12, 0);
+ CONV_FUNC(LAVPixFmt_YUV422, 0);
+ CONV_FUNC(LAVPixFmt_YUV444, 0);
+
+ CONV_FUNCX(LAVPixFmt_YUV420bX);
+ CONV_FUNCX(LAVPixFmt_YUV422bX);
+ CONV_FUNCX(LAVPixFmt_YUV444bX);
+}
+
RGBCoeffs* CLAVPixFmtConverter::getRGBCoeffs(int width, int height)
{
if (!m_rgbCoeffs || width != swsWidth || height != swsHeight) {