Created
June 29, 2016 15:53
-
-
Save Sup3rc4l1fr4g1l1571c3xp14l1d0c10u5/d8cc664db15339d09fff25e364454ef6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// for For image to be given to FreeH264. | |
class yuv420_planar { | |
private: | |
static void yuv_to_bgr(unsigned char bgr[], const unsigned char y, const unsigned char u, const unsigned char v) { | |
auto c = static_cast<int>(y) - 16; | |
auto d = static_cast<int>(u) - 128; | |
auto e = static_cast<int>(v) - 128; | |
auto _r = (298 * c + 409 * e + 128) >> 8; | |
auto _g = (298 * c - 100 * d - 208 * e + 128) >> 8; | |
auto _b = (298 * c + 516 * d + 128) >> 8; | |
if (_r < 0) { _r = 0; } else if (_r > 255) { _r = 255; } | |
if (_g < 0) { _g = 0; } else if (_g > 255) { _g = 255; } | |
if (_b < 0) { _b = 0; } else if (_b > 255) { _b = 255; } | |
bgr[0] = static_cast<unsigned char>(_b); | |
bgr[1] = static_cast<unsigned char>(_g); | |
bgr[2] = static_cast<unsigned char>(_r); | |
} | |
static unsigned char bgr_to_y(const unsigned char b, const unsigned char g, const unsigned char r) | |
{ | |
return static_cast<unsigned char>((66 * static_cast<short>(r) + 129 * static_cast<short>(g) + 25 * static_cast<short>(b) + 128) >> 8) + 16; | |
} | |
static unsigned char bgr_to_u(const unsigned char b, const unsigned char g, const unsigned char r) | |
{ | |
return static_cast<unsigned char>((-38 * static_cast<short>(r) - 74 * static_cast<short>(g) + 112 * static_cast<short>(b) + 128) >> 8) + 128; | |
} | |
static unsigned char bgr_to_v(const unsigned char b, const unsigned char g, const unsigned char r) | |
{ | |
return static_cast<unsigned char>((112 * static_cast<short>(r) - 94 * static_cast<short>(g) - 18 * static_cast<short>(b) + 128) >> 8) + 128; | |
} | |
public: | |
static int yuv420_to_bgr24(int width, int height, unsigned char * planarYUV[], int strideU, int strideV, unsigned char * bmpBuffer, int bmpStride) | |
{ | |
auto planarY = planarYUV[0]; | |
auto planarU = planarYUV[1]; | |
auto planarV = planarYUV[2]; | |
auto bmpScaline = bmpBuffer; | |
for (int _y = 0; _y < height; _y++) { | |
auto pPixel = bmpScaline; | |
auto pY = planarY; | |
auto pU = planarU; | |
auto pV = planarV; | |
for (int _x = 0; _x < width; _x += 2) { | |
yuv_to_bgr(pPixel, *pY++, *pU, *pV); | |
pPixel += 3; | |
yuv_to_bgr(pPixel, *pY++, *pU++, *pV++); | |
pPixel += 3; | |
} | |
bmpScaline += bmpStride; | |
planarY += strideU; | |
if (_y % 2 == 1) { | |
planarU += strideV; | |
planarV += strideV; | |
} | |
} | |
return 0; | |
} | |
public: | |
static int bgr32_to_yuv420( | |
unsigned char * yuvBuffer, | |
const int width, | |
const int height, | |
const unsigned char * bgrBuffer, | |
bool isOddFrame) | |
{ | |
auto planarU = yuvBuffer + width * height; | |
auto planarV = planarU + ((width * height) / 4); | |
for (auto i = 0; i < height / 2; ++i) { | |
auto bgrScanLineEven = bgrBuffer; | |
auto bgrScanLineOdd = bgrBuffer + width * 4; | |
auto planarYeven = yuvBuffer; | |
auto planarYodd = yuvBuffer + width; | |
short r, g, b; | |
for (auto j = 0; j < width / 2; ++j) { | |
b = *bgrScanLineEven++; | |
g = *bgrScanLineEven++; | |
r = *bgrScanLineEven++; | |
++bgrScanLineEven; // skip alpha | |
*planarYeven++ = bgr_to_y(b, g, r); | |
if (!isOddFrame) | |
{ | |
*planarU++ = bgr_to_u(b, g, r); | |
} | |
b = *bgrScanLineEven++; | |
g = *bgrScanLineEven++; | |
r = *bgrScanLineEven++; | |
++bgrScanLineEven; // skip alpha | |
*planarYeven++ = bgr_to_y(b, g, r); | |
if (isOddFrame) | |
{ | |
*planarU++ = bgr_to_u(b, g, r); | |
} | |
b = *bgrScanLineOdd++; | |
g = *bgrScanLineOdd++; | |
r = *bgrScanLineOdd++; | |
++bgrScanLineOdd; // skip alpha | |
*planarYodd++ = bgr_to_y(b, g, r); | |
if (!isOddFrame) | |
{ | |
*planarV++ = bgr_to_v(b, g, r); | |
} | |
b = *bgrScanLineOdd++; | |
g = *bgrScanLineOdd++; | |
r = *bgrScanLineOdd++; | |
++bgrScanLineOdd; // skip alpha | |
*planarYodd++ = bgr_to_y(b, g, r); | |
if (isOddFrame) | |
{ | |
*planarV++ = bgr_to_v(b, g, r); | |
} | |
} | |
yuvBuffer += width * 2; | |
bgrBuffer += width * 4 * 2; | |
} | |
return 0; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment