Directory of Audio and Video Introduction Articles
libyuv
libyuv Google is open source to achieve a variety of YUV and RGB conversion, rotation, scaling and other libraries. It is cross platform and can be compiled and run on Windows, Linux, Mac, Android and other operating systems, x86, x64 and arm architectures. It supports the acceleration of SIMD instructions such as SSE, AVX and NEON.
Preparation
A picture
download rainbow-700x700.bmp BMP picture or prepare a picture by yourself (know the resolution, such as: 700x700)
FFmpeg Toolkit
Download the FFmpeg Static toolkit according to your system.
Get the required yuv420p file
Convert the above image into YUV420P format:
ffmpeg -i rainbow.bmp -video_size 700x700 -pix_fmt yuv420p rainbow-yuv420p.yuv
View YUV files
ffplay -f rawvideo -pixel_format yuv420p -video_size 700x700 rainbow-yuv420p.yuv
libyuv Operating YUV
YUV clipping
[rainbow-yuv420p.yuv] -> [rainbow-yuv420p-clip-x-y.yuv]
#include <stdio.h> #include <stdint.h> #include "libyuv.h" void clip(uint8_t *srcYuvData, uint8_t *dstYuvData, int width, int height, int cropX, int cropY, int cropWidth, int cropHeight) { ConvertToI420( srcYuvData, width*height*3/2, dstYuvData, cropWidth, dstYuvData+cropWidth*cropHeight, (cropWidth+1)/2, dstYuvData+cropWidth*cropHeight+((cropWidth+1)/2)*((cropHeight+1)/2), (cropWidth+1)/2, cropX, cropY, width, height, cropWidth, cropHeight, kRotate0, FOURCC_YU12); } int main() { uint32_t width = 700, height = 700; uint32_t clipWidth = 200, clipHeight = 200; uint8_t YUV[width*height*3/2]; uint8_t YUV_CLIP[clipWidth*clipHeight*3/2]; FILE *yuv420pFile = fopen("/Users/staff/Desktop/rainbow-yuv420p.yuv", "rb"); fread(YUV, sizeof(YUV), 1, yuv420pFile); clip(YUV, YUV_CLIP, width, height, 0, 0, clipWidth, clipHeight); FILE *yuvClipFile = fopen("/Users/staff/Desktop/rainbow-yuv420p-clip-0-0.yuv", "wb"); fwrite(YUV_CLIP, sizeof(YUV_CLIP), 1, yuvClipFile); fclose(yuvClipFile); fclose(yuv420pFile); return 0; }
YUV zoom
[rainbow-yuv420p.yuv] -> [rainbow-yuv420p-scale-X.yuv]
#include <stdio.h> #include <stdint.h> #include "libyuv.h" void scale(uint8_t *srcYuvData, uint8_t *dstYuvData, int width, int height, int dstWidth, int dstHeight) { I420Scale( srcYuvData, width, srcYuvData+width*height, (width+1)/2, srcYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, width, height, dstYuvData, dstWidth, dstYuvData+dstWidth*dstWidth, (dstWidth+1)/2, dstYuvData+dstWidth*dstHeight+((dstWidth+1)/2)*((dstHeight+1)/2), (dstWidth+1)/2, dstWidth, dstHeight, kFilterNone ); } int main() { uint32_t width = 700, height = 700; uint32_t dstWidth = 100, dstHeight = 100; uint8_t YUV[width*height*3/2]; uint8_t YUV_SCALE[dstWidth*dstHeight*3/2]; FILE *yuv420pFile = fopen("/Users/staff/Desktop/rainbow-yuv420p.yuv", "rb"); fread(YUV, sizeof(YUV), 1, yuv420pFile); scale(YUV, YUV_SCALE, width, height, dstWidth, dstHeight); FILE *yuvScaleFile = fopen("/Users/staff/Desktop/rainbow-yuv420p-scale-6.yuv", "wb"); fwrite(YUV_SCALE, sizeof(YUV_SCALE), 1, yuvScaleFile); fclose(yuvScaleFile); fclose(yuv420pFile); return 0; }
YUV rotation
[rainbow-yuv420p.yuv] -> [rainbow-yuv420p-rotation-90.yuv]
#include <stdio.h> #include <stdint.h> #include "libyuv.h" void rotation(uint8_t *srcYuvData, uint8_t *dstYuvData, int width, int height) { I420Rotate( srcYuvData, width, srcYuvData+width*height, (width+1)/2, srcYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, dstYuvData, width, dstYuvData+width*height, (width+1)/2, dstYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, width, height, kRotate90 ); } int main() { uint32_t width = 700, height = 700; uint8_t YUV[width*height*3/2]; uint8_t YUV_ROTATION[width*height*3/2]; FILE *yuv420pFile = fopen("/Users/staff/Desktop/rainbow-yuv420p.yuv", "rb"); fread(YUV, sizeof(YUV), 1, yuv420pFile); rotation(YUV, YUV_ROTATION, width, height); FILE *yuvRotationFile = fopen("/Users/staff/Desktop/rainbow-yuv420p-rotation-90.yuv", "wb"); fwrite(YUV_ROTATION, sizeof(YUV_ROTATION), 1, yuvRotationFile); fclose(yuvRotationFile); fclose(yuv420pFile); return 0; }
YUV mirror image
[rainbow-yuv420p-rotation-90.yuv] -> [rainbow-yuv420p-rotation-90-mirror.yuv]
#include <stdio.h> #include <stdint.h> #include "libyuv.h" void mirror(uint8_t *srcYuvData, uint8_t *dstYuvData, int width, int height) { I420Mirror( srcYuvData, width, srcYuvData+width*height, (width+1)/2, srcYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, dstYuvData, width, dstYuvData+width*height, (width+1)/2, dstYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, width, height ); } int main() { uint32_t width = 700, height = 700; uint8_t YUV[width*height*3/2]; uint8_t YUV_MIRROR[width*height*3/2]; FILE *yuv420pFile = fopen("/Users/staff/Desktop/rainbow-yuv420p-rotation-90.yuv", "rb"); fread(YUV, sizeof(YUV), 1, yuv420pFile); mirror(YUV, YUV_MIRROR, width, height); FILE *yuvMirrorFile = fopen("/Users/staff/Desktop/rainbow-yuv420p-rotation-90-mirror.yuv", "wb"); fwrite(YUV_MIRROR, sizeof(YUV_MIRROR), 1, yuvMirrorFile); fclose(yuvMirrorFile); fclose(yuv420pFile); return 0; }
YUV mixing
[rainbow-yuv420p.yuv] -> [rainbow-yuv420p-blend.yuv]
#include <stdio.h> #include <stdint.h> #include <string.h> #include "libyuv.h" void blend(uint8_t *srcYuvData, uint8_t *dstYuvData, int width, int height) { uint8_t YUV_ROTATION[width*height*3/2]; I420Rotate( srcYuvData, width, srcYuvData+width*height, (width+1)/2, srcYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, YUV_ROTATION, width, YUV_ROTATION+width*height, (width+1)/2, YUV_ROTATION+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, width, height, kRotate90 ); // transparency uint8_t alpha[width*height]; memset(alpha, 0X88, width*height); I420Blend( srcYuvData, width, srcYuvData+width*height, (width+1)/2, srcYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, YUV_ROTATION, width, YUV_ROTATION+width*height, (width+1)/2, YUV_ROTATION+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, alpha, width, dstYuvData, width, dstYuvData+width*height, (width+1)/2, dstYuvData+width*height+((width+1)/2)*((height+1)/2), (width+1)/2, width, height ); } int main() { uint32_t width = 700, height = 700; uint8_t YUV[width*height*3/2]; uint8_t YUV_BLEND[width*height*3/2]; FILE *yuv420pFile = fopen("/Users/staff/Desktop/rainbow-yuv420p.yuv", "rb"); fread(YUV, sizeof(YUV), 1, yuv420pFile); blend(YUV, YUV_BLEND, width, height); FILE *yuvBlendFile = fopen("/Users/staff/Desktop/rainbow-yuv420p-blend.yuv", "wb"); fwrite(YUV_BLEND, sizeof(YUV_BLEND), 1, yuvBlendFile); fclose(yuvBlendFile); fclose(yuv420pFile); return 0; }
Reference material:
Is the content wrong? Contact author: