Оптимальное преобразование буфера BGRA в AYUV - PullRequest
0 голосов
/ 26 марта 2020

У меня есть буфер 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;
    }
...