diff --git a/modules/cudacodec/src/nvidia_surface_format_to_color_converter.cpp b/modules/cudacodec/src/nvidia_surface_format_to_color_converter.cpp index e22549e2296..ff9aa5708c4 100644 --- a/modules/cudacodec/src/nvidia_surface_format_to_color_converter.cpp +++ b/modules/cudacodec/src/nvidia_surface_format_to_color_converter.cpp @@ -142,36 +142,101 @@ class NVSurfaceToColorConverterImpl : public NVSurfaceToColorConverter { const bool yuv420 = surfaceFormat == SurfaceFormat::SF_NV12 || surfaceFormat == SurfaceFormat::SF_P016; CV_Assert(yuv.cols() % 2 == 0); - typedef void (*func_t)(uint8_t* yuv, int yuvPitch, uint8_t* color, int colorPitch, int width, int height, bool videoFullRangeFlag, cudaStream_t stream); - static const func_t funcs[4][5][2][2] = + using func_t = void (*)(uint8_t* yuv, int yuvPitch, uint8_t* color, int colorPitch, int width, int height, bool videoFullRangeFlag, cudaStream_t stream); + + static const func_t funcsNV12[5][2][2] = + { + { + { Nv12ToColor24, Nv12ToColorPlanar24 }, + { Nv12ToColor48, Nv12ToColorPlanar48 } + }, + { + { Nv12ToColor24, Nv12ToColorPlanar24 }, + { Nv12ToColor48, Nv12ToColorPlanar48 } + }, + { + { Nv12ToColor32, Nv12ToColorPlanar32 }, + { Nv12ToColor64, Nv12ToColorPlanar64 } + }, + { + { Nv12ToColor32, Nv12ToColorPlanar32 }, + { Nv12ToColor64, Nv12ToColorPlanar64 } + }, + { + { Y8ToGray8, Y8ToGray8 }, + { Y8ToGray16, Y8ToGray16 } + } + }; + + static const func_t funcsP016[5][2][2] = + { + { + { P016ToColor24, P016ToColorPlanar24 }, + { P016ToColor48, P016ToColorPlanar48 } + }, + { + { P016ToColor24, P016ToColorPlanar24 }, + { P016ToColor48, P016ToColorPlanar48 } + }, + { + { P016ToColor32, P016ToColorPlanar32 }, + { P016ToColor64, P016ToColorPlanar64 } + }, + { + { P016ToColor32, P016ToColorPlanar32 }, + { P016ToColor64, P016ToColorPlanar64 } + }, + { + { Y16ToGray8, Y16ToGray8 }, + { Y16ToGray16, Y16ToGray16 } + } + }; + + static const func_t funcsYUV444[5][2][2] = { { - {{{Nv12ToColor24},{Nv12ToColorPlanar24}},{{Nv12ToColor48},{Nv12ToColorPlanar48}}}, - {{{Nv12ToColor24},{Nv12ToColorPlanar24}},{{Nv12ToColor48},{Nv12ToColorPlanar48}}}, - {{{Nv12ToColor32},{Nv12ToColorPlanar32}},{{Nv12ToColor64},{Nv12ToColorPlanar64}}}, - {{{Nv12ToColor32},{Nv12ToColorPlanar32}},{{Nv12ToColor64},{Nv12ToColorPlanar64}}}, - {{{Y8ToGray8},{Y8ToGray8}},{{Y8ToGray16},{Y8ToGray16}}} + { YUV444ToColor24, YUV444ToColorPlanar24 }, + { YUV444ToColor48, YUV444ToColorPlanar48 } + }, + { + { YUV444ToColor24, YUV444ToColorPlanar24 }, + { YUV444ToColor48, YUV444ToColorPlanar48 } }, { - {{{P016ToColor24},{P016ToColorPlanar24}},{{P016ToColor48},{P016ToColorPlanar48}}}, - {{{P016ToColor24},{P016ToColorPlanar24}},{{P016ToColor48},{P016ToColorPlanar48}}}, - {{{P016ToColor32},{P016ToColorPlanar32}},{{P016ToColor64},{P016ToColorPlanar64}}}, - {{{P016ToColor32},{P016ToColorPlanar32}},{{P016ToColor64},{P016ToColorPlanar64}}}, - {{{Y16ToGray8},{Y16ToGray8}},{{Y16ToGray16},{Y16ToGray16}}} + { YUV444ToColor32, YUV444ToColorPlanar32 }, + { YUV444ToColor64, YUV444ToColorPlanar64 } }, { - {{{YUV444ToColor24},{YUV444ToColorPlanar24}},{{YUV444ToColor48},{YUV444ToColorPlanar48}}}, - {{{YUV444ToColor24},{YUV444ToColorPlanar24}},{{YUV444ToColor48},{YUV444ToColorPlanar48}}}, - {{{YUV444ToColor32},{YUV444ToColorPlanar32}},{{YUV444ToColor64},{YUV444ToColorPlanar64}}}, - {{{YUV444ToColor32},{YUV444ToColorPlanar32}},{{YUV444ToColor64},{YUV444ToColorPlanar64}}}, - {{{Y8ToGray8},{Y8ToGray8}},{{Y8ToGray16},{Y8ToGray16}}} + { YUV444ToColor32, YUV444ToColorPlanar32 }, + { YUV444ToColor64, YUV444ToColorPlanar64 } }, { - {{{YUV444P16ToColor24},{YUV444P16ToColorPlanar24}},{{YUV444P16ToColor48},{YUV444P16ToColorPlanar48}}}, - {{{YUV444P16ToColor24},{YUV444P16ToColorPlanar24}},{{YUV444P16ToColor48},{YUV444P16ToColorPlanar48}}}, - {{{YUV444P16ToColor32},{YUV444P16ToColorPlanar32}},{{YUV444P16ToColor64},{YUV444P16ToColorPlanar64}}}, - {{{YUV444P16ToColor32},{YUV444P16ToColorPlanar32}},{{YUV444P16ToColor64},{YUV444P16ToColorPlanar64}}}, - {{{Y16ToGray8},{Y16ToGray8}},{{Y16ToGray16},{Y16ToGray16}}} + { Y8ToGray8, Y8ToGray8 }, + { Y8ToGray16, Y8ToGray16 } + } + }; + + static const func_t funcsYUV444P16[5][2][2] = + { + { + { YUV444P16ToColor24, YUV444P16ToColorPlanar24 }, + { YUV444P16ToColor48, YUV444P16ToColorPlanar48 } + }, + { + { YUV444P16ToColor24, YUV444P16ToColorPlanar24 }, + { YUV444P16ToColor48, YUV444P16ToColorPlanar48 } + }, + { + { YUV444P16ToColor32, YUV444P16ToColorPlanar32 }, + { YUV444P16ToColor64, YUV444P16ToColorPlanar64 } + }, + { + { YUV444P16ToColor32, YUV444P16ToColorPlanar32 }, + { YUV444P16ToColor64, YUV444P16ToColorPlanar64 } + }, + { + { Y16ToGray8, Y16ToGray8 }, + { Y16ToGray16, Y16ToGray16 } } }; @@ -183,11 +248,31 @@ class NVSurfaceToColorConverterImpl : public NVSurfaceToColorConverter { const int nChannels = NumChannels(outputFormat); const int nRowsOut = nRows * (planar ? nChannels : 1); const BitDepth bitDepth_ = GetBitDepthOut(bitDepth, yuv.depth()); + const int iBitDepth = bitDepth_ == BitDepth::EIGHT ? 0 : 1; const int typeOut = CV_MAKE_TYPE(bitDepth_ == BitDepth::EIGHT ? CV_8U : CV_16U, planar ? 1 : nChannels); GpuMat out_ = getOutputMat(out, nRowsOut, yuv.cols(), typeOut, stream); + const int iSurfaceFormat = static_cast(surfaceFormat); + const int iPlanar = planar ? 1 : 0; const int iOutputFormat = OutputColorFormatIdx(outputFormat); - const func_t func = funcs[static_cast(surfaceFormat)][iOutputFormat][static_cast(bitDepth_)][planar]; + func_t func = nullptr; + + switch (iSurfaceFormat) + { + case 0: + func = funcsNV12[iOutputFormat][iBitDepth][iPlanar]; + break; + case 1: + func = funcsP016[iOutputFormat][iBitDepth][iPlanar]; + break; + case 2: + func = funcsYUV444[iOutputFormat][iBitDepth][iPlanar]; + break; + case 3: + func = funcsYUV444P16[iOutputFormat][iBitDepth][iPlanar]; + break; + } + if (!func) CV_Error(Error::StsUnsupportedFormat, "Unsupported combination of source and destination types");