parent
dc6506be7c
commit
a23f28e411
@ -0,0 +1,60 @@ |
||||
//
|
||||
// Created by xu fulong on 2022/7/8.
|
||||
//
|
||||
|
||||
#include "yuv_to_rgb.h" |
||||
|
||||
static int range(int val) { |
||||
if (val < 0) { |
||||
return 0; |
||||
} else if (val > 255) { |
||||
return 255; |
||||
} else { |
||||
return val; |
||||
} |
||||
} |
||||
|
||||
static void YCbCr_to_RGB(uint8_t *dst, const uint8_t *src, int length) { |
||||
if (length < 1) return; |
||||
int R, G, B; |
||||
int Y, Cb, Cr; |
||||
int i, offset; |
||||
for (i = 0; i < length; i++) { |
||||
offset = (i << 1) + i; |
||||
Y = src[offset]; |
||||
Cb = src[offset + 1] - 128; |
||||
Cr = src[offset + 2] - 128; |
||||
R = Y + ((RGBRCrI * Cr + half_shift) >> shift); |
||||
G = Y + ((RGBGCbI * Cb + RGBGCrI * Cr + half_shift) >> shift); |
||||
B = Y + ((RGBBCbI * Cb + half_shift) >> shift); |
||||
R = range(R); |
||||
G = range(G); |
||||
B = range(B); |
||||
offset = i << 2; |
||||
dst[offset] = (uint8_t) B; |
||||
dst[offset + 1] = (uint8_t) G; |
||||
dst[offset + 2] = (uint8_t) R; |
||||
dst[offset + 3] = 0xff; |
||||
} |
||||
} |
||||
|
||||
static void RGB_to_YCbCr(uint8_t *dst, const uint8_t *src, int length) { |
||||
if (length < 1) return; |
||||
int R, G, B; |
||||
int i, offset; |
||||
for (i = 0; i < length; i++) { |
||||
offset = i << 2; |
||||
B = src[offset]; |
||||
G = src[offset + 1]; |
||||
R = src[offset + 2]; |
||||
offset = (i << 1) + i; |
||||
dst[offset] = (uint8_t) ((YCbCrYRI * R + YCbCrYGI * G + YCbCrYBI * B + half_shift) |
||||
>> shift); |
||||
dst[offset + 1] = (uint8_t) (128 + |
||||
((YCbCrCbRI * R + YCbCrCbGI * G + YCbCrCbBI * B + half_shift) |
||||
>> shift)); |
||||
dst[offset + 2] = (uint8_t) (128 + |
||||
((YCbCrCrRI * R + YCbCrCrGI * G + YCbCrCrBI * B + half_shift) |
||||
>> shift)); |
||||
} |
||||
} |
@ -0,0 +1,47 @@ |
||||
//
|
||||
// Created by xu fulong on 2022/7/8.
|
||||
//
|
||||
|
||||
#ifndef FFMPEGANDROID_YUV_TO_RGB_H |
||||
#define FFMPEGANDROID_YUV_TO_RGB_H |
||||
|
||||
#include <cstdint> |
||||
|
||||
const float YCbCrYRF = 0.299F; |
||||
const float YCbCrYGF = 0.587F; |
||||
const float YCbCrYBF = 0.114F; |
||||
const float YCbCrCbRF = -0.168736F; |
||||
const float YCbCrCbGF = -0.331264F; |
||||
const float YCbCrCbBF = 0.500000F; |
||||
const float YCbCrCrRF = 0.500000F; |
||||
const float YCbCrCrGF = -0.418688F; |
||||
const float YCbCrCrBF = -0.081312F; |
||||
|
||||
const float RGBRCrF = 1.40200F; |
||||
const float RGBGCbF = -0.34414F; |
||||
const float RGBGCrF = -0.71414F; |
||||
const float RGBBCbF = 1.77200F; |
||||
|
||||
const int shift = 20; |
||||
const int half_shift = 1 << (shift - 1); |
||||
|
||||
const int YCbCrYRI = (int)(YCbCrYRF * (1 << shift) + 0.5); |
||||
const int YCbCrYGI = (int)(YCbCrYGF * (1 << shift) + 0.5); |
||||
const int YCbCrYBI = (int)(YCbCrYBF * (1 << shift) + 0.5); |
||||
const int YCbCrCbRI = (int)(YCbCrCbRF * (1 << shift) + 0.5); |
||||
const int YCbCrCbGI = (int)(YCbCrCbGF * (1 << shift) + 0.5); |
||||
const int YCbCrCbBI = (int)(YCbCrCbBF * (1 << shift) + 0.5); |
||||
const int YCbCrCrRI = (int)(YCbCrCrRF * (1 << shift) + 0.5); |
||||
const int YCbCrCrGI = (int)(YCbCrCrGF * (1 << shift) + 0.5); |
||||
const int YCbCrCrBI = (int)(YCbCrCrBF * (1 << shift) + 0.5); |
||||
|
||||
const int RGBRCrI = (int)(RGBRCrF * (1 << shift) + 0.5); |
||||
const int RGBGCbI = (int)(RGBGCbF * (1 << shift) + 0.5); |
||||
const int RGBGCrI = (int)(RGBGCrF * (1 << shift) + 0.5); |
||||
const int RGBBCbI = (int)(RGBBCbF * (1 << shift) + 0.5); |
||||
|
||||
static void YCbCr_to_RGB(uint8_t* dst, const uint8_t* src, int length); |
||||
|
||||
static void RGB_to_YCbCr(uint8_t* dst, const uint8_t* src, int length); |
||||
|
||||
#endif //FFMPEGANDROID_YUV_TO_RGB_H
|
Loading…
Reference in new issue