У меня есть буфер BGRA, и мне нужно конвертировать его в формат AYUV. Функция ниже работает правильно, но очень неэффективно. Я знаю, что могу сделать это немного быстрее, переместив некоторые операции из внутреннего l oop, но я действительно хотел бы не делать никаких ручных манипуляций с битами.
Есть ли какой-то способ DirectX делать это? Или какой-нибудь битблт, который может конвертировать на GPU и т. Д. c? Это слишком много циклов, кодирующих генерируемые нами клипы mov ie.
Это проект c ++, нацеленный на Win10 Pro, написанный на VS2015, SS2
bool Convert2YUV()
{
if (m_pBuffer == nullptr)
return false;
UINT uiPixelInd = 0, uiColInd = 0, uiRowInd = 0;
short sR = 0, sG = 0, sB = 0;
for (uiRowInd = 0; uiRowInd < m_uiHeight; uiRowInd++)
{
for (uiColInd = 0; uiColInd < m_uiStripeByteSize; uiColInd = uiColInd + 4)
{
uiPixelInd = uiRowInd * m_uiStripeByteSize + uiColInd;
// Using local variables to avoid indexing operations every time
// Buffer is assumed to be in A8-B8-G8-R8 format
sR = m_pBuffer[uiPixelInd + 2];
sG = m_pBuffer[uiPixelInd + 1];
sB = m_pBuffer[uiPixelInd];
// Conversion from BGRA color space to AYUV color space - Color sampling is 4:4:4 with 8 bits per component
// Alpha is not participatig in operation since it is the same for BGRA and AYUV
short sY = (( 66 * sR + 129 * sG + 25 * sB + 128) >> 8) + 16;
short sU = ((-38 * sR - 74 * sG + 112 * sB + 128) >> 8) + 128;
short sV = ((112 * sR - 94 * sG - 18 * sB + 128) >> 8) + 128;
// Cannot do direct assignment to buffer since buffer is of the BYTE type, and during calculations, some overflow happens
// Have to assign to short and then from short to BYTE
// Components mus be in V8-U8-Y8-A8 order
m_pBuffer[uiPixelInd + 2] = (BYTE)sY;
m_pBuffer[uiPixelInd + 1] = (BYTE)sU;
m_pBuffer[uiPixelInd] = (BYTE)sV;
}
}
return true;
}