From 98760381e439ec8a4f40f7f5fe508ccec5df2363 Mon Sep 17 00:00:00 2001 From: Kirill Gavrilov Date: Thu, 16 Jan 2025 20:35:09 +0300 Subject: [PATCH] StAVImage - convert planar GBR(A)PF32 formats to packed RGB(A)F --- StShared/StAVImage.cpp | 32 ++++++++++++++++++++++++++++++++ StShared/stAV.cpp | 4 +++- include/StAV/stAV.h | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/StShared/StAVImage.cpp b/StShared/StAVImage.cpp index 36393069..d180a55b 100644 --- a/StShared/StAVImage.cpp +++ b/StShared/StAVImage.cpp @@ -576,6 +576,38 @@ bool StAVImage::loadExtra(const StString& theFilePath, changePlane(0).initWrapper(StImagePlane::ImgRGBA64, myFrame.getPlane(0), myCodecCtx->width, myCodecCtx->height, myFrame.getLineSize(0)); + } else if(myCodecCtx->pix_fmt == stAV::PIX_FMT::GBRPF32 || myCodecCtx->pix_fmt == stAV::PIX_FMT::GBRAPF32) { + // planar RGB(A) is somewhat unusual and suboptimal - always convert to packed RGB(A) + const bool hasAlpha = myCodecCtx->pix_fmt == stAV::PIX_FMT::GBRAPF32; + + StImagePlane aPlanes[4]; + aPlanes[0].initWrapper(StImagePlane::ImgGrayF, myFrame.getPlane(2), + myCodecCtx->width, myCodecCtx->height, myFrame.getLineSize(2)); + aPlanes[1].initWrapper(StImagePlane::ImgGrayF, myFrame.getPlane(0), + myCodecCtx->width, myCodecCtx->height, myFrame.getLineSize(0)); + aPlanes[2].initWrapper(StImagePlane::ImgGrayF, myFrame.getPlane(1), + myCodecCtx->width, myCodecCtx->height, myFrame.getLineSize(1)); + if (hasAlpha) { + aPlanes[3].initWrapper(StImagePlane::ImgGrayF, myFrame.getPlane(3), + myCodecCtx->width, myCodecCtx->height, myFrame.getLineSize(3)); + } + + setColorModel(hasAlpha ? StImage::ImgColor_RGBA : StImage::ImgColor_RGB); + changePlane(0).initZero(hasAlpha ? StImagePlane::ImgRGBAF : StImagePlane::ImgRGBF, myCodecCtx->width, myCodecCtx->height); + const int aNbComps = hasAlpha ? 4 : 3; + for (int aPlnIter = 0; aPlnIter < 4; ++aPlnIter) { + const StImagePlane& aSrcPln = aPlanes[aPlnIter]; + if (aSrcPln.isNull()) { + continue; + } + for (size_t aRow = 0; aRow < myCodecCtx->height; ++aRow) { + float* aDstRow = (float*)changePlane(0).changeData(aRow) + aPlnIter; + const float* aSrcRow = (const float*)aSrcPln.getData(aRow); + for(size_t aCol = 0; aCol < myCodecCtx->width; ++aCol) { + aDstRow[aCol * aNbComps] = aSrcRow[aCol]; + } + } + } } else if(stAV::isFormatYUVPlanar(myCodecCtx, aDimsYUV) && !theIsOnlyRGB) { #if(LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 29, 0)) if(myCodecCtx->color_range == AVCOL_RANGE_JPEG) { diff --git a/StShared/stAV.cpp b/StShared/stAV.cpp index c9bfdbf0..69973d0b 100644 --- a/StShared/stAV.cpp +++ b/StShared/stAV.cpp @@ -135,6 +135,8 @@ const AVPixelFormat stAV::PIX_FMT::RGB48 = ST_AV_GETPIXFMT("rgb48"); const AVPixelFormat stAV::PIX_FMT::BGR48 = ST_AV_GETPIXFMT("bgr48"); const AVPixelFormat stAV::PIX_FMT::RGBA64 = ST_AV_GETPIXFMT("rgba64"); const AVPixelFormat stAV::PIX_FMT::BGRA64 = ST_AV_GETPIXFMT("bgra64"); +const AVPixelFormat stAV::PIX_FMT::GBRPF32 = ST_AV_GETPIXFMT("gbrpf32"); +const AVPixelFormat stAV::PIX_FMT::GBRAPF32 = ST_AV_GETPIXFMT("gbrapf32"); const AVPixelFormat stAV::PIX_FMT::XYZ12 = ST_AV_GETPIXFMT("xyz12"); const AVPixelFormat stAV::PIX_FMT::DXVA2_VLD = ST_AV_GETPIXFMT("dxva2_vld"); const AVPixelFormat stAV::PIX_FMT::VIDEOTOOLBOX_VLD = ST_AV_GETPIXFMT("videotoolbox_vld"); @@ -148,7 +150,7 @@ namespace { static const AVRational ST_AV_TIME_BASE_Q = {1, AV_TIME_BASE}; static const double ST_AV_TIME_BASE_D = av_q2d(ST_AV_TIME_BASE_Q); -}; +} const AVPixelFormat stAV::PIX_FMT::RGBA32 = (AvPixFmtRGBA != stAV::PIX_FMT::NONE) ? AvPixFmtRGBA : AvPixFmtBGR32; const AVPixelFormat stAV::PIX_FMT::BGRA32 = (AvPixFmtBGRA != stAV::PIX_FMT::NONE) ? AvPixFmtBGRA : AvPixFmtRGB32; diff --git a/include/StAV/stAV.h b/include/StAV/stAV.h index e9cda003..034feaf1 100644 --- a/include/StAV/stAV.h +++ b/include/StAV/stAV.h @@ -267,6 +267,8 @@ namespace stAV { ST_SHARED_CPPEXPORT AVPixelFormat BGRA32; ST_SHARED_CPPEXPORT AVPixelFormat RGBA64; ST_SHARED_CPPEXPORT AVPixelFormat BGRA64; + ST_SHARED_CPPEXPORT AVPixelFormat GBRPF32; + ST_SHARED_CPPEXPORT AVPixelFormat GBRAPF32; // XYZ formats ST_SHARED_CPPEXPORT AVPixelFormat XYZ12; // HWAccel formats