See topic on MSDN Forums about coloring issue.
This is a demo of YUY2 to YV12 conversion as suggested copying Y values and averaging U and V.
Original image is on the right.
Code snippet to perform the transformation:
ATLASSERT(pInputBitmapInfoHeader->biCompression == FOURCC_YUY2); const CSize Extent = pInputVideoInfoHeader->GetExtent(); ATLASSERT(Extent == pOutputVideoInfoHeader->GetExtent()); const BYTE* pnInputData = InputMediaBuffer.m_pnData; SSIZE_T nFirstInputRowOffset, nNextInputRowOffset; pInputVideoInfoHeader->GetData(nFirstInputRowOffset, nNextInputRowOffset); ATLASSERT(!nFirstInputRowOffset); BYTE* pnOutputData = OutputMediaBuffer.m_pnData; SSIZE_T nFirstOutputRowOffset, nNextOutputRowOffset; pOutputVideoInfoHeader->GetData(nFirstOutputRowOffset, nNextOutputRowOffset); ATLASSERT(!nFirstOutputRowOffset); BYTE* pnOutputDataY = pnOutputData; BYTE* pnOutputDataV = pnOutputDataY + Extent.cy * nNextOutputRowOffset; BYTE* pnOutputDataU = pnOutputDataV + (Extent.cy * nNextOutputRowOffset) / 4; ATLTRACE2(atlTraceGeneral, 5, _T("pnInputData 0x%08x - 0x%08x, Extent { %d, %d }, pnOutputData 0x%08x - 0x%08x\n"), pnInputData, pnInputData + pInputBitmapInfoHeader->biSizeImage, Extent.cx, Extent.cy, pnOutputData, pnOutputData + pOutputBitmapInfoHeader->biSizeImage); ATLTRACE2(atlTraceGeneral, 5, _T("nFirstInputRowOffset %d, nNextInputRowOffset %d, nFirstOutputRowOffset %d, nNextOutputRowOffset %d\n"), nFirstInputRowOffset, nNextInputRowOffset, nFirstOutputRowOffset, nNextOutputRowOffset); ATLTRACE2(atlTraceGeneral, 5, _T("pnOutputDataY 0x%08x, pnOutputDataV 0x%08x, pnOutputDataU 0x%08x\n"), pnOutputDataY, pnOutputDataV, pnOutputDataU); SSIZE_T nInputRowOffset = nFirstInputRowOffset; for(LONG nY = 0; nY < Extent.cy; nY += 2) { SSIZE_T nInputOffset = nInputRowOffset; for(LONG nX = 0; nX < Extent.cx; nX += 2) { pnOutputDataY[0] = pnInputData[nInputOffset + 0]; const BYTE nU0 = pnInputData[nInputOffset + 1]; pnOutputDataY[1] = pnInputData[nInputOffset + 2]; const BYTE nV0 = pnInputData[nInputOffset + 3]; pnOutputDataY[nNextOutputRowOffset + 0] = pnInputData[nInputOffset + nNextInputRowOffset + 0]; const BYTE nU1 = pnInputData[nInputOffset + nNextInputRowOffset + 1]; pnOutputDataY[nNextOutputRowOffset + 1] = pnInputData[nInputOffset + nNextInputRowOffset + 2]; const BYTE nV1 = pnInputData[nInputOffset + nNextInputRowOffset + 3]; pnOutputDataU[0] = (nU0 + nU1) / 2; pnOutputDataV[0] = (nV0 + nV1) / 2; nInputOffset += 4; pnOutputDataY += 2; pnOutputDataV += 1; pnOutputDataU += 1; } nInputRowOffset += 2 * nNextInputRowOffset; pnOutputDataY += 2 * nNextOutputRowOffset - Extent.cx; pnOutputDataV += nNextOutputRowOffset / 2 - Extent.cx / 2; pnOutputDataU += nNextOutputRowOffset / 2 - Extent.cx / 2; } ATLTRACE2(atlTraceGeneral, 5, _T("pnOutputDataY 0x%08x, pnOutputDataV 0x%08x, pnOutputDataU 0x%08x\n"), pnOutputDataY, pnOutputDataV, pnOutputDataU)
See also: