今天发现,在ffmpeg解码mp4视频的libavformat/mov.c中,有一个YUV420转RGBA的函数,特意单独提取出来,供以后参考,具体如下:
static uint32_t yuv_to_rgba(uint32_t ycbcr)
{
uint8_t r, g, b;
int y, cb, cr;
y = (ycbcr >> 16) & 0xFF;
cr = (ycbcr >> 8) & 0xFF;
cb = ycbcr & 0xFF;
b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
return (r << 16) | (g << 8) | b;
}
上面的转换公式对于一般自己写格式转换的时候比较有用,但是ffmpeg其实是用汇编写的这个转换函数,据说速度是非常非常快的。
// ffmpeg-3.2.4/libavformat/movenc.c [2023-09-20]
static uint32_t rgb_to_yuv(uint32_t rgb)
{
uint8_t r, g, b;
int y, cb, cr;
r = (rgb >> 16) & 0xFF;
g = (rgb >> 8) & 0xFF;
b = (rgb ) & 0xFF;
y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
return (y << 16) | (cr << 8) | cb;
}